@@ -46,9 +46,7 @@ type addressService struct {
4646 ctx context.Context
4747 ctxCancel context.CancelFunc
4848
49- wg sync.WaitGroup
50- updateLocalIPv4Backoff backoff.ExpBackoff
51- updateLocalIPv6Backoff backoff.ExpBackoff
49+ wg sync.WaitGroup
5250
5351 ifaceAddrs * interfaceAddrsCache
5452}
@@ -226,91 +224,15 @@ func (a *addressService) AllAddrs() []ma.Multiaddr {
226224 return nil
227225 }
228226
229- filteredIfaceAddrs := a .ifaceAddrs .Filtered ()
230-
231- // Iterate over all _unresolved_ listen addresses, resolving our primary
232- // interface only to avoid advertising too many addresses.
233227 finalAddrs := make ([]ma.Multiaddr , 0 , 8 )
234- if resolved , err := manet .ResolveUnspecifiedAddresses (listenAddrs , filteredIfaceAddrs ); err != nil {
235- // This can happen if we're listening on no addrs, or listening
236- // on IPv6 addrs, but only have IPv4 interface addrs.
237- log .Debugw ("failed to resolve listen addrs" , "error" , err )
238- } else {
239- finalAddrs = append (finalAddrs , resolved ... )
240- }
241-
242- finalAddrs = ma .Unique (finalAddrs )
228+ finalAddrs = a .appendInterfaceAddrs (finalAddrs , listenAddrs )
243229
244230 // use nat mappings if we have them
245- if a .natmgr != nil && a .natmgr .HasDiscoveredNAT () {
246- // We have successfully mapped ports on our NAT. Use those
247- // instead of observed addresses (mostly).
248- // Next, apply this mapping to our addresses.
249- for _ , listen := range listenAddrs {
250- extMaddr := a .natmgr .GetMapping (listen )
251- if extMaddr == nil {
252- // not mapped
253- continue
254- }
255-
256- // if the router reported a sane address
257- if ! manet .IsIPUnspecified (extMaddr ) {
258- // Add in the mapped addr.
259- finalAddrs = append (finalAddrs , extMaddr )
260- } else {
261- log .Warn ("NAT device reported an unspecified IP as it's external address" )
262- }
263-
264- // Did the router give us a routable public addr?
265- if manet .IsPublicAddr (extMaddr ) {
266- // well done
267- continue
268- }
269-
270- // No.
271- // in case the router gives us a wrong address or we're behind a double-NAT.
272- // also add observed addresses
273- resolved , err := manet .ResolveUnspecifiedAddress (listen , a .ifaceAddrs .All ())
274- if err != nil {
275- // This can happen if we try to resolve /ip6/::/...
276- // without any IPv6 interface addresses.
277- continue
278- }
279-
280- for _ , addr := range resolved {
281- // Now, check if we have any observed addresses that
282- // differ from the one reported by the router. Routers
283- // don't always give the most accurate information.
284- observed := a .ids .ObservedAddrsFor (addr )
285-
286- if len (observed ) == 0 {
287- continue
288- }
289-
290- // Drop the IP from the external maddr
291- _ , extMaddrNoIP := ma .SplitFirst (extMaddr )
292-
293- for _ , obsMaddr := range observed {
294- // Extract a public observed addr.
295- ip , _ := ma .SplitFirst (obsMaddr )
296- if ip == nil || ! manet .IsPublicAddr (ip ) {
297- continue
298- }
299-
300- finalAddrs = append (finalAddrs , ma .Join (ip , extMaddrNoIP ))
301- }
302- }
303- }
304- } else {
305- var observedAddrs []ma.Multiaddr
306- if a .ids != nil {
307- observedAddrs = a .ids .OwnObservedAddrs ()
308- }
309- finalAddrs = append (finalAddrs , observedAddrs ... )
310- }
231+ finalAddrs = a .appendNATAddrs (finalAddrs , listenAddrs )
311232 finalAddrs = ma .Unique (finalAddrs )
233+
312234 // Remove /p2p-circuit addresses from the list.
313- // The p2p-circuit tranport listener reports its address as just /p2p-circuit
235+ // The p2p-circuit transport listener reports its address as just /p2p-circuit
314236 // This is useless for dialing. Users need to manage their circuit addresses themselves,
315237 // or use AutoRelay.
316238 finalAddrs = slices .DeleteFunc (finalAddrs , func (a ma.Multiaddr ) bool {
@@ -322,6 +244,35 @@ func (a *addressService) AllAddrs() []ma.Multiaddr {
322244 return finalAddrs
323245}
324246
247+ func (a * addressService ) appendInterfaceAddrs (result []ma.Multiaddr , listenAddrs []ma.Multiaddr ) []ma.Multiaddr {
248+ // resolving any unspecified listen addressees to use only the primary
249+ // interface to avoid advertising too many addresses.
250+ if resolved , err := manet .ResolveUnspecifiedAddresses (listenAddrs , a .ifaceAddrs .Filtered ()); err != nil {
251+ log .Warnw ("failed to resolve listen addrs" , "error" , err )
252+ } else {
253+ result = append (result , resolved ... )
254+ }
255+ result = ma .Unique (result )
256+ return result
257+ }
258+
259+ func (a * addressService ) appendNATAddrs (result []ma.Multiaddr , listenAddrs []ma.Multiaddr ) []ma.Multiaddr {
260+ ifaceAddrs := a .ifaceAddrs .All ()
261+ // use nat mappings if we have them
262+ if a .natmgr != nil && a .natmgr .HasDiscoveredNAT () {
263+ // we have a NAT device
264+ for _ , listen := range listenAddrs {
265+ extMaddr := a .natmgr .GetMapping (listen )
266+ result = appendValidNATAddrs (result , listen , extMaddr , a .ids .ObservedAddrsFor , ifaceAddrs )
267+ }
268+ } else {
269+ if a .ids != nil {
270+ result = append (result , a .ids .OwnObservedAddrs ()... )
271+ }
272+ }
273+ return result
274+ }
275+
325276func (a * addressService ) addCertHashes (addrs []ma.Multiaddr ) []ma.Multiaddr {
326277 // This is a temporary workaround/hack that fixes #2233. Once we have a
327278 // proper address pipeline, rework this. See the issue for more context.
@@ -536,3 +487,59 @@ func (i *interfaceAddrsCache) updateUnlocked() {
536487 }
537488 }
538489}
490+
491+ func getAllPossibleLocalAddrs (listenAddr ma.Multiaddr , ifaceAddrs []ma.Multiaddr ) []ma.Multiaddr {
492+ // If the nat mapping fails, use the observed addrs
493+ resolved , err := manet .ResolveUnspecifiedAddress (listenAddr , ifaceAddrs )
494+ if err != nil {
495+ log .Warnf ("failed to resolve listen addr %s, %s: %s" , listenAddr , ifaceAddrs , err )
496+ return nil
497+ }
498+ return append (resolved , listenAddr )
499+ }
500+
501+ // appendValidNATAddrs adds the NAT-ed addresses to the result. If the NAT device doesn't provide
502+ // us with a public IP address, we use the observed addresses.
503+ func appendValidNATAddrs (result []ma.Multiaddr , listenAddr ma.Multiaddr , natMapping ma.Multiaddr ,
504+ obsAddrsFunc func (ma.Multiaddr ) []ma.Multiaddr ,
505+ ifaceAddrs []ma.Multiaddr ) []ma.Multiaddr {
506+ if natMapping == nil {
507+ allAddrs := getAllPossibleLocalAddrs (listenAddr , ifaceAddrs )
508+ for _ , a := range allAddrs {
509+ result = append (result , obsAddrsFunc (a )... )
510+ }
511+ return result
512+ }
513+
514+ // if the router reported a sane address, use it.
515+ if ! manet .IsIPUnspecified (natMapping ) {
516+ result = append (result , natMapping )
517+ } else {
518+ log .Warn ("NAT device reported an unspecified IP as it's external address" )
519+ }
520+
521+ // If the router gave us a public address, use it and ignore observed addresses
522+ if manet .IsPublicAddr (natMapping ) {
523+ return result
524+ }
525+
526+ // Router gave us a private IP; maybe we're behind a CGNAT.
527+ // See if we have a public IP from observed addresses.
528+ _ , extMaddrNoIP := ma .SplitFirst (natMapping )
529+ if extMaddrNoIP == nil {
530+ return result
531+ }
532+
533+ allAddrs := getAllPossibleLocalAddrs (listenAddr , ifaceAddrs )
534+ for _ , addr := range allAddrs {
535+ for _ , obsMaddr := range obsAddrsFunc (addr ) {
536+ // Extract a public observed addr.
537+ ip , _ := ma .SplitFirst (obsMaddr )
538+ if ip == nil || ! manet .IsPublicAddr (ip ) {
539+ continue
540+ }
541+ result = append (result , ma .Join (ip , extMaddrNoIP ))
542+ }
543+ }
544+ return result
545+ }
0 commit comments