Skip to content

Commit

Permalink
Always count unhandled requests as pending
Browse files Browse the repository at this point in the history
Fixes #679.
  • Loading branch information
anacrolix committed Oct 25, 2021
1 parent 28726f7 commit e8067f7
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 32 deletions.
38 changes: 9 additions & 29 deletions peerconn.go
Original file line number Diff line number Diff line change
Expand Up @@ -1076,15 +1076,16 @@ func (c *PeerConn) mainReadLoop() (err error) {
if !c.fastEnabled() {
c.deleteAllRequests()
} else {
c.actualRequestState.Requests.Iterate(func(x uint32) bool {
if !c.peerAllowedFast.Contains(x / c.t.chunksPerRegularPiece()) {
c.t.pendingRequests.Dec(x)
}
return true
})
// We don't decrement pending requests here, let's wait for the peer to either
// reject or satisfy the outstanding requests. Additionally some peers may unchoke
// us and resume where they left off, we don't want to have piled on to those chunks
// in the meanwhile. I think a peers ability to abuse this should be limited: they
// could let us request a lot of stuff, then choke us and never reject, but they're
// only a single peer, our chunk balancing should smooth over this abuse.
}
c.peerChoking = true
// We can then reset our interest.
// We can now reset our interest. I think we do this after setting the flag in case the
// peerImpl updates synchronously (webseeds?).
c.updateRequests("choked")
c.updateExpectingChunks()
case pp.Unchoke:
Expand All @@ -1099,7 +1100,6 @@ func (c *PeerConn) mainReadLoop() (err error) {
c.actualRequestState.Requests.Iterate(func(x uint32) bool {
if !c.peerAllowedFast.Contains(x / c.t.chunksPerRegularPiece()) {
preservedCount++
c.t.pendingRequests.Inc(x)
}
return true
})
Expand Down Expand Up @@ -1169,24 +1169,6 @@ func (c *PeerConn) mainReadLoop() (err error) {
case pp.AllowedFast:
torrent.Add("allowed fasts received", 1)
log.Fmsg("peer allowed fast: %d", msg.Index).AddValues(c).SetLevel(log.Debug).Log(c.t.logger)
pieceIndex := msg.Index.Int()
// If we have outstanding requests that aren't currently counted toward the combined
// outstanding request count, increment them.
if c.peerAllowedFast.CheckedAdd(msg.Index.Uint32()) && c.peerChoking &&
// The check here could be against having the info, but really what we need to know
// is if there are any existing requests.
!c.actualRequestState.Requests.IsEmpty() {

i := c.actualRequestState.Requests.Iterator()
i.AdvanceIfNeeded(t.pieceRequestIndexOffset(pieceIndex))
for i.HasNext() {
r := i.Next()
if r >= t.pieceRequestIndexOffset(pieceIndex+1) {
break
}
c.t.pendingRequests.Inc(r)
}
}
c.updateRequests("PeerConn.mainReadLoop allowed fast")
case pp.Extended:
err = c.onReadExtendedMsg(msg.ExtendedID, msg.ExtendedPayload)
Expand Down Expand Up @@ -1534,9 +1516,7 @@ func (c *Peer) deleteRequest(r RequestIndex) bool {
f(PeerRequestEvent{c, c.t.requestIndexToRequest(r)})
}
c.updateExpectingChunks()
if !c.peerChoking || c.peerAllowedFast.Contains(r/c.t.chunksPerRegularPiece()) {
c.t.pendingRequests.Dec(r)
}
c.t.pendingRequests.Dec(r)
return true
}

Expand Down
5 changes: 2 additions & 3 deletions requesting.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,8 @@ func (p *peerRequests) Less(i, j int) bool {
if current {
ret--
}
// I have a hunch that this could trigger for requests for chunks that are choked and not
// allowed fast, since the current conn shouldn't already be included. It's a very specific
// circumstance, and if it triggers I will fix it.
// See https://github.com/anacrolix/torrent/issues/679 for possible issues. This should be
// resolved.
if ret < 0 {
panic(ret)
}
Expand Down

0 comments on commit e8067f7

Please sign in to comment.