async_tls/
acceptor.rs

1use crate::common::tls_state::TlsState;
2use crate::server;
3
4use futures_io::{AsyncRead, AsyncWrite};
5use rustls::{ServerConfig, ServerConnection};
6use std::future::Future;
7use std::io;
8use std::pin::Pin;
9use std::sync::Arc;
10use std::task::{Context, Poll};
11
12/// The TLS accepting part. The acceptor drives
13/// the server side of the TLS handshake process. It works
14/// on any asynchronous stream.
15///
16/// It provides a simple interface (`accept`), returning a future
17/// that will resolve when the handshake process completed. On
18/// success, it will hand you an async `TLSStream`.
19///
20/// ## Example
21///
22/// See /examples/server for an example.
23#[derive(Clone)]
24pub struct TlsAcceptor {
25    inner: Arc<ServerConfig>,
26}
27
28impl TlsAcceptor {
29    /// Accept a client connections. `stream` can be any type implementing `AsyncRead` and `AsyncWrite`,
30    /// such as TcpStreams or Unix domain sockets.
31    ///
32    /// Otherwise, it will return a `Accept` Future, representing the Acceptance part of a
33    /// Tls handshake. It will resolve when the handshake is over.
34    #[inline]
35    pub fn accept<IO>(&self, stream: IO) -> Accept<IO>
36    where
37        IO: AsyncRead + AsyncWrite + Unpin,
38    {
39        self.accept_with(stream, |_| ())
40    }
41
42    // Currently private, as exposing ServerConnections exposes rusttls
43    fn accept_with<IO, F>(&self, stream: IO, f: F) -> Accept<IO>
44    where
45        IO: AsyncRead + AsyncWrite + Unpin,
46        F: FnOnce(&mut ServerConnection),
47    {
48        let mut conn = match ServerConnection::new(self.inner.clone()) {
49            Ok(conn) => conn,
50            Err(_) => {
51                return Accept(server::MidHandshake::End);
52            }
53        };
54
55        f(&mut conn);
56
57        Accept(server::MidHandshake::Handshaking(server::TlsStream {
58            conn,
59            io: stream,
60            state: TlsState::Stream,
61        }))
62    }
63}
64
65/// Future returned from `TlsAcceptor::accept` which will resolve
66/// once the accept handshake has finished.
67pub struct Accept<IO>(server::MidHandshake<IO>);
68
69impl<IO: AsyncRead + AsyncWrite + Unpin> Future for Accept<IO> {
70    type Output = io::Result<server::TlsStream<IO>>;
71
72    #[inline]
73    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
74        Pin::new(&mut self.0).poll(cx)
75    }
76}
77
78impl From<Arc<ServerConfig>> for TlsAcceptor {
79    fn from(inner: Arc<ServerConfig>) -> TlsAcceptor {
80        TlsAcceptor { inner }
81    }
82}
83
84impl From<ServerConfig> for TlsAcceptor {
85    fn from(inner: ServerConfig) -> TlsAcceptor {
86        TlsAcceptor {
87            inner: Arc::new(inner),
88        }
89    }
90}