tailscale/ipn
Avery Pennarun 6a822dcc36 control/controlclient: continue map poll during key expiry to receive extensions
When a client's node key expires and the user clicks "Login" (or runs
`tailscale up`), the Login() method was cancelling the map poll context.
This caused key extension notifications from the server to be lost,
leaving clients stuck in NeedsLogin state even after an admin extended
their key.

The fix has three parts:

1. Login(): Don't cancel mapCtx if we have valid credentials (loggedIn=true)
   or a valid node key. This allows the map poll to continue receiving
   server notifications while the auth flow proceeds in parallel.

2. mapRoutine(): Poll when we have a node key, even if !loggedIn. This
   handles the tsnet restart scenario where control returns an AuthURL
   (so loggedIn=false) but we still have a valid node key that can
   receive map updates.

3. sendStatus()/UpdateFullNetmap(): Forward netmaps when we have a node
   key, not just when loggedIn. This ensures the backend sees key expiry
   changes even when the auth flow hasn't completed.

"First successful flow wins": if a key extension arrives via map poll,
the client recovers automatically. If the auth flow completes first,
that works too. Either way, the client is no longer stuck.

This aligns with the SeamlessKeyRenewal philosophy: maintain connectivity
paths while authentication proceeds, allowing server-initiated recovery.

Fixes #19326

Change-Id: I26dbbc1fa7c1159ba075362e44d02814355d6b44
Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-11 19:21:09 +01:00
..
auditlog all: use Go 1.26 things, run most gofix modernizers 2026-03-06 13:32:03 -08:00
conffile all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
desktop ipn/desktop: use runtime.Pinner to force heap-allocation of msg 2026-04-07 12:55:11 -05:00
ipnauth all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
ipnext net/routecheck: introduce new package for checking peer reachability (#19639) 2026-06-01 10:33:08 -07:00
ipnlocal control/controlclient: continue map poll during key expiry to receive extensions 2026-06-11 19:21:09 +01:00
ipnserver ipn/ipnserver: use peercreds for actor.Username on freebsd (for Taildrive) 2026-03-24 20:35:56 -07:00
ipnstate all: rename NetworkLock functions/types to TailnetLock 2026-06-08 13:14:28 +01:00
lapitest types/ptr: deprecate ptr.To, use Go 1.26 new 2026-03-05 20:13:18 -08:00
localapi ipn: add no-disconnect in-process bus subscribers 2026-06-09 12:51:38 -07:00
policy all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
store ipn/store: make WriteState(id, nil) delete key instead of adding nil entry (#19920) 2026-05-29 11:22:14 -07:00
backend_test.go ipn: add no-disconnect in-process bus subscribers 2026-06-09 12:51:38 -07:00
backend.go ipn: add no-disconnect in-process bus subscribers 2026-06-09 12:51:38 -07:00
conf_test.go ipn: reject advertised routes with non-address bits set (#18649) 2026-03-20 10:10:43 -07:00
conf.go ipn: fix the typo causing NoSNAT always set to true (#19110) 2026-03-24 16:41:58 -04:00
doc.go all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
ipn_clone.go tailcfg: reintroduce UserProfile.Groups 2026-03-09 11:08:45 +00:00
ipn_test.go all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
ipn_view.go tailcfg: reintroduce UserProfile.Groups 2026-03-09 11:08:45 +00:00
prefs_test.go ipn: improve --exit-node hostname error during startup 2026-05-28 16:43:45 +01:00
prefs.go ipn: improve --exit-node hostname error during startup 2026-05-28 16:43:45 +01:00
serve_expand_test.go all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
serve_test.go ipn,ipn/localapi: require local admin to serve Unix domain sockets 2026-06-03 09:45:02 -06:00
serve.go ipn,ipn/localapi: require local admin to serve Unix domain sockets 2026-06-03 09:45:02 -06:00
store_test.go all: remove AUTHORS file and references to it 2026-01-23 15:49:45 -08:00
store.go ipn/store: make WriteState(id, nil) delete key instead of adding nil entry (#19920) 2026-05-29 11:22:14 -07:00