增加命令
This commit is contained in:
+2
-16
@@ -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"
|
||||
@@ -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
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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(());
|
||||
|
||||
@@ -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
@@ -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(), ¤t_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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
/// 探测目标延迟
|
||||
|
||||
@@ -51,6 +51,7 @@ pub fn create_tun(
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
println!("{}", console::style("wintun.dll not found").red());
|
||||
return Err(Error::Stop(format!("{:?}", e)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user