diff --git a/net/netmon/defaultroute_bsd.go b/net/netmon/defaultroute_bsd.go index b66a84636..9195ae073 100644 --- a/net/netmon/defaultroute_bsd.go +++ b/net/netmon/defaultroute_bsd.go @@ -1,11 +1,11 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -// Common code for FreeBSD and Darwin. This might also work on other +// Common code for FreeBSD. This might also work on other // BSD systems (e.g. OpenBSD) but has not been tested. -// Not used on iOS. See defaultroute_ios.go. +// Not used on iOS or macOS. See defaultroute_darwin.go. -//go:build !ios && (darwin || freebsd) +//go:build freebsd package netmon diff --git a/net/netmon/defaultroute_ios.go b/net/netmon/defaultroute_darwin.go similarity index 59% rename from net/netmon/defaultroute_ios.go rename to net/netmon/defaultroute_darwin.go index 63d5e49ce..9da52e311 100644 --- a/net/netmon/defaultroute_ios.go +++ b/net/netmon/defaultroute_darwin.go @@ -1,12 +1,13 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build ios +//go:build darwin || ios package netmon import ( "log" + "net" "tailscale.com/syncs" ) @@ -22,12 +23,12 @@ func UpdateLastKnownDefaultRouteInterface(ifName string) { return } if old := lastKnownDefaultRouteIfName.Swap(ifName); old != ifName { - log.Printf("defaultroute_ios: update from Swift, ifName = %s (was %s)", ifName, old) + log.Printf("defaultroute_darwin: update from Swift, ifName = %s (was %s)", ifName, old) } } func defaultRoute() (d DefaultRouteDetails, err error) { - // We cannot rely on the delegated interface data on iOS. The NetworkExtension framework + // We cannot rely on the delegated interface data on darwin. The NetworkExtension framework // seems to set the delegate interface only once, upon the *creation* of the VPN tunnel. // If a network transition (e.g. from Wi-Fi to Cellular) happens while the tunnel is // connected, it will be ignored and we will still try to set Wi-Fi as the default route @@ -37,16 +38,13 @@ func defaultRoute() (d DefaultRouteDetails, err error) { // the interface name of the first currently satisfied network path. Our Swift code will // call into `UpdateLastKnownDefaultRouteInterface`, so we can rely on that when it is set. // - // If for any reason the Swift machinery didn't work and we don't get any updates, here - // we also have some fallback logic: we try finding a hardcoded Wi-Fi interface called en0. - // If en0 is down, we fall back to cellular (pdp_ip0) as a last resort. This doesn't handle - // all edge cases like USB-Ethernet adapters or multiple Ethernet interfaces, but is good - // enough to ensure connectivity isn't broken. + // If for any reason the Swift machinery didn't work and we don't get any updates, we will + // fallback to the BSD logic. // Start by getting all available interfaces. interfaces, err := netInterfaces() if err != nil { - log.Printf("defaultroute_ios: could not get interfaces: %v", err) + log.Printf("defaultroute_darwin: could not get interfaces: %v", err) return d, ErrNoGatewayIndexFound } @@ -57,13 +55,13 @@ func defaultRoute() (d DefaultRouteDetails, err error) { } if !ifc.IsUp() { - log.Printf("defaultroute_ios: %s is down", name) + log.Printf("defaultroute_darwin: %s is down", name) return nil } addrs, _ := ifc.Addrs() if len(addrs) == 0 { - log.Printf("defaultroute_ios: %s has no addresses", name) + log.Printf("defaultroute_darwin: %s has no addresses", name) return nil } return &ifc @@ -79,30 +77,22 @@ func defaultRoute() (d DefaultRouteDetails, err error) { if ifc != nil { d.InterfaceName = ifc.Name d.InterfaceIndex = ifc.Index + log.Printf("defaultroute_darwin: using lastKnownDefaultRouteInterface %s %v", d.InterfaceName, d.InterfaceIndex) return d, nil } } - // Start of our fallback logic if Swift didn't give us an interface name, or gave us an invalid - // one. - // We start by attempting to use the Wi-Fi interface, which on iPhone is always called en0. - enZeroIf := getInterfaceByName("en0") - if enZeroIf != nil { - log.Println("defaultroute_ios: using en0 (fallback)") - d.InterfaceName = enZeroIf.Name - d.InterfaceIndex = enZeroIf.Index - return d, nil + // Fallback to the BSD logic + idx, err := DefaultRouteInterfaceIndex() + if err != nil { + return d, err } - - // Did it not work? Let's try with Cellular (pdp_ip0). - cellIf := getInterfaceByName("pdp_ip0") - if cellIf != nil { - log.Println("defaultroute_ios: using pdp_ip0 (fallback)") - d.InterfaceName = cellIf.Name - d.InterfaceIndex = cellIf.Index - return d, nil + iface, err := net.InterfaceByIndex(idx) + if err != nil { + return d, err } - - log.Println("defaultroute_ios: no running interfaces available") - return d, ErrNoGatewayIndexFound + d.InterfaceName = iface.Name + d.InterfaceIndex = idx + log.Printf("defaultroute_darwin: using table dervied default if %s %v", d.InterfaceName, d.InterfaceIndex) + return d, nil }