1.更新对称NAT的打洞方式;2.支持windows服务;3.更新协议内容

This commit is contained in:
lubeilin
2023-02-05 18:35:27 +08:00
parent 206c543e8c
commit af58c3990d
20 changed files with 865 additions and 388 deletions
+35
View File
@@ -0,0 +1,35 @@
use std::io;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
use std::time::Duration;
pub struct CommandClient {
udp: UdpSocket,
}
impl CommandClient {
pub fn new() -> io::Result<Self> {
let port = crate::config::read_command_port().unwrap();
let udp = UdpSocket::bind("127.0.0.1:0")?;
udp.set_read_timeout(Some(Duration::from_secs(5)))?;
udp.connect(SocketAddr::V4(SocketAddrV4::new(
Ipv4Addr::new(127, 0, 0, 1),
port,
)))?;
Ok(Self { udp })
}
}
impl CommandClient {
pub fn list(&self) -> io::Result<String> {
self.udp.send(b"list")?;
let mut buf = [0; 10240];
let len = self.udp.recv(&mut buf)?;
Ok(String::from_utf8(buf[..len].to_vec()).unwrap())
}
pub fn status(&self) -> io::Result<String> {
self.udp.send(b"status")?;
let mut buf = [0; 10240];
let len = self.udp.recv(&mut buf)?;
Ok(String::from_utf8(buf[..len].to_vec()).unwrap())
}
}
+2
View File
@@ -0,0 +1,2 @@
pub mod client;
pub mod server;
+157
View File
@@ -0,0 +1,157 @@
use std::io;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
use std::sync::Arc;
use console::style;
use switch::handle::{PeerDeviceStatus, RouteType};
use switch::Switch;
pub struct CommandServer {}
impl CommandServer {
pub fn new() -> Self {
Self {}
}
}
impl CommandServer {
pub fn start(&self, switch: Arc<Switch>) -> io::Result<()> {
let mut port = 21637 as u16;
let udp = loop {
match UdpSocket::bind(SocketAddr::V4(SocketAddrV4::new(
Ipv4Addr::new(127, 0, 0, 1),
port,
))) {
Ok(udp) => {
break udp;
}
Err(e) => {
if e.kind() == io::ErrorKind::AddrInUse {
port += 1;
} else {
log::error!("创建udp失败 {:?}", e);
return Err(e);
}
}
}
};
crate::config::update_command_port(port)?;
let mut buf = [0u8; 64];
loop {
let (len, addr) = udp.recv_from(&mut buf)?;
match std::str::from_utf8(&buf[..len]) {
Ok(cmd) => {
if let Ok(out) = command(cmd, &switch) {
udp.send_to(out.as_bytes(), addr)?;
}
}
Err(e) => {
log::warn!("{:?}", e);
}
}
}
}
}
fn command(cmd: &str, switch: &Switch) -> io::Result<String> {
let mut out_str = String::new();
match cmd {
"list" => {
let server_rt = switch.server_rt();
let device_list = switch.device_list();
if device_list.is_empty() {
return Ok("No other devices found\n".to_string());
}
for peer_device_info in device_list {
let route = switch.route(&peer_device_info.virtual_ip);
let str = if peer_device_info.status == PeerDeviceStatus::Online {
if route.route_type == RouteType::P2P {
let str = if route.rt >= 0 {
format!(
"[{}] {}(p2p delay:{}ms)\n",
peer_device_info.name, peer_device_info.virtual_ip, route.rt
)
} else {
format!(
"[{}] {}(p2p)",
peer_device_info.name, peer_device_info.virtual_ip
)
};
style(str).green().to_string()
} else {
let str = if server_rt >= 0 {
format!(
"[{}] {}(relay delay:{}ms)\n",
peer_device_info.name,
peer_device_info.virtual_ip,
server_rt * 2
)
} else {
format!(
"[{}] {}(relay)\n",
peer_device_info.name, peer_device_info.virtual_ip
)
};
style(str).blue().to_string()
}
} else {
let str = format!(
"[{}] {}(Offline)\n",
peer_device_info.name, peer_device_info.virtual_ip
);
style(str).red().to_string()
};
out_str.push_str(&str);
}
}
"status" => {
let server_rt = switch.server_rt();
let current_device = switch.current_device();
let str = format!("Virtual ip:{}\n", style(current_device.virtual_ip).green());
out_str.push_str(&str);
let str = format!(
"Virtual gateway:{}\n",
style(current_device.virtual_gateway).green()
);
out_str.push_str(&str);
let str = format!(
"Connection status :{}\n",
style(format!("{:?}", switch.connection_status())).green()
);
out_str.push_str(&str);
let str = format!(
"Relay server :{}\n",
style(current_device.connect_server).green()
);
out_str.push_str(&str);
if server_rt >= 0 {
let str = format!("Delay of relay server :{}ms\n", style(server_rt).green());
out_str.push_str(&str);
}
}
"help" | "h" => {
let str = format!("Options: \n");
out_str.push_str(&str);
let str = format!(
"{} , Query the virtual IP of other devices\n",
style("list").green()
);
out_str.push_str(&str);
let str = format!("{} , View current device status\n", style("status").green());
out_str.push_str(&str);
let str = format!("{} , Exit the program\n", style("exit").green());
out_str.push_str(&str);
}
"exit" => {
switch.stop_async();
}
_ => {
let str = format!("command '{}' not fount. \n", style(cmd).red());
out_str.push_str(&str);
let str = format!("Try to enter: '{}'\n", style("help").green());
out_str.push_str(&str);
}
}
Ok(out_str)
}