@@ -22,11 +22,14 @@ var log = logging.Logger("autonat")
22
22
23
23
// AmbientAutoNAT is the implementation of ambient NAT autodiscovery
24
24
type AmbientAutoNAT struct {
25
- ctx context.Context
26
25
host host.Host
27
26
28
27
* config
29
28
29
+ ctx context.Context
30
+ ctxCancel context.CancelFunc // is closed when Close is called
31
+ backgroundRunning chan struct {} // is closed when the background go routine exits
32
+
30
33
inboundConn chan network.Conn
31
34
observations chan autoNATResult
32
35
// status is an autoNATResult reflecting current status.
@@ -50,7 +53,6 @@ type AmbientAutoNAT struct {
50
53
51
54
// StaticAutoNAT is a simple AutoNAT implementation when a single NAT status is desired.
52
55
type StaticAutoNAT struct {
53
- ctx context.Context
54
56
host host.Host
55
57
reachability network.Reachability
56
58
service * autoNATService
@@ -62,7 +64,7 @@ type autoNATResult struct {
62
64
}
63
65
64
66
// New creates a new NAT autodiscovery system attached to a host
65
- func New (ctx context. Context , h host.Host , options ... Option ) (AutoNAT , error ) {
67
+ func New (h host.Host , options ... Option ) (AutoNAT , error ) {
66
68
var err error
67
69
conf := new (config )
68
70
conf .host = h
@@ -84,7 +86,7 @@ func New(ctx context.Context, h host.Host, options ...Option) (AutoNAT, error) {
84
86
85
87
var service * autoNATService
86
88
if (! conf .forceReachability || conf .reachability == network .ReachabilityPublic ) && conf .dialer != nil {
87
- service , err = newAutoNATService (ctx , conf )
89
+ service , err = newAutoNATService (conf )
88
90
if err != nil {
89
91
return nil , err
90
92
}
@@ -95,19 +97,21 @@ func New(ctx context.Context, h host.Host, options ...Option) (AutoNAT, error) {
95
97
emitReachabilityChanged .Emit (event.EvtLocalReachabilityChanged {Reachability : conf .reachability })
96
98
97
99
return & StaticAutoNAT {
98
- ctx : ctx ,
99
100
host : h ,
100
101
reachability : conf .reachability ,
101
102
service : service ,
102
103
}, nil
103
104
}
104
105
106
+ ctx , cancel := context .WithCancel (context .Background ())
105
107
as := & AmbientAutoNAT {
106
- ctx : ctx ,
107
- host : h ,
108
- config : conf ,
109
- inboundConn : make (chan network.Conn , 5 ),
110
- observations : make (chan autoNATResult , 1 ),
108
+ ctx : ctx ,
109
+ ctxCancel : cancel ,
110
+ backgroundRunning : make (chan struct {}),
111
+ host : h ,
112
+ config : conf ,
113
+ inboundConn : make (chan network.Conn , 5 ),
114
+ observations : make (chan autoNATResult , 1 ),
111
115
112
116
emitReachabilityChanged : emitReachabilityChanged ,
113
117
service : service ,
@@ -159,6 +163,7 @@ func ipInList(candidate ma.Multiaddr, list []ma.Multiaddr) bool {
159
163
}
160
164
161
165
func (as * AmbientAutoNAT ) background () {
166
+ defer close (as .backgroundRunning )
162
167
// wait a bit for the node to come online and establish some connections
163
168
// before starting autodetection
164
169
delay := as .config .bootDelay
@@ -426,6 +431,15 @@ func (as *AmbientAutoNAT) getPeerToProbe() peer.ID {
426
431
return candidates [0 ]
427
432
}
428
433
434
+ func (as * AmbientAutoNAT ) Close () error {
435
+ as .ctxCancel ()
436
+ if as .service != nil {
437
+ as .service .Disable ()
438
+ }
439
+ <- as .backgroundRunning
440
+ return nil
441
+ }
442
+
429
443
func shufflePeers (peers []peer.ID ) {
430
444
for i := range peers {
431
445
j := rand .Intn (i + 1 )
@@ -445,3 +459,10 @@ func (s *StaticAutoNAT) PublicAddr() (ma.Multiaddr, error) {
445
459
}
446
460
return nil , errors .New ("no available address" )
447
461
}
462
+
463
+ func (s * StaticAutoNAT ) Close () error {
464
+ if s .service != nil {
465
+ s .service .Disable ()
466
+ }
467
+ return nil
468
+ }
0 commit comments