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

Loading…
Cancel
Save