Merge pull request #1134 from safing/fix/traceroute-location

Fix traceroute locating, improvements
This commit is contained in:
Daniel Hovie 2023-03-17 09:10:36 +01:00 committed by GitHub
commit 8ecb8a4156
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 12 deletions

View file

@ -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.

View file

@ -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
} }

View file

@ -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
} }
} }