支持客户端加密
This commit is contained in:
@@ -82,10 +82,11 @@
|
|||||||
- 客户端中继转发
|
- 客户端中继转发
|
||||||
- IP代理
|
- IP代理
|
||||||
- p2p组播/广播
|
- p2p组播/广播
|
||||||
|
- 客户端数据加密
|
||||||
|
|
||||||
### Todo
|
### Todo
|
||||||
- 支持安卓
|
- 支持安卓
|
||||||
- 数据加密
|
- 服务端数据加密
|
||||||
|
|
||||||
### 常见问题
|
### 常见问题
|
||||||
#### 问题1: 设置网络地址失败
|
#### 问题1: 设置网络地址失败
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ switch_log_help: "Record the log, the output is in the '${home}/.switch_desktop'
|
|||||||
switch_tap_help: "Use tap mode, tun mode will be used by default"
|
switch_tap_help: "Use tap mode, tun mode will be used by default"
|
||||||
switch_in_ip_help: "Use when configuring point-to-network (IP proxy), --in-ip 192.168.10.0/24,10.26.0.3, which means it is allowed to receive data from the network segment 192.168.10.0/24 and forward it to 10.26.0.3"
|
switch_in_ip_help: "Use when configuring point-to-network (IP proxy), --in-ip 192.168.10.0/24,10.26.0.3, which means it is allowed to receive data from the network segment 192.168.10.0/24 and forward it to 10.26.0.3"
|
||||||
switch_out_ip_help: "Use when configuring point-to-network, --out-ip 192.168.10.0/24,192.168.1.10, which means that the data with the target of 192.168.10.0/24 is allowed to be forwarded from the network card 192.168.1.10"
|
switch_out_ip_help: "Use when configuring point-to-network, --out-ip 192.168.10.0/24,192.168.1.10, which means that the data with the target of 192.168.10.0/24 is allowed to be forwarded from the network card 192.168.1.10"
|
||||||
|
switch_password_help: "Client Data Encryption"
|
||||||
switch_config_help: "Read configuration file"
|
switch_config_help: "Read configuration file"
|
||||||
switch_stop_about: "Stop background service"
|
switch_stop_about: "Stop background service"
|
||||||
switch_route_about: "View route"
|
switch_route_about: "View route"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ switch_log_help: "记录日志,输出在 '${home}/.switch_desktop' 目录下
|
|||||||
switch_tap_help: "使用tap模式,默认会使用tun模式"
|
switch_tap_help: "使用tap模式,默认会使用tun模式"
|
||||||
switch_in_ip_help: "配置点对网(IP代理)时使用,--in-ip 192.168.10.0/24,10.26.0.3,表示允许接收网段192.168.10.0/24的数据并转发到10.26.0.3"
|
switch_in_ip_help: "配置点对网(IP代理)时使用,--in-ip 192.168.10.0/24,10.26.0.3,表示允许接收网段192.168.10.0/24的数据并转发到10.26.0.3"
|
||||||
switch_out_ip_help: "配置点对网时使用,--out-ip 192.168.10.0/24,192.168.1.10,表示允许目标为192.168.10.0/24的数据从网卡192.168.1.10转发出去"
|
switch_out_ip_help: "配置点对网时使用,--out-ip 192.168.10.0/24,192.168.1.10,表示允许目标为192.168.10.0/24的数据从网卡192.168.1.10转发出去"
|
||||||
|
switch_password_help: "使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密。使用相同密码的客户端才能通信"
|
||||||
switch_config_help: "读取配置文件"
|
switch_config_help: "读取配置文件"
|
||||||
switch_stop_about: "停止后台服务"
|
switch_stop_about: "停止后台服务"
|
||||||
switch_route_about: "查看路由"
|
switch_route_about: "查看路由"
|
||||||
|
|||||||
@@ -62,6 +62,11 @@ fn common() -> Command {
|
|||||||
.long("out-ip")
|
.long("out-ip")
|
||||||
.help(switch_out_ip_help())
|
.help(switch_out_ip_help())
|
||||||
.action(ArgAction::Append)
|
.action(ArgAction::Append)
|
||||||
|
).arg(
|
||||||
|
Arg::new("password")
|
||||||
|
.long("password")
|
||||||
|
.help(switch_password_help())
|
||||||
|
.action(ArgAction::Set)
|
||||||
).arg(
|
).arg(
|
||||||
Arg::new("config")
|
Arg::new("config")
|
||||||
.long("config")
|
.long("config")
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ pub struct StartConfig {
|
|||||||
#[cfg(any(unix))]
|
#[cfg(any(unix))]
|
||||||
pub off_command_server: bool,
|
pub off_command_server: bool,
|
||||||
pub log: bool,
|
pub log: bool,
|
||||||
|
pub password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ips_parse(ips: &Vec<String>) -> Result<Vec<(u32, u32, Ipv4Addr)>, String> {
|
fn ips_parse(ips: &Vec<String>) -> Result<Vec<(u32, u32, Ipv4Addr)>, String> {
|
||||||
@@ -163,7 +164,7 @@ pub fn default_config(start_args: StartArgs) -> Result<StartConfig, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(format!("{} :{:?}",i18n::switch_relay_server_address_error(), e));
|
return Err(format!("{} :{:?}", i18n::switch_relay_server_address_error(), e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
println!("中继服务器:{:?}", server);
|
println!("中继服务器:{:?}", server);
|
||||||
@@ -187,6 +188,7 @@ pub fn default_config(start_args: StartArgs) -> Result<StartConfig, String> {
|
|||||||
#[cfg(any(unix))]
|
#[cfg(any(unix))]
|
||||||
off_command_server: start_args.off_command_server,
|
off_command_server: start_args.off_command_server,
|
||||||
log: start_args.log,
|
log: start_args.log,
|
||||||
|
password: start_args.password,
|
||||||
};
|
};
|
||||||
println!("========参数配置========");
|
println!("========参数配置========");
|
||||||
Ok(base_config)
|
Ok(base_config)
|
||||||
@@ -268,7 +270,7 @@ pub fn read_config_file(config_path: PathBuf) -> Result<StartConfig, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(format!("{}:{:?}",i18n::switch_relay_server_address_error(), e));
|
return Err(format!("{}:{:?}", i18n::switch_relay_server_address_error(), e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
println!("中继服务器:{:?}", server);
|
println!("中继服务器:{:?}", server);
|
||||||
@@ -294,6 +296,7 @@ pub fn read_config_file(config_path: PathBuf) -> Result<StartConfig, String> {
|
|||||||
#[cfg(any(unix))]
|
#[cfg(any(unix))]
|
||||||
off_command_server: args_config.off_command_server,
|
off_command_server: args_config.off_command_server,
|
||||||
log,
|
log,
|
||||||
|
password:args_config.password
|
||||||
};
|
};
|
||||||
println!("========参数配置========");
|
println!("========参数配置========");
|
||||||
Ok(base_config)
|
Ok(base_config)
|
||||||
@@ -331,6 +334,7 @@ pub struct ArgsConfig {
|
|||||||
pub off_command_server: bool,
|
pub off_command_server: bool,
|
||||||
#[serde(default = "default_false")]
|
#[serde(default = "default_false")]
|
||||||
pub log: bool,
|
pub log: bool,
|
||||||
|
pub password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@@ -355,6 +359,7 @@ impl ArgsConfig {
|
|||||||
log: start_config.log,
|
log: start_config.log,
|
||||||
#[cfg(any(unix))]
|
#[cfg(any(unix))]
|
||||||
off_command_server: start_config.off_command_server,
|
off_command_server: start_config.off_command_server,
|
||||||
|
password: start_config.password,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ pub fn switch_in_ip_help() -> String {
|
|||||||
pub fn switch_out_ip_help() -> String {
|
pub fn switch_out_ip_help() -> String {
|
||||||
rust_i18n::t!("switch_out_ip_help")
|
rust_i18n::t!("switch_out_ip_help")
|
||||||
}
|
}
|
||||||
|
pub fn switch_password_help() -> String {
|
||||||
|
rust_i18n::t!("switch_password_help")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn switch_config_help() -> String {
|
pub fn switch_config_help() -> String {
|
||||||
rust_i18n::t!("switch_config_help")
|
rust_i18n::t!("switch_config_help")
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ pub struct StartArgs {
|
|||||||
/// Use when configuring peer-to-peer networks
|
/// Use when configuring peer-to-peer networks
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
out_ip: Option<Vec<String>>,
|
out_ip: Option<Vec<String>>,
|
||||||
|
/// 客户端数据加密
|
||||||
|
#[arg(long)]
|
||||||
|
password:Option<String>,
|
||||||
/// 读取配置文件 --config config_file_path
|
/// 读取配置文件 --config config_file_path
|
||||||
/// Read configuration file
|
/// Read configuration file
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ pub async fn main0(base_args: BaseArgs) {
|
|||||||
start_config.nat_test_server.clone(),
|
start_config.nat_test_server.clone(),
|
||||||
start_config.in_ips.clone(),
|
start_config.in_ips.clone(),
|
||||||
start_config.out_ips.clone(),
|
start_config.out_ips.clone(),
|
||||||
|
start_config.password.clone(),
|
||||||
);
|
);
|
||||||
let lock = match config::lock_file() {
|
let lock = match config::lock_file() {
|
||||||
Ok(lock) => {
|
Ok(lock) => {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ fn not_started() -> bool {
|
|||||||
if state == ServiceState::Running {
|
if state == ServiceState::Running {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
println!("{}",i18n::switch_service_not_start_print())
|
println!("{}", i18n::switch_service_not_start_print())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -100,7 +100,7 @@ pub fn main0(base_args: BaseArgs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("{}",i18n::switch_service_not_stopped_print());
|
println!("{}", i18n::switch_service_not_stopped_print());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -118,6 +118,7 @@ pub fn main0(base_args: BaseArgs) {
|
|||||||
start_config.nat_test_server,
|
start_config.nat_test_server,
|
||||||
start_config.in_ips,
|
start_config.in_ips,
|
||||||
start_config.out_ips,
|
start_config.out_ips,
|
||||||
|
start_config.password,
|
||||||
);
|
);
|
||||||
let lock = match config::lock_file() {
|
let lock = match config::lock_file() {
|
||||||
Ok(lock) => {
|
Ok(lock) => {
|
||||||
@@ -179,7 +180,7 @@ pub fn main0(base_args: BaseArgs) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if service_state().is_ok() {
|
if service_state().is_ok() {
|
||||||
println!("{}",i18n::switch_server_already_installed_print());
|
println!("{}", i18n::switch_server_already_installed_print());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let path: PathBuf = args.path.into();
|
let path: PathBuf = args.path.into();
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ async fn service_main(arguments: Vec<OsString>) -> windows_service::Result<()> {
|
|||||||
match start_switch(arguments).await {
|
match start_switch(arguments).await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
parker.park();
|
parker.park();
|
||||||
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("服务启动失败 {:?}",e);
|
log::error!("服务启动失败 {:?}",e);
|
||||||
@@ -171,12 +170,13 @@ async fn start_switch(arguments: Vec<OsString>) -> switch::Result<()> {
|
|||||||
start_config.nat_test_server,
|
start_config.nat_test_server,
|
||||||
start_config.in_ips,
|
start_config.in_ips,
|
||||||
start_config.out_ips,
|
start_config.out_ips,
|
||||||
|
start_config.password,
|
||||||
);
|
);
|
||||||
log::info!("switch-service服务启动");
|
log::info!("switch-service服务启动");
|
||||||
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
match Switch::start(config).await {
|
match Switch::start(config).await {
|
||||||
Ok(switch) => {
|
Ok(switch) => {
|
||||||
let switch = Arc::new(switch);
|
let switch = Arc::new(switch);
|
||||||
let command_server = crate::command::server::CommandServer::new();
|
let command_server = crate::command::server::CommandServer::new();
|
||||||
@@ -191,7 +191,6 @@ async fn start_switch(arguments: Vec<OsString>) -> switch::Result<()> {
|
|||||||
log::error!("{:?}", e);
|
log::error!("{:?}", e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ parking_lot = "0.12.1"
|
|||||||
rsa = "0.7.2"
|
rsa = "0.7.2"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
sha2 = { version = "0.10.6", features = ["oid"] }
|
sha2 = { version = "0.10.6", features = ["oid"] }
|
||||||
|
aes-gcm = "0.10.2"
|
||||||
|
|
||||||
thiserror = "1.0.37"
|
thiserror = "1.0.37"
|
||||||
chrono = "0.4.23"
|
chrono = "0.4.23"
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ impl Channel {
|
|||||||
#[cfg(any(unix))]
|
#[cfg(any(unix))]
|
||||||
let id = udp.as_raw_fd() as usize;
|
let id = udp.as_raw_fd() as usize;
|
||||||
context.udp_map.insert(id, udp.clone());
|
context.udp_map.insert(id, udp.clone());
|
||||||
let mut buf = [0; 65546];
|
let mut buf = [0; 65536];
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
rs=udp.recv_from(&mut buf[head_reserve..])=>{
|
rs=udp.recv_from(&mut buf[head_reserve..])=>{
|
||||||
|
|||||||
+26
-5
@@ -1,6 +1,7 @@
|
|||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
use std::net::{Ipv4Addr, SocketAddr};
|
use std::net::{Ipv4Addr, SocketAddr};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use aes_gcm::{Aes256Gcm, Key, KeyInit};
|
||||||
|
|
||||||
use crossbeam::atomic::AtomicCell;
|
use crossbeam::atomic::AtomicCell;
|
||||||
use crossbeam_skiplist::SkipMap;
|
use crossbeam_skiplist::SkipMap;
|
||||||
@@ -41,6 +42,12 @@ pub struct Switch {
|
|||||||
impl Switch {
|
impl Switch {
|
||||||
pub async fn start(config: Config) -> crate::Result<Switch> {
|
pub async fn start(config: Config) -> crate::Result<Switch> {
|
||||||
log::info!("config:{:?}",config);
|
log::info!("config:{:?}",config);
|
||||||
|
let cipher = if let Some(key) = &config.key {
|
||||||
|
let key: &Key<Aes256Gcm> = key.into();
|
||||||
|
Some(Aes256Gcm::new(&key))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let main_channel = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
let main_channel = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
||||||
let response = registration_handler::registration(&main_channel, config.server_address, config.token.clone(), config.device_id.clone(), config.name.clone()).await?;
|
let response = registration_handler::registration(&main_channel, config.server_address, config.token.clone(), config.device_id.clone(), config.name.clone()).await?;
|
||||||
let (cone_sender, cone_receiver) = channel(3);
|
let (cone_sender, cone_receiver) = channel(3);
|
||||||
@@ -62,7 +69,7 @@ impl Switch {
|
|||||||
let local_port = context.main_local_port()?;
|
let local_port = context.main_local_port()?;
|
||||||
// NAT检测
|
// NAT检测
|
||||||
let nat_test = NatTest::new(config.nat_test_server.clone(), Ipv4Addr::from(response.public_ip), response.public_port as u16, local_ip, local_port);
|
let nat_test = NatTest::new(config.nat_test_server.clone(), Ipv4Addr::from(response.public_ip), response.public_port as u16, local_ip, local_port);
|
||||||
let in_ips = config.in_ips.iter().map(|(dest, mask, _)| { (Ipv4Addr::from(*dest), Ipv4Addr::from(*mask)) }).collect::<Vec<(Ipv4Addr, Ipv4Addr)>>();
|
let in_ips = config.in_ips.iter().map(|(dest, mask, _)| { (Ipv4Addr::from(*dest & *mask), Ipv4Addr::from(*mask)) }).collect::<Vec<(Ipv4Addr, Ipv4Addr)>>();
|
||||||
|
|
||||||
let out_ips = config.out_ips.iter().map(|(_, _, ip)| *ip).collect::<Vec<Ipv4Addr>>();
|
let out_ips = config.out_ips.iter().map(|(_, _, ip)| *ip).collect::<Vec<Ipv4Addr>>();
|
||||||
let out_external_route = ExternalRoute::new(config.out_ips);
|
let out_external_route = ExternalRoute::new(config.out_ips);
|
||||||
@@ -78,7 +85,8 @@ impl Switch {
|
|||||||
let (tap_writer, tap_reader) = tun_tap_device::create_device(tun_tap_device::DeviceType::Tap, virtual_ip, virtual_netmask, virtual_gateway, in_ips)?;
|
let (tap_writer, tap_reader) = tun_tap_device::create_device(tun_tap_device::DeviceType::Tap, virtual_ip, virtual_netmask, virtual_gateway, in_ips)?;
|
||||||
let igmp_server = IgmpServer::new(tap_writer.clone());
|
let igmp_server = IgmpServer::new(tap_writer.clone());
|
||||||
//tap数据处理
|
//tap数据处理
|
||||||
tap_handler::start(channel_sender.clone(), tap_reader.clone(), tap_writer.clone(), igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone());
|
tap_handler::start(channel_sender.clone(), tap_reader.clone(), tap_writer.clone(),
|
||||||
|
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
|
||||||
(tap_writer, igmp_server)
|
(tap_writer, igmp_server)
|
||||||
} else {
|
} else {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@@ -90,7 +98,8 @@ impl Switch {
|
|||||||
let (tun_writer, tun_reader) = tun_tap_device::create_device(tun_tap_device::DeviceType::Tun, virtual_ip, virtual_netmask, virtual_gateway, in_ips)?;
|
let (tun_writer, tun_reader) = tun_tap_device::create_device(tun_tap_device::DeviceType::Tun, virtual_ip, virtual_netmask, virtual_gateway, in_ips)?;
|
||||||
let igmp_server = IgmpServer::new(tun_writer.clone());
|
let igmp_server = IgmpServer::new(tun_writer.clone());
|
||||||
//tun数据接收处理
|
//tun数据接收处理
|
||||||
tun_handler::start(channel_sender.clone(), tun_reader.clone(), tun_writer.clone(), igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone());
|
tun_handler::start(channel_sender.clone(), tun_reader.clone(), tun_writer.clone(),
|
||||||
|
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
|
||||||
(tun_writer, igmp_server)
|
(tun_writer, igmp_server)
|
||||||
};
|
};
|
||||||
//外部数据接收处理
|
//外部数据接收处理
|
||||||
@@ -98,7 +107,7 @@ impl Switch {
|
|||||||
register.clone(), nat_test.clone(), igmp_server,
|
register.clone(), nat_test.clone(), igmp_server,
|
||||||
device_writer.clone(), connect_status.clone(),
|
device_writer.clone(), connect_status.clone(),
|
||||||
peer_nat_info_map.clone(), ip_proxy_map, out_external_route,
|
peer_nat_info_map.clone(), ip_proxy_map, out_external_route,
|
||||||
cone_sender, symmetric_sender);
|
cone_sender, symmetric_sender, cipher);
|
||||||
let channel = Channel::new(context.clone(), channel_recv_handler);
|
let channel = Channel::new(context.clone(), channel_recv_handler);
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
tokio::runtime::Builder::new_multi_thread()
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
@@ -178,15 +187,26 @@ pub struct Config {
|
|||||||
pub nat_test_server: Vec<SocketAddr>,
|
pub nat_test_server: Vec<SocketAddr>,
|
||||||
pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
|
pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||||
pub out_ips: Vec<(u32, u32, Ipv4Addr)>,
|
pub out_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||||
|
pub key: Option<[u8; 32]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use sha2::Digest;
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new(tap: bool, token: String,
|
pub fn new(tap: bool, token: String,
|
||||||
device_id: String,
|
device_id: String,
|
||||||
name: String,
|
name: String,
|
||||||
server_address: SocketAddr,
|
server_address: SocketAddr,
|
||||||
nat_test_server: Vec<SocketAddr>,
|
nat_test_server: Vec<SocketAddr>,
|
||||||
in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32, Ipv4Addr)>, ) -> Self {
|
in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32, Ipv4Addr)>, password: Option<String>, ) -> Self {
|
||||||
|
let key = if let Some(password) = password {
|
||||||
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
hasher.update(password.as_bytes());
|
||||||
|
let key: [u8; 32] = hasher.finalize().into();
|
||||||
|
Some(key)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
Self {
|
Self {
|
||||||
tap,
|
tap,
|
||||||
token,
|
token,
|
||||||
@@ -196,6 +216,7 @@ impl Config {
|
|||||||
nat_test_server,
|
nat_test_server,
|
||||||
in_ips,
|
in_ips,
|
||||||
out_ips,
|
out_ips,
|
||||||
|
key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use aes_gcm::{AeadInPlace, Aes256Gcm, Nonce, Tag};
|
||||||
|
use aes_gcm::aead::consts::{U12, U16};
|
||||||
|
use aes_gcm::aead::generic_array::GenericArray;
|
||||||
|
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use crossbeam::atomic::AtomicCell;
|
use crossbeam::atomic::AtomicCell;
|
||||||
@@ -45,6 +48,7 @@ pub struct ChannelDataHandler {
|
|||||||
out_external_route: ExternalRoute,
|
out_external_route: ExternalRoute,
|
||||||
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
|
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
|
||||||
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
|
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
|
||||||
|
cipher: Option<Aes256Gcm>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChannelDataHandler {
|
impl ChannelDataHandler {
|
||||||
@@ -59,7 +63,8 @@ impl ChannelDataHandler {
|
|||||||
ip_proxy_map: IpProxyMap,
|
ip_proxy_map: IpProxyMap,
|
||||||
out_external_route: ExternalRoute,
|
out_external_route: ExternalRoute,
|
||||||
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
|
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
|
||||||
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>, ) -> Self {
|
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
|
||||||
|
cipher: Option<Aes256Gcm>, ) -> Self {
|
||||||
Self {
|
Self {
|
||||||
current_device,
|
current_device,
|
||||||
device_list,
|
device_list,
|
||||||
@@ -73,6 +78,7 @@ impl ChannelDataHandler {
|
|||||||
out_external_route,
|
out_external_route,
|
||||||
cone_sender,
|
cone_sender,
|
||||||
symmetric_sender,
|
symmetric_sender,
|
||||||
|
cipher,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,8 +133,51 @@ impl ChannelDataHandler {
|
|||||||
match net_packet.protocol() {
|
match net_packet.protocol() {
|
||||||
Protocol::IpTurn => {
|
Protocol::IpTurn => {
|
||||||
match ip_turn_packet::Protocol::from(net_packet.transport_protocol()) {
|
match ip_turn_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||||
|
ip_turn_packet::Protocol::Icmp => {
|
||||||
|
let ipv4 = IpV4Packet::new(net_packet.payload())?;
|
||||||
|
if ipv4.protocol() == ipv4::protocol::Protocol::Icmp {
|
||||||
|
self.device_writer.write_ipv4(&mut buf[12..])?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ip_turn_packet::Protocol::Igmp => {
|
||||||
|
let ipv4 = IpV4Packet::new(net_packet.payload())?;
|
||||||
|
if ipv4.protocol() == ipv4::protocol::Protocol::Igmp {
|
||||||
|
self.igmp_server.handle(ipv4.payload(), source)?;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
ip_turn_packet::Protocol::Ipv4 => {
|
ip_turn_packet::Protocol::Ipv4 => {
|
||||||
let mut ipv4 = IpV4Packet::new(net_packet.payload_mut())?;
|
let data = if let Some(cipher) = &self.cipher {
|
||||||
|
if !net_packet.is_encrypt() {
|
||||||
|
//未加密的数据之间丢弃
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if net_packet.payload().len() < 16 {
|
||||||
|
log::error!("数据异常,长度小于16");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
//需要解密
|
||||||
|
let mut nonce = [0; 12];
|
||||||
|
nonce[0..4].copy_from_slice(&source.octets());
|
||||||
|
nonce[4..8].copy_from_slice(&destination.octets());
|
||||||
|
nonce[8] = Protocol::IpTurn.into();
|
||||||
|
nonce[9] = ip_turn_packet::Protocol::Ipv4.into();
|
||||||
|
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce);
|
||||||
|
let data_len = net_packet.payload().len() - 16;
|
||||||
|
let tag: GenericArray<u8, U16> = Tag::clone_from_slice(&net_packet.payload()[data_len..]);
|
||||||
|
match cipher.decrypt_in_place_detached(nonce, &[], &mut net_packet.payload_mut()[..data_len], &tag) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("数据解密异常:{}",e);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&mut net_packet.payload_mut()[..data_len]
|
||||||
|
} else {
|
||||||
|
net_packet.payload_mut()
|
||||||
|
};
|
||||||
|
let mut ipv4 = IpV4Packet::new(data)?;
|
||||||
match ipv4.protocol() {
|
match ipv4.protocol() {
|
||||||
ipv4::protocol::Protocol::Igmp => {
|
ipv4::protocol::Protocol::Igmp => {
|
||||||
self.igmp_server.handle(ipv4.payload(), source)?;
|
self.igmp_server.handle(ipv4.payload(), source)?;
|
||||||
@@ -146,63 +195,87 @@ impl ChannelDataHandler {
|
|||||||
ipv4.update_checksum();
|
ipv4.update_checksum();
|
||||||
net_packet.set_source(destination);
|
net_packet.set_source(destination);
|
||||||
net_packet.set_destination(source);
|
net_packet.set_destination(source);
|
||||||
|
if let Some(cipher) = &self.cipher {
|
||||||
|
//需要加密
|
||||||
|
let mut nonce = [0; 12];
|
||||||
|
nonce[0..4].copy_from_slice(&destination.octets());
|
||||||
|
nonce[4..8].copy_from_slice(&source.octets());
|
||||||
|
nonce[8] = Protocol::IpTurn.into();
|
||||||
|
nonce[9] = ip_turn_packet::Protocol::Ipv4.into();
|
||||||
|
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce);
|
||||||
|
let data_len = net_packet.payload().len() - 16;
|
||||||
|
match cipher.encrypt_in_place_detached(nonce, &[], &mut net_packet.payload_mut()[..data_len]) {
|
||||||
|
Ok(tag) => {
|
||||||
|
if tag.len() != 16 {
|
||||||
|
log::error!("加密tag长度错误:{}",tag.len());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
net_packet.set_encrypt_flag(true);
|
||||||
|
net_packet.payload_mut()[data_len..data_len + 16].copy_from_slice(tag.as_slice());
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("加密失败:{}",e);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
context.send_by_key(net_packet.buffer(), route_key).await?;
|
context.send_by_key(net_packet.buffer(), route_key).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
if ipv4.destination_ip() != destination {
|
}
|
||||||
if let Some(gate_way) = self.out_external_route.route(&ipv4.destination_ip()) {
|
if ipv4.destination_ip() != destination {
|
||||||
match ipv4.protocol() {
|
if let Some(gate_way) = self.out_external_route.route(&ipv4.destination_ip()) {
|
||||||
ipv4::protocol::Protocol::Tcp => {
|
match ipv4.protocol() {
|
||||||
let dest_ip = ipv4.destination_ip();
|
ipv4::protocol::Protocol::Tcp => {
|
||||||
//转发到代理目标地址
|
let dest_ip = ipv4.destination_ip();
|
||||||
let mut tcp_packet = packet::tcp::tcp::TcpPacket::new(source, destination, ipv4.payload_mut())?;
|
//转发到代理目标地址
|
||||||
let source_port = tcp_packet.source_port();
|
let mut tcp_packet = packet::tcp::tcp::TcpPacket::new(source, destination, ipv4.payload_mut())?;
|
||||||
let dest_port = tcp_packet.destination_port();
|
let source_port = tcp_packet.source_port();
|
||||||
tcp_packet.set_destination_port(self.ip_proxy_map.tcp_proxy_port);
|
let dest_port = tcp_packet.destination_port();
|
||||||
tcp_packet.update_checksum();
|
tcp_packet.set_destination_port(self.ip_proxy_map.tcp_proxy_port);
|
||||||
ipv4.set_destination_ip(destination);
|
tcp_packet.update_checksum();
|
||||||
ipv4.update_checksum();
|
ipv4.set_destination_ip(destination);
|
||||||
self.ip_proxy_map.tcp_proxy_map.insert(SocketAddrV4::new(source, source_port),
|
ipv4.update_checksum();
|
||||||
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
|
self.ip_proxy_map.tcp_proxy_map.insert(SocketAddrV4::new(source, source_port),
|
||||||
}
|
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
|
||||||
ipv4::protocol::Protocol::Udp => {
|
}
|
||||||
let dest_ip = ipv4.destination_ip();
|
ipv4::protocol::Protocol::Udp => {
|
||||||
//转发到代理目标地址
|
let dest_ip = ipv4.destination_ip();
|
||||||
let mut udp_packet = packet::udp::udp::UdpPacket::new(source, destination, ipv4.payload_mut())?;
|
//转发到代理目标地址
|
||||||
let source_port = udp_packet.source_port();
|
let mut udp_packet = packet::udp::udp::UdpPacket::new(source, destination, ipv4.payload_mut())?;
|
||||||
let dest_port = udp_packet.destination_port();
|
let source_port = udp_packet.source_port();
|
||||||
udp_packet.set_destination_port(self.ip_proxy_map.udp_proxy_port);
|
let dest_port = udp_packet.destination_port();
|
||||||
udp_packet.update_checksum();
|
udp_packet.set_destination_port(self.ip_proxy_map.udp_proxy_port);
|
||||||
ipv4.set_destination_ip(destination);
|
udp_packet.update_checksum();
|
||||||
ipv4.update_checksum();
|
ipv4.set_destination_ip(destination);
|
||||||
self.ip_proxy_map.udp_proxy_map.insert(SocketAddrV4::new(source, source_port),
|
ipv4.update_checksum();
|
||||||
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
|
self.ip_proxy_map.udp_proxy_map.insert(SocketAddrV4::new(source, source_port),
|
||||||
}
|
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
|
||||||
ipv4::protocol::Protocol::Icmp => {
|
}
|
||||||
let dest_ip = ipv4.destination_ip();
|
ipv4::protocol::Protocol::Icmp => {
|
||||||
//转发到代理目标地址
|
let dest_ip = ipv4.destination_ip();
|
||||||
let icmp_packet = icmp::IcmpPacket::new(ipv4.payload())?;
|
//转发到代理目标地址
|
||||||
match icmp_packet.header_other() {
|
let icmp_packet = icmp::IcmpPacket::new(ipv4.payload())?;
|
||||||
HeaderOther::Identifier(id, seq) => {
|
match icmp_packet.header_other() {
|
||||||
self.ip_proxy_map.icmp_proxy_map.insert((dest_ip, id, seq), source);
|
HeaderOther::Identifier(id, seq) => {
|
||||||
self.ip_proxy_map.send_icmp(ipv4.payload(), &gate_way, &dest_ip)?;
|
self.ip_proxy_map.icmp_proxy_map.insert((dest_ip, id, seq), source);
|
||||||
}
|
self.ip_proxy_map.send_icmp(ipv4.payload(), &gate_way, &dest_ip)?;
|
||||||
_ => {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//传输协议12字节
|
//传输协议12字节
|
||||||
self.device_writer.write_ipv4(&mut buf[12..])?;
|
self.device_writer.write_ipv4(&mut buf[12..])?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
|
use std::io;
|
||||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||||
|
use aes_gcm::{AeadInPlace, Aes256Gcm, Nonce};
|
||||||
|
use aes_gcm::aead::consts::U12;
|
||||||
|
use aes_gcm::aead::generic_array::GenericArray;
|
||||||
use packet::ip::ipv4::packet::IpV4Packet;
|
use packet::ip::ipv4::packet::IpV4Packet;
|
||||||
use packet::ip::ipv4::protocol::Protocol;
|
use packet::ip::ipv4::protocol::Protocol;
|
||||||
use packet::tcp::tcp::TcpPacket;
|
use packet::tcp::tcp::TcpPacket;
|
||||||
@@ -42,9 +46,9 @@ async fn multicast(igmp_server: &IgmpServer, multicast_addr: Ipv4Addr, sender: &
|
|||||||
let mut peer_ips = Vec::with_capacity(8);
|
let mut peer_ips = Vec::with_capacity(8);
|
||||||
let vec = sender.direct_route_table_one();
|
let vec = sender.direct_route_table_one();
|
||||||
if let Some(members) = igmp_server.load(&multicast_addr) {
|
if let Some(members) = igmp_server.load(&multicast_addr) {
|
||||||
let members_guard = members.read();
|
|
||||||
for (peer_ip, route) in vec {
|
for (peer_ip, route) in vec {
|
||||||
if members_guard.is_send(&peer_ip) {
|
let is_send = {members.read().is_send(&peer_ip)};
|
||||||
|
if is_send {
|
||||||
if sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
|
if sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
|
||||||
peer_ips.push(peer_ip);
|
peer_ips.push(peer_ip);
|
||||||
if peer_ips.len() == u8::MAX as usize {
|
if peer_ips.len() == u8::MAX as usize {
|
||||||
@@ -69,42 +73,59 @@ async fn multicast(igmp_server: &IgmpServer, multicast_addr: Ipv4Addr, sender: &
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 实现一个原地发送,必须保证是如下结构
|
/// 实现一个原地发送,必须保证是如下结构
|
||||||
/// |12字节开头|ip报文|至少1024字节结尾|
|
/// |12字节开头|ip报文|至少1024字节+12字节结尾|
|
||||||
///
|
///
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
|
pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
|
||||||
data_len: usize,//数据总长度=ip长度+12
|
mut data_len: usize,//数据总长度=ip长度+12
|
||||||
igmp_server: &IgmpServer,
|
igmp_server: &IgmpServer,
|
||||||
current_device: CurrentDeviceInfo,
|
current_device: CurrentDeviceInfo,
|
||||||
ip_route: &ExternalRoute, proxy_map: &IpProxyMap) -> Result<()> {
|
ip_route: &ExternalRoute, proxy_map: &IpProxyMap, cipher: &Option<Aes256Gcm>) -> Result<()> {
|
||||||
let ipv4_packet = IpV4Packet::new(&buf[12..data_len])?;
|
let ipv4_packet = IpV4Packet::new(&buf[12..data_len])?;
|
||||||
let protocol = ipv4_packet.protocol();
|
let protocol = ipv4_packet.protocol();
|
||||||
let ip_head_len = ipv4_packet.header_len() as usize * 4;
|
let ip_head_len = ipv4_packet.header_len() as usize * 4;
|
||||||
let src_ip = ipv4_packet.source_ip();
|
let src_ip = ipv4_packet.source_ip();
|
||||||
let mut dest_ip = ipv4_packet.destination_ip();
|
let mut dest_ip = ipv4_packet.destination_ip();
|
||||||
let mut net_packet = NetPacket::new(buf)?;
|
let mut net_packet = NetPacket::new(buf)?;
|
||||||
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4.into());
|
|
||||||
net_packet.set_version(Version::V1);
|
net_packet.set_version(Version::V1);
|
||||||
net_packet.set_protocol(protocol::Protocol::IpTurn);
|
net_packet.set_protocol(protocol::Protocol::IpTurn);
|
||||||
|
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4.into());
|
||||||
net_packet.first_set_ttl(3);
|
net_packet.first_set_ttl(3);
|
||||||
net_packet.set_source(src_ip);
|
net_packet.set_source(src_ip);
|
||||||
net_packet.set_destination(dest_ip);
|
net_packet.set_destination(dest_ip);
|
||||||
|
if dest_ip == current_device.virtual_gateway {
|
||||||
|
if protocol == Protocol::Icmp {
|
||||||
|
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Icmp.into());
|
||||||
|
//发送到服务端的不加密
|
||||||
|
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if dest_ip.is_multicast() {
|
||||||
|
if protocol == Protocol::Igmp {
|
||||||
|
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Igmp.into());
|
||||||
|
//发送到服务端
|
||||||
|
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
if dest_ip.is_broadcast() || current_device.broadcast_address == dest_ip {
|
if dest_ip.is_broadcast() || current_device.broadcast_address == dest_ip {
|
||||||
// 广播 发送到直连目标
|
// 广播 发送到直连目标
|
||||||
if Protocol::Udp == protocol {
|
if Protocol::Udp == protocol {
|
||||||
|
if let Some(cipher) = cipher {
|
||||||
|
//需要加密
|
||||||
|
encrypt(cipher, &mut data_len, &mut net_packet)?;
|
||||||
|
}
|
||||||
broadcast(sender, &mut net_packet, data_len, ¤t_device).await?;
|
broadcast(sender, &mut net_packet, data_len, ¤t_device).await?;
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if dest_ip.is_multicast() {
|
} else if dest_ip.is_multicast() {
|
||||||
match protocol {
|
if protocol == Protocol::Udp {
|
||||||
Protocol::Igmp => {
|
if let Some(cipher) = cipher {
|
||||||
//发送到服务端
|
//需要加密
|
||||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
encrypt(cipher, &mut data_len, &mut net_packet)?;
|
||||||
}
|
}
|
||||||
Protocol::Udp => {
|
multicast(igmp_server, dest_ip, sender, &mut net_packet, data_len, ¤t_device).await?;
|
||||||
multicast(igmp_server, dest_ip, sender, &mut net_packet, data_len, ¤t_device).await?;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
@@ -158,9 +179,37 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(cipher) = cipher {
|
||||||
|
//需要加密
|
||||||
|
encrypt(cipher, &mut data_len, &mut net_packet)?;
|
||||||
|
}
|
||||||
|
|
||||||
//优先发到直连到地址
|
//优先发到直连到地址
|
||||||
if sender.send_by_id(&net_packet.buffer()[..data_len], &dest_ip).await.is_err() {
|
if sender.send_by_id(&net_packet.buffer()[..data_len], &dest_ip).await.is_err() {
|
||||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn encrypt(cipher: &Aes256Gcm, data_len: &mut usize, net_packet: &mut NetPacket<&mut [u8]>) -> io::Result<()> {
|
||||||
|
let mut nonce = [0; 12];
|
||||||
|
nonce[0..4].copy_from_slice(&net_packet.source().octets());
|
||||||
|
nonce[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||||
|
nonce[8] = protocol::Protocol::IpTurn.into();
|
||||||
|
nonce[9] = ip_turn_packet::Protocol::Ipv4.into();
|
||||||
|
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce);
|
||||||
|
return match cipher.encrypt_in_place_detached(nonce, &[], &mut net_packet.payload_mut()[..*data_len - 12]) {
|
||||||
|
Ok(tag) => {
|
||||||
|
if tag.len() != 16 {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, format!("加密tag长度错误:{}", tag.len())));
|
||||||
|
}
|
||||||
|
net_packet.set_encrypt_flag(true);
|
||||||
|
net_packet.payload_mut()[*data_len - 12..*data_len - 12 + 16].copy_from_slice(tag.as_slice());
|
||||||
|
*data_len += 16;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
Err(io::Error::new(io::ErrorKind::Other, format!("加密失败:{}", e)))
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
|
use aes_gcm::Aes256Gcm;
|
||||||
use crossbeam::atomic::AtomicCell;
|
use crossbeam::atomic::AtomicCell;
|
||||||
use packet::arp::arp::ArpPacket;
|
use packet::arp::arp::ArpPacket;
|
||||||
use packet::ethernet;
|
use packet::ethernet;
|
||||||
@@ -21,39 +22,41 @@ pub fn start(sender: ChannelSender,
|
|||||||
igmp_server: IgmpServer,
|
igmp_server: IgmpServer,
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||||
ip_route: ExternalRoute,
|
ip_route: ExternalRoute,
|
||||||
ip_proxy_map: IpProxyMap) {
|
ip_proxy_map: IpProxyMap,
|
||||||
|
cipher: Option<Aes256Gcm>) {
|
||||||
thread::Builder::new().name("tap-handler".into()).spawn(move || {
|
thread::Builder::new().name("tap-handler".into()).spawn(move || {
|
||||||
tokio::runtime::Builder::new_current_thread()
|
tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all().build().unwrap()
|
.enable_all().build().unwrap()
|
||||||
.block_on(async move {
|
.block_on(async move {
|
||||||
if let Err(e) = start_(sender, device_reader,
|
if let Err(e) = start_(sender, device_reader,
|
||||||
device_writer, igmp_server,
|
device_writer, igmp_server,
|
||||||
current_device, ip_route, ip_proxy_map).await {
|
current_device, ip_route, ip_proxy_map, cipher).await {
|
||||||
log::warn!("tap:{:?}",e);
|
log::warn!("tap:{:?}",e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_(sender: ChannelSender,
|
async fn start_(sender: ChannelSender,
|
||||||
device_reader: DeviceReader,
|
device_reader: DeviceReader,
|
||||||
device_writer: DeviceWriter,
|
device_writer: DeviceWriter,
|
||||||
igmp_server: IgmpServer,
|
igmp_server: IgmpServer,
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||||
ip_route: ExternalRoute,
|
ip_route: ExternalRoute,
|
||||||
ip_proxy_map: IpProxyMap) -> io::Result<()> {
|
ip_proxy_map: IpProxyMap,
|
||||||
let mut buf = [0; 4096];
|
cipher: Option<Aes256Gcm>) -> io::Result<()> {
|
||||||
|
let mut buf = [0; 2048];
|
||||||
loop {
|
loop {
|
||||||
|
//ip拆包了会直接丢弃?
|
||||||
let len = device_reader.read(&mut buf)?;
|
let len = device_reader.read(&mut buf)?;
|
||||||
if let Err(e) = handle(&mut buf, len, &igmp_server, ¤t_device, &device_writer, &sender, &ip_route, &ip_proxy_map).await {
|
if let Err(e) = handle(&mut buf, len, &igmp_server, ¤t_device, &device_writer, &sender, &ip_route, &ip_proxy_map, &cipher).await {
|
||||||
log::error!("tap handle{:?}",e);
|
log::error!("tap handle{:?}",e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle(buf: &mut [u8], len: usize, igmp_server: &IgmpServer, current_device: &AtomicCell<CurrentDeviceInfo>,
|
async fn handle(buf: &mut [u8], len: usize, igmp_server: &IgmpServer, current_device: &AtomicCell<CurrentDeviceInfo>,
|
||||||
device_writer: &DeviceWriter, sender: &ChannelSender, ip_route: &ExternalRoute, proxy_map: &IpProxyMap) -> crate::Result<()> {
|
device_writer: &DeviceWriter, sender: &ChannelSender, ip_route: &ExternalRoute, proxy_map: &IpProxyMap, cipher: &Option<Aes256Gcm>) -> crate::Result<()> {
|
||||||
let mut ethernet_packet = EthernetPacket::new(&mut buf[..len])?;
|
let mut ethernet_packet = EthernetPacket::new(&mut buf[..len])?;
|
||||||
let current_device = current_device.load();
|
let current_device = current_device.load();
|
||||||
match ethernet_packet.protocol() {
|
match ethernet_packet.protocol() {
|
||||||
@@ -68,12 +71,12 @@ async fn handle(buf: &mut [u8], len: usize, igmp_server: &IgmpServer, current_de
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
//回复一个虚假的MAC地址
|
//回复一个虚假的MAC地址
|
||||||
out_arp_packet.set_sender_hardware_addr(&[target_p[0], target_p[1], target_p[2], target_p[3], 123, 234]);
|
out_arp_packet.set_sender_hardware_addr(&[target_p[0], target_p[1], target_p[2], target_p[3], !sender_h[5], 234]);
|
||||||
out_arp_packet.set_sender_protocol_addr(target_p);
|
out_arp_packet.set_sender_protocol_addr(target_p);
|
||||||
out_arp_packet.set_target_hardware_addr(sender_h);
|
out_arp_packet.set_target_hardware_addr(sender_h);
|
||||||
out_arp_packet.set_target_protocol_addr(sender_p);
|
out_arp_packet.set_target_protocol_addr(sender_p);
|
||||||
out_arp_packet.set_op_code(2);
|
out_arp_packet.set_op_code(2);
|
||||||
out_ethernet_packet.set_source(&[target_p[0], target_p[1], target_p[2], target_p[3], 123, 234]);
|
out_ethernet_packet.set_source(&[target_p[0], target_p[1], target_p[2], target_p[3], !sender_h[5], 234]);
|
||||||
out_ethernet_packet.set_destination(sender_h);
|
out_ethernet_packet.set_destination(sender_h);
|
||||||
device_writer.write_ethernet_tap(&out_ethernet_packet.buffer)?;
|
device_writer.write_ethernet_tap(&out_ethernet_packet.buffer)?;
|
||||||
}
|
}
|
||||||
@@ -105,7 +108,7 @@ async fn handle(buf: &mut [u8], len: usize, igmp_server: &IgmpServer, current_de
|
|||||||
}
|
}
|
||||||
// 以太网帧头部14字节,预留12字节
|
// 以太网帧头部14字节,预留12字节
|
||||||
return crate::handle::tun_tap::base_handle(sender, &mut buf[2..], len - 2, igmp_server, current_device,
|
return crate::handle::tun_tap::base_handle(sender, &mut buf[2..], len - 2, igmp_server, current_device,
|
||||||
ip_route, proxy_map).await;
|
ip_route, proxy_map, cipher).await;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// log::warn!("不支持的二层协议:{:?}",p)
|
// log::warn!("不支持的二层协议:{:?}",p)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use aes_gcm::Aes256Gcm;
|
||||||
|
|
||||||
use crossbeam::atomic::AtomicCell;
|
use crossbeam::atomic::AtomicCell;
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ fn icmp(device_writer: &DeviceWriter, mut ipv4_packet: IpV4Packet<&mut [u8]>) ->
|
|||||||
/// 接收tun数据,并且转发到udp上
|
/// 接收tun数据,并且转发到udp上
|
||||||
#[inline]
|
#[inline]
|
||||||
async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writer: &DeviceWriter, igmp_server: &IgmpServer, current_device: CurrentDeviceInfo,
|
async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writer: &DeviceWriter, igmp_server: &IgmpServer, current_device: CurrentDeviceInfo,
|
||||||
ip_route: &ExternalRoute, proxy_map: &IpProxyMap) -> Result<()> {
|
ip_route: &ExternalRoute, proxy_map: &IpProxyMap,cipher: &Option<Aes256Gcm>) -> Result<()> {
|
||||||
let ipv4_packet = if let Ok(ipv4_packet) = IpV4Packet::new(&mut data[12..len]) {
|
let ipv4_packet = if let Ok(ipv4_packet) = IpV4Packet::new(&mut data[12..len]) {
|
||||||
ipv4_packet
|
ipv4_packet
|
||||||
} else {
|
} else {
|
||||||
@@ -49,7 +50,7 @@ async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writ
|
|||||||
if src_ip == dest_ip {
|
if src_ip == dest_ip {
|
||||||
return icmp(&device_writer, ipv4_packet);
|
return icmp(&device_writer, ipv4_packet);
|
||||||
}
|
}
|
||||||
return crate::handle::tun_tap::base_handle(sender, data, len, igmp_server, current_device, ip_route, proxy_map).await;
|
return crate::handle::tun_tap::base_handle(sender, data, len, igmp_server, current_device, ip_route, proxy_map,cipher).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(sender: ChannelSender,
|
pub fn start(sender: ChannelSender,
|
||||||
@@ -58,12 +59,13 @@ pub fn start(sender: ChannelSender,
|
|||||||
igmp_server: IgmpServer,
|
igmp_server: IgmpServer,
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||||
ip_route: ExternalRoute,
|
ip_route: ExternalRoute,
|
||||||
ip_proxy_map: IpProxyMap) {
|
ip_proxy_map: IpProxyMap,
|
||||||
|
cipher: Option<Aes256Gcm>) {
|
||||||
thread::Builder::new().name("tun-handler".into()).spawn(move || {
|
thread::Builder::new().name("tun-handler".into()).spawn(move || {
|
||||||
tokio::runtime::Builder::new_current_thread()
|
tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all().build().unwrap()
|
.enable_all().build().unwrap()
|
||||||
.block_on(async move {
|
.block_on(async move {
|
||||||
if let Err(e) = start_(sender, device_reader, device_writer, igmp_server, current_device, ip_route, ip_proxy_map).await {
|
if let Err(e) = start_(sender, device_reader, device_writer, igmp_server, current_device, ip_route, ip_proxy_map,cipher).await {
|
||||||
log::warn!("tun:{:?}",e);
|
log::warn!("tun:{:?}",e);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -76,11 +78,12 @@ async fn start_(sender: ChannelSender,
|
|||||||
igmp_server: IgmpServer,
|
igmp_server: IgmpServer,
|
||||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||||
ip_route: ExternalRoute,
|
ip_route: ExternalRoute,
|
||||||
ip_proxy_map: IpProxyMap) -> io::Result<()> {
|
ip_proxy_map: IpProxyMap,
|
||||||
|
cipher: Option<Aes256Gcm>) -> io::Result<()> {
|
||||||
let mut buf = [0; 4096];
|
let mut buf = [0; 4096];
|
||||||
loop {
|
loop {
|
||||||
let len = device_reader.read(&mut buf[12..])? + 12;
|
let len = device_reader.read(&mut buf[12..])? + 12;
|
||||||
match handle(&sender, &mut buf, len, &device_writer, &igmp_server, current_device.load(), &ip_route, &ip_proxy_map).await {
|
match handle(&sender, &mut buf, len, &device_writer, &igmp_server, current_device.load(), &ip_route, &ip_proxy_map,&cipher).await {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("{:?}", e)
|
log::warn!("{:?}", e)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ impl IcmpProxy {
|
|||||||
let mut net_packet = NetPacket::new([0u8; 4 + 8 + 1500]).unwrap();
|
let mut net_packet = NetPacket::new([0u8; 4 + 8 + 1500]).unwrap();
|
||||||
net_packet.set_version(Version::V1);
|
net_packet.set_version(Version::V1);
|
||||||
net_packet.set_protocol(Protocol::IpTurn);
|
net_packet.set_protocol(Protocol::IpTurn);
|
||||||
net_packet.set_transport_protocol(ipv4::protocol::Protocol::Ipv4.into());
|
net_packet.set_transport_protocol(ipv4::protocol::Protocol::Icmp.into());
|
||||||
net_packet.set_ttl(MAX_TTL);
|
net_packet.set_ttl(MAX_TTL);
|
||||||
loop {
|
loop {
|
||||||
match self.recv(data) {
|
match self.recv(data) {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ use std::net::Ipv4Addr;
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
pub enum Protocol {
|
pub enum Protocol {
|
||||||
|
Icmp,
|
||||||
|
Igmp,
|
||||||
Ipv4,
|
Ipv4,
|
||||||
Ipv4Broadcast,
|
Ipv4Broadcast,
|
||||||
Unknown(u8),
|
Unknown(u8),
|
||||||
@@ -11,6 +13,8 @@ pub enum Protocol {
|
|||||||
impl From<u8> for Protocol {
|
impl From<u8> for Protocol {
|
||||||
fn from(value: u8) -> Self {
|
fn from(value: u8) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
1 => Protocol::Icmp,
|
||||||
|
2 => Protocol::Igmp,
|
||||||
4 => Protocol::Ipv4,
|
4 => Protocol::Ipv4,
|
||||||
201 => Protocol::Ipv4Broadcast,
|
201 => Protocol::Ipv4Broadcast,
|
||||||
val => Protocol::Unknown(val),
|
val => Protocol::Unknown(val),
|
||||||
@@ -21,6 +25,8 @@ impl From<u8> for Protocol {
|
|||||||
impl Into<u8> for Protocol {
|
impl Into<u8> for Protocol {
|
||||||
fn into(self) -> u8 {
|
fn into(self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
|
Protocol::Icmp => 1,
|
||||||
|
Protocol::Igmp => 2,
|
||||||
Protocol::Ipv4 => 4,
|
Protocol::Ipv4 => 4,
|
||||||
Protocol::Ipv4Broadcast => 201,
|
Protocol::Ipv4Broadcast => 201,
|
||||||
Protocol::Unknown(val) => val,
|
Protocol::Unknown(val) => val,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::{fmt, io};
|
|||||||
0 15 31
|
0 15 31
|
||||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| 版本(8) | 协议(8) | 上层协议(8) | 初始ttl(4) | 生存时间(4) |
|
| p|unused| 版本(4) | 协议(8) | 上层协议(8) | 初始ttl(4) | 生存时间(4) |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| 源ip地址(32) |
|
| 源ip地址(32) |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
@@ -115,8 +115,11 @@ impl<B: AsRef<[u8]>> NetPacket<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<B: AsRef<[u8]>> NetPacket<B> {
|
impl<B: AsRef<[u8]>> NetPacket<B> {
|
||||||
|
pub fn is_encrypt(&self) -> bool {
|
||||||
|
self.buffer.as_ref()[0] & 0x80 == 0x80
|
||||||
|
}
|
||||||
pub fn version(&self) -> Version {
|
pub fn version(&self) -> Version {
|
||||||
Version::from(self.buffer.as_ref()[0])
|
Version::from(self.buffer.as_ref()[0] & 0x0F)
|
||||||
}
|
}
|
||||||
pub fn protocol(&self) -> Protocol {
|
pub fn protocol(&self) -> Protocol {
|
||||||
Protocol::from(self.buffer.as_ref()[1])
|
Protocol::from(self.buffer.as_ref()[1])
|
||||||
@@ -144,11 +147,19 @@ impl<B: AsRef<[u8]>> NetPacket<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> NetPacket<B> {
|
impl<B: AsRef<[u8]> + AsMut<[u8]>> NetPacket<B> {
|
||||||
pub fn buffer_mut(&mut self)->&mut [u8]{
|
pub fn buffer_mut(&mut self) -> &mut [u8] {
|
||||||
self.buffer.as_mut()
|
self.buffer.as_mut()
|
||||||
}
|
}
|
||||||
|
pub fn set_encrypt_flag(&mut self, is_encrypt: bool) {
|
||||||
|
if is_encrypt {
|
||||||
|
self.buffer.as_mut()[0] = self.buffer.as_ref()[0] | 0x80
|
||||||
|
} else {
|
||||||
|
self.buffer.as_mut()[0] = self.buffer.as_ref()[0] & 0x7F
|
||||||
|
};
|
||||||
|
}
|
||||||
pub fn set_version(&mut self, version: Version) {
|
pub fn set_version(&mut self, version: Version) {
|
||||||
self.buffer.as_mut()[0] = version.into();
|
let v: u8 = version.into();
|
||||||
|
self.buffer.as_mut()[0] = (self.buffer.as_ref()[0] & 0xF0) | (0x0F & v);
|
||||||
}
|
}
|
||||||
pub fn set_protocol(&mut self, protocol: Protocol) {
|
pub fn set_protocol(&mut self, protocol: Protocol) {
|
||||||
self.buffer.as_mut()[1] = protocol.into();
|
self.buffer.as_mut()[1] = protocol.into();
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ impl DeviceWriter {
|
|||||||
Self::write(self.packet_information, writer, &buf[14..])
|
Self::write(self.packet_information, writer, &buf[14..])
|
||||||
}
|
}
|
||||||
DeviceW::Tap((writer, mac)) => {
|
DeviceW::Tap((writer, mac)) => {
|
||||||
let source_mac = [buf[14 + 12], buf[14 + 13], buf[14 + 14], buf[14 + 15], 123, 234];
|
let source_mac = [buf[14 + 12], buf[14 + 13], buf[14 + 14], buf[14 + 15], !mac[5], 234];
|
||||||
let mut ethernet_packet = EthernetPacket::unchecked(buf);
|
let mut ethernet_packet = EthernetPacket::unchecked(buf);
|
||||||
ethernet_packet.set_source(&source_mac);
|
ethernet_packet.set_source(&source_mac);
|
||||||
ethernet_packet.set_destination(mac);
|
ethernet_packet.set_destination(mac);
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ impl DeviceWriter {
|
|||||||
dev.send_packet(packet);
|
dev.send_packet(packet);
|
||||||
}
|
}
|
||||||
Device::Tap((dev, mac)) => {
|
Device::Tap((dev, mac)) => {
|
||||||
let source_mac = [buf[14 + 12], buf[14 + 13], buf[14 + 14], buf[14 + 15], 123, 234];
|
let source_mac = [buf[14 + 12], buf[14 + 13], buf[14 + 14], buf[14 + 15], !mac[5], 234];
|
||||||
let mut ethernet_packet = EthernetPacket::unchecked(buf);
|
let mut ethernet_packet = EthernetPacket::unchecked(buf);
|
||||||
ethernet_packet.set_source(&source_mac);
|
ethernet_packet.set_source(&source_mac);
|
||||||
ethernet_packet.set_destination(mac);
|
ethernet_packet.set_destination(mac);
|
||||||
@@ -128,7 +128,9 @@ impl DeviceWriter {
|
|||||||
dev.add_route(address, netmask, gateway, 1)?;
|
dev.add_route(address, netmask, gateway, 1)?;
|
||||||
// 广播和组播路由
|
// 广播和组播路由
|
||||||
dev.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?;
|
dev.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?;
|
||||||
dev.add_route(Ipv4Addr::from([224, 0, 0, 0]), Ipv4Addr::from([240, 0, 0, 0]), gateway, 1)
|
dev.add_route(Ipv4Addr::from([224, 0, 0, 0]), Ipv4Addr::from([240, 0, 0, 0]), gateway, 1)?;
|
||||||
|
delete_cache();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn ip(&self) -> Ipv4Addr {
|
pub fn ip(&self) -> Ipv4Addr {
|
||||||
self.ip.load()
|
self.ip.load()
|
||||||
@@ -252,6 +254,7 @@ fn create_tun(
|
|||||||
// 广播和组播路由
|
// 广播和组播路由
|
||||||
tun_device.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?;
|
tun_device.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?;
|
||||||
tun_device.add_route(Ipv4Addr::from([224, 0, 0, 0]), Ipv4Addr::from([240, 0, 0, 0]), gateway, 1)?;
|
tun_device.add_route(Ipv4Addr::from([224, 0, 0, 0]), Ipv4Addr::from([240, 0, 0, 0]), gateway, 1)?;
|
||||||
|
delete_cache();
|
||||||
let device = Arc::new(Device::Tun(tun_device));
|
let device = Arc::new(Device::Tun(tun_device));
|
||||||
println!("========TUN网卡配置========");
|
println!("========TUN网卡配置========");
|
||||||
Ok((
|
Ok((
|
||||||
@@ -260,6 +263,18 @@ fn create_tun(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn delete_cache(){
|
||||||
|
//清除路由缓存
|
||||||
|
let delete_cache = "netsh interface ip delete destinationcache";
|
||||||
|
let out = std::process::Command::new("cmd")
|
||||||
|
.arg("/C")
|
||||||
|
.arg(delete_cache)
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
if !out.status.success(){
|
||||||
|
log::warn!("删除缓存失败:{:?}",out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn delete_tun() {
|
fn delete_tun() {
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -304,6 +319,7 @@ fn create_tap(
|
|||||||
// 广播和组播路由
|
// 广播和组播路由
|
||||||
tap_device.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?;
|
tap_device.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?;
|
||||||
tap_device.add_route(Ipv4Addr::from([224, 0, 0, 0]), Ipv4Addr::from([240, 0, 0, 0]), gateway, 1)?;
|
tap_device.add_route(Ipv4Addr::from([224, 0, 0, 0]), Ipv4Addr::from([240, 0, 0, 0]), gateway, 1)?;
|
||||||
|
delete_cache();
|
||||||
let tap = Arc::new(Device::Tap((tap_device, mac)));
|
let tap = Arc::new(Device::Tap((tap_device, mac)));
|
||||||
println!("========TAP网卡配置========");
|
println!("========TAP网卡配置========");
|
||||||
Ok((
|
Ok((
|
||||||
|
|||||||
Reference in New Issue
Block a user