p2p/discover: apply same fix to gotreply and resetTimeout loops

Both loops also called plist.Remove(el) while iterating with
  el = el.Next(), which invalidates the link and skips the rest
  of the list. Save el.Next() before removal like the timeout loop.
This commit is contained in:
Tanvir 2026-04-22 22:30:49 +08:00
parent a37824d1f8
commit 8def19181a

View file

@ -446,7 +446,8 @@ func (t *UDPv4) loop() {
} }
// Start the timer so it fires when the next pending reply has expired. // Start the timer so it fires when the next pending reply has expired.
now := time.Now() now := time.Now()
for el := plist.Front(); el != nil; el = el.Next() { for el := plist.Front(); el != nil; {
next := el.Next()
nextTimeout = el.Value.(*replyMatcher) nextTimeout = el.Value.(*replyMatcher)
if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout { if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout {
timeout.Reset(dist) timeout.Reset(dist)
@ -457,6 +458,7 @@ func (t *UDPv4) loop() {
// backwards after the deadline was assigned. // backwards after the deadline was assigned.
nextTimeout.errc <- errClockWarp nextTimeout.errc <- errClockWarp
plist.Remove(el) plist.Remove(el)
el = next
} }
nextTimeout = nil nextTimeout = nil
timeout.Stop() timeout.Stop()
@ -478,7 +480,8 @@ func (t *UDPv4) loop() {
case r := <-t.gotreply: case r := <-t.gotreply:
var matched bool // whether any replyMatcher considered the reply acceptable. var matched bool // whether any replyMatcher considered the reply acceptable.
for el := plist.Front(); el != nil; el = el.Next() { for el := plist.Front(); el != nil; {
next := el.Next()
p := el.Value.(*replyMatcher) p := el.Value.(*replyMatcher)
if p.from == r.from && p.ptype == r.data.Kind() && p.ip == r.ip { if p.from == r.from && p.ptype == r.data.Kind() && p.ip == r.ip {
ok, requestDone := p.callback(r.data) ok, requestDone := p.callback(r.data)
@ -492,6 +495,7 @@ func (t *UDPv4) loop() {
// Reset the continuous timeout counter (time drift detection) // Reset the continuous timeout counter (time drift detection)
contTimeouts = 0 contTimeouts = 0
} }
el = next
} }
r.matched <- matched r.matched <- matched