Browse Source

wgengine/magicsock: always run ReceiveIPv6

One of the consequences of the 	bind refactoring in 6f23087175
is that attempting to bind an IPv6 socket will always
result in c.pconn6.pconn being non-nil.
If the bind fails, it'll be set to a placeholder packet conn
that blocks forever.

As a result, we can always run ReceiveIPv6 and health check it.
This removes IPv4/IPv6 asymmetry and also will allow health checks
to detect any IPv6 receive func failures.

Signed-off-by: Josh Bleecher Snyder <[email protected]>
Josh Bleecher Snyder 4 years ago
parent
commit
9d542e08e2
2 changed files with 6 additions and 9 deletions
  1. 2 2
      health/health.go
  2. 4 7
      wgengine/magicsock/magicsock.go

+ 2 - 2
health/health.go

@@ -297,10 +297,10 @@ func overallErrorLocked() error {
 
 var (
 	ReceiveIPv4 = ReceiveFuncStats{name: "ReceiveIPv4"}
-	// ReceiveIPv6 isn't guaranteed to be running, so skip it for now.
+	ReceiveIPv6 = ReceiveFuncStats{name: "ReceiveIPv6"}
 	ReceiveDERP = ReceiveFuncStats{name: "ReceiveDERP"}
 
-	receiveFuncs = []*ReceiveFuncStats{&ReceiveIPv4, &ReceiveDERP}
+	receiveFuncs = []*ReceiveFuncStats{&ReceiveIPv4, &ReceiveIPv6, &ReceiveDERP}
 )
 
 // ReceiveFuncStats tracks the calls made to a wireguard-go receive func.

+ 4 - 7
wgengine/magicsock/magicsock.go

@@ -1578,6 +1578,8 @@ func (c *Conn) noteRecvActivityFromEndpoint(e conn.Endpoint) {
 
 // receiveIPv6 receives a UDP IPv6 packet. It is called by wireguard-go.
 func (c *Conn) receiveIPv6(b []byte) (int, conn.Endpoint, error) {
+	health.ReceiveIPv6.Enter()
+	defer health.ReceiveIPv6.Exit()
 	for {
 		n, ipp, err := c.pconn6.ReadFromNetaddr(b)
 		if err != nil {
@@ -2411,10 +2413,7 @@ func (c *connBind) Open(ignoredPort uint16) ([]conn.ReceiveFunc, uint16, error)
 		return nil, 0, errors.New("magicsock: connBind already open")
 	}
 	c.closed = false
-	fns := []conn.ReceiveFunc{c.receiveIPv4, c.receiveDERP}
-	if c.pconn6 != nil {
-		fns = append(fns, c.receiveIPv6)
-	}
+	fns := []conn.ReceiveFunc{c.receiveIPv4, c.receiveIPv6, c.receiveDERP}
 	// TODO: Combine receiveIPv4 and receiveIPv6 and receiveIP into a single
 	// closure that closes over a *RebindingUDPConn?
 	return fns, c.LocalPort(), nil
@@ -2436,9 +2435,7 @@ func (c *connBind) Close() error {
 	c.closed = true
 	// Unblock all outstanding receives.
 	c.pconn4.Close()
-	if c.pconn6 != nil {
-		c.pconn6.Close()
-	}
+	c.pconn6.Close()
 	// Send an empty read result to unblock receiveDERP,
 	// which will then check connBind.Closed.
 	c.derpRecvCh <- derpReadResult{}