6
6
"fmt"
7
7
"net/netip"
8
8
"sync"
9
+ "sync/atomic"
9
10
"time"
10
11
11
12
logging "github.com/ipfs/go-log/v2"
@@ -56,11 +57,11 @@ func DiscoverNAT(ctx context.Context) (*NAT, error) {
56
57
ctx , cancel := context .WithCancel (context .Background ())
57
58
nat := & NAT {
58
59
nat : natInstance ,
59
- extAddr : extAddr ,
60
60
mappings : make (map [entry ]int ),
61
61
ctx : ctx ,
62
62
ctxCancel : cancel ,
63
63
}
64
+ nat .extAddr .Store (& extAddr )
64
65
nat .refCount .Add (1 )
65
66
go func () {
66
67
defer nat .refCount .Done ()
@@ -77,7 +78,7 @@ type NAT struct {
77
78
natmu sync.Mutex
78
79
nat nat.NAT
79
80
// External IP of the NAT. Will be renewed periodically (every CacheTime).
80
- extAddr netip.Addr
81
+ extAddr atomic. Pointer [ netip.Addr ]
81
82
82
83
refCount sync.WaitGroup
83
84
ctx context.Context
@@ -103,15 +104,15 @@ func (nat *NAT) GetMapping(protocol string, port int) (addr netip.AddrPort, foun
103
104
nat .mappingmu .Lock ()
104
105
defer nat .mappingmu .Unlock ()
105
106
106
- if ! nat .extAddr .IsValid () {
107
+ if ! nat .extAddr .Load (). IsValid () {
107
108
return netip.AddrPort {}, false
108
109
}
109
110
extPort , found := nat .mappings [entry {protocol : protocol , port : port }]
110
111
// The mapping may have an invalid port.
111
112
if ! found || extPort == 0 {
112
113
return netip.AddrPort {}, false
113
114
}
114
- return netip .AddrPortFrom (nat .extAddr , uint16 (extPort )), true
115
+ return netip .AddrPortFrom (* nat .extAddr . Load () , uint16 (extPort )), true
115
116
}
116
117
117
118
// AddMapping attempts to construct a mapping on protocol and internal port.
@@ -206,7 +207,7 @@ func (nat *NAT) background() {
206
207
if err == nil {
207
208
extAddr , _ = netip .AddrFromSlice (extIP )
208
209
}
209
- nat .extAddr = extAddr
210
+ nat .extAddr . Store ( & extAddr )
210
211
nextAddrUpdate = time .Now ().Add (CacheTime )
211
212
}
212
213
t .Reset (time .Until (minTime (nextAddrUpdate , nextMappingUpdate )))
0 commit comments