tls_api_openssl/
handshake.rs

1//! Handshake future
2
3use std::future::Future;
4use std::mem;
5use std::pin::Pin;
6use std::result;
7use std::task::Context;
8use std::task::Poll;
9
10use tls_api::async_as_sync::AsyncIoAsSyncIo;
11use tls_api::spi::save_context;
12use tls_api::AsyncSocket;
13
14use crate::stream::OpenSSLStream;
15
16pub(crate) enum HandshakeFuture<F, S: Unpin> {
17    Initial(F, AsyncIoAsSyncIo<S>),
18    MidHandshake(openssl::ssl::MidHandshakeSslStream<AsyncIoAsSyncIo<S>>),
19    Done,
20}
21
22impl<F, S> Future for HandshakeFuture<F, S>
23where
24    S: AsyncSocket,
25    F: FnOnce(
26        AsyncIoAsSyncIo<S>,
27    ) -> result::Result<
28        openssl::ssl::SslStream<AsyncIoAsSyncIo<S>>,
29        openssl::ssl::HandshakeError<AsyncIoAsSyncIo<S>>,
30    >,
31    Self: Unpin,
32{
33    type Output = anyhow::Result<crate::TlsStream<S>>;
34
35    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
36        save_context(cx, || {
37            let self_mut = self.get_mut();
38            match mem::replace(self_mut, HandshakeFuture::Done) {
39                HandshakeFuture::Initial(f, stream) => match f(stream) {
40                    Ok(stream) => Poll::Ready(Ok(crate::TlsStream::new(OpenSSLStream(stream)))),
41                    Err(openssl::ssl::HandshakeError::WouldBlock(mid)) => {
42                        *self_mut = HandshakeFuture::MidHandshake(mid);
43                        Poll::Pending
44                    }
45                    Err(openssl::ssl::HandshakeError::Failure(e)) => {
46                        Poll::Ready(Err(anyhow::Error::new(e.into_error())))
47                    }
48                    Err(openssl::ssl::HandshakeError::SetupFailure(e)) => {
49                        Poll::Ready(Err(anyhow::Error::new(e)))
50                    }
51                },
52                HandshakeFuture::MidHandshake(stream) => match stream.handshake() {
53                    Ok(stream) => Poll::Ready(Ok(crate::TlsStream::new(OpenSSLStream(stream)))),
54                    Err(openssl::ssl::HandshakeError::WouldBlock(mid)) => {
55                        *self_mut = HandshakeFuture::MidHandshake(mid);
56                        Poll::Pending
57                    }
58                    Err(openssl::ssl::HandshakeError::Failure(e)) => {
59                        Poll::Ready(Err(anyhow::Error::new(e.into_error())))
60                    }
61                    Err(openssl::ssl::HandshakeError::SetupFailure(e)) => {
62                        Poll::Ready(Err(anyhow::Error::new(e)))
63                    }
64                },
65                HandshakeFuture::Done => panic!("Future must not be polled after ready"),
66            }
67        })
68    }
69}