Coverage Report

Created: 2026-02-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/hickory-resolver-0.25.1/src/lib.rs
Line
Count
Source
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
//! The Resolver is responsible for performing recursive queries to lookup domain names.
9
//!
10
//! This is a 100% in process DNS resolver. It *does not* use the Host OS' resolver. If what is
11
//! desired is to use the Host OS' resolver, generally in the system's libc, then the
12
//! `std::net::ToSocketAddrs` variant over `&str` should be used.
13
//!
14
//! Unlike the `hickory-client`, this tries to provide a simpler interface to perform DNS
15
//! queries. For update options, i.e. Dynamic DNS, the `hickory-client` crate must be used
16
//! instead. The Resolver library is capable of searching multiple domains (this can be disabled by
17
//! using an FQDN during lookup), dual-stack IPv4/IPv6 lookups, performing chained CNAME lookups,
18
//! and features connection metric tracking for attempting to pick the best upstream DNS resolver.
19
//!
20
//! This as best as possible attempts to abide by the DNS RFCs, please file issues at
21
//! <https://github.com/hickory-dns/hickory-dns>.
22
//!
23
//! # Usage
24
//!
25
//! ## Declare dependency
26
//!
27
//! ```toml
28
//! [dependency]
29
//! hickory-resolver = "*"
30
//! ```
31
//!
32
//! ## Using the host system config
33
//!
34
//! On Unix systems, the `/etc/resolv.conf` can be used for configuration. Not all options
35
//! specified in the host systems `resolv.conf` are applicable or compatible with this software. In
36
//! addition there may be additional options supported which the host system does not. Example:
37
//!
38
//! ```rust,no_run
39
//! # #[tokio::main]
40
//! # async fn main() {
41
//! # #[cfg(feature = "tokio")]
42
//! # {
43
//! # use std::net::*;
44
//! # use hickory_resolver::Resolver;
45
//! // Use the host OS'es `/etc/resolv.conf`
46
//! # #[cfg(unix)]
47
//! let resolver = Resolver::builder_tokio().unwrap().build();
48
//! # #[cfg(unix)]
49
//! let response = resolver.lookup_ip("www.example.com.").await.unwrap();
50
//! # }
51
//! # }
52
//! ```
53
//!
54
//! ## Using the Tokio/Async Resolver
55
//!
56
//! ```rust
57
//! # fn main() {
58
//! # #[cfg(feature = "tokio")]
59
//! # {
60
//! use std::net::*;
61
//! use tokio::runtime::Runtime;
62
//! use hickory_resolver::Resolver;
63
//! use hickory_resolver::name_server::TokioConnectionProvider;
64
//! use hickory_resolver::config::*;
65
//!
66
//! // We need a Tokio Runtime to run the resolver
67
//! //  this is responsible for running all Future tasks and registering interest in IO channels
68
//! let mut io_loop = Runtime::new().unwrap();
69
//!
70
//! // Construct a new Resolver with default configuration options
71
//! let resolver = Resolver::builder_with_config(
72
//!     ResolverConfig::default(),
73
//!     TokioConnectionProvider::default()
74
//! ).build();
75
//!
76
//! // Lookup the IP addresses associated with a name.
77
//! // This returns a future that will lookup the IP addresses, it must be run in the Core to
78
//! //  to get the actual result.
79
//! let lookup_future = resolver.lookup_ip("www.example.com.");
80
//!
81
//! // Run the lookup until it resolves or errors
82
//! let mut response = io_loop.block_on(lookup_future).unwrap();
83
//!
84
//! // There can be many addresses associated with the name,
85
//! //  this can return IPv4 and/or IPv6 addresses
86
//! let _address = response.iter().next().expect("no addresses returned!");
87
//! # }
88
//! # }
89
//! ```
90
//!
91
//! Generally after a lookup in an asynchronous context, there would probably be a connection made
92
//! to a server, for example:
93
//!
94
//! ```rust,no_run
95
//! # fn main() {
96
//! # #[cfg(feature = "tokio")]
97
//! # {
98
//! # use std::net::*;
99
//! # use tokio::runtime::Runtime;
100
//! # use hickory_resolver::Resolver;
101
//! # use hickory_resolver::name_server::TokioConnectionProvider;
102
//! # use hickory_resolver::config::*;
103
//! # use futures_util::TryFutureExt;
104
//! #
105
//! # let mut io_loop = Runtime::new().unwrap();
106
//! #
107
//! # let resolver = Resolver::builder_with_config(
108
//! #     ResolverConfig::default(),
109
//! #     TokioConnectionProvider::default()
110
//! # ).build();
111
//! #
112
//! let ips = io_loop.block_on(resolver.lookup_ip("www.example.com.")).unwrap();
113
//!
114
//! let result = io_loop.block_on(async {
115
//!     let ip = ips.iter().next().unwrap();
116
//!     TcpStream::connect((ip, 443))
117
//! })
118
//! .and_then(|conn| Ok(conn) /* do something with the connection... */)
119
//! .unwrap();
120
//! # }
121
//! # }
122
//! ```
123
//!
124
//! It's beyond the scope of these examples to show how to deal with connection failures and
125
//! looping etc. But if you wanted to say try a different address from the result set after a
126
//! connection failure, it will be necessary to create a type that implements the `Future` trait.
127
//! Inside the `Future::poll` method would be the place to implement a loop over the different IP
128
//! addresses.
129
//!
130
//! ## Optional protocol support
131
//!
132
//! The following DNS protocols are optionally supported:
133
//!
134
//! - Enable `tls` for DNS over TLS (DoT)
135
//! - Enable `https-rustls` for DNS over HTTP/2 (DoH)
136
//! - Enable `quic` for DNS over QUIC (DoQ)
137
//! - Enable `h3` for DNS over HTTP/3 (DoH3)
138
//!
139
//! ### Example
140
//!
141
//! Enable the TLS library through the dependency on `hickory-resolver`:
142
//!
143
//! ```toml
144
//! hickory-resolver = { version = "*", features = ["tls"] }
145
//! ```
146
//!
147
//! A default TLS configuration is available for Cloudflare's `1.1.1.1` DNS service (Quad9 as
148
//! well):
149
//!
150
//! ```rust,no_run
151
//! # fn main() {
152
//! # #[cfg(feature = "tokio")]
153
//! # {
154
//! use hickory_resolver::Resolver;
155
//! use hickory_resolver::name_server::TokioConnectionProvider;
156
//! use hickory_resolver::config::*;
157
//!
158
//! // Construct a new Resolver with default configuration options
159
//! # #[cfg(feature = "__tls")]
160
//! let mut resolver = Resolver::builder_with_config(
161
//!     ResolverConfig::cloudflare_tls(),
162
//!     TokioConnectionProvider::default(),
163
//! ).build();
164
//!
165
//! // see example above...
166
//! # }
167
//! # }
168
//! ```
169
//!
170
//! ## mDNS (multicast DNS)
171
//!
172
//! Multicast DNS is an experimental feature in Hickory DNS at the moment. Its support on different
173
//! platforms is not yet ideal. Initial support is only for IPv4 mDNS, as there are some
174
//! complexities to figure out with IPv6. Once enabled, an mDNS `NameServer` will automatically be
175
//! added to the `Resolver` and used for any lookups performed in the `.local.` zone.
176
177
// LIBRARY WARNINGS
178
#![warn(
179
    clippy::default_trait_access,
180
    clippy::dbg_macro,
181
    clippy::print_stdout,
182
    clippy::unimplemented,
183
    clippy::use_self,
184
    missing_copy_implementations,
185
    missing_docs,
186
    non_snake_case,
187
    non_upper_case_globals,
188
    rust_2018_idioms,
189
    unreachable_pub
190
)]
191
#![recursion_limit = "128"]
192
#![allow(clippy::needless_doctest_main, clippy::single_component_path_imports)]
193
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
194
195
pub use hickory_proto as proto;
196
// reexports from proto
197
pub use proto::rr::{IntoName, Name};
198
199
pub mod caching_client;
200
pub mod config;
201
pub mod dns_lru;
202
mod error;
203
pub use error::{ResolveError, ResolveErrorKind};
204
#[cfg(feature = "__https")]
205
mod h2;
206
#[cfg(feature = "__h3")]
207
mod h3;
208
mod hosts;
209
pub use hosts::Hosts;
210
pub mod lookup;
211
pub mod lookup_ip;
212
// TODO: consider #[doc(hidden)]
213
pub mod name_server;
214
#[cfg(feature = "tokio")]
215
use name_server::TokioConnectionProvider;
216
#[cfg(feature = "__quic")]
217
mod quic;
218
mod resolver;
219
pub use resolver::LookupFuture;
220
#[cfg(feature = "tokio")]
221
pub use resolver::TokioResolver;
222
pub use resolver::{Resolver, ResolverBuilder};
223
pub mod system_conf;
224
#[cfg(test)]
225
mod tests;
226
#[cfg(feature = "__tls")]
227
mod tls;
228
229
#[doc(hidden)]
230
#[deprecated(since = "0.25.0", note = "use `Resolver` instead")]
231
pub type AsyncResolver<P> = Resolver<P>;
232
233
#[doc(hidden)]
234
#[deprecated(since = "0.25.0", note = "use `TokioResolver` instead")]
235
#[cfg(feature = "tokio")]
236
pub type TokioAsyncResolver = Resolver<TokioConnectionProvider>;
237
238
/// returns a version as specified in Cargo.toml
239
0
pub fn version() -> &'static str {
240
0
    env!("CARGO_PKG_VERSION")
241
0
}