支持排除tun

This commit is contained in:
lbl8603
2024-06-09 00:03:28 +08:00
parent 3045e239ff
commit dedc66875b
20 changed files with 460 additions and 465 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ signal-hook = "0.3.17"
winapi = { version = "0.3.9", features = ["handleapi", "processthreadsapi", "winnt", "securitybaseapi", "impl-default"] } winapi = { version = "0.3.9", features = ["handleapi", "processthreadsapi", "winnt", "securitybaseapi", "impl-default"] }
[features] [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 = ["vnt/openssl"]
openssl-vendored = ["vnt/openssl-vendored"] openssl-vendored = ["vnt/openssl-vendored"]
ring-cipher = ["vnt/ring-cipher"] ring-cipher = ["vnt/ring-cipher"]
+3 -2
View File
@@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
tun = { path = "tun" } tun = { path = "tun" ,optional = true}
packet = { path = "./packet" } packet = { path = "./packet" }
bytes = "1.5.0" bytes = "1.5.0"
log = "0.4.17" log = "0.4.17"
@@ -53,7 +53,7 @@ protoc-bin-vendored = "3.0.0"
cfg_aliases = "0.2.1" cfg_aliases = "0.2.1"
[features] [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 = ["openssl-sys"]
# 从源码编译 # 从源码编译
openssl-vendored = ["openssl-sys/vendored"] openssl-vendored = ["openssl-sys/vendored"]
@@ -68,3 +68,4 @@ ip_proxy = ["tokio"]
port_mapping = ["tokio"] port_mapping = ["tokio"]
lz4_compress = ["lz4_flex"] lz4_compress = ["lz4_flex"]
zstd_compress = ["zstd"] zstd_compress = ["zstd"]
inner_tun = ["tun"]
+45 -41
View File
@@ -1,4 +1,3 @@
use anyhow::Context;
use std::collections::HashMap; use std::collections::HashMap;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::sync::Arc; use std::sync::Arc;
@@ -7,8 +6,6 @@ use std::time::Duration;
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use rand::Rng; use rand::Rng;
#[cfg(not(target_os = "android"))]
use tun::device::IFace;
use crate::channel::context::ChannelContext; use crate::channel::context::ChannelContext;
use crate::channel::idle::Idle; use crate::channel::idle::Idle;
@@ -24,13 +21,13 @@ use crate::handle::maintain::PunchReceiver;
use crate::handle::recv_data::RecvDataHandler; use crate::handle::recv_data::RecvDataHandler;
use crate::handle::{maintain, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo}; use crate::handle::{maintain, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest; use crate::nat::NatTest;
#[cfg(feature = "inner_tun")]
use crate::tun_tap_device::tun_create_helper::{DeviceAdapter, TunDeviceHelper}; use crate::tun_tap_device::tun_create_helper::{DeviceAdapter, TunDeviceHelper};
use crate::tun_tap_device::vnt_device::DeviceWrite;
use crate::util::{ use crate::util::{
Scheduler, SingleU64Adder, StopManager, U64Adder, WatchSingleU64Adder, WatchU64Adder, Scheduler, SingleU64Adder, StopManager, U64Adder, WatchSingleU64Adder, WatchU64Adder,
}; };
use crate::{nat, VntCallback}; use crate::{nat, VntCallback};
#[cfg(not(target_os = "android"))]
use crate::{tun_tap_device, DeviceInfo};
#[derive(Clone)] #[derive(Clone)]
pub struct Vnt { pub struct Vnt {
@@ -47,7 +44,23 @@ pub struct Vnt {
} }
impl Vnt { impl Vnt {
#[cfg(feature = "inner_tun")]
pub fn new<Call: VntCallback>(config: Config, callback: Call) -> anyhow::Result<Self> { pub fn new<Call: VntCallback>(config: Config, callback: Call) -> anyhow::Result<Self> {
Vnt::new_device0(config, callback, DeviceAdapter::default())
}
#[cfg(not(feature = "inner_tun"))]
pub fn new_device<Call: VntCallback, Device: DeviceWrite>(
config: Config,
callback: Call,
device: Device,
) -> anyhow::Result<Self> {
Vnt::new_device0(config, callback, device)
}
fn new_device0<Call: VntCallback, Device: DeviceWrite>(
config: Config,
callback: Call,
device: Device,
) -> anyhow::Result<Self> {
log::info!("config.toml:{:?}", config); log::info!("config.toml:{:?}", config);
//服务端非对称加密 //服务端非对称加密
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
@@ -85,6 +98,11 @@ impl Vnt {
config.device_id.clone(), config.device_id.clone(),
config.server_address_str.clone(), config.server_address_str.clone(),
config.name_servers.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 = { let stop_manager = {
@@ -129,21 +147,6 @@ impl Vnt {
udp_ports, udp_ports,
tcp_port, 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 scheduler = Scheduler::new(stop_manager.clone())?;
let external_route = ExternalRoute::new(config.in_ips.clone()); let external_route = ExternalRoute::new(config.in_ips.clone());
@@ -172,24 +175,23 @@ impl Vnt {
); );
let up_counter = SingleU64Adder::new(); let up_counter = SingleU64Adder::new();
let up_count_watcher = up_counter.watch(); let up_count_watcher = up_counter.watch();
let tun_helper = TunDeviceHelper::new( #[cfg(feature = "inner_tun")]
stop_manager.clone(), let tun_device_helper = {
context.clone(), TunDeviceHelper::new(
current_device.clone(), stop_manager.clone(),
external_route.clone(), context.clone(),
#[cfg(feature = "ip_proxy")] current_device.clone(),
proxy_map.clone(), external_route.clone(),
client_cipher.clone(), #[cfg(feature = "ip_proxy")]
server_cipher.clone(), proxy_map.clone(),
config.parallel, client_cipher.clone(),
up_counter, server_cipher.clone(),
device_list.clone(), up_counter,
config.compressor, device_list.clone(),
); config.compressor,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] device.clone().into_device_adapter(),
let device_adapter = DeviceAdapter::new(device.clone()); )
#[cfg(target_os = "android")] };
let device_adapter = DeviceAdapter::new(tun_helper);
let handler = RecvDataHandler::new( let handler = RecvDataHandler::new(
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
@@ -197,7 +199,7 @@ impl Vnt {
server_cipher.clone(), server_cipher.clone(),
client_cipher.clone(), client_cipher.clone(),
current_device.clone(), current_device.clone(),
device_adapter, device,
device_list.clone(), device_list.clone(),
config_info.clone(), config_info.clone(),
nat_test.clone(), nat_test.clone(),
@@ -210,6 +212,8 @@ impl Vnt {
proxy_map.clone(), proxy_map.clone(),
down_counter, down_counter,
handshake.clone(), handshake.clone(),
#[cfg(feature = "inner_tun")]
tun_device_helper,
); );
//初始化网络数据通道 //初始化网络数据通道
@@ -225,8 +229,8 @@ impl Vnt {
nat_test.clone(), nat_test.clone(),
); );
#[cfg(not(target_os = "android"))] // #[cfg(not(target_os = "android"))]
tun_helper.start(device)?; // tun_helper.start(device)?;
maintain::idle_gateway( maintain::idle_gateway(
&scheduler, &scheduler,
+1 -4
View File
@@ -32,13 +32,12 @@ pub struct Config {
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
pub no_proxy: bool, pub no_proxy: bool,
pub server_encrypt: bool, pub server_encrypt: bool,
pub parallel: usize,
pub cipher_model: CipherModel, pub cipher_model: CipherModel,
pub finger: bool, pub finger: bool,
pub punch_model: PunchModel, pub punch_model: PunchModel,
pub ports: Option<Vec<u16>>, pub ports: Option<Vec<u16>>,
pub first_latency: bool, pub first_latency: bool,
#[cfg(not(target_os = "android"))] #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
pub device_name: Option<String>, pub device_name: Option<String>,
pub use_channel_type: UseChannelType, pub use_channel_type: UseChannelType,
//控制丢包率 //控制丢包率
@@ -67,7 +66,6 @@ impl Config {
ip: Option<Ipv4Addr>, ip: Option<Ipv4Addr>,
#[cfg(feature = "ip_proxy")] no_proxy: bool, #[cfg(feature = "ip_proxy")] no_proxy: bool,
server_encrypt: bool, server_encrypt: bool,
parallel: usize,
cipher_model: CipherModel, cipher_model: CipherModel,
finger: bool, finger: bool,
punch_model: PunchModel, punch_model: PunchModel,
@@ -130,7 +128,6 @@ impl Config {
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
no_proxy, no_proxy,
server_encrypt, server_encrypt,
parallel,
cipher_model, cipher_model,
finger, finger,
punch_model, punch_model,
+26 -5
View File
@@ -189,9 +189,14 @@ impl Into<u8> for ErrorType {
} }
} }
#[cfg(target_os = "android")] #[derive(Clone, Debug)]
#[derive(Debug)]
pub struct DeviceConfig { 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<String>,
//虚拟网卡mtu值
pub mtu: u32,
//本机虚拟IP //本机虚拟IP
pub virtual_ip: Ipv4Addr, pub virtual_ip: Ipv4Addr,
//子网掩码 //子网掩码
@@ -204,9 +209,12 @@ pub struct DeviceConfig {
pub external_route: Vec<(Ipv4Addr, Ipv4Addr)>, pub external_route: Vec<(Ipv4Addr, Ipv4Addr)>,
} }
#[cfg(target_os = "android")]
impl DeviceConfig { impl DeviceConfig {
pub fn new( pub fn new(
#[cfg(target_os = "windows")] tap: bool,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
device_name: Option<String>,
mtu: u32,
virtual_ip: Ipv4Addr, virtual_ip: Ipv4Addr,
virtual_netmask: Ipv4Addr, virtual_netmask: Ipv4Addr,
virtual_gateway: Ipv4Addr, virtual_gateway: Ipv4Addr,
@@ -214,6 +222,11 @@ impl DeviceConfig {
external_route: Vec<(Ipv4Addr, Ipv4Addr)>, external_route: Vec<(Ipv4Addr, Ipv4Addr)>,
) -> Self { ) -> Self {
Self { Self {
#[cfg(target_os = "windows")]
tap,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
device_name,
mtu,
virtual_ip, virtual_ip,
virtual_netmask, virtual_netmask,
virtual_gateway, virtual_gateway,
@@ -223,7 +236,6 @@ impl DeviceConfig {
} }
} }
#[cfg(target_os = "android")]
impl Display for DeviceConfig { impl Display for DeviceConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!( 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(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
#[cfg(feature = "inner_tun")]
fn create_tun(&self, _info: DeviceInfo) {} fn create_tun(&self, _info: DeviceInfo) {}
/// 连接 /// 连接
fn connect(&self, _info: ConnectInfo) {} fn connect(&self, _info: ConnectInfo) {}
@@ -283,8 +296,16 @@ pub trait VntCallback: Clone + Send + Sync + 'static {
fn register(&self, _info: RegisterInfo) -> bool { fn register(&self, _info: RegisterInfo) -> bool {
true true
} }
#[cfg(not(feature = "inner_tun"))]
fn create_device(
&self,
_channel_sender: crate::channel::sender::ChannelSender,
_info: DeviceConfig,
) {
}
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
fn generate_tun(&self, _info: DeviceConfig) -> u32 { #[cfg(feature = "inner_tun")]
fn generate_tun(&self, _info: DeviceConfig) -> usize {
0 0
} }
fn peer_client_list(&self, _info: Vec<PeerClientInfo>) {} fn peer_client_list(&self, _info: Vec<PeerClientInfo>) {}
+15 -6
View File
@@ -7,6 +7,7 @@ pub mod handshaker;
pub mod maintain; pub mod maintain;
pub mod recv_data; pub mod recv_data;
pub mod registrar; pub mod registrar;
#[cfg(feature = "inner_tun")]
pub mod tun_tap; pub mod tun_tap;
const SELF_IP: Ipv4Addr = Ipv4Addr::new(0, 0, 0, 2); 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)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct PeerDeviceInfo { pub struct PeerDeviceInfo {
pub virtual_ip: Ipv4Addr, pub virtual_ip: Ipv4Addr,
@@ -64,6 +59,11 @@ pub struct BaseConfigInfo {
pub device_id: String, pub device_id: String,
pub server_addr: String, pub server_addr: String,
pub name_servers: Vec<String>, pub name_servers: Vec<String>,
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<String>,
} }
impl BaseConfigInfo { impl BaseConfigInfo {
@@ -76,6 +76,10 @@ impl BaseConfigInfo {
device_id: String, device_id: String,
server_addr: String, server_addr: String,
name_servers: Vec<String>, name_servers: Vec<String>,
mtu: u32,
#[cfg(target_os = "windows")] tap: bool,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
device_name: Option<String>,
) -> Self { ) -> Self {
Self { Self {
name, name,
@@ -86,6 +90,11 @@ impl BaseConfigInfo {
device_id, device_id,
server_addr, server_addr,
name_servers, name_servers,
mtu,
#[cfg(target_os = "windows")]
tap,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
device_name,
} }
} }
} }
+7 -9
View File
@@ -9,8 +9,6 @@ use protobuf::Message;
use packet::icmp::{icmp, Kind}; use packet::icmp::{icmp, Kind};
use packet::ip::ipv4; use packet::ip::ipv4;
use packet::ip::ipv4::packet::IpV4Packet; 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::context::ChannelContext;
use crate::channel::punch::NatInfo; use crate::channel::punch::NatInfo;
@@ -30,12 +28,12 @@ use crate::protocol::control_packet::ControlPacket;
use crate::protocol::{ use crate::protocol::{
control_packet, ip_turn_packet, other_turn_packet, NetPacket, Protocol, MAX_TTL, 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)] #[derive(Clone)]
pub struct ClientPacketHandler { pub struct ClientPacketHandler<Device> {
device: DeviceAdapter, device: Device,
client_cipher: Cipher, client_cipher: Cipher,
punch_sender: PunchSender, punch_sender: PunchSender,
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>, peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
@@ -45,9 +43,9 @@ pub struct ClientPacketHandler {
ip_proxy_map: Option<IpProxyMap>, ip_proxy_map: Option<IpProxyMap>,
} }
impl ClientPacketHandler { impl<Device: DeviceWrite> ClientPacketHandler<Device> {
pub fn new( pub fn new(
device: DeviceAdapter, device: Device,
client_cipher: Cipher, client_cipher: Cipher,
punch_sender: PunchSender, punch_sender: PunchSender,
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>, peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
@@ -68,7 +66,7 @@ impl ClientPacketHandler {
} }
} }
impl PacketHandler for ClientPacketHandler { impl<Device: DeviceWrite> PacketHandler for ClientPacketHandler<Device> {
fn handle( fn handle(
&self, &self,
mut net_packet: NetPacket<&mut [u8]>, mut net_packet: NetPacket<&mut [u8]>,
@@ -110,7 +108,7 @@ impl PacketHandler for ClientPacketHandler {
} }
} }
impl ClientPacketHandler { impl<Device: DeviceWrite> ClientPacketHandler<Device> {
fn ip_turn( fn ip_turn(
&self, &self,
mut net_packet: NetPacket<&mut [u8]>, mut net_packet: NetPacket<&mut [u8]>,
+11 -7
View File
@@ -25,7 +25,7 @@ use crate::handle::{BaseConfigInfo, CurrentDeviceInfo, PeerDeviceInfo, SELF_IP};
use crate::ip_proxy::IpProxyMap; use crate::ip_proxy::IpProxyMap;
use crate::nat::NatTest; use crate::nat::NatTest;
use crate::protocol::{NetPacket, HEAD_LEN}; 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; use crate::util::U64Adder;
mod client; mod client;
@@ -33,16 +33,16 @@ mod server;
mod turn; mod turn;
#[derive(Clone)] #[derive(Clone)]
pub struct RecvDataHandler<Call> { pub struct RecvDataHandler<Call, Device> {
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
turn: TurnPacketHandler, turn: TurnPacketHandler,
client: ClientPacketHandler, client: ClientPacketHandler<Device>,
server: ServerPacketHandler<Call>, server: ServerPacketHandler<Call, Device>,
counter: U64Adder, counter: U64Adder,
nat_test: NatTest, nat_test: NatTest,
} }
impl<Call: VntCallback> RecvChannelHandler for RecvDataHandler<Call> { impl<Call: VntCallback, Device: DeviceWrite> RecvChannelHandler for RecvDataHandler<Call, Device> {
fn handle( fn handle(
&mut self, &mut self,
buf: &mut [u8], buf: &mut [u8],
@@ -75,13 +75,13 @@ impl<Call: VntCallback> RecvChannelHandler for RecvDataHandler<Call> {
} }
} }
impl<Call: VntCallback> RecvDataHandler<Call> { impl<Call: VntCallback, Device: DeviceWrite> RecvDataHandler<Call, Device> {
pub fn new( pub fn new(
#[cfg(feature = "server_encrypt")] rsa_cipher: Arc<Mutex<Option<RsaCipher>>>, #[cfg(feature = "server_encrypt")] rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
server_cipher: Cipher, server_cipher: Cipher,
client_cipher: Cipher, client_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: DeviceAdapter, device: Device,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
config_info: BaseConfigInfo, config_info: BaseConfigInfo,
nat_test: NatTest, nat_test: NatTest,
@@ -93,6 +93,8 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
counter: U64Adder, counter: U64Adder,
handshake: Handshake, handshake: Handshake,
#[cfg(feature = "inner_tun")]
tun_device_helper: crate::tun_tap_device::tun_create_helper::TunDeviceHelper,
) -> Self { ) -> Self {
let server = ServerPacketHandler::new( let server = ServerPacketHandler::new(
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
@@ -106,6 +108,8 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
callback, callback,
external_route.clone(), external_route.clone(),
handshake, handshake,
#[cfg(feature = "inner_tun")]
tun_device_helper,
); );
let client = ClientPacketHandler::new( let client = ClientPacketHandler::new(
device.clone(), device.clone(),
+85 -82
View File
@@ -12,8 +12,6 @@ use protobuf::Message;
use packet::icmp::{icmp, Kind}; use packet::icmp::{icmp, Kind};
use packet::ip::ipv4; use packet::ip::ipv4;
use packet::ip::ipv4::packet::IpV4Packet; 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::context::ChannelContext;
use crate::channel::{Route, RouteKey}; use crate::channel::{Route, RouteKey};
@@ -35,41 +33,43 @@ use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::control_packet::ControlPacket; use crate::protocol::control_packet::ControlPacket;
use crate::protocol::error_packet::InErrorPacket; use crate::protocol::error_packet::InErrorPacket;
use crate::protocol::{ip_turn_packet, service_packet, NetPacket, Protocol, MAX_TTL}; 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}; use crate::{proto, PeerClientInfo};
/// 处理来源于服务端的包 /// 处理来源于服务端的包
#[derive(Clone)] #[derive(Clone)]
pub struct ServerPacketHandler<Call> { pub struct ServerPacketHandler<Call, Device> {
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
rsa_cipher: Arc<Mutex<Option<RsaCipher>>>, rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
server_cipher: Cipher, server_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: DeviceAdapter, device: Device,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
config_info: BaseConfigInfo, config_info: BaseConfigInfo,
nat_test: NatTest, nat_test: NatTest,
callback: Call, callback: Call,
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
up_key_time: Arc<AtomicCell<Instant>>, up_key_time: Arc<AtomicCell<Instant>>,
#[cfg(not(target_os = "android"))]
route_record: Arc<Mutex<Vec<(Ipv4Addr, Ipv4Addr)>>>,
external_route: ExternalRoute, external_route: ExternalRoute,
handshake: Handshake, handshake: Handshake,
#[cfg(feature = "inner_tun")]
tun_device_helper: crate::tun_tap_device::tun_create_helper::TunDeviceHelper,
} }
impl<Call> ServerPacketHandler<Call> { impl<Call, Device> ServerPacketHandler<Call, Device> {
pub fn new( pub fn new(
#[cfg(feature = "server_encrypt")] rsa_cipher: Arc<Mutex<Option<RsaCipher>>>, #[cfg(feature = "server_encrypt")] rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
server_cipher: Cipher, server_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: DeviceAdapter, device: Device,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
config_info: BaseConfigInfo, config_info: BaseConfigInfo,
nat_test: NatTest, nat_test: NatTest,
callback: Call, callback: Call,
external_route: ExternalRoute, external_route: ExternalRoute,
handshake: Handshake, handshake: Handshake,
#[cfg(feature = "inner_tun")]
tun_device_helper: crate::tun_tap_device::tun_create_helper::TunDeviceHelper,
) -> Self { ) -> Self {
Self { Self {
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
@@ -83,15 +83,15 @@ impl<Call> ServerPacketHandler<Call> {
callback, callback,
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
up_key_time: Arc::new(AtomicCell::new(Instant::now() - Duration::from_secs(60))), 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, external_route,
handshake, handshake,
#[cfg(feature = "inner_tun")]
tun_device_helper,
} }
} }
} }
impl<Call: VntCallback> PacketHandler for ServerPacketHandler<Call> { impl<Call: VntCallback, Device: DeviceWrite> PacketHandler for ServerPacketHandler<Call, Device> {
fn handle( fn handle(
&self, &self,
mut net_packet: NetPacket<&mut [u8]>, mut net_packet: NetPacket<&mut [u8]>,
@@ -246,7 +246,7 @@ impl<Call: VntCallback> PacketHandler for ServerPacketHandler<Call> {
} }
} }
impl<Call: VntCallback> ServerPacketHandler<Call> { impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
fn service( fn service(
&self, &self,
context: &ChannelContext, context: &ChannelContext,
@@ -305,80 +305,83 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
if old.virtual_ip != Ipv4Addr::UNSPECIFIED { if old.virtual_ip != Ipv4Addr::UNSPECIFIED {
log::info!("ip发生变化,old:{:?},response={:?}", old, response); 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( self.tun_device_helper.stop();
virtual_ip, #[cfg(any(
virtual_netmask, target_os = "windows",
virtual_gateway, target_os = "linux",
virtual_network, target_os = "macos"
self.external_route.to_route(), ))]
); match crate::tun_tap_device::create_device(device_config) {
let device_fd = self.callback.generate_tun(device_config); Ok(device) => {
if device_fd == 0 { use tun::device::IFace;
self.callback.error(ErrorInfo::new_msg( let tun_info = crate::handle::callback::DeviceInfo::new(
ErrorType::Unknown, device.name().unwrap_or("unknown".into()),
"device_fd == 0".into(), device.version().unwrap_or("unknown".into()),
)); );
} else { log::info!("tun信息{:?}", tun_info);
if let Err(e) = self.device.start(device_fd as _) { 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( self.callback.error(ErrorInfo::new_msg(
ErrorType::Unknown, 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 { } 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),
));
}
}
} }
} }
} }
-30
View File
@@ -1,30 +0,0 @@
use std::sync::mpsc::{sync_channel, Receiver, SendError, SyncSender};
pub fn channel_group<T>(size: usize, bound: usize) -> (GroupSyncSender<T>, Vec<Receiver<T>>) {
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<T> {
count: usize,
base: Vec<SyncSender<T>>,
}
impl<T> GroupSyncSender<T> {
pub fn send(&mut self, t: T) -> Result<(), SendError<T>> {
self.count += 1;
self.base[self.count % self.base.len()].send(t)
}
}
+35 -1
View File
@@ -1,11 +1,45 @@
mod channel_group;
pub mod tun_handler; pub mod tun_handler;
#[cfg(unix)] #[cfg(unix)]
mod unix; mod unix;
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use std::sync::Arc;
#[cfg(unix)] #[cfg(unix)]
pub(crate) use unix::*; pub(crate) use unix::*;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
mod windows; mod windows;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub(crate) use windows::*; pub(crate) use windows::*;
/// 仅仅是停止tun,不停止vnt
#[derive(Clone, Default)]
pub struct DeviceStop {
f: Arc<Mutex<Option<Box<dyn FnOnce() -> bool + Send>>>>,
stopped: Arc<AtomicCell<bool>>,
}
impl DeviceStop {
pub fn set_stop_fn<F>(&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()
}
}
+30 -83
View File
@@ -13,12 +13,11 @@ use tun::device::IFace;
use tun::Device; use tun::Device;
use crate::channel::context::ChannelContext; use crate::channel::context::ChannelContext;
use crate::channel::BUFFER_SIZE;
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::compression::Compressor; use crate::compression::Compressor;
use crate::external_route::ExternalRoute; use crate::external_route::ExternalRoute;
use crate::handle::tun_tap::channel_group::channel_group; use crate::handle::tun_tap::DeviceStop;
use crate::handle::{check_dest, CurrentDeviceInfo, PeerDeviceInfo}; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
use crate::ip_proxy::IpProxyMap; use crate::ip_proxy::IpProxyMap;
#[cfg(feature = "ip_proxy")] #[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::BroadcastPacket;
use crate::protocol::{ip_turn_packet, NetPacket, MAX_TTL}; use crate::protocol::{ip_turn_packet, NetPacket, MAX_TTL};
use crate::util::{SingleU64Adder, StopManager}; 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<()> { fn icmp(device_writer: &Device, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> anyhow::Result<()> {
if ipv4_packet.protocol() == Protocol::Icmp { if ipv4_packet.protocol() == Protocol::Icmp {
let mut icmp = IcmpPacket::new(ipv4_packet.payload_mut())?; let mut icmp = IcmpPacket::new(ipv4_packet.payload_mut())?;
@@ -54,89 +57,33 @@ pub fn start(
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
parallel: usize,
mut up_counter: SingleU64Adder, mut up_counter: SingleU64Adder,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
device_stop: DeviceStop,
) -> io::Result<()> { ) -> io::Result<()> {
if parallel > 1 { thread::Builder::new()
let (sender, receivers) = channel_group::<(Vec<u8>, usize)>(parallel, 16); .name("tunHandlerS".into())
for (index, receiver) in receivers.into_iter().enumerate() { .spawn(move || {
let context = context.clone(); if let Err(e) = crate::handle::tun_tap::start_simple(
let device = device.clone(); stop_manager,
let current_device = current_device.clone(); &context,
let ip_route = ip_route.clone(); device,
#[cfg(feature = "ip_proxy")] current_device,
let ip_proxy_map = ip_proxy_map.clone(); ip_route,
let client_cipher = client_cipher.clone(); #[cfg(feature = "ip_proxy")]
let server_cipher = server_cipher.clone(); ip_proxy_map,
let device_list = device_list.clone(); client_cipher,
thread::Builder::new() server_cipher,
.name(format!("tunHandler-{}", index)) &mut up_counter,
.spawn(move || { device_list,
let mut extend = [0; BUFFER_SIZE]; compressor,
while let Ok((mut buf, len)) = receiver.recv() { device_stop,
#[cfg(not(target_os = "macos"))] ) {
let start = 0; log::warn!("stop:{}", e);
#[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);
}
})?;
}
Ok(()) Ok(())
} }
+33 -67
View File
@@ -3,7 +3,7 @@ use crate::channel::BUFFER_SIZE;
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::compression::Compressor; use crate::compression::Compressor;
use crate::external_route::ExternalRoute; use crate::external_route::ExternalRoute;
use crate::handle::tun_tap::channel_group::GroupSyncSender; use crate::handle::tun_tap::DeviceStop;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo}; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
use crate::ip_proxy::IpProxyMap; use crate::ip_proxy::IpProxyMap;
@@ -33,13 +33,38 @@ pub(crate) fn start_simple(
up_counter: &mut SingleU64Adder, up_counter: &mut SingleU64Adder,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
device_stop: DeviceStop,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let stop_all = Arc::new(AtomicCell::new(true));
let poll = Poll::new()?; let poll = Poll::new()?;
let waker = Arc::new(Waker::new(poll.registry(), STOP)?); let waker = Arc::new(Waker::new(poll.registry(), STOP)?);
let _waker = waker.clone(); let _waker = waker.clone();
let worker = stop_manager.add_listener("tun_device".into(), move || { let device_cell = Arc::new(AtomicCell::new(Some(waker)));
let _ = waker.wake(); 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( if let Err(e) = start_simple0(
poll, poll,
context, context,
@@ -56,7 +81,10 @@ pub(crate) fn start_simple(
) { ) {
log::error!("{:?}", e); log::error!("{:?}", e);
}; };
worker.stop_all(); device_stop.stopped();
if stop_all.load() {
worker.stop_all();
}
drop(_waker); drop(_waker);
Ok(()) Ok(())
} }
@@ -131,65 +159,3 @@ fn start_simple0(
} }
} }
} }
pub(crate) fn start_multi(
stop_manager: StopManager,
device: Arc<Device>,
group_sync_sender: GroupSyncSender<(Vec<u8>, 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<Device>,
mut group_sync_sender: GroupSyncSender<(Vec<u8>, 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];
}
}
}
}
+29 -40
View File
@@ -3,7 +3,7 @@ use crate::channel::BUFFER_SIZE;
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::compression::Compressor; use crate::compression::Compressor;
use crate::external_route::ExternalRoute; use crate::external_route::ExternalRoute;
use crate::handle::tun_tap::channel_group::GroupSyncSender; use crate::handle::tun_tap::DeviceStop;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo}; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
use crate::ip_proxy::IpProxyMap; use crate::ip_proxy::IpProxyMap;
@@ -26,15 +26,35 @@ pub(crate) fn start_simple(
up_counter: &mut SingleU64Adder, up_counter: &mut SingleU64Adder,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
device_stop: DeviceStop,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let device_cell = Arc::new(AtomicCell::new(Some(device.clone())));
let stop_all = Arc::new(AtomicCell::new(true));
let worker = { let worker = {
let device = device.clone(); let device_cell = device_cell.clone();
stop_manager.add_listener("tun_device".into(), move || { stop_manager.add_listener("tun_device".into(), move || {
if let Err(e) = device.shutdown() { if let Some(device) = device_cell.take() {
log::warn!("{:?}", e); 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( if let Err(e) = start_simple0(
context, context,
device, device,
@@ -50,9 +70,13 @@ pub(crate) fn start_simple(
) { ) {
log::error!("{:?}", e); log::error!("{:?}", e);
} }
worker.stop_all(); device_stop.stopped();
if stop_all.load() {
worker.stop_all();
}
Ok(()) Ok(())
} }
fn start_simple0( fn start_simple0(
context: &ChannelContext, context: &ChannelContext,
device: Arc<Device>, device: Arc<Device>,
@@ -95,38 +119,3 @@ fn start_simple0(
} }
} }
} }
pub(crate) fn start_multi(
stop_manager: StopManager,
device: Arc<Device>,
group_sync_sender: GroupSyncSender<(Vec<u8>, 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<Device>,
mut group_sync_sender: GroupSyncSender<(Vec<u8>, 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(());
}
}
}
+44 -10
View File
@@ -1,4 +1,6 @@
use crate::{DeviceConfig, ErrorInfo, ErrorType};
use std::io; use std::io;
use std::net::Ipv4Addr;
use std::sync::Arc; use std::sync::Arc;
use tun::device::IFace; use tun::device::IFace;
use tun::Device; use tun::Device;
@@ -8,8 +10,47 @@ const DEFAULT_TUN_NAME: &str = "vnt-tun";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
const DEFAULT_TAP_NAME: &str = "vnt-tap"; const DEFAULT_TAP_NAME: &str = "vnt-tap";
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] pub fn create_device(config: DeviceConfig) -> Result<Arc<Device>, ErrorInfo> {
pub fn create_device(config: &crate::core::Config) -> io::Result<Arc<Device>> { 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<Arc<Device>> {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let default_name: &str = if config.tap { let default_name: &str = if config.tap {
DEFAULT_TAP_NAME DEFAULT_TAP_NAME
@@ -37,14 +78,7 @@ pub fn create_device(config: &crate::core::Config) -> io::Result<Arc<Device>> {
.unwrap_or(default_name.to_string()), .unwrap_or(default_name.to_string()),
config.tap, config.tap,
)?); )?);
let mtu = config.mtu.unwrap_or_else(|| { device.set_mtu(config.mtu)?;
if config.password.is_none() {
1450
} else {
1410
}
});
device.set_mtu(mtu)?;
Ok(device) Ok(device)
} }
+5
View File
@@ -1,6 +1,11 @@
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
#[cfg(feature = "inner_tun")]
pub use create_device::create_device; pub use create_device::create_device;
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
#[cfg(feature = "inner_tun")]
mod create_device; mod create_device;
#[cfg(feature = "inner_tun")]
pub mod tun_create_helper; pub mod tun_create_helper;
pub mod vnt_device;
+81 -74
View File
@@ -4,69 +4,60 @@ use std::sync::Arc;
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex; use parking_lot::Mutex;
use tun::device::IFace;
use tun::Device; use tun::Device;
use crate::channel::context::ChannelContext; use crate::channel::context::ChannelContext;
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::compression::Compressor; use crate::compression::Compressor;
use crate::external_route::ExternalRoute; use crate::external_route::ExternalRoute;
use crate::handle::tun_tap::DeviceStop;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo}; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
use crate::ip_proxy::IpProxyMap; use crate::ip_proxy::IpProxyMap;
use crate::tun_tap_device::vnt_device::DeviceWrite;
use crate::util::{SingleU64Adder, StopManager}; use crate::util::{SingleU64Adder, StopManager};
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
#[repr(transparent)] #[repr(transparent)]
#[derive(Clone)] #[derive(Clone, Default)]
pub struct DeviceAdapter { pub struct DeviceAdapter {
tun: Arc<Device>, tun: Arc<Mutex<Option<Arc<Device>>>>,
} }
impl DeviceAdapter { impl DeviceAdapter {
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] pub fn insert(&self, device: Arc<Device>) {
pub fn new(tun: Arc<Device>) -> Self { let r = self.tun.lock().replace(device);
Self { tun } assert!(r.is_none());
} }
#[cfg(target_os = "android")] /// 要保证先remove 再insert
pub fn new(tun_device_helper: TunDeviceHelper) -> Self { pub fn remove(&self) {
Self { drop(self.tun.lock().take());
tun: Arc::new(AtomicCell::new(-1 as _)), }
tun_device_helper, }
impl DeviceWrite for DeviceAdapter {
#[inline]
fn write(&self, buf: &[u8]) -> io::Result<usize> {
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<Device>;
fn deref(&self) -> &Self::Target { fn into_device_adapter(self) -> DeviceAdapter {
&self.tun self
}
}
#[cfg(target_os = "android")]
#[derive(Clone)]
pub struct DeviceAdapter {
tun: Arc<AtomicCell<std::os::fd::RawFd>>,
tun_device_helper: TunDeviceHelper,
}
#[cfg(target_os = "android")]
impl DeviceAdapter {
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
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(())
} }
} }
#[derive(Clone)] #[derive(Clone)]
pub struct TunDeviceHelper { pub struct TunDeviceHelper {
inner: Arc<AtomicCell<Option<TunDeviceHelperInner>>>, inner: Arc<Mutex<TunDeviceHelperInner>>,
device_adapter: DeviceAdapter,
device_stop: Arc<Mutex<Option<DeviceStop>>>,
} }
#[derive(Clone)]
struct TunDeviceHelperInner { struct TunDeviceHelperInner {
stop_manager: StopManager, stop_manager: StopManager,
context: ChannelContext, context: ChannelContext,
@@ -76,7 +67,6 @@ struct TunDeviceHelperInner {
ip_proxy_map: Option<IpProxyMap>, ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
parallel: usize,
up_counter: SingleU64Adder, up_counter: SingleU64Adder,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
@@ -91,48 +81,65 @@ impl TunDeviceHelper {
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
parallel: usize,
up_counter: SingleU64Adder, up_counter: SingleU64Adder,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
device_adapter: DeviceAdapter,
) -> Self { ) -> 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 { Self {
inner: Arc::new(AtomicCell::new(Some(TunDeviceHelperInner { inner: Arc::new(Mutex::new(inner)),
stop_manager, device_adapter,
context, device_stop: Default::default(),
current_device,
ip_route,
#[cfg(feature = "ip_proxy")]
ip_proxy_map,
client_cipher,
server_cipher,
parallel,
up_counter,
device_list,
compressor,
}))),
} }
} }
pub fn start(&self, device: Arc<Device>) -> io::Result<()> { pub fn stop(&self) {
if let Some(inner) = self.inner.take() { //先停止旧的,再启动新的,改变旧网卡的IP太麻烦
crate::handle::tun_tap::tun_handler::start( if let Some(device_stop) = self.device_stop.lock().take() {
inner.stop_manager, self.device_adapter.remove();
inner.context, loop {
device, device_stop.stop();
inner.current_device, std::thread::sleep(std::time::Duration::from_millis(300));
inner.ip_route, //确保停止了
#[cfg(feature = "ip_proxy")] if device_stop.is_stop() {
inner.ip_proxy_map, break;
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"))
} }
} }
/// 要保证先stop 再start
pub fn start(&self, device: Arc<Device>) -> 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,
)
}
} }
+7
View File
@@ -0,0 +1,7 @@
use std::io;
pub trait DeviceWrite: Clone + Send + Sync + 'static {
fn write(&self, buf: &[u8]) -> io::Result<usize>;
#[cfg(feature = "inner_tun")]
fn into_device_adapter(self) -> crate::tun_tap_device::tun_create_helper::DeviceAdapter;
}
+1
View File
@@ -8,6 +8,7 @@ pub struct U64Adder {
inner: Arc<U64AdderInner>, inner: Arc<U64AdderInner>,
index: usize, index: usize,
} }
#[derive(Clone)]
pub struct SingleU64Adder { pub struct SingleU64Adder {
inner: Arc<SingleU64AdderInner>, inner: Arc<SingleU64AdderInner>,
} }
+1 -3
View File
@@ -62,9 +62,7 @@ impl IntoRawFd for Fd {
impl Drop for Fd { impl Drop for Fd {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
if self.0 >= 0 { libc::close(self.0);
libc::close(self.0);
}
} }
} }
} }