♻️ refactor: preparing to serve on multiple interfaces

main
_ 2021-12-09 02:26:45 +00:00
parent 39bcea54d4
commit 1b7c2ce0f4
2 changed files with 38 additions and 12 deletions

View File

@ -29,6 +29,7 @@ pub use crate::{
CliArgError, CliArgError,
recv_msg_from, recv_msg_from,
}, },
ip::get_ips,
message::{ message::{
self, self,
PACKET_SIZE, PACKET_SIZE,

View File

@ -1,9 +1,29 @@
use crate::prelude::*; use crate::prelude::*;
pub async fn server <I: Iterator <Item=String>> (mut args: I) -> Result <(), AppError> struct Params {
common: app_common::Params,
bind_addr: Ipv4Addr,
nickname: String,
our_mac: Option <[u8; 6]>,
}
pub async fn server <I: Iterator <Item=String>> (args: I) -> Result <(), AppError>
{ {
let common_params = app_common::Params::default (); let params = configure (args)?;
let mut bind_addr = "0.0.0.0".to_string ();
let socket = UdpSocket::bind (SocketAddrV4::new (params.bind_addr, params.common.server_port)).await?;
socket.join_multicast_v4 (params.common.multicast_addr, [0u8, 0, 0, 0].into ())?;
serve_interface (&params, socket).await?;
Ok (())
}
fn configure <I: Iterator <Item=String>> (mut args: I) -> Result <Params, AppError>
{
let common = app_common::Params::default ();
let mut bind_addr = Ipv4Addr::UNSPECIFIED;
let mut nickname = String::new (); let mut nickname = String::new ();
while let Some (arg) = args.next () { while let Some (arg) = args.next () {
@ -11,7 +31,7 @@ pub async fn server <I: Iterator <Item=String>> (mut args: I) -> Result <(), App
"--bind-addr" => { "--bind-addr" => {
bind_addr = match args.next () { bind_addr = 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)?,
}; };
}, },
"--nickname" => { "--nickname" => {
@ -29,14 +49,20 @@ pub async fn server <I: Iterator <Item=String>> (mut args: I) -> Result <(), App
println! ("Warning: Can't find our own MAC address. We won't be able to respond to MAC-specific lookaround requests"); 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::from_str (&bind_addr)?, common_params.server_port)).await?; Ok (Params {
common,
socket.join_multicast_v4 (common_params.multicast_addr, [0u8, 0, 0, 0].into ())?; bind_addr,
nickname,
our_mac,
})
}
async fn serve_interface (params: &Params, socket: UdpSocket)
-> Result <(), AppError>
{
let mut recent_idem_ids = Vec::with_capacity (32); let mut recent_idem_ids = Vec::with_capacity (32);
loop { loop {
println! ("Waiting for messages...");
let (req_msgs, remote_addr) = match recv_msg_from (&socket).await { let (req_msgs, remote_addr) = match recv_msg_from (&socket).await {
Ok (x) => x, Ok (x) => x,
Err (e) => { Err (e) => {
@ -59,17 +85,16 @@ pub async fn server <I: Iterator <Item=String>> (mut args: I) -> Result <(), App
idem_id, idem_id,
} => { } => {
if recent_idem_ids.contains (&idem_id) { if recent_idem_ids.contains (&idem_id) {
println! ("Ignoring request we already processed");
None None
} }
else { else {
recent_idem_ids.insert (0, idem_id); recent_idem_ids.insert (0, idem_id);
recent_idem_ids.truncate (30); recent_idem_ids.truncate (30);
Some (vec! [ Some (vec! [
Message::Response1 (our_mac), Message::Response1 (params.our_mac),
Message::Response2 (message::Response2 { Message::Response2 (message::Response2 {
idem_id, idem_id,
nickname: nickname.clone (), nickname: params.nickname.clone (),
}), }),
]) ])
} }