From 05c85db52a17f8988d2e0fac8adf78431673d7d7 Mon Sep 17 00:00:00 2001 From: lubeilin <1791778603@qq.com> Date: Thu, 5 Jan 2023 21:40:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=B2=E7=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 4 +- src/handle/mod.rs | 12 +++--- src/handle/punch_handler.rs | 6 +-- src/handle/tun_handler.rs | 2 +- src/handle/udp_recv_handler.rs | 11 ++--- src/main.rs | 30 ++++++++++++++ src/nat/check.rs | 5 ++- src/tun_device/linux.rs | 39 ++++++++++++++++++ src/tun_device/mac.rs | 68 +++++++++++++++++++++++++++++++ src/tun_device/mod.rs | 19 +++++---- src/tun_device/unix.rs | 74 ++-------------------------------- src/tun_device/windows.rs | 1 + 12 files changed, 175 insertions(+), 96 deletions(-) create mode 100644 src/tun_device/linux.rs create mode 100644 src/tun_device/mac.rs diff --git a/Cargo.toml b/Cargo.toml index b0beeb1..a98859f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,9 @@ edition = "2021" [dependencies] packet = { path = "./packet" } bytes = "1.3.0" - +log = "0.4.17" +log4rs = "1.2.0" +dirs = "4.0.0" libc = "0.2.137" dashmap = "5.4.0" diff --git a/src/handle/mod.rs b/src/handle/mod.rs index e59b538..bb0d57f 100644 --- a/src/handle/mod.rs +++ b/src/handle/mod.rs @@ -1,4 +1,4 @@ -use std::net::{ Ipv4Addr, SocketAddr}; +use std::net::{Ipv4Addr, SocketAddr}; use std::sync::atomic::AtomicI64; use std::time::Duration; @@ -84,13 +84,13 @@ pub fn init_nat_info(public_ip: u32, public_port: u16) { pub struct CurrentDeviceInfo { pub(crate) virtual_ip: Ipv4Addr, pub(crate) virtual_gateway: Ipv4Addr, - pub(crate) virtual_netmask: Ipv4Addr, + pub(crate) virtual_netmask: Ipv4Addr, //网络地址 - pub(crate) virtual_network: Ipv4Addr, + pub(crate) virtual_network: Ipv4Addr, //直接广播地址 - pub(crate) broadcast_address: Ipv4Addr, + pub(crate) broadcast_address: Ipv4Addr, //链接的服务器地址 - pub(crate) connect_server: SocketAddr, + pub(crate) connect_server: SocketAddr, } impl CurrentDeviceInfo { @@ -112,7 +112,7 @@ impl CurrentDeviceInfo { } } -#[derive(Clone,Debug)] +#[derive(Clone, Debug)] pub struct Route { pub(crate) address: SocketAddr, //用心跳探测延迟,收包时更新 diff --git a/src/handle/punch_handler.rs b/src/handle/punch_handler.rs index 93d5226..85c3ca9 100644 --- a/src/handle/punch_handler.rs +++ b/src/handle/punch_handler.rs @@ -215,7 +215,7 @@ pub fn res_symmetric_handle_loop( } } if let Err(e) = handle(&udp, list, packet.buffer()) { - println!("{:?}", e); + log::error!("{:?}",e) } } Err(RecvTimeoutError::Timeout) => { @@ -269,7 +269,7 @@ pub fn handle_loop( } } if let Err(e) = handle(&udp, list, packet.buffer()) { - println!("{:?}", e); + log::error!("{:?}",e) } } Err(_) => { @@ -302,7 +302,7 @@ fn punch_request_handle(udp: &UdpSocket, cur_info: &CurrentDeviceInfo) -> Result if let Err(e) = send_punch(&udp, &cur_info, nat_info) { - println!("发送打洞数据失败 :{:?}", e); + log::error!("发送打洞数据失败 {:?}",e) } Ok(()) } else { diff --git a/src/handle/tun_handler.rs b/src/handle/tun_handler.rs index 99d8cc0..7fd4e79 100644 --- a/src/handle/tun_handler.rs +++ b/src/handle/tun_handler.rs @@ -120,7 +120,7 @@ pub fn handle_loop( match handle(&udp, data, &cur_info, &mut net_packet) { Ok(_) => {} Err(e) => { - println!("{:?}", e) + log::error!("{:?}",e) } } } diff --git a/src/handle/udp_recv_handler.rs b/src/handle/udp_recv_handler.rs index d548c77..f9f86c1 100644 --- a/src/handle/udp_recv_handler.rs +++ b/src/handle/udp_recv_handler.rs @@ -59,7 +59,8 @@ pub fn recv_loop( } } Err(e) => { - println!("{:?}", e); + log::error!("{:?}",e); + // println!("{:?}", e); } }; } @@ -115,7 +116,7 @@ fn recv_handle( return Err(Error::Stop("处理线程停止".to_string())); } Err(e) => { - println!("子线程处理 :{:?}", e); + log::error!("子线程处理 {:?}",e); } } } @@ -137,7 +138,7 @@ pub fn other_loop( return Err(Error::Stop(str)); } Err(e) => { - println!("{:?}", e) + log::error!("other_loop {:?}",e); } } } @@ -194,7 +195,7 @@ fn other_handle( } } InErrorPacket::OtherError(e) => { - println!("{:?}", e.message()); + log::error!("OtherError {:?}",e.message()); } } } @@ -292,7 +293,7 @@ fn other_handle( } } Protocol::UnKnow(p) => { - println!("未知协议:{}", p) + log::error!("未知协议 {}",p); } } Ok(()) diff --git a/src/main.rs b/src/main.rs index 7d06b16..3444ae3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,29 @@ struct Args { token: String, } +fn log_init() { + let home = dirs::home_dir().unwrap().join(".switch"); + if !home.exists() { + std::fs::create_dir(&home).expect(" Failed to create '.switch' directory"); + } + let logfile = log4rs::append::file::FileAppender::builder() + // Pattern: https://docs.rs/log4rs/*/log4rs/encode/pattern/index.html + .encoder(Box::new(log4rs::encode::pattern::PatternEncoder::new("{d(%+)(utc)} [{f}:{L}] {h({l})} {M}:{m}{n}\n"))) + .build(home.join("switch.log")) + .unwrap(); + let config = log4rs::Config::builder() + .appender(log4rs::config::Appender::builder().build("logfile", Box::new(logfile))) + .build( + log4rs::config::Root::builder() + .appender("logfile") + .build(log::LevelFilter::Info), + ) + .unwrap(); + let _ = log4rs::init_config(config); +} + fn main() { + log_init(); let args = Args::parse(); #[cfg(windows)] if !admin_check::is_app_elevated() { @@ -72,6 +94,7 @@ fn main() { if e.kind() == io::ErrorKind::AddrInUse { port += 1; } else { + log::error!("创建udp失败 {:?}",e); println!("创建udp失败:{:?}", e); panic!() } @@ -101,6 +124,7 @@ fn main() { let udp = udp.try_clone().unwrap(); let _ = thread::spawn(move || { if let Err(e) = handle::heartbeat_handler::handle_loop(udp, server_address) { + log::error!("心跳线程停止 {:?}",e); println!("心跳线程停止:{:?}", e); } std::process::exit(1); @@ -127,6 +151,7 @@ fn main() { tun_writer, current_device, ) { + log::error!("udp数据处理线程停止 {:?}",e); println!("udp数据处理线程停止:{:?}", e); } std::process::exit(1); @@ -135,6 +160,7 @@ fn main() { 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) { + log::error!("udp数据处理线程停止 {:?}",e); println!("udp数据处理线程停止:{:?}", e); } std::process::exit(1); @@ -146,6 +172,7 @@ fn main() { let _ = thread::spawn(move || { let current_device = CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, server_address); if let Err(e) = handle::punch_handler::cone_handle_loop(cone_receiver, udp1, current_device) { + log::error!("打洞响应线程停止 {:?}",e); println!("打洞响应线程停止:{:?}", e); } }); @@ -153,6 +180,7 @@ fn main() { let _ = thread::spawn(move || { let current_device = CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, server_address); if let Err(e) = handle::punch_handler::req_symmetric_handle_loop(req_symmetric_receiver, udp1, current_device) { + log::error!("打洞触发线程停止 {:?}",e); println!("打洞触发线程停止:{:?}", e); } }); @@ -160,6 +188,7 @@ fn main() { let _ = thread::spawn(move || { let current_device = CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, server_address); if let Err(e) = handle::punch_handler::res_symmetric_handle_loop(res_symmetric_receiver, udp1, current_device) { + log::error!("打洞触发线程停止 {:?}",e); println!("打洞触发线程停止:{:?}", e); } }); @@ -170,6 +199,7 @@ fn main() { 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) { + log::error!("tun数据处理线程停止 {:?}",e); println!("tun数据处理线程停止:{:?}", e); } std::process::exit(1); diff --git a/src/nat/check.rs b/src/nat/check.rs index e042778..558f7fb 100644 --- a/src/nat/check.rs +++ b/src/nat/check.rs @@ -148,9 +148,10 @@ pub fn nat_test_() -> io::Result { } Ok(NatType::Cone) } + #[test] -fn nat_test_run(){ +fn nat_test_run() { let udp = UdpSocket::bind("0.0.0.0:101").unwrap(); let print = public_ip_list_(&udp).unwrap(); - println!("{:?}",print); + println!("{:?}", print); } \ No newline at end of file diff --git a/src/tun_device/linux.rs b/src/tun_device/linux.rs new file mode 100644 index 0000000..11df490 --- /dev/null +++ b/src/tun_device/linux.rs @@ -0,0 +1,39 @@ +use std::io; +use std::io::{Error, Read, Write}; +use std::net::Ipv4Addr; +use std::os::unix::process::CommandExt; +use std::process::Command; + +use bytes::BufMut; +use tun::Device; +use tun::platform::posix::{Reader, Writer}; + +use crate::tun_device::{TunReader, TunWriter}; + +pub fn create_tun( + address: Ipv4Addr, + netmask: Ipv4Addr, + gateway: Ipv4Addr, +) -> crate::error::Result<(TunWriter, TunReader)> { + let mut config = tun::Configuration::default(); + + config + .destination(gateway) + .address(address) + .netmask(netmask) + .mtu(1420) + .up(); + + config.platform(|config| { + config.packet_information(true); + }); + + let mut dev = tun::create(&config).unwrap(); + let packet_information = dev.has_packet_information(); + let (reader, writer) = dev.split(); + Ok(( + TunWriter(writer, packet_information), + TunReader(reader, packet_information), + )) +} + diff --git a/src/tun_device/mac.rs b/src/tun_device/mac.rs new file mode 100644 index 0000000..0e0db6b --- /dev/null +++ b/src/tun_device/mac.rs @@ -0,0 +1,68 @@ +use std::io; +use std::io::{Error, Read, Write}; +use std::net::Ipv4Addr; +use std::os::unix::process::CommandExt; +use std::process::Command; + +use bytes::BufMut; +use tun::Device; +use tun::platform::posix::{Reader, Writer}; + +use crate::tun_device::{TunReader, TunWriter}; + +pub fn create_tun( + address: Ipv4Addr, + netmask: Ipv4Addr, + gateway: Ipv4Addr, +) -> crate::error::Result<(TunWriter, TunReader)> { + let mut config = tun::Configuration::default(); + + config + .destination(gateway) + .address(address) + .netmask(netmask) + .mtu(1420) + .up(); + + let dev = tun::create(&config).unwrap(); + let up_eth_str: String = format!("ifconfig {} {:?} {:?} up ", dev.name(), address, gateway); + let route_add_str: String = format!( + "sudo route -n add -net {:?} -netmask {:?} {:?}", + address, netmask, gateway + ); + let up_eth_out = Command::new("sh") + .arg("-c") + .arg(up_eth_str) + .output() + .expect("sh exec error!"); + if !up_eth_out.status.success() { + return Err(crate::error::Error::Stop(format!("设置地址失败:{:?}", up_eth_out))); + } + let if_config_out = Command::new("sh") + .arg("-c") + .arg(route_add_str) + .output() + .expect("sh exec error!"); + if !if_config_out.status.success() { + return Err(crate::error::Error::Stop(format!("设置路由失败:{:?}", if_config_out))); + } + // println!("{:?}", if_config_out); + // let cmd_str: String = " ifconfig|grep flags=8051|awk -F ':' '{print $1}'|tail -1".to_string(); + // + // let cmd_str_out = Command::new("sh") + // .arg("-c") + // .arg(cmd_str) + // .output() + // .expect("sh exec error!"); + // if !cmd_str_out.status.success(){ + // return Err(Error::Stop(format!("设置路由失败:{:?}", cmd_str_out))); + // } + // println!("{:?}", cmd_str_out); + let packet_information = dev.has_packet_information(); + let (reader, writer) = dev.split(); + Ok(( + TunWriter(writer, packet_information), + TunReader(reader, packet_information), + )) +} + diff --git a/src/tun_device/mod.rs b/src/tun_device/mod.rs index 410b2cc..1c61abd 100644 --- a/src/tun_device/mod.rs +++ b/src/tun_device/mod.rs @@ -1,14 +1,19 @@ - -#[cfg(any(unix))] -pub use unix::create_tun; +#[cfg(target_os = "linux")] +pub use linux::create_tun; +#[cfg(target_os = "macos")] +pub use mac::create_tun; #[cfg(any(unix))] pub use unix::{TunReader, TunWriter}; +#[cfg(target_os = "windows")] +pub use windows::{TunReader, TunWriter}; +#[cfg(target_os = "windows")] +pub use windows::create_tun; +#[cfg(target_os = "macos")] +pub mod mac; +#[cfg(target_os = "linux")] +pub mod linux; #[cfg(any(unix))] pub mod unix; #[cfg(target_os = "windows")] pub mod windows; -#[cfg(target_os = "windows")] -pub use windows::create_tun; -#[cfg(target_os = "windows")] -pub use windows::{TunReader, TunWriter}; diff --git a/src/tun_device/unix.rs b/src/tun_device/unix.rs index a590581..04f4145 100644 --- a/src/tun_device/unix.rs +++ b/src/tun_device/unix.rs @@ -1,78 +1,10 @@ use std::io; -use std::io::{Error, Read, Write}; -use std::net::Ipv4Addr; -use std::os::unix::process::CommandExt; -use std::process::Command; +use std::io::{Read, Write}; use bytes::BufMut; -use tun::Device; use tun::platform::posix::{Reader, Writer}; -pub fn create_tun( - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, -) -> crate::error::Result<(TunWriter, TunReader)> { - let mut config = tun::Configuration::default(); - - config - .destination(gateway) - .address(address) - .netmask(netmask) - .mtu(1420) - .up(); - - #[cfg(target_os = "linux")] - config.platform(|config| { - config.packet_information(true); - }); - - let mut dev = tun::create(&config).unwrap(); - - // let up_eth_str: String = format!("ifconfig utun3 {:?} {:?} up ", address, gateway); - let route_add_str: String = format!( - "sudo route -n add -net {:?} -netmask {:?} {:?}", - address, netmask, gateway - ); - // - // let up_eth_out = Command::new("sh") - // .arg("-c") - // .arg(up_eth_str) - // .output() - // .expect("sh exec error!"); - // if !up_eth_out.status.success() { - // return Err(crate::error::Error::Stop(format!("设置地址失败:{:?}", up_eth_out))); - // } - // println!("{:?}", up_eth_out); - let if_config_out = Command::new("sh") - .arg("-c") - .arg(route_add_str) - .output() - .expect("sh exec error!"); - if !if_config_out.status.success() { - return Err(crate::error::Error::Stop(format!("设置路由失败:{:?}", if_config_out))); - } - // println!("{:?}", if_config_out); - // let cmd_str: String = " ifconfig|grep flags=8051|awk -F ':' '{print $1}'|tail -1".to_string(); - // - // let cmd_str_out = Command::new("sh") - // .arg("-c") - // .arg(cmd_str) - // .output() - // .expect("sh exec error!"); - // if !cmd_str_out.status.success(){ - // return Err(Error::Stop(format!("设置路由失败:{:?}", cmd_str_out))); - // } - // println!("{:?}", cmd_str_out); - let packet_information = dev.has_packet_information(); - let (reader, writer) = dev.split(); - Ok(( - TunWriter(writer, packet_information), - TunReader(reader, packet_information), - )) -} - -pub struct TunReader(Reader, bool); +pub struct TunReader(pub(crate) Reader, pub(crate) bool); impl TunReader { pub fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> io::Result<&mut [u8]> { @@ -85,7 +17,7 @@ impl TunReader { } } -pub struct TunWriter(Writer, bool); +pub struct TunWriter(pub(crate) Writer, pub(crate) bool); impl TunWriter { pub fn write(&mut self, packet: &[u8]) -> io::Result<()> { diff --git a/src/tun_device/windows.rs b/src/tun_device/windows.rs index 524d79d..8f753e5 100644 --- a/src/tun_device/windows.rs +++ b/src/tun_device/windows.rs @@ -51,6 +51,7 @@ pub fn create_tun( } }, Err(e) => { + log::error!("wintun.dll not found"); println!("{}", console::style("wintun.dll not found").red()); return Err(Error::Stop(format!("{:?}", e))); }