Skip to content

Commit 1b1d3bb

Browse files
committed
use a shared black hole detector
1 parent a3138cf commit 1b1d3bb

13 files changed

+280
-233
lines changed

config/config.go

+27-20
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ type Config struct {
134134
DisableIdentifyAddressDiscovery bool
135135

136136
DisableAutoNATv2 bool
137+
138+
UDPBlackHoleFilter *swarm.BlackHoleFilter
139+
CustomUDPBlackHoleFilter bool
140+
IPv6BlackHoleFilter *swarm.BlackHoleFilter
141+
CustomIPv6BlackHoleFilter bool
137142
}
138143

139144
func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swarm, error) {
@@ -168,7 +173,10 @@ func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swa
168173
return nil, err
169174
}
170175

171-
opts := cfg.SwarmOpts
176+
opts := append(cfg.SwarmOpts,
177+
swarm.WithUDPBlackHoleFilter(cfg.UDPBlackHoleFilter),
178+
swarm.WithIPv6BlackHoleFilter(cfg.IPv6BlackHoleFilter),
179+
)
172180
if cfg.Reporter != nil {
173181
opts = append(opts, swarm.WithMetrics(cfg.Reporter))
174182
}
@@ -196,7 +204,7 @@ func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swa
196204
return swarm.NewSwarm(pid, cfg.Peerstore, eventBus, opts...)
197205
}
198206

199-
func (cfg *Config) makeAutoNATHost() (host.Host, error) {
207+
func (cfg *Config) makeAutoNATV2Host() (host.Host, error) {
200208
autonatPrivKey, _, err := crypto.GenerateEd25519Key(rand.Reader)
201209
if err != nil {
202210
return nil, err
@@ -207,21 +215,21 @@ func (cfg *Config) makeAutoNATHost() (host.Host, error) {
207215
}
208216

209217
autoNatCfg := Config{
210-
Transports: cfg.Transports,
211-
Muxers: cfg.Muxers,
212-
SecurityTransports: cfg.SecurityTransports,
213-
Insecure: cfg.Insecure,
214-
PSK: cfg.PSK,
215-
ConnectionGater: cfg.ConnectionGater,
216-
Reporter: cfg.Reporter,
217-
PeerKey: autonatPrivKey,
218-
Peerstore: ps,
219-
DialRanker: swarm.NoDelayDialRanker,
218+
Transports: cfg.Transports,
219+
Muxers: cfg.Muxers,
220+
SecurityTransports: cfg.SecurityTransports,
221+
Insecure: cfg.Insecure,
222+
PSK: cfg.PSK,
223+
ConnectionGater: cfg.ConnectionGater,
224+
Reporter: cfg.Reporter,
225+
PeerKey: autonatPrivKey,
226+
Peerstore: ps,
227+
DialRanker: swarm.NoDelayDialRanker,
228+
UDPBlackHoleFilter: cfg.UDPBlackHoleFilter,
229+
IPv6BlackHoleFilter: cfg.IPv6BlackHoleFilter,
220230
SwarmOpts: []swarm.Option{
221-
// Disable black hole detection on autonat dialers
222-
// It is better to attempt a dial and fail for AutoNAT use cases
223-
swarm.WithUDPBlackHoleConfig(false, 0, 0),
224-
swarm.WithIPv6BlackHoleConfig(false, 0, 0),
231+
// Don't update black hole state for failed autonat dials
232+
swarm.WithReadOnlyBlackHoleDetector(),
225233
},
226234
}
227235
fxopts, err := autoNatCfg.addTransports()
@@ -366,7 +374,7 @@ func (cfg *Config) addTransports() ([]fx.Option, error) {
366374
func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus) (*bhost.BasicHost, error) {
367375
var autonatv2Dialer host.Host
368376
if !cfg.DisableAutoNATv2 {
369-
ah, err := cfg.makeAutoNATHost()
377+
ah, err := cfg.makeAutoNATV2Host()
370378
if err != nil {
371379
return nil, err
372380
}
@@ -564,9 +572,8 @@ func (cfg *Config) addAutoNAT(h *bhost.BasicHost) error {
564572
Peerstore: ps,
565573
DialRanker: swarm.NoDelayDialRanker,
566574
SwarmOpts: []swarm.Option{
567-
// It is better to disable black hole detection and just attempt a dial for autonat
568-
swarm.WithUDPBlackHoleConfig(false, 0, 0),
569-
swarm.WithIPv6BlackHoleConfig(false, 0, 0),
575+
swarm.WithUDPBlackHoleFilter(nil),
576+
swarm.WithIPv6BlackHoleFilter(nil),
570577
},
571578
}
572579

core/network/network.go

+1-15
Original file line numberDiff line numberDiff line change
@@ -161,20 +161,6 @@ type Network interface {
161161
ResourceManager() ResourceManager
162162
}
163163

164-
// Dialability indicates how dialable a (peer, addr) combination is.
165-
type Dialability int
166-
167-
const (
168-
// DialabilityUnknown indicates that the dialer cannot dial the (peer, addr) combination
169-
DialabilityUnknown Dialability = iota
170-
171-
// DialabilityDialable indicates that the dialer can dial the (peer, addr) combination
172-
DialabilityDialable
173-
174-
// DialabilityUndialable indicates that the dialer cannot dial the (peer, addr) combinaton
175-
DialabilityUndialable
176-
)
177-
178164
// Dialer represents a service that can dial out to peers
179165
// (this is usually just a Network, but other services may not need the whole
180166
// stack, and thus it becomes easier to mock)
@@ -210,7 +196,7 @@ type Dialer interface {
210196
StopNotify(Notifiee)
211197

212198
// CanDial returns whether the dialer can dial peer p at addr
213-
CanDial(p peer.ID, addr ma.Multiaddr) Dialability
199+
CanDial(p peer.ID, addr ma.Multiaddr) bool
214200
}
215201

216202
// AddrDelay provides an address along with the delay after which the address

defaults.go

+25
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
1111
"github.com/libp2p/go-libp2p/p2p/muxer/yamux"
1212
"github.com/libp2p/go-libp2p/p2p/net/connmgr"
13+
"github.com/libp2p/go-libp2p/p2p/net/swarm"
1314
"github.com/libp2p/go-libp2p/p2p/security/noise"
1415
tls "github.com/libp2p/go-libp2p/p2p/security/tls"
1516
quic "github.com/libp2p/go-libp2p/p2p/transport/quic"
@@ -133,6 +134,18 @@ var DefaultPrometheusRegisterer = func(cfg *Config) error {
133134
return cfg.Apply(PrometheusRegisterer(prometheus.DefaultRegisterer))
134135
}
135136

137+
var defaultUDPBlackHoleDetector = func(cfg *Config) error {
138+
// A black hole is a binary property. On a network if UDP dials are blocked, all dials will
139+
// fail. So a low success rate of 5 out 100 dials is good enough.
140+
return cfg.Apply(UDPBlackHoleFilter(&swarm.BlackHoleFilter{N: 100, MinSuccesses: 5, Name: "UDP"}))
141+
}
142+
143+
var defaultIPv6BlackHoleDetector = func(cfg *Config) error {
144+
// A black hole is a binary property. On a network if there is no IPv6 connectivity, all
145+
// dials will fail. So a low success rate of 5 out 100 dials is good enough.
146+
return cfg.Apply(IPv6BlackHoleFilter(&swarm.BlackHoleFilter{N: 100, MinSuccesses: 5, Name: "IPv6"}))
147+
}
148+
136149
// Complete list of default options and when to fallback on them.
137150
//
138151
// Please *DON'T* specify default options any other way. Putting this all here
@@ -189,6 +202,18 @@ var defaults = []struct {
189202
fallback: func(cfg *Config) bool { return !cfg.DisableMetrics && cfg.PrometheusRegisterer == nil },
190203
opt: DefaultPrometheusRegisterer,
191204
},
205+
{
206+
fallback: func(cfg *Config) bool {
207+
return !cfg.CustomUDPBlackHoleFilter && cfg.UDPBlackHoleFilter == nil
208+
},
209+
opt: defaultUDPBlackHoleDetector,
210+
},
211+
{
212+
fallback: func(cfg *Config) bool {
213+
return !cfg.CustomIPv6BlackHoleFilter && cfg.IPv6BlackHoleFilter == nil
214+
},
215+
opt: defaultIPv6BlackHoleDetector,
216+
},
192217
}
193218

194219
// Defaults configures libp2p to use the default options. Can be combined with

options.go

+18
Original file line numberDiff line numberDiff line change
@@ -617,3 +617,21 @@ func DisableAutoNATv2() Option {
617617
return nil
618618
}
619619
}
620+
621+
// UDPBlackHoleFilter configures libp2p to use f as the black hole filter for UDP addrs
622+
func UDPBlackHoleFilter(f *swarm.BlackHoleFilter) Option {
623+
return func(cfg *Config) error {
624+
cfg.UDPBlackHoleFilter = f
625+
cfg.CustomUDPBlackHoleFilter = true
626+
return nil
627+
}
628+
}
629+
630+
// IPv6BlackHoleFilter configures libp2p to use f as the black hole filter for IPv6 addrs
631+
func IPv6BlackHoleFilter(f *swarm.BlackHoleFilter) Option {
632+
return func(cfg *Config) error {
633+
cfg.IPv6BlackHoleFilter = f
634+
cfg.CustomIPv6BlackHoleFilter = true
635+
return nil
636+
}
637+
}

p2p/net/mock/mock_peernet.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,6 @@ func (pn *peernet) ResourceManager() network.ResourceManager {
435435
return &network.NullResourceManager{}
436436
}
437437

438-
func (pn *peernet) CanDial(p peer.ID, addr ma.Multiaddr) network.Dialability {
439-
return network.DialabilityUnknown
438+
func (pn *peernet) CanDial(p peer.ID, addr ma.Multiaddr) bool {
439+
return true
440440
}

0 commit comments

Comments
 (0)