trust_dns_proto/
lib.rs
1#![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, )]
27#![recursion_limit = "2048"]
28#![cfg_attr(docsrs, feature(doc_cfg))]
29
30use async_trait::async_trait;
33use futures_util::future::Future;
34
35use std::marker::Send;
36use std::time::Duration;
37#[cfg(any(test, feature = "tokio-runtime"))]
38use tokio::runtime::Runtime;
39#[cfg(any(test, feature = "tokio-runtime"))]
40use tokio::task::JoinHandle;
41
42macro_rules! try_ready_stream {
43 ($e:expr) => {{
44 match $e {
45 Poll::Ready(Some(Ok(t))) => t,
46 Poll::Ready(None) => return Poll::Ready(None),
47 Poll::Pending => return Poll::Pending,
48 Poll::Ready(Some(Err(e))) => return Poll::Ready(Some(Err(From::from(e)))),
49 }
50 }};
51}
52
53#[cfg(any(test, feature = "tokio-runtime"))]
55#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
56pub fn spawn_bg<F: Future<Output = R> + Send + 'static, R: Send + 'static>(
57 runtime: &Runtime,
58 background: F,
59) -> JoinHandle<R> {
60 runtime.spawn(background)
61}
62
63pub mod error;
64#[cfg(feature = "dns-over-https")]
65#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))]
66pub mod https;
67#[cfg(feature = "mdns")]
68#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))]
69pub mod multicast;
70#[cfg(feature = "dns-over-native-tls")]
71#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-native-tls")))]
72pub mod native_tls;
73pub mod op;
74#[cfg(feature = "dns-over-openssl")]
75#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-openssl")))]
76pub mod openssl;
77#[cfg(all(feature = "dns-over-quic", feature = "tokio-runtime"))]
78#[cfg_attr(
79 docsrs,
80 doc(cfg(all(feature = "dns-over-quic", feature = "tokio-runtime")))
81)]
82pub mod quic;
83pub mod rr;
84#[cfg(feature = "dns-over-rustls")]
85#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-rustls")))]
86pub mod rustls;
87pub mod serialize;
88pub mod tcp;
89#[cfg(any(test, feature = "testing"))]
90#[cfg_attr(docsrs, doc(cfg(feature = "testing")))]
91pub mod tests;
92pub mod udp;
93pub mod xfer;
94
95#[doc(hidden)]
96pub use crate::xfer::dns_handle::{DnsHandle, DnsStreamHandle};
97#[doc(hidden)]
98pub use crate::xfer::dns_multiplexer::DnsMultiplexer;
99#[doc(hidden)]
100#[cfg(feature = "dnssec")]
101pub use crate::xfer::dnssec_dns_handle::DnssecDnsHandle;
102#[doc(hidden)]
103pub use crate::xfer::retry_dns_handle::RetryDnsHandle;
104#[doc(hidden)]
105pub use crate::xfer::BufDnsStreamHandle;
106#[cfg(feature = "backtrace")]
107#[cfg_attr(docsrs, doc(cfg(feature = "backtrace")))]
108pub use error::ExtBacktrace;
109
110#[cfg(feature = "tokio-runtime")]
111#[doc(hidden)]
112pub mod iocompat {
113 use std::io;
114 use std::pin::Pin;
115 use std::task::{Context, Poll};
116
117 use futures_io::{AsyncRead, AsyncWrite};
118 use tokio::io::{AsyncRead as TokioAsyncRead, AsyncWrite as TokioAsyncWrite, ReadBuf};
119
120 pub struct AsyncIoTokioAsStd<T: TokioAsyncRead + TokioAsyncWrite>(pub T);
122
123 impl<T: TokioAsyncRead + TokioAsyncWrite + Unpin> Unpin for AsyncIoTokioAsStd<T> {}
124 impl<R: TokioAsyncRead + TokioAsyncWrite + Unpin> AsyncRead for AsyncIoTokioAsStd<R> {
125 fn poll_read(
126 mut self: Pin<&mut Self>,
127 cx: &mut Context<'_>,
128 buf: &mut [u8],
129 ) -> Poll<io::Result<usize>> {
130 let mut buf = ReadBuf::new(buf);
131 let polled = Pin::new(&mut self.0).poll_read(cx, &mut buf);
132
133 polled.map_ok(|_| buf.filled().len())
134 }
135 }
136
137 impl<W: TokioAsyncRead + TokioAsyncWrite + Unpin> AsyncWrite for AsyncIoTokioAsStd<W> {
138 fn poll_write(
139 mut self: Pin<&mut Self>,
140 cx: &mut Context<'_>,
141 buf: &[u8],
142 ) -> Poll<io::Result<usize>> {
143 Pin::new(&mut self.0).poll_write(cx, buf)
144 }
145 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
146 Pin::new(&mut self.0).poll_flush(cx)
147 }
148 fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
149 Pin::new(&mut self.0).poll_shutdown(cx)
150 }
151 }
152
153 pub struct AsyncIoStdAsTokio<T: AsyncRead + AsyncWrite>(pub T);
155
156 impl<T: AsyncRead + AsyncWrite + Unpin> Unpin for AsyncIoStdAsTokio<T> {}
157 impl<R: AsyncRead + AsyncWrite + Unpin> TokioAsyncRead for AsyncIoStdAsTokio<R> {
158 fn poll_read(
159 self: Pin<&mut Self>,
160 cx: &mut Context<'_>,
161 buf: &mut ReadBuf<'_>,
162 ) -> Poll<io::Result<()>> {
163 Pin::new(&mut self.get_mut().0)
164 .poll_read(cx, buf.initialized_mut())
165 .map_ok(|len| buf.advance(len))
166 }
167 }
168
169 impl<W: AsyncRead + AsyncWrite + Unpin> TokioAsyncWrite for AsyncIoStdAsTokio<W> {
170 fn poll_write(
171 self: Pin<&mut Self>,
172 cx: &mut Context<'_>,
173 buf: &[u8],
174 ) -> Poll<Result<usize, io::Error>> {
175 Pin::new(&mut self.get_mut().0).poll_write(cx, buf)
176 }
177
178 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
179 Pin::new(&mut self.get_mut().0).poll_flush(cx)
180 }
181
182 fn poll_shutdown(
183 self: Pin<&mut Self>,
184 cx: &mut Context<'_>,
185 ) -> Poll<Result<(), io::Error>> {
186 Pin::new(&mut self.get_mut().0).poll_close(cx)
187 }
188 }
189}
190
191pub trait Executor {
195 fn new() -> Self;
197
198 fn block_on<F: Future>(&mut self, future: F) -> F::Output;
201}
202
203#[cfg(feature = "tokio-runtime")]
204#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
205impl Executor for Runtime {
206 fn new() -> Self {
207 Self::new().expect("failed to create tokio runtime")
208 }
209
210 fn block_on<F: Future>(&mut self, future: F) -> F::Output {
211 Self::block_on(self, future)
212 }
213}
214
215#[async_trait]
218pub trait Time {
219 async fn delay_for(duration: Duration);
222
223 async fn timeout<F: 'static + Future + Send>(
225 duration: Duration,
226 future: F,
227 ) -> Result<F::Output, std::io::Error>;
228}
229
230#[cfg(any(test, feature = "tokio-runtime"))]
232#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
233#[derive(Clone, Copy, Debug)]
234pub struct TokioTime;
235
236#[cfg(any(test, feature = "tokio-runtime"))]
237#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
238#[async_trait]
239impl Time for TokioTime {
240 async fn delay_for(duration: Duration) {
241 tokio::time::sleep(duration).await
242 }
243
244 async fn timeout<F: 'static + Future + Send>(
245 duration: Duration,
246 future: F,
247 ) -> Result<F::Output, std::io::Error> {
248 tokio::time::timeout(duration, future)
249 .await
250 .map_err(move |_| std::io::Error::new(std::io::ErrorKind::TimedOut, "future timed out"))
251 }
252}