mirror of https://github.com/status-im/go-waku.git
feat: advertise custom multiaddresses
This replaces the flag `--advertise-address` with `--ext-multiaddr`
This commit is contained in:
parent
57d707ff50
commit
eb9e727b1b
|
@ -147,11 +147,13 @@ var (
|
||||||
Destination: &options.NAT, // TODO: accept none,any,upnp,extaddr
|
Destination: &options.NAT, // TODO: accept none,any,upnp,extaddr
|
||||||
EnvVars: []string{"WAKUNODE2_NAT"},
|
EnvVars: []string{"WAKUNODE2_NAT"},
|
||||||
})
|
})
|
||||||
AdvertiseAddress = altsrc.NewStringFlag(&cli.StringFlag{
|
AdvertiseAddress = cliutils.NewGenericFlagMultiValue(&cli.GenericFlag{
|
||||||
Name: "advertise-address",
|
Name: "ext-multiaddr",
|
||||||
Usage: "External address to advertise to other nodes (overrides --address and --ws-address flags)",
|
Usage: "External address to advertise to other nodes. Ooverrides --address and --ws-address flags. Option may be repeated",
|
||||||
Destination: &options.AdvertiseAddress,
|
Value: &cliutils.MultiaddrSlice{
|
||||||
EnvVars: []string{"WAKUNODE2_ADVERTISE_ADDRESS"},
|
Values: &options.AdvertiseAddresses,
|
||||||
|
},
|
||||||
|
EnvVars: []string{"WAKUNODE2_EXT_MULTIADDR"},
|
||||||
})
|
})
|
||||||
ShowAddresses = altsrc.NewBoolFlag(&cli.BoolFlag{
|
ShowAddresses = altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||||
Name: "show-addresses",
|
Name: "show-addresses",
|
||||||
|
|
39
waku/node.go
39
waku/node.go
|
@ -56,26 +56,6 @@ func failOnErr(err error, msg string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func freePort() (int, error) {
|
|
||||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err := net.ListenTCP("tcp", addr)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
port := l.Addr().(*net.TCPAddr).Port
|
|
||||||
err = l.Close()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return port, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const dialTimeout = 7 * time.Second
|
const dialTimeout = 7 * time.Second
|
||||||
|
|
||||||
// Execute starts a go-waku node with settings determined by the Options parameter
|
// Execute starts a go-waku node with settings determined by the Options parameter
|
||||||
|
@ -127,21 +107,8 @@ func Execute(options Options) {
|
||||||
node.WithKeepAlive(options.KeepAlive),
|
node.WithKeepAlive(options.KeepAlive),
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.AdvertiseAddress != "" {
|
if len(options.AdvertiseAddresses) != 0 {
|
||||||
advertiseAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", options.AdvertiseAddress, options.Port))
|
nodeOpts = append(nodeOpts, node.WithAdvertiseAddresses(options.AdvertiseAddresses...))
|
||||||
failOnErr(err, "Invalid advertise address")
|
|
||||||
|
|
||||||
if advertiseAddr.Port == 0 {
|
|
||||||
for {
|
|
||||||
p, err := freePort()
|
|
||||||
if err == nil {
|
|
||||||
advertiseAddr.Port = p
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeOpts = append(nodeOpts, node.WithAdvertiseAddress(advertiseAddr))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.Dns4DomainName != "" {
|
if options.Dns4DomainName != "" {
|
||||||
|
@ -149,7 +116,7 @@ func Execute(options Options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
libp2pOpts := node.DefaultLibP2POptions
|
libp2pOpts := node.DefaultLibP2POptions
|
||||||
if options.AdvertiseAddress == "" {
|
if len(options.AdvertiseAddresses) == 0 {
|
||||||
libp2pOpts = append(libp2pOpts, libp2p.NATPortMap()) // Attempt to open ports using uPNP for NATed hosts.)
|
libp2pOpts = append(libp2pOpts, libp2p.NATPortMap()) // Attempt to open ports using uPNP for NATed hosts.)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,25 +141,25 @@ type PeerExchangeOptions struct {
|
||||||
// Options contains all the available features and settings that can be
|
// Options contains all the available features and settings that can be
|
||||||
// configured via flags when executing go-waku as a service.
|
// configured via flags when executing go-waku as a service.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Port int
|
Port int
|
||||||
Address string
|
Address string
|
||||||
Dns4DomainName string
|
Dns4DomainName string
|
||||||
NodeKey *ecdsa.PrivateKey
|
NodeKey *ecdsa.PrivateKey
|
||||||
KeyFile string
|
KeyFile string
|
||||||
KeyPasswd string
|
KeyPasswd string
|
||||||
GenerateKey bool
|
GenerateKey bool
|
||||||
Overwrite bool
|
Overwrite bool
|
||||||
StaticNodes []multiaddr.Multiaddr
|
StaticNodes []multiaddr.Multiaddr
|
||||||
KeepAlive time.Duration
|
KeepAlive time.Duration
|
||||||
AdvertiseAddress string
|
AdvertiseAddresses []multiaddr.Multiaddr
|
||||||
ShowAddresses bool
|
ShowAddresses bool
|
||||||
LogLevel string
|
LogLevel string
|
||||||
LogEncoding string
|
LogEncoding string
|
||||||
LogOutput string
|
LogOutput string
|
||||||
NAT string
|
NAT string
|
||||||
PersistPeers bool
|
PersistPeers bool
|
||||||
UserAgent string
|
UserAgent string
|
||||||
PProf bool
|
PProf bool
|
||||||
|
|
||||||
PeerExchange PeerExchangeOptions
|
PeerExchange PeerExchangeOptions
|
||||||
Websocket WSOptions
|
Websocket WSOptions
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/host"
|
"github.com/libp2p/go-libp2p/core/host"
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
"github.com/multiformats/go-multiaddr"
|
||||||
"github.com/waku-org/go-discover/discover"
|
"github.com/waku-org/go-discover/discover"
|
||||||
"github.com/waku-org/go-waku/logging"
|
"github.com/waku-org/go-waku/logging"
|
||||||
"github.com/waku-org/go-waku/waku/v2/utils"
|
"github.com/waku-org/go-waku/waku/v2/utils"
|
||||||
|
@ -22,7 +23,6 @@ import (
|
||||||
|
|
||||||
var ErrNoDiscV5Listener = errors.New("no discv5 listener")
|
var ErrNoDiscV5Listener = errors.New("no discv5 listener")
|
||||||
|
|
||||||
|
|
||||||
type DiscoveryV5 struct {
|
type DiscoveryV5 struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ type discV5Parameters struct {
|
||||||
autoUpdate bool
|
autoUpdate bool
|
||||||
bootnodes []*enode.Node
|
bootnodes []*enode.Node
|
||||||
udpPort uint
|
udpPort uint
|
||||||
advertiseAddr *net.IP
|
advertiseAddr []multiaddr.Multiaddr
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiscoveryV5Option func(*discV5Parameters)
|
type DiscoveryV5Option func(*discV5Parameters)
|
||||||
|
@ -65,9 +65,9 @@ func WithBootnodes(bootnodes []*enode.Node) DiscoveryV5Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithAdvertiseAddr(addr net.IP) DiscoveryV5Option {
|
func WithAdvertiseAddr(addr []multiaddr.Multiaddr) DiscoveryV5Option {
|
||||||
return func(params *discV5Parameters) {
|
return func(params *discV5Parameters) {
|
||||||
params.advertiseAddr = &addr
|
params.advertiseAddr = addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ func writeMultiaddressField(localnode *enode.LocalNode, addrAggr []ma.Multiaddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WakuNode) updateLocalNode(localnode *enode.LocalNode, multiaddrs []ma.Multiaddr, ipAddr *net.TCPAddr, udpPort uint, wakuFlags utils.WakuEnrBitfield, advertiseAddr *net.IP, shouldAutoUpdate bool, log *zap.Logger) error {
|
func (w *WakuNode) updateLocalNode(localnode *enode.LocalNode, multiaddrs []ma.Multiaddr, ipAddr *net.TCPAddr, udpPort uint, wakuFlags utils.WakuEnrBitfield, advertiseAddr []ma.Multiaddr, shouldAutoUpdate bool, log *zap.Logger) error {
|
||||||
localnode.SetFallbackUDP(int(udpPort))
|
localnode.SetFallbackUDP(int(udpPort))
|
||||||
localnode.Set(enr.WithEntry(utils.WakuENRField, wakuFlags))
|
localnode.Set(enr.WithEntry(utils.WakuENRField, wakuFlags))
|
||||||
localnode.SetFallbackIP(net.IP{127, 0, 0, 1})
|
localnode.SetFallbackIP(net.IP{127, 0, 0, 1})
|
||||||
|
@ -65,13 +65,22 @@ func (w *WakuNode) updateLocalNode(localnode *enode.LocalNode, multiaddrs []ma.M
|
||||||
if advertiseAddr != nil {
|
if advertiseAddr != nil {
|
||||||
// An advertised address disables libp2p address updates
|
// An advertised address disables libp2p address updates
|
||||||
// and discv5 predictions
|
// and discv5 predictions
|
||||||
localnode.SetStaticIP(*advertiseAddr)
|
|
||||||
|
ipAddr, err := selectMostExternalAddress(advertiseAddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
localnode.SetStaticIP(ipAddr.IP)
|
||||||
localnode.Set(enr.TCP(uint16(ipAddr.Port))) // TODO: ipv6?
|
localnode.Set(enr.TCP(uint16(ipAddr.Port))) // TODO: ipv6?
|
||||||
|
|
||||||
|
return writeMultiaddresses(localnode, multiaddrs)
|
||||||
} else if !shouldAutoUpdate {
|
} else if !shouldAutoUpdate {
|
||||||
// We received a libp2p address update. Autoupdate is disabled
|
// We received a libp2p address update. Autoupdate is disabled
|
||||||
// Using a static ip will disable endpoint prediction.
|
// Using a static ip will disable endpoint prediction.
|
||||||
localnode.SetStaticIP(ipAddr.IP)
|
localnode.SetStaticIP(ipAddr.IP)
|
||||||
localnode.Set(enr.TCP(uint16(ipAddr.Port))) // TODO: ipv6?
|
localnode.Set(enr.TCP(uint16(ipAddr.Port))) // TODO: ipv6?
|
||||||
|
return writeMultiaddresses(localnode, multiaddrs)
|
||||||
} else {
|
} else {
|
||||||
// We received a libp2p address update, but we should still
|
// We received a libp2p address update, but we should still
|
||||||
// allow discv5 to update the enr record. We set the localnode
|
// allow discv5 to update the enr record. We set the localnode
|
||||||
|
@ -94,8 +103,13 @@ func (w *WakuNode) updateLocalNode(localnode *enode.LocalNode, multiaddrs []ma.M
|
||||||
localnode.Delete(enr.IPv6{})
|
localnode.Delete(enr.IPv6{})
|
||||||
localnode.Delete(enr.TCP6(0))
|
localnode.Delete(enr.TCP6(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return writeMultiaddresses(localnode, multiaddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeMultiaddresses(localnode *enode.LocalNode, multiaddrs []ma.Multiaddr) error {
|
||||||
// Randomly shuffle multiaddresses
|
// Randomly shuffle multiaddresses
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
rand.Shuffle(len(multiaddrs), func(i, j int) { multiaddrs[i], multiaddrs[j] = multiaddrs[j], multiaddrs[i] })
|
rand.Shuffle(len(multiaddrs), func(i, j int) { multiaddrs[i], multiaddrs[j] = multiaddrs[j], multiaddrs[i] })
|
||||||
|
@ -203,7 +217,6 @@ func extractIPAddressForENR(addr ma.Multiaddr) (*net.TCPAddr, error) {
|
||||||
|
|
||||||
func selectMostExternalAddress(addresses []ma.Multiaddr) (*net.TCPAddr, error) {
|
func selectMostExternalAddress(addresses []ma.Multiaddr) (*net.TCPAddr, error) {
|
||||||
var ipAddrs []*net.TCPAddr
|
var ipAddrs []*net.TCPAddr
|
||||||
|
|
||||||
for _, addr := range addresses {
|
for _, addr := range addresses {
|
||||||
ipAddr, err := extractIPAddressForENR(addr)
|
ipAddr, err := extractIPAddressForENR(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -337,7 +350,7 @@ func (w *WakuNode) setupENR(ctx context.Context, addrs []ma.Multiaddr) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w.updateLocalNode(w.localNode, multiaddresses, ipAddr, w.opts.udpPort, w.wakuFlag, w.opts.advertiseAddr, w.opts.discV5autoUpdate, w.log)
|
err = w.updateLocalNode(w.localNode, multiaddresses, ipAddr, w.opts.udpPort, w.wakuFlag, w.opts.advertiseAddrs, w.opts.discV5autoUpdate, w.log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.log.Error("updating localnode ENR record", zap.Error(err))
|
w.log.Error("updating localnode ENR record", zap.Error(err))
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -554,8 +554,8 @@ func (w *WakuNode) mountDiscV5() error {
|
||||||
discv5.WithAutoUpdate(w.opts.discV5autoUpdate),
|
discv5.WithAutoUpdate(w.opts.discV5autoUpdate),
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.opts.advertiseAddr != nil {
|
if w.opts.advertiseAddrs != nil {
|
||||||
discV5Options = append(discV5Options, discv5.WithAdvertiseAddr(*w.opts.advertiseAddr))
|
discV5Options = append(discV5Options, discv5.WithAdvertiseAddr(w.opts.advertiseAddrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
quic "github.com/libp2p/go-libp2p/p2p/transport/quic"
|
quic "github.com/libp2p/go-libp2p/p2p/transport/quic"
|
||||||
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
|
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
|
||||||
"github.com/multiformats/go-multiaddr"
|
"github.com/multiformats/go-multiaddr"
|
||||||
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
manet "github.com/multiformats/go-multiaddr/net"
|
manet "github.com/multiformats/go-multiaddr/net"
|
||||||
"github.com/waku-org/go-waku/waku/v2/protocol/filter"
|
"github.com/waku-org/go-waku/waku/v2/protocol/filter"
|
||||||
"github.com/waku-org/go-waku/waku/v2/protocol/pb"
|
"github.com/waku-org/go-waku/waku/v2/protocol/pb"
|
||||||
|
@ -42,7 +43,7 @@ const defaultMinRelayPeersToPublish = 0
|
||||||
type WakuNodeParameters struct {
|
type WakuNodeParameters struct {
|
||||||
hostAddr *net.TCPAddr
|
hostAddr *net.TCPAddr
|
||||||
dns4Domain string
|
dns4Domain string
|
||||||
advertiseAddr *net.IP
|
advertiseAddrs []multiaddr.Multiaddr
|
||||||
multiAddr []multiaddr.Multiaddr
|
multiAddr []multiaddr.Multiaddr
|
||||||
addressFactory basichost.AddrsFactory
|
addressFactory basichost.AddrsFactory
|
||||||
privKey *ecdsa.PrivateKey
|
privKey *ecdsa.PrivateKey
|
||||||
|
@ -199,32 +200,12 @@ func WithHostAddress(hostAddr *net.TCPAddr) WakuNodeOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithAdvertiseAddress is a WakuNodeOption that allows overriding the address used in the waku node with custom value
|
// WithAdvertiseAddresses is a WakuNodeOption that allows overriding the address used in the waku node with custom value
|
||||||
func WithAdvertiseAddress(address *net.TCPAddr) WakuNodeOption {
|
func WithAdvertiseAddresses(advertiseAddrs ...ma.Multiaddr) WakuNodeOption {
|
||||||
return func(params *WakuNodeParameters) error {
|
return func(params *WakuNodeParameters) error {
|
||||||
params.advertiseAddr = &address.IP
|
params.advertiseAddrs = advertiseAddrs
|
||||||
|
|
||||||
advertiseAddress, err := manet.FromNetAddr(address)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
params.addressFactory = func([]multiaddr.Multiaddr) (addresses []multiaddr.Multiaddr) {
|
params.addressFactory = func([]multiaddr.Multiaddr) (addresses []multiaddr.Multiaddr) {
|
||||||
addresses = append(addresses, advertiseAddress)
|
return advertiseAddrs
|
||||||
if params.enableWSS {
|
|
||||||
wsMa, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d/wss", address.IP, params.wssPort))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
addresses = append(addresses, wsMa)
|
|
||||||
} else if params.enableWS {
|
|
||||||
wsMa, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d/ws", address.IP, params.wsPort))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
addresses = append(addresses, wsMa)
|
|
||||||
}
|
|
||||||
return addresses
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,15 +27,13 @@ func TestWakuOptions(t *testing.T) {
|
||||||
addr, err := multiaddr.NewMultiaddr("/ip4/0.0.0.0/tcp/4000/ws")
|
addr, err := multiaddr.NewMultiaddr("/ip4/0.0.0.0/tcp/4000/ws")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
advertiseAddr, _ := net.ResolveTCPAddr("tcp", "0.0.0.0:0")
|
|
||||||
|
|
||||||
storeFactory := func(w *WakuNode) store.Store {
|
storeFactory := func(w *WakuNode) store.Store {
|
||||||
return store.NewWakuStore(w.host, w.swap, w.opts.messageProvider, w.timesource, w.log)
|
return store.NewWakuStore(w.host, w.swap, w.opts.messageProvider, w.timesource, w.log)
|
||||||
}
|
}
|
||||||
|
|
||||||
options := []WakuNodeOption{
|
options := []WakuNodeOption{
|
||||||
WithHostAddress(hostAddr),
|
WithHostAddress(hostAddr),
|
||||||
WithAdvertiseAddress(advertiseAddr),
|
WithAdvertiseAddresses(addr),
|
||||||
WithMultiaddress([]multiaddr.Multiaddr{addr}),
|
WithMultiaddress([]multiaddr.Multiaddr{addr}),
|
||||||
WithPrivateKey(prvKey),
|
WithPrivateKey(prvKey),
|
||||||
WithLibP2POptions(),
|
WithLibP2POptions(),
|
||||||
|
|
Loading…
Reference in New Issue