2
0
mirror of synced 2025-02-22 13:48:21 +00:00

Remove unnecessary use of SO_REUSEPORT

Fixes https://github.com/anacrolix/torrent/discussions/856.
This commit is contained in:
Matt Joiner 2023-08-14 11:38:47 +10:00
parent 8dcc4cc187
commit 5a33552095
No known key found for this signature in database
GPG Key ID: 6B990B8185E7F782
4 changed files with 51 additions and 31 deletions

View File

@ -897,7 +897,7 @@ func TestBadPeerIpPort(t *testing.T) {
// https://github.com/anacrolix/torrent/issues/837 // https://github.com/anacrolix/torrent/issues/837
func TestClientConfigSetHandlerNotIgnored(t *testing.T) { func TestClientConfigSetHandlerNotIgnored(t *testing.T) {
cfg := NewDefaultClientConfig() cfg := TestingConfig(t)
cfg.Logger.SetHandlers(log.DiscardHandler) cfg.Logger.SetHandlers(log.DiscardHandler)
c := qt.New(t) c := qt.New(t)
cl, err := NewClient(cfg) cl, err := NewClient(cfg)

View File

@ -5,7 +5,7 @@ go 1.20
require ( require (
github.com/anacrolix/envpprof v1.2.1 github.com/anacrolix/envpprof v1.2.1
github.com/anacrolix/fuse v0.2.0 github.com/anacrolix/fuse v0.2.0
github.com/anacrolix/log v0.14.0 github.com/anacrolix/log v0.14.1
github.com/anacrolix/missinggo/v2 v2.7.2-0.20230527121029-a582b4f397b9 github.com/anacrolix/missinggo/v2 v2.7.2-0.20230527121029-a582b4f397b9
github.com/anacrolix/tagflag v1.3.0 github.com/anacrolix/tagflag v1.3.0
github.com/anacrolix/torrent v1.47.1-0.20221102120345-c63f7e1bd720 github.com/anacrolix/torrent v1.47.1-0.20221102120345-c63f7e1bd720

View File

@ -46,6 +46,8 @@ github.com/anacrolix/log v0.10.1-0.20220123034749-3920702c17f8/go.mod h1:GmnE2c0
github.com/anacrolix/log v0.13.1/go.mod h1:D4+CvN8SnruK6zIFS/xPoRJmtvtnxs+CSfDQ+BFxZ68= github.com/anacrolix/log v0.13.1/go.mod h1:D4+CvN8SnruK6zIFS/xPoRJmtvtnxs+CSfDQ+BFxZ68=
github.com/anacrolix/log v0.14.0 h1:mYhTSemILe/Z8tIxbGdTIWWpPspI8W/fhZHpoFbDaL0= github.com/anacrolix/log v0.14.0 h1:mYhTSemILe/Z8tIxbGdTIWWpPspI8W/fhZHpoFbDaL0=
github.com/anacrolix/log v0.14.0/go.mod h1:1OmJESOtxQGNMlUO5rcv96Vpp9mfMqXXbe2RdinFLdY= github.com/anacrolix/log v0.14.0/go.mod h1:1OmJESOtxQGNMlUO5rcv96Vpp9mfMqXXbe2RdinFLdY=
github.com/anacrolix/log v0.14.1 h1:j2FcIpYZ5FbANetUcm5JNu+zUBGADSp/VbjhUPrAY0k=
github.com/anacrolix/log v0.14.1/go.mod h1:1OmJESOtxQGNMlUO5rcv96Vpp9mfMqXXbe2RdinFLdY=
github.com/anacrolix/lsan v0.0.0-20211126052245-807000409a62 h1:P04VG6Td13FHMgS5ZBcJX23NPC/fiC4cp9bXwYujdYM= github.com/anacrolix/lsan v0.0.0-20211126052245-807000409a62 h1:P04VG6Td13FHMgS5ZBcJX23NPC/fiC4cp9bXwYujdYM=
github.com/anacrolix/lsan v0.0.0-20211126052245-807000409a62/go.mod h1:66cFKPCO7Sl4vbFnAaSq7e4OXtdMhRSBagJGWgmpJbM= github.com/anacrolix/lsan v0.0.0-20211126052245-807000409a62/go.mod h1:66cFKPCO7Sl4vbFnAaSq7e4OXtdMhRSBagJGWgmpJbM=
github.com/anacrolix/missinggo v0.0.0-20180725070939-60ef2fbf63df/go.mod h1:kwGiTUTZ0+p4vAz3VbAI5a30t2YbvemcmspjKwrAz5s= github.com/anacrolix/missinggo v0.0.0-20180725070939-60ef2fbf63df/go.mod h1:kwGiTUTZ0+p4vAz3VbAI5a30t2YbvemcmspjKwrAz5s=

View File

@ -37,10 +37,17 @@ func listen(n network, addr string, f firewallCallback, logger log.Logger) (sock
} }
} }
// Dialing TCP from a local port limits us to a single outgoing TCP connection to each remote
// client. Instead, this should be a last resort if we need to use holepunching, and only then to
// connect to other clients that actually try to holepunch TCP.
const dialTcpFromListenPort = false
var tcpListenConfig = net.ListenConfig{ var tcpListenConfig = net.ListenConfig{
Control: func(network, address string, c syscall.RawConn) (err error) { Control: func(network, address string, c syscall.RawConn) (err error) {
controlErr := c.Control(func(fd uintptr) { controlErr := c.Control(func(fd uintptr) {
err = setReusePortSockOpts(fd) if dialTcpFromListenPort {
err = setReusePortSockOpts(fd)
}
}) })
if err != nil { if err != nil {
return return
@ -54,38 +61,49 @@ var tcpListenConfig = net.ListenConfig{
func listenTcp(network, address string) (s socket, err error) { func listenTcp(network, address string) (s socket, err error) {
l, err := tcpListenConfig.Listen(context.Background(), network, address) l, err := tcpListenConfig.Listen(context.Background(), network, address)
return tcpSocket{ if err != nil {
return
}
netDialer := net.Dialer{
// We don't want fallback, as we explicitly manage the IPv4/IPv6 distinction ourselves,
// although it's probably not triggered as I think the network is already constrained to
// tcp4 or tcp6 at this point.
FallbackDelay: -1,
// BitTorrent connections manage their own keepalives.
KeepAlive: tcpListenConfig.KeepAlive,
Control: func(network, address string, c syscall.RawConn) (err error) {
controlErr := c.Control(func(fd uintptr) {
err = setSockNoLinger(fd)
if err != nil {
// Failing to disable linger is undesirable, but not fatal.
log.Levelf(log.Debug, "error setting linger socket option on tcp socket: %v", err)
err = nil
}
// This is no longer required I think, see
// https://github.com/anacrolix/torrent/discussions/856. I added this originally to
// allow dialling out from the client's listen port, but that doesn't really work. I
// think Linux older than ~2013 doesn't support SO_REUSEPORT.
if dialTcpFromListenPort {
err = setReusePortSockOpts(fd)
}
})
if err == nil {
err = controlErr
}
return
},
}
if dialTcpFromListenPort {
netDialer.LocalAddr = l.Addr()
}
s = tcpSocket{
Listener: l, Listener: l,
NetworkDialer: NetworkDialer{ NetworkDialer: NetworkDialer{
Network: network, Network: network,
Dialer: &net.Dialer{ Dialer: &netDialer,
// Dialling TCP from a local port limits us to a single outgoing TCP connection to
// each remote client. Instead this should be a last resort if we need to use holepunching, and only then to connect to other clients that actually try to holepunch TCP.
//LocalAddr: l.Addr(),
// We don't want fallback, as we explicitly manage the IPv4/IPv6 distinction
// ourselves, although it's probably not triggered as I think the network is already
// constrained to tcp4 or tcp6 at this point.
FallbackDelay: -1,
// BitTorrent connections manage their own keep-alives.
KeepAlive: tcpListenConfig.KeepAlive,
Control: func(network, address string, c syscall.RawConn) (err error) {
controlErr := c.Control(func(fd uintptr) {
err = setSockNoLinger(fd)
if err != nil {
// Failing to disable linger is undesirable, but not fatal.
log.Printf("error setting linger socket option on tcp socket: %v", err)
}
err = setReusePortSockOpts(fd)
})
if err == nil {
err = controlErr
}
return
},
},
}, },
}, err }
return
} }
type tcpSocket struct { type tcpSocket struct {