]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Attribute accepted connection to holepunching when connect message is late
authorMatt Joiner <anacrolix@gmail.com>
Sun, 28 May 2023 03:34:58 +0000 (13:34 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 28 May 2023 03:53:22 +0000 (13:53 +1000)
Also perform holepunch metric adjustments sooner to reduce timing issues in tests.

client-stats.go
client.go
torrent.go

index 1a8009708fb3a3c893d60a4c542e009eab9957ed..bfa6994e9890af2e346ac2d354e4b4be9ec0d975 100644 (file)
@@ -2,14 +2,21 @@ package torrent
 
 import (
        "net/netip"
+
+       g "github.com/anacrolix/generics"
 )
 
+func setAdd[K comparable](m *map[K]struct{}, elem K) {
+       g.MakeMapIfNilAndSet(m, elem, struct{}{})
+}
+
 type clientHolepunchAddrSets struct {
        undialableWithoutHolepunch                            map[netip.AddrPort]struct{}
        undialableWithoutHolepunchDialedAfterHolepunchConnect map[netip.AddrPort]struct{}
        dialableOnlyAfterHolepunch                            map[netip.AddrPort]struct{}
        dialedSuccessfullyAfterHolepunchConnect               map[netip.AddrPort]struct{}
        probablyOnlyConnectedDueToHolepunch                   map[netip.AddrPort]struct{}
+       accepted                                              map[netip.AddrPort]struct{}
 }
 
 type ClientStats struct {
index a87e44391f657508406c243b74df06602c81b030..f1a054abc6708a223e3c4159de7e53cb0c35ce84 100644 (file)
--- a/client.go
+++ b/client.go
@@ -498,6 +498,22 @@ func (cl *Client) acceptConnections(l Listener) {
        for {
                conn, err := l.Accept()
                torrent.Add("client listener accepts", 1)
+               if err == nil {
+                       holepunchAddr, holepunchErr := addrPortFromPeerRemoteAddr(conn.RemoteAddr())
+                       if holepunchErr == nil {
+                               cl.lock()
+                               if g.MapContains(cl.undialableWithoutHolepunch, holepunchAddr) {
+                                       setAdd(&cl.accepted, holepunchAddr)
+                               }
+                               if g.MapContains(
+                                       cl.undialableWithoutHolepunchDialedAfterHolepunchConnect,
+                                       holepunchAddr,
+                               ) {
+                                       setAdd(&cl.probablyOnlyConnectedDueToHolepunch, holepunchAddr)
+                               }
+                               cl.unlock()
+                       }
+               }
                conn = pproffd.WrapNetConn(conn)
                cl.rLock()
                closed := cl.closed.IsSet()
@@ -516,20 +532,6 @@ func (cl *Client) acceptConnections(l Listener) {
                        log.Fmsg("error accepting connection: %s", err).LogLevel(log.Debug, cl.logger)
                        continue
                }
-               {
-                       holepunchAddr, holepunchErr := addrPortFromPeerRemoteAddr(conn.RemoteAddr())
-                       if holepunchErr == nil {
-                               cl.lock()
-                               if g.MapContains(
-                                       cl.undialableWithoutHolepunchDialedAfterHolepunchConnect,
-                                       holepunchAddr,
-                               ) {
-                                       g.MakeMapIfNil(&cl.probablyOnlyConnectedDueToHolepunch)
-                                       g.MapInsert(cl.probablyOnlyConnectedDueToHolepunch, holepunchAddr, struct{}{})
-                               }
-                               cl.unlock()
-                       }
-               }
                go func() {
                        if reject != nil {
                                torrent.Add("rejected accepted connections", 1)
@@ -761,17 +763,6 @@ func (cl *Client) dialAndCompleteHandshake(opts outgoingConnOpts) (c *PeerConn,
                }
        }
        holepunchAddr, holepunchAddrErr := addrPortFromPeerRemoteAddr(addr)
-       if holepunchAddrErr == nil && opts.receivedHolepunchConnect {
-               cl.lock()
-               if g.MapContains(cl.undialableWithoutHolepunch, holepunchAddr) {
-                       g.MakeMapIfNilAndSet(
-                               &cl.undialableWithoutHolepunchDialedAfterHolepunchConnect,
-                               holepunchAddr,
-                               struct{}{},
-                       )
-               }
-               cl.unlock()
-       }
        headerObfuscationPolicy := opts.HeaderObfuscationPolicy
        obfuscatedHeaderFirst := headerObfuscationPolicy.Preferred
        firstDialResult := dialPool.getFirst()
index 6cc2e87f1e6db865410a512c9125d631b3ed9e43..42a62fc1f3c99cbaa91508c97e85cd027eec930c 100644 (file)
@@ -2825,7 +2825,14 @@ func (t *Torrent) handleReceivedUtHolepunchMsg(msg utHolepunch.Msg, sender *Peer
                }
                return nil
        case utHolepunch.Connect:
-               t.logger.Printf("got holepunch connect request for %v from %p", msg.AddrPort, sender)
+               holepunchAddr := msg.AddrPort
+               t.logger.Printf("got holepunch connect request for %v from %p", holepunchAddr, sender)
+               if g.MapContains(t.cl.undialableWithoutHolepunch, holepunchAddr) {
+                       setAdd(&t.cl.undialableWithoutHolepunchDialedAfterHolepunchConnect, holepunchAddr)
+                       if g.MapContains(t.cl.accepted, holepunchAddr) {
+                               setAdd(&t.cl.probablyOnlyConnectedDueToHolepunch, holepunchAddr)
+                       }
+               }
                opts := outgoingConnOpts{
                        peerInfo: PeerInfo{
                                Addr:         msg.AddrPort,