Add dontfrag control

This commit is contained in:
世界 2022-09-06 00:44:41 +08:00
parent 6f8d090cec
commit f3d346256d
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 111 additions and 0 deletions

View file

@ -0,0 +1,31 @@
package control
import (
"os"
"syscall"
N "github.com/sagernet/sing/common/network"
"golang.org/x/sys/unix"
)
func DisableUDPFragment() Func {
return func(network, address string, conn syscall.RawConn) error {
switch N.NetworkName(network) {
case N.NetworkUDP:
default:
return nil
}
return Raw(conn, func(fd uintptr) error {
if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_MTU_DISCOVER, unix.IP_PMTUDISC_DO); err != nil {
return os.NewSyscallError("SETSOCKOPT IP_MTU_DISCOVER IP_PMTUDISC_DO", err)
}
if network == "udp6" {
if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_MTU_DISCOVER, unix.IP_PMTUDISC_DO); err != nil {
return os.NewSyscallError("SETSOCKOPT IPV6_MTU_DISCOVER IP_PMTUDISC_DO", err)
}
}
return nil
})
}
}

View file

@ -0,0 +1,7 @@
//go:build !((go1.19 && unix) || (!go1.19 && (linux || darwin)) || windows)
package control
func DisableUDPFragment() Func {
return nil
}

View file

@ -0,0 +1,28 @@
//go:build (go1.19 && unix && !linux) || (!go1.19 && darwin)
package control
import (
"os"
"syscall"
"golang.org/x/sys/unix"
)
func DisableUDPFragment() Func {
return func(network, address string, conn syscall.RawConn) error {
return Raw(conn, func(fd uintptr) error {
switch network {
case "udp4":
if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_DONTFRAG, 1); err != nil {
return os.NewSyscallError("SETSOCKOPT IP_DONTFRAG", err)
}
case "udp6":
if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_DONTFRAG, 1); err != nil {
return os.NewSyscallError("SETSOCKOPT IPV6_DONTFRAG", err)
}
}
return nil
})
}
}

View file

@ -0,0 +1,45 @@
package control
import (
"os"
"syscall"
N "github.com/sagernet/sing/common/network"
"golang.org/x/sys/windows"
)
const (
IP_MTU_DISCOVER = 71
IPV6_MTU_DISCOVER = 71
)
// enum PMTUD_STATE from ws2ipdef.h
const (
IP_PMTUDISC_NOT_SET = iota
IP_PMTUDISC_DO
IP_PMTUDISC_DONT
IP_PMTUDISC_PROBE
IP_PMTUDISC_MAX
)
func DisableUDPFragment() Func {
return func(network, address string, conn syscall.RawConn) error {
switch N.NetworkName(network) {
case N.NetworkUDP:
default:
return nil
}
return Raw(conn, func(fd uintptr) error {
if err := windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DO); err != nil {
return os.NewSyscallError("SETSOCKOPT IP_MTU_DISCOVER IP_PMTUDISC_DO", err)
}
if network == "udp6" {
if err := windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, IPV6_MTU_DISCOVER, IP_PMTUDISC_DO); err != nil {
return os.NewSyscallError("SETSOCKOPT IPV6_MTU_DISCOVER IP_PMTUDISC_DO", err)
}
}
return nil
})
}
}