]> git.lizzy.rs Git - connect-rs.git/blob - examples/tls-echo-server/src/main.rs
2a9abc8eb79afe229c583232973ede8d0f64e1a5
[connect-rs.git] / examples / tls-echo-server / src / main.rs
1 use async_std::{io, task};
2 use connect::tls::rustls::internal::pemfile::{certs, rsa_private_keys};
3 use connect::tls::rustls::{NoClientAuth, ServerConfig};
4 use connect::tls::TlsListener;
5 use connect::{ConnectDatagram, SinkExt, StreamExt};
6 use log::*;
7 use std::env;
8 use std::fs::File;
9 use std::io::BufReader;
10
11 #[async_std::main]
12 async fn main() -> anyhow::Result<()> {
13     env_logger::init();
14
15     // Get ip address from cmd line args
16     let (ip_address, cert_path, key_path) = parse_args();
17
18     let certs = certs(&mut BufReader::new(File::open(cert_path)?))
19         .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))?;
20
21     let mut keys = rsa_private_keys(&mut BufReader::new(File::open(key_path)?))
22         .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))?;
23
24     let mut config = ServerConfig::new(NoClientAuth::new());
25     config
26         .set_single_cert(certs, keys.remove(0))
27         .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
28
29     // create a server
30     let mut server = TlsListener::bind(ip_address, config.into()).await?;
31
32     // handle server connections
33     // wait for a connection to come in and be accepted
34     while let Some(mut conn) = server.next().await {
35         info!("Handling connection from {}", conn.peer_addr());
36
37         task::spawn(async move {
38             while let Some(mut envelope) = conn.reader().next().await {
39                 // handle message based on intended recipient
40                 if envelope.recipient() == 65535 {
41                     // if recipient is 65535, we do custom processing
42                     let data = envelope.take_data().unwrap();
43                     let msg =
44                         String::from_utf8(data).expect("could not build String from payload bytes");
45                     info!("Received a message \"{}\" from {}", msg, conn.peer_addr());
46
47                     let reply = ConnectDatagram::new(envelope.recipient(), msg.into_bytes())
48                         .expect("could not construct new datagram from built String");
49
50                     conn.writer()
51                         .send(reply)
52                         .await
53                         .expect("Could not send message back to source connection");
54                     info!("Sent message back to original sender");
55                 } else {
56                     // if recipient is anything else, we just send it back
57                     warn!(
58                         "Received a message for unknown recipient {} from {}",
59                         envelope.recipient(),
60                         conn.peer_addr()
61                     );
62
63                     conn.writer()
64                         .send(envelope)
65                         .await
66                         .expect("Could not send message back to source connection");
67                     info!("Sent message back to original sender");
68                 }
69             }
70         });
71     }
72
73     Ok(())
74 }
75
76 fn parse_args() -> (String, String, String) {
77     let args: Vec<String> = env::args().collect();
78
79     let ip_address = match args.get(1) {
80         Some(addr) => addr,
81         None => {
82             error!("Need to pass IP address to connect to as first command line argument");
83             panic!();
84         }
85     };
86
87     let cert_path = match args.get(2) {
88         Some(d) => d,
89         None => {
90             error!("Need to pass path to cert file as second command line argument");
91             panic!();
92         }
93     };
94
95     let key_path = match args.get(3) {
96         Some(d) => d,
97         None => {
98             error!("Need to pass path to key file as third command line argument");
99             panic!();
100         }
101     };
102
103     (
104         ip_address.to_string(),
105         cert_path.to_string(),
106         key_path.to_string(),
107     )
108 }