增加端口映射功能

This commit is contained in:
lbl8603
2024-05-08 21:31:21 +08:00
parent d3dce7a3cc
commit 607c8c2e9f
12 changed files with 342 additions and 24 deletions
+9 -8
View File
@@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
vnt = { path = "../vnt", package = "vnt",default-features = false }
vnt = { path = "../vnt", package = "vnt", default-features = false }
common = { path = "../common" }
getopts = "0.2.21"
console = "0.15.2"
@@ -28,16 +28,17 @@ sudo = "0.6.0"
winapi = { version = "0.3.9", features = ["handleapi", "processthreadsapi", "winnt", "securitybaseapi", "impl-default"] }
[features]
default = ["server_encrypt","aes_gcm","aes_cbc","aes_ecb","sm4_cbc","ip_proxy"]
default = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "ip_proxy", "port_mapping"]
openssl = ["vnt/openssl"]
openssl-vendored = ["vnt/openssl-vendored"]
ring-cipher = ["vnt/ring-cipher"]
aes_cbc=["vnt/aes_cbc"]
aes_ecb=["vnt/aes_ecb"]
sm4_cbc=["vnt/sm4_cbc"]
aes_gcm=["vnt/aes_gcm"]
server_encrypt=["vnt/server_encrypt"]
ip_proxy=["vnt/ip_proxy"]
aes_cbc = ["vnt/aes_cbc"]
aes_ecb = ["vnt/aes_ecb"]
sm4_cbc = ["vnt/sm4_cbc"]
aes_gcm = ["vnt/aes_gcm"]
server_encrypt = ["vnt/server_encrypt"]
ip_proxy = ["vnt/ip_proxy"]
port_mapping = ["vnt/port_mapping"]
[build-dependencies]
embed-manifest = "1.4.0"
rand = "0.8.5"
+21 -6
View File
@@ -10,7 +10,7 @@
### -c
关闭控制台交互式命令,后台运行时可以加此参数
### -s `<server>`
注册和中继服务器地址,注册和转发数据
注册和中继服务器地址,注册和转发数据,以'TXT:'开头表示解析TXT记录,TXT记录内容必须是'host:port'形式的服务器地址
### -e `<stun-server>`
使用stun服务探测客户端NAT类型,不同类型有不同的打洞策略
### -a
@@ -72,9 +72,9 @@
注意:默认情况下服务端不会对中转的数据做校验,如果要对中转的数据做校验,则需要客户端、服务端都开启此参数
### --punch `<punch>`
取值ipv4/ipv6,选择只使用ipv4打洞或者只使用ipv6打洞,默认两都会使用
取值ipv4/ipv6,选择只使用ipv4打洞或者只使用ipv6打洞,默认两都会使用
### --ports `<port1,port2>`
指定本地监听的端口组,多个端口使用逗号分隔,多个端口可以分摊流量,增加并发,tcp会监听端口组的第一个端口,用于tcp直连
指定本地监听的端口组,多个端口使用逗号分隔,多个端口可以分摊流量,增加并发、减缓流量限制,tcp会监听端口组的第一个端口,用于tcp直连
- 例1:‘--ports 12345,12346,12347 表示udp监听12345、12346、12347这三个端口,tcp监听12345端口
- 例2:‘--ports 0,0’ 表示udp监听两个未使用的端口,tcp监听一个未使用的端口
@@ -85,6 +85,14 @@
### --no-proxy
关闭内置的ip代理,内置的代理较为简单,而且一般来说直接使用网卡NAT转发性能会更高,
有需要可以自行配置NAT转发,[可参考‘编译’小节中的NAT配置](https://github.com/lbl8603/vnt#%E7%BC%96%E8%AF%91)
### --dns `<223.5.5.5>`
设置域名解析服务器地址,可以设置多个。如果使用TXT记录的域名,则dns默认使用223.5.5.5和114.114.114.114,端口省略值为53
当地址解析失败时,会依次尝试后面的dns,直到有A记录、AAAA记录(或TXT记录)的解析结果
### --mapping `<udp:0.0.0.0:80->10.26.0.10:80>`
端口映射,可以设置多个映射地址,例如 '--mapping udp:0.0.0.0:80->10.26.0.10:80 --mapping tcp:0.0.0.0:80->10.26.0.11:81'
表示将本地udp 80端口的数据转发到10.26.0.10:80,将本地tcp 80端口的数据转发到10.26.0.11:81,转发的目的地址可以使用域名+端口
### -f `<conf>`
指定配置文件
配置文件采用yaml格式,可参考:
@@ -111,7 +119,7 @@ server_encrypt: true #服务端加密
parallel: 1 #任务并行度
cipher_model: aes_gcm #客户端加密算法
finger: false #关闭数据指纹
punch_model: ipv4 #打洞模式
punch_model: ipv4 #打洞模式,表示只使用ipv4地址打洞,默认会同时使用v6和v4
ports:
- 0 #使用随机端口,tcp监听此端口
- 0
@@ -122,7 +130,12 @@ device_name: vnt-tun #网卡名称
packet_loss: 0 #指定丢包率 取值0~1之间的数 用于模拟弱网
packet_delay: 0 #指定延迟 单位毫秒 用于模拟弱网
dns:
- 8.8.8.8:53
- 223.5.5.5 # 首选dns
- 8.8.8.8 # 备选dns
mapping:
- 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:82->localhost:83 # 映射tcp数据
```
或者需要哪个配置就加哪个,当然token是必须的
@@ -134,7 +147,9 @@ token: xxx #组网token
- relay:仅中继模式,会禁止打洞/p2p直连,只使用服务器转发
- p2p:仅直连模式,会禁止网络数据从服务器/客户端转发,只会使用服务器转发控制包
### --packet-loss `<0>`
模拟丢包,取值0~1之间的小数,程序会按设定的概率主动丢包。在模拟弱网环境会有帮助。
模拟丢包,取值0~1之间的小数,程序会按设定的概率主动丢包。在模拟弱网环境会有帮助。
### --packet-delay `<0>`
模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网
### --list
在后台运行时,查看其他设备列表
+7 -1
View File
@@ -40,6 +40,8 @@ pub struct FileConfig {
pub device_name: Option<String>,
pub packet_loss: Option<f64>,
pub packet_delay: u32,
#[cfg(feature = "port_mapping")]
pub mapping: Vec<String>,
}
impl Default for FileConfig {
@@ -54,7 +56,7 @@ impl Default for FileConfig {
stun_server: vec![
"stun1.l.google.com:19302".to_string(),
"stun2.l.google.com:19302".to_string(),
"stun.qq.com:3478".to_string(),
"stun.miwifi.com:3478".to_string(),
],
dns: vec![],
in_ips: vec![],
@@ -77,6 +79,8 @@ impl Default for FileConfig {
device_name: None,
packet_loss: None,
packet_delay: 0,
#[cfg(feature = "port_mapping")]
mapping: vec![],
}
}
}
@@ -157,6 +161,8 @@ pub fn read_config(file_path: &str) -> io::Result<(Config, bool)> {
use_channel_type,
file_conf.packet_loss,
file_conf.packet_delay,
#[cfg(feature = "port_mapping")]
file_conf.mapping,
)
.unwrap();
Ok((config, file_conf.cmd))
+17 -2
View File
@@ -73,6 +73,7 @@ fn main() {
opts.optopt("", "packet-loss", "丢包率", "<packet-loss>");
opts.optopt("", "packet-delay", "延迟", "<packet-delay>");
opts.optmulti("", "dns", "dns", "<dns>");
opts.optmulti("", "mapping", "mapping", "<mapping>");
opts.optopt("f", "", "配置文件", "<conf>");
//"后台运行时,查看其他设备列表"
opts.optflag("", "list", "后台运行时,查看其他设备列表");
@@ -156,7 +157,7 @@ fn main() {
if stun_server.is_empty() {
stun_server.push("stun1.l.google.com:19302".to_string());
stun_server.push("stun2.l.google.com:19302".to_string());
stun_server.push("stun.qq.com:3478".to_string());
stun_server.push("stun.miwifi.com:3478".to_string());
}
let dns = matches.opt_strs("dns");
let in_ip = matches.opt_strs("i");
@@ -287,6 +288,8 @@ fn main() {
.opt_get::<u32>("packet-delay")
.expect("--packet-delay")
.unwrap_or(0);
#[cfg(feature = "port_mapping")]
let port_mapping_list = matches.opt_strs("mapping");
let config = match Config::new(
#[cfg(any(target_os = "windows", target_os = "linux"))]
tap,
@@ -315,6 +318,8 @@ fn main() {
use_channel_type,
packet_loss,
packet_delay,
#[cfg(feature = "port_mapping")]
port_mapping_list,
) {
Ok(config) => config,
Err(e) => {
@@ -338,6 +343,14 @@ fn main() {
mod callback;
fn main0(config: Config, show_cmd: bool) {
#[cfg(feature = "port_mapping")]
for (is_tcp, addr, dest) in config.port_mapping_list.iter() {
if *is_tcp {
println!("TCP port mapping {}->{}", addr, dest)
} else {
println!("UDP port mapping {}->{}", addr, dest)
}
}
let vnt_util = Vnt::new(config, callback::VntHandler {}).unwrap();
let vnt_c = vnt_util.clone();
thread::Builder::new()
@@ -412,7 +425,7 @@ fn print_usage(program: &str, _opts: Options) {
println!(" -n <name> 给设备一个名字,便于区分不同设备,默认使用系统版本");
println!(" -d <id> 设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复");
println!(" -s <server> 注册和中继服务器地址,以'TXT:'开头表示解析TXT记录");
println!(" -e <stun-server> stun服务器,用于探测NAT类型,可使用多个地址,如-e stun.qq.com -e stun1.l.google.com");
println!(" -e <stun-server> stun服务器,用于探测NAT类型,可使用多个地址,如-e stun1.l.google.com -e stun2.l.google.com");
println!(" -a 使用tap模式,默认使用tun模式");
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,可指定多个网段");
@@ -475,6 +488,8 @@ fn print_usage(program: &str, _opts: Options) {
" --packet-delay <0> 模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网"
);
println!(" --dns <host:port> DNS服务器地址,可使用多个dns,不指定时使用系统解析");
#[cfg(feature = "port_mapping")]
println!(" --mapping <mapping> 端口映射,例如 --mapping udp:0.0.0.0:80->10.26.0.10:80 --mapping tcp:0.0.0.0:80->10.26.0.10:80");
println!();
println!(