Revert "control/controlclient: continue map poll during key expiry to receive extensions" (#20257)

* Revert "control/controlclient: continue map poll during key expiry to receive extensions"

This reverts commit 6a822dcc36. This commit
has caused test failures in the corp repo by unexpected changing the login
behaviour when nodes have a valid node key.

Updates tailscale/corp#43705
Updates #19326

Signed-off-by: Alex Chan <alexc@tailscale.com>

* Revert "tsnet: test key extension after server restart"

This reverts commit 317201375f. This test
relies on changes in 317201375f, which is
also being reverted because it causes test failures in corp.

Updates tailscale/corp#43705
Updates #19326

Signed-off-by: Alex Chan <alexc@tailscale.com>

---------

Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit is contained in:
Alex Chan
2026-06-25 15:24:12 -07:00
committed by GitHub
parent 6e1de5b651
commit 9169b206be
4 changed files with 12 additions and 772 deletions
+12 -42
View File
@@ -472,15 +472,16 @@ func (mrs mapRoutineState) UpdateFullNetmap(nm *netmap.NetworkMap) {
c.mu.Lock()
c.inMapPoll = true
c.expiry = nm.SelfKeyExpiry()
c.logf("[v1] mapRoutine: netmap received: loggedIn=%v inMapPoll=true", c.loggedIn)
stillAuthed := c.loggedIn
c.logf("[v1] mapRoutine: netmap received: loggedIn=%v inMapPoll=true", stillAuthed)
// Reset the backoff timer if we got a netmap.
mrs.bo.Reset()
c.mu.Unlock()
// Always send status - sendStatus will check if we should forward the netmap
// based on loggedIn, hasNodeKey, and inMapPoll.
c.sendStatus("mapRoutine-got-netmap", nil, "", nm)
if stillAuthed {
c.sendStatus("mapRoutine-got-netmap", nil, "", nm)
}
}
func (mrs mapRoutineState) UpdateNetmapDelta(muts []netmap.NodeMutation) bool {
@@ -613,16 +614,10 @@ func (c *Auto) mapRoutine() {
c.mu.Lock()
loggedIn := c.loggedIn
c.logf("[v1] mapRoutine: loggedIn=%v", loggedIn)
ctx := c.mapCtx
c.mu.Unlock()
// Check if we have a valid node key that could receive updates.
// Even if !loggedIn (e.g., key expired, waiting for interactive auth),
// we should still poll if we have credentials, because the server
// might send us a key extension notification.
_, hasNodeKey := c.direct.GetPersist().PublicNodeKeyOK()
c.logf("[v1] mapRoutine: loggedIn=%v hasNodeKey=%v", loggedIn, hasNodeKey)
report := func(err error, msg string) {
c.logf("[v1] %s: %v", msg, err)
err = fmt.Errorf("%s: %w", msg, err)
@@ -633,8 +628,8 @@ func (c *Auto) mapRoutine() {
}
}
if !loggedIn && !hasNodeKey {
// No credentials at all, wait for auth to complete.
if !loggedIn {
// Wait for something interesting to happen
c.mu.Lock()
c.inMapPoll = false
c.mu.Unlock()
@@ -725,17 +720,14 @@ func (c *Auto) sendStatus(who string, err error, url string, nm *netmap.NetworkM
loginGoal := c.loginGoal
c.mu.Unlock()
// Check if we have a valid node key - if so, we should forward the netmap
// even if !loggedIn, to allow the backend to see key expiry changes.
_, hasNodeKey := c.direct.GetPersist().PublicNodeKeyOK()
c.logf("[v1] sendStatus: %s: loggedIn=%v inMapPoll=%v hasNodeKey=%v", who, loggedIn, inMapPoll, hasNodeKey)
c.logf("[v1] sendStatus: %s: loggedIn=%v inMapPoll=%v", who, loggedIn, inMapPoll)
var p persist.PersistView
if nm != nil && (loggedIn || hasNodeKey) && inMapPoll {
if nm != nil && loggedIn && inMapPoll {
p = c.direct.GetPersist()
} else {
// don't send netmap status, as it's misleading when we're
// not logged in and have no credentials.
// not logged in.
nm = nil
}
newSt := &Status{
@@ -850,29 +842,7 @@ func (c *Auto) Login(flags LoginFlags) {
c.loginGoal = &LoginGoal{
flags: flags,
}
// If we have valid credentials (loggedIn=true) or a valid node key,
// don't cancel the map poll. This allows the client to continue receiving
// key extension notifications from the server while the auth flow proceeds
// in parallel.
//
// This is important for the "Extend key" feature: if the admin extends a
// key while the user has clicked "Login", we want the map poll to receive
// that notification and recover without requiring the user to complete the
// auth flow.
//
// The hasNodeKey check handles the case where a tsnet server restarts with
// an expired key: loggedIn is false (server returned AuthURL), but we have
// a valid node key that can still receive map updates including key extensions.
//
// "First successful flow wins": if a key extension arrives via map poll,
// the client recovers. If the auth flow completes first, that works too.
var hasNodeKey bool
if c.direct != nil {
_, hasNodeKey = c.direct.GetPersist().PublicNodeKeyOK()
}
if !c.loggedIn && !hasNodeKey {
c.cancelMapCtxLocked()
}
c.cancelMapCtxLocked()
c.cancelAuthCtxLocked()
}