Compare commits

...
18 Commits
Author SHA1 Message Date
lbl8603 f90ef96a5d 增加sys-locale 2024-07-20 11:12:45 +08:00
lbl8603 81c6c8c1fc Merge branch 'refs/heads/1.2.x' into 1.2.x-2024-07-20-1
# Conflicts:
#	common/src/cli.rs
2024-07-20 11:10:15 +08:00
lbl8603 7ebdffcdd3 支持wg 2024-07-20 10:38:18 +08:00
lbl8603 1abe33cb16 Merge pull request #61 from jslyrd/main
添加英文帮助信息
2024-07-16 23:11:44 +08:00
jslyrd 965cbfbb7e 添加英文帮助信息 2024-07-16 22:32:48 +08:00
lbl8603 14ee9c4632 Merge branch 'refs/heads/1.2.x' into 1.2.x-2024-07-04 2024-07-13 12:11:24 +08:00
lbl8603 ddfa89167d 修改地址探测和转发路径 2024-07-13 12:09:15 +08:00
lbl8603 1f9ed7b314 修改features 2024-07-13 12:01:41 +08:00
lbl8603 dc45602661 Merge pull request #58 from lbl8603/1.2.x
调整添加转发路径的逻辑
2024-07-10 23:09:49 +08:00
lbl8603 27c0f389ee 调整添加转发路径的逻辑 2024-07-10 22:54:13 +08:00
lbl8603 59d6bfd957 Merge pull request #56 from lbl8603/1.2.x
1.2.x
2024-07-07 23:29:16 +08:00
lbl8603 31b8661b7d 设置证书 2024-07-07 22:38:01 +08:00
lbl8603 e36e45054c Merge pull request #49 from lbl8603/1.2.x
1.2.x
2024-06-01 17:00:51 +08:00
lbl8603 39170b74ca Merge pull request #43 from lbl8603/1.2.x
调整条件编译
2024-05-15 20:32:05 +08:00
lbl8603 0e3f06429b Merge pull request #42 from lbl8603/1.2.x
处理unix去掉所有模块的编译问题
2024-05-14 09:25:52 +08:00
lbl8603 ee7c597bd8 Merge pull request #41 from lbl8603/1.2.x
1.2.x
2024-05-13 22:53:51 +08:00
lbl8603 7f500d72c7 Merge pull request #39 from lbl8603/1.2.x
支持--no-default-features编译
2024-05-11 13:31:04 +08:00
lbl8603 4dca4c4f22 Merge pull request #38 from lbl8603/1.2.x
1.2.x
2024-05-11 09:21:57 +08:00
29 changed files with 538 additions and 224 deletions
Generated
+22 -2
View File
@@ -319,6 +319,7 @@ dependencies = [
"rand", "rand",
"serde", "serde",
"serde_yaml", "serde_yaml",
"sys-locale",
"uuid", "uuid",
"vnt", "vnt",
] ]
@@ -1536,9 +1537,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls-native-certs" name = "rustls-native-certs"
version = "0.7.0" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba"
dependencies = [ dependencies = [
"openssl-probe", "openssl-probe",
"rustls-pemfile", "rustls-pemfile",
@@ -1834,6 +1835,15 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sys-locale"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.10.1" version = "3.10.1"
@@ -1946,6 +1956,7 @@ dependencies = [
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"tungstenite", "tungstenite",
"webpki-roots",
] ]
[[package]] [[package]]
@@ -2237,6 +2248,15 @@ version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "webpki-roots"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd"
dependencies = [
"rustls-pki-types",
]
[[package]] [[package]]
name = "which" name = "which"
version = "4.4.2" version = "4.4.2"
+1
View File
@@ -16,6 +16,7 @@ serde_yaml = "0.9.32"
getopts = "0.2.21" getopts = "0.2.21"
gethostname = "0.4.3" gethostname = "0.4.3"
uuid = { version = "1.8.0", features = ["v4"] } uuid = { version = "1.8.0", features = ["v4"] }
sys-locale = "0.3.1"
[features] [features]
default = [] default = []
+183 -46
View File
@@ -5,10 +5,12 @@ use crate::{config, generated_serial_number};
use anyhow::anyhow; use anyhow::anyhow;
use console::style; use console::style;
use getopts::Options; use getopts::Options;
use std::collections::HashMap;
use std::io; use std::io;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use sys_locale::get_locale;
use vnt::channel::punch::PunchModel; use vnt::channel::punch::PunchModel;
use vnt::channel::UseChannelType; use vnt::channel::UseChannelType;
use vnt::cipher::CipherModel; use vnt::cipher::CipherModel;
@@ -75,6 +77,7 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
opts.optopt("f", "", "配置文件", "<conf>"); opts.optopt("f", "", "配置文件", "<conf>");
opts.optopt("", "compressor", "压缩算法", "<lz4>"); opts.optopt("", "compressor", "压缩算法", "<lz4>");
opts.optflag("", "disable-stats", "关闭流量统计"); opts.optflag("", "disable-stats", "关闭流量统计");
opts.optflag("", "allow-wg", "允许接入WireGuard");
//"后台运行时,查看其他设备列表" //"后台运行时,查看其他设备列表"
opts.optflag("", "add", "后台运行时,添加地址"); opts.optflag("", "add", "后台运行时,添加地址");
opts.optflag("", "list", "后台运行时,查看其他设备列表"); opts.optflag("", "list", "后台运行时,查看其他设备列表");
@@ -113,10 +116,13 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
} else if matches.opt_present("all") { } else if matches.opt_present("all") {
command::command(command::CommandEnum::All); command::command(command::CommandEnum::All);
return Ok(None); return Ok(None);
} else if matches.opt_present("chart_a") { }
#[cfg(feature = "command")]
if matches.opt_present("chart_a") {
command::command(command::CommandEnum::ChartA); command::command(command::CommandEnum::ChartA);
return Ok(None); return Ok(None);
} }
#[cfg(feature = "command")]
if let Some(v) = matches.opt_str("chart_b") { if let Some(v) = matches.opt_str("chart_b") {
command::command(command::CommandEnum::ChartB(v)); command::command(command::CommandEnum::ChartB(v));
return Ok(None); return Ok(None);
@@ -278,6 +284,7 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
let port_mapping_list = matches.opt_strs("mapping"); let port_mapping_list = matches.opt_strs("mapping");
let vnt_mapping_list = matches.opt_strs("vnt-mapping"); let vnt_mapping_list = matches.opt_strs("vnt-mapping");
let disable_stats = matches.opt_present("disable-stats"); let disable_stats = matches.opt_present("disable-stats");
let allow_wire_guard = matches.opt_present("allow-wg");
let compressor = if let Some(compressor) = matches.opt_str("compressor").as_ref() { let compressor = if let Some(compressor) = matches.opt_str("compressor").as_ref() {
Compressor::from_str(compressor) Compressor::from_str(compressor)
.map_err(|e| anyhow!("{}", e)) .map_err(|e| anyhow!("{}", e))
@@ -318,6 +325,7 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
port_mapping_list, port_mapping_list,
compressor, compressor,
!disable_stats, !disable_stats,
allow_wire_guard,
) { ) {
Ok(config) => config, Ok(config) => config,
Err(e) => { Err(e) => {
@@ -337,38 +345,122 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
Ok(Some((config, vnt_link_config, cmd))) Ok(Some((config, vnt_link_config, cmd)))
} }
fn get_description(key: &str, language: &str) -> String {
// 设置一个全局的映射来存储中英文对照
let descriptions: HashMap<&str, (&str, &str)> = [
("-k <token>", ("使用相同的token,就能组建一个局域网络", "Use the same token to form a local network")),
("-n <name>", ("给设备一个名字,便于区分不同设备,默认使用系统版本", "Give the device a name to distinguish it, defaults to system version")),
("-d <id>", ("设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复", "Device unique identifier, used by the server to allocate virtual IP when --ip parameter is not used, must be unique")),
("-s <server>", ("注册和中继服务器地址,协议支持使用tcp://和ws://和wss://,默认为udp://", "Registration and relay server address, protocols support using tcp://, ws://, and wss://, default is udp://")),
("-e <stun-server>", ("stun服务器,用于探测NAT类型,可使用多个地址,如-e stun.miwifi.com -e turn.cloudflare.com", "STUN server for detecting NAT type, can specify multiple addresses, e.g., -e stun.miwifi.com -e turn.cloudflare.com")),
("-a", ("使用tap模式,默认使用tun模式,使用tap时需要配合'--nic'参数指定tap网卡", "Use tap mode, default is tun mode, specify '--nic' parameter with tap network card")),
("-i <in-ip>", ("配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据并转发到10.26.0.3,可指定多个网段", "Used when configuring point-to-point network (IP proxy), -i 192.168.0.0/24,10.26.0.3 allows receiving data from subnet 192.168.0.0/24 and forwarding to 10.26.0.3, specify multiple subnets")),
("-o <out-ip>", ("配置点对网时使用,-o 192.168.0.0/24表示允许将数据转发到192.168.0.0/24,可指定多个网段", "Used when configuring point-to-point network, -o 192.168.0.0/24 allows forwarding data to 192.168.0.0/24, specify multiple subnets")),
("-w <password>", ("使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信", "Encrypt client data with keys generated by this password, server cannot decrypt, clients must use the same password to communicate")),
("-W", ("加密当前客户端和服务端通信的数据,请留意服务端指纹是否正确", "Encrypt the data currently being communicated between the client and server, please pay attention to whether the server fingerprint is correct")),
("-u <mtu>", ("自定义mtu(不加密默认为1450,加密默认为1410", "Customize MTU (1450 by default without encryption, 1410 with encryption)")),
("-f <conf_file>", ("读取配置文件中的配置", "Read configuration from file")),
("--ip <ip>", ("指定虚拟ip,指定的ip不能和其他设备重复,必须有效并且在服务端所属网段下,默认情况由服务端分配", "Specify virtual IP, must be unique and valid within server subnet, by default allocated by server")),
("--model <model>", ("加密模式(默认aes_gcm),可选值{}", "Encryption mode (default aes_gcm), options {}")),
("--finger", ("增加数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启", "Add data fingerprint verification for increased security, client must enable if server does")),
("--punch <punch>", ("取值ipv4/ipv6/all,ipv4表示仅使用ipv4打洞", "Values ipv4/ipv6/all, ipv4 for IPv4 hole punching only")),
("--ports <port,port>", ("取值0~65535,指定本地监听的一组端口,默认监听两个随机端口,使用过多端口会增加网络负担", "Values 0~65535, specify a group of local listening ports, defaults to two random ports, using many ports increases network load")),
("--cmd", ("开启交互式命令,使用此参数开启控制台输入", "Enable interactive command mode, use this parameter to enable console input")),
("--no-proxy", ("关闭内置代理,如需点对网则需要配置网卡NAT转发", "Disable built-in proxy, configure network card NAT forwarding for point-to-point networking")),
("--first-latency", ("优先低延迟的通道,默认情况优先使用p2p通道", "Prioritize low-latency channels, defaults to prioritizing p2p channel")),
("--use-channel <p2p>", ("使用通道 relay/p2p/all,默认两者都使用", "Use channel relay/p2p/all, defaults to using both")),
("--nic <tun0>", ("指定虚拟网卡名称", "Specify virtual network card name")),
("--packet-loss <0>", ("模拟丢包,取值0~1之间的小数,程序会按设定的概率主动丢包,可用于模拟弱网", "Simulate packet loss, value between 0 and 1, program actively drops packets based on set probability, useful for simulating weak networks")),
("--packet-delay <0>", ("模拟丢包,取值0~1之间的小数,程序会按设定的概率主动丢包,可用于模拟弱网", "Simulate latency, integer, in milliseconds (ms). The program will delay sending packets according to the set value and can be used to simulate weak networks")),
("--dns <host:port>", ("DNS服务器地址,可使用多个dns,不指定时使用系统解析", "DNS server address, can specify multiple DNS servers, defaults to system resolution if not specified")),
("--mapping <mapping>", ("端口映射,例如 --mapping udp:0.0.0.0:80-domain:80 映射目标是本地路由能访问的设备", "Port mapping, e.g., --mapping udp:0.0.0.0:80-domain:80 maps to a device accessible by local routing")),
("--compressor-all <lz4>", ("启用压缩,可选值lz4/zstd<,level>,level为压缩级别,例如 --compressor lz4 或--compressor zstd,10", "Enable compression, options lz4/zstd<,level>, level is compression level, e.g., --compressor lz4 or --compressor zstd,10")),
("--compressor-lz4 <lz4>", ("启用压缩,可选值lz4,例如 --compressor lz4", "Enable compression, option lz4, e.g., --compressor lz4")),
("--compressor-zstd <zstd>", ("启用压缩,可选值zstd<,level>,level为压缩级别,例如 --compressor zstd,10", "Enable compression, options zstd<,level>, level is compression level, e.g., --compressor zstd,10")),
("--vnt-mapping <x>", ("vnt地址映射,例如 --vnt-mapping tcp:80-10.26.0.10:80 映射目标是vnt网络或其子网中的设备", "VNT address mapping, e.g., --vnt-mapping tcp:80-10.26.0.10:80 maps to a device in VNT network or its subnet")),
("--disable-stats", ("关闭流量统计", "Disable traffic statistics")),
("--list", ("后台运行时,查看其他设备列表", "View list of other devices when running in background")),
("--all", ("后台运行时,查看其他设备完整信息", "View complete information of other devices when running in background")),
("--info", ("后台运行时,查看当前设备信息", "View information of current device when running in background")),
("--route", ("后台运行时,查看数据转发路径", "View data forwarding path when running in background")),
("--chart_a", ("后台运行时,查看所有IP的流量统计", "View traffic statistics of all IPs when running in background")),
("--chart_b <IP>", ("后台运行时,查看单个IP的历史流量", "View historical traffic of a single IP when running in background")),
("--stop", ("停止后台运行", "Stop running in background"))
// ... 其他选项
]
.iter()
.cloned()
.collect();
if let Some(&(zh, en)) = descriptions.get(key) {
if language.starts_with("zh") {
return zh.to_string(); // 返回 String 类型
}
// 默认返回英文
return en.to_string(); // 返回 String 类型
}
// 如果没有找到对应的键,则返回空字符串
String::new()
}
fn print_usage(program: &str, _opts: Options) { fn print_usage(program: &str, _opts: Options) {
// 获取系统语言 Locale::user_default().unwrap_or_else(|_| Locale::default());
let language = get_locale().unwrap_or_else(|| String::from("en-US"));
println!("Usage: {} [options]", program); println!("Usage: {} [options]", program);
println!("version:{}", vnt::VNT_VERSION); println!("version:{}", vnt::VNT_VERSION);
println!("Serial:{}", generated_serial_number::SERIAL_NUMBER); println!("Serial:{}", generated_serial_number::SERIAL_NUMBER);
println!("Options:"); println!("Options:");
println!( println!(
" -k <token> {}", " -k <token> {}",
green("使用相同的token,就能组建一个局域网络".to_string()) green(get_description("-k <token>", &language).to_string())
); );
println!(" -n <name> 给设备一个名字,便于区分不同设备,默认使用系统版本");
println!(" -d <id> 设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复");
println!( println!(
" -s <server> 注册和中继服务器地址,协议支持使用tcp://和ws://和wss://,默认为udp://" " -n <name> {}",
get_description("-n <name>", &language)
);
println!(
" -d <id> {}",
get_description("-d <id>", &language)
);
println!(
" -s <server> {}",
get_description("-s <server>", &language)
);
println!(
" -e <stun-server> {}",
get_description("-e <stun-server>", &language)
); );
println!(" -e <stun-server> stun服务器,用于探测NAT类型,可使用多个地址,如-e stun.miwifi.com -e turn.cloudflare.com");
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
#[cfg(feature = "integrated_tun")] #[cfg(feature = "integrated_tun")]
println!(" -a {}", get_description("-a", &language));
println!( println!(
" -a 使用tap模式,默认使用tun模式,使用tap时需要配合'--nic'参数指定tap网卡" " -i <in-ip> {}",
get_description("-i <in-ip>", &language)
);
println!(
" -o <out-ip> {}",
get_description("-o <out-ip>", &language)
);
println!(
" -w <password> {}",
get_description("-w <password>", &language)
); );
println!(" -i <in-ip> 配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据");
println!(" 并转发到10.26.0.3,可指定多个网段");
println!(" -o <out-ip> 配置点对网时使用,-o 192.168.0.0/24表示允许将数据转发到192.168.0.0/24,可指定多个网段");
println!(" -w <password> 使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信");
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
println!(" -W 加密当前客户端和服务端通信的数据,请留意服务端指纹是否正确"); println!(" -W {}", get_description("-W", &language));
println!(" -u <mtu> 自定义mtu(不加密默认为1450,加密默认为1410)"); println!(
" -u <mtu> {}",
get_description("-u <mtu>", &language)
);
#[cfg(feature = "file_config")] #[cfg(feature = "file_config")]
println!(" -f <conf_file> 读取配置文件中的配置"); println!(
" -f <conf_file> {}",
get_description("-f <conf_file>", &language)
);
println!(" --ip <ip> 指定虚拟ip,指定的ip不能和其他设备重复,必须有效并且在服务端所属网段下,默认情况由服务端分配"); println!(
" --ip <ip> {}",
get_description("--ip <ip>", &language)
);
let mut enums = String::new(); let mut enums = String::new();
#[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))] #[cfg(any(feature = "aes_gcm", feature = "server_encrypt"))]
enums.push_str("/aes_gcm"); enums.push_str("/aes_gcm");
@@ -382,7 +474,8 @@ fn print_usage(program: &str, _opts: Options) {
enums.push_str("/sm4_cbc"); enums.push_str("/sm4_cbc");
enums.push_str("/xor"); enums.push_str("/xor");
println!( println!(
" --model <model> 加密模式(默认aes_gcm),可选值{}", " --model <model> {}{}",
get_description("--model <model>", &language),
&enums[1..] &enums[1..]
); );
#[cfg(any( #[cfg(any(
@@ -393,45 +486,89 @@ fn print_usage(program: &str, _opts: Options) {
feature = "aes_ecb", feature = "aes_ecb",
feature = "sm4_cbc" feature = "sm4_cbc"
))] ))]
println!(" --finger 增加数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启"); println!(
println!(" --punch <punch> 取值ipv4/ipv6/all,ipv4表示仅使用ipv4打洞"); " --finger {}",
println!(" --ports <port,port> 取值0~65535,指定本地监听的一组端口,默认监听两个随机端口,使用过多端口会增加网络负担"); get_description("--finger", &language)
);
println!(
" --punch <punch> {}",
get_description("--punch <punch>", &language)
);
println!(
" --ports <port,port> {}",
get_description("--ports <port,port>", &language)
);
#[cfg(feature = "command")] #[cfg(feature = "command")]
println!(" --cmd 开启交互式命令,使用此参数开启控制台输入"); println!(
" --cmd {}",
get_description("--cmd", &language)
);
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
#[cfg(feature = "integrated_tun")] #[cfg(feature = "integrated_tun")]
println!(" --no-proxy 关闭内置代理,如需点对网则需要配置网卡NAT转发");
println!(" --first-latency 优先低延迟的通道,默认情况优先使用p2p通道");
println!(" --use-channel <p2p> 使用通道 relay/p2p/all,默认两者都使用");
#[cfg(not(feature = "vn-link-model"))]
println!(" --nic <tun0> 指定虚拟网卡名称");
println!(" --packet-loss <0> 模拟丢包,取值0~1之间的小数,程序会按设定的概率主动丢包,可用于模拟弱网");
println!( println!(
" --packet-delay <0> 模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网" " --no-proxy {}",
get_description("--no-proxy", &language)
);
println!(
" --first-latency {}",
get_description("--first-latency", &language)
);
println!(
" --use-channel <p2p> {}",
get_description("--use-channel <p2p>", &language)
);
#[cfg(not(feature = "vn-link-model"))]
println!(
" --nic <tun0> {}",
get_description("--nic <tun0>", &language)
);
println!(
" --packet-loss <0> {}",
get_description("--packet-loss <0>", &language)
);
println!(
" --packet-delay <0> {}",
get_description("--packet-delay <0>", &language)
);
println!(
" --dns <host:port> {}",
get_description("--dns <host:port>", &language)
); );
println!(" --dns <host:port> DNS服务器地址,可使用多个dns,不指定时使用系统解析");
#[cfg(feature = "port_mapping")] #[cfg(feature = "port_mapping")]
println!(" --mapping <mapping> 端口映射,例如 --mapping udp:0.0.0.0:80-domain:80 映射目标是本地路由能访问的设备"); println!(
" --mapping <mapping> {}",
get_description("--mapping <mapping>", &language)
);
#[cfg(all(feature = "lz4", feature = "zstd"))] #[cfg(all(feature = "lz4", feature = "zstd"))]
println!(" --compressor <lz4> 启用压缩,可选值lz4/zstd<,level>,level为压缩级别,例如 --compressor lz4 或--compressor zstd,10"); println!(
" --compressor <lz4> {}",
get_description("--compressor-all <lz4>", &language)
);
#[cfg(feature = "lz4")] #[cfg(feature = "lz4")]
#[cfg(not(feature = "zstd"))] #[cfg(not(feature = "zstd"))]
println!(" --compressor <lz4> 启用压缩,可选值lz4,例如 --compressor lz4"); println!(
" --compressor <lz4> {}",
get_description("--compressor-lz4 <lz4>", &language)
);
#[cfg(feature = "zstd")] #[cfg(feature = "zstd")]
#[cfg(not(feature = "lz4"))] #[cfg(not(feature = "lz4"))]
println!(" --compressor <zstd> 启用压缩,可选值zstd<,level>,level为压缩级别,例如 --compressor zstd,10"); println!(
" --compressor <zstd> {}",
get_description("--compressor-zstd <zstd>", &language)
);
#[cfg(not(feature = "integrated_tun"))] #[cfg(not(feature = "integrated_tun"))]
println!( println!(
" --vnt-mapping <x> {}", " --vnt-mapping <x> {}",
green( green(get_description("--vnt-mapping <x>", &language).to_string())
"vnt地址映射,例如 --vnt-mapping tcp:80-10.26.0.10:80 映射目标是vnt网络或其子网中的设备"
.to_string()
)
); );
println!(" --disable-stats 关闭流量统计"); println!(
" --disable-stats {}",
get_description("--disable-stats", &language)
);
println!(" --allow-wg 允许接入WireGuard客户端");
println!(); println!();
#[cfg(feature = "command")] #[cfg(feature = "command")]
{ {
@@ -442,34 +579,34 @@ fn print_usage(program: &str, _opts: Options) {
// ); // );
println!( println!(
" --list {}", " --list {}",
yellow("后台运行时,查看其他设备列表".to_string()) yellow(get_description("--list", &language).to_string())
); );
println!( println!(
" --all {}", " --all {}",
yellow("后台运行时,查看其他设备完整信息".to_string()) yellow(get_description("--all", &language).to_string())
); );
println!( println!(
" --info {}", " --info {}",
yellow("后台运行时,查看当前设备信息".to_string()) yellow(get_description("--info", &language).to_string())
); );
println!( println!(
" --route {}", " --route {}",
yellow("后台运行时,查看数据转发路径".to_string()) yellow(get_description("--route", &language).to_string())
); );
println!( println!(
" --chart_a {}", " --chart_a {}",
yellow("后台运行时,查看所有IP的流量统计".to_string()) yellow(get_description("--chart_a", &language).to_string())
); );
println!( println!(
" --chart_b <IP> {}", " --chart_b <IP> {}",
yellow("后台运行时,查看单个IP的历史流量".to_string()) yellow(get_description("--chart_b <IP>", &language).to_string())
); );
println!( println!(
" --stop {}", " --stop {}",
yellow("停止后台运行".to_string()) yellow(get_description("--stop", &language).to_string())
); );
} }
println!(" -h, --help 帮助"); println!(" -h, --help display help information(显示帮助信息)");
} }
fn green(str: String) -> impl std::fmt::Display { fn green(str: String) -> impl std::fmt::Display {
+1
View File
@@ -45,6 +45,7 @@ pub struct DeviceItem {
pub client_secret_hash: Vec<u8>, pub client_secret_hash: Vec<u8>,
pub current_client_secret: bool, pub current_client_secret: bool,
pub current_client_secret_hash: Vec<u8>, pub current_client_secret_hash: Vec<u8>,
pub wire_guard: bool,
} }
#[derive(Serialize, Deserialize, Debug, Default)] #[derive(Serialize, Deserialize, Debug, Default)]
+1
View File
@@ -219,6 +219,7 @@ pub fn command_list(vnt: &Vnt) -> Vec<DeviceItem> {
client_secret_hash: peer.client_secret_hash, client_secret_hash: peer.client_secret_hash,
current_client_secret, current_client_secret,
current_client_secret_hash: client_encrypt_hash.to_vec(), current_client_secret_hash: client_encrypt_hash.to_vec(),
wire_guard: peer.wireguard,
}; };
list.push(item); list.push(item);
} }
+4
View File
@@ -46,6 +46,8 @@ pub struct FileConfig {
pub compressor: Option<String>, pub compressor: Option<String>,
pub vnt_mapping: Vec<String>, pub vnt_mapping: Vec<String>,
pub disable_stats: bool, pub disable_stats: bool,
// 允许传递wg流量
pub allow_wire_guard: bool,
} }
impl Default for FileConfig { impl Default for FileConfig {
@@ -90,6 +92,7 @@ impl Default for FileConfig {
compressor: None, compressor: None,
vnt_mapping: vec![], vnt_mapping: vec![],
disable_stats: false, disable_stats: false,
allow_wire_guard: false,
} }
} }
} }
@@ -177,6 +180,7 @@ pub fn read_config(file_path: &str) -> anyhow::Result<(Config, Vec<String>, bool
file_conf.mapping, file_conf.mapping,
compressor, compressor,
!file_conf.disable_stats, !file_conf.disable_stats,
file_conf.allow_wire_guard,
)?; )?;
Ok((config, file_conf.vnt_mapping, file_conf.cmd)) Ok((config, file_conf.vnt_mapping, file_conf.cmd))
+14 -8
View File
@@ -132,15 +132,21 @@ pub fn console_device_list(mut list: Vec<DeviceItem>) {
("Rt".to_string(), Style::new()), ("Rt".to_string(), Style::new()),
]); ]);
for item in list { for item in list {
let name = if item.wire_guard {
format!("{}(wg)", item.name)
} else {
item.name
};
if &item.status == "Online" { if &item.status == "Online" {
if item.client_secret != item.current_client_secret if !item.wire_guard
|| (!item.current_client_secret_hash.is_empty() && (item.client_secret != item.current_client_secret
&& !item.client_secret_hash.is_empty() || (!item.current_client_secret_hash.is_empty()
&& item.current_client_secret_hash != item.client_secret_hash) && !item.client_secret_hash.is_empty()
&& item.current_client_secret_hash != item.client_secret_hash))
{ {
//加密状态不一致,无法通信的 //加密状态不一致,无法通信的
out_list.push(vec![ out_list.push(vec![
(item.name, Style::new().red()), (name, Style::new().red()),
(item.virtual_ip, Style::new().red()), (item.virtual_ip, Style::new().red()),
(item.status, Style::new().red()), (item.status, Style::new().red()),
("Mismatch".to_string(), Style::new().red()), ("Mismatch".to_string(), Style::new().red()),
@@ -149,7 +155,7 @@ pub fn console_device_list(mut list: Vec<DeviceItem>) {
} else { } else {
if item.nat_traversal_type.contains("p2p") { if item.nat_traversal_type.contains("p2p") {
out_list.push(vec![ out_list.push(vec![
(item.name, Style::new().green()), (name, Style::new().green()),
(item.virtual_ip, Style::new().green()), (item.virtual_ip, Style::new().green()),
(item.status, Style::new().green()), (item.status, Style::new().green()),
(item.nat_traversal_type, Style::new().green()), (item.nat_traversal_type, Style::new().green()),
@@ -157,7 +163,7 @@ pub fn console_device_list(mut list: Vec<DeviceItem>) {
]); ]);
} else { } else {
out_list.push(vec![ out_list.push(vec![
(item.name, Style::new().yellow()), (name, Style::new().yellow()),
(item.virtual_ip, Style::new().yellow()), (item.virtual_ip, Style::new().yellow()),
(item.status, Style::new().yellow()), (item.status, Style::new().yellow()),
(item.nat_traversal_type, Style::new().yellow()), (item.nat_traversal_type, Style::new().yellow()),
@@ -167,7 +173,7 @@ pub fn console_device_list(mut list: Vec<DeviceItem>) {
} }
} else { } else {
out_list.push(vec![ out_list.push(vec![
(item.name, Style::new().color256(102)), (name, Style::new().color256(102)),
(item.virtual_ip, Style::new().color256(102)), (item.virtual_ip, Style::new().color256(102)),
(item.status, Style::new().color256(102)), (item.status, Style::new().color256(102)),
("".to_string(), Style::new().color256(102)), ("".to_string(), Style::new().color256(102)),
+1 -1
View File
@@ -11,7 +11,7 @@ log = "0.4.17"
[features] [features]
default = ["default-feature"] default = ["default-feature"]
default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "port_mapping", "log", "command", "file_config", "lz4"] default-feature = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "port_mapping", "log", "command", "file_config", "lz4", "ws"]
openssl = ["vn-link/openssl", "common/openssl"] openssl = ["vn-link/openssl", "common/openssl"]
openssl-vendored = ["vn-link/openssl-vendored", "common/openssl-vendored"] openssl-vendored = ["vn-link/openssl-vendored", "common/openssl-vendored"]
+1 -1
View File
@@ -75,4 +75,4 @@ zstd_compress = ["zstd"]
integrated_tun = ["tun"] integrated_tun = ["tun"]
upnp = ["igd"] upnp = ["igd"]
ws = ["tokio-tungstenite"] ws = ["tokio-tungstenite"]
wss = ["ws", "tokio-tungstenite/rustls-tls-native-roots", "rustls"] wss = ["ws", "tokio-tungstenite/rustls-tls-native-roots", "tokio-tungstenite/rustls-tls-webpki-roots", "rustls"]
+1
View File
@@ -43,6 +43,7 @@ message DeviceInfo {
uint32 device_status = 3; uint32 device_status = 3;
bool client_secret = 4; bool client_secret = 4;
bytes client_secret_hash = 5; bytes client_secret_hash = 5;
bool wireguard = 6;
} }
message DeviceList { message DeviceList {
+21 -9
View File
@@ -353,18 +353,18 @@ impl RouteTable {
} }
Err(io::Error::new(io::ErrorKind::NotFound, "route not found")) Err(io::Error::new(io::ErrorKind::NotFound, "route not found"))
} }
pub fn add_route_if_absent(&self, id: Ipv4Addr, route: Route) { pub fn add_route_if_absent(&self, id: Ipv4Addr, route: Route) -> bool {
self.add_route_(id, route, true) self.add_route_(id, route, true)
} }
pub fn add_route(&self, id: Ipv4Addr, route: Route) { pub fn add_route(&self, id: Ipv4Addr, route: Route) -> bool {
self.add_route_(id, route, false) self.add_route_(id, route, false)
} }
fn add_route_(&self, id: Ipv4Addr, route: Route, only_if_absent: bool) { fn add_route_(&self, id: Ipv4Addr, route: Route, only_if_absent: bool) -> bool {
// 限制通道类型 // 限制通道类型
match self.use_channel_type { match self.use_channel_type {
UseChannelType::P2p => { UseChannelType::P2p => {
if !route.is_p2p() { if !route.is_p2p() {
return; return false;
} }
} }
_ => {} _ => {}
@@ -372,10 +372,18 @@ impl RouteTable {
let key = route.route_key(); let key = route.route_key();
if only_if_absent { if only_if_absent {
if let Some((_, list)) = self.route_table.read().get(&id) { if let Some((_, list)) = self.route_table.read().get(&id) {
let mut p2p_num = 0;
for (x, _) in list { for (x, _) in list {
if x.route_key() == key { if x.is_p2p() {
return; p2p_num += 1;
} }
if x.route_key() == key {
return true;
}
}
if !self.first_latency && p2p_num >= self.channel_num {
// 非优先延迟的情况下,通道满了则不用再添加
return false;
} }
} }
} }
@@ -387,11 +395,11 @@ impl RouteTable {
for (x, time) in list.iter_mut() { for (x, time) in list.iter_mut() {
if x.metric < route.metric && !self.first_latency { if x.metric < route.metric && !self.first_latency {
//非优先延迟的情况下 不能比当前的路径更长 //非优先延迟的情况下 不能比当前的路径更长
return; return false;
} }
if x.route_key() == key { if x.route_key() == key {
if only_if_absent { if only_if_absent {
return; return true;
} }
x.metric = route.metric; x.metric = route.metric;
x.rt = route.rt; x.rt = route.rt;
@@ -406,7 +414,7 @@ impl RouteTable {
//如果延迟都稳定了,则去除多余通道 //如果延迟都稳定了,则去除多余通道
for (route, _) in list.iter() { for (route, _) in list.iter() {
if route.rt == DEFAULT_RT { if route.rt == DEFAULT_RT {
return; return true;
} }
} }
//延迟优先模式需要更多的通道探测延迟最低的路线 //延迟优先模式需要更多的通道探测延迟最低的路线
@@ -422,6 +430,9 @@ impl RouteTable {
//非优先延迟的情况下 添加了直连的则排除非直连的 //非优先延迟的情况下 添加了直连的则排除非直连的
list.retain(|(k, _)| k.is_p2p()); list.retain(|(k, _)| k.is_p2p());
} }
if self.channel_num <= list.len() {
return false;
}
}; };
//增加路由表容量,避免波动 //增加路由表容量,避免波动
let limit_len = self.channel_num * 2; let limit_len = self.channel_num * 2;
@@ -429,6 +440,7 @@ impl RouteTable {
self.truncate_(list, limit_len); self.truncate_(list, limit_len);
list.push((route, AtomicCell::new(Instant::now()))); list.push((route, AtomicCell::new(Instant::now())));
} }
return true;
} }
fn truncate_(&self, list: &mut Vec<(Route, AtomicCell<Instant>)>, len: usize) { fn truncate_(&self, list: &mut Vec<(Route, AtomicCell<Instant>)>, len: usize) {
if list.len() <= len { if list.len() <= len {
+2 -3
View File
@@ -264,9 +264,8 @@ impl Punch {
if let Some(ipv4_addr) = nat_info.local_tcp_ipv4addr() { if let Some(ipv4_addr) = nat_info.local_tcp_ipv4addr() {
self.connect_tcp(buf, ipv4_addr) self.connect_tcp(buf, ipv4_addr)
} }
if nat_info.nat_type == NatType::Cone && nat_info.public_ips.len() == 1 { for ip in &nat_info.public_ips {
let addr = let addr = SocketAddr::V4(SocketAddrV4::new(*ip, nat_info.tcp_port));
SocketAddr::V4(SocketAddrV4::new(nat_info.public_ips[0], nat_info.tcp_port));
self.connect_tcp(buf, addr) self.connect_tcp(buf, addr)
} }
} }
+85 -5
View File
@@ -1,9 +1,11 @@
use std::collections::HashMap;
use std::io; use std::io;
use std::net::{Ipv4Addr, SocketAddr}; use std::net::{Ipv4Addr, SocketAddr};
use std::sync::mpsc::{SyncSender, TrySendError}; use std::sync::mpsc::{SyncSender, TrySendError};
use std::sync::Arc; use std::sync::Arc;
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::Sender;
use crate::channel::context::ChannelContext; use crate::channel::context::ChannelContext;
@@ -11,7 +13,7 @@ use crate::channel::notify::AcceptNotify;
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::compression::Compressor; use crate::compression::Compressor;
use crate::external_route::ExternalRoute; use crate::external_route::ExternalRoute;
use crate::handle::CurrentDeviceInfo; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::protocol; use crate::protocol;
use crate::protocol::{ip_turn_packet, NetPacket}; use crate::protocol::{ip_turn_packet, NetPacket};
@@ -21,7 +23,10 @@ pub struct IpPacketSender {
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
compressor: Compressor, compressor: Compressor,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher,
ip_route: ExternalRoute, ip_route: ExternalRoute,
device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
allow_wire_guard: bool,
} }
impl IpPacketSender { impl IpPacketSender {
@@ -30,14 +35,20 @@ impl IpPacketSender {
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
compressor: Compressor, compressor: Compressor,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher,
ip_route: ExternalRoute, ip_route: ExternalRoute,
device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
allow_wire_guard: bool,
) -> Self { ) -> Self {
Self { Self {
context, context,
current_device, current_device,
compressor, compressor,
client_cipher, client_cipher,
server_cipher,
ip_route, ip_route,
device_map,
allow_wire_guard,
} }
} }
pub fn self_virtual_ip(&self) -> Ipv4Addr { pub fn self_virtual_ip(&self) -> Ipv4Addr {
@@ -58,19 +69,54 @@ impl IpPacketSender {
if let Some(v) = self.ip_route.route(&dest_ip) { if let Some(v) = self.ip_route.route(&dest_ip) {
dest_ip = v; dest_ip = v;
} }
if dest_ip.is_multicast() || dest_ip.is_broadcast() || dest_ip == device_info.broadcast_ip { if dest_ip.is_multicast() {
//广播 //广播
dest_ip = Ipv4Addr::BROADCAST; dest_ip = Ipv4Addr::BROADCAST;
} }
let mut net_packet = NetPacket::new0(data_len, buf)?; let mut net_packet = NetPacket::new0(data_len, buf)?;
let mut auxiliary = NetPacket::new(auxiliary_buf)?;
net_packet.set_default_version(); net_packet.set_default_version();
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.set_transport_protocol(ip_turn_packet::Protocol::Ipv4.into());
net_packet.first_set_ttl(6); net_packet.first_set_ttl(6);
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 self.allow_wire_guard {
if dest_ip.is_broadcast() || dest_ip == device_info.broadcast_ip {
let exists_wg = self
.device_map
.lock()
.1
.values()
.any(|v| v.status.is_online() && v.wireguard);
if exists_wg {
send_to_wg_broadcast(
&self.context,
&net_packet,
&self.server_cipher,
&device_info,
)?;
}
} else {
let guard = self.device_map.lock();
if let Some(peer_info) = guard.1.get(&dest_ip) {
if peer_info.wireguard {
if peer_info.status.is_offline() {
return Ok(());
}
drop(guard);
send_to_wg(
&self.context,
&mut net_packet,
&self.server_cipher,
&device_info,
)?;
return Ok(());
}
}
}
}
let mut auxiliary = NetPacket::new(auxiliary_buf)?;
let mut net_packet = if self.compressor.compress(&net_packet, &mut auxiliary)? { let mut net_packet = if self.compressor.compress(&net_packet, &mut auxiliary)? {
auxiliary.set_default_version(); auxiliary.set_default_version();
@@ -84,7 +130,7 @@ impl IpPacketSender {
net_packet net_packet
}; };
self.client_cipher.encrypt_ipv4(&mut net_packet)?; self.client_cipher.encrypt_ipv4(&mut net_packet)?;
if dest_ip.is_broadcast() { if dest_ip.is_broadcast() || dest_ip == device_info.broadcast_ip {
//走服务端广播 //走服务端广播
self.context self.context
.send_default(&net_packet, device_info.connect_server)?; .send_default(&net_packet, device_info.connect_server)?;
@@ -105,6 +151,40 @@ impl IpPacketSender {
} }
} }
pub fn send_to_wg_broadcast(
sender: &ChannelContext,
net_packet: &NetPacket<&mut [u8]>,
server_cipher: &Cipher,
current_device: &CurrentDeviceInfo,
) -> anyhow::Result<()> {
let mut copy_packet = NetPacket::new0(net_packet.data_len(), [0; 65536])?;
copy_packet.set_default_version();
copy_packet.set_protocol(protocol::Protocol::IpTurn);
copy_packet.set_transport_protocol(ip_turn_packet::Protocol::WGIpv4.into());
copy_packet.first_set_ttl(6);
copy_packet.set_source(net_packet.source());
copy_packet.set_destination(net_packet.destination());
copy_packet.set_gateway_flag(true);
copy_packet.set_payload(net_packet.payload())?;
server_cipher.encrypt_ipv4(&mut copy_packet)?;
sender.send_default(&copy_packet, current_device.connect_server)?;
Ok(())
}
pub fn send_to_wg(
sender: &ChannelContext,
net_packet: &mut NetPacket<&mut [u8]>,
server_cipher: &Cipher,
current_device: &CurrentDeviceInfo,
) -> anyhow::Result<()> {
net_packet.set_transport_protocol(ip_turn_packet::Protocol::WGIpv4.into());
net_packet.set_gateway_flag(true);
server_cipher.encrypt_ipv4(net_packet)?;
sender.send_default(&net_packet, current_device.connect_server)?;
Ok(())
}
pub struct AcceptSocketSender<T> { pub struct AcceptSocketSender<T> {
sender: SyncSender<T>, sender: SyncSender<T>,
notify: AcceptNotify, notify: AcceptNotify,
+21 -15
View File
@@ -66,12 +66,13 @@ pub struct VntInner {
config: Config, config: Config,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
nat_test: NatTest, nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
context: Arc<Mutex<Option<ChannelContext>>>, context: Arc<Mutex<Option<ChannelContext>>>,
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>, peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
client_secret_hash: Option<[u8; 16]>, client_secret_hash: Option<[u8; 16]>,
compressor: Compressor, compressor: Compressor,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher,
external_route: ExternalRoute, external_route: ExternalRoute,
up_traffic_meter: Option<TrafficMeterMultiAddress>, up_traffic_meter: Option<TrafficMeterMultiAddress>,
down_traffic_meter: Option<TrafficMeterMultiAddress>, down_traffic_meter: Option<TrafficMeterMultiAddress>,
@@ -128,8 +129,8 @@ impl VntInner {
config.server_address, config.server_address,
))); )));
//设备列表 //设备列表
let device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>> = let device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>> =
Arc::new(Mutex::new((0, Vec::with_capacity(16)))); Arc::new(Mutex::new((0, HashMap::with_capacity(16))));
//基础信息 //基础信息
let config_info = BaseConfigInfo::new( let config_info = BaseConfigInfo::new(
config.name.clone(), config.name.clone(),
@@ -147,6 +148,7 @@ impl VntInner {
#[cfg(feature = "integrated_tun")] #[cfg(feature = "integrated_tun")]
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
config.device_name.clone(), config.device_name.clone(),
config.allow_wire_guard,
); );
// 服务停止管理器 // 服务停止管理器
let stop_manager = { let stop_manager = {
@@ -228,7 +230,7 @@ impl VntInner {
proxy_map.clone(), proxy_map.clone(),
client_cipher.clone(), client_cipher.clone(),
server_cipher.clone(), server_cipher.clone(),
device_list.clone(), device_map.clone(),
config.compressor, config.compressor,
device.clone().into_device_adapter(), device.clone().into_device_adapter(),
) )
@@ -241,7 +243,7 @@ impl VntInner {
client_cipher.clone(), client_cipher.clone(),
current_device.clone(), current_device.clone(),
device, device,
device_list.clone(), device_map.clone(),
config_info.clone(), config_info.clone(),
nat_test.clone(), nat_test.clone(),
callback.clone(), callback.clone(),
@@ -287,7 +289,7 @@ impl VntInner {
{ {
let context = context.clone(); let context = context.clone();
let nat_test = nat_test.clone(); let nat_test = nat_test.clone();
let device_list = device_list.clone(); let device_map = device_map.clone();
let config_info = config_info.clone(); let config_info = config_info.clone();
let current_device = current_device.clone(); let current_device = current_device.clone();
if !config.use_channel_type.is_only_relay() { if !config.use_channel_type.is_only_relay() {
@@ -300,13 +302,14 @@ impl VntInner {
); );
} }
let client_cipher = client_cipher.clone(); let client_cipher = client_cipher.clone();
let server_cipher = server_cipher.clone();
//延迟启动 //延迟启动
scheduler.timeout(Duration::from_secs(3), move |scheduler| { scheduler.timeout(Duration::from_secs(3), move |scheduler| {
start( start(
scheduler, scheduler,
context, context,
nat_test, nat_test,
device_list, device_map,
current_device, current_device,
client_cipher, client_cipher,
server_cipher, server_cipher,
@@ -323,12 +326,13 @@ impl VntInner {
config, config,
current_device, current_device,
nat_test, nat_test,
device_list, device_map,
context: Arc::new(Mutex::new(Some(context))), context: Arc::new(Mutex::new(Some(context))),
peer_nat_info_map, peer_nat_info_map,
client_secret_hash: config_info.client_secret_hash, client_secret_hash: config_info.client_secret_hash,
compressor, compressor,
client_cipher, client_cipher,
server_cipher,
external_route, external_route,
up_traffic_meter, up_traffic_meter,
down_traffic_meter, down_traffic_meter,
@@ -340,7 +344,7 @@ pub fn start<Call: VntCallback>(
scheduler: &Scheduler, scheduler: &Scheduler,
context: ChannelContext, context: ChannelContext,
nat_test: NatTest, nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
@@ -354,7 +358,7 @@ pub fn start<Call: VntCallback>(
&scheduler, &scheduler,
context.clone(), context.clone(),
current_device.clone(), current_device.clone(),
device_list.clone(), device_map.clone(),
client_cipher.clone(), client_cipher.clone(),
server_cipher.clone(), server_cipher.clone(),
); );
@@ -374,7 +378,7 @@ pub fn start<Call: VntCallback>(
&scheduler, &scheduler,
context.clone(), context.clone(),
current_device.clone(), current_device.clone(),
device_list.clone(), device_map.clone(),
client_cipher.clone(), client_cipher.clone(),
); );
} }
@@ -385,7 +389,6 @@ pub fn start<Call: VntCallback>(
&scheduler, &scheduler,
context.clone(), context.clone(),
current_device.clone(), current_device.clone(),
server_cipher.clone(),
nat_test.clone(), nat_test.clone(),
config_info.clone(), config_info.clone(),
); );
@@ -394,7 +397,7 @@ pub fn start<Call: VntCallback>(
&scheduler, &scheduler,
context.clone(), context.clone(),
nat_test.clone(), nat_test.clone(),
device_list.clone(), device_map.clone(),
current_device.clone(), current_device.clone(),
client_cipher.clone(), client_cipher.clone(),
punch_receiver, punch_receiver,
@@ -433,10 +436,10 @@ impl VntInner {
self.nat_test.nat_info() self.nat_test.nat_info()
} }
pub fn device_list(&self) -> Vec<PeerDeviceInfo> { pub fn device_list(&self) -> Vec<PeerDeviceInfo> {
let device_list_lock = self.device_list.lock(); let device_list_lock = self.device_map.lock();
let (_epoch, device_list) = device_list_lock.clone(); let (_epoch, device_list) = device_list_lock.clone();
drop(device_list_lock); drop(device_list_lock);
device_list device_list.into_values().collect()
} }
pub fn route(&self, ip: &Ipv4Addr) -> Option<Route> { pub fn route(&self, ip: &Ipv4Addr) -> Option<Route> {
self.context.lock().as_ref()?.route_table.route_one(ip) self.context.lock().as_ref()?.route_table.route_one(ip)
@@ -508,7 +511,10 @@ impl VntInner {
self.current_device.clone(), self.current_device.clone(),
self.compressor.clone(), self.compressor.clone(),
self.client_cipher.clone(), self.client_cipher.clone(),
self.server_cipher.clone(),
self.external_route.clone(), self.external_route.clone(),
self.device_map.clone(),
self.config.allow_wire_guard,
)) ))
} else { } else {
None None
+4
View File
@@ -51,6 +51,7 @@ pub struct Config {
pub port_mapping_list: Vec<(bool, SocketAddr, String)>, pub port_mapping_list: Vec<(bool, SocketAddr, String)>,
pub compressor: Compressor, pub compressor: Compressor,
pub enable_traffic: bool, pub enable_traffic: bool,
pub allow_wire_guard: bool,
} }
impl Config { impl Config {
@@ -88,6 +89,8 @@ impl Config {
#[cfg(feature = "port_mapping")] port_mapping_list: Vec<String>, #[cfg(feature = "port_mapping")] port_mapping_list: Vec<String>,
compressor: Compressor, compressor: Compressor,
enable_traffic: bool, enable_traffic: bool,
// 允许传递wg流量
allow_wire_guard: bool,
) -> anyhow::Result<Self> { ) -> anyhow::Result<Self> {
for x in stun_server.iter_mut() { for x in stun_server.iter_mut() {
if !x.contains(":") { if !x.contains(":") {
@@ -180,6 +183,7 @@ impl Config {
port_mapping_list, port_mapping_list,
compressor, compressor,
enable_traffic, enable_traffic,
allow_wire_guard,
}) })
} }
} }
+6 -49
View File
@@ -5,48 +5,30 @@ use crossbeam_utils::atomic::AtomicCell;
use crate::channel::context::ChannelContext; use crate::channel::context::ChannelContext;
use crate::channel::punch::NatType; use crate::channel::punch::NatType;
use crate::cipher::Cipher;
use crate::handle::{BaseConfigInfo, CurrentDeviceInfo}; use crate::handle::{BaseConfigInfo, CurrentDeviceInfo};
use crate::nat::NatTest; use crate::nat::NatTest;
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::{control_packet, NetPacket, Protocol, MAX_TTL};
use crate::util::Scheduler; use crate::util::Scheduler;
pub fn addr_request( pub fn addr_request(
scheduler: &Scheduler, scheduler: &Scheduler,
context: ChannelContext, context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>, current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
server_cipher: Cipher,
nat_test: NatTest, nat_test: NatTest,
_config: BaseConfigInfo, _config: BaseConfigInfo,
) { ) {
pub_address_request( pub_address_request(scheduler, context, current_device_info.clone(), nat_test, 0);
scheduler,
context,
current_device_info.clone(),
server_cipher,
nat_test,
0,
);
} }
fn pub_address_request( fn pub_address_request(
scheduler: &Scheduler, scheduler: &Scheduler,
context: ChannelContext, context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>, current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
server_cipher: Cipher,
nat_test: NatTest, nat_test: NatTest,
count: usize, count: usize,
) { ) {
let channel_num = context.channel_num(); let channel_num = context.channel_num();
let index = count % channel_num; let index = count % channel_num;
if let Err(e) = addr_request0( if let Err(e) = addr_request0(&context, &current_device_info, &nat_test, index) {
&context,
&current_device_info,
&server_cipher,
&nat_test,
index,
) {
log::warn!("{:?}", e); log::warn!("{:?}", e);
} }
let nat_info = nat_test.nat_info(); let nat_info = nat_test.nat_info();
@@ -58,7 +40,7 @@ fn pub_address_request(
if index == channel_num - 1 { if index == channel_num - 1 {
19 19
} else { } else {
7 9
} }
} }
} else { } else {
@@ -66,14 +48,7 @@ fn pub_address_request(
}; };
let rs = scheduler.timeout(Duration::from_secs(time), move |s| { let rs = scheduler.timeout(Duration::from_secs(time), move |s| {
pub_address_request( pub_address_request(s, context, current_device_info, nat_test, index + 1)
s,
context,
current_device_info,
server_cipher,
nat_test,
index + 1,
)
}); });
if !rs { if !rs {
log::info!("定时任务停止"); log::info!("定时任务停止");
@@ -83,7 +58,6 @@ fn pub_address_request(
fn addr_request0( fn addr_request0(
context: &ChannelContext, context: &ChannelContext,
current_device: &AtomicCell<CurrentDeviceInfo>, current_device: &AtomicCell<CurrentDeviceInfo>,
server_cipher: &Cipher,
nat_test: &NatTest, nat_test: &NatTest,
index: usize, index: usize,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
@@ -91,24 +65,7 @@ fn addr_request0(
if current_dev.status.offline() { if current_dev.status.offline() {
return Ok(()); return Ok(());
} }
let (data, addr) = nat_test.send_data()?;
if current_dev.connect_server.is_ipv4() && !context.main_protocol().is_base_tcp() { context.send_main_udp(index, &data, addr)?;
// 如果连接的是ipv4服务,则探测公网端口
let gateway_ip = current_dev.virtual_gateway;
let src_ip = current_dev.virtual_ip;
let mut packet = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED]).unwrap();
packet.set_default_version();
packet.set_gateway_flag(true);
packet.set_protocol(Protocol::Control);
packet.set_transport_protocol(control_packet::Protocol::AddrRequest.into());
packet.first_set_ttl(MAX_TTL);
packet.set_source(src_ip);
packet.set_destination(gateway_ip);
server_cipher.encrypt_ipv4(&mut packet)?;
context.send_main_udp(index, packet.buffer(), current_dev.connect_server)?;
} else {
let (data, addr) = nat_test.send_data()?;
context.send_main_udp(index, &data, addr)?;
}
Ok(()) Ok(())
} }
+24 -20
View File
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
@@ -19,14 +20,14 @@ pub fn heartbeat(
scheduler: &Scheduler, scheduler: &Scheduler,
context: ChannelContext, context: ChannelContext,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>, current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
) { ) {
heartbeat0( heartbeat0(
&context, &context,
&current_device_info.load(), &current_device_info.load(),
&device_list, &device_map,
&client_cipher, &client_cipher,
&server_cipher, &server_cipher,
); );
@@ -36,7 +37,7 @@ pub fn heartbeat(
s, s,
context, context,
current_device_info, current_device_info,
device_list, device_map,
client_cipher, client_cipher,
server_cipher, server_cipher,
) )
@@ -49,7 +50,7 @@ pub fn heartbeat(
fn heartbeat0( fn heartbeat0(
context: &ChannelContext, context: &ChannelContext,
current_device: &CurrentDeviceInfo, current_device: &CurrentDeviceInfo,
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>, device_map: &Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>,
client_cipher: &Cipher, client_cipher: &Cipher,
server_cipher: &Cipher, server_cipher: &Cipher,
) { ) {
@@ -57,7 +58,7 @@ fn heartbeat0(
let src_ip = current_device.virtual_ip; let src_ip = current_device.virtual_ip;
// 可能服务器ip发生变化,导致发送失败 // 可能服务器ip发生变化,导致发送失败
let mut is_send_gateway = false; let mut is_send_gateway = false;
match heartbeat_packet_server(device_list, server_cipher, src_ip, gateway_ip) { match heartbeat_packet_server(device_map, server_cipher, src_ip, gateway_ip) {
Ok(net_packet) => { Ok(net_packet) => {
if let Err(e) = context.send_default(&net_packet, current_device.connect_server) { if let Err(e) = context.send_default(&net_packet, current_device.connect_server) {
log::warn!("heartbeat err={:?}", e) log::warn!("heartbeat err={:?}", e)
@@ -75,7 +76,7 @@ fn heartbeat0(
if is_send_gateway { if is_send_gateway {
continue; continue;
} }
heartbeat_packet_server(device_list, server_cipher, src_ip, gateway_ip) heartbeat_packet_server(device_map, server_cipher, src_ip, gateway_ip)
} else { } else {
heartbeat_packet_client(client_cipher, src_ip, dest_ip) heartbeat_packet_client(client_cipher, src_ip, dest_ip)
}; };
@@ -92,9 +93,9 @@ fn heartbeat0(
} }
} }
} }
let peer_list = { device_list.lock().1.clone() }; let peer_list = { device_map.lock().1.clone() };
for peer in &peer_list { for peer in peer_list.values() {
if !peer.status.is_online() { if !peer.status.is_online() || peer.wireguard {
continue; continue;
} }
if current_device.is_gateway(&peer.virtual_ip) { if current_device.is_gateway(&peer.virtual_ip) {
@@ -124,11 +125,11 @@ pub fn client_relay(
scheduler: &Scheduler, scheduler: &Scheduler,
context: ChannelContext, context: ChannelContext,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
client_cipher: Cipher, client_cipher: Cipher,
) { ) {
let rs = scheduler.timeout(Duration::from_secs(30), move |s| { let rs = scheduler.timeout(Duration::from_secs(30), move |s| {
client_relay_(s, context, current_device, device_list, client_cipher) client_relay_(s, context, current_device, device_map, client_cipher)
}); });
if !rs { if !rs {
log::info!("定时任务停止"); log::info!("定时任务停止");
@@ -140,19 +141,19 @@ fn client_relay_(
scheduler: &Scheduler, scheduler: &Scheduler,
context: ChannelContext, context: ChannelContext,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
client_cipher: Cipher, client_cipher: Cipher,
) { ) {
if let Err(e) = client_relay0( if let Err(e) = client_relay0(
&context, &context,
&current_device.load(), &current_device.load(),
&device_list, &device_map,
&client_cipher, &client_cipher,
) { ) {
log::error!("{:?}", e); log::error!("{:?}", e);
} }
let rs = scheduler.timeout(Duration::from_secs(30), move |s| { let rs = scheduler.timeout(Duration::from_secs(30), move |s| {
client_relay_(s, context, current_device, device_list, client_cipher) client_relay_(s, context, current_device, device_map, client_cipher)
}); });
if !rs { if !rs {
log::info!("定时任务停止"); log::info!("定时任务停止");
@@ -162,17 +163,20 @@ fn client_relay_(
fn client_relay0( fn client_relay0(
context: &ChannelContext, context: &ChannelContext,
current_device: &CurrentDeviceInfo, current_device: &CurrentDeviceInfo,
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>, device_map: &Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>,
client_cipher: &Cipher, client_cipher: &Cipher,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
// 离线了不再探测 // 离线了不再探测
if current_device.status.offline() { if current_device.status.offline() {
return Ok(()); return Ok(());
} }
let peer_list = { device_list.lock().1.clone() }; let peer_list = { device_map.lock().1.clone() };
let mut routes = context.route_table.route_table_p2p(); let mut routes = context.route_table.route_table_p2p();
for peer in &peer_list { for peer in peer_list.values() {
if !peer.status.is_online() || peer.virtual_ip == current_device.virtual_ip { if peer.wireguard
|| !peer.status.is_online()
|| peer.virtual_ip == current_device.virtual_ip
{
continue; continue;
} }
if context if context
@@ -232,14 +236,14 @@ fn heartbeat_packet_client(
} }
fn heartbeat_packet_server( fn heartbeat_packet_server(
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>, device_map: &Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>,
server_cipher: &Cipher, server_cipher: &Cipher,
src: Ipv4Addr, src: Ipv4Addr,
dest: Ipv4Addr, dest: Ipv4Addr,
) -> anyhow::Result<NetPacket<[u8; 12 + 4 + ENCRYPTION_RESERVED]>> { ) -> anyhow::Result<NetPacket<[u8; 12 + 4 + ENCRYPTION_RESERVED]>> {
let mut net_packet = heartbeat_packet(src, dest)?; let mut net_packet = heartbeat_packet(src, dest)?;
let mut ping = PingPacket::new(net_packet.payload_mut())?; let mut ping = PingPacket::new(net_packet.payload_mut())?;
ping.set_epoch(device_list.lock().0); ping.set_epoch(device_map.lock().0);
net_packet.set_gateway_flag(true); net_packet.set_gateway_flag(true);
server_cipher.encrypt_ipv4(&mut net_packet)?; server_cipher.encrypt_ipv4(&mut net_packet)?;
Ok(net_packet) Ok(net_packet)
+10 -10
View File
@@ -90,7 +90,7 @@ pub fn punch(
scheduler: &Scheduler, scheduler: &Scheduler,
context: ChannelContext, context: ChannelContext,
nat_test: NatTest, nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher, client_cipher: Cipher,
receiver: PunchReceiver, receiver: PunchReceiver,
@@ -102,7 +102,7 @@ pub fn punch(
scheduler, scheduler,
context, context,
nat_test, nat_test,
device_list, device_map,
current_device.clone(), current_device.clone(),
client_cipher.clone(), client_cipher.clone(),
0, 0,
@@ -170,7 +170,7 @@ fn punch_request(
scheduler: &Scheduler, scheduler: &Scheduler,
context: ChannelContext, context: ChannelContext,
nat_test: NatTest, nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher, client_cipher: Cipher,
count: usize, count: usize,
@@ -182,7 +182,7 @@ fn punch_request(
if let Err(e) = punch0( if let Err(e) = punch0(
&context, &context,
&nat_test, &nat_test,
&device_list, &device_map,
curr, curr,
&client_cipher, &client_cipher,
&punch_record, &punch_record,
@@ -201,7 +201,7 @@ fn punch_request(
s, s,
context, context,
nat_test, nat_test,
device_list, device_map,
current_device, current_device,
client_cipher, client_cipher,
count + 1, count + 1,
@@ -218,7 +218,7 @@ fn punch_request(
fn punch0( fn punch0(
context: &ChannelContext, context: &ChannelContext,
nat_test: &NatTest, nat_test: &NatTest,
device_list: &Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: &Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
current_device: CurrentDeviceInfo, current_device: CurrentDeviceInfo,
client_cipher: &Cipher, client_cipher: &Cipher,
punch_record: &Mutex<HashMap<Ipv4Addr, usize>>, punch_record: &Mutex<HashMap<Ipv4Addr, usize>>,
@@ -233,15 +233,15 @@ fn punch0(
|| nat_info.public_ports.iter().filter(|&&v| v == 0).count() || nat_info.public_ports.iter().filter(|&&v| v == 0).count()
> nat_info.public_ports.len() / 2) > nat_info.public_ports.len() / 2)
{ {
log::info!("公网地址为空,暂时放弃打洞,第{}轮", total_count); log::info!("未获取到公网地址,暂时放弃打洞,第{}轮", total_count);
return Ok(()); return Ok(());
} }
let current_ip = current_device.virtual_ip; let current_ip = current_device.virtual_ip;
let mut list: Vec<PeerDeviceInfo> = device_list let mut list: Vec<PeerDeviceInfo> = device_map
.lock() .lock()
.1 .1
.iter() .values()
.filter(|info| info.status.is_online() && info.virtual_ip > current_ip) .filter(|info| !info.wireguard && info.status.is_online() && info.virtual_ip > current_ip)
.cloned() .cloned()
.collect(); .collect();
list.shuffle(&mut rand::thread_rng()); list.shuffle(&mut rand::thread_rng());
+1 -1
View File
@@ -44,7 +44,7 @@ fn retrieve_nat_type0(
}; };
#[cfg(feature = "upnp")] #[cfg(feature = "upnp")]
nat_test.reset_upnp(); nat_test.reset_upnp();
log::info!("刷新nat成功") log::info!("刷新nat结束")
} }
}) })
.expect("natTest"); .expect("natTest");
+9
View File
@@ -29,6 +29,7 @@ pub struct PeerDeviceInfo {
pub status: PeerDeviceStatus, pub status: PeerDeviceStatus,
pub client_secret: bool, pub client_secret: bool,
pub client_secret_hash: Vec<u8>, pub client_secret_hash: Vec<u8>,
pub wireguard: bool,
} }
impl PeerDeviceInfo { impl PeerDeviceInfo {
@@ -38,6 +39,7 @@ impl PeerDeviceInfo {
status: u8, status: u8,
client_secret: bool, client_secret: bool,
client_secret_hash: Vec<u8>, client_secret_hash: Vec<u8>,
wireguard: bool,
) -> Self { ) -> Self {
Self { Self {
virtual_ip, virtual_ip,
@@ -45,6 +47,7 @@ impl PeerDeviceInfo {
status: PeerDeviceStatus::from(status), status: PeerDeviceStatus::from(status),
client_secret, client_secret,
client_secret_hash, client_secret_hash,
wireguard,
} }
} }
} }
@@ -66,6 +69,7 @@ pub struct BaseConfigInfo {
#[cfg(feature = "integrated_tun")] #[cfg(feature = "integrated_tun")]
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
pub device_name: Option<String>, pub device_name: Option<String>,
pub allow_wire_guard: bool,
} }
impl BaseConfigInfo { impl BaseConfigInfo {
@@ -85,6 +89,7 @@ impl BaseConfigInfo {
#[cfg(feature = "integrated_tun")] #[cfg(feature = "integrated_tun")]
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
device_name: Option<String>, device_name: Option<String>,
allow_wire_guard: bool,
) -> Self { ) -> Self {
Self { Self {
name, name,
@@ -102,6 +107,7 @@ impl BaseConfigInfo {
#[cfg(feature = "integrated_tun")] #[cfg(feature = "integrated_tun")]
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
device_name, device_name,
allow_wire_guard,
} }
} }
} }
@@ -116,6 +122,9 @@ impl PeerDeviceStatus {
pub fn is_online(&self) -> bool { pub fn is_online(&self) -> bool {
self == &PeerDeviceStatus::Online self == &PeerDeviceStatus::Online
} }
pub fn is_offline(&self) -> bool {
self == &PeerDeviceStatus::Offline
}
} }
impl Into<u8> for PeerDeviceStatus { impl Into<u8> for PeerDeviceStatus {
+14 -7
View File
@@ -194,6 +194,9 @@ impl<Device: DeviceWrite> ClientPacketHandler<Device> {
} }
self.device.write(net_packet.payload())?; self.device.write(net_packet.payload())?;
} }
ip_turn_packet::Protocol::WGIpv4 => {
// WG客户端的数据不会直接发过来,不用处理
}
ip_turn_packet::Protocol::Ipv4Broadcast => { ip_turn_packet::Protocol::Ipv4Broadcast => {
//客户端不帮忙转发广播包,所以不会出现这种类型的数据 //客户端不帮忙转发广播包,所以不会出现这种类型的数据
} }
@@ -212,14 +215,18 @@ impl<Device: DeviceWrite> ClientPacketHandler<Device> {
let source = net_packet.source(); let source = net_packet.source();
match ControlPacket::new(net_packet.transport_protocol(), net_packet.payload())? { match ControlPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
ControlPacket::PingPacket(_) => { ControlPacket::PingPacket(_) => {
net_packet.set_transport_protocol(control_packet::Protocol::Pong.into());
net_packet.set_source(current_device.virtual_ip);
net_packet.set_destination(source);
net_packet.first_set_ttl(MAX_TTL);
self.client_cipher.encrypt_ipv4(&mut net_packet)?;
context.send_by_key(&net_packet, route_key)?;
let route = Route::from_default_rt(route_key, metric); let route = Route::from_default_rt(route_key, metric);
context.route_table.add_route_if_absent(source, route); if context.route_table.add_route_if_absent(source, route)
|| net_packet.source() < current_device.virtual_ip
{
//在路由表中,或者来源比自己小,就需要回复,注意不能调换顺序
net_packet.set_transport_protocol(control_packet::Protocol::Pong.into());
net_packet.set_source(current_device.virtual_ip);
net_packet.set_destination(source);
net_packet.first_set_ttl(MAX_TTL);
self.client_cipher.encrypt_ipv4(&mut net_packet)?;
context.send_by_key(&net_packet, route_key)?;
}
} }
ControlPacket::PongPacket(pong_packet) => { ControlPacket::PongPacket(pong_packet) => {
let current_time = crate::handle::now_time() as u16; let current_time = crate::handle::now_time() as u16;
+2 -2
View File
@@ -80,7 +80,7 @@ impl<Call: VntCallback, Device: DeviceWrite> RecvDataHandler<Call, Device> {
client_cipher: Cipher, client_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: Device, device: Device,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
config_info: BaseConfigInfo, config_info: BaseConfigInfo,
nat_test: NatTest, nat_test: NatTest,
callback: Call, callback: Call,
@@ -101,7 +101,7 @@ impl<Call: VntCallback, Device: DeviceWrite> RecvDataHandler<Call, Device> {
server_cipher, server_cipher,
current_device.clone(), current_device.clone(),
device.clone(), device.clone(),
device_list, device_map,
config_info, config_info,
nat_test.clone(), nat_test.clone(),
callback, callback,
+19 -8
View File
@@ -1,4 +1,5 @@
use anyhow::anyhow; use anyhow::anyhow;
use std::collections::HashMap;
use std::io; use std::io;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::sync::Arc; use std::sync::Arc;
@@ -42,7 +43,7 @@ pub struct ServerPacketHandler<Call, Device> {
server_cipher: Cipher, server_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: Device, device: Device,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
config_info: BaseConfigInfo, config_info: BaseConfigInfo,
nat_test: NatTest, nat_test: NatTest,
callback: Call, callback: Call,
@@ -60,7 +61,7 @@ impl<Call, Device> ServerPacketHandler<Call, Device> {
server_cipher: Cipher, server_cipher: Cipher,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device: Device, device: Device,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
config_info: BaseConfigInfo, config_info: BaseConfigInfo,
nat_test: NatTest, nat_test: NatTest,
callback: Call, callback: Call,
@@ -75,7 +76,7 @@ impl<Call, Device> ServerPacketHandler<Call, Device> {
server_cipher, server_cipher,
current_device, current_device,
device, device,
device_list, device_map,
config_info, config_info,
nat_test, nat_test,
callback, callback,
@@ -246,6 +247,11 @@ impl<Call: VntCallback, Device: DeviceWrite> PacketHandler for ServerPacketHandl
_ => {} _ => {}
} }
} }
ip_turn_packet::Protocol::WGIpv4 => {
if self.config_info.allow_wire_guard {
self.device.write(net_packet.payload())?;
}
}
ip_turn_packet::Protocol::Ipv4Broadcast => {} ip_turn_packet::Protocol::Ipv4Broadcast => {}
ip_turn_packet::Protocol::Unknown(_) => {} ip_turn_packet::Protocol::Unknown(_) => {}
} }
@@ -353,7 +359,8 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
); );
log::info!("tun信息{:?}", tun_info); log::info!("tun信息{:?}", tun_info);
self.callback.create_tun(tun_info); self.callback.create_tun(tun_info);
self.tun_device_helper.start(device)?; self.tun_device_helper
.start(device, self.config_info.allow_wire_guard)?;
} }
Err(e) => { Err(e) => {
log::error!("{:?}", e); log::error!("{:?}", e);
@@ -435,14 +442,18 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
info.device_status as u8, info.device_status as u8,
info.client_secret, info.client_secret,
info.client_secret_hash, info.client_secret_hash,
info.wireguard,
) )
}) })
.collect(); .collect();
{ {
let mut dev = self.device_list.lock(); let mut dev = self.device_map.lock();
//这里可能会收到旧的消息,但是随着时间推移总会收到新的 //这里可能会收到旧的消息,但是随着时间推移总会收到新的
dev.0 = epoch; dev.0 = epoch;
dev.1 = ip_list.clone(); dev.1.clear();
for info in ip_list.clone() {
dev.1.insert(info.virtual_ip, info);
}
} }
self.callback.peer_client_list( self.callback.peer_client_list(
ip_list ip_list
@@ -506,7 +517,7 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
self.callback.error(err); self.callback.error(err);
//掉线epoch要归零 //掉线epoch要归零
{ {
let mut dev = self.device_list.lock(); let mut dev = self.device_map.lock();
dev.0 = 0; dev.0 = 0;
drop(dev); drop(dev);
} }
@@ -554,7 +565,7 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
let rt = (current_time - pong_packet.time()) as i64; let rt = (current_time - pong_packet.time()) as i64;
let route = Route::from(route_key, metric, rt); let route = Route::from(route_key, metric, rt);
context.route_table.add_route(net_packet.source(), route); context.route_table.add_route(net_packet.source(), route);
let epoch = self.device_list.lock().0; let epoch = self.device_map.lock().0;
if pong_packet.epoch() != epoch { if pong_packet.epoch() != epoch {
//纪元不一致,可能有新客户端连接,向服务端拉取客户端列表 //纪元不一致,可能有新客户端连接,向服务端拉取客户端列表
let mut poll_device = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED])?; let mut poll_device = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED])?;
+42 -12
View File
@@ -1,10 +1,10 @@
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use std::collections::HashMap;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::sync::Arc; use std::sync::Arc;
use std::{io, thread}; use std::{io, thread};
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use packet::icmp::icmp::IcmpPacket; use packet::icmp::icmp::IcmpPacket;
use packet::icmp::Kind; use packet::icmp::Kind;
use packet::ip::ipv4::packet::IpV4Packet; use packet::ip::ipv4::packet::IpV4Packet;
@@ -13,6 +13,7 @@ use tun::device::IFace;
use tun::Device; use tun::Device;
use crate::channel::context::ChannelContext; use crate::channel::context::ChannelContext;
use crate::channel::sender::{send_to_wg, send_to_wg_broadcast};
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::compression::Compressor; use crate::compression::Compressor;
use crate::external_route::ExternalRoute; use crate::external_route::ExternalRoute;
@@ -27,7 +28,6 @@ use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::ip_turn_packet::BroadcastPacket; use crate::protocol::ip_turn_packet::BroadcastPacket;
use crate::protocol::{ip_turn_packet, NetPacket, MAX_TTL}; use crate::protocol::{ip_turn_packet, NetPacket, MAX_TTL};
use crate::util::StopManager; use crate::util::StopManager;
fn icmp(device_writer: &Device, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> anyhow::Result<()> { fn icmp(device_writer: &Device, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> anyhow::Result<()> {
if ipv4_packet.protocol() == Protocol::Icmp { if ipv4_packet.protocol() == Protocol::Icmp {
let mut icmp = IcmpPacket::new(ipv4_packet.payload_mut())?; let mut icmp = IcmpPacket::new(ipv4_packet.payload_mut())?;
@@ -53,9 +53,10 @@ pub fn start(
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
device_stop: DeviceStop, device_stop: DeviceStop,
allow_wire_guard: bool,
) -> io::Result<()> { ) -> io::Result<()> {
thread::Builder::new() thread::Builder::new()
.name("tunHandlerS".into()) .name("tunHandlerS".into())
@@ -70,9 +71,10 @@ pub fn start(
ip_proxy_map, ip_proxy_map,
client_cipher, client_cipher,
server_cipher, server_cipher,
device_list, device_map,
compressor, compressor,
device_stop, device_stop,
allow_wire_guard,
) { ) {
log::warn!("stop:{}", e); log::warn!("stop:{}", e);
} }
@@ -86,13 +88,13 @@ fn broadcast(
sender: &ChannelContext, sender: &ChannelContext,
net_packet: &mut NetPacket<&mut [u8]>, net_packet: &mut NetPacket<&mut [u8]>,
current_device: &CurrentDeviceInfo, current_device: &CurrentDeviceInfo,
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>, device_map: &Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let list: Vec<Ipv4Addr> = device_list let list: Vec<Ipv4Addr> = device_map
.lock() .lock()
.1 .1
.iter() .values()
.filter(|info| info.status.is_online()) .filter(|info| !info.wireguard && info.status.is_online())
.map(|info| info.virtual_ip) .map(|info| info.virtual_ip)
.collect(); .collect();
const MAX_COUNT: usize = 8; const MAX_COUNT: usize = 8;
@@ -177,8 +179,9 @@ pub(crate) fn handle(
#[cfg(feature = "ip_proxy")] proxy_map: &Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] proxy_map: &Option<IpProxyMap>,
client_cipher: &Cipher, client_cipher: &Cipher,
server_cipher: &Cipher, server_cipher: &Cipher,
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>, device_map: &Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>,
compressor: &Compressor, compressor: &Compressor,
allow_wire_guard: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
//忽略掉结构不对的情况(ipv6数据、win tap会读到空数据),不然日志打印太多了 //忽略掉结构不对的情况(ipv6数据、win tap会读到空数据),不然日志打印太多了
let ipv4_packet = match IpV4Packet::new(&mut buf[12..data_len]) { let ipv4_packet = match IpV4Packet::new(&mut buf[12..data_len]) {
@@ -237,6 +240,33 @@ pub(crate) fn handle(
dest_ip = Ipv4Addr::BROADCAST; dest_ip = Ipv4Addr::BROADCAST;
net_packet.set_destination(Ipv4Addr::BROADCAST); net_packet.set_destination(Ipv4Addr::BROADCAST);
} }
let is_broadcast = dest_ip.is_broadcast() || current_device.broadcast_ip == dest_ip;
if allow_wire_guard {
if is_broadcast {
// wg客户端和vnt客户端分开广播
let exists_wg = device_map
.lock()
.1
.values()
.any(|v| v.status.is_online() && v.wireguard);
if exists_wg {
send_to_wg_broadcast(context, &net_packet, server_cipher, &current_device)?;
}
} else {
// 如果是wg客户端则发到vnts转发
let guard = device_map.lock();
if let Some(peer_info) = guard.1.get(&dest_ip) {
if peer_info.wireguard {
if peer_info.status.is_offline() {
return Ok(());
}
drop(guard);
send_to_wg(context, &mut net_packet, server_cipher, &current_device)?;
return Ok(());
}
}
}
}
let mut net_packet = if compressor.compress(&net_packet, &mut out)? { let mut net_packet = if compressor.compress(&net_packet, &mut out)? {
out.set_default_version(); out.set_default_version();
@@ -257,7 +287,7 @@ pub(crate) fn handle(
context, context,
&mut net_packet, &mut net_packet,
&current_device, &current_device,
device_list, device_map,
)?; )?;
return Ok(()); return Ok(());
} }
+10 -4
View File
@@ -13,7 +13,9 @@ use mio::event::Source;
use mio::unix::SourceFd; use mio::unix::SourceFd;
use mio::{Events, Interest, Poll, Token, Waker}; use mio::{Events, Interest, Poll, Token, Waker};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::collections::HashMap;
use std::io; use std::io;
use std::net::Ipv4Addr;
use std::os::fd::AsRawFd; use std::os::fd::AsRawFd;
use std::sync::Arc; use std::sync::Arc;
use tun::Device; use tun::Device;
@@ -30,9 +32,10 @@ pub(crate) fn start_simple(
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
device_stop: DeviceStop, device_stop: DeviceStop,
allow_wire_guard: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let poll = Poll::new()?; let poll = Poll::new()?;
let waker = Arc::new(Waker::new(poll.registry(), STOP)?); let waker = Arc::new(Waker::new(poll.registry(), STOP)?);
@@ -61,8 +64,9 @@ pub(crate) fn start_simple(
ip_proxy_map, ip_proxy_map,
client_cipher, client_cipher,
server_cipher, server_cipher,
device_list, device_map,
compressor, compressor,
allow_wire_guard,
) { ) {
log::error!("{:?}", e); log::error!("{:?}", e);
}; };
@@ -83,8 +87,9 @@ fn start_simple0(
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
allow_wire_guard: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut buf = [0; BUFFER_SIZE]; let mut buf = [0; BUFFER_SIZE];
let mut extend = [0; BUFFER_SIZE]; let mut extend = [0; BUFFER_SIZE];
@@ -134,8 +139,9 @@ fn start_simple0(
&ip_proxy_map, &ip_proxy_map,
&client_cipher, &client_cipher,
&server_cipher, &server_cipher,
&device_list, &device_map,
&compressor, &compressor,
allow_wire_guard,
) { ) {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
+10 -4
View File
@@ -10,6 +10,8 @@ use crate::ip_proxy::IpProxyMap;
use crate::util::StopManager; use crate::util::StopManager;
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex; use parking_lot::Mutex;
use std::collections::HashMap;
use std::net::Ipv4Addr;
use std::sync::Arc; use std::sync::Arc;
use tun::device::IFace; use tun::device::IFace;
use tun::Device; use tun::Device;
@@ -23,9 +25,10 @@ pub(crate) fn start_simple(
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
device_stop: DeviceStop, device_stop: DeviceStop,
allow_wire_guard: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let worker = { let worker = {
let device = device.clone(); let device = device.clone();
@@ -54,8 +57,9 @@ pub(crate) fn start_simple(
ip_proxy_map, ip_proxy_map,
client_cipher, client_cipher,
server_cipher, server_cipher,
device_list, device_map,
compressor, compressor,
allow_wire_guard,
) { ) {
log::error!("{:?}", e); log::error!("{:?}", e);
} }
@@ -74,8 +78,9 @@ fn start_simple0(
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
allow_wire_guard: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut buf = [0; BUFFER_SIZE]; let mut buf = [0; BUFFER_SIZE];
let mut extend = [0; BUFFER_SIZE]; let mut extend = [0; BUFFER_SIZE];
@@ -96,8 +101,9 @@ fn start_simple0(
&ip_proxy_map, &ip_proxy_map,
&client_cipher, &client_cipher,
&server_cipher, &server_cipher,
&device_list, &device_map,
&compressor, &compressor,
allow_wire_guard,
) { ) {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
+13 -9
View File
@@ -1,4 +1,4 @@
use anyhow::Context; use anyhow::{anyhow, Context};
use std::io; use std::io;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, ToSocketAddrs}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, ToSocketAddrs};
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
@@ -139,17 +139,12 @@ impl Into<NatType> for PunchNatType {
impl NatTest { impl NatTest {
pub fn new( pub fn new(
_channel_num: usize, _channel_num: usize,
mut stun_server: Vec<String>, stun_server: Vec<String>,
local_ipv4: Option<Ipv4Addr>, local_ipv4: Option<Ipv4Addr>,
ipv6: Option<Ipv6Addr>, ipv6: Option<Ipv6Addr>,
udp_ports: Vec<u16>, udp_ports: Vec<u16>,
tcp_port: u16, tcp_port: u16,
) -> NatTest { ) -> NatTest {
if stun_server.len() > 5 {
stun_server.shuffle(&mut rand::thread_rng());
stun_server.truncate(5);
log::info!("stun_server truncate {:?}", stun_server);
}
let ports = vec![0; udp_ports.len()]; let ports = vec![0; udp_ports.len()];
let nat_info = NatInfo::new( let nat_info = NatInfo::new(
Vec::new(), Vec::new(),
@@ -262,8 +257,17 @@ impl NatTest {
&self, &self,
local_ipv4: Option<Ipv4Addr>, local_ipv4: Option<Ipv4Addr>,
ipv6: Option<Ipv6Addr>, ipv6: Option<Ipv6Addr>,
) -> io::Result<NatInfo> { ) -> anyhow::Result<NatInfo> {
let (nat_type, public_ips, port_range) = stun::stun_test_nat(self.stun_server.clone())?; let mut stun_server = self.stun_server.clone();
if stun_server.len() > 5 {
stun_server.shuffle(&mut rand::thread_rng());
stun_server.truncate(5);
log::info!("stun_server truncate {:?}", stun_server);
}
let (nat_type, public_ips, port_range) = stun::stun_test_nat(stun_server)?;
if public_ips.is_empty() {
Err(anyhow!("public_ips.is_empty"))?
}
let mut guard = self.info.lock(); let mut guard = self.info.lock();
guard.nat_type = nat_type; guard.nat_type = nat_type;
guard.public_ips = public_ips; guard.public_ips = public_ips;
+8 -3
View File
@@ -1,9 +1,12 @@
#![allow(dead_code)]
use std::io; use std::io;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
#[derive(Copy, Clone, Eq, PartialEq, Debug)] #[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Protocol { pub enum Protocol {
Ipv4, Ipv4,
WGIpv4,
Ipv4Broadcast, Ipv4Broadcast,
Unknown(u8), Unknown(u8),
} }
@@ -12,16 +15,18 @@ impl From<u8> for Protocol {
fn from(value: u8) -> Self { fn from(value: u8) -> Self {
match value { match value {
4 => Protocol::Ipv4, 4 => Protocol::Ipv4,
5 => Protocol::WGIpv4,
201 => Protocol::Ipv4Broadcast, 201 => Protocol::Ipv4Broadcast,
val => Protocol::Unknown(val), val => Protocol::Unknown(val),
} }
} }
} }
impl Into<u8> for Protocol { impl From<Protocol> for u8 {
fn into(self) -> u8 { fn from(val: Protocol) -> Self {
match self { match val {
Protocol::Ipv4 => 4, Protocol::Ipv4 => 4,
Protocol::WGIpv4 => 5,
Protocol::Ipv4Broadcast => 201, Protocol::Ipv4Broadcast => 201,
Protocol::Unknown(val) => val, Protocol::Unknown(val) => val,
} }
+8 -5
View File
@@ -1,4 +1,6 @@
use std::collections::HashMap;
use std::io; use std::io;
use std::net::Ipv4Addr;
use std::sync::Arc; use std::sync::Arc;
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
@@ -67,7 +69,7 @@ struct TunDeviceHelperInner {
ip_proxy_map: Option<IpProxyMap>, ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
} }
@@ -80,7 +82,7 @@ impl TunDeviceHelper {
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher, client_cipher: Cipher,
server_cipher: Cipher, server_cipher: Cipher,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_map: Arc<Mutex<(u16, HashMap<Ipv4Addr, PeerDeviceInfo>)>>,
compressor: Compressor, compressor: Compressor,
device_adapter: DeviceAdapter, device_adapter: DeviceAdapter,
) -> Self { ) -> Self {
@@ -93,7 +95,7 @@ impl TunDeviceHelper {
ip_proxy_map, ip_proxy_map,
client_cipher, client_cipher,
server_cipher, server_cipher,
device_list, device_map,
compressor, compressor,
}; };
Self { Self {
@@ -117,7 +119,7 @@ impl TunDeviceHelper {
} }
} }
/// 要保证先stop 再start /// 要保证先stop 再start
pub fn start(&self, device: Arc<Device>) -> io::Result<()> { pub fn start(&self, device: Arc<Device>, allow_wire_guard: bool) -> io::Result<()> {
self.device_adapter.insert(device.clone()); self.device_adapter.insert(device.clone());
let device_stop = DeviceStop::default(); let device_stop = DeviceStop::default();
let s = self.device_stop.lock().replace(device_stop.clone()); let s = self.device_stop.lock().replace(device_stop.clone());
@@ -133,9 +135,10 @@ impl TunDeviceHelper {
inner.ip_proxy_map, inner.ip_proxy_map,
inner.client_cipher, inner.client_cipher,
inner.server_cipher, inner.server_cipher,
inner.device_list, inner.device_map,
inner.compressor, inner.compressor,
device_stop, device_stop,
allow_wire_guard,
) )
} }
} }