p2p/discover: fix deadlock in discv5 message dispatch (#21858)
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>
This commit is contained in:
parent
810f9e057d
commit
429e7141f2
@ -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.
|
// callDone tells dispatch that the active call is done.
|
||||||
func (t *UDPv5) callDone(c *callV5) {
|
func (t *UDPv5) callDone(c *callV5) {
|
||||||
select {
|
// This needs a loop because further responses may be incoming until the
|
||||||
case t.callDoneCh <- c:
|
// send to callDoneCh has completed. Such responses need to be discarded
|
||||||
case <-t.closeCtx.Done():
|
// 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user