summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorClaire Wang <claire@tailscale.com>2024-01-22 11:40:25 -0500
committerClaire Wang <claire@tailscale.com>2024-01-22 11:40:25 -0500
commitf3da16b06aea9296cf6f1c2c9e0896243c2d4c42 (patch)
tree561ff97b7d9800408ba007a9b44316ac5a996229
parente92cb93ba7b5b008ea71b193f961bb8eab6bc7ee (diff)
downloadtailscale-clairew/receive-icmp-errors.tar.xz
tailscale-clairew/receive-icmp-errors.zip
-rw-r--r--wgengine/magicsock/magicsock.go4
-rw-r--r--wgengine/magicsock/magicsock_default.go2
-rw-r--r--wgengine/magicsock/magicsock_linux.go19
3 files changed, 24 insertions, 1 deletions
diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go
index fc97722f0..4c8ad03b5 100644
--- a/wgengine/magicsock/magicsock.go
+++ b/wgengine/magicsock/magicsock.go
@@ -2380,7 +2380,9 @@ func (c *Conn) bindSocket(ruc *RebindingUDPConn, network string, curPortFate cur
}
}
trySetSocketBuffer(pconn, c.logf)
-
+ if c.peerMTUEnabled.Load() {
+ trySetIPRECEVRR(pconn, c.logf)
+ }
// Success.
if debugBindSocket() {
c.logf("magicsock: bindSocket: successfully listened %v port %d", network, port)
diff --git a/wgengine/magicsock/magicsock_default.go b/wgengine/magicsock/magicsock_default.go
index 87075e522..9f3a249b3 100644
--- a/wgengine/magicsock/magicsock_default.go
+++ b/wgengine/magicsock/magicsock_default.go
@@ -31,6 +31,8 @@ func getGSOSizeFromControl(control []byte) (int, error) {
func setGSOSizeInControl(control *[]byte, gso uint16) {}
+func trySetIPRECEVRR(pconn nettype.PacketConn, logf logger.Logf) {}
+
const (
controlMessageSize = 0
)
diff --git a/wgengine/magicsock/magicsock_linux.go b/wgengine/magicsock/magicsock_linux.go
index c484f77c0..81c496e4a 100644
--- a/wgengine/magicsock/magicsock_linux.go
+++ b/wgengine/magicsock/magicsock_linux.go
@@ -318,6 +318,25 @@ func trySetSocketBuffer(pconn nettype.PacketConn, logf logger.Logf) {
}
}
+// 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 trySetIPRECEVRR(pconn nettype.PacketConn, logf logger.Logf) {
+ if c, ok := pconn.(*net.UDPConn); ok {
+ var errRcv error
+ rc, err := c.SyscallConn()
+ if err == nil {
+ rc.Control(func(fd uintptr) {
+ err = syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_RECVERR, 1)
+ if errRcv != nil {
+ logf("magicsock: [warning] failed to enable IP_RECVERR: %v", errRcv)
+ }
+ })
+ }
+ }
+}
+
// tryEnableUDPOffload attempts to enable the UDP_GRO socket option on pconn,
// and returns two booleans indicating TX and RX UDP offload support.
func tryEnableUDPOffload(pconn nettype.PacketConn) (hasTX bool, hasRX bool) {