diff --git a/vnt-cli/Cargo.toml b/vnt-cli/Cargo.toml index dfe9120..c7ece4d 100644 --- a/vnt-cli/Cargo.toml +++ b/vnt-cli/Cargo.toml @@ -30,7 +30,7 @@ signal-hook = "0.3.17" winapi = { version = "0.3.9", features = ["handleapi", "processthreadsapi", "winnt", "securitybaseapi", "impl-default"] } [features] -default = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "log", "command", "file_config", "lz4"] +default = ["vnt/inner_tun","server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "log", "command", "file_config", "lz4"] openssl = ["vnt/openssl"] openssl-vendored = ["vnt/openssl-vendored"] ring-cipher = ["vnt/ring-cipher"] diff --git a/vnt/Cargo.toml b/vnt/Cargo.toml index b72442d..bc5c186 100644 --- a/vnt/Cargo.toml +++ b/vnt/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tun = { path = "tun" } +tun = { path = "tun" ,optional = true} packet = { path = "./packet" } bytes = "1.5.0" log = "0.4.17" @@ -53,7 +53,7 @@ protoc-bin-vendored = "3.0.0" cfg_aliases = "0.2.1" [features] -default = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "lz4_compress", "zstd_compress"] +default = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "lz4_compress", "zstd_compress","inner_tun"] openssl = ["openssl-sys"] # 从源码编译 openssl-vendored = ["openssl-sys/vendored"] @@ -68,3 +68,4 @@ ip_proxy = ["tokio"] port_mapping = ["tokio"] lz4_compress = ["lz4_flex"] zstd_compress = ["zstd"] +inner_tun = ["tun"] diff --git a/vnt/src/core/conn.rs b/vnt/src/core/conn.rs index ada0196..7d14533 100644 --- a/vnt/src/core/conn.rs +++ b/vnt/src/core/conn.rs @@ -1,4 +1,3 @@ -use anyhow::Context; use std::collections::HashMap; use std::net::Ipv4Addr; use std::sync::Arc; @@ -7,8 +6,6 @@ use std::time::Duration; use crossbeam_utils::atomic::AtomicCell; use parking_lot::{Mutex, RwLock}; use rand::Rng; -#[cfg(not(target_os = "android"))] -use tun::device::IFace; use crate::channel::context::ChannelContext; use crate::channel::idle::Idle; @@ -24,13 +21,13 @@ use crate::handle::maintain::PunchReceiver; use crate::handle::recv_data::RecvDataHandler; use crate::handle::{maintain, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo}; use crate::nat::NatTest; +#[cfg(feature = "inner_tun")] use crate::tun_tap_device::tun_create_helper::{DeviceAdapter, TunDeviceHelper}; +use crate::tun_tap_device::vnt_device::DeviceWrite; use crate::util::{ Scheduler, SingleU64Adder, StopManager, U64Adder, WatchSingleU64Adder, WatchU64Adder, }; use crate::{nat, VntCallback}; -#[cfg(not(target_os = "android"))] -use crate::{tun_tap_device, DeviceInfo}; #[derive(Clone)] pub struct Vnt { @@ -47,7 +44,23 @@ pub struct Vnt { } impl Vnt { + #[cfg(feature = "inner_tun")] pub fn new(config: Config, callback: Call) -> anyhow::Result { + Vnt::new_device0(config, callback, DeviceAdapter::default()) + } + #[cfg(not(feature = "inner_tun"))] + pub fn new_device( + config: Config, + callback: Call, + device: Device, + ) -> anyhow::Result { + Vnt::new_device0(config, callback, device) + } + fn new_device0( + config: Config, + callback: Call, + device: Device, + ) -> anyhow::Result { log::info!("config.toml:{:?}", config); //服务端非对称加密 #[cfg(feature = "server_encrypt")] @@ -85,6 +98,11 @@ impl Vnt { config.device_id.clone(), config.server_address_str.clone(), config.name_servers.clone(), + config.mtu.unwrap_or(1420), + #[cfg(target_os = "windows")] + config.tap, + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + config.device_name.clone(), ); // 服务停止管理器 let stop_manager = { @@ -129,21 +147,6 @@ impl Vnt { udp_ports, tcp_port, ); - - // pc上先创建虚拟网卡 - #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] - let device = { - log::info!("开始创建tun"); - let device = tun_tap_device::create_device(&config).context("create tun failed")?; - log::info!("创建tun成功"); - let tun_info = DeviceInfo::new( - device.name().unwrap_or("unknown".into()), - device.version().unwrap_or("unknown".into()), - ); - log::info!("tun信息{:?}", tun_info); - callback.create_tun(tun_info); - device - }; // 定时器 let scheduler = Scheduler::new(stop_manager.clone())?; let external_route = ExternalRoute::new(config.in_ips.clone()); @@ -172,24 +175,23 @@ impl Vnt { ); let up_counter = SingleU64Adder::new(); let up_count_watcher = up_counter.watch(); - let tun_helper = TunDeviceHelper::new( - stop_manager.clone(), - context.clone(), - current_device.clone(), - external_route.clone(), - #[cfg(feature = "ip_proxy")] - proxy_map.clone(), - client_cipher.clone(), - server_cipher.clone(), - config.parallel, - up_counter, - device_list.clone(), - config.compressor, - ); - #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] - let device_adapter = DeviceAdapter::new(device.clone()); - #[cfg(target_os = "android")] - let device_adapter = DeviceAdapter::new(tun_helper); + #[cfg(feature = "inner_tun")] + let tun_device_helper = { + TunDeviceHelper::new( + stop_manager.clone(), + context.clone(), + current_device.clone(), + external_route.clone(), + #[cfg(feature = "ip_proxy")] + proxy_map.clone(), + client_cipher.clone(), + server_cipher.clone(), + up_counter, + device_list.clone(), + config.compressor, + device.clone().into_device_adapter(), + ) + }; let handler = RecvDataHandler::new( #[cfg(feature = "server_encrypt")] @@ -197,7 +199,7 @@ impl Vnt { server_cipher.clone(), client_cipher.clone(), current_device.clone(), - device_adapter, + device, device_list.clone(), config_info.clone(), nat_test.clone(), @@ -210,6 +212,8 @@ impl Vnt { proxy_map.clone(), down_counter, handshake.clone(), + #[cfg(feature = "inner_tun")] + tun_device_helper, ); //初始化网络数据通道 @@ -225,8 +229,8 @@ impl Vnt { nat_test.clone(), ); - #[cfg(not(target_os = "android"))] - tun_helper.start(device)?; + // #[cfg(not(target_os = "android"))] + // tun_helper.start(device)?; maintain::idle_gateway( &scheduler, diff --git a/vnt/src/core/mod.rs b/vnt/src/core/mod.rs index 70fd235..f9c580e 100644 --- a/vnt/src/core/mod.rs +++ b/vnt/src/core/mod.rs @@ -32,13 +32,12 @@ pub struct Config { #[cfg(feature = "ip_proxy")] pub no_proxy: bool, pub server_encrypt: bool, - pub parallel: usize, pub cipher_model: CipherModel, pub finger: bool, pub punch_model: PunchModel, pub ports: Option>, pub first_latency: bool, - #[cfg(not(target_os = "android"))] + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] pub device_name: Option, pub use_channel_type: UseChannelType, //控制丢包率 @@ -67,7 +66,6 @@ impl Config { ip: Option, #[cfg(feature = "ip_proxy")] no_proxy: bool, server_encrypt: bool, - parallel: usize, cipher_model: CipherModel, finger: bool, punch_model: PunchModel, @@ -130,7 +128,6 @@ impl Config { #[cfg(feature = "ip_proxy")] no_proxy, server_encrypt, - parallel, cipher_model, finger, punch_model, diff --git a/vnt/src/handle/callback.rs b/vnt/src/handle/callback.rs index 8e7219c..4e4d0ae 100644 --- a/vnt/src/handle/callback.rs +++ b/vnt/src/handle/callback.rs @@ -189,9 +189,14 @@ impl Into for ErrorType { } } -#[cfg(target_os = "android")] -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct DeviceConfig { + #[cfg(target_os = "windows")] + pub tap: bool, + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + pub device_name: Option, + //虚拟网卡mtu值 + pub mtu: u32, //本机虚拟IP pub virtual_ip: Ipv4Addr, //子网掩码 @@ -204,9 +209,12 @@ pub struct DeviceConfig { pub external_route: Vec<(Ipv4Addr, Ipv4Addr)>, } -#[cfg(target_os = "android")] impl DeviceConfig { pub fn new( + #[cfg(target_os = "windows")] tap: bool, + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + device_name: Option, + mtu: u32, virtual_ip: Ipv4Addr, virtual_netmask: Ipv4Addr, virtual_gateway: Ipv4Addr, @@ -214,6 +222,11 @@ impl DeviceConfig { external_route: Vec<(Ipv4Addr, Ipv4Addr)>, ) -> Self { Self { + #[cfg(target_os = "windows")] + tap, + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + device_name, + mtu, virtual_ip, virtual_netmask, virtual_gateway, @@ -223,7 +236,6 @@ impl DeviceConfig { } } -#[cfg(target_os = "android")] impl Display for DeviceConfig { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&format!( @@ -272,6 +284,7 @@ pub trait VntCallback: Clone + Send + Sync + 'static { /// 创建网卡的信息 #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + #[cfg(feature = "inner_tun")] fn create_tun(&self, _info: DeviceInfo) {} /// 连接 fn connect(&self, _info: ConnectInfo) {} @@ -283,8 +296,16 @@ pub trait VntCallback: Clone + Send + Sync + 'static { fn register(&self, _info: RegisterInfo) -> bool { true } + #[cfg(not(feature = "inner_tun"))] + fn create_device( + &self, + _channel_sender: crate::channel::sender::ChannelSender, + _info: DeviceConfig, + ) { + } #[cfg(target_os = "android")] - fn generate_tun(&self, _info: DeviceConfig) -> u32 { + #[cfg(feature = "inner_tun")] + fn generate_tun(&self, _info: DeviceConfig) -> usize { 0 } fn peer_client_list(&self, _info: Vec) {} diff --git a/vnt/src/handle/mod.rs b/vnt/src/handle/mod.rs index e59631d..208b63d 100644 --- a/vnt/src/handle/mod.rs +++ b/vnt/src/handle/mod.rs @@ -7,6 +7,7 @@ pub mod handshaker; pub mod maintain; pub mod recv_data; pub mod registrar; +#[cfg(feature = "inner_tun")] pub mod tun_tap; const SELF_IP: Ipv4Addr = Ipv4Addr::new(0, 0, 0, 2); @@ -21,12 +22,6 @@ pub fn now_time() -> u64 { } } -/// 是否在一个网段 -fn check_dest(dest: Ipv4Addr, virtual_netmask: Ipv4Addr, virtual_network: Ipv4Addr) -> bool { - u32::from_be_bytes(dest.octets()) & u32::from_be_bytes(virtual_netmask.octets()) - == u32::from_be_bytes(virtual_network.octets()) -} - #[derive(Clone, Debug, Eq, PartialEq)] pub struct PeerDeviceInfo { pub virtual_ip: Ipv4Addr, @@ -64,6 +59,11 @@ pub struct BaseConfigInfo { pub device_id: String, pub server_addr: String, pub name_servers: Vec, + pub mtu: u32, + #[cfg(target_os = "windows")] + pub tap: bool, + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + pub device_name: Option, } impl BaseConfigInfo { @@ -76,6 +76,10 @@ impl BaseConfigInfo { device_id: String, server_addr: String, name_servers: Vec, + mtu: u32, + #[cfg(target_os = "windows")] tap: bool, + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + device_name: Option, ) -> Self { Self { name, @@ -86,6 +90,11 @@ impl BaseConfigInfo { device_id, server_addr, name_servers, + mtu, + #[cfg(target_os = "windows")] + tap, + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + device_name, } } } diff --git a/vnt/src/handle/recv_data/client.rs b/vnt/src/handle/recv_data/client.rs index 5d619d6..b28f31c 100644 --- a/vnt/src/handle/recv_data/client.rs +++ b/vnt/src/handle/recv_data/client.rs @@ -9,8 +9,6 @@ use protobuf::Message; use packet::icmp::{icmp, Kind}; use packet::ip::ipv4; use packet::ip::ipv4::packet::IpV4Packet; -#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] -use tun::device::IFace; use crate::channel::context::ChannelContext; use crate::channel::punch::NatInfo; @@ -30,12 +28,12 @@ use crate::protocol::control_packet::ControlPacket; use crate::protocol::{ control_packet, ip_turn_packet, other_turn_packet, NetPacket, Protocol, MAX_TTL, }; -use crate::tun_tap_device::tun_create_helper::DeviceAdapter; +use crate::tun_tap_device::vnt_device::DeviceWrite; /// 处理来源于客户端的包 #[derive(Clone)] -pub struct ClientPacketHandler { - device: DeviceAdapter, +pub struct ClientPacketHandler { + device: Device, client_cipher: Cipher, punch_sender: PunchSender, peer_nat_info_map: Arc>>, @@ -45,9 +43,9 @@ pub struct ClientPacketHandler { ip_proxy_map: Option, } -impl ClientPacketHandler { +impl ClientPacketHandler { pub fn new( - device: DeviceAdapter, + device: Device, client_cipher: Cipher, punch_sender: PunchSender, peer_nat_info_map: Arc>>, @@ -68,7 +66,7 @@ impl ClientPacketHandler { } } -impl PacketHandler for ClientPacketHandler { +impl PacketHandler for ClientPacketHandler { fn handle( &self, mut net_packet: NetPacket<&mut [u8]>, @@ -110,7 +108,7 @@ impl PacketHandler for ClientPacketHandler { } } -impl ClientPacketHandler { +impl ClientPacketHandler { fn ip_turn( &self, mut net_packet: NetPacket<&mut [u8]>, diff --git a/vnt/src/handle/recv_data/mod.rs b/vnt/src/handle/recv_data/mod.rs index 88362a0..95e7f5d 100644 --- a/vnt/src/handle/recv_data/mod.rs +++ b/vnt/src/handle/recv_data/mod.rs @@ -25,7 +25,7 @@ use crate::handle::{BaseConfigInfo, CurrentDeviceInfo, PeerDeviceInfo, SELF_IP}; use crate::ip_proxy::IpProxyMap; use crate::nat::NatTest; use crate::protocol::{NetPacket, HEAD_LEN}; -use crate::tun_tap_device::tun_create_helper::DeviceAdapter; +use crate::tun_tap_device::vnt_device::DeviceWrite; use crate::util::U64Adder; mod client; @@ -33,16 +33,16 @@ mod server; mod turn; #[derive(Clone)] -pub struct RecvDataHandler { +pub struct RecvDataHandler { current_device: Arc>, turn: TurnPacketHandler, - client: ClientPacketHandler, - server: ServerPacketHandler, + client: ClientPacketHandler, + server: ServerPacketHandler, counter: U64Adder, nat_test: NatTest, } -impl RecvChannelHandler for RecvDataHandler { +impl RecvChannelHandler for RecvDataHandler { fn handle( &mut self, buf: &mut [u8], @@ -75,13 +75,13 @@ impl RecvChannelHandler for RecvDataHandler { } } -impl RecvDataHandler { +impl RecvDataHandler { pub fn new( #[cfg(feature = "server_encrypt")] rsa_cipher: Arc>>, server_cipher: Cipher, client_cipher: Cipher, current_device: Arc>, - device: DeviceAdapter, + device: Device, device_list: Arc)>>, config_info: BaseConfigInfo, nat_test: NatTest, @@ -93,6 +93,8 @@ impl RecvDataHandler { #[cfg(feature = "ip_proxy")] ip_proxy_map: Option, counter: U64Adder, handshake: Handshake, + #[cfg(feature = "inner_tun")] + tun_device_helper: crate::tun_tap_device::tun_create_helper::TunDeviceHelper, ) -> Self { let server = ServerPacketHandler::new( #[cfg(feature = "server_encrypt")] @@ -106,6 +108,8 @@ impl RecvDataHandler { callback, external_route.clone(), handshake, + #[cfg(feature = "inner_tun")] + tun_device_helper, ); let client = ClientPacketHandler::new( device.clone(), diff --git a/vnt/src/handle/recv_data/server.rs b/vnt/src/handle/recv_data/server.rs index 747e3be..0e253d2 100644 --- a/vnt/src/handle/recv_data/server.rs +++ b/vnt/src/handle/recv_data/server.rs @@ -12,8 +12,6 @@ use protobuf::Message; use packet::icmp::{icmp, Kind}; use packet::ip::ipv4; use packet::ip::ipv4::packet::IpV4Packet; -#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] -use tun::device::IFace; use crate::channel::context::ChannelContext; use crate::channel::{Route, RouteKey}; @@ -35,41 +33,43 @@ use crate::protocol::body::ENCRYPTION_RESERVED; use crate::protocol::control_packet::ControlPacket; use crate::protocol::error_packet::InErrorPacket; use crate::protocol::{ip_turn_packet, service_packet, NetPacket, Protocol, MAX_TTL}; -use crate::tun_tap_device::tun_create_helper::DeviceAdapter; +use crate::tun_tap_device::vnt_device::DeviceWrite; use crate::{proto, PeerClientInfo}; /// 处理来源于服务端的包 #[derive(Clone)] -pub struct ServerPacketHandler { +pub struct ServerPacketHandler { #[cfg(feature = "server_encrypt")] rsa_cipher: Arc>>, server_cipher: Cipher, current_device: Arc>, - device: DeviceAdapter, + device: Device, device_list: Arc)>>, config_info: BaseConfigInfo, nat_test: NatTest, callback: Call, #[cfg(feature = "server_encrypt")] up_key_time: Arc>, - #[cfg(not(target_os = "android"))] - route_record: Arc>>, external_route: ExternalRoute, handshake: Handshake, + #[cfg(feature = "inner_tun")] + tun_device_helper: crate::tun_tap_device::tun_create_helper::TunDeviceHelper, } -impl ServerPacketHandler { +impl ServerPacketHandler { pub fn new( #[cfg(feature = "server_encrypt")] rsa_cipher: Arc>>, server_cipher: Cipher, current_device: Arc>, - device: DeviceAdapter, + device: Device, device_list: Arc)>>, config_info: BaseConfigInfo, nat_test: NatTest, callback: Call, external_route: ExternalRoute, handshake: Handshake, + #[cfg(feature = "inner_tun")] + tun_device_helper: crate::tun_tap_device::tun_create_helper::TunDeviceHelper, ) -> Self { Self { #[cfg(feature = "server_encrypt")] @@ -83,15 +83,15 @@ impl ServerPacketHandler { callback, #[cfg(feature = "server_encrypt")] up_key_time: Arc::new(AtomicCell::new(Instant::now() - Duration::from_secs(60))), - #[cfg(not(target_os = "android"))] - route_record: Arc::new(Mutex::default()), external_route, handshake, + #[cfg(feature = "inner_tun")] + tun_device_helper, } } } -impl PacketHandler for ServerPacketHandler { +impl PacketHandler for ServerPacketHandler { fn handle( &self, mut net_packet: NetPacket<&mut [u8]>, @@ -246,7 +246,7 @@ impl PacketHandler for ServerPacketHandler { } } -impl ServerPacketHandler { +impl ServerPacketHandler { fn service( &self, context: &ChannelContext, @@ -305,80 +305,83 @@ impl ServerPacketHandler { if old.virtual_ip != Ipv4Addr::UNSPECIFIED { log::info!("ip发生变化,old:{:?},response={:?}", old, response); } - #[cfg(target_os = "android")] + let device_config = crate::handle::callback::DeviceConfig::new( + #[cfg(target_os = "windows")] + self.config_info.tap, + #[cfg(any( + target_os = "windows", + target_os = "linux", + target_os = "macos" + ))] + self.config_info.device_name.clone(), + self.config_info.mtu, + virtual_ip, + virtual_netmask, + virtual_gateway, + virtual_network, + self.external_route.to_route(), + ); + #[cfg(not(feature = "inner_tun"))] + self.callback.create_device(context.sender(), device_config); + #[cfg(feature = "inner_tun")] { - let device_config = crate::handle::callback::DeviceConfig::new( - virtual_ip, - virtual_netmask, - virtual_gateway, - virtual_network, - self.external_route.to_route(), - ); - let device_fd = self.callback.generate_tun(device_config); - if device_fd == 0 { - self.callback.error(ErrorInfo::new_msg( - ErrorType::Unknown, - "device_fd == 0".into(), - )); - } else { - if let Err(e) = self.device.start(device_fd as _) { + self.tun_device_helper.stop(); + #[cfg(any( + target_os = "windows", + target_os = "linux", + target_os = "macos" + ))] + match crate::tun_tap_device::create_device(device_config) { + Ok(device) => { + use tun::device::IFace; + let tun_info = crate::handle::callback::DeviceInfo::new( + device.name().unwrap_or("unknown".into()), + device.version().unwrap_or("unknown".into()), + ); + log::info!("tun信息{:?}", tun_info); + self.callback.create_tun(tun_info); + self.tun_device_helper.start(device)?; + } + Err(e) => { + log::error!("{:?}", e); + self.callback.error(e); + } + } + #[cfg(target_os = "android")] + { + let device_config = crate::handle::callback::DeviceConfig::new( + self.config_info.mtu, + virtual_ip, + virtual_netmask, + virtual_gateway, + virtual_network, + self.external_route.to_route(), + ); + let device_fd = self.callback.generate_tun(device_config); + if device_fd == 0 { self.callback.error(ErrorInfo::new_msg( ErrorType::Unknown, - format!("{:?}", e), + "device_fd == 0".into(), )); - } - } - } - #[cfg(not(target_os = "android"))] - { - if let Err(e) = self.device.set_ip(virtual_ip, virtual_netmask) { - log::error!("LocalIpExists {:?}", e); - self.callback.error(ErrorInfo::new_msg( - ErrorType::LocalIpExists, - format!("set_ip {:?}", e), - )); - return Ok(()); - } - let mut guard = self.route_record.lock(); - for (dest, mask) in guard.drain(..) { - if let Err(e) = self.device.delete_route(dest, mask) { - log::warn!("删除路由失败 ={:?}", e); - } - } - if let Err(e) = - self.device.add_route(virtual_network, virtual_netmask, 1) - { - log::warn!("添加默认路由失败 ={:?}", e); - } else { - guard.push((virtual_network, virtual_netmask)); - } - if let Err(e) = - self.device - .add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, 1) - { - log::warn!("添加广播路由失败 ={:?}", e); - } else { - guard.push((Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST)); - } - - if let Err(e) = self.device.add_route( - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - 1, - ) { - log::warn!("添加组播路由失败 ={:?}", e); - } else { - guard.push(( - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - )); - } - - for (dest, mask) in self.external_route.to_route() { - if let Err(e) = self.device.add_route(dest, mask, 1) { - log::warn!("添加路由失败 ={:?}", e); } else { - guard.push((dest, mask)); + match tun::Device::new(device_fd as _) { + Ok(device) => { + if let Err(e) = + self.tun_device_helper.start(Arc::new(device)) + { + self.callback.error(ErrorInfo::new_msg( + ErrorType::Unknown, + format!("{:?}", e), + )); + } + } + Err(e) => { + self.callback.error(ErrorInfo::new_msg( + ErrorType::Unknown, + format!("{:?}", e), + )); + } + } } } } diff --git a/vnt/src/handle/tun_tap/channel_group.rs b/vnt/src/handle/tun_tap/channel_group.rs deleted file mode 100644 index 531a413..0000000 --- a/vnt/src/handle/tun_tap/channel_group.rs +++ /dev/null @@ -1,30 +0,0 @@ -use std::sync::mpsc::{sync_channel, Receiver, SendError, SyncSender}; - -pub fn channel_group(size: usize, bound: usize) -> (GroupSyncSender, Vec>) { - let mut senders = Vec::with_capacity(size); - let mut receivers = Vec::with_capacity(size); - for _ in 0..size { - let (s, r) = sync_channel(bound); - senders.push(s); - receivers.push(r); - } - ( - GroupSyncSender { - count: 0, - base: senders, - }, - receivers, - ) -} - -pub struct GroupSyncSender { - count: usize, - base: Vec>, -} - -impl GroupSyncSender { - pub fn send(&mut self, t: T) -> Result<(), SendError> { - self.count += 1; - self.base[self.count % self.base.len()].send(t) - } -} diff --git a/vnt/src/handle/tun_tap/mod.rs b/vnt/src/handle/tun_tap/mod.rs index 5d80406..1d1bd33 100644 --- a/vnt/src/handle/tun_tap/mod.rs +++ b/vnt/src/handle/tun_tap/mod.rs @@ -1,11 +1,45 @@ -mod channel_group; pub mod tun_handler; #[cfg(unix)] mod unix; + +use crossbeam_utils::atomic::AtomicCell; +use parking_lot::Mutex; +use std::sync::Arc; #[cfg(unix)] pub(crate) use unix::*; + #[cfg(target_os = "windows")] mod windows; + #[cfg(target_os = "windows")] pub(crate) use windows::*; + +/// 仅仅是停止tun,不停止vnt +#[derive(Clone, Default)] +pub struct DeviceStop { + f: Arc bool + Send>>>>, + stopped: Arc>, +} + +impl DeviceStop { + pub fn set_stop_fn(&self, f: F) + where + F: FnOnce() -> bool + Send + 'static, + { + self.f.lock().replace(Box::new(f)); + } + pub fn stop(&self) -> bool { + if let Some(f) = self.f.lock().take() { + f() + } else { + false + } + } + pub fn stopped(&self) { + self.stopped.store(true); + } + pub fn is_stop(&self) -> bool { + self.stopped.load() + } +} diff --git a/vnt/src/handle/tun_tap/tun_handler.rs b/vnt/src/handle/tun_tap/tun_handler.rs index 9729f67..3e4647c 100644 --- a/vnt/src/handle/tun_tap/tun_handler.rs +++ b/vnt/src/handle/tun_tap/tun_handler.rs @@ -13,12 +13,11 @@ use tun::device::IFace; use tun::Device; use crate::channel::context::ChannelContext; -use crate::channel::BUFFER_SIZE; use crate::cipher::Cipher; use crate::compression::Compressor; use crate::external_route::ExternalRoute; -use crate::handle::tun_tap::channel_group::channel_group; -use crate::handle::{check_dest, CurrentDeviceInfo, PeerDeviceInfo}; +use crate::handle::tun_tap::DeviceStop; +use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo}; #[cfg(feature = "ip_proxy")] use crate::ip_proxy::IpProxyMap; #[cfg(feature = "ip_proxy")] @@ -28,7 +27,11 @@ use crate::protocol::body::ENCRYPTION_RESERVED; use crate::protocol::ip_turn_packet::BroadcastPacket; use crate::protocol::{ip_turn_packet, NetPacket, MAX_TTL}; use crate::util::{SingleU64Adder, StopManager}; - +/// 是否在一个网段 +fn check_dest(dest: Ipv4Addr, virtual_netmask: Ipv4Addr, virtual_network: Ipv4Addr) -> bool { + u32::from_be_bytes(dest.octets()) & u32::from_be_bytes(virtual_netmask.octets()) + == u32::from_be_bytes(virtual_network.octets()) +} fn icmp(device_writer: &Device, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> anyhow::Result<()> { if ipv4_packet.protocol() == Protocol::Icmp { let mut icmp = IcmpPacket::new(ipv4_packet.payload_mut())?; @@ -54,89 +57,33 @@ pub fn start( #[cfg(feature = "ip_proxy")] ip_proxy_map: Option, client_cipher: Cipher, server_cipher: Cipher, - parallel: usize, mut up_counter: SingleU64Adder, device_list: Arc)>>, compressor: Compressor, + device_stop: DeviceStop, ) -> io::Result<()> { - if parallel > 1 { - let (sender, receivers) = channel_group::<(Vec, usize)>(parallel, 16); - for (index, receiver) in receivers.into_iter().enumerate() { - let context = context.clone(); - let device = device.clone(); - let current_device = current_device.clone(); - let ip_route = ip_route.clone(); - #[cfg(feature = "ip_proxy")] - let ip_proxy_map = ip_proxy_map.clone(); - let client_cipher = client_cipher.clone(); - let server_cipher = server_cipher.clone(); - let device_list = device_list.clone(); - thread::Builder::new() - .name(format!("tunHandler-{}", index)) - .spawn(move || { - let mut extend = [0; BUFFER_SIZE]; - while let Ok((mut buf, len)) = receiver.recv() { - #[cfg(not(target_os = "macos"))] - let start = 0; - #[cfg(target_os = "macos")] - let start = 4; - match handle( - &context, - &mut buf[start..], - len, - &mut extend, - &device, - current_device.load(), - &ip_route, - #[cfg(feature = "ip_proxy")] - &ip_proxy_map, - &client_cipher, - &server_cipher, - &device_list, - &compressor, - ) { - Ok(_) => {} - Err(e) => { - log::warn!("{:?}", e) - } - } - } - })?; - } - thread::Builder::new() - .name("tunHandlerM".into()) - .spawn(move || { - if let Err(e) = crate::handle::tun_tap::start_multi( - stop_manager, - device, - sender, - &mut up_counter, - ) { - log::warn!("stop:{}", e); - } - })?; - } else { - thread::Builder::new() - .name("tunHandlerS".into()) - .spawn(move || { - if let Err(e) = crate::handle::tun_tap::start_simple( - stop_manager, - &context, - device, - current_device, - ip_route, - #[cfg(feature = "ip_proxy")] - ip_proxy_map, - client_cipher, - server_cipher, - &mut up_counter, - device_list, - compressor, - ) { - log::warn!("stop:{}", e); - } - })?; - } + thread::Builder::new() + .name("tunHandlerS".into()) + .spawn(move || { + if let Err(e) = crate::handle::tun_tap::start_simple( + stop_manager, + &context, + device, + current_device, + ip_route, + #[cfg(feature = "ip_proxy")] + ip_proxy_map, + client_cipher, + server_cipher, + &mut up_counter, + device_list, + compressor, + device_stop, + ) { + log::warn!("stop:{}", e); + } + })?; + Ok(()) } diff --git a/vnt/src/handle/tun_tap/unix.rs b/vnt/src/handle/tun_tap/unix.rs index 6417dfb..4931857 100644 --- a/vnt/src/handle/tun_tap/unix.rs +++ b/vnt/src/handle/tun_tap/unix.rs @@ -3,7 +3,7 @@ use crate::channel::BUFFER_SIZE; use crate::cipher::Cipher; use crate::compression::Compressor; use crate::external_route::ExternalRoute; -use crate::handle::tun_tap::channel_group::GroupSyncSender; +use crate::handle::tun_tap::DeviceStop; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo}; #[cfg(feature = "ip_proxy")] use crate::ip_proxy::IpProxyMap; @@ -33,13 +33,38 @@ pub(crate) fn start_simple( up_counter: &mut SingleU64Adder, device_list: Arc)>>, compressor: Compressor, + device_stop: DeviceStop, ) -> anyhow::Result<()> { + let stop_all = Arc::new(AtomicCell::new(true)); let poll = Poll::new()?; let waker = Arc::new(Waker::new(poll.registry(), STOP)?); let _waker = waker.clone(); - let worker = stop_manager.add_listener("tun_device".into(), move || { - let _ = waker.wake(); - })?; + let device_cell = Arc::new(AtomicCell::new(Some(waker))); + let worker = { + let device_cell = device_cell.clone(); + stop_manager.add_listener("tun_device".into(), move || { + if let Some(waker) = device_cell.take() { + if let Err(e) = waker.wake() { + log::warn!("{:?}", e); + } + } + })? + }; + { + let stop_all = stop_all.clone(); + device_stop.set_stop_fn(move || { + if let Some(waker) = device_cell.take() { + stop_all.store(false); + if let Err(e) = waker.wake() { + log::warn!("{:?}", e); + return false; + } + true + } else { + false + } + }); + } if let Err(e) = start_simple0( poll, context, @@ -56,7 +81,10 @@ pub(crate) fn start_simple( ) { log::error!("{:?}", e); }; - worker.stop_all(); + device_stop.stopped(); + if stop_all.load() { + worker.stop_all(); + } drop(_waker); Ok(()) } @@ -131,65 +159,3 @@ fn start_simple0( } } } - -pub(crate) fn start_multi( - stop_manager: StopManager, - device: Arc, - group_sync_sender: GroupSyncSender<(Vec, usize)>, - up_counter: &mut SingleU64Adder, -) -> anyhow::Result<()> { - let poll = Poll::new()?; - let waker = Arc::new(Waker::new(poll.registry(), STOP)?); - let _waker = waker.clone(); - let worker = stop_manager.add_listener("tun_device".into(), move || { - let _ = waker.wake(); - })?; - if let Err(e) = start_multi0(poll, device, group_sync_sender, up_counter) { - log::error!("{:?}", e); - }; - worker.stop_all(); - drop(_waker); - Ok(()) -} - -fn start_multi0( - mut poll: Poll, - device: Arc, - mut group_sync_sender: GroupSyncSender<(Vec, usize)>, - up_counter: &mut SingleU64Adder, -) -> anyhow::Result<()> { - let fd = device.as_tun_fd(); - fd.set_nonblock()?; - SourceFd(&fd.as_raw_fd()).register(poll.registry(), FD, Interest::READABLE)?; - let mut evnets = Events::with_capacity(4); - let mut buf = vec![0; 1024 * 16]; - #[cfg(not(target_os = "macos"))] - let start = 12; - #[cfg(target_os = "macos")] - let start = 12 - 4; - loop { - poll.poll(&mut evnets, None)?; - for event in evnets.iter() { - if event.token() == STOP { - return Ok(()); - } - loop { - let len = match fd.read(&mut buf[start..]) { - Ok(len) => len + start, - Err(e) => { - if e.kind() == io::ErrorKind::WouldBlock { - break; - } - Err(e)? - } - }; - //单线程的 - up_counter.add(len as u64); - if group_sync_sender.send((buf, len)).is_err() { - return Ok(()); - } - buf = vec![0; 1024 * 16]; - } - } - } -} diff --git a/vnt/src/handle/tun_tap/windows.rs b/vnt/src/handle/tun_tap/windows.rs index 0d03b1e..e2469eb 100644 --- a/vnt/src/handle/tun_tap/windows.rs +++ b/vnt/src/handle/tun_tap/windows.rs @@ -3,7 +3,7 @@ use crate::channel::BUFFER_SIZE; use crate::cipher::Cipher; use crate::compression::Compressor; use crate::external_route::ExternalRoute; -use crate::handle::tun_tap::channel_group::GroupSyncSender; +use crate::handle::tun_tap::DeviceStop; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo}; #[cfg(feature = "ip_proxy")] use crate::ip_proxy::IpProxyMap; @@ -26,15 +26,35 @@ pub(crate) fn start_simple( up_counter: &mut SingleU64Adder, device_list: Arc)>>, compressor: Compressor, + device_stop: DeviceStop, ) -> anyhow::Result<()> { + let device_cell = Arc::new(AtomicCell::new(Some(device.clone()))); + let stop_all = Arc::new(AtomicCell::new(true)); let worker = { - let device = device.clone(); + let device_cell = device_cell.clone(); stop_manager.add_listener("tun_device".into(), move || { - if let Err(e) = device.shutdown() { - log::warn!("{:?}", e); + if let Some(device) = device_cell.take() { + if let Err(e) = device.shutdown() { + log::warn!("{:?}", e); + } } })? }; + { + let stop_all = stop_all.clone(); + device_stop.set_stop_fn(move || { + if let Some(device) = device_cell.take() { + stop_all.store(false); + if let Err(e) = device.shutdown() { + log::warn!("{:?}", e); + return false; + } + true + } else { + false + } + }); + } if let Err(e) = start_simple0( context, device, @@ -50,9 +70,13 @@ pub(crate) fn start_simple( ) { log::error!("{:?}", e); } - worker.stop_all(); + device_stop.stopped(); + if stop_all.load() { + worker.stop_all(); + } Ok(()) } + fn start_simple0( context: &ChannelContext, device: Arc, @@ -95,38 +119,3 @@ fn start_simple0( } } } -pub(crate) fn start_multi( - stop_manager: StopManager, - device: Arc, - group_sync_sender: GroupSyncSender<(Vec, usize)>, - up_counter: &mut SingleU64Adder, -) -> anyhow::Result<()> { - let worker = { - let device = device.clone(); - stop_manager.add_listener("tun_device_multi".into(), move || { - if let Err(e) = device.shutdown() { - log::warn!("{:?}", e); - } - })? - }; - if let Err(e) = start_multi0(device, group_sync_sender, up_counter) { - log::error!("{:?}", e); - }; - worker.stop_all(); - Ok(()) -} -fn start_multi0( - device: Arc, - mut group_sync_sender: GroupSyncSender<(Vec, usize)>, - up_counter: &mut SingleU64Adder, -) -> anyhow::Result<()> { - loop { - let mut buf = vec![0; 1024 * 16]; - let len = device.read(&mut buf[12..])? + 12; - //单线程的 - up_counter.add(len as u64); - if group_sync_sender.send((buf, len)).is_err() { - return Ok(()); - } - } -} diff --git a/vnt/src/tun_tap_device/create_device.rs b/vnt/src/tun_tap_device/create_device.rs index 5b6fd4e..7485cde 100644 --- a/vnt/src/tun_tap_device/create_device.rs +++ b/vnt/src/tun_tap_device/create_device.rs @@ -1,4 +1,6 @@ +use crate::{DeviceConfig, ErrorInfo, ErrorType}; use std::io; +use std::net::Ipv4Addr; use std::sync::Arc; use tun::device::IFace; use tun::Device; @@ -8,8 +10,47 @@ const DEFAULT_TUN_NAME: &str = "vnt-tun"; #[cfg(target_os = "windows")] const DEFAULT_TAP_NAME: &str = "vnt-tap"; -#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] -pub fn create_device(config: &crate::core::Config) -> io::Result> { +pub fn create_device(config: DeviceConfig) -> Result, ErrorInfo> { + let device = match create_device0(&config) { + Ok(device) => device, + Err(e) => { + return Err(ErrorInfo::new_msg( + ErrorType::Unknown, + format!("create device {:?}", e), + )); + } + }; + if let Err(e) = device.set_ip(config.virtual_ip, config.virtual_netmask) { + log::error!("LocalIpExists {:?}", e); + return Err(ErrorInfo::new_msg( + ErrorType::LocalIpExists, + format!("set_ip {:?}", e), + )); + } + if let Err(e) = device.add_route(config.virtual_network, config.virtual_netmask, 1) { + log::warn!("添加默认路由失败 ={:?}", e); + } + if let Err(e) = device.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, 1) { + log::warn!("添加广播路由失败 ={:?}", e); + } + + if let Err(e) = device.add_route( + Ipv4Addr::from([224, 0, 0, 0]), + Ipv4Addr::from([240, 0, 0, 0]), + 1, + ) { + log::warn!("添加组播路由失败 ={:?}", e); + } + + for (dest, mask) in config.external_route { + if let Err(e) = device.add_route(dest, mask, 1) { + log::warn!("添加路由失败 ={:?}", e); + } + } + Ok(device) +} + +fn create_device0(config: &DeviceConfig) -> io::Result> { #[cfg(target_os = "windows")] let default_name: &str = if config.tap { DEFAULT_TAP_NAME @@ -37,14 +78,7 @@ pub fn create_device(config: &crate::core::Config) -> io::Result> { .unwrap_or(default_name.to_string()), config.tap, )?); - let mtu = config.mtu.unwrap_or_else(|| { - if config.password.is_none() { - 1450 - } else { - 1410 - } - }); - device.set_mtu(mtu)?; + device.set_mtu(config.mtu)?; Ok(device) } diff --git a/vnt/src/tun_tap_device/mod.rs b/vnt/src/tun_tap_device/mod.rs index f5037c8..2db7f75 100644 --- a/vnt/src/tun_tap_device/mod.rs +++ b/vnt/src/tun_tap_device/mod.rs @@ -1,6 +1,11 @@ #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] +#[cfg(feature = "inner_tun")] pub use create_device::create_device; #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] +#[cfg(feature = "inner_tun")] mod create_device; +#[cfg(feature = "inner_tun")] pub mod tun_create_helper; + +pub mod vnt_device; diff --git a/vnt/src/tun_tap_device/tun_create_helper.rs b/vnt/src/tun_tap_device/tun_create_helper.rs index 67b7665..99dd74f 100644 --- a/vnt/src/tun_tap_device/tun_create_helper.rs +++ b/vnt/src/tun_tap_device/tun_create_helper.rs @@ -4,69 +4,60 @@ use std::sync::Arc; use crossbeam_utils::atomic::AtomicCell; use parking_lot::Mutex; +use tun::device::IFace; use tun::Device; use crate::channel::context::ChannelContext; use crate::cipher::Cipher; use crate::compression::Compressor; use crate::external_route::ExternalRoute; +use crate::handle::tun_tap::DeviceStop; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo}; #[cfg(feature = "ip_proxy")] use crate::ip_proxy::IpProxyMap; +use crate::tun_tap_device::vnt_device::DeviceWrite; use crate::util::{SingleU64Adder, StopManager}; -#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + #[repr(transparent)] -#[derive(Clone)] +#[derive(Clone, Default)] pub struct DeviceAdapter { - tun: Arc, + tun: Arc>>>, } + impl DeviceAdapter { - #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] - pub fn new(tun: Arc) -> Self { - Self { tun } + pub fn insert(&self, device: Arc) { + let r = self.tun.lock().replace(device); + assert!(r.is_none()); } - #[cfg(target_os = "android")] - pub fn new(tun_device_helper: TunDeviceHelper) -> Self { - Self { - tun: Arc::new(AtomicCell::new(-1 as _)), - tun_device_helper, + /// 要保证先remove 再insert + pub fn remove(&self) { + drop(self.tun.lock().take()); + } +} + +impl DeviceWrite for DeviceAdapter { + #[inline] + fn write(&self, buf: &[u8]) -> io::Result { + if let Some(tun) = self.tun.lock().as_ref() { + tun.write(buf) + } else { + Err(io::Error::new(io::ErrorKind::NotFound, "not tun device")) } } -} -#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] -impl std::ops::Deref for DeviceAdapter { - type Target = Arc; - fn deref(&self) -> &Self::Target { - &self.tun - } -} - -#[cfg(target_os = "android")] -#[derive(Clone)] -pub struct DeviceAdapter { - tun: Arc>, - tun_device_helper: TunDeviceHelper, -} -#[cfg(target_os = "android")] -impl DeviceAdapter { - pub fn write(&self, buf: &[u8]) -> io::Result { - let fd = self.tun.load(); - tun::Fd(fd).write(buf) - } - pub fn start(&self, fd: std::os::fd::RawFd) -> io::Result<()> { - //安卓端fd是由外部释放的,所以这里这么搞免得加锁 - self.tun_device_helper.start(Arc::new(Device::new(fd)?))?; - self.tun.store(fd); - Ok(()) + fn into_device_adapter(self) -> DeviceAdapter { + self } } #[derive(Clone)] pub struct TunDeviceHelper { - inner: Arc>>, + inner: Arc>, + device_adapter: DeviceAdapter, + device_stop: Arc>>, } +#[derive(Clone)] struct TunDeviceHelperInner { stop_manager: StopManager, context: ChannelContext, @@ -76,7 +67,6 @@ struct TunDeviceHelperInner { ip_proxy_map: Option, client_cipher: Cipher, server_cipher: Cipher, - parallel: usize, up_counter: SingleU64Adder, device_list: Arc)>>, compressor: Compressor, @@ -91,48 +81,65 @@ impl TunDeviceHelper { #[cfg(feature = "ip_proxy")] ip_proxy_map: Option, client_cipher: Cipher, server_cipher: Cipher, - parallel: usize, up_counter: SingleU64Adder, device_list: Arc)>>, compressor: Compressor, + device_adapter: DeviceAdapter, ) -> Self { + let inner = TunDeviceHelperInner { + stop_manager, + context, + current_device, + ip_route, + #[cfg(feature = "ip_proxy")] + ip_proxy_map, + client_cipher, + server_cipher, + up_counter, + device_list, + compressor, + }; Self { - inner: Arc::new(AtomicCell::new(Some(TunDeviceHelperInner { - stop_manager, - context, - current_device, - ip_route, - #[cfg(feature = "ip_proxy")] - ip_proxy_map, - client_cipher, - server_cipher, - parallel, - up_counter, - device_list, - compressor, - }))), + inner: Arc::new(Mutex::new(inner)), + device_adapter, + device_stop: Default::default(), } } - pub fn start(&self, device: Arc) -> io::Result<()> { - if let Some(inner) = self.inner.take() { - crate::handle::tun_tap::tun_handler::start( - inner.stop_manager, - inner.context, - device, - inner.current_device, - inner.ip_route, - #[cfg(feature = "ip_proxy")] - inner.ip_proxy_map, - inner.client_cipher, - inner.server_cipher, - inner.parallel, - inner.up_counter, - inner.device_list, - inner.compressor, - )?; - Ok(()) - } else { - Err(io::Error::new(io::ErrorKind::Other, "Repeated start")) + pub fn stop(&self) { + //先停止旧的,再启动新的,改变旧网卡的IP太麻烦 + if let Some(device_stop) = self.device_stop.lock().take() { + self.device_adapter.remove(); + loop { + device_stop.stop(); + std::thread::sleep(std::time::Duration::from_millis(300)); + //确保停止了 + if device_stop.is_stop() { + break; + } + } } } + /// 要保证先stop 再start + pub fn start(&self, device: Arc) -> io::Result<()> { + self.device_adapter.insert(device.clone()); + let device_stop = DeviceStop::default(); + let s = self.device_stop.lock().replace(device_stop.clone()); + assert!(s.is_none()); + let inner = self.inner.lock().clone(); + crate::handle::tun_tap::tun_handler::start( + inner.stop_manager, + inner.context, + device, + inner.current_device, + inner.ip_route, + #[cfg(feature = "ip_proxy")] + inner.ip_proxy_map, + inner.client_cipher, + inner.server_cipher, + inner.up_counter, + inner.device_list, + inner.compressor, + device_stop, + ) + } } diff --git a/vnt/src/tun_tap_device/vnt_device.rs b/vnt/src/tun_tap_device/vnt_device.rs new file mode 100644 index 0000000..27e2549 --- /dev/null +++ b/vnt/src/tun_tap_device/vnt_device.rs @@ -0,0 +1,7 @@ +use std::io; + +pub trait DeviceWrite: Clone + Send + Sync + 'static { + fn write(&self, buf: &[u8]) -> io::Result; + #[cfg(feature = "inner_tun")] + fn into_device_adapter(self) -> crate::tun_tap_device::tun_create_helper::DeviceAdapter; +} diff --git a/vnt/src/util/counter/adder.rs b/vnt/src/util/counter/adder.rs index 38a1749..0dc3701 100644 --- a/vnt/src/util/counter/adder.rs +++ b/vnt/src/util/counter/adder.rs @@ -8,6 +8,7 @@ pub struct U64Adder { inner: Arc, index: usize, } +#[derive(Clone)] pub struct SingleU64Adder { inner: Arc, } diff --git a/vnt/tun/src/unix/fd.rs b/vnt/tun/src/unix/fd.rs index 4c3f973..7c2f973 100644 --- a/vnt/tun/src/unix/fd.rs +++ b/vnt/tun/src/unix/fd.rs @@ -62,9 +62,7 @@ impl IntoRawFd for Fd { impl Drop for Fd { fn drop(&mut self) { unsafe { - if self.0 >= 0 { - libc::close(self.0); - } + libc::close(self.0); } } }