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 (
"encoding/binary"
"net"
"strings"
"github.com/safing/portbase/utils"
"github.com/umahmood/haversine"
)
@ -56,11 +58,11 @@ type Coordinates struct {
*/
const (
weightContinentMatch = 25
weightCountryMatch = 20
weightASOrgMatch = 15
weightASNMatch = 10
weightCoordinateDistance = 30
weightContinentMatch = 20
weightCountryMatch = 15
weightASOrgMatch = 10
weightASNMatch = 5
weightCoordinateDistance = 50
)
/*
@ -94,11 +96,14 @@ func (l *Location) EstimateNetworkProximity(to *Location) (proximity float32) {
}
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,
// especially when combining location data from multiple sources.
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
}
@ -183,3 +188,20 @@ func PrimitiveNetworkProximity(from net.IP, to net.IP, ipVersion uint8) int {
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.
// Matching on somewhat older data is not a problem, as these IPs would not
// just randomly pop up somewhere else that fast.
mine, matched := checkIfMyIP(ip)
if matched {
return mine, nil
}
// Check if the network changed.
if !myNetworksNetworkChangedFlag.IsSet() {
// Network did not change, return "no match".
mine, myNet := checkIfMyIP(ip)
switch {
case mine:
// IP matched.
return true, nil
case myNetworksNetworkChangedFlag.IsSet():
// The network changed, so we need to refresh the data.
case myNet:
// IP is one of the networks and nothing changed, so this is not our IP.
return false, nil
}
@ -104,13 +105,13 @@ func IsMyIP(ip net.IP) (yes bool, err error) {
}
myNetworks = make([]*net.IPNet, 0, len(interfaceNetworks))
for _, ifNet := range interfaceNetworks {
net, ok := ifNet.(*net.IPNet)
ipNet, ok := ifNet.(*net.IPNet)
if !ok {
log.Warningf("netenv: interface network of unexpected type %T", ifNet)
continue
}
myNetworks = append(myNetworks, net)
myNetworks = append(myNetworks, ipNet)
}
// Reset error.
@ -126,7 +127,7 @@ func IsMyIP(ip net.IP) (yes bool, err error) {
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.
for _, myNet := range myNetworks {
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)
if err != nil {
log.Warningf("netenv: failed to get geolocation data of %s (from %s): %s", ip, source, err)
return nil, false
} else {
loc.Location = geoLoc
}
@ -214,6 +215,10 @@ func SetInternetLocation(ip net.IP, source DeviceLocationSource) (dl *DeviceLoca
}
func addLocation(dl *DeviceLocation) {
if dl == nil {
return
}
locationsLock.Lock()
defer locationsLock.Unlock()

View file

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