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};
9 use std::io::BufReader;
12 async fn main() -> anyhow::Result<()> {
15 // Get ip address from cmd line args
16 let (ip_address, cert_path, key_path) = parse_args();
18 let certs = certs(&mut BufReader::new(File::open(cert_path)?))
19 .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))?;
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"))?;
24 let mut config = ServerConfig::new(NoClientAuth::new());
26 .set_single_cert(certs, keys.remove(0))
27 .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
30 let mut server = TlsListener::bind(ip_address, config.into()).await?;
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());
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();
44 String::from_utf8(data).expect("could not build String from payload bytes");
45 info!("Received a message \"{}\" from {}", msg, conn.peer_addr());
47 let reply = ConnectDatagram::new(envelope.recipient(), msg.into_bytes())
48 .expect("could not construct new datagram from built String");
53 .expect("Could not send message back to source connection");
54 info!("Sent message back to original sender");
56 // if recipient is anything else, we just send it back
58 "Received a message for unknown recipient {} from {}",
66 .expect("Could not send message back to source connection");
67 info!("Sent message back to original sender");
76 fn parse_args() -> (String, String, String) {
77 let args: Vec<String> = env::args().collect();
79 let ip_address = match args.get(1) {
82 error!("Need to pass IP address to connect to as first command line argument");
87 let cert_path = match args.get(2) {
90 error!("Need to pass path to cert file as second command line argument");
95 let key_path = match args.get(3) {
98 error!("Need to pass path to key file as third command line argument");
104 ip_address.to_string(),
105 cert_path.to_string(),
106 key_path.to_string(),