♻️ 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,
recv_msg_from,
},
ip::get_ips,
message::{
self,
PACKET_SIZE,

View File

@ -1,9 +1,29 @@
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 mut bind_addr = "0.0.0.0".to_string ();
let params = configure (args)?;
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 ();
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 = match args.next () {
None => return Err (CliArgError::MissingArgumentValue (arg).into ()),
Some (x) => x
Some (x) => Ipv4Addr::from_str (&x)?,
};
},
"--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");
}
let socket = UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::from_str (&bind_addr)?, common_params.server_port)).await?;
socket.join_multicast_v4 (common_params.multicast_addr, [0u8, 0, 0, 0].into ())?;
Ok (Params {
common,
bind_addr,
nickname,
our_mac,
})
}
async fn serve_interface (params: &Params, socket: UdpSocket)
-> Result <(), AppError>
{
let mut recent_idem_ids = Vec::with_capacity (32);
loop {
println! ("Waiting for messages...");
let (req_msgs, remote_addr) = match recv_msg_from (&socket).await {
Ok (x) => x,
Err (e) => {
@ -59,17 +85,16 @@ pub async fn server <I: Iterator <Item=String>> (mut args: I) -> Result <(), App
idem_id,
} => {
if recent_idem_ids.contains (&idem_id) {
println! ("Ignoring request we already processed");
None
}
else {
recent_idem_ids.insert (0, idem_id);
recent_idem_ids.truncate (30);
Some (vec! [
Message::Response1 (our_mac),
Message::Response1 (params.our_mac),
Message::Response2 (message::Response2 {
idem_id,
nickname: nickname.clone (),
nickname: params.nickname.clone (),
}),
])
}