hickory_proto/
lib.rs

1// Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com>
2// Copyright 2017 Google LLC.
3//
4// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
5// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
6// https://opensource.org/licenses/MIT>, at your option. This file may not be
7// copied, modified, or distributed except according to those terms.
8
9#![no_std]
10// LIBRARY WARNINGS
11#![warn(
12    clippy::alloc_instead_of_core,
13    clippy::default_trait_access,
14    clippy::dbg_macro,
15    clippy::print_stdout,
16    clippy::std_instead_of_core,
17    clippy::std_instead_of_alloc,
18    clippy::unimplemented,
19    clippy::use_self,
20    missing_copy_implementations,
21    missing_docs,
22    non_snake_case,
23    non_upper_case_globals,
24    rust_2018_idioms,
25    unreachable_pub
26)]
27#![allow(
28    clippy::single_component_path_imports,
29    clippy::upper_case_acronyms, // can be removed on a major release boundary
30    clippy::bool_to_int_with_if,
31)]
32#![recursion_limit = "2048"]
33#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
34
35//! Hickory DNS Protocol library
36
37#[cfg(feature = "std")]
38extern crate std;
39
40#[macro_use]
41extern crate alloc;
42
43#[cfg(feature = "std")]
44macro_rules! try_ready_stream {
45    ($e:expr) => {{
46        match $e {
47            Poll::Ready(Some(Ok(t))) => t,
48            Poll::Ready(None) => return Poll::Ready(None),
49            Poll::Pending => return Poll::Pending,
50            Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(From::from(e)))),
51        }
52    }};
53}
54
55#[cfg(any(feature = "dnssec-aws-lc-rs", feature = "dnssec-ring"))]
56pub mod dnssec;
57mod error;
58#[cfg(feature = "__https")]
59pub mod h2;
60#[cfg(feature = "__h3")]
61pub mod h3;
62#[cfg(any(feature = "__https", feature = "__h3"))]
63pub mod http;
64#[cfg(feature = "mdns")]
65pub mod multicast;
66pub mod op;
67#[cfg(all(feature = "__quic", feature = "tokio"))]
68pub mod quic;
69pub mod rr;
70#[cfg(feature = "std")]
71pub mod runtime;
72#[cfg(feature = "__tls")]
73pub mod rustls;
74pub mod serialize;
75#[cfg(feature = "std")]
76pub mod tcp;
77#[cfg(all(feature = "std", any(test, feature = "testing")))]
78pub mod tests;
79#[cfg(feature = "std")]
80pub mod udp;
81pub mod xfer;
82
83#[doc(hidden)]
84#[cfg(feature = "std")]
85pub use crate::xfer::BufDnsStreamHandle;
86#[doc(hidden)]
87pub use crate::xfer::dns_handle::{DnsHandle, DnsStreamHandle};
88#[doc(hidden)]
89#[cfg(feature = "std")]
90pub use crate::xfer::dns_multiplexer::DnsMultiplexer;
91#[doc(hidden)]
92pub use crate::xfer::retry_dns_handle::RetryDnsHandle;
93#[cfg(feature = "backtrace")]
94pub use error::{ENABLE_BACKTRACE, ExtBacktrace};
95pub use error::{ForwardData, ForwardNSData, ProtoError, ProtoErrorKind};
96
97#[cfg(feature = "std")]
98pub(crate) use rand::random;
99
100#[cfg(all(not(feature = "std"), feature = "no-std-rand"))]
101pub(crate) use no_std_rand::random;
102#[cfg(all(not(feature = "std"), feature = "no-std-rand"))]
103pub use no_std_rand::seed;
104
105/// A simple shim that allows us to use a [`random`] in `no_std` environments.
106#[cfg(all(not(feature = "std"), feature = "no-std-rand"))]
107mod no_std_rand {
108    use core::cell::RefCell;
109
110    use critical_section::Mutex;
111    use rand::distr::{Distribution, StandardUniform};
112    use rand::{Rng, SeedableRng, rngs::StdRng};
113
114    /// Generates a random value on `no_std`.
115    ///
116    /// # Panics
117    /// This function will panic if the rng has not been seeded.
118    /// The rng needs to be seeded using [`crate::seed`] before it can be used!
119    pub(crate) fn random<T>() -> T
120    where
121        StandardUniform: Distribution<T>,
122    {
123        critical_section::with(|cs| {
124            RNG.borrow_ref_mut(cs)
125                .as_mut()
126                .expect("the no_std rng was not seeded using `hickory_proto::seed()`")
127                .random()
128        })
129    }
130
131    /// Seed the rng that is used to create random DNS IDs throughout the lib (no_std-only).
132    pub fn seed(seed: u64) {
133        critical_section::with(|cs| *RNG.borrow_ref_mut(cs) = Some(StdRng::seed_from_u64(seed)));
134    }
135
136    static RNG: Mutex<RefCell<Option<StdRng>>> = Mutex::new(RefCell::new(None));
137
138    #[cfg(test)]
139    mod test {
140        use super::*;
141
142        #[test]
143        fn test_no_std_rand() {
144            // In practice, the seed needs to be a secure random number.
145            seed(0x1337);
146            let _ = random::<u32>();
147        }
148    }
149}