add AutoNat PublicAddr when host can be dialed but not get public addr by net.InterfaceAddrs()

This commit is contained in:
sandman 2020-07-23 15:19:47 +08:00
parent 9cd6aaa9ea
commit a55891f71b
2 changed files with 20 additions and 1 deletions

View File

@ -335,7 +335,7 @@ func (cfg *Config) NewNode(ctx context.Context) (host.Host, error) {
autonatOpts = append(autonatOpts, autonat.WithReachability(*cfg.AutoNATConfig.ForceReachability))
}
if _, err = autonat.New(ctx, h, autonatOpts...); err != nil {
if h.AutoNat, err = autonat.New(ctx, h, autonatOpts...); err != nil {
h.Close()
return nil, fmt.Errorf("cannot enable autorelay; autonat failed to start: %v", err)
}

View File

@ -9,6 +9,7 @@ import (
"sync"
"time"
autonat "github.com/libp2p/go-libp2p-autonat"
"github.com/libp2p/go-libp2p-core/connmgr"
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/event"
@ -110,6 +111,8 @@ type BasicHost struct {
disableSignedPeerRecord bool
signKey crypto.PrivKey
caBook peerstore.CertifiedAddrBook
AutoNat autonat.AutoNAT
}
var _ host.Host = (*BasicHost)(nil)
@ -805,6 +808,22 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr {
finalAddrs = append(finalAddrs, resolved...)
}
// add autonat PublicAddr Consider the following scenario
// For example, it is deployed on a cloud server,
// it provides an elastic ip accessible to the public network,
// but not have an external network card,
// so net.InterfaceAddrs() not has the public ip
// The host can indeed be dialed
if h.AutoNat != nil {
ambientAutoNat, ok := h.AutoNat.(*autonat.AmbientAutoNAT)
if ok && ambientAutoNat != nil {
publicAddr, _ := ambientAutoNat.PublicAddr()
if publicAddr != nil {
finalAddrs = append(finalAddrs, publicAddr)
}
}
}
finalAddrs = dedupAddrs(finalAddrs)
var natMappings []inat.Mapping