1#![warn(unreachable_pub, clippy::use_self)]
40
41use std::io;
42#[cfg(unix)]
43use std::os::unix::io::{AsRawFd, RawFd};
44#[cfg(windows)]
45use std::os::windows::io::{AsRawSocket, RawSocket};
46use std::pin::Pin;
47use std::task::{Context, Poll};
48
49pub use rustls;
50use rustls::CommonState;
51use tokio::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf};
52
53macro_rules! ready {
54 ( $e:expr ) => {
55 match $e {
56 std::task::Poll::Ready(t) => t,
57 std::task::Poll::Pending => return std::task::Poll::Pending,
58 }
59 };
60}
61
62pub mod client;
63pub use client::{Connect, FallibleConnect, TlsConnector, TlsConnectorWithAlpn};
64mod common;
65pub mod server;
66pub use server::{Accept, FallibleAccept, LazyConfigAcceptor, StartHandshake, TlsAcceptor};
67
68#[allow(clippy::large_enum_variant)] #[derive(Debug)]
74pub enum TlsStream<T> {
75 Client(client::TlsStream<T>),
76 Server(server::TlsStream<T>),
77}
78
79impl<T> TlsStream<T> {
80 pub fn get_ref(&self) -> (&T, &CommonState) {
81 use TlsStream::*;
82 match self {
83 Client(io) => {
84 let (io, session) = io.get_ref();
85 (io, session)
86 }
87 Server(io) => {
88 let (io, session) = io.get_ref();
89 (io, session)
90 }
91 }
92 }
93
94 pub fn get_mut(&mut self) -> (&mut T, &mut CommonState) {
95 use TlsStream::*;
96 match self {
97 Client(io) => {
98 let (io, session) = io.get_mut();
99 (io, &mut *session)
100 }
101 Server(io) => {
102 let (io, session) = io.get_mut();
103 (io, &mut *session)
104 }
105 }
106 }
107}
108
109impl<T> From<client::TlsStream<T>> for TlsStream<T> {
110 fn from(s: client::TlsStream<T>) -> Self {
111 Self::Client(s)
112 }
113}
114
115impl<T> From<server::TlsStream<T>> for TlsStream<T> {
116 fn from(s: server::TlsStream<T>) -> Self {
117 Self::Server(s)
118 }
119}
120
121#[cfg(unix)]
122impl<S> AsRawFd for TlsStream<S>
123where
124 S: AsRawFd,
125{
126 fn as_raw_fd(&self) -> RawFd {
127 self.get_ref().0.as_raw_fd()
128 }
129}
130
131#[cfg(windows)]
132impl<S> AsRawSocket for TlsStream<S>
133where
134 S: AsRawSocket,
135{
136 fn as_raw_socket(&self) -> RawSocket {
137 self.get_ref().0.as_raw_socket()
138 }
139}
140
141impl<T> AsyncRead for TlsStream<T>
142where
143 T: AsyncRead + AsyncWrite + Unpin,
144{
145 #[inline]
146 fn poll_read(
147 self: Pin<&mut Self>,
148 cx: &mut Context<'_>,
149 buf: &mut ReadBuf<'_>,
150 ) -> Poll<io::Result<()>> {
151 match self.get_mut() {
152 Self::Client(x) => Pin::new(x).poll_read(cx, buf),
153 Self::Server(x) => Pin::new(x).poll_read(cx, buf),
154 }
155 }
156}
157
158impl<T> AsyncBufRead for TlsStream<T>
159where
160 T: AsyncRead + AsyncWrite + Unpin,
161{
162 #[inline]
163 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
164 match self.get_mut() {
165 Self::Client(x) => Pin::new(x).poll_fill_buf(cx),
166 Self::Server(x) => Pin::new(x).poll_fill_buf(cx),
167 }
168 }
169
170 #[inline]
171 fn consume(self: Pin<&mut Self>, amt: usize) {
172 match self.get_mut() {
173 Self::Client(x) => Pin::new(x).consume(amt),
174 Self::Server(x) => Pin::new(x).consume(amt),
175 }
176 }
177}
178
179impl<T> AsyncWrite for TlsStream<T>
180where
181 T: AsyncRead + AsyncWrite + Unpin,
182{
183 #[inline]
184 fn poll_write(
185 self: Pin<&mut Self>,
186 cx: &mut Context<'_>,
187 buf: &[u8],
188 ) -> Poll<io::Result<usize>> {
189 match self.get_mut() {
190 Self::Client(x) => Pin::new(x).poll_write(cx, buf),
191 Self::Server(x) => Pin::new(x).poll_write(cx, buf),
192 }
193 }
194
195 #[inline]
196 fn poll_write_vectored(
197 self: Pin<&mut Self>,
198 cx: &mut Context<'_>,
199 bufs: &[io::IoSlice<'_>],
200 ) -> Poll<io::Result<usize>> {
201 match self.get_mut() {
202 Self::Client(x) => Pin::new(x).poll_write_vectored(cx, bufs),
203 Self::Server(x) => Pin::new(x).poll_write_vectored(cx, bufs),
204 }
205 }
206
207 #[inline]
208 fn is_write_vectored(&self) -> bool {
209 match self {
210 Self::Client(x) => x.is_write_vectored(),
211 Self::Server(x) => x.is_write_vectored(),
212 }
213 }
214
215 #[inline]
216 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
217 match self.get_mut() {
218 Self::Client(x) => Pin::new(x).poll_flush(cx),
219 Self::Server(x) => Pin::new(x).poll_flush(cx),
220 }
221 }
222
223 #[inline]
224 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
225 match self.get_mut() {
226 Self::Client(x) => Pin::new(x).poll_shutdown(cx),
227 Self::Server(x) => Pin::new(x).poll_shutdown(cx),
228 }
229 }
230}