Skip to content

Commit 9c625fa

Browse files
committed
basichost: don't advertise unreachable addrs.
1 parent d2e6f83 commit 9c625fa

File tree

2 files changed

+53
-15
lines changed

2 files changed

+53
-15
lines changed

p2p/host/basic/addrs_manager.go

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,8 @@ func (a *addrsManager) updateAddrs(relayAddrs []ma.Multiaddr) hostAddrs {
414414
currReachableAddrs, currUnreachableAddrs, currUnknownAddrs = a.getConfirmedAddrs(localAddrs)
415415
}
416416
relayAddrs = slices.Clone(relayAddrs)
417-
currAddrs := a.getAddrs(slices.Clone(localAddrs), relayAddrs)
418-
417+
currAddrs := a.getDialableAddrs(localAddrs, currReachableAddrs, currUnreachableAddrs, relayAddrs)
418+
currAddrs = a.applyAddrsFactory(currAddrs)
419419
a.addrsMx.Lock()
420420
a.currentAddrs = hostAddrs{
421421
addrs: append(a.currentAddrs.addrs[:0], currAddrs...),
@@ -479,25 +479,36 @@ func (a *addrsManager) notifyAddrsChanged(emitter event.Emitter, localAddrsEmitt
479479
// the node's relay addresses and private network addresses.
480480
func (a *addrsManager) Addrs() []ma.Multiaddr {
481481
a.addrsMx.RLock()
482-
directAddrs := slices.Clone(a.currentAddrs.localAddrs)
483-
relayAddrs := slices.Clone(a.currentAddrs.relayAddrs)
482+
addrs := a.getDialableAddrs(a.currentAddrs.localAddrs, a.currentAddrs.reachableAddrs, a.currentAddrs.unreachableAddrs, a.currentAddrs.relayAddrs)
484483
a.addrsMx.RUnlock()
485-
return a.getAddrs(directAddrs, relayAddrs)
484+
// don't hold the lock while applying addrs factory
485+
return a.applyAddrsFactory(addrs)
486486
}
487487

488-
// getAddrs returns the node's dialable addresses. Mutates localAddrs
489-
func (a *addrsManager) getAddrs(localAddrs []ma.Multiaddr, relayAddrs []ma.Multiaddr) []ma.Multiaddr {
490-
addrs := localAddrs
491-
rch := a.hostReachability.Load()
492-
if rch != nil && *rch == network.ReachabilityPrivate {
493-
// Delete public addresses if the node's reachability is private, and we have relay addresses
494-
if len(relayAddrs) > 0 {
488+
// getDialableAddrs returns the node's dialable addrs. Doesn't mutate any argument.
489+
func (a *addrsManager) getDialableAddrs(localAddrs, reachableAddrs, unreachableAddrs, relayAddrs []ma.Multiaddr) []ma.Multiaddr {
490+
addrs := slices.Clone(localAddrs)
491+
// remove known unreachable addrs
492+
removeInSource(addrs, unreachableAddrs)
493+
// If we have no confirmed reachable addresses, add the relay addresses
494+
if a.addrsReachabilityTracker != nil {
495+
if len(reachableAddrs) == 0 {
496+
addrs = append(addrs, relayAddrs...)
497+
}
498+
} else {
499+
// If we're only using autonatv1, remove public addrs and add relay addrs
500+
if len(relayAddrs) > 0 && *a.hostReachability.Load() == network.ReachabilityPrivate {
495501
addrs = slices.DeleteFunc(addrs, manet.IsPublicAddr)
496502
addrs = append(addrs, relayAddrs...)
497503
}
498504
}
499-
// Make a copy. Consumers can modify the slice elements
500-
addrs = slices.Clone(a.addrsFactory(addrs))
505+
return addrs
506+
}
507+
508+
func (a *addrsManager) applyAddrsFactory(addrs []ma.Multiaddr) []ma.Multiaddr {
509+
af := a.addrsFactory(addrs)
510+
// Copy to our slice in case addrsFactory returns its own same slice always.
511+
addrs = append(addrs[:0], af...)
501512
// Add certhashes for the addresses provided by the user via address factory.
502513
addrs = a.addCertHashes(ma.Unique(addrs))
503514
slices.SortFunc(addrs, func(a, b ma.Multiaddr) int { return a.Compare(b) })
@@ -980,3 +991,30 @@ func removeNotInSource(addrs, source []ma.Multiaddr) []ma.Multiaddr {
980991
}
981992
return addrs[:i]
982993
}
994+
995+
// removeInSource removes items from addrs that are present in source.
996+
// Modifies the addrs slice in place
997+
// addrs and source must be sorted using multiaddr.Compare.
998+
func removeInSource(addrs, source []ma.Multiaddr) []ma.Multiaddr {
999+
j := 0
1000+
// mark entries in source as nil
1001+
for i, a := range addrs {
1002+
// move right in source as long as a > source[j]
1003+
for j < len(source) && a.Compare(source[j]) > 0 {
1004+
j++
1005+
}
1006+
// a is in source, mark nil
1007+
if j < len(source) && a.Compare(source[j]) == 0 {
1008+
addrs[i] = nil
1009+
}
1010+
}
1011+
// j is the current element, i is the lowest index nil element
1012+
i := 0
1013+
for j := range len(addrs) {
1014+
if addrs[j] != nil {
1015+
addrs[i], addrs[j] = addrs[j], addrs[i]
1016+
i++
1017+
}
1018+
}
1019+
return addrs[:i]
1020+
}

p2p/host/basic/addrs_manager_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,6 @@ func BenchmarkUpdateAddrs(b *testing.B) {
516516
b.ReportAllocs()
517517
b.ResetTimer()
518518
for i := 0; i < b.N; i++ {
519-
am.updateAddrs(false, nil)
519+
am.updateAddrs(nil)
520520
}
521521
}

0 commit comments

Comments
 (0)