Skip to content

Commit 0ac09cd

Browse files
committed
basichost: don't advertise unreachable addrs.
1 parent 1c6037b commit 0ac09cd

File tree

1 file changed

+52
-14
lines changed

1 file changed

+52
-14
lines changed

p2p/host/basic/addrs_manager.go

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,13 @@ func (a *addrsManager) updateAddrs(prevHostAddrs hostAddrs, relayAddrs []ma.Mult
317317
currReachableAddrs, currUnreachableAddrs, currUnknownAddrs = a.getConfirmedAddrs(localAddrs)
318318
}
319319
relayAddrs = slices.Clone(relayAddrs)
320-
currAddrs := a.getAddrs(slices.Clone(localAddrs), relayAddrs)
320+
currAddrs := a.getDialableAddrs(localAddrs, currReachableAddrs, currUnreachableAddrs, relayAddrs)
321+
currAddrs = a.applyAddrsFactory(currAddrs)
321322

322323
if areAddrsDifferent(prevHostAddrs.addrs, currAddrs) {
323324
_, _, removed := diffAddrs(prevHostAddrs.addrs, currAddrs)
324325
a.updatePeerStore(currAddrs, removed)
325326
}
326-
327327
a.addrsMx.Lock()
328328
a.currentAddrs = hostAddrs{
329329
addrs: append(a.currentAddrs.addrs[:0], currAddrs...),
@@ -410,25 +410,36 @@ func (a *addrsManager) notifyAddrsUpdated(emitter event.Emitter, localAddrsEmitt
410410
// the node's relay addresses and private network addresses.
411411
func (a *addrsManager) Addrs() []ma.Multiaddr {
412412
a.addrsMx.RLock()
413-
directAddrs := slices.Clone(a.currentAddrs.localAddrs)
414-
relayAddrs := slices.Clone(a.currentAddrs.relayAddrs)
413+
addrs := a.getDialableAddrs(a.currentAddrs.localAddrs, a.currentAddrs.reachableAddrs, a.currentAddrs.unreachableAddrs, a.currentAddrs.relayAddrs)
415414
a.addrsMx.RUnlock()
416-
return a.getAddrs(directAddrs, relayAddrs)
415+
// don't hold the lock while applying addrs factory
416+
return a.applyAddrsFactory(addrs)
417417
}
418418

419-
// getAddrs returns the node's dialable addresses. Mutates localAddrs
420-
func (a *addrsManager) getAddrs(localAddrs []ma.Multiaddr, relayAddrs []ma.Multiaddr) []ma.Multiaddr {
421-
addrs := localAddrs
422-
rch := a.hostReachability.Load()
423-
if rch != nil && *rch == network.ReachabilityPrivate {
424-
// Delete public addresses if the node's reachability is private, and we have relay addresses
425-
if len(relayAddrs) > 0 {
419+
// getDialableAddrs returns the node's dialable addrs. Doesn't mutate any argument.
420+
func (a *addrsManager) getDialableAddrs(localAddrs, reachableAddrs, unreachableAddrs, relayAddrs []ma.Multiaddr) []ma.Multiaddr {
421+
addrs := slices.Clone(localAddrs)
422+
// remove known unreachable addrs
423+
removeInSource(addrs, unreachableAddrs)
424+
// If we have no confirmed reachable addresses, add the relay addresses
425+
if a.addrsReachabilityTracker != nil {
426+
if len(reachableAddrs) == 0 {
427+
addrs = append(addrs, relayAddrs...)
428+
}
429+
} else {
430+
// If we're only using autonatv1, remove public addrs and add relay addrs
431+
if len(relayAddrs) > 0 && *a.hostReachability.Load() == network.ReachabilityPrivate {
426432
addrs = slices.DeleteFunc(addrs, manet.IsPublicAddr)
427433
addrs = append(addrs, relayAddrs...)
428434
}
429435
}
430-
// Make a copy. Consumers can modify the slice elements
431-
addrs = slices.Clone(a.addrsFactory(addrs))
436+
return addrs
437+
}
438+
439+
func (a *addrsManager) applyAddrsFactory(addrs []ma.Multiaddr) []ma.Multiaddr {
440+
af := a.addrsFactory(addrs)
441+
// Copy to our slice in case addrsFactory returns its own same slice always.
442+
addrs = append(addrs[:0], af...)
432443
// Add certhashes for the addresses provided by the user via address factory.
433444
addrs = a.addCertHashes(ma.Unique(addrs))
434445
slices.SortFunc(addrs, func(a, b ma.Multiaddr) int { return a.Compare(b) })
@@ -880,6 +891,33 @@ func removeNotInSource(addrs, source []ma.Multiaddr) []ma.Multiaddr {
880891
return addrs[:i]
881892
}
882893

894+
// removeInSource removes items from addrs that are present in source.
895+
// Modifies the addrs slice in place
896+
// addrs and source must be sorted using multiaddr.Compare.
897+
func removeInSource(addrs, source []ma.Multiaddr) []ma.Multiaddr {
898+
j := 0
899+
// mark entries in source as nil
900+
for i, a := range addrs {
901+
// move right in source as long as a > source[j]
902+
for j < len(source) && a.Compare(source[j]) > 0 {
903+
j++
904+
}
905+
// a is in source, mark nil
906+
if j < len(source) && a.Compare(source[j]) == 0 {
907+
addrs[i] = nil
908+
}
909+
}
910+
// j is the current element, i is the lowest index nil element
911+
i := 0
912+
for j := range len(addrs) {
913+
if addrs[j] != nil {
914+
addrs[i], addrs[j] = addrs[j], addrs[i]
915+
i++
916+
}
917+
}
918+
return addrs[:i]
919+
}
920+
883921
type multiCloser []io.Closer
884922

885923
func (mc *multiCloser) Close() error {

0 commit comments

Comments
 (0)