mirror of
https://github.com/safing/portmaster
synced 2025-09-02 02:29:12 +00:00
Merge pull request #1134 from safing/fix/traceroute-location
Fix traceroute locating, improvements
This commit is contained in:
commit
8ecb8a4156
3 changed files with 23 additions and 12 deletions
|
@ -135,8 +135,8 @@ func (l *Location) EstimateNetworkProximity(to *Location) (proximity float32) {
|
||||||
toCoords := haversine.Coord{Lat: to.Coordinates.Latitude, Lon: to.Coordinates.Longitude}
|
toCoords := haversine.Coord{Lat: to.Coordinates.Latitude, Lon: to.Coordinates.Longitude}
|
||||||
_, km := haversine.Distance(fromCoords, toCoords)
|
_, km := haversine.Distance(fromCoords, toCoords)
|
||||||
|
|
||||||
if km <= 50 && accuracy <= 100 {
|
if km <= 100 && accuracy <= 100 {
|
||||||
// Give a flat out ten for highly accurate coordinates within 50km.
|
// Give the full value for highly accurate coordinates within 100km.
|
||||||
proximity += weightCoordinateDistance
|
proximity += weightCoordinateDistance
|
||||||
} else {
|
} else {
|
||||||
// Else, take a percentage.
|
// Else, take a percentage.
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
|
@ -108,6 +107,8 @@ func (dls *DeviceLocations) AddLocation(dl *DeviceLocation) {
|
||||||
|
|
||||||
// Sort locations.
|
// Sort locations.
|
||||||
sort.Sort(sortLocationsByAccuracy(dls.All))
|
sort.Sort(sortLocationsByAccuracy(dls.All))
|
||||||
|
|
||||||
|
log.Debugf("netenv: added new device location to IPv%d scope: %s from %s", dl.IPVersion, dl, dl.Source)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeviceLocation represents a single IP and metadata. It must not be changed
|
// DeviceLocation represents a single IP and metadata. It must not be changed
|
||||||
|
@ -288,6 +289,7 @@ func GetInternetLocation() (deviceLocations *DeviceLocations, ok bool) {
|
||||||
|
|
||||||
// Create new location list.
|
// Create new location list.
|
||||||
dls := &DeviceLocations{}
|
dls := &DeviceLocations{}
|
||||||
|
log.Debug("netenv: getting new device locations")
|
||||||
|
|
||||||
// Check interfaces for global addresses.
|
// Check interfaces for global addresses.
|
||||||
v4ok, v6ok := getLocationFromInterfaces(dls)
|
v4ok, v6ok := getLocationFromInterfaces(dls)
|
||||||
|
@ -359,11 +361,11 @@ func getLocationFromUPnP() (ok bool) {
|
||||||
|
|
||||||
func getLocationFromTraceroute(dls *DeviceLocations) (dl *DeviceLocation, err error) {
|
func getLocationFromTraceroute(dls *DeviceLocations) (dl *DeviceLocation, err error) {
|
||||||
// Create connection.
|
// Create connection.
|
||||||
conn, err := net.ListenPacket("ip4:icmp", "")
|
conn, err := icmp.ListenPacket("ip4:icmp", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to open icmp conn: %w", err)
|
return nil, fmt.Errorf("failed to open icmp conn: %w", err)
|
||||||
}
|
}
|
||||||
v4Conn := ipv4.NewPacketConn(conn)
|
v4Conn := conn.IPv4PacketConn()
|
||||||
|
|
||||||
// Generate a random ID for the ICMP packets.
|
// Generate a random ID for the ICMP packets.
|
||||||
generatedID, err := rng.Number(0xFFFF) // uint16
|
generatedID, err := rng.Number(0xFFFF) // uint16
|
||||||
|
@ -393,7 +395,7 @@ nextHop:
|
||||||
for i := 1; i <= maxHops; i++ {
|
for i := 1; i <= maxHops; i++ {
|
||||||
minSeq := msgSeq + 1
|
minSeq := msgSeq + 1
|
||||||
|
|
||||||
repeat:
|
repeatHop:
|
||||||
for j := 1; j <= 2; j++ { // Try every hop twice.
|
for j := 1; j <= 2; j++ { // Try every hop twice.
|
||||||
// Increase sequence number.
|
// Increase sequence number.
|
||||||
msgSeq++
|
msgSeq++
|
||||||
|
@ -412,11 +414,16 @@ nextHop:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send ICMP packet.
|
// Send ICMP packet.
|
||||||
if _, err := conn.WriteTo(pingPacket, locationTestingIPv4Addr); err != nil {
|
// Try to send three times, as this can be flaky.
|
||||||
var opErr *net.OpError
|
sendICMP:
|
||||||
if errors.As(err, &opErr) && errors.Is(opErr.Err, syscall.ENOBUFS) {
|
for i := 0; i < 3; i++ {
|
||||||
continue
|
_, err = conn.WriteTo(pingPacket, locationTestingIPv4Addr)
|
||||||
|
if err == nil {
|
||||||
|
break sendICMP
|
||||||
}
|
}
|
||||||
|
time.Sleep(30 * time.Millisecond)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to send icmp packet: %w", err)
|
return nil, fmt.Errorf("failed to send icmp packet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +432,8 @@ nextHop:
|
||||||
for {
|
for {
|
||||||
remoteIP, icmpPacket, ok := recvICMP(i, icmpPacketsViaFirewall)
|
remoteIP, icmpPacket, ok := recvICMP(i, icmpPacketsViaFirewall)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue repeat
|
// Timed out.
|
||||||
|
continue repeatHop
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-filter by message type.
|
// Pre-filter by message type.
|
||||||
|
@ -485,6 +493,9 @@ nextHop:
|
||||||
return dl, nil
|
return dl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add one max hop for every reply that was not global.
|
||||||
|
maxHops++
|
||||||
|
|
||||||
// Otherwise, continue.
|
// Otherwise, continue.
|
||||||
continue nextHop
|
continue nextHop
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,7 +419,7 @@ resolveLoop:
|
||||||
return nil, err
|
return nil, err
|
||||||
default:
|
default:
|
||||||
resolver.Conn.ReportFailure()
|
resolver.Conn.ReportFailure()
|
||||||
log.Tracer(ctx).Debugf("resolver: query to %s failed: %s", resolver.Info.ID(), err)
|
log.Tracer(ctx).Warningf("resolver: query to %s failed: %s", resolver.Info.ID(), err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue