diff --git a/crates/anemo/src/endpoint.rs b/crates/anemo/src/endpoint.rs index c06ec23..add10a4 100644 --- a/crates/anemo/src/endpoint.rs +++ b/crates/anemo/src/endpoint.rs @@ -1,7 +1,4 @@ -use crate::{ - config::EndpointConfig, connection::Connection, types::Address, ConnectionOrigin, PeerId, - Result, -}; +use crate::{config::EndpointConfig, connection::Connection, ConnectionOrigin, PeerId, Result}; use std::sync::Arc; use std::time::Duration; use std::{ @@ -47,18 +44,21 @@ impl Endpoint { } #[cfg(test)] - fn new_with_address>(config: EndpointConfig, addr: A) -> Result { + fn new_with_address>( + config: EndpointConfig, + addr: A, + ) -> Result { let socket = std::net::UdpSocket::bind(addr.into())?; Self::new(config, socket) } - pub fn connect(&self, address: Address) -> Result { + pub fn connect(&self, address: SocketAddr) -> Result { self.connect_with_client_config(self.config.client_config().clone(), address) } pub fn connect_with_expected_peer_id( &self, - address: Address, + address: SocketAddr, peer_id: PeerId, ) -> Result { let config = self @@ -70,12 +70,10 @@ impl Endpoint { fn connect_with_client_config( &self, config: quinn::ClientConfig, - address: Address, + address: SocketAddr, ) -> Result { - let addr = address.resolve()?; - self.inner - .connect_with(config, addr, self.config.server_name()) + .connect_with(config, address, self.config.server_name()) .map_err(Into::into) .map(Connecting::new_outbound) } diff --git a/crates/anemo/src/network/connection_manager.rs b/crates/anemo/src/network/connection_manager.rs index 7d1058f..eaec5ac 100644 --- a/crates/anemo/src/network/connection_manager.rs +++ b/crates/anemo/src/network/connection_manager.rs @@ -429,33 +429,32 @@ impl ConnectionManager { peer_id: Option, oneshot: oneshot::Sender>, ) { - let target_address = address.clone(); - let maybe_connecting = if let Some(peer_id) = peer_id { - self.endpoint - .connect_with_expected_peer_id(address, peer_id) - } else { - self.endpoint.connect(address) - }; self.pending_connections.spawn(Self::dial_peer_task( - maybe_connecting, - target_address, + self.endpoint.clone(), + address, peer_id, oneshot, self.config.clone(), )); } - // TODO maybe look at cloning the endpoint so that we can try multiple addresses in the event - // Address resolves to multiple ips. + // TODO maybe look at trying all addresses that are resolved vs just the first one. async fn dial_peer_task( - maybe_connecting: Result, + endpoint: Arc, target_address: Address, peer_id: Option, oneshot: oneshot::Sender>, config: Arc, ) -> ConnectingOutput { let fut = async { - let connection = maybe_connecting?.await?; + let socket_addr = target_address.resolve().await?; + + let connection = if let Some(peer_id) = peer_id { + endpoint.connect_with_expected_peer_id(socket_addr, peer_id) + } else { + endpoint.connect(socket_addr) + }? + .await?; super::wire::handshake(connection).await }; diff --git a/crates/anemo/src/types/address.rs b/crates/anemo/src/types/address.rs index b9ba202..16964e1 100644 --- a/crates/anemo/src/types/address.rs +++ b/crates/anemo/src/types/address.rs @@ -14,7 +14,15 @@ pub enum Address { } impl Address { - pub(crate) fn resolve(&self) -> std::io::Result { + pub(crate) async fn resolve(&self) -> std::io::Result { + let address = self.to_owned(); + + tokio::task::spawn_blocking(move || address.resolve_blocking()) + .await + .unwrap() + } + + fn resolve_blocking(&self) -> std::io::Result { std::net::ToSocketAddrs::to_socket_addrs(self).and_then(|mut iter| { iter.next().ok_or_else(|| { std::io::Error::new(std::io::ErrorKind::NotFound, "unable to resolve host")