➕ add `find-nick` command
							parent
							
								
									b261d7ba4a
								
							
						
					
					
						commit
						4f66c0495e
					
				
							
								
								
									
										13
									
								
								README.md
								
								
								
								
							
							
						
						
									
										13
									
								
								README.md
								
								
								
								
							|  | @ -59,6 +59,19 @@ Run the server manually: (If you haven't installed it with systemd yet) | |||
| lookaround server --nickname my-desktop | ||||
| ``` | ||||
| 
 | ||||
| Use `find-nick` to find an IP, or ping it, or SSH into it, or pull a file from it: | ||||
| 
 | ||||
| ```bash | ||||
| lookaround find-nick laptop | ||||
| 
 | ||||
| ping $(lookaround find-nick laptop) | ||||
| 
 | ||||
| ssh user@$(lookaround find-nick laptop) | ||||
| 
 | ||||
| # After starting `nc -l -p 9000 < some-file` on the laptop | ||||
| nc $(lookaround find-nick laptop) 9000 | ||||
| `` | ||||
| 
 | ||||
| Run a client to ping all servers in the same multi-cast domain: | ||||
| 
 | ||||
| ```bash | ||||
|  |  | |||
							
								
								
									
										1
									
								
								ideas.md
								
								
								
								
							
							
						
						
									
										1
									
								
								ideas.md
								
								
								
								
							|  | @ -1,7 +1,6 @@ | |||
| Cool ideas that can be done but probably won't be. | ||||
| 
 | ||||
| - Exit faster if the user only wants to see known servers | ||||
| - Command for shell substituting IPs into commands | ||||
| - Arbitrary TCP forwarding of (stdin? stdout? TCP?) | ||||
| - Netcat replacement "Just send a file" _including filename_ | ||||
| - Public-key crypto for trusting peers on first use (Hard cause it requires mutable disk state) | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ pub enum AppError { | |||
| 	AddrParse (#[from] std::net::AddrParseError), | ||||
| 	#[error (transparent)] | ||||
| 	CliArgs (#[from] CliArgError), | ||||
| 	#[error ("Operation timed out")] | ||||
| 	Elapsed (#[from] tokio::time::error::Elapsed), | ||||
| 	#[error (transparent)] | ||||
| 	Io (#[from] std::io::Error), | ||||
| 	#[error (transparent)] | ||||
|  | @ -26,6 +28,8 @@ pub enum AppError { | |||
| pub enum CliArgError { | ||||
| 	#[error ("Missing value for argument `{0}`")] | ||||
| 	MissingArgumentValue (String), | ||||
| 	#[error ("Missing required argument <{0}>")] | ||||
| 	MissingRequiredArg (String), | ||||
| 	#[error ("First argument should be a subcommand")] | ||||
| 	MissingSubcommand, | ||||
| 	#[error ("Unknown subcommand `{0}`")] | ||||
|  |  | |||
|  | @ -12,10 +12,17 @@ struct ClientParams { | |||
| } | ||||
| 
 | ||||
| pub async fn client <I: Iterator <Item=String>> (args: I) -> Result <(), AppError> { | ||||
| 	match get_mac_address() { | ||||
| 		Ok(Some(ma)) => { | ||||
| 			println!("Our MAC addr = {}", ma); | ||||
| 		} | ||||
| 		Ok(None) => println!("No MAC address found."), | ||||
| 		Err(e) => println!("{:?}", e), | ||||
| 	} | ||||
| 	
 | ||||
| 	let params = configure_client (args)?; | ||||
| 	let socket = make_socket (¶ms).await?; | ||||
| 	let msg = Message::new_request1 ().to_vec ()?; | ||||
| 	
 | ||||
| 	tokio::spawn (send_requests (Arc::clone (&socket), params.common, msg)); | ||||
| 	
 | ||||
| 	let mut peers = HashMap::with_capacity (10); | ||||
|  | @ -49,6 +56,64 @@ pub async fn client <I: Iterator <Item=String>> (args: I) -> Result <(), AppErro | |||
| 	Ok (()) | ||||
| } | ||||
| 
 | ||||
| pub async fn find_nick <I: Iterator <Item=String>> (mut args: I) -> Result <(), AppError> 
 | ||||
| { | ||||
| 	let mut nick = None; | ||||
| 	let mut timeout_ms = 500; | ||||
| 	
 | ||||
| 	while let Some (arg) = args.next () { | ||||
| 		match arg.as_str () { | ||||
| 			"--timeout-ms" => { | ||||
| 				timeout_ms = match args.next () { | ||||
| 					None => return Err (CliArgError::MissingArgumentValue (arg).into ()), | ||||
| 					Some (x) => u64::from_str (&x)?, | ||||
| 				}; | ||||
| 			}, | ||||
| 			_ => nick = Some (arg), | ||||
| 		} | ||||
| 	} | ||||
| 	
 | ||||
| 	let needle_nick = nick.ok_or_else (|| CliArgError::MissingRequiredArg ("nickname".to_string ()))?; | ||||
| 	let needle_nick = Some (needle_nick); | ||||
| 	
 | ||||
| 	let params = ClientParams { | ||||
| 		common: Default::default (), | ||||
| 		bind_addrs: get_ips ()?, | ||||
| 		timeout_ms, | ||||
| 	}; | ||||
| 	
 | ||||
| 	let socket = make_socket (¶ms).await?; | ||||
| 	let msg = Message::new_request1 ().to_vec ()?; | ||||
| 	tokio::spawn (send_requests (Arc::clone (&socket), params.common, msg)); | ||||
| 	
 | ||||
| 	timeout (Duration::from_millis (params.timeout_ms), async move { loop { | ||||
| 		let (msgs, remote_addr) = match recv_msg_from (&socket).await { | ||||
| 			Err (_) => continue, | ||||
| 			Ok (x) => x, | ||||
| 		}; | ||||
| 		
 | ||||
| 		let mut resp = ServerResponse { | ||||
| 			mac: None, | ||||
| 			nickname: None, | ||||
| 		}; | ||||
| 		
 | ||||
| 		for msg in msgs.into_iter () { | ||||
| 			match msg { | ||||
| 				Message::Response1 (x) => resp.mac = x, | ||||
| 				Message::Response2 (x) => resp.nickname = Some (x.nickname), | ||||
| 				_ => (), | ||||
| 			} | ||||
| 		} | ||||
| 		
 | ||||
| 		if resp.nickname == needle_nick { | ||||
| 			println! ("{}", remote_addr.ip ()); | ||||
| 			return; | ||||
| 		} | ||||
| 	}}).await?; | ||||
| 	
 | ||||
| 	Ok (()) | ||||
| } | ||||
| 
 | ||||
| fn configure_client <I: Iterator <Item=String>> (mut args: I) 
 | ||||
| -> Result <ClientParams, AppError> | ||||
| { | ||||
|  |  | |||
|  | @ -24,19 +24,12 @@ async fn async_main () -> Result <(), AppError> { | |||
| 	
 | ||||
| 	let _exe_name = args.next (); | ||||
| 	
 | ||||
| 	match get_mac_address() { | ||||
| 		Ok(Some(ma)) => { | ||||
| 			println!("Our MAC addr = {}", ma); | ||||
| 		} | ||||
| 		Ok(None) => println!("No MAC address found."), | ||||
| 		Err(e) => println!("{:?}", e), | ||||
| 	} | ||||
| 	
 | ||||
| 	let subcommand: Option <String> = args.next (); | ||||
| 	
 | ||||
| 	match subcommand.as_ref ().map (|x| &x[..]) { | ||||
| 		None => return Err (CliArgError::MissingSubcommand.into ()), | ||||
| 		Some ("client") => client::client (args).await?, | ||||
| 		Some ("find-nick") => client::find_nick (args).await?, | ||||
| 		Some ("my-ips") => my_ips ()?, | ||||
| 		Some ("server") => server::server (args).await?, | ||||
| 		Some (x) => return Err (CliArgError::UnknownSubcommand (x.to_string ()).into ()), | ||||
|  |  | |||
|  | @ -10,6 +10,14 @@ struct Params { | |||
| 
 | ||||
| pub async fn server <I: Iterator <Item=String>> (args: I) -> Result <(), AppError> 
 | ||||
| { | ||||
| 	match get_mac_address() { | ||||
| 		Ok(Some(ma)) => { | ||||
| 			println!("Our MAC addr = {}", ma); | ||||
| 		} | ||||
| 		Ok(None) => println!("No MAC address found."), | ||||
| 		Err(e) => println!("{:?}", e), | ||||
| 	} | ||||
| 	
 | ||||
| 	let params = configure (args)?; | ||||
| 	
 | ||||
| 	let socket = UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, params.common.server_port)).await?; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 _
						_