@@ -34,6 +34,7 @@ type hostAddrs struct {
3434 localAddrs []ma.Multiaddr
3535 reachableAddrs []ma.Multiaddr
3636 unreachableAddrs []ma.Multiaddr
37+ relayAddrs []ma.Multiaddr
3738}
3839
3940type addrsManager struct {
@@ -56,11 +57,8 @@ type addrsManager struct {
5657
5758 hostReachability atomic.Pointer [network.Reachability ]
5859
59- addrsMx sync.RWMutex // protects fields below
60+ addrsMx sync.RWMutex
6061 currentAddrs hostAddrs
61- // relayAddrs are the host's relay addresses. Kept separate from hostAddrs as we
62- // update them differently from hostAddrs.
63- relayAddrs []ma.Multiaddr
6462
6563 wg sync.WaitGroup
6664 ctx context.Context
@@ -140,7 +138,7 @@ func (a *addrsManager) NetNotifee() network.Notifiee {
140138}
141139
142140func (a * addrsManager ) triggerAddrsUpdate () {
143- a .updateAddrs ()
141+ a .updateAddrs (false , nil )
144142 select {
145143 case a .triggerAddrsUpdateChan <- struct {}{}:
146144 default :
@@ -177,11 +175,12 @@ func (a *addrsManager) startBackgroundWorker() error {
177175 return errors .Join (err , err1 , err2 )
178176 }
179177
178+ var relayAddrs []ma.Multiaddr
180179 // update relay addrs in case we're private
181180 select {
182181 case e := <- autoRelayAddrsSub .Out ():
183182 if evt , ok := e .(event.EvtAutoRelayAddrsUpdated ); ok {
184- a . updateRelayAddrs (evt .RelayAddrs )
183+ relayAddrs = slices . Clone (evt .RelayAddrs )
185184 }
186185 default :
187186 }
@@ -195,24 +194,23 @@ func (a *addrsManager) startBackgroundWorker() error {
195194 }
196195 // update addresses before starting the worker loop. This ensures that any address updates
197196 // before calling addrsManager.Start are correctly reported after Start returns.
198- a .updateAddrs ()
197+ a .updateAddrs (true , relayAddrs )
198+
199199 a .wg .Add (1 )
200- go func () {
201- defer a .wg .Done ()
202- a .background (autoRelayAddrsSub , autonatReachabilitySub , emitter )
203- }()
200+ go a .background (autoRelayAddrsSub , autonatReachabilitySub , emitter , relayAddrs )
204201 return nil
205202}
206203
207- func (a * addrsManager ) background (autoRelayAddrsSub , autonatReachabilitySub event.Subscription , emitter event.Emitter ) {
204+ func (a * addrsManager ) background (autoRelayAddrsSub , autonatReachabilitySub event.Subscription ,
205+ emitter event.Emitter , relayAddrs []ma.Multiaddr ,
206+ ) {
207+ defer a .wg .Done ()
208208 defer func () {
209209 err := autoRelayAddrsSub .Close ()
210210 if err != nil {
211211 log .Warnf ("error closing auto relay addrs sub: %s" , err )
212212 }
213- }()
214- defer func () {
215- err := autonatReachabilitySub .Close ()
213+ err = autonatReachabilitySub .Close ()
216214 if err != nil {
217215 log .Warnf ("error closing autonat reachability sub: %s" , err )
218216 }
@@ -222,7 +220,7 @@ func (a *addrsManager) background(autoRelayAddrsSub, autonatReachabilitySub even
222220 defer ticker .Stop ()
223221 var previousAddrs hostAddrs
224222 for {
225- currAddrs := a .updateAddrs ()
223+ currAddrs := a .updateAddrs (true , relayAddrs )
226224 a .notifyAddrsChanged (emitter , previousAddrs , currAddrs )
227225 previousAddrs = currAddrs
228226 select {
@@ -231,7 +229,7 @@ func (a *addrsManager) background(autoRelayAddrsSub, autonatReachabilitySub even
231229 case <- a .triggerReachabilityUpdate :
232230 case e := <- autoRelayAddrsSub .Out ():
233231 if evt , ok := e .(event.EvtAutoRelayAddrsUpdated ); ok {
234- a . updateRelayAddrs (evt .RelayAddrs )
232+ relayAddrs = slices . Clone (evt .RelayAddrs )
235233 }
236234 case e := <- autonatReachabilitySub .Out ():
237235 if evt , ok := e .(event.EvtLocalReachabilityChanged ); ok {
@@ -243,7 +241,9 @@ func (a *addrsManager) background(autoRelayAddrsSub, autonatReachabilitySub even
243241 }
244242}
245243
246- func (a * addrsManager ) updateAddrs () hostAddrs {
244+ // updateAddrs updates the addresses of the host and returns the new updated
245+ // addrs
246+ func (a * addrsManager ) updateAddrs (updateRelayAddrs bool , relayAddrs []ma.Multiaddr ) hostAddrs {
247247 // Must lock while doing both recompute and update as this method is called from
248248 // multiple goroutines.
249249 a .addrsMx .Lock ()
@@ -254,29 +254,31 @@ func (a *addrsManager) updateAddrs() hostAddrs {
254254 if a .addrsReachabilityTracker != nil {
255255 currReachableAddrs , currUnreachableAddrs = a .getConfirmedAddrs (localAddrs )
256256 }
257- currAddrs := a .getAddrs (slices .Clone (localAddrs ), a .getRelayAddrsUnlocked ())
257+ if ! updateRelayAddrs {
258+ relayAddrs = a .currentAddrs .relayAddrs
259+ } else {
260+ // Copy the callers slice
261+ relayAddrs = slices .Clone (relayAddrs )
262+ }
263+ currAddrs := a .getAddrs (slices .Clone (localAddrs ), relayAddrs )
258264
259265 a .currentAddrs = hostAddrs {
260266 addrs : append (a .currentAddrs .addrs [:0 ], currAddrs ... ),
261267 localAddrs : append (a .currentAddrs .localAddrs [:0 ], localAddrs ... ),
262268 reachableAddrs : append (a .currentAddrs .reachableAddrs [:0 ], currReachableAddrs ... ),
263269 unreachableAddrs : append (a .currentAddrs .unreachableAddrs [:0 ], currUnreachableAddrs ... ),
270+ relayAddrs : append (a .currentAddrs .relayAddrs [:0 ], relayAddrs ... ),
264271 }
265272
266273 return hostAddrs {
267274 localAddrs : localAddrs ,
268275 addrs : currAddrs ,
269276 reachableAddrs : currReachableAddrs ,
270277 unreachableAddrs : currUnreachableAddrs ,
278+ relayAddrs : relayAddrs ,
271279 }
272280}
273281
274- func (a * addrsManager ) updateRelayAddrs (addrs []ma.Multiaddr ) {
275- a .addrsMx .Lock ()
276- defer a .addrsMx .Unlock ()
277- a .relayAddrs = append (a .relayAddrs [:0 ], addrs ... )
278- }
279-
280282func (a * addrsManager ) notifyAddrsChanged (emitter event.Emitter , previous , current hostAddrs ) {
281283 if areAddrsDifferent (previous .localAddrs , current .localAddrs ) {
282284 log .Debugf ("host local addresses updated: %s" , current .localAddrs )
@@ -308,7 +310,11 @@ func (a *addrsManager) notifyAddrsChanged(emitter event.Emitter, previous, curre
308310// If autorelay is enabled and node reachability is private, it returns
309311// the node's relay addresses and private network addresses.
310312func (a * addrsManager ) Addrs () []ma.Multiaddr {
311- return a .getAddrs (a .DirectAddrs (), a .RelayAddrs ())
313+ a .addrsMx .RLock ()
314+ directAddrs := slices .Clone (a .currentAddrs .localAddrs )
315+ relayAddrs := slices .Clone (a .currentAddrs .relayAddrs )
316+ a .addrsMx .RUnlock ()
317+ return a .getAddrs (directAddrs , relayAddrs )
312318}
313319
314320// getAddrs returns the node's dialable addresses. Mutates localAddrs
@@ -358,48 +364,9 @@ func (a *addrsManager) ReachableAddrs() []ma.Multiaddr {
358364 return slices .Clone (a .currentAddrs .reachableAddrs )
359365}
360366
361- // RelayAddrs returns all the relay addresses of the host.
362- func (a * addrsManager ) RelayAddrs () []ma.Multiaddr {
363- a .addrsMx .RLock ()
364- defer a .addrsMx .RUnlock ()
365- return a .getRelayAddrsUnlocked ()
366- }
367-
368- func (a * addrsManager ) getRelayAddrsUnlocked () []ma.Multiaddr {
369- return slices .Clone (a .relayAddrs )
370- }
371-
372367func (a * addrsManager ) getConfirmedAddrs (localAddrs []ma.Multiaddr ) (reachableAddrs , unreachableAddrs []ma.Multiaddr ) {
373368 reachableAddrs , unreachableAddrs = a .addrsReachabilityTracker .ConfirmedAddrs ()
374- return removeIfNotInSource (reachableAddrs , localAddrs ), removeIfNotInSource (unreachableAddrs , localAddrs )
375- }
376-
377- // removeIfNotInSource removes items from addrs that are not present in source.
378- // Modifies the addrs slice in place
379- // addrs and source must be sorted using multiaddr.Compare.
380- func removeIfNotInSource (addrs , source []ma.Multiaddr ) []ma.Multiaddr {
381- j := 0
382- // mark entries not in source as nil
383- for i , a := range addrs {
384- // move right till a is greater
385- for j < len (source ) && a .Compare (source [j ]) > 0 {
386- j ++
387- }
388- // a is not in source if we've reached the end, or a is lesser
389- if j == len (source ) || a .Compare (source [j ]) < 0 {
390- addrs [i ] = nil
391- }
392- // a is in source, nothing to do
393- }
394- // j is the current element, i is the lowest index nil element
395- i := 0
396- for j := 0 ; j < len (addrs ); j ++ {
397- if addrs [j ] != nil {
398- addrs [i ], addrs [j ] = addrs [j ], addrs [i ]
399- i ++
400- }
401- }
402- return addrs [:i ]
369+ return removeNotInSource (reachableAddrs , localAddrs ), removeNotInSource (unreachableAddrs , localAddrs )
403370}
404371
405372var p2pCircuitAddr = ma .StringCast ("/p2p-circuit" )
@@ -701,3 +668,31 @@ func (i *interfaceAddrsCache) updateUnlocked() {
701668 }
702669 }
703670}
671+
672+ // removeNotInSource removes items from addrs that are not present in source.
673+ // Modifies the addrs slice in place
674+ // addrs and source must be sorted using multiaddr.Compare.
675+ func removeNotInSource (addrs , source []ma.Multiaddr ) []ma.Multiaddr {
676+ j := 0
677+ // mark entries not in source as nil
678+ for i , a := range addrs {
679+ // move right till a is greater
680+ for j < len (source ) && a .Compare (source [j ]) > 0 {
681+ j ++
682+ }
683+ // a is not in source if we've reached the end, or a is lesser
684+ if j == len (source ) || a .Compare (source [j ]) < 0 {
685+ addrs [i ] = nil
686+ }
687+ // a is in source, nothing to do
688+ }
689+ // j is the current element, i is the lowest index nil element
690+ i := 0
691+ for j := range len (addrs ) {
692+ if addrs [j ] != nil {
693+ addrs [i ], addrs [j ] = addrs [j ], addrs [i ]
694+ i ++
695+ }
696+ }
697+ return addrs [:i ]
698+ }
0 commit comments