1use std::{
2 net::ToSocketAddrs,
3 task::{Context, Poll},
4 vec::IntoIter,
5};
6
7use hyper::{client::connect::dns::Name, service::Service};
8use ipnet::{Ipv4Net, Ipv6Net};
9use trust_dns_resolver::{
10 config::{ResolverConfig, ResolverOpts},
11 TokioAsyncResolver,
12};
13
14use crate::_prelude::*;
15
16pub trait Resolver: Send + Sync + Debug + 'static {
17 fn resolve(&self, host: &str) -> PinnedFut<Result<IntoIter<SocketAddr>, io::Error>>;
18}
19
20#[derive(Clone, Debug)]
21pub struct AsyncStaticResolver {
22 addrs: Vec<SocketAddr>,
23}
24
25#[derive(Clone, Debug)]
26pub struct AsyncTrustDnsResolver {
27 resolver: Arc<TokioAsyncResolver>,
28 net_v4_blacklist: Arc<Vec<Ipv4Net>>,
29 net_v6_blacklist: Arc<Vec<Ipv6Net>>,
30}
31
32impl AsyncTrustDnsResolver {
33 pub fn new(config: ResolverConfig, options: ResolverOpts) -> Result<Self, io::Error> {
34 let resolver = Arc::new(TokioAsyncResolver::tokio(config, options)?);
35
36 Ok(Self { resolver, net_v4_blacklist: Arc::new(vec![]), net_v6_blacklist: Arc::new(vec![]) })
37 }
38
39 pub fn with_net_v4_blacklist(&mut self, blacklist: Vec<Ipv4Net>) {
40 self.net_v4_blacklist = Arc::new(blacklist);
41 }
42
43 pub fn with_net_v6_blacklist(&mut self, blacklist: Vec<Ipv6Net>) {
44 self.net_v6_blacklist = Arc::new(blacklist);
45 }
46}
47
48impl AsyncStaticResolver {
49 pub fn new(addrs: Vec<SocketAddr>) -> Self {
50 Self { addrs }
51 }
52}
53
54impl Resolver for AsyncTrustDnsResolver {
55 fn resolve(&self, name: &str) -> PinnedFut<Result<IntoIter<SocketAddr>, io::Error>> {
56 let resolver = self.clone();
57
58 let name = name.to_string();
59 Box::pin(async move {
60 let r = resolver
61 .resolver
62 .lookup_ip(name.as_str())
63 .await?
64 .iter()
65 .map(|addr| (addr, 0_u16).to_socket_addrs())
66 .try_fold(Vec::new(), |mut acc, s_addr| {
67 acc.extend(s_addr?);
68 Ok::<_, io::Error>(acc)
69 })?
70 .into_iter();
71
72 let mut err = None;
73 let mut out_addrs: Vec<SocketAddr> = vec![];
74 for addr in r.into_iter() {
75 match addr {
76 SocketAddr::V4(addr) => {
77 for blacklisted_net in resolver.net_v4_blacklist.iter() {
78 if blacklisted_net.contains(addr.ip()) {
79 err = Some(io::Error::new(
80 io::ErrorKind::Interrupted,
81 format!("resolved IPv4 {} is blacklisted", addr.ip().to_string().as_str()),
82 ));
83 continue
84 }
85 }
86 }
87 SocketAddr::V6(addr) => {
88 for blacklisted_net in resolver.net_v6_blacklist.iter() {
89 if blacklisted_net.contains(addr.ip()) {
90 err = Some(io::Error::new(
91 io::ErrorKind::Interrupted,
92 format!("resolved IPv6 {} is blacklisted", addr.ip().to_string().as_str()),
93 ));
94 continue
95 }
96 }
97 }
98 }
99 out_addrs.push(addr);
100 }
101
102 if out_addrs.is_empty() {
103 if let Some(err) = err {
104 return Err(err)
105 }
106 }
107
108 Ok(out_addrs.into_iter())
109 })
110 }
111}
112
113impl Resolver for AsyncStaticResolver {
114 fn resolve(&self, _name: &str) -> PinnedFut<Result<IntoIter<SocketAddr>, io::Error>> {
115 let resolver = self.clone();
116
117 Box::pin(async move { Ok(resolver.addrs.into_iter()) })
118 }
119}
120
121#[derive(Clone)]
122pub(crate) struct Adaptor {
123 resolver: Arc<Box<dyn Resolver>>,
124}
125
126impl Adaptor {
127 pub fn new(resolver: Arc<Box<dyn Resolver>>) -> Self {
128 Self { resolver }
129 }
130}
131
132impl Service<Name> for Adaptor {
133 type Error = io::Error;
134 type Future = PinnedFut<Result<Self::Response, Self::Error>>;
135 type Response = std::vec::IntoIter<SocketAddr>;
136
137 fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
138 Poll::Ready(Ok(()))
139 }
140
141 fn call(&mut self, name: Name) -> Self::Future {
142 let adaptor = self.clone();
143 Box::pin(async move { adaptor.resolver.resolve(name.as_str()).await })
144 }
145}
146
147lazy_static! {
148 pub static ref RESERVED_V4_SUBNETS: Vec<Ipv4Net> = {
149 vec![
150 "0.0.0.0/8",
152 "10.0.0.0/8",
153 "100.64.0.0/10",
154 "127.0.0.0/8",
155 "169.254.0.0/16",
156 "172.16.0.0/12",
157 "192.0.0.0/24",
158 "192.0.2.0/24",
159 "192.88.99.0/24",
160 "192.168.0.0/16",
161 "198.18.0.0/15",
162 "198.51.100.0/24",
163 "203.0.113.0/24",
164 "224.0.0.0/4",
165 "233.252.0.0/24",
166 "240.0.0.0/4",
167 "255.255.255.255/32",
168 ].iter().map(|net|net.parse().unwrap()).collect::<Vec<_>>()
169 };
170
171 pub static ref RESERVED_V6_SUBNETS: Vec<Ipv6Net> = {
172 vec![
173 "::1/128",
175 "::/128",
176 "::ffff:0:0/96",
177 "64:ff9b::/96",
178 "64:ff9b:1::/48",
179 "100::/64",
180 "2001::/23",
181 "2001::/32",
182 "2001:1::1/128",
183 "2001:1::2/128",
184 "2001:2::/48",
185 "2001:3::/32",
186 "2001:4:112::/48",
187 "2001:10::/28",
188 "2001:20::/28",
189 "2001:db8::/32",
190 "2002::/16",
191 "2620:4f:8000::/48",
192 "fc00::/7",
193 "fe80::/10",
194 ].iter().map(|net|net.parse().unwrap()).collect::<Vec<_>>()
195 };
196}