Skip to content

Commit

Permalink
Use async-trait instead of Pin<Box<_>>
Browse files Browse the repository at this point in the history
  • Loading branch information
dlon committed Nov 21, 2024
1 parent a516890 commit 9df62bc
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 36 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mullvad-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ workspace = true
api-override = []

[dependencies]
async-trait = "0.1"
libc = "0.2"
chrono = { workspace = true }
thiserror = { workspace = true }
Expand Down
26 changes: 10 additions & 16 deletions mullvad-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(rustdoc::private_intra_doc_links)]
use async_trait::async_trait;
#[cfg(target_os = "android")]
use futures::channel::mpsc;
#[cfg(target_os = "android")]
Expand All @@ -16,7 +17,6 @@ use std::{
net::{IpAddr, Ipv4Addr, SocketAddr},
ops::Deref,
path::Path,
pin::Pin,
sync::{Arc, OnceLock},
};
use talpid_types::ErrorExt;
Expand Down Expand Up @@ -306,28 +306,21 @@ impl ApiEndpoint {
}
}

#[async_trait]
pub trait DnsResolver: 'static + Send + Sync {
fn resolve(
&self,
host: String,
) -> Pin<Box<dyn Future<Output = io::Result<Vec<IpAddr>>> + Send>>;
async fn resolve(&self, host: String) -> io::Result<Vec<IpAddr>>;
}

pub struct DefaultDnsResolver;

#[async_trait]
impl DnsResolver for DefaultDnsResolver {
fn resolve(
&self,
host: String,
) -> Pin<Box<dyn Future<Output = io::Result<Vec<IpAddr>>> + Send>> {
async fn resolve(&self, host: String) -> io::Result<Vec<IpAddr>> {
use std::net::ToSocketAddrs;

Box::pin(async move {
let addrs = tokio::task::spawn_blocking(move || (host, 0).to_socket_addrs())
.await
.expect("DNS task panicked")?;
Ok(addrs.map(|addr| addr.ip()).collect())
})
let addrs = tokio::task::spawn_blocking(move || (host, 0).to_socket_addrs())
.await
.expect("DNS task panicked")?;
Ok(addrs.map(|addr| addr.ip()).collect())
}
}

Expand Down Expand Up @@ -408,6 +401,7 @@ impl Runtime {
if API.disable_address_cache {
return Self::new_inner(
handle,
dns_resolver,
#[cfg(target_os = "android")]
socket_bypass_tx,
);
Expand Down
1 change: 1 addition & 0 deletions mullvad-daemon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ tokio = { workspace = true, features = ["test-util"] }

[target.'cfg(target_os="android")'.dependencies]
android_logger = "0.8"
async-trait = "0.1"
hickory-resolver = { version = "0.24.1" }

[target.'cfg(unix)'.dependencies]
Expand Down
37 changes: 17 additions & 20 deletions mullvad-daemon/src/android_dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
//! dropped, since it waits indefinitely on blocking threads. This is particularly bad on Android,
//! so we use a non-blocking resolver instead.
use async_trait::async_trait;
use hickory_resolver::{
config::{NameServerConfigGroup, ResolverConfig, ResolverOpts},
TokioAsyncResolver,
};
use mullvad_api::DnsResolver;
use std::{future::Future, io, net::IpAddr, pin::Pin};
use std::{io, net::IpAddr};

pub struct AndroidDnsResolver {
connectivity_listener: talpid_core::connectivity_listener::ConnectivityListener,
Expand All @@ -24,30 +25,26 @@ impl AndroidDnsResolver {
}
}

#[async_trait]
impl DnsResolver for AndroidDnsResolver {
fn resolve(
&self,
host: String,
) -> Pin<Box<dyn Future<Output = io::Result<Vec<IpAddr>>> + Send>> {
async fn resolve(&self, host: String) -> io::Result<Vec<IpAddr>> {
let ips = self.connectivity_listener.current_dns_servers();

Box::pin(async move {
let ips = ips.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("Failed to retrieve current servers: {err}"),
)
})?;
let group = NameServerConfigGroup::from_ips_clear(&ips, 53, false);
let ips = ips.map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("Failed to retrieve current servers: {err}"),
)
})?;
let group = NameServerConfigGroup::from_ips_clear(&ips, 53, false);

let config = ResolverConfig::from_parts(None, vec![], group);
let resolver = TokioAsyncResolver::tokio(config, ResolverOpts::default());
let config = ResolverConfig::from_parts(None, vec![], group);
let resolver = TokioAsyncResolver::tokio(config, ResolverOpts::default());

let lookup = resolver.lookup_ip(host).await.map_err(|err| {
io::Error::new(io::ErrorKind::Other, format!("lookup_ip failed: {err}"))
})?;
let lookup = resolver.lookup_ip(host).await.map_err(|err| {
io::Error::new(io::ErrorKind::Other, format!("lookup_ip failed: {err}"))
})?;

Ok(lookup.into_iter().collect())
})
Ok(lookup.into_iter().collect())
}
}
1 change: 1 addition & 0 deletions test/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9df62bc

Please sign in to comment.