"io"
"net"
"strings"
+ "sync"
"time"
"github.com/RoaringBitmap/roaring"
}
req := c.t.requestIndexFromRequest(ppReq)
- if c.bannableAddr.Ok {
- t.smartBanCache.RecordBlock(c.bannableAddr.Value, req, msg.Piece)
- }
+ recordBlockForSmartBan := sync.OnceFunc(func() {
+ c.recordBlockForSmartBan(req, msg.Piece)
+ })
+ // This needs to occur before we return, but we try to do it when the client is unlocked. It
+ // can't be done before checking if chunks are valid because they won't be deallocated by piece
+ // hashing if they're out of bounds.
+ defer recordBlockForSmartBan()
if c.peerChoking {
chunksReceived.Add("while choked", 1)
err = func() error {
cl.unlock()
defer cl.lock()
+ // Opportunistically do this here while we aren't holding the client lock.
+ recordBlockForSmartBan()
concurrentChunkWrites.Add(1)
defer concurrentChunkWrites.Add(-1)
// Write the chunk out. Note that the upper bound on chunk writing concurrency will be the
// }
p.peakRequests--
}
+
+func (p *Peer) recordBlockForSmartBan(req RequestIndex, blockData []byte) {
+ if p.bannableAddr.Ok {
+ p.t.smartBanCache.RecordBlock(p.bannableAddr.Value, req, blockData)
+ }
+}