Merge pull request #501 from safing/fix/patch-set-13

Fix location related issues
This commit is contained in:
Daniel 2022-01-26 13:13:40 +01:00 committed by GitHub
commit f625024bfc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 22 deletions

View file

@ -3,7 +3,9 @@ package geoip
import ( import (
"encoding/binary" "encoding/binary"
"net" "net"
"strings"
"github.com/safing/portbase/utils"
"github.com/umahmood/haversine" "github.com/umahmood/haversine"
) )
@ -56,11 +58,11 @@ type Coordinates struct {
*/ */
const ( const (
weightContinentMatch = 25 weightContinentMatch = 20
weightCountryMatch = 20 weightCountryMatch = 15
weightASOrgMatch = 15 weightASOrgMatch = 10
weightASNMatch = 10 weightASNMatch = 5
weightCoordinateDistance = 30 weightCoordinateDistance = 50
) )
/* /*
@ -94,11 +96,14 @@ func (l *Location) EstimateNetworkProximity(to *Location) (proximity float32) {
} }
switch { switch {
case l.AutonomousSystemNumber != 0 && l.AutonomousSystemNumber == to.AutonomousSystemNumber: case l.AutonomousSystemNumber == to.AutonomousSystemNumber &&
l.AutonomousSystemNumber != 0:
// Rely more on the ASN data, as it is more accurate than the ASOrg data, // Rely more on the ASN data, as it is more accurate than the ASOrg data,
// especially when combining location data from multiple sources. // especially when combining location data from multiple sources.
proximity += weightASOrgMatch + weightASNMatch proximity += weightASOrgMatch + weightASNMatch
case l.AutonomousSystemOrganization != "" && l.AutonomousSystemOrganization == to.AutonomousSystemOrganization: case l.AutonomousSystemOrganization == to.AutonomousSystemOrganization &&
l.AutonomousSystemNumber != 0 && // Check if an ASN is set. If the ASOrg is known, the ASN must be too.
!ASOrgUnknown(l.AutonomousSystemOrganization): // Check if the ASOrg name is valid.
proximity += weightASOrgMatch proximity += weightASOrgMatch
} }
@ -183,3 +188,20 @@ func PrimitiveNetworkProximity(from net.IP, to net.IP, ipVersion uint8) int {
return 0 return 0
} }
} }
var unknownASOrgNames = []string{
"", // Expected default for unknown.
"not routed", // Observed as "Not routed" in data set.
"unknown", // Observed as "UNKNOWN" in online data set.
"nil", // Programmatic unknown value.
"null", // Programmatic unknown value.
"undef", // Programmatic unknown value.
"undefined", // Programmatic unknown value.
}
func ASOrgUnknown(asOrg string) bool {
return utils.StringInSlice(
unknownASOrgNames,
strings.ToLower(asOrg),
)
}

View file

@ -76,14 +76,15 @@ func IsMyIP(ip net.IP) (yes bool, err error) {
// Check if current data matches IP. // Check if current data matches IP.
// Matching on somewhat older data is not a problem, as these IPs would not // Matching on somewhat older data is not a problem, as these IPs would not
// just randomly pop up somewhere else that fast. // just randomly pop up somewhere else that fast.
mine, matched := checkIfMyIP(ip) mine, myNet := checkIfMyIP(ip)
if matched { switch {
return mine, nil case mine:
} // IP matched.
return true, nil
// Check if the network changed. case myNetworksNetworkChangedFlag.IsSet():
if !myNetworksNetworkChangedFlag.IsSet() { // The network changed, so we need to refresh the data.
// Network did not change, return "no match". case myNet:
// IP is one of the networks and nothing changed, so this is not our IP.
return false, nil return false, nil
} }
@ -104,13 +105,13 @@ func IsMyIP(ip net.IP) (yes bool, err error) {
} }
myNetworks = make([]*net.IPNet, 0, len(interfaceNetworks)) myNetworks = make([]*net.IPNet, 0, len(interfaceNetworks))
for _, ifNet := range interfaceNetworks { for _, ifNet := range interfaceNetworks {
net, ok := ifNet.(*net.IPNet) ipNet, ok := ifNet.(*net.IPNet)
if !ok { if !ok {
log.Warningf("netenv: interface network of unexpected type %T", ifNet) log.Warningf("netenv: interface network of unexpected type %T", ifNet)
continue continue
} }
myNetworks = append(myNetworks, net) myNetworks = append(myNetworks, ipNet)
} }
// Reset error. // Reset error.
@ -126,7 +127,7 @@ func IsMyIP(ip net.IP) (yes bool, err error) {
return false, nil return false, nil
} }
func checkIfMyIP(ip net.IP) (mine bool, matched bool) { func checkIfMyIP(ip net.IP) (mine bool, myNet bool) {
// Check against assigned IPs. // Check against assigned IPs.
for _, myNet := range myNetworks { for _, myNet := range myNetworks {
if ip.Equal(myNet.IP) { if ip.Equal(myNet.IP) {

View file

@ -205,6 +205,7 @@ func SetInternetLocation(ip net.IP, source DeviceLocationSource) (dl *DeviceLoca
geoLoc, err := geoip.GetLocation(ip) geoLoc, err := geoip.GetLocation(ip)
if err != nil { if err != nil {
log.Warningf("netenv: failed to get geolocation data of %s (from %s): %s", ip, source, err) log.Warningf("netenv: failed to get geolocation data of %s (from %s): %s", ip, source, err)
return nil, false
} else { } else {
loc.Location = geoLoc loc.Location = geoLoc
} }
@ -214,6 +215,10 @@ func SetInternetLocation(ip net.IP, source DeviceLocationSource) (dl *DeviceLoca
} }
func addLocation(dl *DeviceLocation) { func addLocation(dl *DeviceLocation) {
if dl == nil {
return
}
locationsLock.Lock() locationsLock.Lock()
defer locationsLock.Unlock() defer locationsLock.Unlock()

View file

@ -40,8 +40,8 @@ serviceLoop:
for { for {
trigger := false trigger := false
timeout := time.Minute timeout := 15 * time.Second
if GetOnlineStatus() != StatusOnline { if !Online() {
timeout = time.Second timeout = time.Second
} }
// wait for trigger // wait for trigger
@ -62,7 +62,7 @@ serviceLoop:
hasher := sha1.New() //nolint:gosec // not used for security hasher := sha1.New() //nolint:gosec // not used for security
interfaces, err := net.Interfaces() interfaces, err := net.Interfaces()
if err != nil { if err != nil {
log.Warningf("environment: failed to get interfaces: %s", err) log.Warningf("netenv: failed to get interfaces: %s", err)
continue continue
} }
for _, iface := range interfaces { for _, iface := range interfaces {
@ -72,7 +72,7 @@ serviceLoop:
// log.Tracef("adding: %s", iface.Flags.String()) // log.Tracef("adding: %s", iface.Flags.String())
addrs, err := iface.Addrs() addrs, err := iface.Addrs()
if err != nil { if err != nil {
log.Warningf("environment: failed to get addrs from interface %s: %s", iface.Name, err) log.Warningf("netenv: failed to get addrs from interface %s: %s", iface.Name, err)
continue continue
} }
for _, addr := range addrs { for _, addr := range addrs {