@@ -24,6 +24,7 @@ import (
24
24
"github.com/libp2p/go-libp2p/p2p/host/autonat"
25
25
"github.com/libp2p/go-libp2p/p2p/host/autorelay"
26
26
bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
27
+ blankhost "github.com/libp2p/go-libp2p/p2p/host/blank"
27
28
"github.com/libp2p/go-libp2p/p2p/host/eventbus"
28
29
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
29
30
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
@@ -131,6 +132,8 @@ type Config struct {
131
132
SwarmOpts []swarm.Option
132
133
133
134
DisableIdentifyAddressDiscovery bool
135
+
136
+ DisableAutoNATv2 bool
134
137
}
135
138
136
139
func (cfg * Config ) makeSwarm (eventBus event.Bus , enableMetrics bool ) (* swarm.Swarm , error ) {
@@ -193,6 +196,76 @@ func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swa
193
196
return swarm .NewSwarm (pid , cfg .Peerstore , eventBus , opts ... )
194
197
}
195
198
199
+ func (cfg * Config ) makeAutoNATHost () (host.Host , error ) {
200
+ autonatPrivKey , _ , err := crypto .GenerateEd25519Key (rand .Reader )
201
+ if err != nil {
202
+ return nil , err
203
+ }
204
+ ps , err := pstoremem .NewPeerstore ()
205
+ if err != nil {
206
+ return nil , err
207
+ }
208
+
209
+ 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 ,
220
+ 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 ),
225
+ },
226
+ }
227
+ fxopts , err := autoNatCfg .addTransports ()
228
+ if err != nil {
229
+ return nil , err
230
+ }
231
+ var dialerHost host.Host
232
+ fxopts = append (fxopts ,
233
+ fx .Provide (eventbus .NewBus ),
234
+ fx .Provide (func (lifecycle fx.Lifecycle , b event.Bus ) (* swarm.Swarm , error ) {
235
+ lifecycle .Append (fx.Hook {
236
+ OnStop : func (context.Context ) error {
237
+ return ps .Close ()
238
+ }})
239
+ sw , err := autoNatCfg .makeSwarm (b , false )
240
+ return sw , err
241
+ }),
242
+ fx .Provide (func (sw * swarm.Swarm ) * blankhost.BlankHost {
243
+ return blankhost .NewBlankHost (sw )
244
+ }),
245
+ fx .Provide (func (bh * blankhost.BlankHost ) host.Host {
246
+ return bh
247
+ }),
248
+ fx .Provide (func () crypto.PrivKey { return autonatPrivKey }),
249
+ fx .Provide (func (bh host.Host ) peer.ID { return bh .ID () }),
250
+ fx .Invoke (func (bh * blankhost.BlankHost ) {
251
+ dialerHost = bh
252
+ }),
253
+ )
254
+ app := fx .New (fxopts ... )
255
+ if err := app .Err (); err != nil {
256
+ return nil , err
257
+ }
258
+ err = app .Start (context .Background ())
259
+ if err != nil {
260
+ return nil , err
261
+ }
262
+ go func () {
263
+ <- dialerHost .Network ().(* swarm.Swarm ).Done ()
264
+ app .Stop (context .Background ())
265
+ }()
266
+ return dialerHost , nil
267
+ }
268
+
196
269
func (cfg * Config ) addTransports () ([]fx.Option , error ) {
197
270
fxopts := []fx.Option {
198
271
fx .WithLogger (func () fxevent.Logger { return getFXLogger () }),
@@ -291,6 +364,14 @@ func (cfg *Config) addTransports() ([]fx.Option, error) {
291
364
}
292
365
293
366
func (cfg * Config ) newBasicHost (swrm * swarm.Swarm , eventBus event.Bus ) (* bhost.BasicHost , error ) {
367
+ var autonatv2Dialer host.Host
368
+ if ! cfg .DisableAutoNATv2 {
369
+ ah , err := cfg .makeAutoNATHost ()
370
+ if err != nil {
371
+ return nil , err
372
+ }
373
+ autonatv2Dialer = ah
374
+ }
294
375
h , err := bhost .NewHost (swrm , & bhost.HostOpts {
295
376
EventBus : eventBus ,
296
377
ConnManager : cfg .ConnManager ,
@@ -306,6 +387,8 @@ func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus) (*bhost.B
306
387
EnableMetrics : ! cfg .DisableMetrics ,
307
388
PrometheusRegisterer : cfg .PrometheusRegisterer ,
308
389
DisableIdentifyAddressDiscovery : cfg .DisableIdentifyAddressDiscovery ,
390
+ EnableAutoNATv2 : ! cfg .DisableAutoNATv2 ,
391
+ AutoNATv2Dialer : autonatv2Dialer ,
309
392
})
310
393
if err != nil {
311
394
return nil , err
0 commit comments