From 2b1502e3e3a3f2cd353eb3448c52e1c20bb4ecff Mon Sep 17 00:00:00 2001 From: Yevhenii Babichenko Date: Thu, 7 May 2020 15:16:55 +0300 Subject: [PATCH] dns: better error reporting --- jormungandr-lib/src/multiaddr.rs | 59 +++++++++++++++++---------- jormungandr/src/settings/start/mod.rs | 24 +++++------ 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/jormungandr-lib/src/multiaddr.rs b/jormungandr-lib/src/multiaddr.rs index 9f1678787f..7217fd2f9d 100644 --- a/jormungandr-lib/src/multiaddr.rs +++ b/jormungandr-lib/src/multiaddr.rs @@ -3,6 +3,19 @@ use std::{ io, net::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}, }; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + #[error("Not enough components in multiaddr")] + InvalidMultiaddr, + #[error("Cannot find DNS record")] + NotFound(#[source] io::Error), + #[error("No IPv4 address found")] + NoIP4, + #[error("No IPv6 address found")] + NoIP6, +} pub fn multiaddr_to_socket_addr(addr: &Multiaddr) -> Option { let mut components = addr.iter(); @@ -21,30 +34,34 @@ pub fn multiaddr_to_socket_addr(addr: &Multiaddr) -> Option { } } -pub fn multiaddr_resolve_dns(addr: Multiaddr) -> io::Result> { +pub fn multiaddr_resolve_dns(addr: &Multiaddr) -> Result, Error> { let mut components = addr.iter(); - let ip_or_fqdn = if let Some(ip) = components.next() { - ip - } else { - return Ok(None); - }; - - let port = if let Some(AddrComponent::TCP(port)) = components.next() { - port - } else { - return Ok(None); - }; + let ip_or_fqdn = components.next().ok_or(Error::InvalidMultiaddr)?; + let port = components + .next() + .and_then(|ac| { + if let AddrComponent::TCP(port) = ac { + Some(port) + } else { + None + } + }) + .ok_or(Error::InvalidMultiaddr)?; - let maybe_socket_addr = match ip_or_fqdn { - AddrComponent::DNS4(fqdn) => (fqdn.as_ref(), port) - .to_socket_addrs()? - .find(|addr| matches!(addr, SocketAddr::V4(_))), - AddrComponent::DNS6(fqdn) => (fqdn.as_ref(), port) - .to_socket_addrs()? - .find(|addr| matches!(addr, SocketAddr::V6(_))), - _ => return Ok(Some(addr)), + let socket_addr = match ip_or_fqdn { + AddrComponent::DNS4(fqdn) => (fqdn.as_str(), port) + .to_socket_addrs() + .map_err(Error::NotFound)? + .find(|addr| matches!(addr, SocketAddr::V4(_))) + .ok_or(Error::NoIP4)?, + AddrComponent::DNS6(fqdn) => (fqdn.as_str(), port) + .to_socket_addrs() + .map_err(Error::NotFound)? + .find(|addr| matches!(addr, SocketAddr::V6(_))) + .ok_or(Error::NoIP6)?, + _ => return Ok(None), }; - Ok(maybe_socket_addr.map(|socket_addr| socket_addr.to_multiaddr().unwrap())) + Ok(Some(socket_addr.to_multiaddr().unwrap())) } diff --git a/jormungandr/src/settings/start/mod.rs b/jormungandr/src/settings/start/mod.rs index dcb92b680b..96783ea13c 100644 --- a/jormungandr/src/settings/start/mod.rs +++ b/jormungandr/src/settings/start/mod.rs @@ -196,7 +196,7 @@ fn generate_network( config: &Option, logger: &Logger, ) -> Result { - use jormungandr_lib::multiaddr::*; + use jormungandr_lib::multiaddr::{multiaddr_resolve_dns, multiaddr_to_socket_addr}; let (mut p2p, http_fetch_block0_service, skip_bootstrap, bootstrap_from_trusted_peers) = if let Some(cfg) = config { @@ -220,25 +220,23 @@ fn generate_network( p2p.trusted_peers.as_mut().map(|peers| { *peers = peers.iter().filter_map(|peer| { - let address = match multiaddr_resolve_dns(peer.address.multi_address().clone()) { - Ok(Some(addr)) => { - info!(logger, "DNS resolved"; "fqdn" => peer.address.multi_address().to_string(), "resolved" => addr.to_string()); - addr + match multiaddr_resolve_dns(peer.address.multi_address()) { + Ok(Some(address)) => { + info!(logger, "DNS resolved"; "fqdn" => peer.address.multi_address().to_string(), "resolved" => address.to_string()); + let address = poldercast::Address::from(address); + Some(config::TrustedPeer { + address, + id: peer.id.clone(), + }) } Ok(None) => { - warn!(logger, "failed to resolve DNS"; "fqdn" => peer.address.multi_address().to_string()); - return None; + Some(peer.clone()) }, Err(e) => { warn!(logger, "failed to resolve dns"; "fqdn" => peer.address.multi_address().to_string(), "error" => e.to_string()); return None; } - }; - let address = poldercast::Address::from(address); - Some(config::TrustedPeer { - address, - id: peer.id.clone(), - }) + } }).collect(); });