diff --git a/dnscrypt-proxy/proxy.go b/dnscrypt-proxy/proxy.go index a50d4d69..b0cc39d3 100644 --- a/dnscrypt-proxy/proxy.go +++ b/dnscrypt-proxy/proxy.go @@ -1,6 +1,7 @@ package main import ( + "context" crypto_rand "crypto/rand" "encoding/binary" "net" @@ -288,16 +289,6 @@ func (proxy *Proxy) udpListener(clientPc *net.UDPConn) { } } -func (proxy *Proxy) udpListenerFromAddr(listenAddr *net.UDPAddr) error { - clientPc, err := net.ListenUDP("udp", listenAddr) - if err != nil { - return err - } - proxy.registerUDPListener(clientPc) - dlog.Noticef("Now listening to %v [UDP]", listenAddr) - return nil -} - func (proxy *Proxy) tcpListener(acceptPc *net.TCPListener) { defer acceptPc.Close() for { @@ -326,22 +317,44 @@ func (proxy *Proxy) tcpListener(acceptPc *net.TCPListener) { } } -func (proxy *Proxy) tcpListenerFromAddr(listenAddr *net.TCPAddr) error { - acceptPc, err := net.ListenTCP("tcp", listenAddr) +func (proxy *Proxy) udpListenerFromAddr(listenAddr *net.UDPAddr) error { + listenConfig, err := proxy.udpListenerConfig() if err != nil { return err } - proxy.registerTCPListener(acceptPc) + clientPc, err := listenConfig.ListenPacket(context.Background(), "udp", listenAddr.String()) + if err != nil { + return err + } + proxy.registerUDPListener(clientPc.(*net.UDPConn)) + dlog.Noticef("Now listening to %v [UDP]", listenAddr) + return nil +} + +func (proxy *Proxy) tcpListenerFromAddr(listenAddr *net.TCPAddr) error { + listenConfig, err := proxy.tcpListenerConfig() + if err != nil { + return err + } + acceptPc, err := listenConfig.Listen(context.Background(), "tcp", listenAddr.String()) + if err != nil { + return err + } + proxy.registerTCPListener(acceptPc.(*net.TCPListener)) dlog.Noticef("Now listening to %v [TCP]", listenAddr) return nil } func (proxy *Proxy) localDoHListenerFromAddr(listenAddr *net.TCPAddr) error { - acceptPc, err := net.ListenTCP("tcp", listenAddr) + listenConfig, err := proxy.tcpListenerConfig() if err != nil { return err } - proxy.registerLocalDoHListener(acceptPc) + acceptPc, err := listenConfig.Listen(context.Background(), "tcp", listenAddr.String()) + if err != nil { + return err + } + proxy.registerLocalDoHListener(acceptPc.(*net.TCPListener)) dlog.Noticef("Now listening to https://%v%v [DoH]", listenAddr, proxy.localDoHPath) return nil } diff --git a/dnscrypt-proxy/setsockopts_darwin.go b/dnscrypt-proxy/setsockopts_darwin.go new file mode 100644 index 00000000..3a0ba71f --- /dev/null +++ b/dnscrypt-proxy/setsockopts_darwin.go @@ -0,0 +1,31 @@ +package main + +import ( + "net" + "syscall" +) + +func (proxy *Proxy) udpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_DF, 0) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUF, 4096) + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUF, 4096) + }) + return nil + }, + }, nil +} + +func (proxy *Proxy) tcpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + }) + return nil + }, + }, nil +} diff --git a/dnscrypt-proxy/setsockopts_freebsd.go b/dnscrypt-proxy/setsockopts_freebsd.go new file mode 100644 index 00000000..dd15593e --- /dev/null +++ b/dnscrypt-proxy/setsockopts_freebsd.go @@ -0,0 +1,35 @@ +package main + +import ( + "net" + "syscall" +) + +func (proxy *Proxy) udpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BINDANY, 1) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BINDANY, 1) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_DF, 0) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUF, 4096) + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUF, 4096) + }) + return nil + }, + }, nil +} + +func (proxy *Proxy) tcpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BINDANY, 1) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BINDANY, 1) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + }) + return nil + }, + }, nil +} diff --git a/dnscrypt-proxy/setsockopts_linux.go b/dnscrypt-proxy/setsockopts_linux.go new file mode 100644 index 00000000..d7b67655 --- /dev/null +++ b/dnscrypt-proxy/setsockopts_linux.go @@ -0,0 +1,35 @@ +package main + +import ( + "net" + "syscall" +) + +func (proxy *Proxy) udpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_FREEBIND, 1) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_DF, 0) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_MTU_DISCOVER, syscall.IP_PMTUDISC_DONT) + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUFFORCE, 4096) + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUFFORCE, 4096) + }) + return nil + }, + }, nil +} + +func (proxy *Proxy) tcpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_FREEBIND, 1) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_QUICKACK, 1) + }) + return nil + }, + }, nil +} diff --git a/dnscrypt-proxy/setsockopts_openbsd.go b/dnscrypt-proxy/setsockopts_openbsd.go new file mode 100644 index 00000000..990d578a --- /dev/null +++ b/dnscrypt-proxy/setsockopts_openbsd.go @@ -0,0 +1,33 @@ +package main + +import ( + "net" + "syscall" +) + +func (proxy *Proxy) udpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_BINDANY, 1) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_DF, 0) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUF, 4096) + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUF, 4096) + }) + return nil + }, + }, nil +} + +func (proxy *Proxy) tcpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_BINDANY, 1) + _ = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + }) + return nil + }, + }, nil +} diff --git a/dnscrypt-proxy/setsockopts_others.go b/dnscrypt-proxy/setsockopts_others.go new file mode 100644 index 00000000..a1b288fc --- /dev/null +++ b/dnscrypt-proxy/setsockopts_others.go @@ -0,0 +1,15 @@ +// +build !freebsd,!openbsd,!windows,!darwin,!linux + +package main + +import ( + "net" +) + +func (proxy *Proxy) udpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{}, nil +} + +func (proxy *Proxy) tcpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{}, nil +} diff --git a/dnscrypt-proxy/setsockopts_windows.go b/dnscrypt-proxy/setsockopts_windows.go new file mode 100644 index 00000000..76def65c --- /dev/null +++ b/dnscrypt-proxy/setsockopts_windows.go @@ -0,0 +1,30 @@ +package main + +import ( + "net" + "syscall" +) + +func (proxy *Proxy) udpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + _ = syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUF, 4096) + _ = syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUF, 4096) + }) + return nil + }, + }, nil +} + +func (proxy *Proxy) tcpListenerConfig() (*net.ListenConfig, error) { + return &net.ListenConfig{ + Control: func(network, address string, c syscall.RawConn) error { + _ = c.Control(func(fd uintptr) { + _ = syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 0x70) + }) + return nil + }, + }, nil +}