🚧 wip: not working the way I expect
							parent
							
								
									1b7c2ce0f4
								
							
						
					
					
						commit
						0bb702f312
					
				| 
						 | 
				
			
			@ -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 <Message>, 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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 ()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
use crate::prelude::*;
 | 
			
		||||
 | 
			
		||||
#[derive (Clone)]
 | 
			
		||||
struct Params {
 | 
			
		||||
	common: app_common::Params,
 | 
			
		||||
	bind_addr: Ipv4Addr,
 | 
			
		||||
	bind_addrs: Vec <Ipv4Addr>,
 | 
			
		||||
	nickname: String,
 | 
			
		||||
	our_mac: Option <[u8; 6]>,
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,11 +12,28 @@ pub async fn server <I: Iterator <Item=String>> (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,
 | 
			
		||||
		};
 | 
			
		||||
		
 | 
			
		||||
	serve_interface (¶ms, socket).await?;
 | 
			
		||||
		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 {
 | 
			
		||||
		task.await??;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	Ok (())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -23,16 +41,16 @@ pub async fn server <I: Iterator <Item=String>> (args: I) -> Result <(), AppErro
 | 
			
		|||
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 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 <I: Iterator <Item=String>> (mut args: I) -> Result <Params, AppErr
 | 
			
		|||
		println! ("Warning: Can't find our own MAC address. We won't be able to respond to MAC-specific lookaround requests");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if bind_addrs.is_empty () {
 | 
			
		||||
		println! ("No bind addresses found, auto-detecting all local IPs");
 | 
			
		||||
		bind_addrs = get_ips ()?;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	Ok (Params {
 | 
			
		||||
		common,
 | 
			
		||||
		bind_addr,
 | 
			
		||||
		bind_addrs,
 | 
			
		||||
		nickname,
 | 
			
		||||
		our_mac,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn serve_interface (params: &Params, socket: UdpSocket) 
 | 
			
		||||
async fn serve_interface (params: Params, socket: UdpSocket) 
 | 
			
		||||
-> 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) => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue