]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Fix panic when sustaining unrejected requests after being choked
authorMatt Joiner <anacrolix@gmail.com>
Mon, 25 Oct 2021 02:00:56 +0000 (13:00 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 25 Oct 2021 02:00:56 +0000 (13:00 +1100)
Fixes https://github.com/anacrolix/torrent/issues/680.

peerconn.go
requesting.go

index 005c6b7d93f1c497b703f0a514f61861fd7a64cb..c1b98c2ade52405b3989fba3e736840db60069df 100644 (file)
@@ -556,6 +556,8 @@ func (pc *PeerConn) writeInterested(interested bool) bool {
 // are okay.
 type messageWriter func(pp.Message) bool
 
+// This function seems to only used by Peer.request. It's all logic checks, so maybe we can no-op it
+// when we want to go fast.
 func (cn *Peer) shouldRequest(r RequestIndex) error {
        pi := pieceIndex(r / cn.t.chunksPerRegularPiece())
        if !cn.peerHasPiece(pi) {
@@ -574,7 +576,11 @@ func (cn *Peer) shouldRequest(r RequestIndex) error {
                panic("piece is queued for hash")
        }
        if cn.peerChoking && !cn.peerAllowedFast.Contains(bitmap.BitIndex(pi)) {
-               panic("peer choking and piece not allowed fast")
+               // This could occur if we made a request with the fast extension, and then got choked and
+               // haven't had the request rejected yet.
+               if !cn.actualRequestState.Requests.Contains(r) {
+                       panic("peer choking and piece not allowed fast")
+               }
        }
        return nil
 }
index 6d707fdef229ab4605b978366987069458e45c15..1d2d5e19a455a8f7f893ae58171765829a35ea24 100644 (file)
@@ -216,8 +216,12 @@ func (p *Peer) getDesiredRequestState() (desired requestState) {
                        allowedFast := p.peerAllowedFast.ContainsInt(pieceIndex)
                        rsp.IterPendingChunks.Iter(func(ci request_strategy.ChunkIndex) {
                                if !allowedFast {
-                                       // We must signal interest to request this..
+                                       // We must signal interest to request this
                                        desired.Interested = true
+                                       // We can make or will allow sustaining a request here if we're not choked, or
+                                       // have made the request previously (presumably while unchoked), and haven't had
+                                       // the peer respond yet (and the request was retained because we are using the
+                                       // fast extension).
                                        if p.peerChoking && !p.actualRequestState.Requests.Contains(ci) {
                                                // We can't request this right now.
                                                return