支持排除tun
This commit is contained in:
+1
-1
@@ -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"]
|
||||
|
||||
+3
-2
@@ -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"]
|
||||
|
||||
+45
-41
@@ -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<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);
|
||||
//服务端非对称加密
|
||||
#[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,
|
||||
|
||||
+1
-4
@@ -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<Vec<u16>>,
|
||||
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 use_channel_type: UseChannelType,
|
||||
//控制丢包率
|
||||
@@ -67,7 +66,6 @@ impl Config {
|
||||
ip: Option<Ipv4Addr>,
|
||||
#[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,
|
||||
|
||||
@@ -189,9 +189,14 @@ impl Into<u8> 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<String>,
|
||||
//虚拟网卡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<String>,
|
||||
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<PeerClientInfo>) {}
|
||||
|
||||
+15
-6
@@ -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<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 {
|
||||
@@ -76,6 +76,10 @@ impl BaseConfigInfo {
|
||||
device_id: String,
|
||||
server_addr: 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 {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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: Device,
|
||||
client_cipher: Cipher,
|
||||
punch_sender: PunchSender,
|
||||
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
|
||||
@@ -45,9 +43,9 @@ pub struct ClientPacketHandler {
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
}
|
||||
|
||||
impl ClientPacketHandler {
|
||||
impl<Device: DeviceWrite> ClientPacketHandler<Device> {
|
||||
pub fn new(
|
||||
device: DeviceAdapter,
|
||||
device: Device,
|
||||
client_cipher: Cipher,
|
||||
punch_sender: PunchSender,
|
||||
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(
|
||||
&self,
|
||||
mut net_packet: NetPacket<&mut [u8]>,
|
||||
@@ -110,7 +108,7 @@ impl PacketHandler for ClientPacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientPacketHandler {
|
||||
impl<Device: DeviceWrite> ClientPacketHandler<Device> {
|
||||
fn ip_turn(
|
||||
&self,
|
||||
mut net_packet: NetPacket<&mut [u8]>,
|
||||
|
||||
@@ -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<Call> {
|
||||
pub struct RecvDataHandler<Call, Device> {
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
turn: TurnPacketHandler,
|
||||
client: ClientPacketHandler,
|
||||
server: ServerPacketHandler<Call>,
|
||||
client: ClientPacketHandler<Device>,
|
||||
server: ServerPacketHandler<Call, Device>,
|
||||
counter: U64Adder,
|
||||
nat_test: NatTest,
|
||||
}
|
||||
|
||||
impl<Call: VntCallback> RecvChannelHandler for RecvDataHandler<Call> {
|
||||
impl<Call: VntCallback, Device: DeviceWrite> RecvChannelHandler for RecvDataHandler<Call, Device> {
|
||||
fn handle(
|
||||
&mut self,
|
||||
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(
|
||||
#[cfg(feature = "server_encrypt")] rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
|
||||
server_cipher: Cipher,
|
||||
client_cipher: Cipher,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
device: DeviceAdapter,
|
||||
device: Device,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
config_info: BaseConfigInfo,
|
||||
nat_test: NatTest,
|
||||
@@ -93,6 +93,8 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
|
||||
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
||||
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<Call: VntCallback> RecvDataHandler<Call> {
|
||||
callback,
|
||||
external_route.clone(),
|
||||
handshake,
|
||||
#[cfg(feature = "inner_tun")]
|
||||
tun_device_helper,
|
||||
);
|
||||
let client = ClientPacketHandler::new(
|
||||
device.clone(),
|
||||
|
||||
@@ -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<Call> {
|
||||
pub struct ServerPacketHandler<Call, Device> {
|
||||
#[cfg(feature = "server_encrypt")]
|
||||
rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
|
||||
server_cipher: Cipher,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
device: DeviceAdapter,
|
||||
device: Device,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
config_info: BaseConfigInfo,
|
||||
nat_test: NatTest,
|
||||
callback: Call,
|
||||
#[cfg(feature = "server_encrypt")]
|
||||
up_key_time: Arc<AtomicCell<Instant>>,
|
||||
#[cfg(not(target_os = "android"))]
|
||||
route_record: Arc<Mutex<Vec<(Ipv4Addr, Ipv4Addr)>>>,
|
||||
external_route: ExternalRoute,
|
||||
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(
|
||||
#[cfg(feature = "server_encrypt")] rsa_cipher: Arc<Mutex<Option<RsaCipher>>>,
|
||||
server_cipher: Cipher,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
device: DeviceAdapter,
|
||||
device: Device,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
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<Call> ServerPacketHandler<Call> {
|
||||
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<Call: VntCallback> PacketHandler for ServerPacketHandler<Call> {
|
||||
impl<Call: VntCallback, Device: DeviceWrite> PacketHandler for ServerPacketHandler<Call, Device> {
|
||||
fn handle(
|
||||
&self,
|
||||
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(
|
||||
&self,
|
||||
context: &ChannelContext,
|
||||
@@ -305,80 +305,83 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
|
||||
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),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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<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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<IpProxyMap>,
|
||||
client_cipher: Cipher,
|
||||
server_cipher: Cipher,
|
||||
parallel: usize,
|
||||
mut up_counter: SingleU64Adder,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
compressor: Compressor,
|
||||
device_stop: DeviceStop,
|
||||
) -> io::Result<()> {
|
||||
if parallel > 1 {
|
||||
let (sender, receivers) = channel_group::<(Vec<u8>, 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(())
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
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<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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
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<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(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Arc<Device>> {
|
||||
pub fn create_device(config: DeviceConfig) -> Result<Arc<Device>, 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<Arc<Device>> {
|
||||
#[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<Arc<Device>> {
|
||||
.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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<Device>,
|
||||
tun: Arc<Mutex<Option<Arc<Device>>>>,
|
||||
}
|
||||
|
||||
impl DeviceAdapter {
|
||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||
pub fn new(tun: Arc<Device>) -> Self {
|
||||
Self { tun }
|
||||
pub fn insert(&self, device: Arc<Device>) {
|
||||
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<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 {
|
||||
&self.tun
|
||||
}
|
||||
}
|
||||
|
||||
#[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(())
|
||||
fn into_device_adapter(self) -> DeviceAdapter {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
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 {
|
||||
stop_manager: StopManager,
|
||||
context: ChannelContext,
|
||||
@@ -76,7 +67,6 @@ struct TunDeviceHelperInner {
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
client_cipher: Cipher,
|
||||
server_cipher: Cipher,
|
||||
parallel: usize,
|
||||
up_counter: SingleU64Adder,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
compressor: Compressor,
|
||||
@@ -91,48 +81,65 @@ impl TunDeviceHelper {
|
||||
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
|
||||
client_cipher: Cipher,
|
||||
server_cipher: Cipher,
|
||||
parallel: usize,
|
||||
up_counter: SingleU64Adder,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
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<Device>) -> 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<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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -8,6 +8,7 @@ pub struct U64Adder {
|
||||
inner: Arc<U64AdderInner>,
|
||||
index: usize,
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct SingleU64Adder {
|
||||
inner: Arc<SingleU64AdderInner>,
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user