hickory_client/client/
dnssec_client.rs1use std::future::Future;
9use std::pin::Pin;
10use std::sync::Arc;
11
12use futures_util::stream::Stream;
13
14use crate::client::Client;
15use crate::proto::ProtoError;
16use crate::proto::dnssec::DnssecDnsHandle;
17use crate::proto::dnssec::TrustAnchors;
18use crate::proto::runtime::TokioTime;
19use crate::proto::xfer::{
20 DnsExchangeBackground, DnsHandle, DnsRequest, DnsRequestSender, DnsResponse,
21};
22
23pub struct DnssecClient {
28 client: DnssecDnsHandle<Client>,
29}
30
31impl DnssecClient {
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: Client, trust_anchor: Arc<TrustAnchors>) -> Self {
56 Self {
57 client: DnssecDnsHandle::with_trust_anchor(client, trust_anchor),
58 }
59 }
60}
61
62impl Clone for DnssecClient {
63 fn clone(&self) -> Self {
64 Self {
65 client: self.client.clone(),
66 }
67 }
68}
69
70impl DnsHandle for DnssecClient {
71 type Response = Pin<Box<(dyn Stream<Item = Result<DnsResponse, ProtoError>> + Send + 'static)>>;
72
73 fn send<R: Into<DnsRequest> + Unpin + Send + 'static>(&self, request: R) -> Self::Response {
74 self.client.send(request)
75 }
76}
77
78pub struct AsyncSecureClientBuilder<F, S>
80where
81 F: Future<Output = Result<S, ProtoError>> + 'static + Send + Unpin,
82 S: DnsRequestSender + 'static,
83{
84 connect_future: F,
85 trust_anchor: Option<TrustAnchors>,
86}
87
88impl<F, S> AsyncSecureClientBuilder<F, S>
89where
90 F: Future<Output = Result<S, ProtoError>> + 'static + Send + Unpin,
91 S: DnsRequestSender + 'static,
92{
93 pub fn trust_anchor(mut self, trust_anchor: TrustAnchors) -> Self {
100 self.trust_anchor = Some(trust_anchor);
101 self
102 }
103
104 pub async fn build(
106 mut self,
107 ) -> Result<(DnssecClient, DnsExchangeBackground<S, TokioTime>), ProtoError> {
108 let trust_anchor = Arc::new(self.trust_anchor.take().unwrap_or_default());
109 let result = Client::connect(self.connect_future).await;
110
111 result.map(|(client, bg)| (DnssecClient::from_client(client, trust_anchor), bg))
112 }
113}