From 9251dc327d57f917ec67b4967d0bc41e1125de13 Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Wed, 8 Dec 2021 14:54:01 -0600 Subject: [PATCH] :heavy_plus_sign: add `--bind-addr` CLI args to both client and server. This lets you pick an interface. I can't enumerate them automatically yet. --- issues.md | 7 ++----- src/main.rs | 34 +++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/issues.md b/issues.md index d91e1a2..f118957 100644 --- a/issues.md +++ b/issues.md @@ -22,9 +22,6 @@ for that. I think on Linux I can get it from `/sys/class/net` but I can't remember the trick for that. I think last time I did this (for that work project) I just punted to Qt. -# 01FP9A272Q94Y08MAKX7BFT11M +# 01FPDWYH3ZY52DFF6PNRSA63GB -Need CLI args - -I don't know if this multicast addr and this port are unused. -Having CLI args lets us work around other apps. +Sending an invalid packet directly to the server's UDP port crashes the server. diff --git a/src/main.rs b/src/main.rs index d263230..3d75f20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use std::{ SocketAddrV4, UdpSocket, }, + str::FromStr, time::{Duration, Instant}, }; @@ -26,6 +27,8 @@ use message::{ #[derive (Debug, Error)] enum AppError { + #[error (transparent)] + AddrParse (#[from] std::net::AddrParseError), #[error (transparent)] CliArgs (#[from] CliArgError), #[error (transparent)] @@ -84,7 +87,7 @@ fn main () -> Result <(), AppError> { match subcommand.as_ref ().map (|x| &x[..]) { None => return Err (CliArgError::MissingSubcommand.into ()), - Some ("client") => client ()?, + Some ("client") => client (args)?, Some ("server") => server (args)?, Some (x) => return Err (CliArgError::UnknownSubcommand (x.to_string ()).into ()), } @@ -97,13 +100,27 @@ struct ServerResponse { nickname: Option , } -fn client () -> Result <(), AppError> { +fn client > (mut args: I) -> Result <(), AppError> { use rand::RngCore; let mut common_params = CommonParams::default (); - let socket = UdpSocket::bind ("0.0.0.0:0")?; + let mut bind_addr = "0.0.0.0".to_string (); - socket.join_multicast_v4 (&common_params.multicast_addr, &([0u8, 0, 0, 0].into ()))?; + while let Some (arg) = args.next () { + match arg.as_str () { + "--bind-addr" => { + bind_addr = match args.next () { + None => return Err (CliArgError::MissingArgumentValue (arg).into ()), + Some (x) => x + }; + }, + _ => return Err (CliArgError::UnrecognizedArgument (arg).into ()), + } + } + + let socket = UdpSocket::bind (&format! ("{}:0", bind_addr))?; + + socket.join_multicast_v4 (&common_params.multicast_addr, &Ipv4Addr::from_str (&bind_addr)?)?; socket.set_read_timeout (Some (Duration::from_millis (1_000)))?; let mut idem_id = [0u8; 8]; @@ -175,10 +192,17 @@ fn client () -> Result <(), AppError> { fn server > (mut args: I) -> Result <(), AppError> { let mut common_params = CommonParams::default (); + let mut bind_addr = "0.0.0.0".to_string (); let mut nickname = String::new (); while let Some (arg) = args.next () { match arg.as_str () { + "--bind-addr" => { + bind_addr = match args.next () { + None => return Err (CliArgError::MissingArgumentValue (arg).into ()), + Some (x) => x + }; + }, "--nickname" => { nickname = match args.next () { None => return Err (CliArgError::MissingArgumentValue (arg).into ()), @@ -194,7 +218,7 @@ fn server > (mut args: I) -> Result <(), AppError> println! ("Warning: Can't find our own MAC address. We won't be able to respond to MAC-specific lookaround requests"); } - let socket = UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, common_params.server_port)).unwrap (); + let socket = UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::from_str (&bind_addr)?, common_params.server_port)).unwrap (); socket.join_multicast_v4 (&common_params.multicast_addr, &([0u8, 0, 0, 0].into ())).unwrap ();