Allow arbitrary addresses to be set in listen_addresses

Only works on OpenBSD/FreeBSD/Linux (including Android)

Fixes #1362
This commit is contained in:
Frank Denis 2020-11-25 18:15:48 +01:00
parent 02a6ca1098
commit f9c11f0897
7 changed files with 207 additions and 15 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}