]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
conn: separate gso and sticky control
authorJason A. Donenfeld <Jason@zx2c4.com>
Sat, 21 Oct 2023 16:41:27 +0000 (18:41 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Sat, 21 Oct 2023 16:44:01 +0000 (18:44 +0200)
Android wants GSO but not sticky.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
conn/bind_std.go
conn/gso_default.go [new file with mode: 0644]
conn/gso_linux.go [new file with mode: 0644]
conn/sticky_default.go [moved from conn/control_default.go with 72% similarity]
conn/sticky_linux.go [moved from conn/control_linux.go with 66% similarity]
conn/sticky_linux_test.go [moved from conn/control_linux_test.go with 96% similarity]

index 5a00f34b36966d3589cb1bae563504f2c657250b..e1bcbd13202091d911aaaa3d4fff117adf25f0ac 100644 (file)
@@ -65,7 +65,7 @@ func NewStdNetBind() Bind {
                                msgs := make([]ipv6.Message, IdealBatchSize)
                                for i := range msgs {
                                        msgs[i].Buffers = make(net.Buffers, 1)
-                                       msgs[i].OOB = make([]byte, controlSize)
+                                       msgs[i].OOB = make([]byte, stickyControlSize+gsoControlSize)
                                }
                                return &msgs
                        },
diff --git a/conn/gso_default.go b/conn/gso_default.go
new file mode 100644 (file)
index 0000000..57780db
--- /dev/null
@@ -0,0 +1,21 @@
+//go:build !linux
+
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
+ */
+
+package conn
+
+// getGSOSize parses control for UDP_GRO and if found returns its GSO size data.
+func getGSOSize(control []byte) (int, error) {
+       return 0, nil
+}
+
+// setGSOSize sets a UDP_SEGMENT in control based on gsoSize.
+func setGSOSize(control *[]byte, gsoSize uint16) {
+}
+
+// gsoControlSize returns the recommended buffer size for pooling sticky and UDP
+// offloading control data.
+const gsoControlSize = 0
diff --git a/conn/gso_linux.go b/conn/gso_linux.go
new file mode 100644 (file)
index 0000000..b8599ce
--- /dev/null
@@ -0,0 +1,65 @@
+//go:build linux
+
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
+ */
+
+package conn
+
+import (
+       "fmt"
+       "unsafe"
+
+       "golang.org/x/sys/unix"
+)
+
+const (
+       sizeOfGSOData = 2
+)
+
+// getGSOSize parses control for UDP_GRO and if found returns its GSO size data.
+func getGSOSize(control []byte) (int, error) {
+       var (
+               hdr  unix.Cmsghdr
+               data []byte
+               rem  = control
+               err  error
+       )
+
+       for len(rem) > unix.SizeofCmsghdr {
+               hdr, data, rem, err = unix.ParseOneSocketControlMessage(rem)
+               if err != nil {
+                       return 0, fmt.Errorf("error parsing socket control message: %w", err)
+               }
+               if hdr.Level == unix.SOL_UDP && hdr.Type == unix.UDP_GRO && len(data) >= sizeOfGSOData {
+                       var gso uint16
+                       copy(unsafe.Slice((*byte)(unsafe.Pointer(&gso)), sizeOfGSOData), data[:sizeOfGSOData])
+                       return int(gso), nil
+               }
+       }
+       return 0, nil
+}
+
+// setGSOSize sets a UDP_SEGMENT in control based on gsoSize. It leaves existing
+// data in control untouched.
+func setGSOSize(control *[]byte, gsoSize uint16) {
+       existingLen := len(*control)
+       avail := cap(*control) - existingLen
+       space := unix.CmsgSpace(sizeOfGSOData)
+       if avail < space {
+               return
+       }
+       *control = (*control)[:cap(*control)]
+       gsoControl := (*control)[existingLen:]
+       hdr := (*unix.Cmsghdr)(unsafe.Pointer(&(gsoControl)[0]))
+       hdr.Level = unix.SOL_UDP
+       hdr.Type = unix.UDP_SEGMENT
+       hdr.SetLen(unix.CmsgLen(sizeOfGSOData))
+       copy((gsoControl)[unix.SizeofCmsghdr:], unsafe.Slice((*byte)(unsafe.Pointer(&gsoSize)), sizeOfGSOData))
+       *control = (*control)[:existingLen+space]
+}
+
+// gsoControlSize returns the recommended buffer size for pooling UDP
+// offloading control data.
+var gsoControlSize = unix.CmsgSpace(sizeOfGSOData)
similarity index 72%
rename from conn/control_default.go
rename to conn/sticky_default.go
index 9459da555067546e13040dded1d0139118cc441c..0b213867d7a682a222d7d2b845d355d75c6f1a6a 100644 (file)
@@ -35,17 +35,8 @@ func getSrcFromControl(control []byte, ep *StdNetEndpoint) {
 func setSrcControl(control *[]byte, ep *StdNetEndpoint) {
 }
 
-// getGSOSize parses control for UDP_GRO and if found returns its GSO size data.
-func getGSOSize(control []byte) (int, error) {
-       return 0, nil
-}
-
-// setGSOSize sets a UDP_SEGMENT in control based on gsoSize.
-func setGSOSize(control *[]byte, gsoSize uint16) {
-}
-
-// controlSize returns the recommended buffer size for pooling sticky and UDP
+// stickyControlSize returns the recommended buffer size for pooling sticky
 // offloading control data.
-const controlSize = 0
+const stickyControlSize = 0
 
 const StdNetSupportsStickySockets = false
similarity index 66%
rename from conn/control_linux.go
rename to conn/sticky_linux.go
index 44a94e67091e9edb68d1f65d30074f49f4db6d81..8e206e90b26a777ff4f12cae9b13744df33c5df3 100644 (file)
@@ -8,7 +8,6 @@
 package conn
 
 import (
-       "fmt"
        "net/netip"
        "unsafe"
 
@@ -106,54 +105,8 @@ func setSrcControl(control *[]byte, ep *StdNetEndpoint) {
        *control = append(*control, ep.src...)
 }
 
-const (
-       sizeOfGSOData = 2
-)
-
-// getGSOSize parses control for UDP_GRO and if found returns its GSO size data.
-func getGSOSize(control []byte) (int, error) {
-       var (
-               hdr  unix.Cmsghdr
-               data []byte
-               rem  = control
-               err  error
-       )
-
-       for len(rem) > unix.SizeofCmsghdr {
-               hdr, data, rem, err = unix.ParseOneSocketControlMessage(rem)
-               if err != nil {
-                       return 0, fmt.Errorf("error parsing socket control message: %w", err)
-               }
-               if hdr.Level == unix.SOL_UDP && hdr.Type == unix.UDP_GRO && len(data) >= sizeOfGSOData {
-                       var gso uint16
-                       copy(unsafe.Slice((*byte)(unsafe.Pointer(&gso)), sizeOfGSOData), data[:sizeOfGSOData])
-                       return int(gso), nil
-               }
-       }
-       return 0, nil
-}
-
-// setGSOSize sets a UDP_SEGMENT in control based on gsoSize. It leaves existing
-// data in control untouched.
-func setGSOSize(control *[]byte, gsoSize uint16) {
-       existingLen := len(*control)
-       avail := cap(*control) - existingLen
-       space := unix.CmsgSpace(sizeOfGSOData)
-       if avail < space {
-               return
-       }
-       *control = (*control)[:cap(*control)]
-       gsoControl := (*control)[existingLen:]
-       hdr := (*unix.Cmsghdr)(unsafe.Pointer(&(gsoControl)[0]))
-       hdr.Level = unix.SOL_UDP
-       hdr.Type = unix.UDP_SEGMENT
-       hdr.SetLen(unix.CmsgLen(sizeOfGSOData))
-       copy((gsoControl)[unix.SizeofCmsghdr:], unsafe.Slice((*byte)(unsafe.Pointer(&gsoSize)), sizeOfGSOData))
-       *control = (*control)[:existingLen+space]
-}
-
-// controlSize returns the recommended buffer size for pooling sticky and UDP
+// stickyControlSize returns the recommended buffer size for pooling sticky
 // offloading control data.
-var controlSize = unix.CmsgSpace(unix.SizeofInet6Pktinfo) + unix.CmsgSpace(sizeOfGSOData)
+var stickyControlSize = unix.CmsgSpace(unix.SizeofInet6Pktinfo)
 
 const StdNetSupportsStickySockets = true
similarity index 96%
rename from conn/control_linux_test.go
rename to conn/sticky_linux_test.go
index 96f9da2e004c816598076a367f8f460101b360e2..d2bd58436ade3a08ebd50da64f89819ca4b7f8f1 100644 (file)
@@ -60,7 +60,7 @@ func Test_setSrcControl(t *testing.T) {
                }
                setSrc(ep, netip.MustParseAddr("127.0.0.1"), 5)
 
-               control := make([]byte, controlSize)
+               control := make([]byte, stickyControlSize)
 
                setSrcControl(&control, ep)
 
@@ -89,7 +89,7 @@ func Test_setSrcControl(t *testing.T) {
                }
                setSrc(ep, netip.MustParseAddr("::1"), 5)
 
-               control := make([]byte, controlSize)
+               control := make([]byte, stickyControlSize)
 
                setSrcControl(&control, ep)
 
@@ -113,7 +113,7 @@ func Test_setSrcControl(t *testing.T) {
        })
 
        t.Run("ClearOnNoSrc", func(t *testing.T) {
-               control := make([]byte, controlSize)
+               control := make([]byte, stickyControlSize)
                hdr := (*unix.Cmsghdr)(unsafe.Pointer(&control[0]))
                hdr.Level = 1
                hdr.Type = 2
@@ -129,7 +129,7 @@ func Test_setSrcControl(t *testing.T) {
 
 func Test_getSrcFromControl(t *testing.T) {
        t.Run("IPv4", func(t *testing.T) {
-               control := make([]byte, controlSize)
+               control := make([]byte, stickyControlSize)
                hdr := (*unix.Cmsghdr)(unsafe.Pointer(&control[0]))
                hdr.Level = unix.IPPROTO_IP
                hdr.Type = unix.IP_PKTINFO
@@ -149,7 +149,7 @@ func Test_getSrcFromControl(t *testing.T) {
                }
        })
        t.Run("IPv6", func(t *testing.T) {
-               control := make([]byte, controlSize)
+               control := make([]byte, stickyControlSize)
                hdr := (*unix.Cmsghdr)(unsafe.Pointer(&control[0]))
                hdr.Level = unix.IPPROTO_IPV6
                hdr.Type = unix.IPV6_PKTINFO