mirror of
https://github.com/safing/portmaster
synced 2025-04-22 20:09:09 +00:00
* Move portbase into monorepo * Add new simple module mgr * [WIP] Switch to new simple module mgr * Add StateMgr and more worker variants * [WIP] Switch more modules * [WIP] Switch more modules * [WIP] swtich more modules * [WIP] switch all SPN modules * [WIP] switch all service modules * [WIP] Convert all workers to the new module system * [WIP] add new task system to module manager * [WIP] Add second take for scheduling workers * [WIP] Add FIXME for bugs in new scheduler * [WIP] Add minor improvements to scheduler * [WIP] Add new worker scheduler * [WIP] Fix more bug related to new module system * [WIP] Fix start handing of the new module system * [WIP] Improve startup process * [WIP] Fix minor issues * [WIP] Fix missing subsystem in settings * [WIP] Initialize managers in constructor * [WIP] Move module event initialization to constrictors * [WIP] Fix setting for enabling and disabling the SPN module * [WIP] Move API registeration into module construction * [WIP] Update states mgr for all modules * [WIP] Add CmdLine operation support * Add state helper methods to module group and instance * Add notification and module status handling to status package * Fix starting issues * Remove pilot widget and update security lock to new status data * Remove debug logs * Improve http server shutdown * Add workaround for cleanly shutting down firewall+netquery * Improve logging * Add syncing states with notifications for new module system * Improve starting, stopping, shutdown; resolve FIXMEs/TODOs * [WIP] Fix most unit tests * Review new module system and fix minor issues * Push shutdown and restart events again via API * Set sleep mode via interface * Update example/template module * [WIP] Fix spn/cabin unit test * Remove deprecated UI elements * Make log output more similar for the logging transition phase * Switch spn hub and observer cmds to new module system * Fix log sources * Make worker mgr less error prone * Fix tests and minor issues * Fix observation hub * Improve shutdown and restart handling * Split up big connection.go source file * Move varint and dsd packages to structures repo * Improve expansion test * Fix linter warnings * Fix interception module on windows * Fix linter errors --------- Co-authored-by: Vladimir Stoilov <vladimir@safing.io>
279 lines
6.1 KiB
Go
279 lines
6.1 KiB
Go
package navigator
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/brianvoe/gofakeit"
|
|
|
|
"github.com/safing/jess/lhash"
|
|
"github.com/safing/portmaster/service/intel/geoip"
|
|
"github.com/safing/portmaster/spn/hub"
|
|
)
|
|
|
|
var (
|
|
fakeLock sync.Mutex
|
|
|
|
defaultMapCreate sync.Once
|
|
defaultMap *Map
|
|
)
|
|
|
|
func getDefaultTestMap() *Map {
|
|
defaultMapCreate.Do(func() {
|
|
defaultMap = createRandomTestMap(1, 200)
|
|
})
|
|
return defaultMap
|
|
}
|
|
|
|
func TestRandomMapCreation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
m := getDefaultTestMap()
|
|
|
|
fmt.Println("All Pins:")
|
|
for _, pin := range m.all {
|
|
fmt.Printf("%s: %s %s\n", pin, pin.Hub.Info.IPv4, pin.Hub.Info.IPv6)
|
|
}
|
|
|
|
// Print stats
|
|
fmt.Printf("\n%s\n", m.Stats())
|
|
|
|
// Print home
|
|
fmt.Printf("Selected Home Hub: %s\n", m.home)
|
|
}
|
|
|
|
func createRandomTestMap(seed int64, size int) *Map {
|
|
fakeLock.Lock()
|
|
defer fakeLock.Unlock()
|
|
|
|
// Seed with parameter to make it reproducible.
|
|
gofakeit.Seed(seed)
|
|
|
|
// Enforce minimum size.
|
|
if size < 10 {
|
|
size = 10
|
|
}
|
|
|
|
// Create Hub list.
|
|
hubs := make([]*hub.Hub, 0, size)
|
|
|
|
// Create Intel data structure.
|
|
mapIntel := &hub.Intel{
|
|
Hubs: make(map[string]*hub.HubIntel),
|
|
}
|
|
|
|
// Define periodic values.
|
|
var currentGroup string
|
|
|
|
// Create [size] fake Hubs.
|
|
for i := range size {
|
|
// Change group every 5 Hubs.
|
|
if i%5 == 0 {
|
|
currentGroup = gofakeit.Username()
|
|
}
|
|
|
|
// Create new fake Hub and add to the list.
|
|
h := createFakeHub(currentGroup, true, mapIntel)
|
|
hubs = append(hubs, h)
|
|
}
|
|
|
|
// Fake three superseeded Hubs.
|
|
for i := range 3 {
|
|
h := hubs[size-1-i]
|
|
|
|
// Set FirstSeen in the past and copy an IP address of an existing Hub.
|
|
h.FirstSeen = time.Now().Add(-1 * time.Hour)
|
|
if i%2 == 0 {
|
|
h.Info.IPv4 = hubs[i].Info.IPv4
|
|
} else {
|
|
h.Info.IPv6 = hubs[i].Info.IPv6
|
|
}
|
|
}
|
|
|
|
// Create Lanes between Hubs in order to create the network.
|
|
totalConnections := size * 10
|
|
for range totalConnections {
|
|
// Get new random indexes.
|
|
indexA := gofakeit.Number(0, size-1)
|
|
indexB := gofakeit.Number(0, size-1)
|
|
if indexA == indexB {
|
|
continue
|
|
}
|
|
|
|
// Get Hubs and check if they are already connected.
|
|
hubA := hubs[indexA]
|
|
hubB := hubs[indexB]
|
|
if hubA.GetLaneTo(hubB.ID) != nil {
|
|
// already connected
|
|
continue
|
|
}
|
|
if hubB.GetLaneTo(hubA.ID) != nil {
|
|
// already connected
|
|
continue
|
|
}
|
|
|
|
// Create connections.
|
|
_ = hubA.AddLane(createLane(hubB.ID))
|
|
// Add the second connection in 99% of cases.
|
|
// If this is missing, the Pins should not show up as connected.
|
|
if gofakeit.Number(0, 100) != 0 {
|
|
_ = hubB.AddLane(createLane(hubA.ID))
|
|
}
|
|
}
|
|
|
|
// Parse constructed intel data
|
|
err := mapIntel.ParseAdvisories()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Create map and add Pins.
|
|
m := NewMap(fmt.Sprintf("Test-Map-%d", seed), true)
|
|
m.intel = mapIntel
|
|
for _, h := range hubs {
|
|
m.UpdateHub(h)
|
|
}
|
|
|
|
// Fake communication error with three Hubs.
|
|
var i int
|
|
for _, pin := range m.all {
|
|
pin.MarkAsFailingFor(1 * time.Hour)
|
|
pin.addStates(StateFailing)
|
|
|
|
if i++; i >= 3 {
|
|
break
|
|
}
|
|
}
|
|
|
|
// Set a Home Hub.
|
|
findFakeHomeHub(m)
|
|
|
|
return m
|
|
}
|
|
|
|
func createFakeHub(group string, randomFailes bool, mapIntel *hub.Intel) *hub.Hub {
|
|
// Create fake Hub ID.
|
|
idSrc := gofakeit.Password(true, true, true, true, true, 64)
|
|
id := lhash.Digest(lhash.BLAKE2b_256, []byte(idSrc)).Base58()
|
|
ip4, _ := createGoodIP(true)
|
|
ip6, _ := createGoodIP(false)
|
|
|
|
// Create and return new fake Hub.
|
|
h := &hub.Hub{
|
|
ID: id,
|
|
Info: &hub.Announcement{
|
|
ID: id,
|
|
Timestamp: time.Now().Unix(),
|
|
Name: gofakeit.Username(),
|
|
Group: group,
|
|
// ContactAddress // TODO
|
|
// ContactService // TODO
|
|
// Hosters []string // TODO
|
|
// Datacenter string // TODO
|
|
IPv4: ip4,
|
|
IPv6: ip6,
|
|
},
|
|
Status: &hub.Status{
|
|
Timestamp: time.Now().Unix(),
|
|
Keys: map[string]*hub.Key{
|
|
"a": {
|
|
Expires: time.Now().Add(48 * time.Hour).Unix(),
|
|
},
|
|
},
|
|
Load: gofakeit.Number(10, 100),
|
|
},
|
|
Measurements: hub.NewMeasurements(),
|
|
FirstSeen: time.Now(),
|
|
}
|
|
h.Measurements.Latency = createLatency()
|
|
h.Measurements.Capacity = createCapacity()
|
|
h.Measurements.CalculatedCost = CalculateLaneCost(
|
|
h.Measurements.Latency,
|
|
h.Measurements.Capacity,
|
|
)
|
|
|
|
// Return if not failures of any kind should be simulated.
|
|
if !randomFailes {
|
|
return h
|
|
}
|
|
|
|
// Set hub-based states.
|
|
if gofakeit.Number(0, 100) == 0 {
|
|
// Fake Info message error.
|
|
h.InvalidInfo = true
|
|
}
|
|
if gofakeit.Number(0, 100) == 0 {
|
|
// Fake Status message error.
|
|
h.InvalidStatus = true
|
|
}
|
|
if gofakeit.Number(0, 100) == 0 {
|
|
// Fake expired exchange keys.
|
|
for _, key := range h.Status.Keys {
|
|
key.Expires = time.Now().Add(-1 * time.Hour).Unix()
|
|
}
|
|
}
|
|
|
|
// Return if not failures of any kind should be simulated.
|
|
if mapIntel == nil {
|
|
return h
|
|
}
|
|
|
|
// Set advisory-based states.
|
|
if gofakeit.Number(0, 10) == 0 {
|
|
// Make Trusted State
|
|
mapIntel.Hubs[h.ID] = &hub.HubIntel{
|
|
Trusted: true,
|
|
}
|
|
}
|
|
if gofakeit.Number(0, 100) == 0 {
|
|
// Discourage any usage.
|
|
mapIntel.HubAdvisory = append(mapIntel.HubAdvisory, "- "+h.Info.IPv4.String())
|
|
}
|
|
if gofakeit.Number(0, 100) == 0 {
|
|
// Discourage Home Hub usage.
|
|
mapIntel.HomeHubAdvisory = append(mapIntel.HomeHubAdvisory, "- "+h.Info.IPv4.String())
|
|
}
|
|
if gofakeit.Number(0, 100) == 0 {
|
|
// Discourage Destination Hub usage.
|
|
mapIntel.DestinationHubAdvisory = append(mapIntel.DestinationHubAdvisory, "- "+h.Info.IPv4.String())
|
|
}
|
|
|
|
return h
|
|
}
|
|
|
|
func createGoodIP(v4 bool) (net.IP, *geoip.Location) {
|
|
var candidate net.IP
|
|
for range 100 {
|
|
if v4 {
|
|
candidate = net.ParseIP(gofakeit.IPv4Address())
|
|
} else {
|
|
candidate = net.ParseIP(gofakeit.IPv6Address())
|
|
}
|
|
loc, err := geoip.GetLocation(candidate)
|
|
if err == nil && loc.Coordinates.Latitude != 0 {
|
|
return candidate, loc
|
|
}
|
|
}
|
|
return candidate, nil
|
|
}
|
|
|
|
func createLane(toHubID string) *hub.Lane {
|
|
return &hub.Lane{
|
|
ID: toHubID,
|
|
Latency: createLatency(),
|
|
Capacity: createCapacity(),
|
|
}
|
|
}
|
|
|
|
func createLatency() time.Duration {
|
|
// Return a value between 10ms and 100ms.
|
|
return time.Duration(gofakeit.Float64Range(10, 100) * float64(time.Millisecond))
|
|
}
|
|
|
|
func createCapacity() int {
|
|
// Return a value between 10Mbit/s and 1Gbit/s.
|
|
return gofakeit.Number(10000000, 1000000000)
|
|
}
|