Skip to content

Commit fb1d951

Browse files
authored
basichost: use autonatv2 to verify reachability (libp2p#3231)
This introduces addrsReachabilityTracker that tracks reachability on a set of addresses. It probes reachability for addresses periodically and has an exponential backoff in case there are too many errors or we don't have any valid autonatv2 peer. There's no smartness in the address selection logic currently. We just test all provided addresses. It also doesn't use the addresses provided by `AddrsFactory`, so currently there's no way to get a user provided address tested for reachability, something that would be a problem for dns addresses. I intend to introduce an alternative to `AddrsFactory`, something like, `AnnounceAddrs(addrs []ma.Multiaddr)` that's just appended to the set of addresses that we have, and check reachability for those addresses. There's only one method exposed in the BasicHost right now that's `ReachableAddrs() []ma.Multiadd`r that returns the host's reachable addrs. Users can also use the event `EvtHostReachableAddrsChanged` to be notified when any addrs reachability changes.
1 parent 31c8c83 commit fb1d951

15 files changed

+2420
-321
lines changed

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ linters:
88
- revive
99
- unused
1010
- prealloc
11+
disable:
12+
- errcheck
1113

1214
settings:
1315
revive:

config/config.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
routed "github.com/libp2p/go-libp2p/p2p/host/routed"
3434
"github.com/libp2p/go-libp2p/p2p/net/swarm"
3535
tptu "github.com/libp2p/go-libp2p/p2p/net/upgrader"
36+
"github.com/libp2p/go-libp2p/p2p/protocol/autonatv2"
3637
circuitv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client"
3738
relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay"
3839
"github.com/libp2p/go-libp2p/p2p/protocol/holepunch"
@@ -413,15 +414,7 @@ func (cfg *Config) addTransports() ([]fx.Option, error) {
413414
return fxopts, nil
414415
}
415416

416-
func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus) (*bhost.BasicHost, error) {
417-
var autonatv2Dialer host.Host
418-
if cfg.EnableAutoNATv2 {
419-
ah, err := cfg.makeAutoNATV2Host()
420-
if err != nil {
421-
return nil, err
422-
}
423-
autonatv2Dialer = ah
424-
}
417+
func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus, an *autonatv2.AutoNAT) (*bhost.BasicHost, error) {
425418
h, err := bhost.NewHost(swrm, &bhost.HostOpts{
426419
EventBus: eventBus,
427420
ConnManager: cfg.ConnManager,
@@ -437,8 +430,7 @@ func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus) (*bhost.B
437430
EnableMetrics: !cfg.DisableMetrics,
438431
PrometheusRegisterer: cfg.PrometheusRegisterer,
439432
DisableIdentifyAddressDiscovery: cfg.DisableIdentifyAddressDiscovery,
440-
EnableAutoNATv2: cfg.EnableAutoNATv2,
441-
AutoNATv2Dialer: autonatv2Dialer,
433+
AutoNATv2: an,
442434
})
443435
if err != nil {
444436
return nil, err
@@ -517,6 +509,24 @@ func (cfg *Config) NewNode() (host.Host, error) {
517509
})
518510
return sw, nil
519511
}),
512+
fx.Provide(func() (*autonatv2.AutoNAT, error) {
513+
if !cfg.EnableAutoNATv2 {
514+
return nil, nil
515+
}
516+
ah, err := cfg.makeAutoNATV2Host()
517+
if err != nil {
518+
return nil, err
519+
}
520+
var mt autonatv2.MetricsTracer
521+
if !cfg.DisableMetrics {
522+
mt = autonatv2.NewMetricsTracer(cfg.PrometheusRegisterer)
523+
}
524+
autoNATv2, err := autonatv2.New(ah, autonatv2.WithMetricsTracer(mt))
525+
if err != nil {
526+
return nil, fmt.Errorf("failed to create autonatv2: %w", err)
527+
}
528+
return autoNATv2, nil
529+
}),
520530
fx.Provide(cfg.newBasicHost),
521531
fx.Provide(func(bh *bhost.BasicHost) identify.IDService {
522532
return bh.IDService()

core/event/reachability.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package event
22

33
import (
44
"github.com/libp2p/go-libp2p/core/network"
5+
ma "github.com/multiformats/go-multiaddr"
56
)
67

78
// EvtLocalReachabilityChanged is an event struct to be emitted when the local's
@@ -11,3 +12,12 @@ import (
1112
type EvtLocalReachabilityChanged struct {
1213
Reachability network.Reachability
1314
}
15+
16+
// EvtHostReachableAddrsChanged is sent when host's reachable or unreachable addresses change
17+
// Reachable and Unreachable both contain only Public IP or DNS addresses
18+
//
19+
// Experimental: This API is unstable. Any changes to this event will be done without a deprecation notice.
20+
type EvtHostReachableAddrsChanged struct {
21+
Reachable []ma.Multiaddr
22+
Unreachable []ma.Multiaddr
23+
}

0 commit comments

Comments
 (0)