3838
3939#![ warn( unreachable_pub) ]
4040
41- use std:: future:: Future ;
4241use std:: io;
4342#[ cfg( unix) ]
4443use std:: os:: unix:: io:: { AsRawFd , RawFd } ;
4544#[ cfg( windows) ]
4645use std:: os:: windows:: io:: { AsRawSocket , RawSocket } ;
4746use std:: pin:: Pin ;
48- use std:: sync:: Arc ;
4947use std:: task:: { Context , Poll } ;
5048
5149pub use rustls;
5250
53- use rustls:: server:: AcceptedAlert ;
54- use rustls:: { CommonState , ServerConfig , ServerConnection } ;
51+ use rustls:: CommonState ;
5552use tokio:: io:: { AsyncBufRead , AsyncRead , AsyncWrite , ReadBuf } ;
5653
5754macro_rules! ready {
@@ -66,284 +63,8 @@ macro_rules! ready {
6663pub mod client;
6764pub use client:: { Connect , FallibleConnect , TlsConnector , TlsConnectorWithAlpn } ;
6865mod common;
69- use common:: { MidHandshake , TlsState } ;
7066pub mod server;
71-
72- /// A wrapper around a `rustls::ServerConfig`, providing an async `accept` method.
73- #[ derive( Clone ) ]
74- pub struct TlsAcceptor {
75- inner : Arc < ServerConfig > ,
76- }
77-
78- impl From < Arc < ServerConfig > > for TlsAcceptor {
79- fn from ( inner : Arc < ServerConfig > ) -> TlsAcceptor {
80- TlsAcceptor { inner }
81- }
82- }
83-
84- impl TlsAcceptor {
85- #[ inline]
86- pub fn accept < IO > ( & self , stream : IO ) -> Accept < IO >
87- where
88- IO : AsyncRead + AsyncWrite + Unpin ,
89- {
90- self . accept_with ( stream, |_| ( ) )
91- }
92-
93- pub fn accept_with < IO , F > ( & self , stream : IO , f : F ) -> Accept < IO >
94- where
95- IO : AsyncRead + AsyncWrite + Unpin ,
96- F : FnOnce ( & mut ServerConnection ) ,
97- {
98- let mut session = match ServerConnection :: new ( self . inner . clone ( ) ) {
99- Ok ( session) => session,
100- Err ( error) => {
101- return Accept ( MidHandshake :: Error {
102- io : stream,
103- // TODO(eliza): should this really return an `io::Error`?
104- // Probably not...
105- error : io:: Error :: new ( io:: ErrorKind :: Other , error) ,
106- } ) ;
107- }
108- } ;
109- f ( & mut session) ;
110-
111- Accept ( MidHandshake :: Handshaking ( server:: TlsStream {
112- session,
113- io : stream,
114- state : TlsState :: Stream ,
115- need_flush : false ,
116- } ) )
117- }
118-
119- /// Get a read-only reference to underlying config
120- pub fn config ( & self ) -> & Arc < ServerConfig > {
121- & self . inner
122- }
123- }
124-
125- pub struct LazyConfigAcceptor < IO > {
126- acceptor : rustls:: server:: Acceptor ,
127- io : Option < IO > ,
128- alert : Option < ( rustls:: Error , AcceptedAlert ) > ,
129- }
130-
131- impl < IO > LazyConfigAcceptor < IO >
132- where
133- IO : AsyncRead + AsyncWrite + Unpin ,
134- {
135- #[ inline]
136- pub fn new ( acceptor : rustls:: server:: Acceptor , io : IO ) -> Self {
137- Self {
138- acceptor,
139- io : Some ( io) ,
140- alert : None ,
141- }
142- }
143-
144- /// Takes back the client connection. Will return `None` if called more than once or if the
145- /// connection has been accepted.
146- ///
147- /// # Example
148- ///
149- /// ```no_run
150- /// # fn choose_server_config(
151- /// # _: rustls::server::ClientHello,
152- /// # ) -> std::sync::Arc<rustls::ServerConfig> {
153- /// # unimplemented!();
154- /// # }
155- /// # #[allow(unused_variables)]
156- /// # async fn listen() {
157- /// use tokio::io::AsyncWriteExt;
158- /// let listener = tokio::net::TcpListener::bind("127.0.0.1:4443").await.unwrap();
159- /// let (stream, _) = listener.accept().await.unwrap();
160- ///
161- /// let acceptor = tokio_rustls::LazyConfigAcceptor::new(rustls::server::Acceptor::default(), stream);
162- /// tokio::pin!(acceptor);
163- ///
164- /// match acceptor.as_mut().await {
165- /// Ok(start) => {
166- /// let clientHello = start.client_hello();
167- /// let config = choose_server_config(clientHello);
168- /// let stream = start.into_stream(config).await.unwrap();
169- /// // Proceed with handling the ServerConnection...
170- /// }
171- /// Err(err) => {
172- /// if let Some(mut stream) = acceptor.take_io() {
173- /// stream
174- /// .write_all(
175- /// format!("HTTP/1.1 400 Invalid Input\r\n\r\n\r\n{:?}\n", err)
176- /// .as_bytes()
177- /// )
178- /// .await
179- /// .unwrap();
180- /// }
181- /// }
182- /// }
183- /// # }
184- /// ```
185- pub fn take_io ( & mut self ) -> Option < IO > {
186- self . io . take ( )
187- }
188- }
189-
190- impl < IO > Future for LazyConfigAcceptor < IO >
191- where
192- IO : AsyncRead + AsyncWrite + Unpin ,
193- {
194- type Output = Result < StartHandshake < IO > , io:: Error > ;
195-
196- fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
197- let this = self . get_mut ( ) ;
198- loop {
199- let io = match this. io . as_mut ( ) {
200- Some ( io) => io,
201- None => {
202- return Poll :: Ready ( Err ( io:: Error :: new (
203- io:: ErrorKind :: Other ,
204- "acceptor cannot be polled after acceptance" ,
205- ) ) )
206- }
207- } ;
208-
209- if let Some ( ( err, mut alert) ) = this. alert . take ( ) {
210- match alert. write ( & mut common:: SyncWriteAdapter { io, cx } ) {
211- Err ( e) if e. kind ( ) == io:: ErrorKind :: WouldBlock => {
212- this. alert = Some ( ( err, alert) ) ;
213- return Poll :: Pending ;
214- }
215- Ok ( 0 ) | Err ( _) => {
216- return Poll :: Ready ( Err ( io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) )
217- }
218- Ok ( _) => {
219- this. alert = Some ( ( err, alert) ) ;
220- continue ;
221- }
222- } ;
223- }
224-
225- let mut reader = common:: SyncReadAdapter { io, cx } ;
226- match this. acceptor . read_tls ( & mut reader) {
227- Ok ( 0 ) => return Err ( io:: ErrorKind :: UnexpectedEof . into ( ) ) . into ( ) ,
228- Ok ( _) => { }
229- Err ( e) if e. kind ( ) == io:: ErrorKind :: WouldBlock => return Poll :: Pending ,
230- Err ( e) => return Err ( e) . into ( ) ,
231- }
232-
233- match this. acceptor . accept ( ) {
234- Ok ( Some ( accepted) ) => {
235- let io = this. io . take ( ) . unwrap ( ) ;
236- return Poll :: Ready ( Ok ( StartHandshake { accepted, io } ) ) ;
237- }
238- Ok ( None ) => { }
239- Err ( ( err, alert) ) => {
240- this. alert = Some ( ( err, alert) ) ;
241- }
242- }
243- }
244- }
245- }
246-
247- /// An incoming connection received through [`LazyConfigAcceptor`].
248- ///
249- /// This contains the generic `IO` asynchronous transport,
250- /// [`ClientHello`](rustls::server::ClientHello) data,
251- /// and all the state required to continue the TLS handshake (e.g. via
252- /// [`StartHandshake::into_stream`]).
253- #[ derive( Debug ) ]
254- pub struct StartHandshake < IO > {
255- accepted : rustls:: server:: Accepted ,
256- io : IO ,
257- }
258-
259- impl < IO > StartHandshake < IO >
260- where
261- IO : AsyncRead + AsyncWrite + Unpin ,
262- {
263- pub fn client_hello ( & self ) -> rustls:: server:: ClientHello < ' _ > {
264- self . accepted . client_hello ( )
265- }
266-
267- pub fn into_stream ( self , config : Arc < ServerConfig > ) -> Accept < IO > {
268- self . into_stream_with ( config, |_| ( ) )
269- }
270-
271- pub fn into_stream_with < F > ( self , config : Arc < ServerConfig > , f : F ) -> Accept < IO >
272- where
273- F : FnOnce ( & mut ServerConnection ) ,
274- {
275- let mut conn = match self . accepted . into_connection ( config) {
276- Ok ( conn) => conn,
277- Err ( ( error, alert) ) => {
278- return Accept ( MidHandshake :: SendAlert {
279- io : self . io ,
280- alert,
281- // TODO(eliza): should this really return an `io::Error`?
282- // Probably not...
283- error : io:: Error :: new ( io:: ErrorKind :: InvalidData , error) ,
284- } ) ;
285- }
286- } ;
287- f ( & mut conn) ;
288-
289- Accept ( MidHandshake :: Handshaking ( server:: TlsStream {
290- session : conn,
291- io : self . io ,
292- state : TlsState :: Stream ,
293- need_flush : false ,
294- } ) )
295- }
296- }
297-
298- /// Future returned from `TlsAcceptor::accept` which will resolve
299- /// once the accept handshake has finished.
300- pub struct Accept < IO > ( MidHandshake < server:: TlsStream < IO > > ) ;
301-
302- /// Like [Accept], but returns `IO` on failure.
303- pub struct FallibleAccept < IO > ( MidHandshake < server:: TlsStream < IO > > ) ;
304-
305- impl < IO > Accept < IO > {
306- #[ inline]
307- pub fn into_fallible ( self ) -> FallibleAccept < IO > {
308- FallibleAccept ( self . 0 )
309- }
310-
311- pub fn get_ref ( & self ) -> Option < & IO > {
312- match & self . 0 {
313- MidHandshake :: Handshaking ( sess) => Some ( sess. get_ref ( ) . 0 ) ,
314- MidHandshake :: SendAlert { io, .. } => Some ( io) ,
315- MidHandshake :: Error { io, .. } => Some ( io) ,
316- MidHandshake :: End => None ,
317- }
318- }
319-
320- pub fn get_mut ( & mut self ) -> Option < & mut IO > {
321- match & mut self . 0 {
322- MidHandshake :: Handshaking ( sess) => Some ( sess. get_mut ( ) . 0 ) ,
323- MidHandshake :: SendAlert { io, .. } => Some ( io) ,
324- MidHandshake :: Error { io, .. } => Some ( io) ,
325- MidHandshake :: End => None ,
326- }
327- }
328- }
329-
330- impl < IO : AsyncRead + AsyncWrite + Unpin > Future for Accept < IO > {
331- type Output = io:: Result < server:: TlsStream < IO > > ;
332-
333- #[ inline]
334- fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
335- Pin :: new ( & mut self . 0 ) . poll ( cx) . map_err ( |( err, _) | err)
336- }
337- }
338-
339- impl < IO : AsyncRead + AsyncWrite + Unpin > Future for FallibleAccept < IO > {
340- type Output = Result < server:: TlsStream < IO > , ( io:: Error , IO ) > ;
341-
342- #[ inline]
343- fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
344- Pin :: new ( & mut self . 0 ) . poll ( cx)
345- }
346- }
67+ pub use server:: { Accept , FallibleAccept , LazyConfigAcceptor , StartHandshake , TlsAcceptor } ;
34768
34869/// Unified TLS stream type
34970///
0 commit comments