Browse Source

health: don't report a warning in DERP homeless mode

Updates #3363
Updates tailscale/corp#396

Change-Id: Ibfb0496821cb58a78399feb88d4206d81e95ca0f
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 2 years ago
parent
commit
4d196c12d9
2 changed files with 20 additions and 12 deletions
  1. 17 10
      health/health.go
  2. 3 2
      wgengine/magicsock/derp.go

+ 17 - 10
health/health.go

@@ -37,6 +37,7 @@ var (
 	lastMapPollEndedAt      time.Time
 	lastStreamedMapResponse time.Time
 	derpHomeRegion          int
+	derpHomeless            bool
 	derpRegionConnected     = map[int]bool{}
 	derpRegionHealthProblem = map[int]string{}
 	derpRegionLastFrame     = map[int]time.Time{}
@@ -315,10 +316,14 @@ func GetInPollNetMap() bool {
 }
 
 // SetMagicSockDERPHome notes what magicsock's view of its home DERP is.
-func SetMagicSockDERPHome(region int) {
+//
+// The homeless parameter is whether magicsock is running in DERP-disconnected
+// mode, without discovering and maintaining a connection to its home DERP.
+func SetMagicSockDERPHome(region int, homeless bool) {
 	mu.Lock()
 	defer mu.Unlock()
 	derpHomeRegion = region
+	derpHomeless = homeless
 	selfCheckLocked()
 }
 
@@ -447,15 +452,17 @@ func overallErrorLocked() error {
 	if d := now.Sub(lastStreamedMapResponse).Round(time.Second); d > tooIdle {
 		return fmt.Errorf("no map response in %v", d)
 	}
-	rid := derpHomeRegion
-	if rid == 0 {
-		return errors.New("no DERP home")
-	}
-	if !derpRegionConnected[rid] {
-		return fmt.Errorf("not connected to home DERP region %v", rid)
-	}
-	if d := now.Sub(derpRegionLastFrame[rid]).Round(time.Second); d > tooIdle {
-		return fmt.Errorf("haven't heard from home DERP region %v in %v", rid, d)
+	if !derpHomeless {
+		rid := derpHomeRegion
+		if rid == 0 {
+			return errors.New("no DERP home")
+		}
+		if !derpRegionConnected[rid] {
+			return fmt.Errorf("not connected to home DERP region %v", rid)
+		}
+		if d := now.Sub(derpRegionLastFrame[rid]).Round(time.Second); d > tooIdle {
+			return fmt.Errorf("haven't heard from home DERP region %v in %v", rid, d)
+		}
 	}
 	if udp4Unbound {
 		return errors.New("no udp4 bind")

+ 3 - 2
wgengine/magicsock/derp.go

@@ -141,11 +141,12 @@ func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) {
 	defer c.mu.Unlock()
 	if !c.wantDerpLocked() {
 		c.myDerp = 0
-		health.SetMagicSockDERPHome(0)
+		health.SetMagicSockDERPHome(0, c.homeless)
 		return false
 	}
 	if c.homeless {
 		c.myDerp = 0
+		health.SetMagicSockDERPHome(0, c.homeless)
 		return false
 	}
 	if derpNum == c.myDerp {
@@ -156,7 +157,7 @@ func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) {
 		metricDERPHomeChange.Add(1)
 	}
 	c.myDerp = derpNum
-	health.SetMagicSockDERPHome(derpNum)
+	health.SetMagicSockDERPHome(derpNum, c.homeless)
 
 	if c.privateKey.IsZero() {
 		// No private key yet, so DERP connections won't come up anyway.