@@ -414,8 +414,8 @@ func (a *addrsManager) updateAddrs(relayAddrs []ma.Multiaddr) hostAddrs {
414
414
currReachableAddrs , currUnreachableAddrs , currUnknownAddrs = a .getConfirmedAddrs (localAddrs )
415
415
}
416
416
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 )
419
419
a .addrsMx .Lock ()
420
420
a .currentAddrs = hostAddrs {
421
421
addrs : append (a .currentAddrs .addrs [:0 ], currAddrs ... ),
@@ -479,25 +479,36 @@ func (a *addrsManager) notifyAddrsChanged(emitter event.Emitter, localAddrsEmitt
479
479
// the node's relay addresses and private network addresses.
480
480
func (a * addrsManager ) Addrs () []ma.Multiaddr {
481
481
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 )
484
483
a .addrsMx .RUnlock ()
485
- return a .getAddrs (directAddrs , relayAddrs )
484
+ // don't hold the lock while applying addrs factory
485
+ return a .applyAddrsFactory (addrs )
486
486
}
487
487
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 {
495
501
addrs = slices .DeleteFunc (addrs , manet .IsPublicAddr )
496
502
addrs = append (addrs , relayAddrs ... )
497
503
}
498
504
}
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 ... )
501
512
// Add certhashes for the addresses provided by the user via address factory.
502
513
addrs = a .addCertHashes (ma .Unique (addrs ))
503
514
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 {
980
991
}
981
992
return addrs [:i ]
982
993
}
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
+ }
0 commit comments