Simplify `to_address_string` by implying more context on the structure.

pull/438/head
Philipp Hoenisch 3 years ago
parent c8e6db24f8
commit ea6e2f8f09
No known key found for this signature in database
GPG Key ID: E5F8E74C672BC666

@ -1,3 +1,4 @@
use anyhow::anyhow;
use data_encoding::BASE32; use data_encoding::BASE32;
use futures::future::Ready; use futures::future::Ready;
use futures::prelude::*; use futures::prelude::*;
@ -6,7 +7,6 @@ use libp2p::core::transport::TransportError;
use libp2p::core::Transport; use libp2p::core::Transport;
use libp2p::tcp::tokio::{Tcp, TcpStream}; use libp2p::tcp::tokio::{Tcp, TcpStream};
use libp2p::tcp::{GenTcpConfig, TcpListenStream, TokioTcpConfig}; use libp2p::tcp::{GenTcpConfig, TcpListenStream, TokioTcpConfig};
use std::cmp::Ordering;
use std::io; use std::io;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::pin::Pin; use std::pin::Pin;
@ -55,13 +55,14 @@ impl Transport for TorTcpConfig {
} }
match to_address_string(addr.clone()) { match to_address_string(addr.clone()) {
Some(tor_address_string) => { Ok(tor_address_string) => {
Ok(Box::pin(do_tor_dial(self.socks_port, tor_address_string))) Ok(Box::pin(do_tor_dial(self.socks_port, tor_address_string)))
} }
_ => { Err(e) => {
tracing::warn!( tracing::warn!(
"Address {} could not be formatted. Dialling via clear net", "Address {} could not be formatted. Dialling via clear net. Details: {}",
addr addr,
e
); );
self.inner.dial(addr) self.inner.dial(addr)
} }
@ -76,68 +77,41 @@ impl Transport for TorTcpConfig {
/// Tor expects an address format of ADDR:PORT. /// Tor expects an address format of ADDR:PORT.
/// This helper function tries to convert the provided multi-address into this /// This helper function tries to convert the provided multi-address into this
/// format. None is returned if an unsupported protocol was provided. /// format. None is returned if an unsupported protocol was provided.
fn to_address_string(multi: Multiaddr) -> Option<String> { fn to_address_string(multi: Multiaddr) -> anyhow::Result<String> {
let components = multi.iter(); let mut protocols = multi.iter();
for protocol in components { let address_string = match protocols.next() {
if let Protocol::Onion3(addr) = protocol { // if it is an Onion address, we have all we need and can return
return Some(format!( Some(Protocol::Onion3(addr)) => {
return Ok(format!(
"{}.onion:{}", "{}.onion:{}",
BASE32.encode(addr.hash()).to_lowercase(), BASE32.encode(addr.hash()).to_lowercase(),
addr.port() addr.port()
)); ))
} }
// Deal with non-onion addresses
Some(Protocol::Ip4(addr)) => Some(format!("{}", addr)),
Some(Protocol::Ip6(addr)) => Some(format!("{}", addr)),
Some(Protocol::Dns(addr)) => Some(format!("{}", addr)),
Some(Protocol::Dns4(addr)) => Some(format!("{}", addr)),
_ => None,
} }
.ok_or_else(|| {
// Deal with non-onion addresses anyhow!(
let protocols = multi.iter().collect::<Vec<_>>();
let address_string = protocols
.iter()
.filter_map(|protocol| match protocol {
Protocol::Ip4(addr) => Some(format!("{}", addr)),
Protocol::Ip6(addr) => Some(format!("{}", addr)),
Protocol::Dns(addr) => Some(format!("{}", addr)),
Protocol::Dns4(addr) => Some(format!("{}", addr)),
_ => None,
})
.collect::<Vec<_>>();
if address_string.is_empty() {
tracing::warn!(
"Could not format address {}. Please consider reporting this issue. ", "Could not format address {}. Please consider reporting this issue. ",
multi multi
); )
return None; })?;
}
let port_string = match protocols.next() {
let address_string = address_string Some(Protocol::Tcp(port)) => Some(format!("{}", port)),
.get(0) Some(Protocol::Udp(port)) => Some(format!("{}", port)),
.expect("Valid multiaddr consist out of max 1 address") _ => None,
.clone(); };
// check for port if let Some(port) = port_string {
let port = protocols Ok(format!("{}:{}", address_string, port))
.iter() } else {
.filter_map(|protocol| match protocol { Ok(address_string)
Protocol::Tcp(port) => Some(format!("{}", port)),
Protocol::Udp(port) => Some(format!("{}", port)),
_ => None,
})
.collect::<Vec<_>>();
match port.len().cmp(&1) {
Ordering::Greater => {
tracing::warn!(
"Did not expect more than 1 port in address {}. Please consider reporting this issue.",
multi
);
Some(address_string)
}
Ordering::Less => Some(address_string),
Ordering::Equal => Some(format!(
"{}:{}",
address_string,
port.get(0)
.expect("Already verified the length of the vec.")
)),
} }
} }
@ -219,7 +193,7 @@ pub mod test {
#[test] #[test]
fn dnsaddr_to_address_string_should_be_none() { fn dnsaddr_to_address_string_should_be_none() {
let address = "/dnsaddr/randomdomain.com"; let address = "/dnsaddr/randomdomain.com";
let address_string = to_address_string(address.parse().unwrap()); let address_string = to_address_string(address.parse().unwrap()).ok();
assert_eq!(address_string, None); assert_eq!(address_string, None);
} }
} }

Loading…
Cancel
Save