Dns discovery (#1015)

* Add cli flag and parse dns address

* Fail if enr udp port isn't set

* Improve docs and address parsing

* address review comments

* Remove debug statements

* Add requires condition for enr-address

* Return address in error
This commit is contained in:
Pawan Dhananjay 2020-05-03 18:48:19 +05:30 committed by GitHub
parent b4a1a2e483
commit 36f213c092
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 12 deletions

View File

@ -94,10 +94,12 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
Arg::with_name("enr-address") Arg::with_name("enr-address")
.long("enr-address") .long("enr-address")
.value_name("ADDRESS") .value_name("ADDRESS")
.help("The IP address to broadcast to other peers on how to reach this node. \ .help("The IP address/ DNS address to broadcast to other peers on how to reach this node. \
If a DNS address is provided, the enr-address is set to the IP address it resolves to and \
does not auto-update based on PONG responses in discovery. \
Set this only if you are sure other nodes can connect to your local node on this address. \ Set this only if you are sure other nodes can connect to your local node on this address. \
Discovery will automatically find your external address,if possible. Discovery will automatically find your external address,if possible.")
") .requires("enr-udp-port")
.takes_value(true), .takes_value(true),
) )
.arg( .arg(

View File

@ -9,7 +9,7 @@ use ssz::Encode;
use std::fs; use std::fs;
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs};
use std::net::{TcpListener, UdpSocket}; use std::net::{TcpListener, UdpSocket};
use std::path::PathBuf; use std::path::PathBuf;
use types::{ChainSpec, EthSpec}; use types::{ChainSpec, EthSpec};
@ -141,14 +141,6 @@ pub fn get_config<E: EthSpec>(
.collect::<Result<Vec<Multiaddr>, _>>()?; .collect::<Result<Vec<Multiaddr>, _>>()?;
} }
if let Some(enr_address_str) = cli_args.value_of("enr-address") {
client_config.network.enr_address = Some(
enr_address_str
.parse()
.map_err(|_| format!("Invalid discovery address: {:?}", enr_address_str))?,
)
}
if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp-port") { if let Some(enr_udp_port_str) = cli_args.value_of("enr-udp-port") {
client_config.network.enr_udp_port = Some( client_config.network.enr_udp_port = Some(
enr_udp_port_str enr_udp_port_str
@ -178,6 +170,40 @@ pub fn get_config<E: EthSpec>(
client_config.network.enr_udp_port = Some(client_config.network.discovery_port); client_config.network.enr_udp_port = Some(client_config.network.discovery_port);
} }
if let Some(enr_address) = cli_args.value_of("enr-address") {
let resolved_addr = match enr_address.parse::<IpAddr>() {
Ok(addr) => addr, // // Input is an IpAddr
Err(_) => {
let mut addr = enr_address.to_string();
// Appending enr-port to the dns hostname to appease `to_socket_addrs()` parsing.
// Since enr-update is disabled with a dns address, not setting the enr-udp-port
// will make the node undiscoverable.
if let Some(enr_udp_port) = client_config.network.enr_udp_port {
addr.push_str(&format!(":{}", enr_udp_port.to_string()));
} else {
return Err(
"enr-udp-port must be set for node to be discoverable with dns address"
.into(),
);
}
// `to_socket_addr()` does the dns resolution
// Note: `to_socket_addrs()` is a blocking call
let resolved_addr = if let Ok(mut resolved_addrs) = addr.to_socket_addrs() {
// Pick the first ip from the list of resolved addresses
resolved_addrs
.next()
.map(|a| a.ip())
.ok_or_else(|| format!("Resolved dns addr contains no entries"))?
} else {
return Err(format!("Failed to parse enr-address: {}", enr_address));
};
client_config.network.discv5_config.enr_update = false;
resolved_addr
}
};
client_config.network.enr_address = Some(resolved_addr);
}
if cli_args.is_present("disable_enr_auto_update") { if cli_args.is_present("disable_enr_auto_update") {
client_config.network.discv5_config.enr_update = false; client_config.network.discv5_config.enr_update = false;
} }