From f7d632b58a7f015a078db992211f390217f61973 Mon Sep 17 00:00:00 2001 From: kari-ts Date: Tue, 19 May 2026 15:17:20 -0700 Subject: [PATCH] android: push default gateway IP from LinkProperties to go backend likelyHomeRouterIPHelper was replaced with a cached gateway read in 86f9e7a9ea47e368e394a8e4e1866bbd40e6ed4a. This provides the value by retrieving the default gateway from LinkProperties.getRoute() in NetworkChangeCallback on every onLinkPropertiesChanged event. Updates tailscale/tailscale#18622 Updates tailscale/tailscale#13352 Signed-off-by: kari-ts --- .../main/java/com/tailscale/ipn/NetworkChangeCallback.kt | 8 ++++++++ libtailscale/callbacks.go | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/android/src/main/java/com/tailscale/ipn/NetworkChangeCallback.kt b/android/src/main/java/com/tailscale/ipn/NetworkChangeCallback.kt index 2919e4d431..90a6cb1eaa 100644 --- a/android/src/main/java/com/tailscale/ipn/NetworkChangeCallback.kt +++ b/android/src/main/java/com/tailscale/ipn/NetworkChangeCallback.kt @@ -197,6 +197,14 @@ object NetworkChangeCallback { if (dns.updateDNSFromNetwork(sb.toString())) { TSLog.d(TAG, "$why: updated DNS config for iface=${info.linkProps.interfaceName}") + + val gatewayIP = info.linkProps.routes + .filter { it.isDefaultRoute && it.gateway != null } + .sortedBy { if (it.gateway is java.net.Inet4Address) 0 else 1 } + .firstNotNullOfOrNull { it.gateway?.hostAddress } + ?: "" + + Libtailscale.onGatewayChanged(gatewayIP) Libtailscale.onDNSConfigChanged(info.linkProps.interfaceName) } } diff --git a/libtailscale/callbacks.go b/libtailscale/callbacks.go index 9daec5c6b5..65489cccbc 100644 --- a/libtailscale/callbacks.go +++ b/libtailscale/callbacks.go @@ -5,6 +5,8 @@ package libtailscale import ( "sync" + + "tailscale.com/net/netmon" ) var ( @@ -36,6 +38,11 @@ func OnDNSConfigChanged(ifname string) { } } +// OnGatewayChanged is called when LinkProperties provides an updated default gateway IP. +func OnGatewayChanged(gatewayIP string) { + netmon.UpdateLastKnownDefaultGateway(gatewayIP) +} + var android struct { // mu protects all fields of this structure. However, once a // non-nil jvm is returned from javaVM, all the other fields may