From 1cb799edccacdf2db8fc9a1d213e0535b4e13b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 24 Sep 2024 14:35:52 +0200 Subject: [PATCH] Make discovery more robust by sending multiple packets --- CHANGELOG.md | 1 + src/crusader-lib/src/discovery.rs | 59 ++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b4b92e..4cb9566 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This file lists the changes that have occurred since January 2024 in the project * Clock synchronization now uses the average of the lowest 1/3rd of samples * Adjust for clock drift in tests * Fix connecting to servers on non-standard port with peers +* Make discovery more robust by sending multiple packets ## 0.3 - 2024-09-16 diff --git a/src/crusader-lib/src/discovery.rs b/src/crusader-lib/src/discovery.rs index 515ea03..eaf5c7e 100644 --- a/src/crusader-lib/src/discovery.rs +++ b/src/crusader-lib/src/discovery.rs @@ -88,9 +88,13 @@ fn interfaces() -> Vec { #[cfg(feature = "client")] pub async fn locate(peer_server: bool) -> Result { - use crate::common::fresh_socket_addr; - use std::{net::SocketAddrV6, time::Duration}; - use tokio::time::timeout; + use crate::{common::fresh_socket_addr, serve::OnDrop}; + use std::{ + net::SocketAddrV6, + sync::atomic::{AtomicBool, Ordering}, + time::Duration, + }; + use tokio::time::{self, timeout}; fn handle_packet( peer_server: bool, @@ -142,6 +146,8 @@ pub async fn locate(peer_server: bool) -> Result { socket.set_broadcast(true)?; + let socket = Arc::new(socket); + let data = Data { hello: Hello::new(), message: Message::Discover { peer: peer_server }, @@ -151,20 +157,47 @@ pub async fn locate(peer_server: bool) -> Result { let ip = Ipv6Addr::from_str("ff02::1").unwrap(); - let mut any = false; - for interface in interfaces() { - if socket - .send_to(&buf, SocketAddrV6::new(ip, DISCOVER_PORT, 0, interface)) - .await - .is_ok() - { - any = true; + let socket_ = socket.clone(); + let send_packet = move || { + let socket = socket_.clone(); + let buf = buf.clone(); + async move { + let mut any = false; + for interface in interfaces() { + if socket + .send_to(&buf, SocketAddrV6::new(ip, DISCOVER_PORT, 0, interface)) + .await + .is_ok() + { + any = true; + } + } + any } - } - if !any { + }; + + if !send_packet().await { bail!("Failed to send any discovery multicast packets"); } + let done = Arc::new(AtomicBool::new(false)); + let done_ = done.clone(); + let _on_drop = OnDrop(|| { + done_.store(true, Ordering::Release); + }); + + tokio::spawn(async move { + loop { + time::sleep(Duration::from_millis(100)).await; + + if done.load(Ordering::Acquire) { + break; + } + + send_packet().await; + } + }); + let find = async { let mut buf = [0; 1500]; loop {