diff --git a/internal/pmtud/icmp/df_linux.go b/internal/pmtud/icmp/df_linux.go index 06e247fc..a0fd6f9c 100644 --- a/internal/pmtud/icmp/df_linux.go +++ b/internal/pmtud/icmp/df_linux.go @@ -4,7 +4,11 @@ import ( "golang.org/x/sys/unix" ) -func setDontFragment(fd uintptr) (err error) { - return unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, - unix.IP_MTU_DISCOVER, unix.IP_PMTUDISC_PROBE) +func setDontFragment(fd uintptr, ipv4 bool) (err error) { + if ipv4 { + return unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, + unix.IP_MTU_DISCOVER, unix.IP_PMTUDISC_PROBE) + } + return unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, + unix.IPV6_MTU_DISCOVER, unix.IPV6_PMTUDISC_PROBE) } diff --git a/internal/pmtud/icmp/df.go b/internal/pmtud/icmp/df_unspecified.go similarity index 79% rename from internal/pmtud/icmp/df.go rename to internal/pmtud/icmp/df_unspecified.go index 32c3ea32..6e49defa 100644 --- a/internal/pmtud/icmp/df.go +++ b/internal/pmtud/icmp/df_unspecified.go @@ -5,6 +5,6 @@ package icmp // setDontFragment for platforms other than Linux and Windows // is not implemented, so we just return assuming the don't // fragment flag is set on IP packets. -func setDontFragment(fd uintptr) (err error) { +func setDontFragment(fd uintptr, ipv4 bool) (err error) { return nil } diff --git a/internal/pmtud/icmp/df_windows.go b/internal/pmtud/icmp/df_windows.go index 709271dd..56a5b713 100644 --- a/internal/pmtud/icmp/df_windows.go +++ b/internal/pmtud/icmp/df_windows.go @@ -4,8 +4,11 @@ import ( "golang.org/x/sys/windows" ) -func setDontFragment(fd uintptr) (err error) { - // https://docs.microsoft.com/en-us/troubleshoot/windows/win32/header-library-requirement-socket-ipproto-ip - // #define IP_DONTFRAGMENT 14 /* don't fragment IP datagrams */ - return windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, 14, 1) +func setDontFragment(fd uintptr, ipv4 bool) (err error) { + if ipv4 { + // https://docs.microsoft.com/en-us/troubleshoot/windows/win32/header-library-requirement-socket-ipproto-ip + // #define IP_DONTFRAGMENT 14 /* don't fragment IP datagrams */ + return windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, 14, 1) + } + return windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, 14, 1) } diff --git a/internal/pmtud/icmp/ipv4.go b/internal/pmtud/icmp/ipv4.go index 684ea4a1..bc1fa186 100644 --- a/internal/pmtud/icmp/ipv4.go +++ b/internal/pmtud/icmp/ipv4.go @@ -25,7 +25,8 @@ func listenICMPv4(ctx context.Context) (conn net.PacketConn, err error) { listenConfig.Control = func(_, _ string, rawConn syscall.RawConn) error { var setDFErr error err := rawConn.Control(func(fd uintptr) { - setDFErr = setDontFragment(fd) // runs when calling ListenPacket + const ipv4 = true + setDFErr = setDontFragment(fd, ipv4) // runs when calling ListenPacket }) if err == nil { err = setDFErr diff --git a/internal/pmtud/icmp/ipv6.go b/internal/pmtud/icmp/ipv6.go index a707bed3..c14f499c 100644 --- a/internal/pmtud/icmp/ipv6.go +++ b/internal/pmtud/icmp/ipv6.go @@ -6,6 +6,7 @@ import ( "net" "net/netip" "strings" + "syscall" "time" "github.com/qdm12/gluetun/internal/pmtud/constants" @@ -19,6 +20,17 @@ const ( func listenICMPv6(ctx context.Context) (conn net.PacketConn, err error) { var listenConfig net.ListenConfig + listenConfig.Control = func(_, _ string, rawConn syscall.RawConn) error { + var setDFErr error + err := rawConn.Control(func(fd uintptr) { + const ipv4 = false + setDFErr = setDontFragment(fd, ipv4) // runs when calling ListenPacket + }) + if err == nil { + err = setDFErr + } + return err + } const listenAddress = "" packetConn, err := listenConfig.ListenPacket(ctx, "ip6:ipv6-icmp", listenAddress) if err != nil {