@@ -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"
@@ -129,6 +130,8 @@ type Config struct {
129
130
DialRanker network.DialRanker
130
131
131
132
SwarmOpts []swarm.Option
133
+
134
+ DisableAutoNATv2 bool
132
135
}
133
136
134
137
func (cfg * Config ) makeSwarm (eventBus event.Bus , enableMetrics bool ) (* swarm.Swarm , error ) {
@@ -191,6 +194,76 @@ func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swa
191
194
return swarm .NewSwarm (pid , cfg .Peerstore , eventBus , opts ... )
192
195
}
193
196
197
+ func (cfg * Config ) makeAutoNATHost () (host.Host , error ) {
198
+ autonatPrivKey , _ , err := crypto .GenerateEd25519Key (rand .Reader )
199
+ if err != nil {
200
+ return nil , err
201
+ }
202
+ ps , err := pstoremem .NewPeerstore ()
203
+ if err != nil {
204
+ return nil , err
205
+ }
206
+
207
+ autoNatCfg := Config {
208
+ Transports : cfg .Transports ,
209
+ Muxers : cfg .Muxers ,
210
+ SecurityTransports : cfg .SecurityTransports ,
211
+ Insecure : cfg .Insecure ,
212
+ PSK : cfg .PSK ,
213
+ ConnectionGater : cfg .ConnectionGater ,
214
+ Reporter : cfg .Reporter ,
215
+ PeerKey : autonatPrivKey ,
216
+ Peerstore : ps ,
217
+ DialRanker : swarm .NoDelayDialRanker ,
218
+ SwarmOpts : []swarm.Option {
219
+ // Disable black hole detection on autonat dialers
220
+ // It is better to attempt a dial and fail for AutoNAT use cases
221
+ swarm .WithUDPBlackHoleConfig (false , 0 , 0 ),
222
+ swarm .WithIPv6BlackHoleConfig (false , 0 , 0 ),
223
+ },
224
+ }
225
+ fxopts , err := autoNatCfg .addTransports ()
226
+ if err != nil {
227
+ return nil , err
228
+ }
229
+ var dialerHost host.Host
230
+ fxopts = append (fxopts ,
231
+ fx .Provide (eventbus .NewBus ),
232
+ fx .Provide (func (lifecycle fx.Lifecycle , b event.Bus ) (* swarm.Swarm , error ) {
233
+ lifecycle .Append (fx.Hook {
234
+ OnStop : func (context.Context ) error {
235
+ return ps .Close ()
236
+ }})
237
+ sw , err := autoNatCfg .makeSwarm (b , false )
238
+ return sw , err
239
+ }),
240
+ fx .Provide (func (sw * swarm.Swarm ) * blankhost.BlankHost {
241
+ return blankhost .NewBlankHost (sw )
242
+ }),
243
+ fx .Provide (func (bh * blankhost.BlankHost ) host.Host {
244
+ return bh
245
+ }),
246
+ fx .Provide (func () crypto.PrivKey { return autonatPrivKey }),
247
+ fx .Provide (func (bh host.Host ) peer.ID { return bh .ID () }),
248
+ fx .Invoke (func (bh * blankhost.BlankHost ) {
249
+ dialerHost = bh
250
+ }),
251
+ )
252
+ app := fx .New (fxopts ... )
253
+ if err := app .Err (); err != nil {
254
+ return nil , err
255
+ }
256
+ err = app .Start (context .Background ())
257
+ if err != nil {
258
+ return nil , err
259
+ }
260
+ go func () {
261
+ <- dialerHost .Network ().(* swarm.Swarm ).Done ()
262
+ app .Stop (context .Background ())
263
+ }()
264
+ return dialerHost , nil
265
+ }
266
+
194
267
func (cfg * Config ) addTransports () ([]fx.Option , error ) {
195
268
fxopts := []fx.Option {
196
269
fx .WithLogger (func () fxevent.Logger { return getFXLogger () }),
@@ -289,6 +362,14 @@ func (cfg *Config) addTransports() ([]fx.Option, error) {
289
362
}
290
363
291
364
func (cfg * Config ) newBasicHost (swrm * swarm.Swarm , eventBus event.Bus ) (* bhost.BasicHost , error ) {
365
+ var autonatv2Dialer host.Host
366
+ if ! cfg .DisableAutoNATv2 {
367
+ ah , err := cfg .makeAutoNATHost ()
368
+ if err != nil {
369
+ return nil , err
370
+ }
371
+ autonatv2Dialer = ah
372
+ }
292
373
h , err := bhost .NewHost (swrm , & bhost.HostOpts {
293
374
EventBus : eventBus ,
294
375
ConnManager : cfg .ConnManager ,
@@ -303,6 +384,8 @@ func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus) (*bhost.B
303
384
RelayServiceOpts : cfg .RelayServiceOpts ,
304
385
EnableMetrics : ! cfg .DisableMetrics ,
305
386
PrometheusRegisterer : cfg .PrometheusRegisterer ,
387
+ EnableAutoNATv2 : ! cfg .DisableAutoNATv2 ,
388
+ AutoNATv2Dialer : autonatv2Dialer ,
306
389
})
307
390
if err != nil {
308
391
return nil , err
0 commit comments