]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Fixes for webseed peers not having request state
authorMatt Joiner <anacrolix@gmail.com>
Fri, 4 Jul 2025 06:13:59 +0000 (16:13 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Fri, 4 Jul 2025 06:13:59 +0000 (16:13 +1000)
conn-stats.go
peer-impl.go
peer.go
peerconn.go
webseed-peer.go

index c574a4d048e501caa458e6a926f6ed8a635dd226..12e00287686a1f3c64728c5437504a2f9a392d12 100644 (file)
@@ -8,9 +8,10 @@ import (
 
 // Various connection-level metrics. At the Torrent level these are aggregates. Chunks are messages
 // with data payloads. Data is actual torrent content without any overhead. Useful is something we
-// needed locally. Unwanted is something we didn't ask for (but may still be useful). Written is
-// things sent to the peer, and Read is stuff received from them. Due to the implementation of
-// Count, must be aligned on some platforms: See https://github.com/anacrolix/torrent/issues/262.
+// needed locally. Intended is something we were expecting (I think such as when we cancel a request
+// but it arrives anyway). Written is things sent to the peer, and Read is stuff received from them.
+// Due to the implementation of Count, must be aligned on some platforms: See
+// https://github.com/anacrolix/torrent/issues/262.
 type ConnStats struct {
        // Total bytes on the wire. Includes handshakes and encryption.
        BytesWritten     Count
index 7cd2d57c8c66b4e4679e2de3c393103749f9cdbf..5586e43b4270cb2c1afa1d1c7b7eae1e3e22f58a 100644 (file)
@@ -2,6 +2,7 @@ package torrent
 
 import (
        "github.com/RoaringBitmap/roaring"
+       pp "github.com/anacrolix/torrent/peer_protocol"
 
        "github.com/anacrolix/torrent/metainfo"
 )
@@ -44,7 +45,7 @@ type legacyPeerImpl interface {
 type newHotPeerImpl interface {
        lastWriteUploadRate() float64
        // Bookkeeping for a chunk being received and any specific checks.
-       checkReceivedChunk(ri RequestIndex) error
+       checkReceivedChunk(ri RequestIndex, msg *pp.Message, req Request) (intended bool, err error)
        // Whether we're expecting to receive chunks because we have outstanding requests. Used for
        // example to calculate download rate.
        expectingChunks() bool
diff --git a/peer.go b/peer.go
index 2d79a4bf0c070239a2baa493bfd45dd634465f94..9b031fb82cf6d168c875500c006e6da4de9947f5 100644 (file)
--- a/peer.go
+++ b/peer.go
@@ -626,36 +626,11 @@ func (c *Peer) receiveChunk(msg *pp.Message) error {
                ChunksReceived.Add("while choked", 1)
        }
 
-       err = c.peerImpl.checkReceivedChunk(req)
+       intended, err := c.peerImpl.checkReceivedChunk(req, msg, ppReq)
        if err != nil {
                return err
        }
 
-       if c.peerChoking && c.peerAllowedFast.Contains(pieceIndex(ppReq.Index)) {
-               ChunksReceived.Add("due to allowed fast", 1)
-       }
-
-       // The request needs to be deleted immediately to prevent cancels occurring asynchronously when
-       // have actually already received the piece, while we have the Client unlocked to write the data
-       // out.
-       intended := false
-       {
-               if c.requestState.Requests.Contains(req) {
-                       for _, f := range c.callbacks.ReceivedRequested {
-                               f(PeerMessageEvent{c, msg})
-                       }
-               }
-               // Request has been satisfied.
-               if c.deleteRequest(req) || c.requestState.Cancelled.CheckedRemove(req) {
-                       intended = true
-                       if c.isLowOnRequests() {
-                               c.onNeedUpdateRequests("Peer.receiveChunk deleted request")
-                       }
-               } else {
-                       ChunksReceived.Add("unintended", 1)
-               }
-       }
-
        cl := t.cl
 
        // Do we actually want this chunk?
index 95d7972c7788691fdf42439d94f5c3e35f052f8e..5ccf23cec4cdab7179f3b2e2932184ff3c859d73 100644 (file)
@@ -1492,11 +1492,36 @@ func (me *PeerConn) setPeerLoggers(a log.Logger, s *slog.Logger) {
        me.protocolLogger = me.logger.WithNames(protocolLoggingName)
 }
 
-func (c *PeerConn) checkReceivedChunk(req RequestIndex) error {
+func (c *PeerConn) checkReceivedChunk(req RequestIndex, msg *pp.Message, ppReq Request) (intended bool, err error) {
        if c.validReceiveChunks[req] <= 0 {
                ChunksReceived.Add("unexpected", 1)
-               return errors.New("received unexpected chunk")
+               err = errors.New("received unexpected chunk")
+               return
        }
        c.decExpectedChunkReceive(req)
-       return nil
+
+       if c.peerChoking && c.peerAllowedFast.Contains(pieceIndex(ppReq.Index)) {
+               ChunksReceived.Add("due to allowed fast", 1)
+       }
+       // The request needs to be deleted immediately to prevent cancels occurring asynchronously when
+       // have actually already received the piece, while we have the Client unlocked to write the data
+       // out.
+       {
+               if c.requestState.Requests.Contains(req) {
+                       for _, f := range c.callbacks.ReceivedRequested {
+                               f(PeerMessageEvent{c.peerPtr(), msg})
+                       }
+               }
+               // Request has been satisfied.
+               if c.deleteRequest(req) || c.requestState.Cancelled.CheckedRemove(req) {
+                       intended = true
+                       if c.isLowOnRequests() {
+                               c.onNeedUpdateRequests("Peer.receiveChunk deleted request")
+                       }
+               } else {
+                       ChunksReceived.Add("unintended", 1)
+               }
+       }
+
+       return
 }
index 6fd865b2aad833f30fb2ba1deb35ebb454532661..45b8c9be8a90a45fa778ad1b9895e0b9d5aadb09 100644 (file)
@@ -41,8 +41,8 @@ func (me *webseedPeer) expectingChunks() bool {
        return len(me.activeRequests) > 0
 }
 
-func (me *webseedPeer) checkReceivedChunk(ri RequestIndex) error {
-       return nil
+func (me *webseedPeer) checkReceivedChunk(RequestIndex, *pp.Message, Request) (bool, error) {
+       return true, nil
 }
 
 func (me *webseedPeer) numRequests() int {
@@ -121,7 +121,7 @@ func (ws *webseedPeer) spawnRequest(begin, end RequestIndex) {
                "begin", begin,
                "end", end,
                "len", end-begin,
-               "avail", ws.peer.requestState.Requests.GetCardinality())
+       )
        go ws.runRequest(&wsReq)
 }