hickory_proto/openssl/
tls_client_stream.rs1use std::future::Future;
9use std::io;
10use std::net::SocketAddr;
11use std::pin::Pin;
12
13use futures_util::TryFutureExt;
14use openssl::x509::X509;
15use tokio_openssl::SslStream as TokioTlsStream;
16
17use crate::error::ProtoError;
18use crate::iocompat::AsyncIoStdAsTokio;
19use crate::iocompat::AsyncIoTokioAsStd;
20use crate::tcp::{Connect, DnsTcpStream, TcpClientStream};
21use crate::xfer::BufDnsStreamHandle;
22
23use super::TlsStreamBuilder;
24
25pub type TlsClientStream<S> =
27 TcpClientStream<AsyncIoTokioAsStd<TokioTlsStream<AsyncIoStdAsTokio<S>>>>;
28
29pub struct TlsClientStreamBuilder<S>(TlsStreamBuilder<S>);
31
32impl<S: DnsTcpStream> TlsClientStreamBuilder<S> {
33 pub fn new() -> Self {
35 Self(TlsStreamBuilder::new())
36 }
37
38 pub fn add_ca(&mut self, ca: X509) {
42 self.0.add_ca(ca);
43 }
44
45 pub fn add_ca_der(&mut self, ca_der: &[u8]) -> io::Result<()> {
49 let ca = X509::from_der(ca_der)
50 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e.to_string()))?;
51 self.add_ca(ca);
52 Ok(())
53 }
54
55 pub fn bind_addr(&mut self, bind_addr: SocketAddr) {
57 self.0.bind_addr(bind_addr);
58 }
59
60 #[allow(clippy::type_complexity)]
68 pub fn build_with_future<F>(
69 self,
70 future: F,
71 name_server: SocketAddr,
72 dns_name: String,
73 ) -> (
74 Pin<Box<dyn Future<Output = Result<TlsClientStream<S>, ProtoError>> + Send>>,
75 BufDnsStreamHandle,
76 )
77 where
78 F: Future<Output = io::Result<S>> + Send + Unpin + 'static,
79 {
80 let (stream_future, sender) = self.0.build_with_future(future, name_server, dns_name);
81
82 let new_future = Box::pin(
83 stream_future
84 .map_ok(TcpClientStream::from_stream)
85 .map_err(ProtoError::from),
86 );
87
88 (new_future, sender)
89 }
90}
91
92impl<S: DnsTcpStream> Default for TlsClientStreamBuilder<S> {
93 fn default() -> Self {
94 Self::new()
95 }
96}
97
98impl<S: Connect> TlsClientStreamBuilder<S> {
99 #[allow(clippy::type_complexity)]
107 pub fn build(
108 self,
109 name_server: SocketAddr,
110 dns_name: String,
111 ) -> (
112 Pin<Box<dyn Future<Output = Result<TlsClientStream<S>, ProtoError>> + Send>>,
113 BufDnsStreamHandle,
114 ) {
115 let (stream_future, sender) = self.0.build(name_server, dns_name);
116
117 let new_future = Box::pin(
118 stream_future
119 .map_ok(TcpClientStream::from_stream)
120 .map_err(ProtoError::from),
121 );
122
123 (new_future, sender)
124 }
125}