From a682f7602e8aa0f03e018ba432e2816ddb40265e Mon Sep 17 00:00:00 2001 From: Andrew Dunham Date: Wed, 17 Apr 2024 10:59:30 -0400 Subject: [PATCH] net/tsdial: assume all connections are affected if no default route is present If this happens, it results in us pessimistically closing more connections than might be necessary, but is more correct since we won't "miss" a change to the default route interface and keep trying to send data over a nonexistent interface, or one that can't reach the internet. Updates tailscale/corp#19124 Signed-off-by: Andrew Dunham Change-Id: Ia0b8b04cb8cdcb0da0155fd08751c9dccba62c1a --- net/tsdial/tsdial.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/net/tsdial/tsdial.go b/net/tsdial/tsdial.go index 85f763997..1a5ca7052 100644 --- a/net/tsdial/tsdial.go +++ b/net/tsdial/tsdial.go @@ -142,10 +142,16 @@ func (d *Dialer) SetNetMon(netMon *netmon.Monitor) { } var ( - metricLinkChangeConnClosed = clientmetric.NewCounter("tsdial_linkchange_closes") + metricLinkChangeConnClosed = clientmetric.NewCounter("tsdial_linkchange_closes") + metricChangeDeltaNoDefaultRoute = clientmetric.NewCounter("tsdial_changedelta_no_default_route") ) func (d *Dialer) linkChanged(delta *netmon.ChangeDelta) { + // Track how often we see ChangeDeltas with no DefaultRouteInterface. + if delta.New.DefaultRouteInterface == "" { + metricChangeDeltaNoDefaultRoute.Add(1) + } + d.mu.Lock() defer d.mu.Unlock() var anyClosed bool @@ -179,6 +185,14 @@ func changeAffectsConn(delta *netmon.ChangeDelta, conn net.Conn) bool { delta.Old.HTTPProxy != delta.New.HTTPProxy { return true } + + // In a few cases, we don't have a new DefaultRouteInterface (e.g. on + // Android; see tailscale/corp#19124); if so, pessimistically assume + // that all connections are affected. + if delta.New.DefaultRouteInterface == "" { + return true + } + if !delta.New.HasIP(lip) && delta.Old.HasIP(lip) { // Our interface with this source IP went away. return true