diff --git a/splash.txt b/splash.txt new file mode 100644 index 0000000..6978e58 --- /dev/null +++ b/splash.txt @@ -0,0 +1,9 @@ +  ▗▆ ▇▄╴ ▊▗▍▍▖▏▄━╴ ▋╺▁▘▗▖▗▏▅▅▖▄▅▖▗▄▄╼▄▉┲▄▏ + ▗ ▂▃▃▂▂▃▂▁ ▝▏ ▌▌▖▌▌▎▊╵▂ ▗▂▇▊▌▎▎▊╻▃▉▋▂▋▍▎▎▎▉▗▗▍▍ +▗▏ ▗ ▝▏ ▌ ▇▇▇▇▇▆▆╴▆ ╴▆▆▇▇▆▆▊▁▁▘▆▆▇▆╴▆▇▆╴▆▆╴ +▋ ▊▏ ▗▆▏▗▆▎ ▌ ▊  +▝▏ ▊▁ ▇▇▁▇▇▏▁▌ ▌ ▗▄▄▄  + ▝ ▇▅▘▇▇▇▝▅▆ ▗▏ ▝▃▃▋ ▊┓▁▋╺▁▆▉▌▉▌▗▂▆▉▖▘╸▖▗╴▉▖▁▁▁▗┎ +  ▝▂ ▁▄╴ ▗▘▉▉ ▊▊▇▊▌┗▍▉▝▂▋▌▗▎▊▝▃╴▋▍ ▋▌▎▗▎▌▍ +  ╴▆▄▃▂▁▁▃▃▅▇ ▇ ▇ ▇ ▇ ▇▇ ▇▇▝▇ ▇ ▇▇ ▆▇▇▇▇▇ +[?25h \ No newline at end of file diff --git a/src/ctx.rs b/src/ctx.rs index 99fbcb0..0fed2d3 100644 --- a/src/ctx.rs +++ b/src/ctx.rs @@ -26,7 +26,7 @@ pub struct Context { pub messages: RwLock>, pub accounts: RwLock>, pub messages_offset: AtomicU64, - pub notifications: RwLock>>, + pub notifications: RwLock>>, // u32 - ip pub timeouts: RwLock>, } diff --git a/src/main.rs b/src/main.rs index af46597..798464a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,30 +1,16 @@ -use std::{ - error::Error, - fs, - io::{Read, Write}, - net::{SocketAddr, TcpListener}, - sync::Arc, - thread, -}; - -use log::{debug, info}; +use std::{fs, sync::Arc}; use clap::Parser; -use rustls::{ - ServerConfig, ServerConnection, StreamOwned, - pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}, -}; +use log::info; use crate::{ ctx::{Account, Context}, - rac::accept_rac_stream, - wrac::accept_wrac_stream, + proto::run_listener, }; -mod ctx; -mod logic; -mod rac; -mod wrac; +pub mod ctx; +pub mod logic; +pub mod proto; fn load_accounts(accounts_file: Option) -> Vec { if let Some(accounts_file) = accounts_file.clone() { @@ -55,100 +41,9 @@ fn load_messages(messages_file: Option) -> Vec { } } -fn accept_stream( - stream: impl Read + Write, - addr: SocketAddr, - ctx: Arc, -) -> Result<(), Box> { - if ctx.args.enable_wrac { - accept_wrac_stream(stream, addr, ctx)?; - } else { - accept_rac_stream(stream, addr, ctx)?; - } - - Ok(()) -} - -fn run_normal_listener(ctx: Arc) { - let listener = - TcpListener::bind(&ctx.args.host).expect("error trying bind to the provided addr"); - - for stream in listener.incoming() { - let Ok(stream) = stream else { continue }; - - let ctx = ctx.clone(); - - thread::spawn(move || { - let Ok(addr) = stream.peer_addr() else { - return; - }; - match accept_stream(stream, addr, ctx) { - Ok(_) => {} - Err(e) => { - debug!("{}", e) - } - } - }); - } -} - -fn run_secure_listener(ctx: Arc) { - let listener = - TcpListener::bind(&ctx.args.host).expect("error trying bind to the provided addr"); - - let server_config = Arc::new( - ServerConfig::builder() - .with_no_client_auth() - .with_single_cert( - CertificateDer::pem_file_iter( - ctx.args.ssl_cert.clone().expect("--ssl-cert is required"), - ) - .unwrap() - .map(|cert| cert.unwrap()) - .collect(), - PrivateKeyDer::from_pem_file( - ctx.args.ssl_key.clone().expect("--ssl-key is required"), - ) - .unwrap(), - ) - .unwrap(), - ); - - for stream in listener.incoming() { - let Ok(stream) = stream else { continue }; - - let ctx = ctx.clone(); - let server_config = server_config.clone(); - - thread::spawn(move || { - let Ok(addr) = stream.peer_addr() else { - return; - }; - - let Ok(connection) = ServerConnection::new(server_config) else { - return; - }; - let mut stream = StreamOwned::new(connection, stream); - - while stream.conn.is_handshaking() { - let Ok(_) = stream.conn.complete_io(&mut stream.sock) else { - return; - }; - } - - match accept_stream(stream, addr, ctx) { - Ok(_) => {} - Err(e) => { - debug!("{}", e) - } - } - }); - } -} - #[derive(Parser, Debug)] #[command(version)] -struct Args { +pub struct Args { /// Server host #[arg(short = 'H', long)] host: String, @@ -219,9 +114,5 @@ fn main() { info!("Server started on {}", &args.host); - if args.enable_ssl { - run_secure_listener(context); - } else { - run_normal_listener(context); - } + run_listener(context); } diff --git a/src/proto/mod.rs b/src/proto/mod.rs new file mode 100644 index 0000000..1cfec7d --- /dev/null +++ b/src/proto/mod.rs @@ -0,0 +1,120 @@ +use std::{ + error::Error, + io::{Read, Write}, + net::{SocketAddr, TcpListener}, + sync::Arc, + thread, +}; + +use log::debug; +use rustls::{ + ServerConfig, ServerConnection, StreamOwned, + pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}, +}; + +use crate::{ + ctx::Context, + proto::{rac::accept_rac_stream, wrac::accept_wrac_stream}, +}; + +pub mod rac; +pub mod wrac; + +fn accept_stream( + stream: impl Read + Write, + addr: SocketAddr, + ctx: Arc, +) -> Result<(), Box> { + if ctx.args.enable_wrac { + accept_wrac_stream(stream, addr, ctx)?; + } else { + accept_rac_stream(stream, addr, ctx)?; + } + + Ok(()) +} + +fn run_normal_listener(ctx: Arc) { + let listener = + TcpListener::bind(&ctx.args.host).expect("error trying bind to the provided addr"); + + for stream in listener.incoming() { + let Ok(stream) = stream else { continue }; + + let ctx = ctx.clone(); + + thread::spawn(move || { + let Ok(addr) = stream.peer_addr() else { + return; + }; + match accept_stream(stream, addr, ctx) { + Ok(_) => {} + Err(e) => { + debug!("{}", e) + } + } + }); + } +} + +fn run_secure_listener(ctx: Arc) { + let listener = + TcpListener::bind(&ctx.args.host).expect("error trying bind to the provided addr"); + + let server_config = Arc::new( + ServerConfig::builder() + .with_no_client_auth() + .with_single_cert( + CertificateDer::pem_file_iter( + ctx.args.ssl_cert.clone().expect("--ssl-cert is required"), + ) + .unwrap() + .map(|cert| cert.unwrap()) + .collect(), + PrivateKeyDer::from_pem_file( + ctx.args.ssl_key.clone().expect("--ssl-key is required"), + ) + .unwrap(), + ) + .unwrap(), + ); + + for stream in listener.incoming() { + let Ok(stream) = stream else { continue }; + + let ctx = ctx.clone(); + let server_config = server_config.clone(); + + thread::spawn(move || { + let Ok(addr) = stream.peer_addr() else { + return; + }; + + let Ok(connection) = ServerConnection::new(server_config) else { + return; + }; + let mut stream = StreamOwned::new(connection, stream); + + while stream.conn.is_handshaking() { + let Ok(_) = stream.conn.complete_io(&mut stream.sock) else { + return; + }; + } + + match accept_stream(stream, addr, ctx) { + Ok(_) => {} + Err(e) => { + debug!("{}", e) + } + } + }); + } +} + +pub fn run_listener(ctx: Arc) { + if ctx.args.enable_ssl { + run_secure_listener(ctx); + } else { + run_normal_listener(ctx); + } +} diff --git a/src/rac.rs b/src/proto/rac.rs similarity index 93% rename from src/rac.rs rename to src/proto/rac.rs index 862449f..de74f6f 100644 --- a/src/rac.rs +++ b/src/proto/rac.rs @@ -38,13 +38,13 @@ pub fn accept_rac_stream( )?)?; } } else if buf[0] == 0x01 { - let mut buf = vec![0; 1024]; + let mut buf = vec![0; ctx.args.message_limit]; let size = stream.read(&mut buf)?; buf.truncate(size); on_send_message(ctx.clone(), addr.clone(), buf)?; } else if buf[0] == 0x02 { - let mut buf = vec![0; 8192]; + let mut buf = vec![0; ctx.args.message_limit + 2 + 512]; // FIXME: softcode this (512 = name + password) let size = stream.read(&mut buf)?; buf.truncate(size); diff --git a/src/wrac.rs b/src/proto/wrac.rs similarity index 100% rename from src/wrac.rs rename to src/proto/wrac.rs