1 use crate::tls::TlsConnectionMetadata;
3 use async_std::net::{SocketAddr, TcpListener, TcpStream, ToSocketAddrs};
4 use async_std::pin::Pin;
5 use async_std::task::{Context, Poll};
6 use async_stream::stream;
7 use async_tls::{server::TlsStream, TlsAcceptor};
9 use futures_lite::StreamExt;
12 /// Listens on a bound socket for incoming TLS connections to be handled as independent
15 /// Implements the [`Stream`] trait to asynchronously accept incoming TLS connections.
19 /// Please see the [tls-echo-server](https://github.com/sachanganesh/connect-rs/blob/main/examples/tls-echo-server/src/main.rs)
20 /// example program for a more thorough showcase.
25 /// let mut server = TlsListener::bind("127.0.0.1:3456", config.into()).await?;
27 /// // wait for a connection to come in and be accepted
28 /// while let Some(mut conn) = server.next().await {
29 /// // do something with connection
33 pub struct TlsListener {
34 local_addrs: SocketAddr,
39 Option<(SocketAddr, Result<TlsStream<TcpStream>, std::io::Error>)>,
45 // listener: TcpListener,
46 // acceptor: TlsAcceptor,
50 /// Creates a [`TlsListener`] by binding to an IP address and port and listens for incoming TLS
51 /// connections that have successfully been accepted.
58 /// let mut server = TlsListener::bind("127.0.0.1:3456", config.into()).await?;
60 pub async fn bind<A: ToSocketAddrs + std::fmt::Display>(
62 acceptor: TlsAcceptor,
63 ) -> anyhow::Result<Self> {
64 let listener = TcpListener::bind(&ip_addrs).await?;
65 info!("Started TLS server at {}", &ip_addrs);
67 let local_addrs = listener.local_addr()?;
69 let stream = Box::pin(stream! {
71 yield match listener.incoming().next().await {
72 Some(Ok(tcp_stream)) => {
73 let peer_addr = tcp_stream
75 .expect("Could not retrieve peer IP address");
76 debug!("Received connection attempt from {}", peer_addr);
78 Some(Some((peer_addr, acceptor.accept(tcp_stream).await)))
83 "Encountered error when trying to accept new connection {}",
102 // /// Creates a [`Connection`] for the next `accept`ed TCP connection at the bound socket.
109 // /// let mut server = TlsListener::bind("127.0.0.1:3456", config.into()).await?;
110 // /// while let Some(mut conn) = server.next().await {
111 // /// // do something with connection
114 // pub async fn accept(&self) -> anyhow::Result<Connection> {
115 // let (tcp_stream, peer_addr) = self.listener.accept().await?;
116 // debug!("Received connection attempt from {}", peer_addr);
118 // match self.acceptor.accept(tcp_stream).await {
119 // Ok(tls_stream) => {
120 // debug!("Completed TLS handshake with {}", peer_addr);
121 // Ok(Connection::from(TlsConnectionMetadata::Listener {
122 // local_addr: self.local_addrs.clone(),
124 // stream: tls_stream,
129 // warn!("Could not encrypt connection with TLS from {}", peer_addr);
130 // Err(anyhow::Error::new(e))
136 impl Stream for TlsListener {
137 type Item = Connection;
139 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
140 match self.conn_stream.poll_next(cx) {
141 Poll::Ready(Some(Some(Some((peer_addr, Ok(tls_stream)))))) => {
142 debug!("Completed TLS handshake with {}", peer_addr);
143 Poll::Ready(Some(Connection::from(TlsConnectionMetadata::Listener {
144 local_addr: self.local_addrs.clone(),
150 Poll::Ready(Some(Some(Some((peer_addr, Err(err)))))) => {
152 "Could not encrypt connection with TLS from {}: {}",
158 Poll::Pending => Poll::Pending,
160 _ => Poll::Ready(None),