fix autonat race

fix #7947
move `BasicHost.AutoNat` to a private field (it has no public method and shouldn't be accessed afaik.
Instead add a setter for config that sets it while holding the address mutex to prevent reads of the
field at the same time.
parent bbde01b3
...@@ -335,10 +335,12 @@ func (cfg *Config) NewNode(ctx context.Context) (host.Host, error) { ...@@ -335,10 +335,12 @@ func (cfg *Config) NewNode(ctx context.Context) (host.Host, error) {
autonatOpts = append(autonatOpts, autonat.WithReachability(*cfg.AutoNATConfig.ForceReachability)) autonatOpts = append(autonatOpts, autonat.WithReachability(*cfg.AutoNATConfig.ForceReachability))
} }
if h.AutoNat, err = autonat.New(ctx, h, autonatOpts...); err != nil { autonat, err := autonat.New(ctx, h, autonatOpts...)
if err != nil {
h.Close() h.Close()
return nil, fmt.Errorf("cannot enable autorelay; autonat failed to start: %v", err) return nil, fmt.Errorf("cannot enable autorelay; autonat failed to start: %v", err)
} }
h.SetAutoNat(autonat)
// start the host background tasks // start the host background tasks
h.Start() h.Start()
......
...@@ -112,7 +112,7 @@ type BasicHost struct { ...@@ -112,7 +112,7 @@ type BasicHost struct {
signKey crypto.PrivKey signKey crypto.PrivKey
caBook peerstore.CertifiedAddrBook caBook peerstore.CertifiedAddrBook
AutoNat autonat.AutoNAT autoNat autonat.AutoNAT
} }
var _ host.Host = (*BasicHost)(nil) var _ host.Host = (*BasicHost)(nil)
...@@ -811,6 +811,7 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr { ...@@ -811,6 +811,7 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr {
h.addrMu.RLock() h.addrMu.RLock()
filteredIfaceAddrs := h.filteredInterfaceAddrs filteredIfaceAddrs := h.filteredInterfaceAddrs
allIfaceAddrs := h.allInterfaceAddrs allIfaceAddrs := h.allInterfaceAddrs
autonat := h.autoNat
h.addrMu.RUnlock() h.addrMu.RUnlock()
// Iterate over all _unresolved_ listen addresses, resolving our primary // Iterate over all _unresolved_ listen addresses, resolving our primary
...@@ -831,8 +832,8 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr { ...@@ -831,8 +832,8 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr {
// but not have an external network card, // but not have an external network card,
// so net.InterfaceAddrs() not has the public ip // so net.InterfaceAddrs() not has the public ip
// The host can indeed be dialed !!! // The host can indeed be dialed !!!
if h.AutoNat != nil { if autonat != nil {
publicAddr, _ := h.AutoNat.PublicAddr() publicAddr, _ := autonat.PublicAddr()
if publicAddr != nil { if publicAddr != nil {
finalAddrs = append(finalAddrs, publicAddr) finalAddrs = append(finalAddrs, publicAddr)
} }
...@@ -992,6 +993,15 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr { ...@@ -992,6 +993,15 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr {
return dedupAddrs(finalAddrs) return dedupAddrs(finalAddrs)
} }
// SetAutoNat sets the autonat service for the host.
func (h *BasicHost) SetAutoNat(a autonat.AutoNAT) {
h.addrMu.Lock()
defer h.addrMu.Unlock()
if h.autoNat == nil {
h.autoNat = a
}
}
// Close shuts down the Host's services (network, etc). // Close shuts down the Host's services (network, etc).
func (h *BasicHost) Close() error { func (h *BasicHost) Close() error {
h.closeSync.Do(func() { h.closeSync.Do(func() {
......
...@@ -203,7 +203,7 @@ func TestHostAddrsFactory(t *testing.T) { ...@@ -203,7 +203,7 @@ func TestHostAddrsFactory(t *testing.T) {
} }
var err error var err error
h.AutoNat, err = autonat.New(ctx, h, autonat.WithReachability(network.ReachabilityPublic)) h.autoNat, err = autonat.New(ctx, h, autonat.WithReachability(network.ReachabilityPublic))
if err != nil { if err != nil {
t.Fatalf("should be able to attach autonat: %v", err) t.Fatalf("should be able to attach autonat: %v", err)
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment