mod argument;
mod connection;
mod log;
use argument::Argument;
use log::Log;
use clap::Parser;
use native_tls::{Identity, TlsAcceptor};
use std::{
fs::File,
io::{Read, Result},
net::TcpListener,
sync::Arc,
thread,
};
fn main() -> Result<()> {
let argument = Argument::parse();
let mut pfx = vec![];
File::open(argument.identity)
.unwrap()
.read_to_end(&mut pfx)
.unwrap();
let acceptor = Arc::new(
TlsAcceptor::new(Identity::from_pkcs12(&pfx, &argument.password).unwrap()).unwrap(),
);
let listener = TcpListener::bind(&argument.address)?;
log::notice(format!("Server listening on `{}`", argument.address));
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let log = Log::new(stream.peer_addr()?.to_string());
log.notice("New client connected".to_string());
thread::spawn({
let acceptor = acceptor.clone();
move || {
connection::handle(acceptor.accept(stream).unwrap(), log);
}
});
}
Err(e) => log::error(format!("Failed to accept connection: `{e}`")),
}
}
Ok(())
}