mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
p2p/nat: return exactly n random STUN servers on every call
randomServers drew indices with rand.Intn into a dedup map, bounded by len(serverList)*2 iterations. When n approaches the number of configured servers, repeated random collisions can exhaust the iteration budget before n unique servers are collected, so the function sometimes returns fewer servers than requested even though enough exist. For example, with 2 configured servers and requestLimit==3 (capped to 2), the four allowed draws can collide and yield only a single server. If that server is down, ExternalIP fails without ever trying the other. Replace the sampling loop with rand.Perm, which produces a uniform permutation of all indices in one pass. Slicing the first n entries always yields exactly min(n, len(serverList)) distinct servers, with no probabilistic shortfall.
This commit is contained in:
parent
eea6242742
commit
42c013f2af
1 changed files with 1 additions and 7 deletions
|
|
@ -91,15 +91,9 @@ func (s *stun) ExternalIP() (net.IP, error) {
|
||||||
|
|
||||||
func (s *stun) randomServers(n int) []string {
|
func (s *stun) randomServers(n int) []string {
|
||||||
n = min(n, len(s.serverList))
|
n = min(n, len(s.serverList))
|
||||||
m := make(map[int]struct{}, n)
|
|
||||||
list := make([]string, 0, n)
|
list := make([]string, 0, n)
|
||||||
for i := 0; i < len(s.serverList)*2 && len(list) < n; i++ {
|
for _, index := range rand.Perm(len(s.serverList))[:n] {
|
||||||
index := rand.Intn(len(s.serverList))
|
|
||||||
if _, alreadyHit := m[index]; alreadyHit {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
list = append(list, s.serverList[index])
|
list = append(list, s.serverList[index])
|
||||||
m[index] = struct{}{}
|
|
||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue