@@ -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,36 @@ 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
+ 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 {
426
432
addrs = slices .DeleteFunc (addrs , manet .IsPublicAddr )
427
433
addrs = append (addrs , relayAddrs ... )
428
434
}
429
435
}
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 ... )
432
443
// Add certhashes for the addresses provided by the user via address factory.
433
444
addrs = a .addCertHashes (ma .Unique (addrs ))
434
445
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 {
880
891
return addrs [:i ]
881
892
}
882
893
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
+
883
921
type multiCloser []io.Closer
884
922
885
923
func (mc * multiCloser ) Close () error {
0 commit comments