Browse Source

wgengine/magicsock,net/sockopts: export Windows ICMP suppression logic (#16917)

For eventual use by net/udprelay.Server.

Updates tailscale/corp#31506

Signed-off-by: Jordan Whited <[email protected]>
Jordan Whited 6 months ago
parent
commit
b17cfe4aed

+ 1 - 1
cmd/k8s-operator/depaware.txt

@@ -867,7 +867,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
         tailscale.com/net/portmapper                                 from tailscale.com/ipn/localapi+
         tailscale.com/net/proxymux                                   from tailscale.com/tsnet
         tailscale.com/net/routetable                                 from tailscale.com/doctor/routetable
-        tailscale.com/net/sockopts                                   from tailscale.com/wgengine/magicsock
+     💣 tailscale.com/net/sockopts                                   from tailscale.com/wgengine/magicsock
         tailscale.com/net/socks5                                     from tailscale.com/tsnet
         tailscale.com/net/sockstats                                  from tailscale.com/control/controlclient+
         tailscale.com/net/stun                                       from tailscale.com/ipn/localapi+

+ 1 - 1
cmd/tailscaled/depaware.txt

@@ -339,7 +339,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
         tailscale.com/net/portmapper                                 from tailscale.com/ipn/localapi+
         tailscale.com/net/proxymux                                   from tailscale.com/cmd/tailscaled
         tailscale.com/net/routetable                                 from tailscale.com/doctor/routetable
-        tailscale.com/net/sockopts                                   from tailscale.com/wgengine/magicsock+
+     💣 tailscale.com/net/sockopts                                   from tailscale.com/wgengine/magicsock+
         tailscale.com/net/socks5                                     from tailscale.com/cmd/tailscaled
         tailscale.com/net/sockstats                                  from tailscale.com/control/controlclient+
         tailscale.com/net/stun                                       from tailscale.com/ipn/localapi+

+ 1 - 1
cmd/tsidp/depaware.txt

@@ -297,7 +297,7 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
         tailscale.com/net/portmapper                                 from tailscale.com/ipn/localapi+
         tailscale.com/net/proxymux                                   from tailscale.com/tsnet
         tailscale.com/net/routetable                                 from tailscale.com/doctor/routetable
-        tailscale.com/net/sockopts                                   from tailscale.com/wgengine/magicsock
+     💣 tailscale.com/net/sockopts                                   from tailscale.com/wgengine/magicsock
         tailscale.com/net/socks5                                     from tailscale.com/tsnet
         tailscale.com/net/sockstats                                  from tailscale.com/control/controlclient+
         tailscale.com/net/stun                                       from tailscale.com/ipn/localapi+

+ 5 - 3
wgengine/magicsock/magicsock_notwindows.go → net/sockopts/sockopts_notwindows.go

@@ -3,11 +3,13 @@
 
 //go:build !windows
 
-package magicsock
+package sockopts
 
 import (
-	"tailscale.com/types/logger"
 	"tailscale.com/types/nettype"
 )
 
-func trySetUDPSocketOptions(pconn nettype.PacketConn, logf logger.Logf) {}
+// SetICMPErrImmunity is no-op on non-Windows.
+func SetICMPErrImmunity(pconn nettype.PacketConn) error {
+	return nil
+}

+ 12 - 8
wgengine/magicsock/magicsock_windows.go → net/sockopts/sockopts_windows.go

@@ -3,28 +3,31 @@
 
 //go:build windows
 
-package magicsock
+package sockopts
 
 import (
+	"fmt"
 	"net"
 	"unsafe"
 
 	"golang.org/x/sys/windows"
-	"tailscale.com/types/logger"
 	"tailscale.com/types/nettype"
 )
 
-func trySetUDPSocketOptions(pconn nettype.PacketConn, logf logger.Logf) {
+// SetICMPErrImmunity sets socket options on pconn to prevent ICMP reception,
+// e.g. ICMP Port Unreachable, from surfacing as a syscall error.
+//
+// If pconn is not a [*net.UDPConn], then SetICMPErrImmunity is no-op.
+func SetICMPErrImmunity(pconn nettype.PacketConn) error {
 	c, ok := pconn.(*net.UDPConn)
 	if !ok {
 		// not a UDP connection; nothing to do
-		return
+		return nil
 	}
 
 	sysConn, err := c.SyscallConn()
 	if err != nil {
-		logf("trySetUDPSocketOptions: getting SyscallConn failed: %v", err)
-		return
+		return fmt.Errorf("SetICMPErrImmunity: getting SyscallConn failed: %v", err)
 	}
 
 	// Similar to https://github.com/golang/go/issues/5834 (which involved
@@ -50,9 +53,10 @@ func trySetUDPSocketOptions(pconn nettype.PacketConn, logf logger.Logf) {
 		)
 	})
 	if ioctlErr != nil {
-		logf("trySetUDPSocketOptions: could not set SIO_UDP_NETRESET: %v", ioctlErr)
+		return fmt.Errorf("SetICMPErrImmunity: could not set SIO_UDP_NETRESET: %v", ioctlErr)
 	}
 	if err != nil {
-		logf("trySetUDPSocketOptions: SyscallConn.Control failed: %v", err)
+		return fmt.Errorf("SetICMPErrImmunity: SyscallConn.Control failed: %v", err)
 	}
+	return nil
 }

+ 1 - 1
tsnet/depaware.txt

@@ -293,7 +293,7 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
         tailscale.com/net/portmapper                                 from tailscale.com/ipn/localapi+
         tailscale.com/net/proxymux                                   from tailscale.com/tsnet
         tailscale.com/net/routetable                                 from tailscale.com/doctor/routetable
-        tailscale.com/net/sockopts                                   from tailscale.com/wgengine/magicsock
+     💣 tailscale.com/net/sockopts                                   from tailscale.com/wgengine/magicsock
         tailscale.com/net/socks5                                     from tailscale.com/tsnet
         tailscale.com/net/sockstats                                  from tailscale.com/control/controlclient+
         tailscale.com/net/stun                                       from tailscale.com/ipn/localapi+

+ 6 - 6
wgengine/magicsock/magicsock.go

@@ -3537,7 +3537,6 @@ func (c *Conn) bindSocket(ruc *RebindingUDPConn, network string, curPortFate cur
 				}
 			}
 		}
-		trySetSocketBuffer(pconn, c.logf)
 		trySetUDPSocketOptions(pconn, c.logf)
 
 		// Success.
@@ -3858,11 +3857,7 @@ func (c *Conn) DebugForcePreferDERP(n int) {
 	c.netChecker.SetForcePreferredDERP(n)
 }
 
-// trySetSocketBuffer attempts to set SO_SNDBUFFORCE and SO_RECVBUFFORCE which
-// can overcome the limit of net.core.{r,w}mem_max, but require CAP_NET_ADMIN.
-// It falls back to the portable implementation if that fails, which may be
-// silently capped to net.core.{r,w}mem_max.
-func trySetSocketBuffer(pconn nettype.PacketConn, logf logger.Logf) {
+func trySetUDPSocketOptions(pconn nettype.PacketConn, logf logger.Logf) {
 	directions := []sockopts.BufferDirection{sockopts.ReadDirection, sockopts.WriteDirection}
 	for _, direction := range directions {
 		forceErr, portableErr := sockopts.SetBufferSize(pconn, direction, socketBufferSize)
@@ -3873,6 +3868,11 @@ func trySetSocketBuffer(pconn nettype.PacketConn, logf logger.Logf) {
 			logf("magicsock: failed to set UDP %v buffer size to %d: %v", direction, socketBufferSize, portableErr)
 		}
 	}
+
+	err := sockopts.SetICMPErrImmunity(pconn)
+	if err != nil {
+		logf("magicsock: %v", err)
+	}
 }
 
 // derpStr replaces DERP IPs in s with "derp-".