Skip to content

Commit

Permalink
p2p/discover: fix deadlock in discv5 message dispatch (ethereum#21858)
Browse files Browse the repository at this point in the history
This fixes a deadlock that could occur when a response packet arrived
after a call had already received enough responses and was about to
signal completion to the dispatch loop.

Co-authored-by: Felix Lange <fjl@twurst.com>
  • Loading branch information
nisdas and fjl committed Nov 25, 2020
1 parent 810f9e0 commit 429e714
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions p2p/discover/v5_udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,20 @@ func (t *UDPv5) call(node *enode.Node, responseType byte, packet v5wire.Packet)

// callDone tells dispatch that the active call is done.
func (t *UDPv5) callDone(c *callV5) {
select {
case t.callDoneCh <- c:
case <-t.closeCtx.Done():
// This needs a loop because further responses may be incoming until the
// send to callDoneCh has completed. Such responses need to be discarded
// in order to avoid blocking the dispatch loop.
for {
select {
case <-c.ch:
// late response, discard.
case <-c.err:
// late error, discard.
case t.callDoneCh <- c:
return
case <-t.closeCtx.Done():
return
}
}
}

Expand Down

0 comments on commit 429e714

Please sign in to comment.