diff --git a/src/app_common.rs b/src/app_common.rs index 4e7a8b5..b0a4a12 100644 --- a/src/app_common.rs +++ b/src/app_common.rs @@ -11,6 +11,8 @@ pub enum AppError { #[error (transparent)] Ip (#[from] crate::ip::IpError), #[error (transparent)] + Join (#[from] tokio::task::JoinError), + #[error (transparent)] MacAddr (#[from] mac_address::MacAddressError), #[error (transparent)] Message (#[from] crate::message::MessageError), @@ -40,6 +42,7 @@ pub async fn recv_msg_from (socket: &UdpSocket) -> Result <(Vec , Socke Ok ((msgs, remote_addr)) } +#[derive (Clone)] pub struct Params { // Servers bind on this port, clients must send to the port pub server_port: u16, diff --git a/src/ip.rs b/src/ip.rs index b93b77c..bbcac88 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -54,6 +54,7 @@ pub mod linux { .filter_map (|l| l.strip_prefix ("inet ")) .filter_map (|l| l.find ('/').map (|x| &l [0..x])) .filter_map (|l| Ipv4Addr::from_str (l).ok ()) + .filter (|a| ! a.is_loopback ()) .collect () } } diff --git a/src/main.rs b/src/main.rs index 415ca8e..d429ca8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,8 +47,6 @@ async fn async_main () -> Result <(), AppError> { fn my_ips () -> Result <(), AppError> { for addr in ip::get_ips ()? - .iter () - .filter (|a| ! a.is_loopback ()) { println! ("{:?}", addr); } diff --git a/src/server.rs b/src/server.rs index b614649..4aa5b19 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,8 +1,9 @@ use crate::prelude::*; +#[derive (Clone)] struct Params { common: app_common::Params, - bind_addr: Ipv4Addr, + bind_addrs: Vec , nickname: String, our_mac: Option <[u8; 6]>, } @@ -11,11 +12,28 @@ pub async fn server > (args: I) -> Result <(), AppErro { let params = configure (args)?; - let socket = UdpSocket::bind (SocketAddrV4::new (params.bind_addr, params.common.server_port)).await?; + // This was too hard to do in a functional style + let mut tasks = vec! []; - socket.join_multicast_v4 (params.common.multicast_addr, [0u8, 0, 0, 0].into ())?; + for bind_addr in ¶ms.bind_addrs { + let socket = match UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, params.common.server_port)).await { + Err (e) => { + println! ("Error binding socket: {:?}", e); + continue; + }, + Ok (x) => x, + }; + + socket.join_multicast_v4 (params.common.multicast_addr, *bind_addr)?; + + dbg! (bind_addr); + + tasks.push (tokio::spawn (serve_interface (params.clone (), socket))); + } - serve_interface (¶ms, socket).await?; + for task in tasks { + task.await??; + } Ok (()) } @@ -23,16 +41,16 @@ pub async fn server > (args: I) -> Result <(), AppErro fn configure > (mut args: I) -> Result { let common = app_common::Params::default (); - let mut bind_addr = Ipv4Addr::UNSPECIFIED; + let mut bind_addrs = vec![]; let mut nickname = String::new (); while let Some (arg) = args.next () { match arg.as_str () { "--bind-addr" => { - bind_addr = match args.next () { + bind_addrs.push (match args.next () { None => return Err (CliArgError::MissingArgumentValue (arg).into ()), Some (x) => Ipv4Addr::from_str (&x)?, - }; + }); }, "--nickname" => { nickname = match args.next () { @@ -49,20 +67,26 @@ fn configure > (mut args: I) -> Result Result <(), AppError> { let mut recent_idem_ids = Vec::with_capacity (32); loop { + println! ("Listening..."); let (req_msgs, remote_addr) = match recv_msg_from (&socket).await { Ok (x) => x, Err (e) => {