Skip to main content

leyline/tls/
resolver.rs

1use std::future::Future;
2use std::io;
3use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
4use std::pin::Pin;
5
6pub type ResolveFuture<'a> =
7    Pin<Box<dyn Future<Output = Result<Vec<SocketAddr>, io::Error>> + Send + 'a>>;
8
9pub trait Resolver: Send + Sync + 'static {
10    fn resolve<'a>(&'a self, host: &'a str, port: u16) -> ResolveFuture<'a>;
11}
12
13#[derive(Debug, Default, Clone, Copy)]
14pub struct SystemResolver;
15
16impl Resolver for SystemResolver {
17    fn resolve<'a>(&'a self, host: &'a str, port: u16) -> ResolveFuture<'a> {
18        if let Ok(ip) = host.parse::<IpAddr>() {
19            let addr = SocketAddr::new(ip, port);
20            return Box::pin(async move { Ok(vec![addr]) });
21        }
22        let host = host.to_owned();
23        Box::pin(async move {
24            let addr = format!("{host}:{port}");
25            tokio::task::spawn_blocking(move || {
26                addr.to_socket_addrs().map(|it| it.collect::<Vec<_>>())
27            })
28            .await
29            .map_err(io::Error::other)?
30        })
31    }
32}
33
34#[cfg(test)]
35mod tests;