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