diff --git a/Cargo.lock b/Cargo.lock index d3766b5..741a286 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.19" @@ -177,6 +192,12 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + [[package]] name = "bitflags" version = "2.9.1" @@ -196,12 +217,41 @@ dependencies = [ "piper", ] +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "cc" +version = "1.2.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + [[package]] name = "clap" version = "4.5.41" @@ -257,6 +307,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -325,17 +381,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "heck" version = "0.5.0" @@ -348,12 +393,46 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "libc" version = "0.2.174" @@ -366,6 +445,21 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -378,6 +472,103 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +[[package]] +name = "orx-concurrent-iter" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c7567a3f51c144ea6e55e0c7e4a26039d22d8948c268f5244c539aa84d2e67" +dependencies = [ + "orx-iterable", + "orx-pseudo-default", +] + +[[package]] +name = "orx-concurrent-option" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "842a5c05d6f02368d1cdfebec87ae6e2277ca0cf544ab3778e6f2e6c5c947da3" + +[[package]] +name = "orx-concurrent-vec" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384cd6cd25e3cf031091ca7cfe947a59be14e62e1a28480a5e92d46b792b6303" +dependencies = [ + "orx-concurrent-option", + "orx-fixed-vec", + "orx-pinned-concurrent-col", + "orx-pinned-vec", + "orx-pseudo-default", + "orx-split-vec", +] + +[[package]] +name = "orx-fixed-vec" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf1694c28d604fe9139aeeec1ce20e091c1e7a58beb0e444f23b2cd95ed781e0" +dependencies = [ + "orx-concurrent-iter", + "orx-iterable", + "orx-pinned-vec", + "orx-pseudo-default", +] + +[[package]] +name = "orx-iterable" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa2cb3f82a187c68835faac9cf03faaee70b93f4da3b85515ac1b4c6f8a432d" +dependencies = [ + "orx-self-or", +] + +[[package]] +name = "orx-pinned-concurrent-col" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a78c53b0f313be2663e525cf8cdba2e66e58b755247dc920bd8eb324071432" +dependencies = [ + "orx-fixed-vec", + "orx-pinned-vec", + "orx-pseudo-default", + "orx-split-vec", +] + +[[package]] +name = "orx-pinned-vec" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2707ef8045673419bec5b92a3073b0066fed6d42b1f1be07aa50201fd3cb4e92" +dependencies = [ + "orx-iterable", + "orx-pseudo-default", +] + +[[package]] +name = "orx-pseudo-default" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34eaace9ae01f7025804fbca40ec45b87c19ba0328d97195e01c6135897762a8" + +[[package]] +name = "orx-self-or" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8e35dfe18921e475b9861266fd58a5ecfd681161f242d24a9e2d1e07fbc28" + +[[package]] +name = "orx-split-vec" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20887c6f134a4346e96db3c0235576b6a7ff3b10030f3a64a0d306235ee9adfe" +dependencies = [ + "orx-concurrent-iter", + "orx-iterable", + "orx-pinned-vec", + "orx-pseudo-default", +] + [[package]] name = "parking" version = "2.2.1" @@ -388,8 +579,10 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" name = "pea_2_pea" version = "0.1.0" dependencies = [ + "chrono", "clap", - "rand", + "orx-concurrent-vec", + "readonly", "smol", "tappers", ] @@ -425,15 +618,6 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "proc-macro2" version = "1.0.95" @@ -453,33 +637,14 @@ dependencies = [ ] [[package]] -name = "rand" -version = "0.8.5" +name = "readonly" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "f2a62d85ed81ca5305dc544bd42c8804c5060b78ffa5ad3c64b0fb6a8c13d062" dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -495,6 +660,18 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.5" @@ -568,10 +745,121 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" +name = "wasm-bindgen" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] [[package]] name = "windows-sys" @@ -718,23 +1006,3 @@ name = "windows_x86_64_msvc" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "zerocopy" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/Cargo.toml b/Cargo.toml index 0b7389e..ffdb9ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,9 @@ path = "src/client/main.rs" [dependencies] +chrono = "0.4.41" clap = { version = "4.5.41", features = ["derive"] } -rand = "0.8.5" +orx-concurrent-vec = "3.6.0" +readonly = "0.2.13" smol = "2.0.2" tappers = "0.4.2" diff --git a/src/client/main.rs b/src/client/main.rs index 4d04bfb..f06a64f 100644 --- a/src/client/main.rs +++ b/src/client/main.rs @@ -1,7 +1,7 @@ use pea_2_pea::SERVER_PORT; use std::{ - io::{ErrorKind, Read, Write}, + io::{Error, ErrorKind, Read, Write}, net::UdpSocket, process::exit, time::Duration, @@ -15,35 +15,35 @@ struct Cli { #[arg(help = "registrar ip address or hostname")] registrar: String, + #[arg(short = 'p', long = "registrar-port")] + #[arg(help = format!("optional Port number for the registrar service (1-65535) Default: {}", SERVER_PORT))] + registrar_port: Option, + + #[arg(short = 'n', long = "network-id")] + #[arg(help = "your virtual network id that allows other people to connect to you")] + network_id: String, + + #[arg(short = 'P', long = "password")] + #[arg( + help = "encryption password for your virtual network if not provided transmitions will be unencrypted" + )] + password: Option, + #[arg(short = 'v', long = "verbose")] verbose: bool, #[arg(short = 'V', long = "version")] version: bool, - - #[arg(short = 'p', long = "registrar-port")] - #[arg(help = format!("Port number for the registrar service (1-65535) Default: {}", SERVER_PORT))] - registrar_port: Option, - - #[arg(short = 'P', long = "bind-port")] - bind_port: Option, } fn main() -> std::io::Result<()> { let cli = ::parse(); { let socket: UdpSocket = (|| -> std::io::Result { - let mut port: u16; - match cli.bind_port { - Some(port_proveded) => port = port_proveded, - None => port = 59999, // Magic number - } - loop { - port += 1; - match UdpSocket::bind(format!("0.0.0.0:{}", port)) { - Ok(socket) => return Ok(socket), - Err(_) => continue, // Retry on error - } + match UdpSocket::bind("0.0.0.0:0") { + // bind to OS assigned random port + Ok(socket) => return Ok(socket), + Err(e) => Err(e), // exit on error } })() .expect("Failed to bind to any available port"); @@ -52,12 +52,13 @@ fn main() -> std::io::Result<()> { // send query request to get server public key let server_port: u16 = (|| -> u16 { - match cli.bind_port { + match cli.registrar_port { Some(port_proveded) => return port_proveded, None => return pea_2_pea::SERVER_PORT, } })(); + #[allow(non_snake_case)] // i think this is valid snake case but rustc doesnt think so let server_SocketAddr: core::net::SocketAddr = format!("{}:{}", cli.registrar, server_port) .parse() .unwrap(); diff --git a/src/lib.rs b/src/lib.rs index d5c8b7a..43daedf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,10 +6,25 @@ pub const RSA_SIZE: usize = 2048; #[repr(u8)] pub enum ServerMethods { - QUERY = 0, + QUERY = 0, // return IP and port of the client REGISTER = 1, GET = 2, HEARTBEAT = 3, } +pub enum ServerResponse { + // avoid 0 from empty buffers + OK = 1, + GENERAL_ERROR = 255, + ID_EXISTS = 254, + ID_DOESNT_EXIST = 253, // both error since sometimes it is the problem that the id exist and somethimes problem is that is doesn't +} + +pub enum RegisterRequestDataPositions { + ENCRYPTED = 1, // this feeld should be 0 if not encrypted + ID_LEN = 2, + SOCKADDR_LEN = 3, + DATA = 4, // after this there will be id and sockaddr in string or encrypted form after +} + pub mod shared; diff --git a/src/server/main.rs b/src/server/main.rs index 917f3bb..1d6ae32 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -1,6 +1,13 @@ mod net; -use std::{net::UdpSocket, process::exit, sync::Arc}; +mod types; +mod utils; +use std::{ + net::UdpSocket, + process::exit, + sync::{Arc, RwLock}, +}; +use orx_concurrent_vec::ConcurrentVec; fn main() -> std::io::Result<()> { { let socket: Arc = Arc::new( @@ -14,13 +21,22 @@ fn main() -> std::io::Result<()> { .expect("Failed to bind to any available port"), ); + let registration_vector: Arc> = + Arc::new(orx_concurrent_vec::ConcurrentVec::new()); + let mut buf: [u8; pea_2_pea::BUFFER_SIZE] = [0; pea_2_pea::BUFFER_SIZE]; smol::block_on(async { loop { match socket.recv_from(&mut buf) { Ok((data_length, src)) => { - smol::spawn(net::handle_request(buf, socket.clone(), src, data_length)) - .detach(); + smol::spawn(net::handle_request( + buf, + socket.clone(), + src, + data_length, + registration_vector.clone(), + )) + .detach(); } Err(e) => { eprintln!("Error receiving data: {}", e); diff --git a/src/server/net.rs b/src/server/net.rs index e88a8b1..697ec81 100644 --- a/src/server/net.rs +++ b/src/server/net.rs @@ -1,19 +1,24 @@ +use super::types; +use super::utils; +use orx_concurrent_vec::ConcurrentVec; +use pea_2_pea::*; + +use std::sync::Arc; pub async fn handle_request( - buf: [u8; pea_2_pea::BUFFER_SIZE], + buf: [u8; BUFFER_SIZE], socket: std::sync::Arc, src: core::net::SocketAddr, data_len: usize, + registration_vector: Arc>, ) { - let mut rng: rand::prelude::ThreadRng = rand::thread_rng(); - match buf[0] { - x if x == pea_2_pea::ServerMethods::QUERY as u8 => { + x if x == ServerMethods::QUERY as u8 => { #[cfg(debug_assertions)] eprintln!("QUERY method"); let client_sock_addr_str: String = src.to_string(); let mut send_vec: Vec = client_sock_addr_str.into(); - send_vec.insert(0, pea_2_pea::ServerMethods::QUERY as u8); + send_vec.insert(0, ServerMethods::QUERY as u8); match socket.send_to(&send_vec, &src) { Ok(s) => { @@ -26,15 +31,53 @@ pub async fn handle_request( } } - x if x == pea_2_pea::ServerMethods::GET as u8 => { + x if x == ServerMethods::GET as u8 => { #[cfg(debug_assertions)] println!("GET method"); } - x if x == pea_2_pea::ServerMethods::REGISTER as u8 => { + x if x == ServerMethods::REGISTER as u8 => { #[cfg(debug_assertions)] println!("REGISTER method"); + let encrypted: bool = buf[RegisterRequestDataPositions::ENCRYPTED as usize] != 0; + + //read lenght of sockaddr + // rustc be like RUST HAS NO TERNARY OPERATON USE if-else + let len_id: u8 = if buf[RegisterRequestDataPositions::ID_LEN as usize] != 0 { + buf[RegisterRequestDataPositions::ID_LEN as usize] + } else { + return; + }; + + let sock_addr_len: u8 = if buf[RegisterRequestDataPositions::SOCKADDR_LEN as usize] != 0 + { + buf[RegisterRequestDataPositions::SOCKADDR_LEN as usize] + } else { + return; + }; + + registration_vector.push(types::Registration::new( + match std::str::from_utf8( + &buf[(RegisterRequestDataPositions::DATA as usize) + ..(len_id as usize) + (RegisterRequestDataPositions::DATA as usize)], + ) { + Ok(s) => s.to_string(), + Err(e) => { + eprint!("id to utf-8 failed: {}", e); + utils::send_general_error_to_client(src, e, socket); + return; + } + }, + buf[(len_id as usize) + (RegisterRequestDataPositions::DATA as usize) + ..(len_id as usize) + + (RegisterRequestDataPositions::DATA as usize) + + (sock_addr_len as usize)] + .to_vec(), + encrypted, + chrono::Utc::now().timestamp(), + )); } - x if x == pea_2_pea::ServerMethods::HEARTBEAT as u8 => { + + x if x == ServerMethods::HEARTBEAT as u8 => { #[cfg(debug_assertions)] println!("HEARTBEAT method"); } diff --git a/src/server/types.rs b/src/server/types.rs new file mode 100644 index 0000000..7dd8336 --- /dev/null +++ b/src/server/types.rs @@ -0,0 +1,96 @@ +use std::sync::{Arc, atomic::Ordering}; + +#[readonly::make] +pub struct Client { + #[readonly] + pub client_sock_addr: Vec, + pub last_heart_beat: i64, +} + +impl Client { + pub fn new(client_addr: Vec, heart_beat: i64) -> Self { + Client { + client_sock_addr: client_addr, + last_heart_beat: heart_beat, + } + } +} + +#[readonly::make] +pub struct Registration { + #[readonly] + pub net_id: String, + pub clients: Vec, + #[readonly] + pub encrypted: bool, + pub last_heart_beat: i64, +} + +impl Registration { + pub fn new(net_id: String, client_addr: Vec, encrypted: bool, heart_beat: i64) -> Self { + Registration { + net_id: net_id, + clients: vec![Client::new(client_addr, heart_beat)], + encrypted, + last_heart_beat: heart_beat, + } + } +} + +pub struct BatchLock { + inner: std::sync::Mutex, // true = blocking new locks + condvar: std::sync::Condvar, + active_count: std::sync::atomic::AtomicUsize, +} + +pub struct LockGuard { + lock: Arc, +} + +impl BatchLock { + pub fn new() -> Arc { + Arc::new(BatchLock { + inner: std::sync::Mutex::new(false), + condvar: std::sync::Condvar::new(), + active_count: std::sync::atomic::AtomicUsize::new(0), + }) + } + + // Acquire a lock (blocks if waiting for all to unlock) + pub fn lock(self: &Arc) -> LockGuard { + let mut blocking = self.inner.lock().unwrap(); + + // Wait while new locks are blocked + while *blocking { + blocking = self.condvar.wait(blocking).unwrap(); + } + + self.active_count.fetch_add(1, Ordering::SeqCst); + + LockGuard { + lock: Arc::clone(self), + } + } + + // Block new locks and wait for all current locks to finish + pub fn wait_all_unlock(self: &Arc) { + // Block new locks + *self.inner.lock().unwrap() = true; + + // Wait for all active locks to finish + while self.active_count.load(Ordering::SeqCst) > 0 { + std::thread::sleep(std::time::Duration::from_millis(1)); + } + + // Allow new locks again + *self.inner.lock().unwrap() = false; + self.condvar.notify_all(); + } +} + +impl Drop for LockGuard { + fn drop(&mut self) { + // Automatically release lock when guard is dropped + self.lock.active_count.fetch_sub(1, Ordering::SeqCst); + } +} diff --git a/src/server/utils.rs b/src/server/utils.rs new file mode 100644 index 0000000..1dd2be2 --- /dev/null +++ b/src/server/utils.rs @@ -0,0 +1,14 @@ +use pea_2_pea::*; +pub fn send_general_error_to_client( + dst: core::net::SocketAddr, + e: T, + socket: std::sync::Arc, +) { + let mut resp_buf: Box<[u8]> = vec![0; e.to_string().len() + 1].into_boxed_slice(); + + resp_buf[0] = ServerResponse::GENERAL_ERROR as u8; // set 1st byte to ERROR + resp_buf[1..1 + e.to_string().len()] // send error text to client + .copy_from_slice(e.to_string().as_bytes()); + + let _ = socket.send_to(&[ServerResponse::GENERAL_ERROR as u8], dst); +}