From 290843c0e3b1f5303264c19703e3302faa08f67e Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Thu, 31 Jul 2025 11:52:19 +1000 Subject: [PATCH] Prevent webseed requests when torrent data download disallowed --- piece.go | 2 +- webseed-peer.go | 4 +++- webseed-requesting.go | 13 ++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/piece.go b/piece.go index 166da4d4..12d28be2 100644 --- a/piece.go +++ b/piece.go @@ -292,7 +292,7 @@ func (p *Piece) purePriority() (ret PiecePriority) { } func (p *Piece) ignoreForRequests() bool { - return p.hashing || p.marking || !p.haveHash() || p.t.pieceComplete(p.index) || p.queuedForHash() + return p.hashing || p.marking || !p.haveHash() || p.t.pieceComplete(p.index) || p.queuedForHash() || p.t.dataDownloadDisallowed.IsSet() } // This is the priority adjusted for piece state like completion, hashing etc. diff --git a/webseed-peer.go b/webseed-peer.go index 9b64680f..d32aab93 100644 --- a/webseed-peer.go +++ b/webseed-peer.go @@ -52,7 +52,9 @@ func (me *webseedPeer) isLowOnRequests() bool { } // Webseed requests are issued globally so per-connection reasons or handling make no sense. -func (me *webseedPeer) onNeedUpdateRequests(updateRequestReason) {} +func (me *webseedPeer) onNeedUpdateRequests(updateRequestReason) { + me.peer.cl.scheduleImmediateWebseedRequestUpdate() +} func (me *webseedPeer) expectingChunks() bool { return len(me.activeRequests) > 0 diff --git a/webseed-requesting.go b/webseed-requesting.go index a386e091..48d7eea4 100644 --- a/webseed-requesting.go +++ b/webseed-requesting.go @@ -102,6 +102,10 @@ func (cl *Client) updateWebseedRequests() { } // Add remaining existing requests. for key := range unusedExistingRequests { + // Don't reconsider existing requests that aren't wanted anymore. + if key.t.dataDownloadDisallowed.IsSet() { + continue + } heapSlice = append(heapSlice, heapElem{key, existingRequests[key]}) } aprioriHeap := heap.InterfaceForSlice( @@ -136,6 +140,12 @@ func (cl *Client) updateWebseedRequests() { // handling overhead. Need the value to avoid looking this up again. costKey := elem.costKey panicif.Zero(costKey) + if elem.existingWebseedRequest == nil { + // Existing requests might be within the allowed discard range. + panicif.Eq(elem.priority, PiecePriorityNone) + } + panicif.True(elem.t.dataDownloadDisallowed.IsSet()) + panicif.True(elem.t.closed.IsSet()) if len(plan.byCost[costKey]) >= webseedHostRequestConcurrency { continue } @@ -363,7 +373,8 @@ func (cl *Client) scheduleImmediateWebseedRequestUpdate() { } // Set the timer to fire right away (this will coalesce consecutive updates without forcing an // update on every call to this method). Since we're holding the Client lock, and we cancelled - // the timer, and it wasn't active, nobody else should have reset it before us. + // the timer, and it wasn't active, nobody else should have reset it before us. Do we need to + // introduce a "reason" field here, (albeit Client-level?). panicif.True(cl.webseedRequestTimer.Reset(0)) } -- 2.51.0