diff --git a/Cargo.lock b/Cargo.lock index dd6c5cc..0b54a75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "libc" version = "0.2.109" @@ -37,6 +48,7 @@ name = "lookaround" version = "0.1.0" dependencies = [ "mac_address", + "rand", "thiserror", ] @@ -72,6 +84,12 @@ dependencies = [ "memoffset", ] +[[package]] +name = "ppv-lite86" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" + [[package]] name = "proc-macro2" version = "1.0.32" @@ -90,6 +108,46 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core", +] + [[package]] name = "syn" version = "1.0.82" @@ -127,6 +185,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 133a946..1e8cd78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] mac_address = "1.1.2" +rand = "0.8.4" thiserror = "1.0.30" [profile.release] diff --git a/src/main.rs b/src/main.rs index 9048a12..971d571 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,14 +87,26 @@ fn main () -> Result <(), AppError> { } fn client () -> Result <(), AppError> { + use rand::RngCore; + let params = CommonParams::default (); let socket = UdpSocket::bind ("0.0.0.0:0")?; socket.join_multicast_v4 (¶ms.multicast_addr, &([0u8, 0, 0, 0].into ()))?; socket.set_read_timeout (Some (Duration::from_millis (1_000)))?; - let msg = Message::Request (None).to_vec ()?; - socket.send_to (&msg, (params.multicast_addr, params.server_port))?; + let mut idem_id = [0u8; 8]; + rand::thread_rng ().fill_bytes (&mut idem_id); + + let msg = Message::Request { + idem_id, + mac: None, + }.to_vec ()?; + + for _ in 0..5 { + socket.send_to (&msg, (params.multicast_addr, params.server_port))?; + std::thread::sleep (Duration::from_millis (50)); + } let start_time = Instant::now (); @@ -139,13 +151,26 @@ fn server () -> Result <(), AppError> { socket.join_multicast_v4 (¶ms.multicast_addr, &([0u8, 0, 0, 0].into ())).unwrap (); + let mut recent_idem_ids = Vec::with_capacity (32); + loop { println! ("Waiting for messages..."); let (req, remote_addr) = recv_msg_from (&socket)?; let resp = match req { - Message::Request (None) => { - Some (Message::Response (our_mac)) + Message::Request { + mac: None, + idem_id, + } => { + if recent_idem_ids.contains (&idem_id) { + println! ("Ignoring request we already processed"); + None + } + else { + recent_idem_ids.insert (0, idem_id); + recent_idem_ids.truncate (30); + Some (Message::Response (our_mac)) + } }, _ => continue, }; diff --git a/src/message.rs b/src/message.rs index 2626ad2..ad91c95 100644 --- a/src/message.rs +++ b/src/message.rs @@ -11,7 +11,10 @@ pub const PACKET_SIZE: usize = 1024; #[derive (Debug)] pub enum Message { - Request (Option <[u8; 6]>), + Request { + idem_id: [u8; 8], + mac: Option <[u8; 6]> + }, Response (Option <[u8; 6]>), } @@ -31,8 +34,12 @@ impl Message { w.write_all (&MAGIC_NUMBER)?; match self { - Self::Request (mac) => { + Self::Request { + idem_id, + mac, + }=> { w.write_all (&[1])?; + w.write_all (&idem_id[..])?; Self::write_mac_opt (w, *mac)?; }, Self::Response (mac) => { @@ -68,8 +75,14 @@ impl Message { Ok (match t { 1 => { + let mut idem_id = [0u8; 8]; + r.read_exact (&mut idem_id)?; + let mac = Self::read_mac_opt (r)?; - Self::Request (mac) + Self::Request { + idem_id, + mac, + } }, 2 => { let mac = Self::read_mac_opt (r)?;