trust_dns_client/client/
async_secure_client.rs1#![cfg(feature = "dnssec")]
8
9use std::future::Future;
10use std::pin::Pin;
11
12use futures_util::stream::Stream;
13
14use crate::client::AsyncClient;
15use crate::proto::error::ProtoError;
16use crate::proto::rr::dnssec::TrustAnchor;
17use crate::proto::xfer::{
18 DnsExchangeBackground, DnsHandle, DnsRequest, DnsRequestSender, DnsResponse,
19};
20use crate::proto::DnssecDnsHandle;
21use crate::proto::TokioTime;
22
23pub struct AsyncDnssecClient {
28 client: DnssecDnsHandle<AsyncClient>,
29}
30
31impl AsyncDnssecClient {
32 pub fn builder<F, S>(connect_future: F) -> AsyncSecureClientBuilder<F, S>
34 where
35 F: Future<Output = Result<S, ProtoError>> + 'static + Send + Unpin,
36 S: DnsRequestSender + 'static,
37 {
38 AsyncSecureClientBuilder {
39 connect_future,
40 trust_anchor: None,
41 }
42 }
43
44 pub async fn connect<F, S>(
46 connect_future: F,
47 ) -> Result<(Self, DnsExchangeBackground<S, TokioTime>), ProtoError>
48 where
49 S: DnsRequestSender,
50 F: Future<Output = Result<S, ProtoError>> + 'static + Send + Unpin,
51 {
52 Self::builder(connect_future).build().await
53 }
54
55 fn from_client(client: AsyncClient, trust_anchor: TrustAnchor) -> Self {
56 Self {
57 client: DnssecDnsHandle::with_trust_anchor(client, trust_anchor),
58 }
59 }
60}
61
62impl Clone for AsyncDnssecClient {
63 fn clone(&self) -> Self {
64 Self {
65 client: self.client.clone(),
66 }
67 }
68}
69
70impl DnsHandle for AsyncDnssecClient {
71 type Response = Pin<Box<(dyn Stream<Item = Result<DnsResponse, ProtoError>> + Send + 'static)>>;
72 type Error = ProtoError;
73
74 fn send<R: Into<DnsRequest> + Unpin + Send + 'static>(&mut self, request: R) -> Self::Response {
75 self.client.send(request)
76 }
77}
78
79#[cfg(feature = "dnssec")]
81#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
82pub struct AsyncSecureClientBuilder<F, S>
83where
84 F: Future<Output = Result<S, ProtoError>> + 'static + Send + Unpin,
85 S: DnsRequestSender + 'static,
86{
87 connect_future: F,
88 trust_anchor: Option<TrustAnchor>,
89}
90
91#[cfg(feature = "dnssec")]
92impl<F, S> AsyncSecureClientBuilder<F, S>
93where
94 F: Future<Output = Result<S, ProtoError>> + 'static + Send + Unpin,
95 S: DnsRequestSender + 'static,
96{
97 pub fn trust_anchor(mut self, trust_anchor: TrustAnchor) -> Self {
104 self.trust_anchor = Some(trust_anchor);
105 self
106 }
107
108 pub async fn build(
110 mut self,
111 ) -> Result<(AsyncDnssecClient, DnsExchangeBackground<S, TokioTime>), ProtoError> {
112 let trust_anchor = if let Some(trust_anchor) = self.trust_anchor.take() {
113 trust_anchor
114 } else {
115 TrustAnchor::default()
116 };
117 let result = AsyncClient::connect(self.connect_future).await;
118
119 result.map(|(client, bg)| (AsyncDnssecClient::from_client(client, trust_anchor), bg))
120 }
121}