]> git.lizzy.rs Git - connect-rs.git/blob - src/tls/client.rs
1bb345bf242509c9a1d299882c2d69f29b101c90
[connect-rs.git] / src / tls / client.rs
1 use async_tls::TlsConnector;
2 use log::*;
3
4 use crate::Connection;
5 use async_std::net::{SocketAddr, TcpStream, ToSocketAddrs};
6 use async_tls::client;
7 use async_tls::server;
8 use futures::AsyncReadExt;
9
10 pub enum TlsConnectionMetadata {
11     Client {
12         local_addr: SocketAddr,
13         peer_addr: SocketAddr,
14         stream: client::TlsStream<TcpStream>,
15     },
16     Server {
17         local_addr: SocketAddr,
18         peer_addr: SocketAddr,
19         stream: server::TlsStream<TcpStream>,
20     },
21 }
22
23 impl Connection {
24     pub async fn tls_client<A: ToSocketAddrs + std::fmt::Display>(
25         ip_addrs: A,
26         domain: &str,
27         connector: TlsConnector,
28     ) -> anyhow::Result<Self> {
29         let stream = TcpStream::connect(&ip_addrs).await?;
30         info!("Established client TCP connection to {}", ip_addrs);
31         stream.set_nodelay(true)?;
32
33         let local_addr = stream.peer_addr()?;
34         let peer_addr = stream.peer_addr()?;
35
36         let encrypted_stream: client::TlsStream<TcpStream> = connector.connect(domain, stream).await?;
37         info!("Completed TLS handshake with {}", peer_addr);
38
39         Ok(Self::from(TlsConnectionMetadata::Client {
40             local_addr,
41             peer_addr,
42             stream: encrypted_stream,
43         }))
44     }
45 }
46
47 impl From<TlsConnectionMetadata> for Connection {
48     fn from(metadata: TlsConnectionMetadata) -> Self {
49         match metadata {
50             TlsConnectionMetadata::Client {
51                 local_addr,
52                 peer_addr,
53                 stream,
54             } => {
55                 let (read_stream, write_stream) = stream.split();
56
57                 Self::new(
58                     local_addr,
59                     peer_addr,
60                     Box::pin(read_stream),
61                     Box::pin(write_stream),
62                 )
63             }
64
65             TlsConnectionMetadata::Server {
66                 local_addr,
67                 peer_addr,
68                 stream,
69             } => {
70                 let (read_stream, write_stream) = stream.split();
71
72                 Self::new(
73                     local_addr,
74                     peer_addr,
75                     Box::pin(read_stream),
76                     Box::pin(write_stream),
77                 )
78             }
79         }
80     }
81 }