Skip to content

fix: race condition on connIdIssued in Client.request#1039

Merged
anacrolix merged 7 commits intoanacrolix:masterfrom
Giulio2002:fix-udp-client-race
Feb 26, 2026
Merged

fix: race condition on connIdIssued in Client.request#1039
anacrolix merged 7 commits intoanacrolix:masterfrom
Giulio2002:fix-udp-client-race

Conversation

@Giulio2002
Copy link
Contributor

Problem

The write to connIdIssued in Client.request() (line 235) on error response (Connection ID mismatch) is not protected by the client mutex. This races with concurrent requestWriter goroutines that read connIdIssued via writeRequestconnectshouldReconnect, which do hold the lock.

When multiple announce goroutines are spawned by startAnnounce(), they share the same Client and can concurrently enter request(). If two of them receive error responses simultaneously, both write to connIdIssued without synchronization.

Race detected with -race:

Write at 0x00c0f5193528 by goroutine 60999585:
  github.com/anacrolix/torrent/tracker/udp.(*Client).request()
    tracker/udp/client.go:235

Previous write at 0x00c0f5193528 by goroutine 60999531:
  github.com/anacrolix/torrent/tracker/udp.(*Client).request()
    tracker/udp/client.go:235

Fix

Acquire cl.mu before writing connIdIssued = time.Time{} in the error response handler, matching the locking discipline used by writeRequest when reading the same field.

Uses LockCtx(ctx) so the lock attempt is cancelled if the context is already done.

Fixes erigontech/erigon#18901

Giulio2002 and others added 5 commits February 20, 2026 16:49
The write to connIdIssued on error response (Connection ID mismatch)
was not protected by the client mutex, racing with concurrent
requestWriter goroutines that read connIdIssued via writeRequest ->
connect -> shouldReconnect (which do hold the lock).

Fixes erigontech/erigon#18901
_pendingPieces.Add(0) was called without holding the client lock and
without updating the piece request order, causing two issues:
1. Data race with timer goroutines accessing the roaring bitmap
2. Panic in checkPendingPiecesMatchesRequestOrder due to _pendingPieces
   and requestOrder being out of sync

Replace the direct bitmap manipulation with updatePiecePriority(0, ...)
which properly updates both _pendingPieces and the piece request order
while holding the client lock.

Co-authored-by: info@weblogix.biz <admin@10gbps.weblogix.it>
Co-authored-by: Matt Joiner <anacrolix@gmail.com>
@anacrolix anacrolix merged commit b14abfc into anacrolix:master Feb 26, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

p2p: race in main

2 participants