mirror of https://github.com/waku-org/nwaku.git
chore: resolving DNS IP and publishing it when no extIp is provided (#2030)
This commit is contained in:
parent
89854a96f6
commit
7797b2cd03
|
@ -1,9 +1,12 @@
|
|||
import
|
||||
std/options,
|
||||
stew/shims/net,
|
||||
stew/results,
|
||||
chronicles,
|
||||
chronos,
|
||||
libp2p/crypto/crypto,
|
||||
libp2p/multiaddress
|
||||
libp2p/multiaddress,
|
||||
libp2p/nameresolving/dnsresolver,
|
||||
std/options,
|
||||
stew/results,
|
||||
stew/shims/net
|
||||
import
|
||||
../../waku/common/utils/nat,
|
||||
../../waku/node/config,
|
||||
|
@ -18,6 +21,23 @@ proc validateExtMultiAddrs*(vals: seq[string]):
|
|||
multiaddrs.add(multiaddr)
|
||||
return ok(multiaddrs)
|
||||
|
||||
proc dnsResolve*(domain: string, conf: WakuNodeConf): Future[Result[string, string]] {.async} =
|
||||
|
||||
# Use conf's DNS servers
|
||||
var nameServers: seq[TransportAddress]
|
||||
for ip in conf.dnsAddrsNameServers:
|
||||
nameServers.add(initTAddress(ip, Port(53))) # Assume all servers use port 53
|
||||
|
||||
let dnsResolver = DnsResolver.new(nameServers)
|
||||
|
||||
# Resolve domain IP
|
||||
let resolved = await dnsResolver.resolveIp(domain, 0.Port, Domain.AF_UNSPEC)
|
||||
|
||||
if resolved.len > 0:
|
||||
return ok(resolved[0].host) # Use only first answer
|
||||
else:
|
||||
return err("Could not resolve IP from DNS: empty response")
|
||||
|
||||
proc networkConfiguration*(conf: WakuNodeConf,
|
||||
clientId: string,
|
||||
): NetConfigResult =
|
||||
|
@ -30,7 +50,7 @@ proc networkConfiguration*(conf: WakuNodeConf,
|
|||
if natRes.isErr():
|
||||
return err("failed to setup NAT: " & $natRes.error)
|
||||
|
||||
let (extIp, extTcpPort, _) = natRes.get()
|
||||
var (extIp, extTcpPort, _) = natRes.get()
|
||||
|
||||
let
|
||||
dns4DomainName = if conf.dns4DomainName != "": some(conf.dns4DomainName)
|
||||
|
@ -69,6 +89,18 @@ proc networkConfiguration*(conf: WakuNodeConf,
|
|||
relay = conf.relay
|
||||
)
|
||||
|
||||
# Resolve and use DNS domain IP
|
||||
if dns4DomainName.isSome() and extIp.isNone():
|
||||
try:
|
||||
let dnsRes = waitFor dnsResolve(conf.dns4DomainName, conf)
|
||||
|
||||
if dnsRes.isErr():
|
||||
return err($dnsRes.error) # Pass error down the stack
|
||||
|
||||
extIp = some(ValidIpAddress.init(dnsRes.get()))
|
||||
except CatchableError:
|
||||
return err("Could not update extIp to resolved DNS IP: " & getCurrentExceptionMsg())
|
||||
|
||||
# Wrap in none because NetConfig does not have a default constructor
|
||||
# TODO: We could change bindIp in NetConfig to be something less restrictive
|
||||
# than ValidIpAddress, which doesn't allow default construction
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{.used.}
|
||||
|
||||
import
|
||||
std/sequtils,
|
||||
std/[sequtils,strutils],
|
||||
stew/byteutils,
|
||||
stew/shims/net as stewNet,
|
||||
testutils/unittests,
|
||||
|
@ -215,6 +215,65 @@ suite "WakuNode":
|
|||
node.announcedAddresses.len == 1
|
||||
node.announcedAddresses.contains(expectedDns4Addr)
|
||||
|
||||
asyncTest "Node uses dns4 resolved ip in announced addresses if no extIp is provided":
|
||||
let
|
||||
nodeKey = generateSecp256k1Key()
|
||||
bindIp = ValidIpAddress.init("0.0.0.0")
|
||||
bindPort = Port(0)
|
||||
|
||||
domainName = "status.im"
|
||||
node = newTestWakuNode(
|
||||
nodeKey,
|
||||
bindIp, bindPort,
|
||||
dns4DomainName = some(domainName))
|
||||
|
||||
var ipStr = ""
|
||||
var enrIp = node.enr.tryGet("ip", array[4, byte])
|
||||
|
||||
if enrIp.isSome():
|
||||
ipStr &= $ipv4(enrIp.get())
|
||||
|
||||
# Check that the IP filled is the one received by the DNS lookup
|
||||
# As IPs may change, we check that it's not empty, not the 0 IP and not localhost
|
||||
check:
|
||||
ipStr.len() > 0
|
||||
not ipStr.contains("0.0.0.0")
|
||||
not ipStr.contains("127.0.0.1")
|
||||
|
||||
asyncTest "Node creation fails when invalid dns4 address is provided":
|
||||
let
|
||||
nodeKey = generateSecp256k1Key()
|
||||
bindIp = ValidIpAddress.init("0.0.0.0")
|
||||
bindPort = Port(0)
|
||||
|
||||
inexistentDomain = "thisdomain.doesnot.exist"
|
||||
invalidDomain = ""
|
||||
expectedError = "Could not resolve IP from DNS: empty response"
|
||||
|
||||
var inexistentDomainErr, invalidDomainErr: string = ""
|
||||
|
||||
# Create node with inexistent domain
|
||||
try:
|
||||
let node = newTestWakuNode(
|
||||
nodeKey,
|
||||
bindIp, bindPort,
|
||||
dns4DomainName = some(inexistentDomain))
|
||||
except Exception as e:
|
||||
inexistentDomainErr = e.msg
|
||||
|
||||
# Create node with invalid domain
|
||||
try:
|
||||
let node = newTestWakuNode(
|
||||
nodeKey,
|
||||
bindIp, bindPort,
|
||||
dns4DomainName = some(invalidDomain))
|
||||
except Exception as e:
|
||||
invalidDomainErr = e.msg
|
||||
|
||||
# Check that exceptions were raised in both cases
|
||||
check:
|
||||
inexistentDomainErr == expectedError
|
||||
invalidDomainErr == expectedError
|
||||
|
||||
asyncTest "Agent string is set and advertised correctly":
|
||||
let
|
||||
|
|
|
@ -13,6 +13,8 @@ import
|
|||
../../../waku/node/peer_manager,
|
||||
../../../waku/waku_enr,
|
||||
../../../waku/waku_discv5,
|
||||
../../apps/wakunode2/internal_config,
|
||||
../wakunode2/test_app,
|
||||
./common
|
||||
|
||||
|
||||
|
@ -38,10 +40,29 @@ proc newTestWakuNode*(nodeKey: crypto.PrivateKey,
|
|||
discv5UdpPort = none(Port),
|
||||
agentString = none(string),
|
||||
peerStoreCapacity = none(int)): WakuNode =
|
||||
|
||||
var resolvedExtIp = extIp
|
||||
|
||||
# Update extPort to default value if it's missing and there's an extIp or a DNS domain
|
||||
let extPort = if (extIp.isSome() or dns4DomainName.isSome()) and
|
||||
extPort.isNone():
|
||||
some(Port(60000))
|
||||
else:
|
||||
extPort
|
||||
|
||||
if dns4DomainName.isSome() and extIp.isNone():
|
||||
let conf = defaultTestWakuNodeConf()
|
||||
# If there's an error resolving the IP, an exception is thrown and test fails
|
||||
let dnsRes = waitFor dnsResolve(dns4DomainName.get(), conf)
|
||||
if dnsRes.isErr():
|
||||
raise newException(Defect, $dnsRes.error)
|
||||
else:
|
||||
resolvedExtIp = some(ValidIpAddress.init(dnsRes.get()))
|
||||
|
||||
let netConfigRes = NetConfig.init(
|
||||
bindIp = bindIp,
|
||||
bindPort = bindPort,
|
||||
extIp = extIp,
|
||||
extIp = resolvedExtIp,
|
||||
extPort = extPort,
|
||||
extMultiAddrs = extMultiAddrs,
|
||||
wsBindPort = wsBindPort,
|
||||
|
|
|
@ -15,12 +15,13 @@ import
|
|||
../testlib/common,
|
||||
../testlib/wakucore
|
||||
|
||||
proc defaultTestWakuNodeConf(): WakuNodeConf =
|
||||
proc defaultTestWakuNodeConf*(): WakuNodeConf =
|
||||
WakuNodeConf(
|
||||
listenAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
rpcAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
restAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
metricsServerAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
dnsAddrsNameServers: @[ValidIpAddress.init("1.1.1.1"), ValidIpAddress.init("1.0.0.1")],
|
||||
nat: "any",
|
||||
maxConnections: 50,
|
||||
topics: @["/waku/2/default-waku/proto"],
|
||||
|
|
Loading…
Reference in New Issue