From d7619d273b7e04c75c285a8f37ed39ef04eb76c5 Mon Sep 17 00:00:00 2001 From: Andrea Gottardo Date: Tue, 18 Jun 2024 22:34:50 -0700 Subject: [PATCH] health: fix nil DERPMap dereference panic Looks like a DERPmap might not be available when we try to get the name associated with a region ID, and that was causing an intermittent panic in CI. Fixes #12534 Change-Id: I4ace53681bf004df46c728cff830b27339254243 Signed-off-by: Andrea Gottardo --- health/health.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/health/health.go b/health/health.go index 5aa489843..c1740b1f1 100644 --- a/health/health.go +++ b/health/health.go @@ -685,6 +685,18 @@ func (t *Tracker) SetDERPMap(dm *tailcfg.DERPMap) { t.selfCheckLocked() } +// derpRegionNameLocked returns the name of the DERP region with the given ID +// or the empty string if unknown. +func (t *Tracker) derpRegionNameLocked(regID int) string { + if t.derpMap == nil { + return "" + } + if r, ok := t.derpMap.Regions[regID]; ok { + return r.RegionName + } + return "" +} + // state is an ipn.State.String() value: "Running", "Stopped", "NeedsLogin", etc. func (t *Tracker) SetIPNState(state string, wantRunning bool) { if t.nil() { @@ -928,13 +940,13 @@ func (t *Tracker) updateBuiltinWarnablesLocked() { } else if !t.derpRegionConnected[rid] { t.setUnhealthyLocked(noDERPConnectionWarnable, Args{ ArgDERPRegionID: fmt.Sprint(rid), - ArgDERPRegionName: t.derpMap.Regions[rid].RegionName, + ArgDERPRegionName: t.derpRegionNameLocked(rid), }) return } else if d := now.Sub(t.derpRegionLastFrame[rid]).Round(time.Second); d > tooIdle { t.setUnhealthyLocked(derpTimeoutWarnable, Args{ ArgDERPRegionID: fmt.Sprint(rid), - ArgDERPRegionName: t.derpMap.Regions[rid].RegionName, + ArgDERPRegionName: t.derpRegionNameLocked(rid), ArgDuration: d.String(), }) return