增加命令

This commit is contained in:
lubeilin
2023-01-04 22:09:59 +08:00
parent e37b4d718b
commit d4f941d4e7
9 changed files with 119 additions and 51 deletions
+2 -16
View File
@@ -1,5 +1,5 @@
[package]
name = "virtual_network"
name = "switch"
version = "0.1.0"
edition = "2021"
@@ -18,7 +18,7 @@ parking_lot = "0.12.1"
rsa = "0.7.2"
rand = "0.8.5"
sha2 = { version = "0.10.6", features = ["oid"] }
colored = "2.0.0"
#colored = "2.0.0"
thiserror = "1.0.37"
chrono = "0.4.23"
@@ -29,7 +29,6 @@ protobuf = "3.2.0"
console = "0.15.2"
mac_address = "1.1.4"
clap = { version = "4.0.32", features = ["derive"] }
#clap_derive = "4.0.21"
[target.'cfg(any(unix))'.dependencies]
tun = { version = "0.5" }
sudo = "0.6.0"
@@ -40,19 +39,6 @@ wintun = "0.2.1"
libloading = "0.7.4"
runas = "0.2.1"
#[dependencies.windows]
#
#libloading = "0.7.4"
#
#version = "0.37.0"
#features = [
# "alloc",
# "Win32_Foundation",
# "Win32_NetworkManagement_IpHelper",
# "Win32_Networking_WinSock",
# "Win32_UI_WindowsAndMessaging",
# "Win32_System_IO"
#]
[build-dependencies]
protobuf-codegen = "3.2.0"
protoc-bin-vendored = "3.0.0"
+7 -7
View File
@@ -4,15 +4,15 @@ use std::time::Duration;
use chrono::Local;
use crate::DEVICE_LIST;
use crate::error::*;
use crate::handle::DIRECT_ROUTE_TABLE;
use crate::protocol::control_packet::PingPacket;
use crate::protocol::{control_packet, NetPacket, Protocol, Version};
use crate::DEVICE_LIST;
use crate::protocol::control_packet::PingPacket;
pub fn handle_loop(udp: UdpSocket, server_addr: SocketAddr) -> Result<()> {
const INTERVAL: u64 = 3000;
const MAX_INTERVAL: i64 = 3000 * 5;
const MAX_INTERVAL: i64 = 3000 * 3;
let mut buf = [0u8; (4 + 8 + 4)];
let mut net_packet = NetPacket::new(&mut buf)?;
net_packet.set_version(Version::V1);
@@ -20,23 +20,23 @@ pub fn handle_loop(udp: UdpSocket, server_addr: SocketAddr) -> Result<()> {
net_packet.set_transport_protocol(control_packet::Protocol::Ping.into());
net_packet.set_ttl(255);
loop {
let current_time = Local::now().timestamp();
let current_time = Local::now().timestamp_millis();
{
let mut ping = PingPacket::new(net_packet.payload_mut())?;
ping.set_time(current_time);
let epoch = { DEVICE_LIST.lock().0 };
ping.set_epoch(epoch);
}
udp.send_to(net_packet.buffer(), server_addr)?;
let _ = udp.send_to(net_packet.buffer(), server_addr);
for x in DIRECT_ROUTE_TABLE.iter() {
let virtual_ip = x.key().clone();
let route = x.value().clone();
drop(x);
if current_time - route.recv_time <= MAX_INTERVAL {
udp.send_to(net_packet.buffer(), route.address)?;
let _ = udp.send_to(net_packet.buffer(), route.address);
} else {
DIRECT_ROUTE_TABLE.remove_if(&virtual_ip, |_, route| {
current_time - route.recv_time > MAX_INTERVAL
current_time - route.recv_time <= MAX_INTERVAL
});
}
}
+10 -10
View File
@@ -82,15 +82,15 @@ pub fn init_nat_info(public_ip: u32, public_port: u16) {
#[derive(Clone, Debug)]
pub struct CurrentDeviceInfo {
virtual_ip: Ipv4Addr,
virtual_gateway: Ipv4Addr,
virtual_netmask: Ipv4Addr,
pub(crate) virtual_ip: Ipv4Addr,
pub(crate) virtual_gateway: Ipv4Addr,
pub(crate) virtual_netmask: Ipv4Addr,
//网络地址
virtual_network: Ipv4Addr,
pub(crate) virtual_network: Ipv4Addr,
//直接广播地址
broadcast_address: Ipv4Addr,
pub(crate) broadcast_address: Ipv4Addr,
//链接的服务器地址
connect_server: SocketAddr,
pub(crate) connect_server: SocketAddr,
}
impl CurrentDeviceInfo {
@@ -114,11 +114,11 @@ impl CurrentDeviceInfo {
#[derive(Clone,Debug)]
pub struct Route {
address: SocketAddr,
pub(crate) address: SocketAddr,
//用心跳探测延迟,收包时更新
delay: i64,
pub(crate) delay: i64,
//收包时更新,如果太久没有收到消息则剔除
recv_time: i64,
pub(crate) recv_time: i64,
}
impl Route {
@@ -126,7 +126,7 @@ impl Route {
Self {
address,
delay: -1,
recv_time: Local::now().timestamp(),
recv_time: Local::now().timestamp_millis(),
}
}
}
+2 -2
View File
@@ -91,7 +91,7 @@ fn registration_request_packet(token: String, mac_address: String) -> Result<Net
pub fn fast_registration(udp: &UdpSocket, server_address: SocketAddr) -> Result<()> {
let last = REGISTRATION_TIME.load(Ordering::Relaxed);
let new = Local::now().timestamp();
let new = Local::now().timestamp_millis();
if new - last < 2000
|| REGISTRATION_TIME
.compare_exchange(last, new, Ordering::Relaxed, Ordering::Relaxed)
@@ -106,7 +106,7 @@ pub fn fast_registration(udp: &UdpSocket, server_address: SocketAddr) -> Result<
if let Some((token, mac_address)) = option {
let request_packet = registration_request_packet(token, mac_address)?;
udp.send_to(request_packet.buffer(), server_address)?;
REGISTRATION_TIME.store(Local::now().timestamp(), Ordering::Relaxed);
REGISTRATION_TIME.store(Local::now().timestamp_millis(), Ordering::Relaxed);
return Ok(());
}
return Err(Error::Stop("注册信息不存在".to_string()));
+1 -1
View File
@@ -71,7 +71,7 @@ fn handle(
ipv4_turn_packet.set_payload(ipv4_packet.buffer);
//优先发到直连到地址
if let Some(route) = DIRECT_ROUTE_TABLE.get(&dest_ip) {
let current_time = Local::now().timestamp();
let current_time = Local::now().timestamp_millis();
if current_time - route.recv_time < 3_000 {
udp.send_to(&net_packet.buffer()[..(4 + 8 + data_len)], route.address)?;
return Ok(());
+2 -2
View File
@@ -200,12 +200,12 @@ fn other_handle(
}
Protocol::Control => {
match ControlPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
ControlPacket::PingPacket(_) => {
ControlPacket::PingPacket(ping) => {
net_packet.set_transport_protocol(control_packet::Protocol::Pong.into());
udp.send_to(&net_packet.buffer()[..12], peer_addr)?;
}
ControlPacket::PongPacket(pong_packet) => {
let current_time = Local::now().timestamp();
let current_time = Local::now().timestamp_millis();
let rt = current_time - pong_packet.time();
if rt >= 0 {
if peer_addr == server_addr {
+76 -13
View File
@@ -1,11 +1,11 @@
use std::{io, thread};
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
use std::sync::atomic::Ordering;
use clap::Parser;
use console::style;
use crossbeam::sync::Parker;
use crate::handle::{CurrentDeviceInfo, DEVICE_LIST, NAT_INFO, NatInfo};
use crate::handle::{CurrentDeviceInfo, DEVICE_LIST, DIRECT_ROUTE_TABLE, NAT_INFO, NatInfo, SERVER_RT};
use crate::handle::registration_handler::registration;
use crate::tun_device::create_tun;
@@ -96,16 +96,14 @@ fn main() {
println!("virtual_gateway:{:?}", virtual_gateway);
println!("virtual_netmask:{:?}", virtual_netmask);
println!("当前设备ip(virtual_ip):{}", style(virtual_ip).green());
let parker = Parker::new();
//心跳线程
{
let un_parker = parker.unparker().clone();
let udp = udp.try_clone().unwrap();
let _ = thread::spawn(move || {
if let Err(e) = handle::heartbeat_handler::handle_loop(udp, server_address) {
println!("心跳线程停止:{:?}", e);
}
un_parker.unpark();
std::process::exit(1);
});
}
//初始化nat数据
@@ -117,7 +115,6 @@ fn main() {
let (punch_sender, cone_receiver, req_symmetric_receiver, res_symmetric_receiver) = handle::punch_handler::bounded();
//udp数据处理
{
let un_parker = parker.unparker().clone();
// 低优先级的udp数据通道
let (sender, receiver) = crossbeam::channel::bounded(100);
let udp1 = udp.try_clone().unwrap();
@@ -132,16 +129,15 @@ fn main() {
) {
println!("udp数据处理线程停止:{:?}", e);
}
un_parker.unpark();
std::process::exit(1);
});
let udp1 = udp.try_clone().unwrap();
let un_parker = parker.unparker().clone();
let _ = thread::spawn(move || {
let current_device = CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, server_address);
if let Err(e) = handle::udp_recv_handler::other_loop(udp1, receiver, current_device, punch_sender) {
println!("udp数据处理线程停止:{:?}", e);
}
un_parker.unpark();
std::process::exit(1);
});
}
//打洞处理
@@ -171,15 +167,82 @@ fn main() {
//tun数据处理
{
let udp = udp.try_clone().unwrap();
let un_parker = parker.unparker().clone();
let _ = thread::spawn(move || {
let current_device = CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, server_address);
if let Err(e) = handle::tun_handler::handle_loop(udp, tun_reader, current_device) {
println!("tun数据处理线程停止:{:?}", e);
}
un_parker.unpark();
std::process::exit(1);
});
}
parker.park();
std::process::exit(1);
use console::Term;
let term = Term::stdout();
let current_device = CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, server_address);
loop {
println!("{}", style("Please enter the command (Usage: list,status,exit,help):").color256(102));
match term.read_line() {
Ok(cmd) => {
command(cmd.trim(), &current_device);
}
Err(e) => {
println!("read_line:{:?}", e);
std::process::exit(1);
}
}
}
}
fn command(cmd: &str, current_device: &CurrentDeviceInfo) {
match cmd {
"list" => {
let server_delay = SERVER_RT.load(Ordering::Relaxed);
let device_list_lock = DEVICE_LIST.lock();
let (_epoch, device_list) = device_list_lock.clone();
drop(device_list_lock);
if device_list.is_empty() {
println!("No other devices found");
return;
}
for ip in device_list {
if let Some(route_ref) = DIRECT_ROUTE_TABLE.get(&ip) {
let str = if route_ref.value().delay >= 0 {
format!("{}(p2p delay:{}ms)", ip, route_ref.value().delay)
} else {
format!("{}(p2p)", ip)
};
drop(route_ref);
println!("{}", style(str).green());
} else {
let str = if server_delay >= 0 {
format!("{}(relay delay:{}ms)", ip, server_delay * 2)
} else {
format!("{}(relay)", ip)
};
println!("{}", style(str).blue());
}
}
}
"status" => {
let server_delay = SERVER_RT.load(Ordering::Relaxed);
println!("Virtual ip:{}", style(current_device.virtual_ip).green());
println!("Virtual gateway:{}", style(current_device.virtual_gateway).green());
println!("Relay server :{}", style(current_device.connect_server).green());
if server_delay >= 0 {
println!("Delay of relay server :{}", style(server_delay).green());
}
}
"help" | "h" => {
println!("Options: ");
println!("{} , Query the virtual IP of other devices", style("list").green());
println!("{} , View current device status", style("status").green());
println!("{} , Exit the program", style("exit").green());
}
"exit" => {
std::process::exit(1);
}
_ => {
println!("command {} not fount. ", style(cmd).red());
println!("Try to enter: '{}'", style("help").green());
}
}
}
+18
View File
@@ -70,6 +70,7 @@ pub struct PongPacket<B> {
buffer: B,
}
impl<B: AsRef<[u8]>> PingPacket<B> {
pub fn new(buffer: B) -> Result<PingPacket<B>> {
let len = buffer.as_ref().len();
@@ -98,6 +99,15 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> PingPacket<B> {
}
}
impl<B: AsRef<[u8]>> fmt::Debug for PingPacket<B> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PingPacket")
.field("time", &self.time())
.field("epoch", &self.epoch())
.finish()
}
}
impl<B: AsRef<[u8]>> PongPacket<B> {
pub fn new(buffer: B) -> Result<PongPacket<B>> {
let len = buffer.as_ref().len();
@@ -120,6 +130,14 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> PongPacket<B> {
}
}
impl<B: AsRef<[u8]>> fmt::Debug for PongPacket<B> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PongPacket")
.field("time", &self.time())
.finish()
}
}
pub type TurnPongPacket<B> = TurnPingPacket<B>;
/// 探测目标延迟
+1
View File
@@ -51,6 +51,7 @@ pub fn create_tun(
}
},
Err(e) => {
println!("{}", console::style("wintun.dll not found").red());
return Err(Error::Stop(format!("{:?}", e)));
}
}