mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-09 20:29:23 +02:00
chore(pmtud): remove calls to syscall in favor of unix and windows
- syscall is deprecated and is not kept up-to-date - each OS is inherently different hence the syscall being deprecated
This commit is contained in:
@@ -3,7 +3,6 @@ package ip
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net/netip"
|
||||
"syscall"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/pmtud/constants"
|
||||
)
|
||||
@@ -19,7 +18,7 @@ func HeaderV4(srcIP, dstIP netip.Addr, payloadLength uint32) []byte {
|
||||
const flagsAndOffset uint16 = 0x4000 // DF bit set
|
||||
putUint16(ipHeader[6:], flagsAndOffset)
|
||||
ipHeader[8] = 64 // ttl
|
||||
ipHeader[9] = syscall.IPPROTO_TCP
|
||||
ipHeader[9] = constants.IPPROTO_TCP
|
||||
srcIPBytes := srcIP.As4()
|
||||
copy(ipHeader[12:16], srcIPBytes[:])
|
||||
dstIPBytes := dstIP.As4()
|
||||
@@ -51,7 +50,7 @@ func ipChecksum(header []byte) uint16 {
|
||||
|
||||
// HeaderV6 makes an IPv6 header.
|
||||
// payloadLen is the length of the payload following the header.
|
||||
// nextHeader can be byte([syscall.IPPROTO_TCP]) for example.
|
||||
// nextHeader can be byte([constants.IPPROTO_TCP]) for example.
|
||||
func HeaderV6(srcIP, dstIP netip.Addr,
|
||||
payloadLen uint16, nextHeader byte,
|
||||
) []byte {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
package ip
|
||||
|
||||
import "syscall"
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func SetIPv4HeaderIncluded(fd int) error {
|
||||
return syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1)
|
||||
return unix.SetsockoptInt(fd, unix.IPPROTO_IP, unix.IP_HDRINCL, 1)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package ip
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func SetIPv4HeaderIncluded(handle syscall.Handle) error {
|
||||
func SetIPv4HeaderIncluded(handle windows.Handle) error {
|
||||
const ipHdrIncluded = windows.IP_HDRINCL
|
||||
return syscall.SetsockoptInt(handle, syscall.IPPROTO_IP, ipHdrIncluded, 1)
|
||||
return windows.SetsockoptInt(handle, windows.IPPROTO_IP, ipHdrIncluded, 1)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package ip
|
||||
|
||||
import "syscall"
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func SetIPv6HeaderIncluded(fd int) error {
|
||||
const ipv6HdrIncluded = 36 // IPV6_HDRINCL
|
||||
return syscall.SetsockoptInt(fd, syscall.IPPROTO_IPV6, ipv6HdrIncluded, 1)
|
||||
return unix.SetsockoptInt(fd, unix.IPPROTO_IPV6, unix.IPV6_HDRINCL, 1)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package ip
|
||||
|
||||
import "syscall"
|
||||
import "golang.org/x/sys/windows"
|
||||
|
||||
func SetIPv6HeaderIncluded(fd syscall.Handle) error {
|
||||
func SetIPv6HeaderIncluded(fd windows.Handle) error {
|
||||
panic("windows does not allow an application to build IPv6 headers")
|
||||
}
|
||||
|
||||
+11
-30
@@ -3,9 +3,9 @@ package ip
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"syscall"
|
||||
|
||||
"github.com/jsimonetti/rtnetlink"
|
||||
"github.com/qdm12/gluetun/internal/pmtud/constants"
|
||||
)
|
||||
|
||||
// SrcAddr determines the appropriate source IP address to use when sending a packet to the
|
||||
@@ -35,9 +35,9 @@ func srcIP(dst netip.Addr) (netip.Addr, error) {
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
family := uint8(syscall.AF_INET)
|
||||
family := uint8(constants.AF_INET)
|
||||
if dst.Is6() {
|
||||
family = syscall.AF_INET6
|
||||
family = constants.AF_INET6
|
||||
}
|
||||
|
||||
// Request route to destination
|
||||
@@ -71,53 +71,34 @@ func srcIP(dst netip.Addr) (netip.Addr, error) {
|
||||
// It doesn't actually listen on the port.
|
||||
// The cleanup function returned should be called to release the port when done.
|
||||
func srcPort(srcAddr netip.Addr, proto int) (srcPort uint16, cleanup func(), err error) {
|
||||
family := syscall.AF_INET
|
||||
family := constants.AF_INET
|
||||
if srcAddr.Is6() {
|
||||
family = syscall.AF_INET6
|
||||
family = constants.AF_INET6
|
||||
}
|
||||
|
||||
fd, err := syscall.Socket(family, syscall.SOCK_STREAM, proto)
|
||||
fd, err := socket(family, constants.SOCK_STREAM, proto)
|
||||
if err != nil {
|
||||
return 0, nil, fmt.Errorf("creating reservation socket: %w", err)
|
||||
}
|
||||
cleanup = func() {
|
||||
_ = syscall.Close(fd)
|
||||
_ = closeSocket(fd)
|
||||
}
|
||||
|
||||
// Bind to port 0 to get an ephemeral port
|
||||
const port = 0
|
||||
var bindAddr syscall.Sockaddr
|
||||
if srcAddr.Is4() {
|
||||
bindAddr = &syscall.SockaddrInet4{
|
||||
Port: port,
|
||||
Addr: srcAddr.As4(),
|
||||
}
|
||||
} else {
|
||||
bindAddr = &syscall.SockaddrInet6{
|
||||
Port: port,
|
||||
Addr: srcAddr.As16(),
|
||||
}
|
||||
}
|
||||
bindAddr := makeSockAddr(srcAddr, port)
|
||||
|
||||
err = syscall.Bind(fd, bindAddr)
|
||||
err = bind(fd, bindAddr)
|
||||
if err != nil {
|
||||
cleanup()
|
||||
return 0, nil, fmt.Errorf("binding reservation socket: %w", err)
|
||||
}
|
||||
|
||||
sockAddr, err := syscall.Getsockname(fd)
|
||||
srcPort, err = extractPortFromFD(fd)
|
||||
if err != nil {
|
||||
cleanup()
|
||||
return 0, nil, fmt.Errorf("getting bound socket name: %w", err)
|
||||
return 0, nil, fmt.Errorf("extracting port from socket fd: %w", err)
|
||||
}
|
||||
|
||||
switch typedSockAddr := sockAddr.(type) {
|
||||
case *syscall.SockaddrInet4:
|
||||
srcPort = uint16(typedSockAddr.Port) //nolint:gosec
|
||||
case *syscall.SockaddrInet6:
|
||||
srcPort = uint16(typedSockAddr.Port) //nolint:gosec
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected sockaddr type: %T", typedSockAddr))
|
||||
}
|
||||
return srcPort, cleanup, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
//go:build linux || darwin
|
||||
|
||||
package ip
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func socket(domain int, typ int, proto int) (fd int, err error) {
|
||||
return unix.Socket(domain, typ, proto)
|
||||
}
|
||||
|
||||
func closeSocket(fd int) error {
|
||||
return unix.Close(fd)
|
||||
}
|
||||
|
||||
func bind(fd int, addr unix.Sockaddr) error {
|
||||
return unix.Bind(fd, addr)
|
||||
}
|
||||
|
||||
func makeSockAddr(ip netip.Addr, port uint16) unix.Sockaddr {
|
||||
if ip.Is4() {
|
||||
return &unix.SockaddrInet4{
|
||||
Port: int(port),
|
||||
Addr: ip.As4(),
|
||||
}
|
||||
}
|
||||
return &unix.SockaddrInet6{
|
||||
Port: int(port),
|
||||
Addr: ip.As16(),
|
||||
}
|
||||
}
|
||||
|
||||
func extractPortFromFD(fd int) (uint16, error) {
|
||||
sockAddr, err := unix.Getsockname(fd)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("getting sockname: %w", err)
|
||||
}
|
||||
|
||||
switch typedSockAddr := sockAddr.(type) {
|
||||
case *unix.SockaddrInet4:
|
||||
return uint16(typedSockAddr.Port), nil //nolint:gosec
|
||||
case *unix.SockaddrInet6:
|
||||
return uint16(typedSockAddr.Port), nil //nolint:gosec
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected sockaddr type: %T", typedSockAddr))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package ip
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func socket(domain int, typ int, proto int) (fd windows.Handle, err error) {
|
||||
return windows.Socket(domain, typ, proto)
|
||||
}
|
||||
|
||||
func closeSocket(fd windows.Handle) error {
|
||||
return windows.Close(fd)
|
||||
}
|
||||
|
||||
func bind(fd windows.Handle, addr windows.Sockaddr) error {
|
||||
return windows.Bind(fd, addr)
|
||||
}
|
||||
|
||||
func makeSockAddr(ip netip.Addr, port uint16) windows.Sockaddr {
|
||||
if ip.Is4() {
|
||||
return &windows.SockaddrInet4{
|
||||
Port: int(port),
|
||||
Addr: ip.As4(),
|
||||
}
|
||||
}
|
||||
return &windows.SockaddrInet6{
|
||||
Port: int(port),
|
||||
Addr: ip.As16(),
|
||||
}
|
||||
}
|
||||
|
||||
func extractPortFromFD(fd windows.Handle) (uint16, error) {
|
||||
sockAddr, err := windows.Getsockname(fd)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("getting sockname: %w", err)
|
||||
}
|
||||
|
||||
switch typedSockAddr := sockAddr.(type) {
|
||||
case *windows.SockaddrInet4:
|
||||
return uint16(typedSockAddr.Port), nil //nolint:gosec
|
||||
case *windows.SockaddrInet6:
|
||||
return uint16(typedSockAddr.Port), nil //nolint:gosec
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected sockaddr type: %T", typedSockAddr))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user