trust_dns_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// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
6// http://opensource.org/licenses/MIT>, at your option. This file may not be
7// copied, modified, or distributed except according to those terms.
8
9// LIBRARY WARNINGS
10#![warn(
11    clippy::default_trait_access,
12    clippy::dbg_macro,
13    clippy::print_stdout,
14    clippy::unimplemented,
15    clippy::use_self,
16    missing_copy_implementations,
17    missing_docs,
18    non_snake_case,
19    non_upper_case_globals,
20    rust_2018_idioms,
21    unreachable_pub
22)]
23#![allow(
24    clippy::single_component_path_imports,
25    clippy::upper_case_acronyms, // can be removed on a major release boundary
26    clippy::bool_to_int_with_if,
27)]
28#![recursion_limit = "2048"]
29#![cfg_attr(docsrs, feature(doc_cfg))]
30
31//! **NOTICE** This project has been rebranded to Hickory DNS and has been moved to the https://github.com/hickory-dns/hickory-dns organization and repo, this crate/binary has been moved to [hickory-proto](https://docs.rs/hickory-proto/latest/hickory_proto/), from `0.24` and onward.
32//!
33//! Trust-DNS Protocol library
34
35use async_trait::async_trait;
36use futures_util::future::Future;
37
38use std::marker::Send;
39use std::time::Duration;
40#[cfg(any(test, feature = "tokio-runtime"))]
41use tokio::runtime::Runtime;
42#[cfg(any(test, feature = "tokio-runtime"))]
43use tokio::task::JoinHandle;
44
45macro_rules! try_ready_stream {
46    ($e:expr) => {{
47        match $e {
48            Poll::Ready(Some(Ok(t))) => t,
49            Poll::Ready(None) => return Poll::Ready(None),
50            Poll::Pending => return Poll::Pending,
51            Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(From::from(e)))),
52        }
53    }};
54}
55
56/// Spawn a background task, if it was present
57#[cfg(any(test, feature = "tokio-runtime"))]
58#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
59pub fn spawn_bg<F: Future<Output = R> + Send + 'static, R: Send + 'static>(
60    runtime: &Runtime,
61    background: F,
62) -> JoinHandle<R> {
63    runtime.spawn(background)
64}
65
66pub mod error;
67#[cfg(feature = "dns-over-https")]
68#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))]
69pub mod https;
70#[cfg(feature = "mdns")]
71#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))]
72pub mod multicast;
73#[cfg(feature = "dns-over-native-tls")]
74#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-native-tls")))]
75pub mod native_tls;
76pub mod op;
77#[cfg(feature = "dns-over-openssl")]
78#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-openssl")))]
79pub mod openssl;
80#[cfg(all(feature = "dns-over-quic", feature = "tokio-runtime"))]
81#[cfg_attr(
82    docsrs,
83    doc(cfg(all(feature = "dns-over-quic", feature = "tokio-runtime")))
84)]
85pub mod quic;
86pub mod rr;
87#[cfg(feature = "dns-over-rustls")]
88#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-rustls")))]
89pub mod rustls;
90pub mod serialize;
91pub mod tcp;
92#[cfg(any(test, feature = "testing"))]
93#[cfg_attr(docsrs, doc(cfg(feature = "testing")))]
94pub mod tests;
95pub mod udp;
96pub mod xfer;
97
98#[doc(hidden)]
99pub use crate::xfer::dns_handle::{DnsHandle, DnsStreamHandle};
100#[doc(hidden)]
101pub use crate::xfer::dns_multiplexer::DnsMultiplexer;
102#[doc(hidden)]
103#[cfg(feature = "dnssec")]
104pub use crate::xfer::dnssec_dns_handle::DnssecDnsHandle;
105#[doc(hidden)]
106pub use crate::xfer::retry_dns_handle::RetryDnsHandle;
107#[doc(hidden)]
108pub use crate::xfer::BufDnsStreamHandle;
109#[cfg(feature = "backtrace")]
110#[cfg_attr(docsrs, doc(cfg(feature = "backtrace")))]
111pub use error::ExtBacktrace;
112
113#[cfg(feature = "tokio-runtime")]
114#[doc(hidden)]
115pub mod iocompat {
116    use std::io;
117    use std::pin::Pin;
118    use std::task::{Context, Poll};
119
120    use futures_io::{AsyncRead, AsyncWrite};
121    use tokio::io::{AsyncRead as TokioAsyncRead, AsyncWrite as TokioAsyncWrite, ReadBuf};
122
123    /// Conversion from `tokio::io::{AsyncRead, AsyncWrite}` to `std::io::{AsyncRead, AsyncWrite}`
124    pub struct AsyncIoTokioAsStd<T: TokioAsyncRead + TokioAsyncWrite>(pub T);
125
126    impl<T: TokioAsyncRead + TokioAsyncWrite + Unpin> Unpin for AsyncIoTokioAsStd<T> {}
127    impl<R: TokioAsyncRead + TokioAsyncWrite + Unpin> AsyncRead for AsyncIoTokioAsStd<R> {
128        fn poll_read(
129            mut self: Pin<&mut Self>,
130            cx: &mut Context<'_>,
131            buf: &mut [u8],
132        ) -> Poll<io::Result<usize>> {
133            let mut buf = ReadBuf::new(buf);
134            let polled = Pin::new(&mut self.0).poll_read(cx, &mut buf);
135
136            polled.map_ok(|_| buf.filled().len())
137        }
138    }
139
140    impl<W: TokioAsyncRead + TokioAsyncWrite + Unpin> AsyncWrite for AsyncIoTokioAsStd<W> {
141        fn poll_write(
142            mut self: Pin<&mut Self>,
143            cx: &mut Context<'_>,
144            buf: &[u8],
145        ) -> Poll<io::Result<usize>> {
146            Pin::new(&mut self.0).poll_write(cx, buf)
147        }
148        fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
149            Pin::new(&mut self.0).poll_flush(cx)
150        }
151        fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
152            Pin::new(&mut self.0).poll_shutdown(cx)
153        }
154    }
155
156    /// Conversion from `std::io::{AsyncRead, AsyncWrite}` to `tokio::io::{AsyncRead, AsyncWrite}`
157    pub struct AsyncIoStdAsTokio<T: AsyncRead + AsyncWrite>(pub T);
158
159    impl<T: AsyncRead + AsyncWrite + Unpin> Unpin for AsyncIoStdAsTokio<T> {}
160    impl<R: AsyncRead + AsyncWrite + Unpin> TokioAsyncRead for AsyncIoStdAsTokio<R> {
161        fn poll_read(
162            self: Pin<&mut Self>,
163            cx: &mut Context<'_>,
164            buf: &mut ReadBuf<'_>,
165        ) -> Poll<io::Result<()>> {
166            Pin::new(&mut self.get_mut().0)
167                .poll_read(cx, buf.initialized_mut())
168                .map_ok(|len| buf.advance(len))
169        }
170    }
171
172    impl<W: AsyncRead + AsyncWrite + Unpin> TokioAsyncWrite for AsyncIoStdAsTokio<W> {
173        fn poll_write(
174            self: Pin<&mut Self>,
175            cx: &mut Context<'_>,
176            buf: &[u8],
177        ) -> Poll<Result<usize, io::Error>> {
178            Pin::new(&mut self.get_mut().0).poll_write(cx, buf)
179        }
180
181        fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
182            Pin::new(&mut self.get_mut().0).poll_flush(cx)
183        }
184
185        fn poll_shutdown(
186            self: Pin<&mut Self>,
187            cx: &mut Context<'_>,
188        ) -> Poll<Result<(), io::Error>> {
189            Pin::new(&mut self.get_mut().0).poll_close(cx)
190        }
191    }
192}
193
194/// Generic executor.
195// This trait is created to facilitate running the tests defined in the tests mod using different types of
196// executors. It's used in Fuchsia OS, please be mindful when update it.
197pub trait Executor {
198    /// Create the implementor itself.
199    fn new() -> Self;
200
201    /// Spawns a future object to run synchronously or asynchronously depending on the specific
202    /// executor.
203    fn block_on<F: Future>(&mut self, future: F) -> F::Output;
204}
205
206#[cfg(feature = "tokio-runtime")]
207#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
208impl Executor for Runtime {
209    fn new() -> Self {
210        Self::new().expect("failed to create tokio runtime")
211    }
212
213    fn block_on<F: Future>(&mut self, future: F) -> F::Output {
214        Self::block_on(self, future)
215    }
216}
217
218/// Generic Time for Delay and Timeout.
219// This trait is created to allow to use different types of time systems. It's used in Fuchsia OS, please be mindful when update it.
220#[async_trait]
221pub trait Time {
222    /// Return a type that implements `Future` that will wait until the specified duration has
223    /// elapsed.
224    async fn delay_for(duration: Duration);
225
226    /// Return a type that implement `Future` to complete before the specified duration has elapsed.
227    async fn timeout<F: 'static + Future + Send>(
228        duration: Duration,
229        future: F,
230    ) -> Result<F::Output, std::io::Error>;
231}
232
233/// New type which is implemented using tokio::time::{Delay, Timeout}
234#[cfg(any(test, feature = "tokio-runtime"))]
235#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
236#[derive(Clone, Copy, Debug)]
237pub struct TokioTime;
238
239#[cfg(any(test, feature = "tokio-runtime"))]
240#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
241#[async_trait]
242impl Time for TokioTime {
243    async fn delay_for(duration: Duration) {
244        tokio::time::sleep(duration).await
245    }
246
247    async fn timeout<F: 'static + Future + Send>(
248        duration: Duration,
249        future: F,
250    ) -> Result<F::Output, std::io::Error> {
251        tokio::time::timeout(duration, future)
252            .await
253            .map_err(move |_| std::io::Error::new(std::io::ErrorKind::TimedOut, "future timed out"))
254    }
255}