From 375617c5c804134ad28a34122e072e4bbb009675 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