use crate::*;
pub(crate) async fn ipc_create(
mode: GroupMode,
name: Option<String>,
hostname: Option<String>,
tor: bool,
) -> Result<()> {
let transport = if tor {
Some(config::TransportMode::Tor)
} else {
None
};
let mut stream = ipc::connect().await?;
ipc::send(
&mut stream,
ipc::IpcMessage::Create {
mode,
name,
hostname,
transport,
},
)
.await?;
let resp = ipc::recv(&mut stream).await?;
match resp {
ipc::IpcMessage::Created {
name,
network_key,
my_ip,
my_ipv6,
} => {
let key_str = network_key.to_string();
let short = if key_str.len() > 12 {
format!("{}…{}", &key_str[..4], &key_str[key_str.len() - 4..])
} else {
key_str.clone()
};
let _ = my_ipv6;
println!();
println!(
" {} {} {}",
style::check(),
style::value("created"),
style::bold(&name)
);
println!(
" {} {} {} {}",
style::label("address"),
style::value(&my_ip.to_string()),
style::faint("·"),
style::rose(&short),
);
let join = format!("ray join {network_key}");
print_next(&[
(&join, "share this to invite peers"),
("ray up", "activate the VPN"),
]);
println!();
}
ipc::IpcMessage::Error { message } => print_error("create failed", &message, None),
other => eprintln!("Unexpected response: {:?}", other),
}
Ok(())
}
pub(crate) async fn ipc_join(
network_key: &str,
name: Option<&str>,
hostname: Option<String>,
tor: bool,
auto_accept_firewall: bool,
) -> Result<()> {
let transport = if tor {
Some(config::TransportMode::Tor)
} else {
None
};
let (network_key, invite, coordinator) = match invite::decode_invite_code(network_key) {
Ok((net_pubkey, coord, secret)) => (net_pubkey.to_string(), Some(secret), Some(coord)),
Err(_) => (network_key.to_string(), None, None),
};
let mut stream = ipc::connect().await?;
ipc::send(
&mut stream,
ipc::IpcMessage::Join {
network_key,
name: name.map(|s| s.to_string()),
hostname,
transport,
invite,
coordinator,
auto_accept_firewall,
},
)
.await?;
let spinner = progress::spinner("joining…");
let resp = ipc::recv(&mut stream).await?;
spinner.finish_and_clear();
match resp {
ipc::IpcMessage::Ok { message } => {
println!("{}", message);
}
ipc::IpcMessage::Joined {
name,
my_ip,
my_ipv6,
} => {
let _ = my_ipv6;
let dns = format!("{name}.{DNS_DOMAIN}");
println!();
println!(
" {} {} {}",
style::check(),
style::value("joined"),
style::bold(&name)
);
println!(
" {} {} {} {}",
style::label("address"),
style::value(&my_ip.to_string()),
style::faint("·"),
style::value(&dns),
);
print_next(&[
("ray status", "see who's online"),
("ray up", "activate the VPN"),
]);
println!();
}
ipc::IpcMessage::Error { message } => print_error("join failed", &message, None),
other => eprintln!("Unexpected response: {:?}", other),
}
Ok(())
}
pub(crate) async fn ipc_nuke(name: &str, force: bool) -> Result<()> {
let mut stream = ipc::connect().await?;
ipc::send(
&mut stream,
ipc::IpcMessage::Nuke {
name: name.to_string(),
force,
},
)
.await?;
let resp = ipc::recv(&mut stream).await?;
match resp {
ipc::IpcMessage::Ok { message } => println!("{}", message),
ipc::IpcMessage::Error { message } => print_error("error", &message, None),
other => eprintln!("Unexpected response: {:?}", other),
}
Ok(())
}
pub(crate) async fn ipc_leave(name: &str) -> Result<()> {
let mut stream = ipc::connect().await?;
ipc::send(
&mut stream,
ipc::IpcMessage::Leave {
name: name.to_string(),
},
)
.await?;
let resp = ipc::recv(&mut stream).await?;
match resp {
ipc::IpcMessage::Ok { message } => println!("{}", message),
ipc::IpcMessage::Error { message } => print_error("error", &message, None),
other => eprintln!("Unexpected response: {:?}", other),
}
Ok(())
}