@@ -317,13 +317,13 @@ func (a *addrsManager) updateAddrs(prevHostAddrs hostAddrs, relayAddrs []ma.Mult
317
317
currReachableAddrs , currUnreachableAddrs , currUnknownAddrs = a .getConfirmedAddrs (localAddrs )
318
318
}
319
319
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 )
321
322
322
323
if areAddrsDifferent (prevHostAddrs .addrs , currAddrs ) {
323
324
_ , _ , removed := diffAddrs (prevHostAddrs .addrs , currAddrs )
324
325
a .updatePeerStore (currAddrs , removed )
325
326
}
326
-
327
327
a .addrsMx .Lock ()
328
328
a .currentAddrs = hostAddrs {
329
329
addrs : append (a .currentAddrs .addrs [:0 ], currAddrs ... ),
@@ -410,25 +410,35 @@ func (a *addrsManager) notifyAddrsUpdated(emitter event.Emitter, localAddrsEmitt
410
410
// the node's relay addresses and private network addresses.
411
411
func (a * addrsManager ) Addrs () []ma.Multiaddr {
412
412
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 )
415
414
a .addrsMx .RUnlock ()
416
- return a .getAddrs (directAddrs , relayAddrs )
415
+ // don't hold the lock while applying addrs factory
416
+ return a .applyAddrsFactory (addrs )
417
417
}
418
418
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
+ // remove known unreachable addrs
422
+ addrs := removeInSource (slices .Clone (localAddrs ), unreachableAddrs )
423
+ // If we have no confirmed reachable addresses, add the relay addresses
424
+ if a .addrsReachabilityTracker != nil {
425
+ if len (reachableAddrs ) == 0 {
426
+ addrs = append (addrs , relayAddrs ... )
427
+ }
428
+ } else {
429
+ // If we're only using autonatv1, remove public addrs and add relay addrs
430
+ if len (relayAddrs ) > 0 && * a .hostReachability .Load () == network .ReachabilityPrivate {
426
431
addrs = slices .DeleteFunc (addrs , manet .IsPublicAddr )
427
432
addrs = append (addrs , relayAddrs ... )
428
433
}
429
434
}
430
- // Make a copy. Consumers can modify the slice elements
431
- addrs = slices .Clone (a .addrsFactory (addrs ))
435
+ return addrs
436
+ }
437
+
438
+ func (a * addrsManager ) applyAddrsFactory (addrs []ma.Multiaddr ) []ma.Multiaddr {
439
+ af := a .addrsFactory (addrs )
440
+ // Copy to our slice in case addrsFactory returns its own same slice always.
441
+ addrs = append (addrs [:0 ], af ... )
432
442
// Add certhashes for the addresses provided by the user via address factory.
433
443
addrs = a .addCertHashes (ma .Unique (addrs ))
434
444
slices .SortFunc (addrs , func (a , b ma.Multiaddr ) int { return a .Compare (b ) })
@@ -880,6 +890,33 @@ func removeNotInSource(addrs, source []ma.Multiaddr) []ma.Multiaddr {
880
890
return addrs [:i ]
881
891
}
882
892
893
+ // removeInSource removes items from addrs that are present in source.
894
+ // Modifies the addrs slice in place
895
+ // addrs and source must be sorted using multiaddr.Compare.
896
+ func removeInSource (addrs , source []ma.Multiaddr ) []ma.Multiaddr {
897
+ j := 0
898
+ // mark entries in source as nil
899
+ for i , a := range addrs {
900
+ // move right in source as long as a > source[j]
901
+ for j < len (source ) && a .Compare (source [j ]) > 0 {
902
+ j ++
903
+ }
904
+ // a is in source, mark nil
905
+ if j < len (source ) && a .Compare (source [j ]) == 0 {
906
+ addrs [i ] = nil
907
+ }
908
+ }
909
+ // j is the current element, i is the lowest index nil element
910
+ i := 0
911
+ for j := range len (addrs ) {
912
+ if addrs [j ] != nil {
913
+ addrs [i ], addrs [j ] = addrs [j ], addrs [i ]
914
+ i ++
915
+ }
916
+ }
917
+ return addrs [:i ]
918
+ }
919
+
883
920
type multiCloser []io.Closer
884
921
885
922
func (mc * multiCloser ) Close () error {
0 commit comments