Created
February 20, 2022 03:42
-
-
Save tobyxdd/1964cc8d559fb367010c80c1dafee1b1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/conn.go b/conn.go | |
index 2f4e3a23..811279c9 100644 | |
--- a/conn.go | |
+++ b/conn.go | |
@@ -29,6 +29,19 @@ type OOBCapablePacketConn interface { | |
var _ OOBCapablePacketConn = &net.UDPConn{} | |
func wrapConn(pc net.PacketConn) (connection, error) { | |
+ conn, ok := pc.(interface { | |
+ SyscallConn() (syscall.RawConn, error) | |
+ }) | |
+ if ok { | |
+ rawConn, err := conn.SyscallConn() | |
+ if err != nil { | |
+ return nil, err | |
+ } | |
+ err = setDF(rawConn) | |
+ if err != nil { | |
+ return nil, err | |
+ } | |
+ } | |
c, ok := pc.(OOBCapablePacketConn) | |
if !ok { | |
utils.DefaultLogger.Infof("PacketConn is not a net.UDPConn. Disabling optimizations possible on UDP connections.") | |
diff --git a/conn_oob_opts.go b/conn_df.go | |
similarity index 59% | |
rename from conn_oob_opts.go | |
rename to conn_df.go | |
index 4d29c7c4..544fea3e 100644 | |
--- a/conn_oob_opts.go | |
+++ b/conn_df.go | |
@@ -3,6 +3,9 @@ | |
package quic | |
-func setOOBSockOpts(fd uintptr) { | |
+import "syscall" | |
+ | |
+func setDF(rawConn syscall.RawConn) error { | |
// no-op on unsupported platforms | |
+ return nil | |
} | |
diff --git a/conn_df_linux.go b/conn_df_linux.go | |
new file mode 100644 | |
index 00000000..89948ff8 | |
--- /dev/null | |
+++ b/conn_df_linux.go | |
@@ -0,0 +1,34 @@ | |
+//go:build linux | |
+// +build linux | |
+ | |
+package quic | |
+ | |
+import ( | |
+ "errors" | |
+ "github.com/lucas-clemente/quic-go/internal/utils" | |
+ "golang.org/x/sys/unix" | |
+ "syscall" | |
+) | |
+ | |
+func setDF(rawConn syscall.RawConn) error { | |
+ // Enabling IP_MTU_DISCOVER will force the kernel to return "sendto: message too long" | |
+ // and the datagram will not be fragmented | |
+ var errDFIPv4, errDFIPv6 error | |
+ if err := rawConn.Control(func(fd uintptr) { | |
+ errDFIPv4 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_MTU_DISCOVER, unix.IP_PMTUDISC_DO) | |
+ errDFIPv6 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_MTU_DISCOVER, unix.IPV6_PMTUDISC_DO) | |
+ }); err != nil { | |
+ return err | |
+ } | |
+ switch { | |
+ case errDFIPv4 == nil && errDFIPv6 == nil: | |
+ utils.DefaultLogger.Debugf("Setting DF for IPv4 and IPv6.") | |
+ case errDFIPv4 == nil && errDFIPv6 != nil: | |
+ utils.DefaultLogger.Debugf("Setting DF for IPv4.") | |
+ case errDFIPv4 != nil && errDFIPv6 == nil: | |
+ utils.DefaultLogger.Debugf("Setting DF for IPv6.") | |
+ case errDFIPv4 != nil && errDFIPv6 != nil: | |
+ return errors.New("setting DF failed for both IPv4 and IPv6") | |
+ } | |
+ return nil | |
+} | |
diff --git a/conn_df_windows.go b/conn_df_windows.go | |
new file mode 100644 | |
index 00000000..0f5a5b0b | |
--- /dev/null | |
+++ b/conn_df_windows.go | |
@@ -0,0 +1,40 @@ | |
+//go:build windows | |
+// +build windows | |
+ | |
+package quic | |
+ | |
+import ( | |
+ "errors" | |
+ "github.com/lucas-clemente/quic-go/internal/utils" | |
+ "golang.org/x/sys/windows" | |
+ "syscall" | |
+) | |
+ | |
+const ( | |
+ // same for both IPv4 and IPv6 on Windows | |
+ // https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/constant.IP_DONTFRAG.html | |
+ // https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/constant.IPV6_DONTFRAG.html | |
+ IP_DONTFRAGMENT = 14 | |
+ IPV6_DONTFRAG = 14 | |
+) | |
+ | |
+func setDF(rawConn syscall.RawConn) error { | |
+ var errDFIPv4, errDFIPv6 error | |
+ if err := rawConn.Control(func(fd uintptr) { | |
+ errDFIPv4 = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, IP_DONTFRAGMENT, 1) | |
+ errDFIPv6 = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, IPV6_DONTFRAG, 1) | |
+ }); err != nil { | |
+ return err | |
+ } | |
+ switch { | |
+ case errDFIPv4 == nil && errDFIPv6 == nil: | |
+ utils.DefaultLogger.Debugf("Setting DF for IPv4 and IPv6.") | |
+ case errDFIPv4 == nil && errDFIPv6 != nil: | |
+ utils.DefaultLogger.Debugf("Setting DF for IPv4.") | |
+ case errDFIPv4 != nil && errDFIPv6 == nil: | |
+ utils.DefaultLogger.Debugf("Setting DF for IPv6.") | |
+ case errDFIPv4 != nil && errDFIPv6 != nil: | |
+ return errors.New("setting DF failed for both IPv4 and IPv6") | |
+ } | |
+ return nil | |
+} | |
diff --git a/conn_oob.go b/conn_oob.go | |
index f1aebfaa..b4678137 100644 | |
--- a/conn_oob.go | |
+++ b/conn_oob.go | |
@@ -87,8 +87,6 @@ func newConn(c OOBCapablePacketConn) (*oobConn, error) { | |
errPIIPv4 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, ipv4RECVPKTINFO, 1) | |
errPIIPv6 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, ipv6RECVPKTINFO, 1) | |
} | |
- | |
- setOOBSockOpts(fd) | |
}); err != nil { | |
return nil, err | |
} | |
diff --git a/conn_oob_opts_linux.go b/conn_oob_opts_linux.go | |
deleted file mode 100644 | |
index 81e7ca58..00000000 | |
--- a/conn_oob_opts_linux.go | |
+++ /dev/null | |
@@ -1,15 +0,0 @@ | |
-//go:build linux | |
-// +build linux | |
- | |
-package quic | |
- | |
-import ( | |
- "golang.org/x/sys/unix" | |
-) | |
- | |
-func setOOBSockOpts(fd uintptr) { | |
- // Enabling IP_MTU_DISCOVER will force the kernel to return "sendto: message too long" | |
- // and the datagram will not be fragmented | |
- unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_MTU_DISCOVER, unix.IP_PMTUDISC_DO) | |
- unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_MTU_DISCOVER, unix.IPV6_PMTUDISC_DO) | |
-} | |
diff --git a/conn_windows.go b/conn_windows.go | |
index 72906b89..4869d67a 100644 | |
--- a/conn_windows.go | |
+++ b/conn_windows.go | |
@@ -9,40 +9,10 @@ import ( | |
"net" | |
"syscall" | |
- "github.com/lucas-clemente/quic-go/internal/utils" | |
"golang.org/x/sys/windows" | |
) | |
-const ( | |
- // same for both IPv4 and IPv6 on Windows | |
- // https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/constant.IP_DONTFRAG.html | |
- // https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/constant.IPV6_DONTFRAG.html | |
- IP_DONTFRAGMENT = 14 | |
- IPV6_DONTFRAG = 14 | |
-) | |
- | |
func newConn(c OOBCapablePacketConn) (connection, error) { | |
- rawConn, err := c.SyscallConn() | |
- if err != nil { | |
- return nil, fmt.Errorf("couldn't get syscall.RawConn: %w", err) | |
- } | |
- var errDFIPv4, errDFIPv6 error | |
- if err := rawConn.Control(func(fd uintptr) { | |
- errDFIPv4 = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, IP_DONTFRAGMENT, 1) | |
- errDFIPv6 = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, IPV6_DONTFRAG, 1) | |
- }); err != nil { | |
- return nil, err | |
- } | |
- switch { | |
- case errDFIPv4 == nil && errDFIPv6 == nil: | |
- utils.DefaultLogger.Debugf("Setting DF for IPv4 and IPv6.") | |
- case errDFIPv4 == nil && errDFIPv6 != nil: | |
- utils.DefaultLogger.Debugf("Setting DF for IPv4.") | |
- case errDFIPv4 != nil && errDFIPv6 == nil: | |
- utils.DefaultLogger.Debugf("Setting DF for IPv6.") | |
- case errDFIPv4 != nil && errDFIPv6 != nil: | |
- return nil, errors.New("setting Df failed for both IPv4 and IPv6") | |
- } | |
return &basicConn{PacketConn: c}, nil | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment