ipn/ipnlocal: discard cached netmaps upon panic during SetNetworkMap (#19414)

For debugging purposes, unstable builds will sometimes intentionally panic for
unexpected behaviours. We observed such a panic after loading a cached netmap,
but because we had a valid cached map, the client was unable to recover on its
own and the operator had to manually reset the cache.

As a defensive hedge, when netmap caching is enabled, check for a panic during
installation of a net network map: If one occurs, discard any cached netmaps
before letting the panic unwind, so that we do not lose the panic itself, but
reduce the need for manual intervention.

Updates #12639
Updates tailscale/corp#27300

Change-Id: I0436889c6bdc2fa728c9cb83630cd7b00a72ce68
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This commit is contained in:
M. J. Fromberger 2026-04-15 11:07:42 -07:00 committed by GitHub
parent 958bcda5bf
commit 1e4934659b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -6402,6 +6402,23 @@ func (b *LocalBackend) resolveExitNodeInPrefsLocked(prefs *ipn.Prefs) (changed b
// received nm. If nm is nil, it resets all configuration as though
// Tailscale is turned off.
func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) {
if buildfeatures.HasCacheNetMap {
// As a defensive measure, if something triggers a panic when we are
// installing a network map, make an effort to discard any cached netmaps.
// This helps avert the possibility that a restart after panic will stick in
// a cycle. Importantly, we do not attempt to swallow or handle the panic,
// since that indicates a real bug.
//
// See https://github.com/tailscale/tailscale/issues/12639
defer func() {
if p := recover(); p != nil {
b.logf("WARNING: Panic while installing netmap; discardng caches")
b.discardDiskCacheLocked()
panic(p) // propagate
}
}()
}
oldSelf := b.currentNode().NetMap().SelfNodeOrZero()
b.dialer.SetNetMap(nm)