#[macro_use]
extern crate log;
use std::collections::HashSet;
use std::io;
use std::net::{SocketAddr, UdpSocket};
use clap::clap_app;
fn main() {
env_logger::init();
let matches = clap_app!(secure_message_server =>
(version: env!("CARGO_PKG_VERSION"))
(about: "Relay server for Secure Message chat client.")
(@arg port: -p --port [number] "Listening port (default: 7573)")
)
.get_matches();
let port = matches.value_of("port").unwrap_or("7573").parse().unwrap();
let listen_addr = SocketAddr::new([0; 16].into(), port);
let socket = UdpSocket::bind(&listen_addr).expect("server listen");
let mut peers = HashSet::new();
let mut process_message = || -> io::Result<()> {
let (message, sender) = recv_from(&socket)?;
if peers.insert(sender) {
info!("new peer: {}", sender);
}
for peer in &peers {
socket.send_to(&message, peer)?;
}
Ok(())
};
info!("listening on port {}", port);
loop {
if let Err(e) = process_message() {
error!("failed to process message: {}", e);
break;
}
}
}
fn recv_from(socket: &UdpSocket) -> io::Result<(Vec<u8>, SocketAddr)> {
let mut message = vec![0; 65536];
let (length, sender) = socket.recv_from(&mut message)?;
message.truncate(length);
Ok((message, sender))
}