Просмотр исходного кода

health: track whether we have a functional udp4 bind

Suggested-by: Brad Fitzpatrick <[email protected]>
Signed-off-by: Josh Bleecher Snyder <[email protected]>
Josh Bleecher Snyder 4 лет назад
Родитель
Сommit
fe50ded95c
2 измененных файлов с 19 добавлено и 1 удалено
  1. 13 1
      health/health.go
  2. 6 0
      wgengine/magicsock/magicsock.go

+ 13 - 1
health/health.go

@@ -37,6 +37,7 @@ var (
 	ipnState                string
 	ipnWantRunning          bool
 	anyInterfaceUp          = true // until told otherwise
+	udp4Unbound             bool
 )
 
 // Subsystem is the name of a subsystem whose health can be monitored.
@@ -47,7 +48,7 @@ const (
 	// the system, rather than one particular subsystem.
 	SysOverall = Subsystem("overall")
 
-	// SysRouter is the name the wgengine/router subsystem.
+	// SysRouter is the name of the wgengine/router subsystem.
 	SysRouter = Subsystem("router")
 
 	// SysDNS is the name of the net/dns subsystem.
@@ -214,6 +215,14 @@ func SetAnyInterfaceUp(up bool) {
 	selfCheckLocked()
 }
 
+// SetUDP4Unbound sets whether the udp4 bind failed completely.
+func SetUDP4Unbound(unbound bool) {
+	mu.Lock()
+	defer mu.Unlock()
+	udp4Unbound = unbound
+	selfCheckLocked()
+}
+
 func timerSelfCheck() {
 	mu.Lock()
 	defer mu.Unlock()
@@ -257,6 +266,9 @@ func overallErrorLocked() error {
 	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")
+	}
 
 	// TODO: use
 	_ = inMapPollSince

+ 6 - 0
wgengine/magicsock/magicsock.go

@@ -2671,6 +2671,9 @@ func (c *Conn) bindSocket(rucPtr **RebindingUDPConn, network string) error {
 		}
 		// Success.
 		ruc.pconn = pconn
+		if network == "udp4" {
+			health.SetUDP4Unbound(false)
+		}
 		return nil
 	}
 
@@ -2679,6 +2682,9 @@ func (c *Conn) bindSocket(rucPtr **RebindingUDPConn, network string) error {
 	// This keeps the receive funcs alive for a future in which
 	// we get a link change and we can try binding again.
 	ruc.pconn = newBlockForeverConn()
+	if network == "udp4" {
+		health.SetUDP4Unbound(true)
+	}
 	return fmt.Errorf("failed to bind any ports (tried %v)", ports)
 }