-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
trust_dns.rs
60 lines (50 loc) · 1.84 KB
/
trust_dns.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! DNS resolution via the [trust_dns_resolver](https://github.com/bluejekyll/trust-dns) crate
use hyper::client::connect::dns::Name;
use once_cell::sync::OnceCell;
pub use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
use trust_dns_resolver::{lookup_ip::LookupIpIntoIter, system_conf, TokioAsyncResolver};
use std::io;
use std::net::SocketAddr;
use std::sync::Arc;
use super::{Addrs, Resolve, Resolving};
/// Wrapper around an `AsyncResolver`, which implements the `Resolve` trait.
#[derive(Debug, Default, Clone)]
pub(crate) struct TrustDnsResolver {
/// Since we might not have been called in the context of a
/// Tokio Runtime in initialization, so we must delay the actual
/// construction of the resolver.
state: Arc<OnceCell<TokioAsyncResolver>>,
}
struct SocketAddrs {
iter: LookupIpIntoIter,
}
impl Resolve for TrustDnsResolver {
fn resolve(&self, name: Name) -> Resolving {
let resolver = self.clone();
Box::pin(async move {
let resolver = resolver.state.get_or_try_init(new_resolver)?;
let lookup = resolver.lookup_ip(name.as_str()).await?;
let addrs: Addrs = Box::new(SocketAddrs {
iter: lookup.into_iter(),
});
Ok(addrs)
})
}
}
impl Iterator for SocketAddrs {
type Item = SocketAddr;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|ip_addr| SocketAddr::new(ip_addr, 0))
}
}
/// Create a new resolver with the default configuration,
/// which reads from `/etc/resolve.conf`.
fn new_resolver() -> io::Result<TokioAsyncResolver> {
let (config, opts) = system_conf::read_system_conf().map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!("error reading DNS system conf: {}", e),
)
})?;
Ok(TokioAsyncResolver::tokio(config, opts))
}