Coverage Report

Created: 2024-12-17 06:15

/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
];