mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-13 06:07:34 +00:00
ipn/ipnlocal: handle more edge cases in netmap expiry timer
We now handle the case where the NetworkMap.SelfNode has already expired and do not return an expiry time in the past (which causes an ~infinite loop of timers to fire). Additionally, we now add an explicit check to ensure that the next expiry time is never before the current local-to-the-system time, to ensure that we don't end up in a similar situation due to clock skew. Finally, we add more tests for this logic to ensure that we don't regress on these edge cases. Fixes #7193 Change-Id: Iaf8e3d83be1d133a7aab7f8d62939e508cc53f9c Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
This commit is contained in:
@@ -830,7 +830,8 @@ func (b *LocalBackend) setClientStatus(st controlclient.Status) {
|
||||
|
||||
// Handle node expiry in the netmap
|
||||
if st.NetMap != nil {
|
||||
b.em.flagExpiredPeers(st.NetMap)
|
||||
now := time.Now()
|
||||
b.em.flagExpiredPeers(st.NetMap, now)
|
||||
|
||||
// Always stop the existing netmap timer if we have a netmap;
|
||||
// it's possible that we have no nodes expiring, so we should
|
||||
@@ -844,31 +845,9 @@ func (b *LocalBackend) setClientStatus(st controlclient.Status) {
|
||||
b.nmExpiryTimer = nil
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
// Figure out when the next node in the netmap is expiring so we can
|
||||
// start a timer to reconfigure at that point.
|
||||
var nextExpiry time.Time // zero if none
|
||||
for _, peer := range st.NetMap.Peers {
|
||||
if peer.KeyExpiry.IsZero() {
|
||||
continue // tagged node
|
||||
} else if peer.Expired {
|
||||
// Peer already expired; Expired is set by the
|
||||
// flagExpiredPeers function, above.
|
||||
continue
|
||||
}
|
||||
if nextExpiry.IsZero() || peer.KeyExpiry.Before(nextExpiry) {
|
||||
nextExpiry = peer.KeyExpiry
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that we also fire this timer if our own node key expires.
|
||||
if st.NetMap.SelfNode != nil {
|
||||
if selfExpiry := st.NetMap.SelfNode.KeyExpiry; !selfExpiry.IsZero() && selfExpiry.Before(nextExpiry) {
|
||||
nextExpiry = selfExpiry
|
||||
}
|
||||
}
|
||||
|
||||
nextExpiry := b.em.nextPeerExpiry(st.NetMap, now)
|
||||
if !nextExpiry.IsZero() {
|
||||
tmrDuration := nextExpiry.Sub(now) + 10*time.Second
|
||||
b.nmExpiryTimer = time.AfterFunc(tmrDuration, func() {
|
||||
|
Reference in New Issue
Block a user