diff --git a/crates/arti/src/dns.rs b/crates/arti/src/dns.rs index 034daa2a0..8e3970c9b 100644 --- a/crates/arti/src/dns.rs +++ b/crates/arti/src/dns.rs @@ -19,6 +19,9 @@ use tor_rtcompat::{Runtime, UdpSocket}; use anyhow::{anyhow, Result}; +/// Maximum lenght for receiving a single datagram +const MAX_DATAGRAM_SIZE: usize = 1536; + /// Send an error DNS response with code NotImplemented async fn not_implemented(id: u16, addr: &SocketAddr, socket: &U) -> Result<()> { let response = Message::error_msg(id, OpCode::Query, ResponseCode::NotImp); @@ -133,7 +136,7 @@ pub(crate) async fn run_dns_resolver( // We weren't able to bind any ports: There's nothing to do. if listeners.is_empty() { error!("Couldn't open any DNS listeners."); - return Err(anyhow!("Couldn't open SOCKS listeners")); + return Err(anyhow!("Couldn't open any DNS listeners")); } let mut incoming = futures::stream::select_all( @@ -141,7 +144,7 @@ pub(crate) async fn run_dns_resolver( .into_iter() .map(|socket| { futures::stream::unfold(Arc::new(socket), |socket| async { - let mut packet = [0; 1536]; + let mut packet = [0; MAX_DATAGRAM_SIZE]; let packet = socket .recv(&mut packet) .await diff --git a/crates/arti/src/lib.rs b/crates/arti/src/lib.rs index 87dbd7759..e4d357d7c 100644 --- a/crates/arti/src/lib.rs +++ b/crates/arti/src/lib.rs @@ -131,6 +131,9 @@ use tracing::{info, warn}; use std::convert::TryInto; +/// Shorthand for a boxed and pinned Future. +type PinnedFuture = std::pin::Pin>>; + /// Run the main loop of the proxy. /// /// # Panics @@ -156,21 +159,23 @@ pub async fn run( watch_cfg::watch_for_config_changes(config_sources, arti_config, client.clone())?; } - let mut proxy: Vec>>>> = Vec::new(); + let mut proxy: Vec, &str)>> = Vec::new(); if socks_port != 0 { - proxy.push(Box::pin(socks::run_socks_proxy( - runtime.clone(), - client.isolated_client(), - socks_port, - ))); + let runtime = runtime.clone(); + let client = client.isolated_client(); + proxy.push(Box::pin(async move { + let res = socks::run_socks_proxy(runtime, client, socks_port).await; + (res, "SOCKS") + })); } if dns_port != 0 { - proxy.push(Box::pin(dns::run_dns_resolver( - runtime.clone(), - client.isolated_client(), - dns_port, - ))); + let runtime = runtime.clone(); + let client = client.isolated_client(); + proxy.push(Box::pin(async move { + let res = dns::run_dns_resolver(runtime, client, dns_port).await; + (res, "DNS") + })); } if proxy.is_empty() { @@ -179,12 +184,12 @@ pub async fn run( return Ok(()); } - let proxy = futures::future::select_all(proxy); + let proxy = futures::future::select_all(proxy).map(|(finished, _index, _others)| finished); futures::select!( r = exit::wait_for_ctrl_c().fuse() => r.context("waiting for termination signal"), r = proxy.fuse() - => r.0.context("SOCKS proxy failure"), + => r.0.context(format!("{} proxy failure", r.1)), r = async { client.bootstrap().await?; info!("Sufficiently bootstrapped; system SOCKS now functional."); diff --git a/crates/tor-rtcompat/src/traits.rs b/crates/tor-rtcompat/src/traits.rs index 6901a891f..7c028d57d 100644 --- a/crates/tor-rtcompat/src/traits.rs +++ b/crates/tor-rtcompat/src/traits.rs @@ -204,7 +204,7 @@ pub trait UdpSocket { /// Connect to a remote address. After calling this [`UdpSocket::recv`] may only /// return that same address, and the target provided to [`UdpSocket::send`] must /// be this address. - // rational for taking &mut self: this changes the behavior of the whole socket, + // rationale for taking &mut self: this changes the behavior of the whole socket, // so it should probably only be used when you have ownership of the socket and // not when sharing it. async fn connect(&mut self, addr: &SocketAddr) -> IoResult<()>;