Skip to content

Commit a0a3297

Browse files
committed
fix: preserve next element when removing expired matchers
1 parent 5b0ba8d commit a0a3297

2 files changed

Lines changed: 19 additions & 7 deletions

File tree

p2p/discover/common.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
package discover
2121

2222
import (
23+
"container/list"
2324
"crypto/ecdsa"
2425
crand "crypto/rand"
2526
"encoding/binary"
27+
"iter"
2628
"math/rand"
2729
"net"
2830
"net/netip"
@@ -146,3 +148,16 @@ func (r *reseedingRandom) Shuffle(n int, swap func(i, j int)) {
146148
defer r.mu.Unlock()
147149
r.cur.Shuffle(n, swap)
148150
}
151+
152+
// iterList iterates over the elements of the given list.
153+
func iterList[T any](l *list.List) iter.Seq2[T, *list.Element] {
154+
return func(yield func(T, *list.Element) bool) {
155+
for el := l.Front(); el != nil; {
156+
next := el.Next()
157+
if !yield(el.Value.(T), el) {
158+
return
159+
}
160+
el = next
161+
}
162+
}
163+
}

p2p/discover/v4_udp.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -452,9 +452,8 @@ func (t *UDPv4) loop() {
452452
}
453453
// Start the timer so it fires when the next pending reply has expired.
454454
now := time.Now()
455-
for el := plist.Front(); el != nil; el = el.Next() {
456-
nextTimeout = el.Value.(*replyMatcher)
457-
if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout {
455+
for p, el := range iterList[*replyMatcher](plist) {
456+
if dist := p.deadline.Sub(now); dist < 2*respTimeout {
458457
timeout.Reset(dist)
459458
return
460459
}
@@ -484,8 +483,7 @@ func (t *UDPv4) loop() {
484483

485484
case r := <-t.gotreply:
486485
var matched bool // whether any replyMatcher considered the reply acceptable.
487-
for el := plist.Front(); el != nil; el = el.Next() {
488-
p := el.Value.(*replyMatcher)
486+
for p, el := range iterList[*replyMatcher](plist) {
489487
if p.from == r.from && p.ptype == r.data.Kind() && p.ip == r.ip {
490488
ok, requestDone := p.callback(r.data)
491489
matched = matched || ok
@@ -505,8 +503,7 @@ func (t *UDPv4) loop() {
505503
nextTimeout = nil
506504

507505
// Notify and remove callbacks whose deadline is in the past.
508-
for el := plist.Front(); el != nil; el = el.Next() {
509-
p := el.Value.(*replyMatcher)
506+
for p, el := range iterList[*replyMatcher](plist) {
510507
if now.After(p.deadline) || now.Equal(p.deadline) {
511508
p.errc <- errTimeout
512509
plist.Remove(el)

0 commit comments

Comments
 (0)