@@ -315,8 +315,8 @@ func (a *addrsManager) updateAddrs(relayAddrs []ma.Multiaddr) hostAddrs {
315315 currReachableAddrs , currUnreachableAddrs , currUnknownAddrs = a .getConfirmedAddrs (localAddrs )
316316 }
317317 relayAddrs = slices .Clone (relayAddrs )
318- currAddrs := a .getAddrs ( slices . Clone ( localAddrs ) , relayAddrs )
319-
318+ currAddrs := a .getDialableAddrs ( localAddrs , currReachableAddrs , currUnreachableAddrs , relayAddrs )
319+ currAddrs = a . applyAddrsFactory ( currAddrs )
320320 a .addrsMx .Lock ()
321321 a .currentAddrs = hostAddrs {
322322 addrs : append (a .currentAddrs .addrs [:0 ], currAddrs ... ),
@@ -378,25 +378,36 @@ func (a *addrsManager) handleAddrsUpdated(emitter event.Emitter, localAddrsEmitt
378378// the node's relay addresses and private network addresses.
379379func (a * addrsManager ) Addrs () []ma.Multiaddr {
380380 a .addrsMx .RLock ()
381- directAddrs := slices .Clone (a .currentAddrs .localAddrs )
382- relayAddrs := slices .Clone (a .currentAddrs .relayAddrs )
381+ addrs := a .getDialableAddrs (a .currentAddrs .localAddrs , a .currentAddrs .reachableAddrs , a .currentAddrs .unreachableAddrs , a .currentAddrs .relayAddrs )
383382 a .addrsMx .RUnlock ()
384- return a .getAddrs (directAddrs , relayAddrs )
383+ // don't hold the lock while applying addrs factory
384+ return a .applyAddrsFactory (addrs )
385385}
386386
387- // getAddrs returns the node's dialable addresses. Mutates localAddrs
388- func (a * addrsManager ) getAddrs (localAddrs []ma.Multiaddr , relayAddrs []ma.Multiaddr ) []ma.Multiaddr {
389- addrs := localAddrs
390- rch := a .hostReachability .Load ()
391- if rch != nil && * rch == network .ReachabilityPrivate {
392- // Delete public addresses if the node's reachability is private, and we have relay addresses
393- if len (relayAddrs ) > 0 {
387+ // getDialableAddrs returns the node's dialable addrs. Doesn't mutate any argument.
388+ func (a * addrsManager ) getDialableAddrs (localAddrs , reachableAddrs , unreachableAddrs , relayAddrs []ma.Multiaddr ) []ma.Multiaddr {
389+ addrs := slices .Clone (localAddrs )
390+ // remove known unreachable addrs
391+ removeInSource (addrs , unreachableAddrs )
392+ // If we have no confirmed reachable addresses, add the relay addresses
393+ if a .addrsReachabilityTracker != nil {
394+ if len (reachableAddrs ) == 0 {
395+ addrs = append (addrs , relayAddrs ... )
396+ }
397+ } else {
398+ // If we're only using autonatv1, remove public addrs and add relay addrs
399+ if len (relayAddrs ) > 0 && * a .hostReachability .Load () == network .ReachabilityPrivate {
394400 addrs = slices .DeleteFunc (addrs , manet .IsPublicAddr )
395401 addrs = append (addrs , relayAddrs ... )
396402 }
397403 }
398- // Make a copy. Consumers can modify the slice elements
399- addrs = slices .Clone (a .addrsFactory (addrs ))
404+ return addrs
405+ }
406+
407+ func (a * addrsManager ) applyAddrsFactory (addrs []ma.Multiaddr ) []ma.Multiaddr {
408+ af := a .addrsFactory (addrs )
409+ // Copy to our slice in case addrsFactory returns its own same slice always.
410+ addrs = append (addrs [:0 ], af ... )
400411 // Add certhashes for the addresses provided by the user via address factory.
401412 addrs = a .addCertHashes (ma .Unique (addrs ))
402413 slices .SortFunc (addrs , func (a , b ma.Multiaddr ) int { return a .Compare (b ) })
@@ -872,6 +883,33 @@ func removeNotInSource(addrs, source []ma.Multiaddr) []ma.Multiaddr {
872883 return addrs [:i ]
873884}
874885
886+ // removeInSource removes items from addrs that are present in source.
887+ // Modifies the addrs slice in place
888+ // addrs and source must be sorted using multiaddr.Compare.
889+ func removeInSource (addrs , source []ma.Multiaddr ) []ma.Multiaddr {
890+ j := 0
891+ // mark entries in source as nil
892+ for i , a := range addrs {
893+ // move right in source as long as a > source[j]
894+ for j < len (source ) && a .Compare (source [j ]) > 0 {
895+ j ++
896+ }
897+ // a is in source, mark nil
898+ if j < len (source ) && a .Compare (source [j ]) == 0 {
899+ addrs [i ] = nil
900+ }
901+ }
902+ // j is the current element, i is the lowest index nil element
903+ i := 0
904+ for j := range len (addrs ) {
905+ if addrs [j ] != nil {
906+ addrs [i ], addrs [j ] = addrs [j ], addrs [i ]
907+ i ++
908+ }
909+ }
910+ return addrs [:i ]
911+ }
912+
875913type multiCloser []io.Closer
876914
877915func (mc * multiCloser ) Close () error {
0 commit comments