]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Remove unnecessary use of SO_REUSEPORT
authorMatt Joiner <anacrolix@gmail.com>
Mon, 14 Aug 2023 01:38:47 +0000 (11:38 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 14 Aug 2023 22:07:49 +0000 (08:07 +1000)
Fixes https://github.com/anacrolix/torrent/discussions/856.

client_test.go
fs/go.mod
fs/go.sum
socket.go

index 22281efd6cde9bf0eaa6a0b03d7f48150ee5a500..d2a88e9e7a769abcd1871092c006e37b33573a51 100644 (file)
@@ -897,7 +897,7 @@ func TestBadPeerIpPort(t *testing.T) {
 
 // https://github.com/anacrolix/torrent/issues/837
 func TestClientConfigSetHandlerNotIgnored(t *testing.T) {
-       cfg := NewDefaultClientConfig()
+       cfg := TestingConfig(t)
        cfg.Logger.SetHandlers(log.DiscardHandler)
        c := qt.New(t)
        cl, err := NewClient(cfg)
index 67c01ef0816e5696836f70acd3e0d8c2b2b28e1f..004cee727d24a2c813c4d48454ce34e4455d191a 100644 (file)
--- a/fs/go.mod
+++ b/fs/go.mod
@@ -5,7 +5,7 @@ go 1.20
 require (
        github.com/anacrolix/envpprof v1.2.1
        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/tagflag v1.3.0
        github.com/anacrolix/torrent v1.47.1-0.20221102120345-c63f7e1bd720
index 3f7daed35a0c57c667b5022357a3b3f3bc22001c..b32d6e438e0023a31b3619824bc2139a5beeb178 100644 (file)
--- a/fs/go.sum
+++ b/fs/go.sum
@@ -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.14.0 h1:mYhTSemILe/Z8tIxbGdTIWWpPspI8W/fhZHpoFbDaL0=
 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/go.mod h1:66cFKPCO7Sl4vbFnAaSq7e4OXtdMhRSBagJGWgmpJbM=
 github.com/anacrolix/missinggo v0.0.0-20180725070939-60ef2fbf63df/go.mod h1:kwGiTUTZ0+p4vAz3VbAI5a30t2YbvemcmspjKwrAz5s=
index c1fb97fdbcbee17728d530da76a9fe5a6f5ab094..2d4ea863ac292f39e4d97effd297fe2b98afcfa5 100644 (file)
--- a/socket.go
+++ b/socket.go
@@ -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{
        Control: func(network, address string, c syscall.RawConn) (err error) {
                controlErr := c.Control(func(fd uintptr) {
-                       err = setReusePortSockOpts(fd)
+                       if dialTcpFromListenPort {
+                               err = setReusePortSockOpts(fd)
+                       }
                })
                if err != nil {
                        return
@@ -54,38 +61,49 @@ var tcpListenConfig = net.ListenConfig{
 
 func listenTcp(network, address string) (s socket, err error) {
        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,
                NetworkDialer: NetworkDialer{
                        Network: network,
-                       Dialer: &net.Dialer{
-                               // 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
-                               },
-                       },
+                       Dialer:  &netDialer,
                },
-       }, err
+       }
+       return
 }
 
 type tcpSocket struct {