➕ 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