diff --git a/.gitmodules b/.gitmodules index 9d46fd00a..f3da114d5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -135,3 +135,8 @@ url = https://github.com/status-im/nim-dnsdisc.git ignore = untracked branch = main +[submodule "vendor/dnsclient.nim"] + path = vendor/dnsclient.nim + url = https://github.com/jm-clius/dnsclient.nim.git + ignore = untracked + branch = master diff --git a/examples/v2/chat2.nim b/examples/v2/chat2.nim index 493afabb1..043b19754 100644 --- a/examples/v2/chat2.nim +++ b/examples/v2/chat2.nim @@ -19,8 +19,10 @@ import libp2p/[switch, # manage transports, a single entry poi protobuf/minprotobuf, # message serialisation/deserialisation from and to protobufs protocols/protocol, # define the protocol base type protocols/secure/secio, # define the protocol of secure input / output, allows encrypted communication that uses public keys to validate signed messages instead of a certificate authority like in TLS + nameresolving/dnsresolver,# define DNS resolution muxers/muxer] # define an interface for stream multiplexing, allowing peers to offer many protocols over a single connection import ../../waku/v2/node/[wakunode2, waku_payload], + ../../waku/v2/node/./dnsdisc/waku_dnsdisc, ../../waku/v2/utils/peers, ../../waku/common/utils/nat, ./config_chat2 @@ -344,6 +346,30 @@ proc processInput(rfd: AsyncFD, rng: ref BrHmacDrbgContext) {.async.} = if conf.staticnodes.len > 0: await connectToNodes(chat, conf.staticnodes) + elif conf.dnsDiscovery and conf.dnsDiscoveryUrl != "": + # Discover nodes via DNS + debug "Discovering nodes using Waku DNS discovery", url=conf.dnsDiscoveryUrl + + var nameServers: seq[TransportAddress] + for ip in conf.dnsDiscoveryNameServers: + nameServers.add(initTAddress(ip, Port(53))) # Assume all servers use port 53 + + let dnsResolver = DnsResolver.new(nameServers) + + proc resolver(domain: string): Future[string] {.async, gcsafe.} = + trace "resolving", domain=domain + let resolved = await dnsResolver.resolveTxt(domain) + return resolved[0] # Use only first answer + + var wakuDnsDiscovery = WakuDnsDiscovery.init(conf.dnsDiscoveryUrl, + resolver) + if wakuDnsDiscovery.isOk: + let discoveredPeers = wakuDnsDiscovery.get().findPeers() + if discoveredPeers.isOk: + info "Connecting to discovered peers" + waitFor chat.node.connectToNodes(discoveredPeers.get()) + else: + warn "Failed to init Waku DNS discovery" elif conf.fleet != Fleet.none: # Connect to at least one random fleet node echo "No static peers configured. Choosing one at random from " & $conf.fleet & " fleet..." diff --git a/examples/v2/config_chat2.nim b/examples/v2/config_chat2.nim index a21ed58b9..fc22a834c 100644 --- a/examples/v2/config_chat2.nim +++ b/examples/v2/config_chat2.nim @@ -186,6 +186,23 @@ type defaultValue: false name: "metrics-logging" }: bool + ## DNS discovery config + + dnsDiscovery* {. + desc: "Enable discovering nodes via DNS" + defaultValue: false + name: "dns-discovery" }: bool + + dnsDiscoveryUrl* {. + desc: "URL for DNS node list in format 'enrtree://@'", + defaultValue: "" + name: "dns-discovery-url" }: string + + dnsDiscoveryNameServers* {. + desc: "DNS name server IPs to query. Argument may be repeated." + defaultValue: @[ValidIpAddress.init("1.1.1.1"), ValidIpAddress.init("1.0.0.1")] + name: "dns-discovery-name-server" }: seq[ValidIpAddress] + ## Chat2 configuration fleet* {. diff --git a/vendor/dnsclient.nim b/vendor/dnsclient.nim new file mode 160000 index 000000000..c3ddd26a2 --- /dev/null +++ b/vendor/dnsclient.nim @@ -0,0 +1 @@ +Subproject commit c3ddd26a2eece2a7bb558cb67d2f92846f9b8402 diff --git a/vendor/nim-libp2p b/vendor/nim-libp2p index c1b2d45d1..f274bfe19 160000 --- a/vendor/nim-libp2p +++ b/vendor/nim-libp2p @@ -1 +1 @@ -Subproject commit c1b2d45d1b562df1af29012e58f33ff8bff597ac +Subproject commit f274bfe19db5a39ffbca177b52db7e8a7eb44537 diff --git a/waku/v2/node/config.nim b/waku/v2/node/config.nim index 2c5004a03..d41cb69dd 100644 --- a/waku/v2/node/config.nim +++ b/waku/v2/node/config.nim @@ -192,6 +192,11 @@ type desc: "URL for DNS node list in format 'enrtree://@'", defaultValue: "" name: "dns-discovery-url" }: string + + dnsDiscoveryNameServers* {. + desc: "DNS name server IPs to query. Argument may be repeated." + defaultValue: @[ValidIpAddress.init("1.1.1.1"), ValidIpAddress.init("1.0.0.1")] + name: "dns-discovery-name-server" }: seq[ValidIpAddress] # NOTE: Keys are different in nim-libp2p proc parseCmdArg*(T: type crypto.PrivateKey, p: TaintedString): T = diff --git a/waku/v2/node/wakunode2.nim b/waku/v2/node/wakunode2.nim index 9a16dc8ab..240d3cca1 100644 --- a/waku/v2/node/wakunode2.nim +++ b/waku/v2/node/wakunode2.nim @@ -9,6 +9,7 @@ import libp2p/crypto/crypto, libp2p/protocols/ping, libp2p/protocols/pubsub/gossipsub, + libp2p/nameresolving/dnsresolver, libp2p/builders, ../protocol/[waku_relay, waku_message], ../protocol/waku_store/waku_store, @@ -850,11 +851,21 @@ when isMainModule: # Connect to discovered nodes if conf.dnsDiscovery and conf.dnsDiscoveryUrl != "": - # @ TODO: this is merely POC integration with an empty resolver - debug "Waku DNS Discovery enabled. Using empty resolver." + debug "Discovering nodes using Waku DNS discovery", url=conf.dnsDiscoveryUrl + + var nameServers: seq[TransportAddress] + for ip in conf.dnsDiscoveryNameServers: + nameServers.add(initTAddress(ip, Port(53))) # Assume all servers use port 53 + + let dnsResolver = DnsResolver.new(nameServers) + + proc resolver(domain: string): Future[string] {.async, gcsafe.} = + trace "resolving", domain=domain + let resolved = await dnsResolver.resolveTxt(domain) + return resolved[0] # Use only first answer var wakuDnsDiscovery = WakuDnsDiscovery.init(conf.dnsDiscoveryUrl, - emptyResolver) # TODO: Add DNS resolver + resolver) if wakuDnsDiscovery.isOk: let discoveredPeers = wakuDnsDiscovery.get().findPeers() if discoveredPeers.isOk: