Compare commits

..

2 Commits

Author SHA1 Message Date
_ 7a0880fc02 do it similar on the client 2021-12-08 21:40:03 -06:00
_ fd4f70b1c9 🐛 bug: think I figured out the server part
turns out you can join multiple multicast groups on the same socket.
And then I think the OS or the network somehow decides how to route
packets to you. Without touching anything else, if I'm plugged into
Ethernet, it picks that address (when running client on the desktop)
and when I unplug it, it picks the laptop's WiFi.
2021-12-08 21:31:07 -06:00
2 changed files with 19 additions and 25 deletions

View File

@ -9,23 +9,29 @@ pub async fn client <I : Iterator <Item=String>> (mut args: I) -> Result <(), Ap
use rand::RngCore; use rand::RngCore;
let common_params = app_common::Params::default (); let common_params = app_common::Params::default ();
let mut bind_addr = "0.0.0.0".to_string (); let mut bind_addrs = vec! [];
while let Some (arg) = args.next () { while let Some (arg) = args.next () {
match arg.as_str () { match arg.as_str () {
"--bind-addr" => { "--bind-addr" => {
bind_addr = match args.next () { bind_addrs.push (match args.next () {
None => return Err (CliArgError::MissingArgumentValue (arg).into ()), None => return Err (CliArgError::MissingArgumentValue (arg).into ()),
Some (x) => x Some (x) => Ipv4Addr::from_str (&x)?
}; });
}, },
_ => return Err (CliArgError::UnrecognizedArgument (arg).into ()), _ => return Err (CliArgError::UnrecognizedArgument (arg).into ()),
} }
} }
let socket = UdpSocket::bind (&format! ("{}:0", bind_addr)).await?; if bind_addrs.is_empty () {
bind_addrs = get_ips ()?;
}
socket.join_multicast_v4 (common_params.multicast_addr, Ipv4Addr::from_str (&bind_addr)?)?; let socket = UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, 0)).await?;
for bind_addr in bind_addrs {
socket.join_multicast_v4 (common_params.multicast_addr, bind_addr)?;
}
let mut idem_id = [0u8; 8]; let mut idem_id = [0u8; 8];
rand::thread_rng ().fill_bytes (&mut idem_id); rand::thread_rng ().fill_bytes (&mut idem_id);

View File

@ -12,28 +12,13 @@ pub async fn server <I: Iterator <Item=String>> (args: I) -> Result <(), AppErro
{ {
let params = configure (args)?; let params = configure (args)?;
// This was too hard to do in a functional style let socket = UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, params.common.server_port)).await?;
let mut tasks = vec! [];
for bind_addr in &params.bind_addrs { for bind_addr in &params.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)?; socket.join_multicast_v4 (params.common.multicast_addr, *bind_addr)?;
dbg! (bind_addr);
tasks.push (tokio::spawn (serve_interface (params.clone (), socket)));
} }
for task in tasks { serve_interface (params, socket).await?;
task.await??;
}
Ok (()) Ok (())
} }
@ -68,7 +53,7 @@ fn configure <I: Iterator <Item=String>> (mut args: I) -> Result <Params, AppErr
} }
if bind_addrs.is_empty () { if bind_addrs.is_empty () {
println! ("No bind addresses found, auto-detecting all local IPs"); println! ("No bind addresses given, auto-detecting all local IPs");
bind_addrs = get_ips ()?; bind_addrs = get_ips ()?;
} }
@ -80,7 +65,10 @@ fn configure <I: Iterator <Item=String>> (mut args: I) -> Result <Params, AppErr
}) })
} }
async fn serve_interface (params: Params, socket: UdpSocket) async fn serve_interface (
params: Params,
socket: UdpSocket,
)
-> Result <(), AppError> -> Result <(), AppError>
{ {
let mut recent_idem_ids = Vec::with_capacity (32); let mut recent_idem_ids = Vec::with_capacity (32);