/rust/registry/src/index.crates.io-6f17d22bba15001f/hickory-resolver-0.24.2/src/config.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com> |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or |
4 | | // https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or |
5 | | // https://opensource.org/licenses/MIT>, at your option. This file may not be |
6 | | // copied, modified, or distributed except according to those terms. |
7 | | |
8 | | //! Configuration for a resolver |
9 | | #![allow(clippy::use_self)] |
10 | | |
11 | | use std::fmt; |
12 | | use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; |
13 | | use std::ops::{Deref, DerefMut}; |
14 | | use std::time::Duration; |
15 | | |
16 | | #[cfg(feature = "dns-over-rustls")] |
17 | | use std::sync::Arc; |
18 | | |
19 | | use proto::rr::Name; |
20 | | #[cfg(feature = "dns-over-rustls")] |
21 | | use rustls::ClientConfig; |
22 | | |
23 | | #[cfg(all(feature = "serde-config", feature = "dns-over-rustls"))] |
24 | | use serde::{ |
25 | | de::{Deserialize as DeserializeT, Deserializer}, |
26 | | ser::{Serialize as SerializeT, Serializer}, |
27 | | }; |
28 | | |
29 | | /// Configuration for the upstream nameservers to use for resolution |
30 | | #[derive(Clone, Debug, PartialEq, Eq)] |
31 | | #[cfg_attr(feature = "serde-config", derive(Serialize, Deserialize))] |
32 | | pub struct ResolverConfig { |
33 | | // base search domain |
34 | | #[cfg_attr(feature = "serde-config", serde(default))] |
35 | | domain: Option<Name>, |
36 | | // search domains |
37 | | #[cfg_attr(feature = "serde-config", serde(default))] |
38 | | search: Vec<Name>, |
39 | | // nameservers to use for resolution. |
40 | | name_servers: NameServerConfigGroup, |
41 | | } |
42 | | |
43 | | impl ResolverConfig { |
44 | | /// Creates a new empty configuration |
45 | 0 | pub fn new() -> Self { |
46 | 0 | Self { |
47 | 0 | // TODO: this should get the hostname and use the basename as the default |
48 | 0 | domain: None, |
49 | 0 | search: vec![], |
50 | 0 | name_servers: NameServerConfigGroup::new(), |
51 | 0 | } |
52 | 0 | } Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::new Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::new |
53 | | |
54 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). |
55 | | /// |
56 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
57 | | /// |
58 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
59 | 0 | pub fn google() -> Self { |
60 | 0 | Self { |
61 | 0 | // TODO: this should get the hostname and use the basename as the default |
62 | 0 | domain: None, |
63 | 0 | search: vec![], |
64 | 0 | name_servers: NameServerConfigGroup::google(), |
65 | 0 | } |
66 | 0 | } Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::google Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::google |
67 | | |
68 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). This limits the registered connections to just TLS lookups |
69 | | /// |
70 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
71 | | /// |
72 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
73 | | #[cfg(feature = "dns-over-tls")] |
74 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-tls")))] |
75 | | pub fn google_tls() -> Self { |
76 | | Self { |
77 | | // TODO: this should get the hostname and use the basename as the default |
78 | | domain: None, |
79 | | search: vec![], |
80 | | name_servers: NameServerConfigGroup::google_tls(), |
81 | | } |
82 | | } |
83 | | |
84 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). This limits the registered connections to just HTTPS lookups |
85 | | /// |
86 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
87 | | /// |
88 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
89 | | #[cfg(feature = "dns-over-https")] |
90 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))] |
91 | | pub fn google_https() -> Self { |
92 | | Self { |
93 | | // TODO: this should get the hostname and use the basename as the default |
94 | | domain: None, |
95 | | search: vec![], |
96 | | name_servers: NameServerConfigGroup::google_https(), |
97 | | } |
98 | | } |
99 | | |
100 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). This limits the registered connections to just HTTP/3 lookups |
101 | | /// |
102 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
103 | | /// |
104 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
105 | | #[cfg(feature = "dns-over-h3")] |
106 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-h3")))] |
107 | | pub fn google_h3() -> Self { |
108 | | Self { |
109 | | // TODO: this should get the hostname and use the basename as the default |
110 | | domain: None, |
111 | | search: vec![], |
112 | | name_servers: NameServerConfigGroup::google_h3(), |
113 | | } |
114 | | } |
115 | | |
116 | | /// Creates a default configuration, using `1.1.1.1`, `1.0.0.1` and `2606:4700:4700::1111`, `2606:4700:4700::1001` (thank you, Cloudflare). |
117 | | /// |
118 | | /// Please see: <https://www.cloudflare.com/dns/> |
119 | | /// |
120 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
121 | 0 | pub fn cloudflare() -> Self { |
122 | 0 | Self { |
123 | 0 | // TODO: this should get the hostname and use the basename as the default |
124 | 0 | domain: None, |
125 | 0 | search: vec![], |
126 | 0 | name_servers: NameServerConfigGroup::cloudflare(), |
127 | 0 | } |
128 | 0 | } Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::cloudflare Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::cloudflare |
129 | | |
130 | | /// Creates a configuration, using `1.1.1.1`, `1.0.0.1` and `2606:4700:4700::1111`, `2606:4700:4700::1001` (thank you, Cloudflare). This limits the registered connections to just TLS lookups |
131 | | /// |
132 | | /// Please see: <https://www.cloudflare.com/dns/> |
133 | | /// |
134 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
135 | | #[cfg(feature = "dns-over-tls")] |
136 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-tls")))] |
137 | | pub fn cloudflare_tls() -> Self { |
138 | | Self { |
139 | | // TODO: this should get the hostname and use the basename as the default |
140 | | domain: None, |
141 | | search: vec![], |
142 | | name_servers: NameServerConfigGroup::cloudflare_tls(), |
143 | | } |
144 | | } |
145 | | |
146 | | /// Creates a configuration, using `1.1.1.1`, `1.0.0.1` and `2606:4700:4700::1111`, `2606:4700:4700::1001` (thank you, Cloudflare). This limits the registered connections to just HTTPS lookups |
147 | | /// |
148 | | /// Please see: <https://www.cloudflare.com/dns/> |
149 | | /// |
150 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
151 | | #[cfg(feature = "dns-over-https")] |
152 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))] |
153 | | pub fn cloudflare_https() -> Self { |
154 | | Self { |
155 | | // TODO: this should get the hostname and use the basename as the default |
156 | | domain: None, |
157 | | search: vec![], |
158 | | name_servers: NameServerConfigGroup::cloudflare_https(), |
159 | | } |
160 | | } |
161 | | |
162 | | /// Creates a configuration, using `9.9.9.9`, `149.112.112.112` and `2620:fe::fe`, `2620:fe::fe:9`, the "secure" variants of the quad9 settings (thank you, Quad9). |
163 | | /// |
164 | | /// Please see: <https://www.quad9.net/faq/> |
165 | | /// |
166 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
167 | 0 | pub fn quad9() -> Self { |
168 | 0 | Self { |
169 | 0 | // TODO: this should get the hostname and use the basename as the default |
170 | 0 | domain: None, |
171 | 0 | search: vec![], |
172 | 0 | name_servers: NameServerConfigGroup::quad9(), |
173 | 0 | } |
174 | 0 | } Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::quad9 Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::quad9 |
175 | | |
176 | | /// Creates a configuration, using `9.9.9.9`, `149.112.112.112` and `2620:fe::fe`, `2620:fe::fe:9`, the "secure" variants of the quad9 settings. This limits the registered connections to just TLS lookups |
177 | | /// |
178 | | /// Please see: <https://www.quad9.net/faq/> |
179 | | /// |
180 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
181 | | #[cfg(feature = "dns-over-tls")] |
182 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-tls")))] |
183 | | pub fn quad9_tls() -> Self { |
184 | | Self { |
185 | | // TODO: this should get the hostname and use the basename as the default |
186 | | domain: None, |
187 | | search: vec![], |
188 | | name_servers: NameServerConfigGroup::quad9_tls(), |
189 | | } |
190 | | } |
191 | | |
192 | | /// Creates a configuration, using `9.9.9.9`, `149.112.112.112` and `2620:fe::fe`, `2620:fe::fe:9`, the "secure" variants of the quad9 settings. This limits the registered connections to just HTTPS lookups |
193 | | /// |
194 | | /// Please see: <https://www.quad9.net/faq/> |
195 | | /// |
196 | | /// NameServerConfigGroups can be combined to use a set of different providers, see `NameServerConfigGroup` and `ResolverConfig::from_parts` |
197 | | #[cfg(feature = "dns-over-https")] |
198 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))] |
199 | | pub fn quad9_https() -> Self { |
200 | | Self { |
201 | | // TODO: this should get the hostname and use the basename as the default |
202 | | domain: None, |
203 | | search: vec![], |
204 | | name_servers: NameServerConfigGroup::quad9_https(), |
205 | | } |
206 | | } |
207 | | |
208 | | /// Create a ResolverConfig with all parts specified |
209 | | /// |
210 | | /// # Arguments |
211 | | /// |
212 | | /// * `domain` - domain of the entity querying results. If the `Name` being looked up is not an FQDN, then this is the first part appended to attempt a lookup. `ndots` in the `ResolverOption` does take precedence over this. |
213 | | /// * `search` - additional search domains that are attempted if the `Name` is not found in `domain`, defaults to `vec![]` |
214 | | /// * `name_servers` - set of name servers to use for lookups, defaults are Google: `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` |
215 | 3.68k | pub fn from_parts<G: Into<NameServerConfigGroup>>( |
216 | 3.68k | domain: Option<Name>, |
217 | 3.68k | search: Vec<Name>, |
218 | 3.68k | name_servers: G, |
219 | 3.68k | ) -> Self { |
220 | 3.68k | Self { |
221 | 3.68k | domain, |
222 | 3.68k | search, |
223 | 3.68k | name_servers: name_servers.into(), |
224 | 3.68k | } |
225 | 3.68k | } <hickory_resolver::config::ResolverConfig>::from_parts::<alloc::vec::Vec<hickory_resolver::config::NameServerConfig>> Line | Count | Source | 215 | 3.68k | pub fn from_parts<G: Into<NameServerConfigGroup>>( | 216 | 3.68k | domain: Option<Name>, | 217 | 3.68k | search: Vec<Name>, | 218 | 3.68k | name_servers: G, | 219 | 3.68k | ) -> Self { | 220 | 3.68k | Self { | 221 | 3.68k | domain, | 222 | 3.68k | search, | 223 | 3.68k | name_servers: name_servers.into(), | 224 | 3.68k | } | 225 | 3.68k | } |
Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::from_parts::<alloc::vec::Vec<hickory_resolver::config::NameServerConfig>> |
226 | | |
227 | | /// Returns the local domain |
228 | | /// |
229 | | /// By default any names will be appended to all non-fully-qualified-domain names, and searched for after any ndots rules |
230 | 2.83k | pub fn domain(&self) -> Option<&Name> { |
231 | 2.83k | self.domain.as_ref() |
232 | 2.83k | } <hickory_resolver::config::ResolverConfig>::domain Line | Count | Source | 230 | 2.83k | pub fn domain(&self) -> Option<&Name> { | 231 | 2.83k | self.domain.as_ref() | 232 | 2.83k | } |
Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::domain |
233 | | |
234 | | /// Set the domain of the entity querying results. |
235 | 0 | pub fn set_domain(&mut self, domain: Name) { |
236 | 0 | self.domain = Some(domain.clone()); |
237 | 0 | self.search = vec![domain]; |
238 | 0 | } Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::set_domain Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::set_domain |
239 | | |
240 | | /// Returns the search domains |
241 | | /// |
242 | | /// These will be queried after any local domain and then in the order of the set of search domains |
243 | 5.67k | pub fn search(&self) -> &[Name] { |
244 | 5.67k | &self.search |
245 | 5.67k | } <hickory_resolver::config::ResolverConfig>::search Line | Count | Source | 243 | 5.67k | pub fn search(&self) -> &[Name] { | 244 | 5.67k | &self.search | 245 | 5.67k | } |
Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::search |
246 | | |
247 | | /// Add a search domain |
248 | 0 | pub fn add_search(&mut self, search: Name) { |
249 | 0 | self.search.push(search) |
250 | 0 | } Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::add_search Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::add_search |
251 | | |
252 | | // TODO: consider allowing options per NameServer... like different timeouts? |
253 | | /// Add the configuration for a name server |
254 | 0 | pub fn add_name_server(&mut self, name_server: NameServerConfig) { |
255 | 0 | self.name_servers.push(name_server); |
256 | 0 | } Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::add_name_server Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::add_name_server |
257 | | |
258 | | /// Returns a reference to the name servers |
259 | 7.36k | pub fn name_servers(&self) -> &[NameServerConfig] { |
260 | 7.36k | &self.name_servers |
261 | 7.36k | } <hickory_resolver::config::ResolverConfig>::name_servers Line | Count | Source | 259 | 7.36k | pub fn name_servers(&self) -> &[NameServerConfig] { | 260 | 7.36k | &self.name_servers | 261 | 7.36k | } |
Unexecuted instantiation: <hickory_resolver::config::ResolverConfig>::name_servers |
262 | | |
263 | | /// return the associated TlsClientConfig |
264 | | #[cfg(feature = "dns-over-rustls")] |
265 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-rustls")))] |
266 | | pub fn client_config(&self) -> &Option<TlsClientConfig> { |
267 | | &self.name_servers.1 |
268 | | } |
269 | | |
270 | | /// adds the `rustls::ClientConf` for every configured NameServer |
271 | | /// of the Resolver. |
272 | | /// |
273 | | /// ``` |
274 | | /// use std::sync::Arc; |
275 | | /// |
276 | | /// use rustls::{ClientConfig, ProtocolVersion, RootCertStore, OwnedTrustAnchor}; |
277 | | /// use hickory_resolver::config::ResolverConfig; |
278 | | /// # #[cfg(feature = "webpki-roots")] |
279 | | /// use webpki_roots; |
280 | | /// |
281 | | /// let mut root_store = RootCertStore::empty(); |
282 | | /// # #[cfg(feature = "webpki-roots")] |
283 | | /// root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { |
284 | | /// OwnedTrustAnchor::from_subject_spki_name_constraints( |
285 | | /// ta.subject, |
286 | | /// ta.spki, |
287 | | /// ta.name_constraints, |
288 | | /// ) |
289 | | /// })); |
290 | | /// |
291 | | /// let mut client_config = ClientConfig::builder() |
292 | | /// .with_safe_default_cipher_suites() |
293 | | /// .with_safe_default_kx_groups() |
294 | | /// .with_protocol_versions(&[&rustls::version::TLS12]) |
295 | | /// .unwrap() |
296 | | /// .with_root_certificates(root_store) |
297 | | /// .with_no_client_auth(); |
298 | | /// |
299 | | /// let mut resolver_config = ResolverConfig::quad9_tls(); |
300 | | /// resolver_config.set_tls_client_config(Arc::new(client_config)); |
301 | | /// ``` |
302 | | #[cfg(feature = "dns-over-rustls")] |
303 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-rustls")))] |
304 | | pub fn set_tls_client_config(&mut self, client_config: Arc<ClientConfig>) { |
305 | | self.name_servers = self.name_servers.clone().with_client_config(client_config); |
306 | | } |
307 | | } |
308 | | |
309 | | impl Default for ResolverConfig { |
310 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). |
311 | | /// |
312 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
313 | 0 | fn default() -> Self { |
314 | 0 | Self::google() |
315 | 0 | } Unexecuted instantiation: <hickory_resolver::config::ResolverConfig as core::default::Default>::default Unexecuted instantiation: <hickory_resolver::config::ResolverConfig as core::default::Default>::default |
316 | | } |
317 | | |
318 | | /// The protocol on which a NameServer should be communicated with |
319 | | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
320 | | #[cfg_attr( |
321 | | feature = "serde-config", |
322 | | derive(Serialize, Deserialize), |
323 | | serde(rename_all = "lowercase") |
324 | | )] |
325 | | #[non_exhaustive] |
326 | | pub enum Protocol { |
327 | | /// UDP is the traditional DNS port, this is generally the correct choice |
328 | | Udp, |
329 | | /// TCP can be used for large queries, but not all NameServers support it |
330 | | Tcp, |
331 | | /// Tls for DNS over TLS |
332 | | #[cfg(feature = "dns-over-tls")] |
333 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-tls")))] |
334 | | Tls, |
335 | | /// Https for DNS over HTTPS |
336 | | #[cfg(feature = "dns-over-https")] |
337 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))] |
338 | | Https, |
339 | | /// QUIC for DNS over QUIC |
340 | | #[cfg(feature = "dns-over-quic")] |
341 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-quic")))] |
342 | | Quic, |
343 | | /// HTTP/3 for DNS over HTTP/3 |
344 | | #[cfg(feature = "dns-over-h3")] |
345 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-h3")))] |
346 | | H3, |
347 | | } |
348 | | |
349 | | impl fmt::Display for Protocol { |
350 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
351 | 0 | let protocol = match self { |
352 | 0 | Self::Udp => "udp", |
353 | 0 | Self::Tcp => "tcp", |
354 | | #[cfg(feature = "dns-over-tls")] |
355 | | Self::Tls => "tls", |
356 | | #[cfg(feature = "dns-over-https")] |
357 | | Self::Https => "https", |
358 | | #[cfg(feature = "dns-over-quic")] |
359 | | Self::Quic => "quic", |
360 | | #[cfg(feature = "dns-over-h3")] |
361 | | Self::H3 => "h3", |
362 | | }; |
363 | | |
364 | 0 | f.write_str(protocol) |
365 | 0 | } Unexecuted instantiation: <hickory_resolver::config::Protocol as core::fmt::Display>::fmt Unexecuted instantiation: <hickory_resolver::config::Protocol as core::fmt::Display>::fmt |
366 | | } |
367 | | |
368 | | impl Protocol { |
369 | | /// Returns true if this is a datagram oriented protocol, e.g. UDP |
370 | 14.7k | pub fn is_datagram(self) -> bool { |
371 | 14.7k | match self { |
372 | 7.36k | Self::Udp => true, |
373 | 7.36k | Self::Tcp => false, |
374 | | #[cfg(feature = "dns-over-tls")] |
375 | | Self::Tls => false, |
376 | | #[cfg(feature = "dns-over-https")] |
377 | | Self::Https => false, |
378 | | // TODO: if you squint, this is true... |
379 | | #[cfg(feature = "dns-over-quic")] |
380 | | Self::Quic => true, |
381 | | #[cfg(feature = "dns-over-h3")] |
382 | | Self::H3 => true, |
383 | | } |
384 | 14.7k | } <hickory_resolver::config::Protocol>::is_datagram Line | Count | Source | 370 | 14.7k | pub fn is_datagram(self) -> bool { | 371 | 14.7k | match self { | 372 | 7.36k | Self::Udp => true, | 373 | 7.36k | Self::Tcp => false, | 374 | | #[cfg(feature = "dns-over-tls")] | 375 | | Self::Tls => false, | 376 | | #[cfg(feature = "dns-over-https")] | 377 | | Self::Https => false, | 378 | | // TODO: if you squint, this is true... | 379 | | #[cfg(feature = "dns-over-quic")] | 380 | | Self::Quic => true, | 381 | | #[cfg(feature = "dns-over-h3")] | 382 | | Self::H3 => true, | 383 | | } | 384 | 14.7k | } |
Unexecuted instantiation: <hickory_resolver::config::Protocol>::is_datagram |
385 | | |
386 | | /// Returns true if this is a stream oriented protocol, e.g. TCP |
387 | 7.36k | pub fn is_stream(self) -> bool { |
388 | 7.36k | !self.is_datagram() |
389 | 7.36k | } <hickory_resolver::config::Protocol>::is_stream Line | Count | Source | 387 | 7.36k | pub fn is_stream(self) -> bool { | 388 | 7.36k | !self.is_datagram() | 389 | 7.36k | } |
Unexecuted instantiation: <hickory_resolver::config::Protocol>::is_stream |
390 | | |
391 | | /// Is this an encrypted protocol, i.e. TLS or HTTPS |
392 | 0 | pub fn is_encrypted(self) -> bool { |
393 | 0 | match self { |
394 | 0 | Self::Udp => false, |
395 | 0 | Self::Tcp => false, |
396 | | #[cfg(feature = "dns-over-tls")] |
397 | | Self::Tls => true, |
398 | | #[cfg(feature = "dns-over-https")] |
399 | | Self::Https => true, |
400 | | #[cfg(feature = "dns-over-quic")] |
401 | | Self::Quic => true, |
402 | | #[cfg(feature = "dns-over-h3")] |
403 | | Self::H3 => true, |
404 | | } |
405 | 0 | } Unexecuted instantiation: <hickory_resolver::config::Protocol>::is_encrypted Unexecuted instantiation: <hickory_resolver::config::Protocol>::is_encrypted |
406 | | } |
407 | | |
408 | | impl Default for Protocol { |
409 | | /// Default protocol should be UDP, which is supported by all DNS servers |
410 | 0 | fn default() -> Self { |
411 | 0 | Self::Udp |
412 | 0 | } Unexecuted instantiation: <hickory_resolver::config::Protocol as core::default::Default>::default Unexecuted instantiation: <hickory_resolver::config::Protocol as core::default::Default>::default |
413 | | } |
414 | | |
415 | | /// a compatibility wrapper around rustls |
416 | | /// ClientConfig |
417 | | #[cfg(feature = "dns-over-rustls")] |
418 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-rustls")))] |
419 | | #[derive(Clone)] |
420 | | pub struct TlsClientConfig(pub Arc<ClientConfig>); |
421 | | |
422 | | #[cfg(feature = "dns-over-rustls")] |
423 | | impl std::cmp::PartialEq for TlsClientConfig { |
424 | | fn eq(&self, other: &Self) -> bool { |
425 | | Arc::ptr_eq(&self.0, &other.0) |
426 | | } |
427 | | } |
428 | | |
429 | | #[cfg(feature = "dns-over-rustls")] |
430 | | impl std::cmp::Eq for TlsClientConfig {} |
431 | | |
432 | | #[cfg(feature = "dns-over-rustls")] |
433 | | impl std::fmt::Debug for TlsClientConfig { |
434 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
435 | | write!(f, "rustls client config") |
436 | | } |
437 | | } |
438 | | |
439 | | /// Configuration for the NameServer |
440 | | #[derive(Clone, Debug, Eq, PartialEq)] |
441 | | #[cfg_attr(feature = "serde-config", derive(Serialize, Deserialize))] |
442 | | pub struct NameServerConfig { |
443 | | /// The address which the DNS NameServer is registered at. |
444 | | pub socket_addr: SocketAddr, |
445 | | /// The protocol to use when communicating with the NameServer. |
446 | | #[cfg_attr(feature = "serde-config", serde(default))] |
447 | | pub protocol: Protocol, |
448 | | /// SPKI name, only relevant for TLS connections |
449 | | #[cfg_attr(feature = "serde-config", serde(default))] |
450 | | pub tls_dns_name: Option<String>, |
451 | | /// Whether to trust `NXDOMAIN` responses from upstream nameservers. |
452 | | /// |
453 | | /// When this is `true`, and an empty `NXDOMAIN` response or `NOERROR` |
454 | | /// with an empty answers set is received, the |
455 | | /// query will not be retried against other configured name servers if |
456 | | /// the response has the Authoritative flag set. |
457 | | /// |
458 | | /// (On a response with any other error |
459 | | /// response code, the query will still be retried regardless of this |
460 | | /// configuration setting.) |
461 | | /// |
462 | | /// Defaults to false. |
463 | | #[cfg_attr(feature = "serde-config", serde(default))] |
464 | | pub trust_negative_responses: bool, |
465 | | #[cfg(feature = "dns-over-rustls")] |
466 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-rustls")))] |
467 | | #[cfg_attr(feature = "serde-config", serde(skip))] |
468 | | /// Optional configuration for the TLS client. |
469 | | /// |
470 | | /// The correct ALPN for the corresponding protocol is automatically |
471 | | /// inserted if none was specificed. |
472 | | pub tls_config: Option<TlsClientConfig>, |
473 | | /// The client address (IP and port) to use for connecting to the server. |
474 | | pub bind_addr: Option<SocketAddr>, |
475 | | } |
476 | | |
477 | | impl NameServerConfig { |
478 | | /// Constructs a Nameserver configuration with some basic defaults |
479 | 0 | pub fn new(socket_addr: SocketAddr, protocol: Protocol) -> Self { |
480 | 0 | Self { |
481 | 0 | socket_addr, |
482 | 0 | protocol, |
483 | 0 | trust_negative_responses: true, |
484 | 0 | tls_dns_name: None, |
485 | 0 | #[cfg(feature = "dns-over-rustls")] |
486 | 0 | tls_config: None, |
487 | 0 | bind_addr: None, |
488 | 0 | } |
489 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfig>::new Unexecuted instantiation: <hickory_resolver::config::NameServerConfig>::new |
490 | | } |
491 | | |
492 | | impl fmt::Display for NameServerConfig { |
493 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
494 | 0 | write!(f, "{}:", self.protocol)?; |
495 | | |
496 | 0 | if let Some(ref tls_dns_name) = self.tls_dns_name { |
497 | 0 | write!(f, "{tls_dns_name}@")?; |
498 | 0 | } |
499 | | |
500 | 0 | write!(f, "{}", self.socket_addr) |
501 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfig as core::fmt::Display>::fmt Unexecuted instantiation: <hickory_resolver::config::NameServerConfig as core::fmt::Display>::fmt |
502 | | } |
503 | | |
504 | | /// A set of name_servers to associate with a [`ResolverConfig`]. |
505 | | #[derive(Clone, Debug, Eq, PartialEq)] |
506 | | #[cfg_attr( |
507 | | all(feature = "serde-config", not(feature = "dns-over-rustls")), |
508 | | derive(Serialize, Deserialize) |
509 | | )] |
510 | | pub struct NameServerConfigGroup( |
511 | | Vec<NameServerConfig>, |
512 | | #[cfg(feature = "dns-over-rustls")] Option<TlsClientConfig>, |
513 | | ); |
514 | | |
515 | | #[cfg(all(feature = "serde-config", feature = "dns-over-rustls"))] |
516 | | impl SerializeT for NameServerConfigGroup { |
517 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
518 | | where |
519 | | S: Serializer, |
520 | | { |
521 | | self.0.serialize(serializer) |
522 | | } |
523 | | } |
524 | | |
525 | | #[cfg(all(feature = "serde-config", feature = "dns-over-rustls"))] |
526 | | impl<'de> DeserializeT<'de> for NameServerConfigGroup { |
527 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
528 | | where |
529 | | D: Deserializer<'de>, |
530 | | { |
531 | | Vec::deserialize(deserializer).map(|nameservers| Self(nameservers, None)) |
532 | | } |
533 | | } |
534 | | |
535 | | impl NameServerConfigGroup { |
536 | | /// Creates a new `NameServerConfigGroup` with a default size of 2 |
537 | 0 | pub fn new() -> Self { |
538 | 0 | // this might be a nice opportunity for SmallVec |
539 | 0 | // most name_server configs will be 2. |
540 | 0 | Self::with_capacity(2) |
541 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::new Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::new |
542 | | |
543 | | /// Creates a new `NameServiceConfigGroup` with the specified capacity |
544 | 0 | pub fn with_capacity(capacity: usize) -> Self { |
545 | 0 | Self( |
546 | 0 | Vec::with_capacity(capacity), |
547 | 0 | #[cfg(feature = "dns-over-rustls")] |
548 | 0 | None, |
549 | 0 | ) |
550 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::with_capacity Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::with_capacity |
551 | | |
552 | | /// Returns the inner vec of configs |
553 | 0 | pub fn into_inner(self) -> Vec<NameServerConfig> { |
554 | 0 | self.0 |
555 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::into_inner Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::into_inner |
556 | | |
557 | | /// Configure a NameServer address and port |
558 | | /// |
559 | | /// This will create UDP and TCP connections, using the same port. |
560 | 0 | pub fn from_ips_clear(ips: &[IpAddr], port: u16, trust_negative_responses: bool) -> Self { |
561 | 0 | let mut name_servers = Self::with_capacity(ips.len()); |
562 | | |
563 | 0 | for ip in ips { |
564 | 0 | let udp = NameServerConfig { |
565 | 0 | socket_addr: SocketAddr::new(*ip, port), |
566 | 0 | protocol: Protocol::Udp, |
567 | 0 | tls_dns_name: None, |
568 | 0 | trust_negative_responses, |
569 | 0 | #[cfg(feature = "dns-over-rustls")] |
570 | 0 | tls_config: None, |
571 | 0 | bind_addr: None, |
572 | 0 | }; |
573 | 0 | let tcp = NameServerConfig { |
574 | 0 | socket_addr: SocketAddr::new(*ip, port), |
575 | 0 | protocol: Protocol::Tcp, |
576 | 0 | tls_dns_name: None, |
577 | 0 | trust_negative_responses, |
578 | 0 | #[cfg(feature = "dns-over-rustls")] |
579 | 0 | tls_config: None, |
580 | 0 | bind_addr: None, |
581 | 0 | }; |
582 | 0 |
|
583 | 0 | name_servers.push(udp); |
584 | 0 | name_servers.push(tcp); |
585 | 0 | } |
586 | | |
587 | 0 | name_servers |
588 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::from_ips_clear Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::from_ips_clear |
589 | | |
590 | | #[cfg(any(feature = "dns-over-tls", feature = "dns-over-https"))] |
591 | | fn from_ips_encrypted( |
592 | | ips: &[IpAddr], |
593 | | port: u16, |
594 | | tls_dns_name: String, |
595 | | protocol: Protocol, |
596 | | trust_negative_responses: bool, |
597 | | ) -> Self { |
598 | | assert!(protocol.is_encrypted()); |
599 | | |
600 | | let mut name_servers = Self::with_capacity(ips.len()); |
601 | | |
602 | | for ip in ips { |
603 | | let config = NameServerConfig { |
604 | | socket_addr: SocketAddr::new(*ip, port), |
605 | | protocol, |
606 | | tls_dns_name: Some(tls_dns_name.clone()), |
607 | | trust_negative_responses, |
608 | | #[cfg(feature = "dns-over-rustls")] |
609 | | tls_config: None, |
610 | | bind_addr: None, |
611 | | }; |
612 | | |
613 | | name_servers.push(config); |
614 | | } |
615 | | |
616 | | name_servers |
617 | | } |
618 | | |
619 | | /// Configure a NameServer address and port for DNS-over-TLS |
620 | | /// |
621 | | /// This will create a TLS connections. |
622 | | #[cfg(feature = "dns-over-tls")] |
623 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-tls")))] |
624 | | pub fn from_ips_tls( |
625 | | ips: &[IpAddr], |
626 | | port: u16, |
627 | | tls_dns_name: String, |
628 | | trust_negative_responses: bool, |
629 | | ) -> Self { |
630 | | Self::from_ips_encrypted( |
631 | | ips, |
632 | | port, |
633 | | tls_dns_name, |
634 | | Protocol::Tls, |
635 | | trust_negative_responses, |
636 | | ) |
637 | | } |
638 | | |
639 | | /// Configure a NameServer address and port for DNS-over-HTTPS |
640 | | /// |
641 | | /// This will create a HTTPS connections. |
642 | | #[cfg(feature = "dns-over-https")] |
643 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))] |
644 | | pub fn from_ips_https( |
645 | | ips: &[IpAddr], |
646 | | port: u16, |
647 | | tls_dns_name: String, |
648 | | trust_negative_responses: bool, |
649 | | ) -> Self { |
650 | | Self::from_ips_encrypted( |
651 | | ips, |
652 | | port, |
653 | | tls_dns_name, |
654 | | Protocol::Https, |
655 | | trust_negative_responses, |
656 | | ) |
657 | | } |
658 | | |
659 | | /// Configure a NameServer address and port for DNS-over-QUIC |
660 | | /// |
661 | | /// This will create a QUIC connections. |
662 | | #[cfg(feature = "dns-over-quic")] |
663 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-quic")))] |
664 | | pub fn from_ips_quic( |
665 | | ips: &[IpAddr], |
666 | | port: u16, |
667 | | tls_dns_name: String, |
668 | | trust_negative_responses: bool, |
669 | | ) -> Self { |
670 | | Self::from_ips_encrypted( |
671 | | ips, |
672 | | port, |
673 | | tls_dns_name, |
674 | | Protocol::Quic, |
675 | | trust_negative_responses, |
676 | | ) |
677 | | } |
678 | | |
679 | | /// Configure a NameServer address and port for DNS-over-HTTP/3 |
680 | | /// |
681 | | /// This will create a HTTP/3 connection. |
682 | | #[cfg(feature = "dns-over-h3")] |
683 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-h3")))] |
684 | | pub fn from_ips_h3( |
685 | | ips: &[IpAddr], |
686 | | port: u16, |
687 | | tls_dns_name: String, |
688 | | trust_negative_responses: bool, |
689 | | ) -> Self { |
690 | | Self::from_ips_encrypted( |
691 | | ips, |
692 | | port, |
693 | | tls_dns_name, |
694 | | Protocol::H3, |
695 | | trust_negative_responses, |
696 | | ) |
697 | | } |
698 | | |
699 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). |
700 | | /// |
701 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
702 | 0 | pub fn google() -> Self { |
703 | 0 | Self::from_ips_clear(GOOGLE_IPS, 53, true) |
704 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::google Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::google |
705 | | |
706 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). This limits the registered connections to just TLS lookups |
707 | | /// |
708 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
709 | | #[cfg(feature = "dns-over-tls")] |
710 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-tls")))] |
711 | | pub fn google_tls() -> Self { |
712 | | Self::from_ips_tls(GOOGLE_IPS, 853, "dns.google".to_string(), true) |
713 | | } |
714 | | |
715 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). This limits the registered connections to just HTTPS lookups |
716 | | /// |
717 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
718 | | #[cfg(feature = "dns-over-https")] |
719 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))] |
720 | | pub fn google_https() -> Self { |
721 | | Self::from_ips_https(GOOGLE_IPS, 443, "dns.google".to_string(), true) |
722 | | } |
723 | | |
724 | | /// Creates a default configuration, using `8.8.8.8`, `8.8.4.4` and `2001:4860:4860::8888`, `2001:4860:4860::8844` (thank you, Google). This limits the registered connections to just HTTP/3 lookups |
725 | | /// |
726 | | /// Please see Google's [privacy statement](https://developers.google.com/speed/public-dns/privacy) for important information about what they track, many ISP's track similar information in DNS. To use the system configuration see: `Resolver::from_system_conf` and `AsyncResolver::from_system_conf` |
727 | | #[cfg(feature = "dns-over-h3")] |
728 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-h3")))] |
729 | | pub fn google_h3() -> Self { |
730 | | Self::from_ips_h3(GOOGLE_IPS, 443, "dns.google".to_string(), true) |
731 | | } |
732 | | |
733 | | /// Creates a default configuration, using `1.1.1.1`, `1.0.0.1` and `2606:4700:4700::1111`, `2606:4700:4700::1001` (thank you, Cloudflare). |
734 | | /// |
735 | | /// Please see: <https://www.cloudflare.com/dns/> |
736 | 0 | pub fn cloudflare() -> Self { |
737 | 0 | Self::from_ips_clear(CLOUDFLARE_IPS, 53, true) |
738 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::cloudflare Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::cloudflare |
739 | | |
740 | | /// Creates a configuration, using `1.1.1.1`, `1.0.0.1` and `2606:4700:4700::1111`, `2606:4700:4700::1001` (thank you, Cloudflare). This limits the registered connections to just TLS lookups |
741 | | /// |
742 | | /// Please see: <https://www.cloudflare.com/dns/> |
743 | | #[cfg(feature = "dns-over-tls")] |
744 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-tls")))] |
745 | | pub fn cloudflare_tls() -> Self { |
746 | | Self::from_ips_tls(CLOUDFLARE_IPS, 853, "cloudflare-dns.com".to_string(), true) |
747 | | } |
748 | | |
749 | | /// Creates a configuration, using `1.1.1.1`, `1.0.0.1` and `2606:4700:4700::1111`, `2606:4700:4700::1001` (thank you, Cloudflare). This limits the registered connections to just HTTPS lookups |
750 | | /// |
751 | | /// Please see: <https://www.cloudflare.com/dns/> |
752 | | #[cfg(feature = "dns-over-https")] |
753 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))] |
754 | | pub fn cloudflare_https() -> Self { |
755 | | Self::from_ips_https(CLOUDFLARE_IPS, 443, "cloudflare-dns.com".to_string(), true) |
756 | | } |
757 | | |
758 | | /// Creates a configuration, using `9.9.9.9`, `149.112.112.112` and `2620:fe::fe`, `2620:fe::fe:9`, the "secure" variants of the quad9 settings (thank you, Quad9). |
759 | | /// |
760 | | /// Please see: <https://www.quad9.net/faq/> |
761 | 0 | pub fn quad9() -> Self { |
762 | 0 | Self::from_ips_clear(QUAD9_IPS, 53, true) |
763 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::quad9 Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::quad9 |
764 | | |
765 | | /// Creates a configuration, using `9.9.9.9`, `149.112.112.112` and `2620:fe::fe`, `2620:fe::fe:9`, the "secure" variants of the quad9 settings. This limits the registered connections to just TLS lookups |
766 | | /// |
767 | | /// Please see: <https://www.quad9.net/faq/> |
768 | | #[cfg(feature = "dns-over-tls")] |
769 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-tls")))] |
770 | | pub fn quad9_tls() -> Self { |
771 | | Self::from_ips_tls(QUAD9_IPS, 853, "dns.quad9.net".to_string(), true) |
772 | | } |
773 | | |
774 | | /// Creates a configuration, using `9.9.9.9`, `149.112.112.112` and `2620:fe::fe`, `2620:fe::fe:9`, the "secure" variants of the quad9 settings. This limits the registered connections to just HTTPS lookups |
775 | | /// |
776 | | /// Please see: <https://www.quad9.net/faq/> |
777 | | #[cfg(feature = "dns-over-https")] |
778 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))] |
779 | | pub fn quad9_https() -> Self { |
780 | | Self::from_ips_https(QUAD9_IPS, 443, "dns.quad9.net".to_string(), true) |
781 | | } |
782 | | |
783 | | /// Merges this set of [`NameServerConfig`]s with the other |
784 | | /// |
785 | | /// ``` |
786 | | /// use std::net::{SocketAddr, Ipv4Addr}; |
787 | | /// use hickory_resolver::config::NameServerConfigGroup; |
788 | | /// |
789 | | /// let mut group = NameServerConfigGroup::google(); |
790 | | /// group.merge(NameServerConfigGroup::cloudflare()); |
791 | | /// group.merge(NameServerConfigGroup::quad9()); |
792 | | /// |
793 | | /// assert!(group.iter().any(|c| c.socket_addr == SocketAddr::new(Ipv4Addr::new(8, 8, 8, 8).into(), 53))); |
794 | | /// assert!(group.iter().any(|c| c.socket_addr == SocketAddr::new(Ipv4Addr::new(1, 1, 1, 1).into(), 53))); |
795 | | /// assert!(group.iter().any(|c| c.socket_addr == SocketAddr::new(Ipv4Addr::new(9, 9, 9, 9).into(), 53))); |
796 | | /// ``` |
797 | 0 | pub fn merge(&mut self, mut other: Self) { |
798 | 0 | #[cfg(not(feature = "dns-over-rustls"))] |
799 | 0 | { |
800 | 0 | self.append(&mut other); |
801 | 0 | } |
802 | 0 | #[cfg(feature = "dns-over-rustls")] |
803 | 0 | { |
804 | 0 | self.0.append(&mut other); |
805 | 0 | } |
806 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::merge Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::merge |
807 | | |
808 | | /// add a [`rustls::ClientConfig`] |
809 | | #[cfg(feature = "dns-over-rustls")] |
810 | | #[cfg_attr(docsrs, doc(cfg(feature = "dns-over-rustls")))] |
811 | | pub fn with_client_config(self, client_config: Arc<ClientConfig>) -> Self { |
812 | | Self(self.0, Some(TlsClientConfig(client_config))) |
813 | | } |
814 | | |
815 | | /// Sets the client address (IP and port) to connect from on all name servers. |
816 | 0 | pub fn with_bind_addr(mut self, bind_addr: Option<SocketAddr>) -> Self { |
817 | 0 | for server in &mut self.0 { |
818 | 0 | server.bind_addr = bind_addr; |
819 | 0 | } |
820 | 0 | self |
821 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::with_bind_addr Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup>::with_bind_addr |
822 | | } |
823 | | |
824 | | impl Default for NameServerConfigGroup { |
825 | 0 | fn default() -> Self { |
826 | 0 | Self::new() |
827 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup as core::default::Default>::default Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup as core::default::Default>::default |
828 | | } |
829 | | |
830 | | impl Deref for NameServerConfigGroup { |
831 | | type Target = Vec<NameServerConfig>; |
832 | 7.36k | fn deref(&self) -> &Self::Target { |
833 | 7.36k | &self.0 |
834 | 7.36k | } <hickory_resolver::config::NameServerConfigGroup as core::ops::deref::Deref>::deref Line | Count | Source | 832 | 7.36k | fn deref(&self) -> &Self::Target { | 833 | 7.36k | &self.0 | 834 | 7.36k | } |
Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup as core::ops::deref::Deref>::deref |
835 | | } |
836 | | |
837 | | impl DerefMut for NameServerConfigGroup { |
838 | 0 | fn deref_mut(&mut self) -> &mut Self::Target { |
839 | 0 | &mut self.0 |
840 | 0 | } Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup as core::ops::deref::DerefMut>::deref_mut Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup as core::ops::deref::DerefMut>::deref_mut |
841 | | } |
842 | | |
843 | | impl From<Vec<NameServerConfig>> for NameServerConfigGroup { |
844 | 3.68k | fn from(configs: Vec<NameServerConfig>) -> Self { |
845 | 3.68k | #[cfg(not(feature = "dns-over-rustls"))] |
846 | 3.68k | { |
847 | 3.68k | Self(configs) |
848 | 3.68k | } |
849 | 3.68k | #[cfg(feature = "dns-over-rustls")] |
850 | 3.68k | { |
851 | 3.68k | Self(configs, None) |
852 | 3.68k | } |
853 | 3.68k | } <hickory_resolver::config::NameServerConfigGroup as core::convert::From<alloc::vec::Vec<hickory_resolver::config::NameServerConfig>>>::from Line | Count | Source | 844 | 3.68k | fn from(configs: Vec<NameServerConfig>) -> Self { | 845 | 3.68k | #[cfg(not(feature = "dns-over-rustls"))] | 846 | 3.68k | { | 847 | 3.68k | Self(configs) | 848 | 3.68k | } | 849 | 3.68k | #[cfg(feature = "dns-over-rustls")] | 850 | 3.68k | { | 851 | 3.68k | Self(configs, None) | 852 | 3.68k | } | 853 | 3.68k | } |
Unexecuted instantiation: <hickory_resolver::config::NameServerConfigGroup as core::convert::From<alloc::vec::Vec<hickory_resolver::config::NameServerConfig>>>::from |
854 | | } |
855 | | |
856 | | /// The lookup ip strategy |
857 | | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
858 | | #[cfg_attr(feature = "serde-config", derive(Serialize, Deserialize))] |
859 | | pub enum LookupIpStrategy { |
860 | | /// Only query for A (Ipv4) records |
861 | | Ipv4Only, |
862 | | /// Only query for AAAA (Ipv6) records |
863 | | Ipv6Only, |
864 | | /// Query for A and AAAA in parallel |
865 | | Ipv4AndIpv6, |
866 | | /// Query for Ipv6 if that fails, query for Ipv4 |
867 | | Ipv6thenIpv4, |
868 | | /// Query for Ipv4 if that fails, query for Ipv6 (default) |
869 | | Ipv4thenIpv6, |
870 | | } |
871 | | |
872 | | impl Default for LookupIpStrategy { |
873 | | /// Returns [`LookupIpStrategy::Ipv4thenIpv6`] as the default. |
874 | 3.68k | fn default() -> Self { |
875 | 3.68k | Self::Ipv4thenIpv6 |
876 | 3.68k | } <hickory_resolver::config::LookupIpStrategy as core::default::Default>::default Line | Count | Source | 874 | 3.68k | fn default() -> Self { | 875 | 3.68k | Self::Ipv4thenIpv6 | 876 | 3.68k | } |
Unexecuted instantiation: <hickory_resolver::config::LookupIpStrategy as core::default::Default>::default |
877 | | } |
878 | | |
879 | | /// The strategy for establishing the query order of name servers in a pool. |
880 | | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
881 | | #[cfg_attr(feature = "serde-config", derive(Serialize, Deserialize))] |
882 | | pub enum ServerOrderingStrategy { |
883 | | /// Servers are ordered based on collected query statistics. The ordering |
884 | | /// may vary over time. |
885 | | QueryStatistics, |
886 | | /// The order provided to the resolver is used. The ordering does not vary |
887 | | /// over time. |
888 | | UserProvidedOrder, |
889 | | } |
890 | | |
891 | | impl Default for ServerOrderingStrategy { |
892 | | /// Returns [`ServerOrderingStrategy::QueryStatistics`] as the default. |
893 | 3.68k | fn default() -> Self { |
894 | 3.68k | Self::QueryStatistics |
895 | 3.68k | } <hickory_resolver::config::ServerOrderingStrategy as core::default::Default>::default Line | Count | Source | 893 | 3.68k | fn default() -> Self { | 894 | 3.68k | Self::QueryStatistics | 895 | 3.68k | } |
Unexecuted instantiation: <hickory_resolver::config::ServerOrderingStrategy as core::default::Default>::default |
896 | | } |
897 | | |
898 | | /// Configuration for the Resolver |
899 | | #[derive(Debug, Clone, Eq, PartialEq)] |
900 | | #[cfg_attr( |
901 | | feature = "serde-config", |
902 | | derive(Serialize, Deserialize), |
903 | | serde(default) |
904 | | )] |
905 | | #[allow(missing_copy_implementations)] |
906 | | #[non_exhaustive] |
907 | | pub struct ResolverOpts { |
908 | | /// Sets the number of dots that must appear (unless it's a final dot representing the root) |
909 | | /// before a query is assumed to include the TLD. The default is one, which means that `www` |
910 | | /// would never be assumed to be a TLD, and would always be appended to either the search |
911 | | pub ndots: usize, |
912 | | /// Specify the timeout for a request. Defaults to 5 seconds |
913 | | pub timeout: Duration, |
914 | | /// Number of retries after lookup failure before giving up. Defaults to 2 |
915 | | pub attempts: usize, |
916 | | /// Rotate through the resource records in the response (if there is more than one for a given name) |
917 | | pub rotate: bool, |
918 | | /// Validate the names in the response, not implemented don't really see the point unless you need to support |
919 | | /// badly configured DNS |
920 | | pub check_names: bool, |
921 | | /// Enable edns, for larger records |
922 | | pub edns0: bool, |
923 | | /// Use DNSSEC to validate the request |
924 | | pub validate: bool, |
925 | | /// The ip_strategy for the Resolver to use when lookup Ipv4 or Ipv6 addresses |
926 | | pub ip_strategy: LookupIpStrategy, |
927 | | /// Cache size is in number of records (some records can be large) |
928 | | pub cache_size: usize, |
929 | | /// Check /ect/hosts file before dns requery (only works for unix like OS) |
930 | | pub use_hosts_file: bool, |
931 | | /// Optional minimum TTL for positive responses. |
932 | | /// |
933 | | /// If this is set, any positive responses with a TTL lower than this value will have a TTL of |
934 | | /// `positive_min_ttl` instead. Otherwise, this will default to 0 seconds. |
935 | | pub positive_min_ttl: Option<Duration>, |
936 | | /// Optional minimum TTL for negative (`NXDOMAIN`) responses. |
937 | | /// |
938 | | /// If this is set, any negative responses with a TTL lower than this value will have a TTL of |
939 | | /// `negative_min_ttl` instead. Otherwise, this will default to 0 seconds. |
940 | | pub negative_min_ttl: Option<Duration>, |
941 | | /// Optional maximum TTL for positive responses. |
942 | | /// |
943 | | /// If this is set, any positive responses with a TTL higher than this value will have a TTL of |
944 | | /// `positive_max_ttl` instead. Otherwise, this will default to [`MAX_TTL`] seconds. |
945 | | /// |
946 | | /// [`MAX_TTL`]: ../dns_lru/const.MAX_TTL.html |
947 | | pub positive_max_ttl: Option<Duration>, |
948 | | /// Optional maximum TTL for negative (`NXDOMAIN`) responses. |
949 | | /// |
950 | | /// If this is set, any negative responses with a TTL higher than this value will have a TTL of |
951 | | /// `negative_max_ttl` instead. Otherwise, this will default to [`MAX_TTL`] seconds. |
952 | | /// |
953 | | /// [`MAX_TTL`]: ../dns_lru/const.MAX_TTL.html |
954 | | pub negative_max_ttl: Option<Duration>, |
955 | | /// Number of concurrent requests per query |
956 | | /// |
957 | | /// Where more than one nameserver is configured, this configures the resolver to send queries |
958 | | /// to a number of servers in parallel. Defaults to 2; 0 or 1 will execute requests serially. |
959 | | pub num_concurrent_reqs: usize, |
960 | | /// Preserve all intermediate records in the lookup response, such as CNAME records |
961 | | pub preserve_intermediates: bool, |
962 | | /// Try queries over TCP if they fail over UDP. |
963 | | pub try_tcp_on_error: bool, |
964 | | /// The server ordering strategy that the resolver should use. |
965 | | pub server_ordering_strategy: ServerOrderingStrategy, |
966 | | /// Request upstream recursive resolvers to not perform any recursion. |
967 | | /// |
968 | | /// This is true by default, disabling this is useful for requesting single records, but may prevent successful resolution. |
969 | | pub recursion_desired: bool, |
970 | | /// This is true by default, disabling this is useful for requesting single records, but may prevent successful resolution. |
971 | | pub authentic_data: bool, |
972 | | /// Shuffle DNS servers before each query. |
973 | | pub shuffle_dns_servers: bool, |
974 | | } |
975 | | |
976 | | impl Default for ResolverOpts { |
977 | | /// Default values for the Resolver configuration. |
978 | | /// |
979 | | /// This follows the resolv.conf defaults as defined in the [Linux man pages](https://man7.org/linux/man-pages/man5/resolv.conf.5.html) |
980 | 3.68k | fn default() -> Self { |
981 | 3.68k | Self { |
982 | 3.68k | ndots: 1, |
983 | 3.68k | timeout: Duration::from_secs(5), |
984 | 3.68k | attempts: 2, |
985 | 3.68k | rotate: false, |
986 | 3.68k | check_names: true, |
987 | 3.68k | edns0: false, |
988 | 3.68k | validate: false, |
989 | 3.68k | ip_strategy: LookupIpStrategy::default(), |
990 | 3.68k | cache_size: 32, |
991 | 3.68k | use_hosts_file: true, |
992 | 3.68k | positive_min_ttl: None, |
993 | 3.68k | negative_min_ttl: None, |
994 | 3.68k | positive_max_ttl: None, |
995 | 3.68k | negative_max_ttl: None, |
996 | 3.68k | num_concurrent_reqs: 2, |
997 | 3.68k | |
998 | 3.68k | // Defaults to `true` to match the behavior of dig and nslookup. |
999 | 3.68k | preserve_intermediates: true, |
1000 | 3.68k | |
1001 | 3.68k | try_tcp_on_error: false, |
1002 | 3.68k | server_ordering_strategy: ServerOrderingStrategy::default(), |
1003 | 3.68k | recursion_desired: true, |
1004 | 3.68k | authentic_data: false, |
1005 | 3.68k | shuffle_dns_servers: false, |
1006 | 3.68k | } |
1007 | 3.68k | } <hickory_resolver::config::ResolverOpts as core::default::Default>::default Line | Count | Source | 980 | 3.68k | fn default() -> Self { | 981 | 3.68k | Self { | 982 | 3.68k | ndots: 1, | 983 | 3.68k | timeout: Duration::from_secs(5), | 984 | 3.68k | attempts: 2, | 985 | 3.68k | rotate: false, | 986 | 3.68k | check_names: true, | 987 | 3.68k | edns0: false, | 988 | 3.68k | validate: false, | 989 | 3.68k | ip_strategy: LookupIpStrategy::default(), | 990 | 3.68k | cache_size: 32, | 991 | 3.68k | use_hosts_file: true, | 992 | 3.68k | positive_min_ttl: None, | 993 | 3.68k | negative_min_ttl: None, | 994 | 3.68k | positive_max_ttl: None, | 995 | 3.68k | negative_max_ttl: None, | 996 | 3.68k | num_concurrent_reqs: 2, | 997 | 3.68k | | 998 | 3.68k | // Defaults to `true` to match the behavior of dig and nslookup. | 999 | 3.68k | preserve_intermediates: true, | 1000 | 3.68k | | 1001 | 3.68k | try_tcp_on_error: false, | 1002 | 3.68k | server_ordering_strategy: ServerOrderingStrategy::default(), | 1003 | 3.68k | recursion_desired: true, | 1004 | 3.68k | authentic_data: false, | 1005 | 3.68k | shuffle_dns_servers: false, | 1006 | 3.68k | } | 1007 | 3.68k | } |
Unexecuted instantiation: <hickory_resolver::config::ResolverOpts as core::default::Default>::default |
1008 | | } |
1009 | | |
1010 | | /// IP addresses for Google Public DNS |
1011 | | pub const GOOGLE_IPS: &[IpAddr] = &[ |
1012 | | IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), |
1013 | | IpAddr::V4(Ipv4Addr::new(8, 8, 4, 4)), |
1014 | | IpAddr::V6(Ipv6Addr::new(0x2001, 0x4860, 0x4860, 0, 0, 0, 0, 0x8888)), |
1015 | | IpAddr::V6(Ipv6Addr::new(0x2001, 0x4860, 0x4860, 0, 0, 0, 0, 0x8844)), |
1016 | | ]; |
1017 | | |
1018 | | /// IP addresses for Cloudflare's 1.1.1.1 DNS service |
1019 | | pub const CLOUDFLARE_IPS: &[IpAddr] = &[ |
1020 | | IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)), |
1021 | | IpAddr::V4(Ipv4Addr::new(1, 0, 0, 1)), |
1022 | | IpAddr::V6(Ipv6Addr::new(0x2606, 0x4700, 0x4700, 0, 0, 0, 0, 0x1111)), |
1023 | | IpAddr::V6(Ipv6Addr::new(0x2606, 0x4700, 0x4700, 0, 0, 0, 0, 0x1001)), |
1024 | | ]; |
1025 | | |
1026 | | /// IP address for the Quad9 DNS service |
1027 | | pub const QUAD9_IPS: &[IpAddr] = &[ |
1028 | | IpAddr::V4(Ipv4Addr::new(9, 9, 9, 9)), |
1029 | | IpAddr::V4(Ipv4Addr::new(149, 112, 112, 112)), |
1030 | | IpAddr::V6(Ipv6Addr::new(0x2620, 0x00fe, 0, 0, 0, 0, 0, 0x00fe)), |
1031 | | IpAddr::V6(Ipv6Addr::new(0x2620, 0x00fe, 0, 0, 0, 0, 0x00fe, 0x0009)), |
1032 | | ]; |