Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13b7b1761d | ||
|
|
352f322f61 | ||
|
|
be966c4f83 | ||
|
|
b8cbf2cdac | ||
|
|
05cf0e1a6f | ||
|
|
f90ef96a5d | ||
|
|
81c6c8c1fc | ||
|
|
7ebdffcdd3 | ||
|
|
1abe33cb16 | ||
|
|
965cbfbb7e | ||
|
|
aa332b4f4d | ||
|
|
14ee9c4632 | ||
|
|
ddfa89167d | ||
|
|
1f9ed7b314 |
Generated
+19
-8
@@ -307,7 +307,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "common"
|
name = "common"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -319,6 +319,7 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
|
"sys-locale",
|
||||||
"uuid",
|
"uuid",
|
||||||
"vnt",
|
"vnt",
|
||||||
]
|
]
|
||||||
@@ -880,7 +881,7 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "libsm"
|
name = "libsm"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
source = "git+https://github.com/lbl8603/libsm#f9e1b8cf20d0829efb4934a940d0ba4f3ee0ac14"
|
source = "git+https://github.com/vnt-dev/libsm#f9e1b8cf20d0829efb4934a940d0ba4f3ee0ac14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
@@ -954,7 +955,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "lwip-rs"
|
name = "lwip-rs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/lbl8603/lwip-rs#3133f0c3bde55333a27641182ae3550e7acc2a39"
|
source = "git+https://github.com/vnt-dev/lwip-rs#3133f0c3bde55333a27641182ae3550e7acc2a39"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -1120,7 +1121,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.93"
|
version = "0.9.93"
|
||||||
source = "git+https://github.com/lbl8603/rust-openssl#e8b3d2c02d2d07a0e4a82ff4e4bef210f4bc71c8"
|
source = "git+https://github.com/vnt-dev/rust-openssl#e8b3d2c02d2d07a0e4a82ff4e4bef210f4bc71c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -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"
|
||||||
@@ -1958,6 +1968,7 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand",
|
||||||
|
"sha2",
|
||||||
"widestring",
|
"widestring",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
@@ -2095,7 +2106,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vn-link"
|
name = "vn-link"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
@@ -2108,7 +2119,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vn-link-cli"
|
name = "vn-link-cli"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"common",
|
"common",
|
||||||
"log",
|
"log",
|
||||||
@@ -2118,7 +2129,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vnt"
|
name = "vnt"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
@@ -2165,7 +2176,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vnt-cli"
|
name = "vnt-cli"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ A virtual network tool (VPN)
|
|||||||
|
|
||||||
将不同网络下的多个设备虚拟到一个局域网下
|
将不同网络下的多个设备虚拟到一个局域网下
|
||||||
|
|
||||||
### vnt-cli参数详解 [参数说明](https://github.com/lbl8603/vnt/blob/main/vnt-cli/README.md)
|
### vnt-cli参数详解 [参数说明](https://github.com/vnt-dev/vnt/blob/main/vnt-cli/README.md)
|
||||||
|
|
||||||
### 快速使用:
|
### 快速使用:
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ A virtual network tool (VPN)
|
|||||||
```
|
```
|
||||||
4. 最后可以用虚拟ip实现设备间相互访问
|
4. 最后可以用虚拟ip实现设备间相互访问
|
||||||
|
|
||||||
<img width="506" alt="ssh" src="https://raw.githubusercontent.com/lbl8603/vnt/main/documents/img/ssh.jpg">
|
<img width="506" alt="ssh" src="https://raw.githubusercontent.com/vnt-dev/vnt/main/documents/img/ssh.jpg">
|
||||||
5. 帮助,使用-h命令查看
|
5. 帮助,使用-h命令查看
|
||||||
|
|
||||||
### 更多玩法
|
### 更多玩法
|
||||||
@@ -56,7 +56,7 @@ A virtual network tool (VPN)
|
|||||||
- 需要root/管理员权限
|
- 需要root/管理员权限
|
||||||
- vnt-cli需要使用命令行运行
|
- vnt-cli需要使用命令行运行
|
||||||
- Mac和Linux下需要加可执行权限(例如:chmod +x ./vnt-cli)
|
- Mac和Linux下需要加可执行权限(例如:chmod +x ./vnt-cli)
|
||||||
- 可以自己搭注册和中继服务器([server](https://github.com/lbl8603/vnts))
|
- 可以自己搭注册和中继服务器([server](https://github.com/vnt-dev/vnts))
|
||||||
- vnt使用stun服务器探测网络NAT类型,默认使用谷歌和腾讯的stun服务器,也可自己搭建(-e参数指定)
|
- vnt使用stun服务器探测网络NAT类型,默认使用谷歌和腾讯的stun服务器,也可自己搭建(-e参数指定)
|
||||||
|
|
||||||
### 编译
|
### 编译
|
||||||
@@ -181,7 +181,7 @@ sudo pfctl -f /etc/pf.conf -e
|
|||||||
|
|
||||||
### GUI
|
### GUI
|
||||||
|
|
||||||
支持安卓和Windows [下载](https://github.com/lbl8603/VntApp/releases/)
|
支持安卓和Windows [下载](https://github.com/vnt-dev/VntApp/releases/)
|
||||||
|
|
||||||
### 特性
|
### 特性
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ QQ: 1034868233
|
|||||||
### 赞助
|
### 赞助
|
||||||
如果VNT对你有帮助,欢迎打赏作者
|
如果VNT对你有帮助,欢迎打赏作者
|
||||||
|
|
||||||
<img width="300" alt="" src="https://github.com/lbl8603/vnt/assets/49143209/0d3a7311-43fc-4ed7-9507-863b5d69b6b2">
|
<img width="300" alt="" src="https://github.com/vnt-dev/vnt/assets/49143209/0d3a7311-43fc-4ed7-9507-863b5d69b6b2">
|
||||||
|
|
||||||
### 其他
|
### 其他
|
||||||
|
|
||||||
@@ -302,6 +302,6 @@ QQ: 1034868233
|
|||||||
|
|
||||||
### 参与贡献
|
### 参与贡献
|
||||||
|
|
||||||
<a href="https://github.com/lbl8603/vnt/graphs/contributors">
|
<a href="https://github.com/vnt-dev/vnt/graphs/contributors">
|
||||||
<img src="https://contrib.rocks/image?repo=lbl8603/vnt" />
|
<img src="https://contrib.rocks/image?repo=vnt-dev/vnt" />
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "common"
|
name = "common"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vn-link-cli"
|
name = "vn-link-cli"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -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"]
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vn-link"
|
name = "vn-link"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lwip-rs = { git = "https://github.com/lbl8603/lwip-rs" }
|
lwip-rs = { git = "https://github.com/vnt-dev/lwip-rs" }
|
||||||
vnt = { path = "../vnt", package = "vnt", default-features = false }
|
vnt = { path = "../vnt", package = "vnt", default-features = false }
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
anyhow = "1.0.82"
|
anyhow = "1.0.82"
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vnt-cli"
|
name = "vnt-cli"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
+11
-1
@@ -135,7 +135,7 @@ aes_gcm/aes_cbc/aes_ecb/sm4_cbc/chacha20_poly1305/chacha20/xor,默认使用aes
|
|||||||
### --no-proxy
|
### --no-proxy
|
||||||
|
|
||||||
关闭内置的ip代理,内置的代理较为简单,而且一般来说直接使用网卡NAT转发性能会更高,
|
关闭内置的ip代理,内置的代理较为简单,而且一般来说直接使用网卡NAT转发性能会更高,
|
||||||
有需要可以自行配置NAT转发,[可参考‘编译’小节中的NAT配置](https://github.com/lbl8603/vnt#%E7%BC%96%E8%AF%91)
|
有需要可以自行配置NAT转发,[可参考‘编译’小节中的NAT配置](https://github.com/vnt-dev/vnt#%E7%BC%96%E8%AF%91)
|
||||||
|
|
||||||
### --dns `<223.5.5.5>`
|
### --dns `<223.5.5.5>`
|
||||||
|
|
||||||
@@ -201,6 +201,8 @@ mapping:
|
|||||||
- udp:0.0.0.0:80-10.26.0.10:80 # 映射udp数据
|
- udp:0.0.0.0:80-10.26.0.10:80 # 映射udp数据
|
||||||
- tcp:0.0.0.0:80-10.26.0.10:81 # 映射tcp数据
|
- tcp:0.0.0.0:80-10.26.0.10:81 # 映射tcp数据
|
||||||
- tcp:0.0.0.0:82-localhost:83 # 映射tcp数据
|
- tcp:0.0.0.0:82-localhost:83 # 映射tcp数据
|
||||||
|
disable_stats: false # 为true表示关闭统计
|
||||||
|
allow_wire_guard: false # 为true则表示允许接入wg
|
||||||
```
|
```
|
||||||
|
|
||||||
或者需要哪个配置就加哪个,当然token是必须的
|
或者需要哪个配置就加哪个,当然token是必须的
|
||||||
@@ -223,6 +225,14 @@ token: xxx #组网token
|
|||||||
|
|
||||||
模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网
|
模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网
|
||||||
|
|
||||||
|
### --disable-stats
|
||||||
|
|
||||||
|
关闭流量统计
|
||||||
|
|
||||||
|
### --allow-wg
|
||||||
|
|
||||||
|
允许接入WireGuard客户端,和wg混用时必须开启此参数
|
||||||
|
|
||||||
### --list
|
### --list
|
||||||
|
|
||||||
在后台运行时,查看其他设备列表
|
在后台运行时,查看其他设备列表
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vnt"
|
name = "vnt"
|
||||||
version = "1.2.11"
|
version = "1.2.12"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
@@ -29,8 +29,8 @@ aes = "0.8.3"
|
|||||||
stun-format = { version = "1.0.1", features = ["fmt", "rfc3489"] }
|
stun-format = { version = "1.0.1", features = ["fmt", "rfc3489"] }
|
||||||
rsa = { version = "0.9.2", features = [], optional = true }
|
rsa = { version = "0.9.2", features = [], optional = true }
|
||||||
spki = { version = "0.7.2", features = ["fingerprint", "alloc", "base64"], optional = true }
|
spki = { version = "0.7.2", features = ["fingerprint", "alloc", "base64"], optional = true }
|
||||||
openssl-sys = { git = "https://github.com/lbl8603/rust-openssl", optional = true }
|
openssl-sys = { git = "https://github.com/vnt-dev/rust-openssl", optional = true }
|
||||||
libsm = { git = "https://github.com/lbl8603/libsm", optional = true }
|
libsm = { git = "https://github.com/vnt-dev/libsm", optional = true }
|
||||||
|
|
||||||
mio = { version = "=0.8.11", features = ["os-poll", "net", "os-ext"] }
|
mio = { version = "=0.8.11", features = ["os-poll", "net", "os-ext"] }
|
||||||
crossbeam-queue = "0.3.11"
|
crossbeam-queue = "0.3.11"
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(©_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
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, ¤t_device_info, &nat_test, index) {
|
||||||
&context,
|
|
||||||
¤t_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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
¤t_device_info.load(),
|
¤t_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,
|
||||||
¤t_device.load(),
|
¤t_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)
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 => {
|
||||||
//客户端不帮忙转发广播包,所以不会出现这种类型的数据
|
//客户端不帮忙转发广播包,所以不会出现这种类型的数据
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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])?;
|
||||||
|
|||||||
@@ -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,18 +88,21 @@ 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();
|
||||||
|
if list.is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
const MAX_COUNT: usize = 8;
|
const MAX_COUNT: usize = 8;
|
||||||
let mut p2p_ips = Vec::with_capacity(8);
|
let mut p2p_ips = Vec::with_capacity(8);
|
||||||
let mut relay_ips = Vec::with_capacity(8);
|
let mut relay = false;
|
||||||
let mut overflow = false;
|
let mut overflow = false;
|
||||||
for (index, peer_ip) in list.into_iter().enumerate() {
|
for (index, peer_ip) in list.into_iter().enumerate() {
|
||||||
if index > MAX_COUNT {
|
if index > MAX_COUNT {
|
||||||
@@ -110,38 +115,22 @@ fn broadcast(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
relay_ips.push(peer_ip);
|
relay = true;
|
||||||
}
|
}
|
||||||
if !overflow && relay_ips.is_empty() {
|
if !overflow && !relay {
|
||||||
//全部p2p,不需要服务器中转
|
//全部p2p,不需要服务器中转
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if p2p_ips.is_empty() {
|
|
||||||
//都没有p2p则直接由服务器转发
|
|
||||||
if current_device.status.online() {
|
|
||||||
sender.send_default(&net_packet, current_device.connect_server)?;
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
if !overflow && relay_ips.len() == 2 {
|
|
||||||
// 如果转发的ip数不多就直接发
|
|
||||||
for peer_ip in relay_ips {
|
|
||||||
//非直连的广播要改变目的地址,不然服务端收到了会再次广播
|
|
||||||
net_packet.set_destination(peer_ip);
|
|
||||||
sender.send_ipv4_by_id(
|
|
||||||
&net_packet,
|
|
||||||
&peer_ip,
|
|
||||||
current_device.connect_server,
|
|
||||||
current_device.status.online(),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
if current_device.status.offline() {
|
if current_device.status.offline() {
|
||||||
//离线的不再转发
|
//离线的不再转发
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
if p2p_ips.is_empty() {
|
||||||
|
//都没有p2p则直接由服务器转发
|
||||||
|
sender.send_default(&net_packet, current_device.connect_server)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let buf = vec![0u8; 12 + 1 + p2p_ips.len() * 4 + net_packet.data_len() + ENCRYPTION_RESERVED];
|
let buf = vec![0u8; 12 + 1 + p2p_ips.len() * 4 + net_packet.data_len() + ENCRYPTION_RESERVED];
|
||||||
//剩余的发送到服务端,需要告知哪些已发送过
|
//剩余的发送到服务端,需要告知哪些已发送过
|
||||||
let mut server_packet = NetPacket::new_encrypt(buf)?;
|
let mut server_packet = NetPacket::new_encrypt(buf)?;
|
||||||
@@ -177,8 +166,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 +227,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, ¤t_device)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果是wg客户端则发到vnts转发
|
||||||
|
let guard = device_map.lock();
|
||||||
|
if let Some(peer_info) = guard.1.get(&dest_ip) {
|
||||||
|
if peer_info.status.is_offline() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if peer_info.wireguard {
|
||||||
|
drop(guard);
|
||||||
|
send_to_wg(context, &mut net_packet, server_cipher, ¤t_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();
|
||||||
@@ -249,7 +266,7 @@ pub(crate) fn handle(
|
|||||||
} else {
|
} else {
|
||||||
net_packet
|
net_packet
|
||||||
};
|
};
|
||||||
if dest_ip.is_broadcast() || current_device.broadcast_ip == dest_ip {
|
if is_broadcast {
|
||||||
// 广播 发送到直连目标
|
// 广播 发送到直连目标
|
||||||
client_cipher.encrypt_ipv4(&mut net_packet)?;
|
client_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||||
broadcast(
|
broadcast(
|
||||||
@@ -257,7 +274,7 @@ pub(crate) fn handle(
|
|||||||
context,
|
context,
|
||||||
&mut net_packet,
|
&mut net_packet,
|
||||||
¤t_device,
|
¤t_device,
|
||||||
device_list,
|
device_map,
|
||||||
)?;
|
)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,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
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ libc = "0.2.153"
|
|||||||
|
|
||||||
log = { version = "0.4.20", features = [] }
|
log = { version = "0.4.20", features = [] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
sha2 = { version = "0.10.6", features = ["oid"] }
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies]
|
[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies]
|
||||||
ioctl = { version = "0.8", package = "ioctl-sys" }
|
ioctl = { version = "0.8", package = "ioctl-sys" }
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use libloading::Library;
|
use libloading::Library;
|
||||||
|
use sha2::Digest;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use rand::Rng;
|
|
||||||
use winapi::um::winbase;
|
use winapi::um::winbase;
|
||||||
use winapi::um::{synchapi, winnt};
|
use winapi::um::{synchapi, winnt};
|
||||||
|
|
||||||
@@ -81,8 +80,7 @@ impl Device {
|
|||||||
if Self::delete_for_name(&win_tun, &name_utf16).is_ok() {
|
if Self::delete_for_name(&win_tun, &name_utf16).is_ok() {
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
}
|
}
|
||||||
let mut guid_bytes: [u8; 16] = [0u8; 16];
|
let guid_bytes: [u8; 16] = hash_guid(&name);
|
||||||
rand::thread_rng().fill(&mut guid_bytes);
|
|
||||||
let guid = u128::from_ne_bytes(guid_bytes);
|
let guid = u128::from_ne_bytes(guid_bytes);
|
||||||
//SAFETY: guid is a unique integer so transmuting either all zeroes or the user's preferred
|
//SAFETY: guid is a unique integer so transmuting either all zeroes or the user's preferred
|
||||||
//guid to the winapi guid type is safe and will allow the windows kernel to see our GUID
|
//guid to the winapi guid type is safe and will allow the windows kernel to see our GUID
|
||||||
@@ -154,7 +152,14 @@ impl Device {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn hash_guid(input: &str) -> [u8; 16] {
|
||||||
|
let mut hasher = sha2::Sha256::new();
|
||||||
|
hasher.update(b"VNT");
|
||||||
|
hasher.update(input.as_bytes());
|
||||||
|
hasher.update(b"2024");
|
||||||
|
let hash: [u8; 32] = hasher.finalize().into();
|
||||||
|
hash[..16].try_into().unwrap()
|
||||||
|
}
|
||||||
impl IFace for Device {
|
impl IFace for Device {
|
||||||
fn version(&self) -> io::Result<String> {
|
fn version(&self) -> io::Result<String> {
|
||||||
let version = unsafe { self.win_tun.WintunGetRunningDriverVersion() };
|
let version = unsafe { self.win_tun.WintunGetRunningDriverVersion() };
|
||||||
|
|||||||
Reference in New Issue
Block a user