增加服务端加密、完善客户端加密
This commit is contained in:
@@ -77,6 +77,9 @@ jobs:
|
||||
- TARGET: x86_64-pc-windows-msvc # tested on a windows machine
|
||||
OS: windows-latest
|
||||
FEATURES: ring-cipher
|
||||
- TARGET: mipsel-unknown-linux-musl # openwrt
|
||||
OS: ubuntu-latest
|
||||
FEATURES: normal
|
||||
# needs: test
|
||||
runs-on: ${{ matrix.OS }}
|
||||
env:
|
||||
@@ -102,22 +105,45 @@ jobs:
|
||||
# dependencies are only needed on ubuntu as that's the only place where
|
||||
# we make cross-compilation
|
||||
if [[ $OS =~ ^ubuntu.*$ ]]; then
|
||||
sudo apt-get update && sudo apt-get install -qq crossbuild-essential-arm64 crossbuild-essential-armhf musl-tools
|
||||
sudo apt-get update && sudo apt-get install -qq crossbuild-essential-arm64 crossbuild-essential-armhf musl-tools gcc-mipsel-linux-gnu
|
||||
fi
|
||||
# some additional configuration for cross-compilation on linux
|
||||
cat >>~/.cargo/config <<EOF
|
||||
[target.x86_64-unknown-linux-musl]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.aarch64-unknown-linux-gnu]
|
||||
linker = "aarch64-linux-gnu-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.aarch64-unknown-linux-musl]
|
||||
linker = "aarch64-linux-gnu-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.armv7-unknown-linux-gnueabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.armv7-unknown-linux-musleabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.arm-unknown-linux-gnueabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.arm-unknown-linux-musleabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.mipsel-unknown-linux-musl]
|
||||
linker = "mipsel-linux-gnu-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.i686-pc-windows-msvc]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.x86_64-apple-darwin]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.aarch64-apple-darwin]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.i686-unknown-linux-musl]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
EOF
|
||||
- name: Install rust target
|
||||
run: rustup target add $TARGET
|
||||
|
||||
@@ -85,11 +85,11 @@ A virtual network tool (VPN)
|
||||
- IP代理
|
||||
- p2p组播/广播
|
||||
- 客户端数据加密
|
||||
- 服务端数据加密
|
||||
|
||||
### Todo
|
||||
|
||||
- 桌面UI(测试中)
|
||||
- 服务端数据加密
|
||||
- 支持Ipv6
|
||||
|
||||
### 常见问题
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "common"
|
||||
version = "1.1.2"
|
||||
version = "1.2.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "vnt-cli"
|
||||
version = "1.1.2"
|
||||
version = "1.2.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@@ -16,6 +16,7 @@ dirs = "4.0.0"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0.94"
|
||||
log = "0.4.17"
|
||||
log4rs = "1.2.0"
|
||||
[dependencies.uuid]
|
||||
version = "1.4.1"
|
||||
features = [
|
||||
|
||||
+3
-1
@@ -25,13 +25,15 @@
|
||||
|
||||
### -w `<password>`
|
||||
|
||||
提升通信安全性,使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密。使用相同密码的客户端才能通信
|
||||
提升通信安全性,使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密(包括中继数据)。使用相同密码的客户端才能通信
|
||||
|
||||
| 密码位数 | 加密算法 |
|
||||
|---------|-------|
|
||||
| 小于8 | AES128-GCM
|
||||
| 大于等于8 | AES256-GCM |
|
||||
|
||||
### -W
|
||||
开启和服务端通信加密,可以避免中间人攻击
|
||||
### -m
|
||||
模拟组播,高频使用组播通信时,可以尝试开启此参数,默认情况下会把组播当作广播发给所有节点
|
||||
|
||||
|
||||
@@ -31,4 +31,6 @@ pub struct DeviceItem {
|
||||
pub nat_traversal_type: String,
|
||||
pub rt: String,
|
||||
pub status: String,
|
||||
pub client_secret: bool,
|
||||
pub current_client_secret:bool,
|
||||
}
|
||||
@@ -75,6 +75,7 @@ pub fn command_list(vnt: &Vnt) -> Vec<DeviceItem> {
|
||||
let info = vnt.current_device();
|
||||
let device_list = vnt.device_list();
|
||||
let mut list = Vec::new();
|
||||
let current_client_secret = vnt.client_encrypt();
|
||||
for peer in device_list {
|
||||
let name = peer.name;
|
||||
let virtual_ip = peer.virtual_ip.to_string();
|
||||
@@ -105,6 +106,7 @@ pub fn command_list(vnt: &Vnt) -> Vec<DeviceItem> {
|
||||
("relay".to_string(), "".to_string())
|
||||
};
|
||||
let status = format!("{:?}", peer.status);
|
||||
let client_secret = peer.client_secret;
|
||||
let item = DeviceItem {
|
||||
name,
|
||||
virtual_ip,
|
||||
@@ -114,6 +116,8 @@ pub fn command_list(vnt: &Vnt) -> Vec<DeviceItem> {
|
||||
nat_traversal_type,
|
||||
rt,
|
||||
status,
|
||||
client_secret,
|
||||
current_client_secret,
|
||||
};
|
||||
list.push(item);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::io;
|
||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use std::io::Write;
|
||||
use tokio::net::UdpSocket;
|
||||
|
||||
use vnt::core::Vnt;
|
||||
@@ -15,27 +15,11 @@ impl CommandServer {
|
||||
|
||||
impl CommandServer {
|
||||
pub async fn start(self, vnt: Vnt) -> io::Result<()> {
|
||||
let mut port = 21637 as u16;
|
||||
let udp = loop {
|
||||
match UdpSocket::bind(SocketAddr::V4(SocketAddrV4::new(
|
||||
Ipv4Addr::new(127, 0, 0, 1),
|
||||
port,
|
||||
))).await {
|
||||
Ok(udp) => {
|
||||
break udp;
|
||||
}
|
||||
Err(e) => {
|
||||
if e.kind() == io::ErrorKind::AddrInUse {
|
||||
port += 1;
|
||||
} else {
|
||||
log::error!("创建udp失败 {:?}", e);
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let udp = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let path_buf = crate::app_home()?.join("command-port");
|
||||
std::fs::write(path_buf, udp.local_addr()?.port().to_string())?;
|
||||
let mut file = std::fs::File::create(path_buf)?;
|
||||
file.write_all(udp.local_addr()?.port().to_string().as_bytes())?;
|
||||
file.sync_all()?;
|
||||
let mut buf = [0u8; 64];
|
||||
loop {
|
||||
let (len, addr) = udp.recv_from(&mut buf).await?;
|
||||
|
||||
@@ -56,18 +56,27 @@ pub fn console_device_list(mut list: Vec<DeviceItem>) {
|
||||
("Rt".to_string(), Style::new())]);
|
||||
for item in list {
|
||||
if &item.status == "Online" {
|
||||
if &item.nat_traversal_type == "p2p" {
|
||||
out_list.push(vec![(item.name, Style::new().green()),
|
||||
(item.virtual_ip, Style::new().green()),
|
||||
(item.status, Style::new().green()),
|
||||
(item.nat_traversal_type, Style::new().green()),
|
||||
(item.rt, Style::new().green())]);
|
||||
if item.client_secret != item.current_client_secret {
|
||||
//加密状态不一致,无法通信的
|
||||
out_list.push(vec![(item.name, Style::new().red()),
|
||||
(item.virtual_ip, Style::new().red()),
|
||||
(item.status, Style::new().red()),
|
||||
("".to_string(), Style::new().red()),
|
||||
("".to_string(), Style::new().red())]);
|
||||
} else {
|
||||
out_list.push(vec![(item.name, Style::new().yellow()),
|
||||
(item.virtual_ip, Style::new().yellow()),
|
||||
(item.status, Style::new().yellow()),
|
||||
(item.nat_traversal_type, Style::new().yellow()),
|
||||
(item.rt, Style::new().yellow())]);
|
||||
if &item.nat_traversal_type == "p2p" {
|
||||
out_list.push(vec![(item.name, Style::new().green()),
|
||||
(item.virtual_ip, Style::new().green()),
|
||||
(item.status, Style::new().green()),
|
||||
(item.nat_traversal_type, Style::new().green()),
|
||||
(item.rt, Style::new().green())]);
|
||||
} else {
|
||||
out_list.push(vec![(item.name, Style::new().yellow()),
|
||||
(item.virtual_ip, Style::new().yellow()),
|
||||
(item.status, Style::new().yellow()),
|
||||
(item.nat_traversal_type, Style::new().yellow()),
|
||||
(item.rt, Style::new().yellow())]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out_list.push(vec![(item.name, Style::new().color256(102)),
|
||||
|
||||
@@ -7,7 +7,7 @@ pub fn println_table(table: Vec<Vec<(String, Style)>>) {
|
||||
let mut width_list = vec![0; table[0].len()];
|
||||
for in_list in table.iter() {
|
||||
for (index, (item, _)) in in_list.iter().enumerate() {
|
||||
let width = console::measure_text_width(item) + 6;
|
||||
let width = console::measure_text_width(item) + 4;
|
||||
if width_list[index] < width {
|
||||
width_list[index] = width;
|
||||
}
|
||||
|
||||
+177
-68
@@ -2,11 +2,17 @@ use std::io;
|
||||
use std::net::{Ipv4Addr, ToSocketAddrs};
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use console::style;
|
||||
use getopts::Options;
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
use tokio::signal;
|
||||
#[cfg(unix)]
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
use common::args_parse::{ips_parse, out_ips_parse};
|
||||
use vnt::core::{Config, VntUtil};
|
||||
use vnt::core::{Config, Vnt, VntUtil};
|
||||
use vnt::handle::handshake_handler::HandshakeEnum;
|
||||
use vnt::handle::registration_handler::ReqEnum;
|
||||
|
||||
mod command;
|
||||
@@ -28,24 +34,26 @@ async fn main() {
|
||||
}
|
||||
|
||||
async fn main0() {
|
||||
let _ = log4rs::init_file("log4rs.yaml", Default::default());
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let program = args[0].clone();
|
||||
let mut opts = Options::new();
|
||||
opts.optopt("k", "", "必选,使用相同的token,就能组建一个局域网络", "<token>");
|
||||
opts.optopt("n", "", "给设备一个名字,便于区分不同设备,默认使用系统版本", "<name>");
|
||||
opts.optopt("d", "", "设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip", "<id>");
|
||||
opts.optflag("c", "", "关闭交互式命令,使用此参数禁用控制台输入");
|
||||
opts.optopt("k", "", "组网标识", "<token>");
|
||||
opts.optopt("n", "", "设备名称", "<name>");
|
||||
opts.optopt("d", "", "设备标识", "<id>");
|
||||
opts.optflag("c", "", "关闭交互式命令");
|
||||
opts.optopt("s", "", "注册和中继服务器地址", "<server>");
|
||||
opts.optmulti("e", "", "stun服务器,用于探测NAT类型,可多次指定,如-e addr1 -e addr2", "<stun-server>");
|
||||
opts.optflag("a", "", "使用tap模式,默认使用tun模式");
|
||||
opts.optmulti("i", "", "配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3 \n表示允许接收网段192.168.0.0/24的数据并转发到10.26.0.3,可指定多个网段", "<in-ip>");
|
||||
opts.optmulti("o", "", "配置点对网时使用,-o 192.168.0.0/24 \n表示允许将数据转发到192.168.0.0/24,可指定多个网段", "<out-ip>");
|
||||
opts.optopt("w", "", "使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信", "<password>");
|
||||
opts.optflag("m", "", "模拟组播,默认情况下组播数据会被当作广播发送,开启后会模拟真实组播的数据发送");
|
||||
opts.optmulti("e", "", "stun服务器", "<stun-server>");
|
||||
opts.optflag("a", "", "使用tap模式");
|
||||
opts.optmulti("i", "", "配置点对网(IP代理)入站时使用", "<in-ip>");
|
||||
opts.optmulti("o", "", "配置点对网出站时使用", "<out-ip>");
|
||||
opts.optopt("w", "", "客户端加密", "<password>");
|
||||
opts.optflag("W", "", "服务端加密");
|
||||
opts.optflag("m", "", "模拟组播");
|
||||
opts.optopt("u", "", "自定义mtu(默认为1430)", "<mtu>");
|
||||
opts.optflag("", "tcp", "和服务端使用tcp通信,默认使用udp,一般来说udp延迟和消耗更低");
|
||||
opts.optopt("", "ip", "指定虚拟ip,指定的ip不能和其他设备重复,必须有效并且在服务端所属网段下,默认情况由服务端分配", "<IP>");
|
||||
opts.optflag("", "relay", "仅使用服务器转发,不使用p2p,默认情况允许使用p2p");
|
||||
opts.optflag("", "tcp", "tcp");
|
||||
opts.optopt("", "ip", "指定虚拟ip", "<IP>");
|
||||
opts.optflag("", "relay", "仅使用服务器转发");
|
||||
//"后台运行时,查看其他设备列表"
|
||||
opts.optflag("", "list", "后台运行时,查看其他设备列表");
|
||||
opts.optflag("", "all", "后台运行时,查看其他设备完整信息");
|
||||
@@ -117,7 +125,7 @@ async fn main0() {
|
||||
return;
|
||||
}
|
||||
let name = matches.opt_get_default("n", os_info::get().to_string()).unwrap();
|
||||
let server_address_str = matches.opt_get_default("s", "nat1.wherewego.top:29871".to_string()).unwrap();
|
||||
let server_address_str = matches.opt_get_default("s", "nat1.wherewego.top:29872".to_string()).unwrap();
|
||||
let server_address = match server_address_str.to_socket_addrs() {
|
||||
Ok(mut addr) => {
|
||||
if let Some(addr) = addr.next() {
|
||||
@@ -162,6 +170,7 @@ async fn main0() {
|
||||
}
|
||||
};
|
||||
let password: Option<String> = matches.opt_get("w").unwrap();
|
||||
let server_encrypt = matches.opt_present("W");
|
||||
let simulate_multicast = matches.opt_present("m");
|
||||
let unused_cmd = matches.opt_present("c");
|
||||
let mtu: Option<String> = matches.opt_get("u").unwrap();
|
||||
@@ -190,45 +199,101 @@ async fn main0() {
|
||||
}
|
||||
let tcp_channel = matches.opt_present("tcp");
|
||||
let relay = matches.opt_present("relay");
|
||||
println!("version 1.2.0");
|
||||
let config = Config::new(tap,
|
||||
token, device_id, name,
|
||||
server_address, server_address_str,
|
||||
stun_server, in_ip,
|
||||
out_ip, password, simulate_multicast, mtu, tcp_channel, virtual_ip, relay);
|
||||
out_ip, password, simulate_multicast, mtu,
|
||||
tcp_channel, virtual_ip, relay, server_encrypt);
|
||||
let mut vnt_util = VntUtil::new(config).await.unwrap();
|
||||
let mut conn_count = 0;
|
||||
let response = loop {
|
||||
match vnt_util.connect().await {
|
||||
if conn_count > 0 {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
|
||||
}
|
||||
conn_count += 1;
|
||||
if let Err(e) = vnt_util.connect().await {
|
||||
println!("connect server failed {}", e);
|
||||
return;
|
||||
}
|
||||
match vnt_util.handshake().await {
|
||||
Ok(response) => {
|
||||
break response;
|
||||
if server_encrypt {
|
||||
let finger = response.unwrap().finger().unwrap();
|
||||
println!("{}{}", green("server fingerprint:".to_string()), finger);
|
||||
match vnt_util.secret_handshake().await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
match e {
|
||||
HandshakeEnum::NotSecret => {}
|
||||
HandshakeEnum::KeyError => {}
|
||||
HandshakeEnum::Timeout => {
|
||||
println!("handshake timeout")
|
||||
}
|
||||
HandshakeEnum::ServerError(str) => {
|
||||
println!("error:{}", str);
|
||||
}
|
||||
HandshakeEnum::Other(str) => {
|
||||
println!("error:{}", str);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
match vnt_util.register().await {
|
||||
Ok(response) => {
|
||||
break response;
|
||||
}
|
||||
Err(e) => {
|
||||
match e {
|
||||
ReqEnum::TokenError => {
|
||||
println!("token error");
|
||||
return;
|
||||
}
|
||||
ReqEnum::AddressExhausted => {
|
||||
println!("address exhausted");
|
||||
return;
|
||||
}
|
||||
ReqEnum::Timeout => {
|
||||
println!("timeout...");
|
||||
}
|
||||
ReqEnum::ServerError(str) => {
|
||||
println!("error:{}", str);
|
||||
}
|
||||
ReqEnum::Other(str) => {
|
||||
println!("error:{}", str);
|
||||
}
|
||||
ReqEnum::IpAlreadyExists => {
|
||||
println!("ip already exists");
|
||||
return;
|
||||
}
|
||||
ReqEnum::InvalidIp => {
|
||||
println!("invalid ip");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
match e {
|
||||
ReqEnum::TokenError => {
|
||||
println!("token error");
|
||||
HandshakeEnum::NotSecret => {
|
||||
println!("The server does not support encryption");
|
||||
return;
|
||||
}
|
||||
ReqEnum::AddressExhausted => {
|
||||
println!("address exhausted");
|
||||
HandshakeEnum::KeyError => {}
|
||||
HandshakeEnum::Timeout => {
|
||||
println!("handshake timeout")
|
||||
}
|
||||
ReqEnum::Timeout => {
|
||||
println!("timeout...");
|
||||
continue;
|
||||
}
|
||||
ReqEnum::ServerError(str) => {
|
||||
HandshakeEnum::ServerError(str) => {
|
||||
println!("error:{}", str);
|
||||
continue;
|
||||
}
|
||||
ReqEnum::Other(str) => {
|
||||
HandshakeEnum::Other(str) => {
|
||||
println!("error:{}", str);
|
||||
continue;
|
||||
}
|
||||
ReqEnum::IpAlreadyExists => {
|
||||
println!("ip already exists");
|
||||
}
|
||||
ReqEnum::InvalidIp => {
|
||||
println!("invalid ip");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -259,44 +324,56 @@ async fn main0() {
|
||||
let stdin = tokio::io::stdin();
|
||||
let mut cmd = String::new();
|
||||
let mut reader = BufReader::new(stdin);
|
||||
#[cfg(unix)]
|
||||
let mut sigterm = signal(SignalKind::terminate()).expect("Error setting SIGTERM handler");
|
||||
loop {
|
||||
cmd.clear();
|
||||
println!("input:list,info,route,all,stop");
|
||||
#[cfg(unix)]
|
||||
tokio::select! {
|
||||
_ = vnt.wait_stop()=>{
|
||||
break;
|
||||
}
|
||||
_ = signal::ctrl_c()=>{
|
||||
let _ = vnt.stop();
|
||||
vnt.wait_stop_ms(std::time::Duration::from_secs(3)).await;
|
||||
return;
|
||||
}
|
||||
_ = sigterm.recv()=>{
|
||||
let _ = vnt.stop();
|
||||
vnt.wait_stop_ms(std::time::Duration::from_secs(3)).await;
|
||||
return;
|
||||
}
|
||||
rs = reader.read_line(&mut cmd)=>{
|
||||
match rs {
|
||||
Ok(len) => {
|
||||
if len ==0 {
|
||||
if !command(&cmd[..len],&vnt){
|
||||
break;
|
||||
}
|
||||
match cmd[..len].to_lowercase().trim() {
|
||||
"list" => {
|
||||
let list = command::command_list(&vnt);
|
||||
console_out::console_device_list(list);
|
||||
}
|
||||
"info"=>{
|
||||
let info = command::command_info(&vnt);
|
||||
console_out::console_info(info);
|
||||
}
|
||||
"route" =>{
|
||||
let route = command::command_route(&vnt);
|
||||
console_out::console_route_table(route);
|
||||
}
|
||||
"all" =>{
|
||||
let list = command::command_list(&vnt);
|
||||
console_out::console_device_list_all(list);
|
||||
}
|
||||
"stop" =>{
|
||||
let _ = vnt.stop();
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
println!("input err:{}",e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(windows)]
|
||||
tokio::select! {
|
||||
_ = vnt.wait_stop()=>{
|
||||
break;
|
||||
}
|
||||
_ = signal::ctrl_c()=>{
|
||||
let _ = vnt.stop();
|
||||
vnt.wait_stop_ms(std::time::Duration::from_secs(3)).await;
|
||||
return;
|
||||
}
|
||||
rs = reader.read_line(&mut cmd)=>{
|
||||
match rs {
|
||||
Ok(len) => {
|
||||
if !command(&cmd[..len],&vnt){
|
||||
break;
|
||||
}
|
||||
println!();
|
||||
}
|
||||
Err(e) => {
|
||||
println!("input err:{}",e);
|
||||
@@ -310,9 +387,40 @@ async fn main0() {
|
||||
vnt.wait_stop().await;
|
||||
}
|
||||
|
||||
fn command(cmd: &str, vnt: &Vnt) -> bool {
|
||||
if cmd.is_empty() {
|
||||
return false;
|
||||
}
|
||||
match cmd.to_lowercase().trim() {
|
||||
"list" => {
|
||||
let list = command::command_list(&vnt);
|
||||
console_out::console_device_list(list);
|
||||
}
|
||||
"info" => {
|
||||
let info = command::command_info(&vnt);
|
||||
console_out::console_info(info);
|
||||
}
|
||||
"route" => {
|
||||
let route = command::command_route(&vnt);
|
||||
console_out::console_route_table(route);
|
||||
}
|
||||
"all" => {
|
||||
let list = command::command_list(&vnt);
|
||||
console_out::console_device_list_all(list);
|
||||
}
|
||||
"stop" => {
|
||||
let _ = vnt.stop();
|
||||
return false;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
println!();
|
||||
return true;
|
||||
}
|
||||
|
||||
fn print_usage(program: &str, _opts: Options) {
|
||||
println!("Usage: {} [options]", program);
|
||||
println!("version:1.1.2");
|
||||
println!("version:1.2.0");
|
||||
println!("Options:");
|
||||
println!(" -k <token> {}", green("必选,使用相同的token,就能组建一个局域网络".to_string()));
|
||||
println!(" -n <name> 给设备一个名字,便于区分不同设备,默认使用系统版本");
|
||||
@@ -325,17 +433,18 @@ fn print_usage(program: &str, _opts: Options) {
|
||||
println!(" 并转发到10.26.0.3,可指定多个网段");
|
||||
println!(" -o <out-ip> 配置点对网时使用,-o 192.168.0.0/24表示允许将数据转发到192.168.0.0/24,可指定多个网段");
|
||||
println!(" -w <password> 使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信");
|
||||
println!(" -W 加密当前客户端和服务端通信的数据,请留意服务端指纹是否正确");
|
||||
println!(" -m 模拟组播,默认情况下组播数据会被当作广播发送,开启后会模拟真实组播的数据发送");
|
||||
println!(" -u <mtu> 自定义mtu(默认为1430)");
|
||||
println!(" --tcp 和服务端使用tcp通信,默认使用udp,遇到udp qos时可指定使用tcp");
|
||||
println!(" --ip <IP> 指定虚拟ip,指定的ip不能和其他设备重复,必须有效并且在服务端所属网段下,默认情况由服务端分配");
|
||||
println!(" --relay 仅使用服务器转发,不使用p2p,默认情况允许使用p2p");
|
||||
println!();
|
||||
println!(" --list {}",yellow("后台运行时,查看其他设备列表".to_string()));
|
||||
println!(" --all {}",yellow("后台运行时,查看其他设备完整信息".to_string()));
|
||||
println!(" --info {}",yellow("后台运行时,查看当前设备信息".to_string()));
|
||||
println!(" --route {}",yellow("后台运行时,查看数据转发路径".to_string()));
|
||||
println!(" --stop {}",yellow("停止后台运行".to_string()));
|
||||
println!(" --list {}", yellow("后台运行时,查看其他设备列表".to_string()));
|
||||
println!(" --all {}", yellow("后台运行时,查看其他设备完整信息".to_string()));
|
||||
println!(" --info {}", yellow("后台运行时,查看当前设备信息".to_string()));
|
||||
println!(" --route {}", yellow("后台运行时,查看数据转发路径".to_string()));
|
||||
println!(" --stop {}", yellow("停止后台运行".to_string()));
|
||||
println!(" -h, --help 帮助");
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "vnt"
|
||||
version = "1.1.2"
|
||||
version = "1.2.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@@ -11,7 +11,7 @@ bytes = "1.3.0"
|
||||
log = "0.4.17"
|
||||
libc = "0.2.137"
|
||||
crossbeam-utils = "0.8"
|
||||
crossbeam-skiplist = "0.1"
|
||||
crossbeam-skiplist = "0.1.1"
|
||||
parking_lot = "0.12.1"
|
||||
rand = "0.8.5"
|
||||
sha2 = { version = "0.10.6", features = ["oid"] }
|
||||
@@ -22,6 +22,8 @@ tokio = { version = "1.28.1", features = ["full"] }
|
||||
aes-gcm = {version="0.10.2", optional = true}
|
||||
ring = {version="0.16.20", optional = true}
|
||||
stun-format = {version="1.0.1",features=["fmt","rfc3489"]}
|
||||
rsa = {version="0.7.2", features = [] }
|
||||
spki = {version="0.6.0",features=["fingerprint","alloc"]}
|
||||
|
||||
[target.'cfg(any(target_os = "linux",target_os = "macos"))'.dependencies]
|
||||
tun = { path = "./rust-tun" }
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
syntax = "proto3";
|
||||
message HandshakeRequest{
|
||||
string version = 1;
|
||||
bool secret = 2;
|
||||
}
|
||||
message HandshakeResponse{
|
||||
string version = 1;
|
||||
bool secret = 2;
|
||||
bytes public_key = 3;
|
||||
string key_finger = 4;
|
||||
}
|
||||
message SecretHandshakeRequest{
|
||||
string token = 1;
|
||||
bytes key = 2;
|
||||
}
|
||||
message RegistrationRequest{
|
||||
string token = 1;
|
||||
string device_id = 2;
|
||||
@@ -7,6 +21,7 @@ message RegistrationRequest{
|
||||
string version = 5;
|
||||
fixed32 virtual_ip = 6;
|
||||
bool allow_ip_change = 7;
|
||||
bool client_secret = 8;
|
||||
}
|
||||
|
||||
message RegistrationResponse{
|
||||
@@ -23,6 +38,7 @@ message DeviceInfo{
|
||||
string name = 1;
|
||||
fixed32 virtual_ip = 2;
|
||||
uint32 device_status = 3;
|
||||
bool client_secret = 4;
|
||||
}
|
||||
|
||||
message DeviceList{
|
||||
|
||||
+89
-55
@@ -92,9 +92,7 @@ impl Context {
|
||||
}
|
||||
pub async fn send_main(&self, buf: &[u8], addr: SocketAddr) -> io::Result<usize> {
|
||||
if let Some(sender) = &self.inner.main_tcp_channel {
|
||||
let mut vec = vec![0; 4 + buf.len()];
|
||||
vec[4..].copy_from_slice(buf);
|
||||
if sender.send(vec).await.is_ok() {
|
||||
if sender.send(buf.to_vec()).await.is_ok() {
|
||||
Ok(buf.len())
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "send_main err"))
|
||||
@@ -105,9 +103,7 @@ impl Context {
|
||||
}
|
||||
pub fn try_send_main(&self, buf: &[u8], addr: SocketAddr) -> io::Result<usize> {
|
||||
if let Some(sender) = &self.inner.main_tcp_channel {
|
||||
let mut vec = vec![0; 4 + buf.len()];
|
||||
vec[4..].copy_from_slice(buf);
|
||||
if sender.try_send(vec).is_ok() {
|
||||
if sender.try_send(buf.to_vec()).is_ok() {
|
||||
Ok(buf.len())
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "try_send_main err"))
|
||||
@@ -339,71 +335,91 @@ impl Channel {
|
||||
}
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
async fn handle(handler: &mut ChannelDataHandler,
|
||||
context: &Context,
|
||||
id: usize,
|
||||
result: io::Result<(usize, SocketAddr)>,
|
||||
buf: &mut [u8], start: usize) {
|
||||
match result {
|
||||
Ok((len, addr)) => {
|
||||
handler.handle(buf, start, start + len, RouteKey::new(id, addr), context).await;
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{:?}",e)
|
||||
}
|
||||
}
|
||||
#[derive(Clone)]
|
||||
struct BufSenderGroup(usize, Vec<tokio::sync::mpsc::Sender<(Vec<u8>, usize, usize, RouteKey)>>);
|
||||
|
||||
struct BufReceiverGroup(Vec<tokio::sync::mpsc::Receiver<(Vec<u8>, usize, usize, RouteKey)>>);
|
||||
|
||||
impl BufSenderGroup {
|
||||
pub async fn send(&mut self, val: (Vec<u8>, usize, usize, RouteKey)) -> bool {
|
||||
let index = self.0 % self.1.len();
|
||||
self.0 = self.0.wrapping_add(1);
|
||||
self.1[index].send(val).await.is_ok()
|
||||
}
|
||||
async fn tcp_handle(mut tcp_r: OwnedReadHalf, context: Context,
|
||||
mut handler: ChannelDataHandler, head_reserve: usize, ) -> io::Result<()> {
|
||||
let mut buf = [0; 4096];
|
||||
}
|
||||
|
||||
fn buf_channel_group(size: usize) -> (BufSenderGroup, BufReceiverGroup) {
|
||||
let mut buf_sender_group = Vec::with_capacity(size);
|
||||
let mut buf_receiver_group = Vec::with_capacity(size);
|
||||
for _ in 0..size {
|
||||
let (buf_sender, buf_receiver) = tokio::sync::mpsc::channel::<(Vec<u8>, usize, usize, RouteKey)>(10);
|
||||
buf_sender_group.push(buf_sender);
|
||||
buf_receiver_group.push(buf_receiver);
|
||||
}
|
||||
(BufSenderGroup(0, buf_sender_group), BufReceiverGroup(buf_receiver_group))
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
async fn tcp_handle(mut tcp_r: OwnedReadHalf, mut buf_sender: BufSenderGroup, head_reserve: usize) -> io::Result<()> {
|
||||
let mut head = [0; 4];
|
||||
let addr = tcp_r.peer_addr()?;
|
||||
let key = RouteKey::new(0, addr);
|
||||
loop {
|
||||
tcp_r.read_exact(&mut buf[head_reserve..head_reserve + 4]).await?;
|
||||
let len = 4 + (((buf[head_reserve + 2] as u16) << 8) | buf[head_reserve + 3] as u16) as usize;
|
||||
tcp_r.read_exact(&mut buf[head_reserve + 4..head_reserve + len]).await?;
|
||||
handler.handle(&mut buf[4..], head_reserve, head_reserve + len - 4, key, &context).await;
|
||||
let mut buf = vec![0; 4096];
|
||||
tcp_r.read_exact(&mut head).await?;
|
||||
let len = (((head[2] as u16) << 8) | head[3] as u16) as usize;
|
||||
if len < 12 || len > buf.len() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"length overflow",
|
||||
));
|
||||
}
|
||||
tcp_r.read_exact(&mut buf[head_reserve..head_reserve + len]).await?;
|
||||
if !buf_sender.send((buf, head_reserve, head_reserve + len, key)).await {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "buf_sender发送数据失败"));
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn start_tcp(mut worker: VntWorker, tcp_stream: TcpStream, mut receiver: tokio::sync::mpsc::Receiver<Vec<u8>>, context: Context, handler: ChannelDataHandler, head_reserve: usize) {
|
||||
async fn start_tcp(mut worker: VntWorker, tcp_stream: TcpStream, mut receiver: tokio::sync::mpsc::Receiver<Vec<u8>>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
buf_sender: BufSenderGroup, head_reserve: usize) {
|
||||
let (tcp_r, mut tcp_w) = tcp_stream.into_split();
|
||||
{
|
||||
let context = context.clone();
|
||||
let handler = handler.clone();
|
||||
let buf_sender = buf_sender.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = Self::tcp_handle(tcp_r, context, handler, head_reserve).await {
|
||||
if let Err(e) = Self::tcp_handle(tcp_r, buf_sender, head_reserve).await {
|
||||
log::info!("tcp链接断开:{:?}",e);
|
||||
}
|
||||
});
|
||||
}
|
||||
let mut head = [0; 4];
|
||||
loop {
|
||||
tokio::select! {
|
||||
_=worker.stop_wait()=>{
|
||||
break;
|
||||
}
|
||||
rs=receiver.recv()=>{
|
||||
if let Some(mut data) = rs{
|
||||
if data.len()<4{
|
||||
continue
|
||||
}
|
||||
let len = data.len() - 4;
|
||||
data[2] = (len >> 8) as u8;
|
||||
data[3] = (len & 0xFF) as u8;
|
||||
if let Err(e) = tcp_w.write_all(&data).await {
|
||||
if context.is_close() {
|
||||
break;
|
||||
}
|
||||
if let Some(data) = rs{
|
||||
let len = data.len();
|
||||
head[2] = (len >> 8) as u8;
|
||||
head[3] = (len & 0xFF) as u8;
|
||||
let mut err = false;
|
||||
if let Err(e) = tcp_w.write_all(&head).await{
|
||||
err = true;
|
||||
log::info!("发送失败,需要重连:{:?}",e);
|
||||
}else if let Err(e) = tcp_w.write_all(&data).await{
|
||||
err = true;
|
||||
log::info!("发送失败,需要重连:{:?}",e);
|
||||
}
|
||||
if err {
|
||||
let _ = tcp_w.shutdown().await;
|
||||
match TcpStream::connect(context.inner.current_device.load().connect_server).await {
|
||||
match TcpStream::connect(current_device.load().connect_server).await {
|
||||
Ok(tcp_stream) => {
|
||||
let (r, w) = tcp_stream.into_split();
|
||||
tcp_w = w;
|
||||
let context = context.clone();
|
||||
let handler = handler.clone();
|
||||
let buf_sender = buf_sender.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = Self::tcp_handle(r, context, handler, head_reserve).await {
|
||||
if let Err(e) = Self::tcp_handle(r, buf_sender, head_reserve).await {
|
||||
log::info!("tcp 链接断开:{:?}",e);
|
||||
}
|
||||
});
|
||||
@@ -421,6 +437,7 @@ impl Channel {
|
||||
}
|
||||
worker.stop_all();
|
||||
}
|
||||
|
||||
pub async fn start(self,
|
||||
mut worker: VntWorker,
|
||||
tcp: Option<(TcpStream, tokio::sync::mpsc::Receiver<Vec<u8>>)>,
|
||||
@@ -428,14 +445,22 @@ impl Channel {
|
||||
symmetric_channel_num: usize,//对称网络,则再加一组监听,提升打洞成功率
|
||||
relay: bool,
|
||||
) {
|
||||
let (buf_sender, buf_receiver) = buf_channel_group(6);
|
||||
for mut buf_receiver in buf_receiver.0 {
|
||||
let context = self.context.clone();
|
||||
let handler = self.handler.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some((mut buf, start, end, route_key)) = buf_receiver.recv().await {
|
||||
handler.handle(&mut buf, start, end, route_key, &context).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
let context = self.context;
|
||||
let main_channel = context.inner.main_channel.clone();
|
||||
let handler = self.handler.clone();
|
||||
if let Some((tcp_stream, receiver)) = tcp {
|
||||
tokio::spawn(Self::start_tcp(worker.worker("main_channel_tcp"), tcp_stream, receiver, context.clone(), handler.clone(), head_reserve));
|
||||
tokio::spawn(Self::start_tcp(worker.worker("main_channel_tcp"), tcp_stream, receiver, context.inner.current_device.clone(), buf_sender.clone(), head_reserve));
|
||||
}
|
||||
tokio::spawn(Self::start_(worker.worker("main_channel_1"), context.clone(), handler.clone(), main_channel.clone(), head_reserve, true));
|
||||
// tokio::spawn(Self::start_(worker.worker("main_channel_2"), context.clone(), handler, main_channel, head_reserve, true));
|
||||
tokio::spawn(Self::start_(worker.worker("main_channel_1"), context.clone(), main_channel.clone(), buf_sender.clone(), head_reserve, true));
|
||||
if relay {
|
||||
worker.stop_wait().await;
|
||||
return;
|
||||
@@ -465,8 +490,7 @@ impl Channel {
|
||||
Ok(udp) => {
|
||||
let udp = Arc::new(udp);
|
||||
let context = context.clone();
|
||||
let handler = self.handler.clone();
|
||||
tokio::spawn(Self::start_(worker.worker("symmetric_channel"),context, handler, udp, head_reserve, false));
|
||||
tokio::spawn(Self::start_(worker.worker("symmetric_channel"),context, udp,buf_sender.clone(), head_reserve, false));
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{}",e);
|
||||
@@ -489,8 +513,8 @@ impl Channel {
|
||||
worker.stop_all();
|
||||
}
|
||||
async fn start_(mut worker: VntWorker, context: Context,
|
||||
mut handler: ChannelDataHandler,
|
||||
udp: Arc<UdpSocket>,
|
||||
mut buf_sender: BufSenderGroup,
|
||||
head_reserve: usize,
|
||||
is_core: bool) {
|
||||
let mut status_receiver = context.inner.status_receiver.clone();
|
||||
@@ -503,11 +527,21 @@ impl Channel {
|
||||
#[cfg(any(unix))]
|
||||
let id = 1 + udp.as_raw_fd() as usize;
|
||||
context.inner.udp_map.insert(id, udp.clone());
|
||||
let mut buf = [0; 4096];
|
||||
loop {
|
||||
let mut buf = vec![0; 4096];
|
||||
tokio::select! {
|
||||
rs=udp.recv_from(&mut buf[head_reserve..])=>{
|
||||
Self::handle(&mut handler,&context,id,rs,&mut buf,head_reserve).await;
|
||||
match rs {
|
||||
Ok((len, addr)) => {
|
||||
if !buf_sender.send((buf,head_reserve,head_reserve+len,RouteKey::new(id, addr))).await{
|
||||
log::error!("udp buf_sender发送数据失败");
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{:?}",e)
|
||||
}
|
||||
}
|
||||
}
|
||||
changed=status_receiver.changed()=>{
|
||||
match changed {
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
use std::io;
|
||||
use crate::cipher::Finger;
|
||||
use crate::protocol::NetPacket;
|
||||
use sha2::Digest;
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
use crate::cipher::ring_cipher::AesGcmCipher;
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
use crate::cipher::aes_gcm_cipher::AesGcmCipher;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Cipher {
|
||||
Aes((AesGcmCipher, Vec<u8>)),
|
||||
None,
|
||||
}
|
||||
|
||||
impl Cipher {
|
||||
pub fn new_password(password: Option<String>, token: String) -> Self {
|
||||
let finger = Finger::new(token);
|
||||
if let Some(password) = password {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(password.as_bytes());
|
||||
let key: [u8; 32] = hasher.finalize().into();
|
||||
if password.len() < 8 {
|
||||
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||
Cipher::Aes((aes, key[..16].to_vec()))
|
||||
} else {
|
||||
let aes = AesGcmCipher::new_256(key, finger);
|
||||
Cipher::Aes((aes, key.to_vec()))
|
||||
}
|
||||
} else {
|
||||
Cipher::None
|
||||
}
|
||||
}
|
||||
pub fn new_key(key: [u8; 32], token: String) -> io::Result<Self> {
|
||||
let finger = Finger::new(token);
|
||||
match key.len() {
|
||||
16 => {
|
||||
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
|
||||
Ok(Cipher::Aes((aes, key[..16].to_vec())))
|
||||
}
|
||||
32 => {
|
||||
let aes = AesGcmCipher::new_256(key, finger);
|
||||
Ok(Cipher::Aes((aes, key.to_vec())))
|
||||
}
|
||||
_ => {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "key error"))
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<()> {
|
||||
match self {
|
||||
Cipher::Aes((aes_gcm, _)) => {
|
||||
aes_gcm.decrypt_ipv4(net_packet)
|
||||
}
|
||||
Cipher::None => {
|
||||
if net_packet.is_encrypt() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not key"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<()> {
|
||||
match self {
|
||||
Cipher::Aes((aes_gcm, _)) => {
|
||||
aes_gcm.encrypt_ipv4(net_packet)
|
||||
}
|
||||
Cipher::None => {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn check_finger<B: AsRef<[u8]>>(&self, net_packet: &NetPacket<B>) -> io::Result<()> {
|
||||
match self {
|
||||
Cipher::Aes((aes_gcm, _)) => {
|
||||
aes_gcm.finger.check_finger(net_packet)
|
||||
}
|
||||
Cipher::None => {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn key(&self) -> Option<&[u8]> {
|
||||
match self {
|
||||
Cipher::Aes((_, key)) => {
|
||||
Some(key)
|
||||
}
|
||||
Cipher::None => {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,111 +1,111 @@
|
||||
use std::io;
|
||||
|
||||
use aes_gcm::{AeadInPlace, Aes128Gcm, Aes256Gcm, Key, Nonce, Tag,KeyInit};
|
||||
use aes_gcm::{AeadInPlace, Aes128Gcm, Aes256Gcm, Key, KeyInit, Nonce, Tag};
|
||||
use aes_gcm::aead::consts::{U12, U16};
|
||||
use aes_gcm::aead::generic_array::GenericArray;
|
||||
use sha2::Digest;
|
||||
use rand::RngCore;
|
||||
|
||||
use crate::cipher::finger::Finger;
|
||||
use crate::protocol::{body::ENCRYPTION_RESERVED, body::SecretBody, NetPacket};
|
||||
|
||||
|
||||
use crate::protocol;
|
||||
use crate::protocol::{ip_turn_packet, NetPacket};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Cipher {
|
||||
AesGCM128(Aes128Gcm),
|
||||
AesGCM256(Aes256Gcm),
|
||||
None,
|
||||
pub struct AesGcmCipher {
|
||||
pub(crate) cipher: AesGcmEnum,
|
||||
pub(crate) finger: Finger,
|
||||
}
|
||||
|
||||
impl Cipher {
|
||||
pub fn new(password: Option<String>) -> Self {
|
||||
if let Some(password) = password {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(password.as_bytes());
|
||||
let key: [u8; 32] = hasher.finalize().into();
|
||||
if password.len() < 8 {
|
||||
let key: &Key<Aes128Gcm> = key[..16].into();
|
||||
Cipher::AesGCM128(Aes128Gcm::new(&key))
|
||||
} else {
|
||||
let key: &Key<Aes256Gcm> = &key.into();
|
||||
Cipher::AesGCM256(Aes256Gcm::new(&key))
|
||||
}
|
||||
} else {
|
||||
Cipher::None
|
||||
#[derive(Clone)]
|
||||
pub enum AesGcmEnum {
|
||||
AES128GCM(Aes128Gcm),
|
||||
AES256GCM(Aes256Gcm),
|
||||
}
|
||||
|
||||
impl AesGcmCipher {
|
||||
pub fn new_128(key: [u8; 16], finger: Finger) -> Self {
|
||||
let key: &Key<Aes128Gcm> = &key.into();
|
||||
Self {
|
||||
cipher: AesGcmEnum::AES128GCM(Aes128Gcm::new(key)),
|
||||
finger,
|
||||
}
|
||||
}
|
||||
pub fn decrypt_ipv4(&self, net_packet: &mut NetPacket<&mut [u8]>) -> io::Result<Option<usize>> {
|
||||
match &self {
|
||||
Cipher::None => {
|
||||
return Ok(None);
|
||||
}
|
||||
_ => {}
|
||||
pub fn new_256(key: [u8; 32], finger: Finger) -> Self {
|
||||
let key: &Key<Aes256Gcm> = &key.into();
|
||||
Self {
|
||||
cipher: AesGcmEnum::AES256GCM(Aes256Gcm::new(key)),
|
||||
finger,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
}
|
||||
if net_packet.payload().len() < 16 {
|
||||
log::error!("数据异常,长度小于16");
|
||||
if net_packet.payload().len() < ENCRYPTION_RESERVED {
|
||||
log::error!("数据异常,长度小于{}",ENCRYPTION_RESERVED);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
}
|
||||
let mut nonce = [0; 12];
|
||||
nonce[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce[8] = protocol::Protocol::IpTurn.into();
|
||||
nonce[9] = ip_turn_packet::Protocol::Ipv4.into();
|
||||
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce);
|
||||
let payload_len = net_packet.payload().len() - 16;
|
||||
let tag: GenericArray<u8, U16> = Tag::clone_from_slice(&net_packet.payload()[payload_len..]);
|
||||
let rs = match &self {
|
||||
Cipher::AesGCM128(cipher) => {
|
||||
cipher.decrypt_in_place_detached(nonce, &[], &mut net_packet.payload_mut()[..payload_len], &tag)
|
||||
}
|
||||
Cipher::AesGCM256(cipher) => {
|
||||
cipher.decrypt_in_place_detached(nonce, &[], &mut net_packet.payload_mut()[..payload_len], &tag)
|
||||
}
|
||||
Cipher::None => {
|
||||
return Ok(None);
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce_raw);
|
||||
|
||||
let mut secret_body = SecretBody::new(net_packet.payload_mut())?;
|
||||
let tag = secret_body.tag();
|
||||
if tag.len() != 16 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "tag err"));
|
||||
}
|
||||
let finger = self.finger.calculate_finger(&nonce_raw, &secret_body);
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
}
|
||||
let tag: GenericArray<u8, U16> = Tag::clone_from_slice(tag);
|
||||
let rs = match &self.cipher {
|
||||
AesGcmEnum::AES128GCM(aes_gcm) => { aes_gcm.decrypt_in_place_detached(nonce, &[], secret_body.body_mut(), &tag) }
|
||||
AesGcmEnum::AES256GCM(aes_gcm) => { aes_gcm.decrypt_in_place_detached(nonce, &[], secret_body.body_mut(), &tag) }
|
||||
};
|
||||
if let Err(e) = rs {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("解密失败:{}", e)));
|
||||
}
|
||||
return Ok(Some(payload_len));
|
||||
net_packet.set_encrypt_flag(false);
|
||||
net_packet.set_data_len(net_packet.data_len() - ENCRYPTION_RESERVED)?;
|
||||
return Ok(());
|
||||
}
|
||||
/// net_packet 必须预留足够长度
|
||||
/// data_len是有效载荷的长度
|
||||
/// 返回加密后载荷的长度
|
||||
pub fn encrypt_ipv4(&self, payload_len: usize, net_packet: &mut NetPacket<&mut [u8]>) -> io::Result<Option<usize>> {
|
||||
match &self {
|
||||
Cipher::None => {
|
||||
return Ok(None);
|
||||
}
|
||||
_ => {}
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<()> {
|
||||
if net_packet.reserve() < ENCRYPTION_RESERVED {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "too short"));
|
||||
}
|
||||
let mut nonce = [0; 12];
|
||||
nonce[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce[8] = protocol::Protocol::IpTurn.into();
|
||||
nonce[9] = ip_turn_packet::Protocol::Ipv4.into();
|
||||
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce);
|
||||
let rs = match &self {
|
||||
Cipher::AesGCM128(cipher) => {
|
||||
cipher.encrypt_in_place_detached(nonce, &[], &mut net_packet.payload_mut()[..payload_len])
|
||||
}
|
||||
Cipher::AesGCM256(cipher) => {
|
||||
cipher.encrypt_in_place_detached(nonce, &[], &mut net_packet.payload_mut()[..payload_len])
|
||||
}
|
||||
Cipher::None => {
|
||||
return Ok(None);
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce_raw);
|
||||
let data_len = net_packet.data_len() + ENCRYPTION_RESERVED;
|
||||
net_packet.set_data_len(data_len)?;
|
||||
let mut secret_body = SecretBody::new(net_packet.payload_mut())?;
|
||||
secret_body.set_random(rand::thread_rng().next_u32());
|
||||
let rs = match &self.cipher {
|
||||
AesGcmEnum::AES128GCM(aes_gcm) => { aes_gcm.encrypt_in_place_detached(nonce, &[], secret_body.body_mut()) }
|
||||
AesGcmEnum::AES256GCM(aes_gcm) => { aes_gcm.encrypt_in_place_detached(nonce, &[], secret_body.body_mut()) }
|
||||
};
|
||||
return match rs {
|
||||
Ok(tag) => {
|
||||
if tag.len() != 16 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("加密tag长度错误:{}", tag.len())));
|
||||
}
|
||||
secret_body.set_tag(tag.as_slice())?;
|
||||
let finger = self.finger.calculate_finger(&nonce_raw, &secret_body);
|
||||
secret_body.set_finger(&finger)?;
|
||||
net_packet.set_encrypt_flag(true);
|
||||
net_packet.payload_mut()[payload_len..payload_len + 16].copy_from_slice(tag.as_slice());
|
||||
Ok(Some(payload_len + 16))
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
Err(io::Error::new(io::ErrorKind::Other, format!("加密失败:{}", e)))
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
use std::io;
|
||||
|
||||
use sha2::Digest;
|
||||
|
||||
use crate::protocol::{body::ENCRYPTION_RESERVED, body::SecretBody, NetPacket};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Finger {
|
||||
token: String,
|
||||
}
|
||||
|
||||
impl Finger {
|
||||
pub fn new(token: String) -> Self {
|
||||
Finger { token }
|
||||
}
|
||||
pub fn check_finger<B: AsRef<[u8]>>(&self, net_packet: &NetPacket<B>) -> io::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
}
|
||||
if net_packet.payload().len() < ENCRYPTION_RESERVED {
|
||||
log::error!("数据异常,长度小于{}",ENCRYPTION_RESERVED);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
}
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
let secret_body = SecretBody::new(net_packet.payload())?;
|
||||
let finger = self.calculate_finger(&nonce_raw, &secret_body);
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn calculate_finger<B: AsRef<[u8]>>(&self, nonce_raw: &[u8; 12], secret_body: &SecretBody<B>) -> [u8; 12] {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(secret_body.body());
|
||||
hasher.update(nonce_raw);
|
||||
hasher.update(secret_body.tag());
|
||||
hasher.update(&self.token);
|
||||
let key: [u8; 32] = hasher.finalize().into();
|
||||
return key[20..].try_into().unwrap();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
mod ring_cipher;
|
||||
#[cfg(feature = "ring-cipher")]
|
||||
pub use ring_cipher::Cipher;
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
mod aes_gcm_cipher;
|
||||
#[cfg(not(feature = "ring-cipher"))]
|
||||
pub use aes_gcm_cipher::Cipher;
|
||||
mod rsa_cipher;
|
||||
mod finger;
|
||||
mod aes_c;
|
||||
|
||||
pub use aes_c::Cipher;
|
||||
pub use finger::Finger;
|
||||
pub use rsa_cipher::RsaCipher;
|
||||
@@ -1,117 +1,118 @@
|
||||
|
||||
|
||||
use std::io;
|
||||
use rand::RngCore;
|
||||
use ring::aead;
|
||||
use ring::aead::{LessSafeKey, UnboundKey};
|
||||
use sha2::Digest;
|
||||
use crate::cipher::Finger;
|
||||
|
||||
use crate::protocol;
|
||||
use crate::protocol::{ip_turn_packet, NetPacket};
|
||||
use crate::protocol::NetPacket;
|
||||
use crate::protocol::body::{ENCRYPTION_RESERVED, SecretBody};
|
||||
|
||||
pub enum Cipher {
|
||||
#[derive(Clone)]
|
||||
pub struct AesGcmCipher {
|
||||
pub(crate) cipher: AesGcmEnum,
|
||||
pub(crate) finger: Finger,
|
||||
}
|
||||
|
||||
pub enum AesGcmEnum {
|
||||
AesGCM128(LessSafeKey, [u8; 16]),
|
||||
AesGCM256(LessSafeKey, [u8; 32]),
|
||||
None,
|
||||
}
|
||||
|
||||
impl Clone for Cipher {
|
||||
impl Clone for AesGcmEnum {
|
||||
fn clone(&self) -> Self {
|
||||
match &self {
|
||||
Cipher::AesGCM128(_, key) => {
|
||||
AesGcmEnum::AesGCM128(_, key) => {
|
||||
let c = LessSafeKey::new(UnboundKey::new(&aead::AES_128_GCM, key.as_slice()).unwrap());
|
||||
Cipher::AesGCM128(c, *key)
|
||||
AesGcmEnum::AesGCM128(c, *key)
|
||||
}
|
||||
Cipher::AesGCM256(_, key) => {
|
||||
AesGcmEnum::AesGCM256(_, key) => {
|
||||
let c = LessSafeKey::new(UnboundKey::new(&aead::AES_256_GCM, key.as_slice()).unwrap());
|
||||
Cipher::AesGCM256(c, *key)
|
||||
}
|
||||
Cipher::None => {
|
||||
Cipher::None
|
||||
AesGcmEnum::AesGCM256(c, *key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cipher {
|
||||
pub fn new(password: Option<String>) -> Self {
|
||||
if let Some(password) = password {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(password.as_bytes());
|
||||
let key: [u8; 32] = hasher.finalize().into();
|
||||
if password.len() < 8 {
|
||||
let c = LessSafeKey::new(UnboundKey::new(&aead::AES_128_GCM, &key[..16]).unwrap());
|
||||
Cipher::AesGCM128(c, key[..16].try_into().unwrap())
|
||||
} else {
|
||||
let c = LessSafeKey::new(UnboundKey::new(&aead::AES_256_GCM, &key).unwrap());
|
||||
Cipher::AesGCM256(c, key)
|
||||
}
|
||||
} else {
|
||||
Cipher::None
|
||||
impl AesGcmCipher {
|
||||
pub fn new_128(key: [u8; 16], finger: Finger) -> Self {
|
||||
let cipher = LessSafeKey::new(UnboundKey::new(&aead::AES_128_GCM, &key).unwrap());
|
||||
Self {
|
||||
cipher: AesGcmEnum::AesGCM128(cipher, key),
|
||||
finger,
|
||||
}
|
||||
}
|
||||
pub fn decrypt_ipv4(&self, net_packet: &mut NetPacket<&mut [u8]>) -> io::Result<Option<usize>> {
|
||||
match &self {
|
||||
Cipher::None => {
|
||||
return Ok(None);
|
||||
}
|
||||
_ => {}
|
||||
pub fn new_256(key: [u8; 32], finger: Finger) -> Self {
|
||||
let cipher = LessSafeKey::new(UnboundKey::new(&aead::AES_256_GCM, &key).unwrap());
|
||||
Self {
|
||||
cipher: AesGcmEnum::AesGCM256(cipher, key),
|
||||
finger,
|
||||
}
|
||||
}
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<()> {
|
||||
if !net_packet.is_encrypt() {
|
||||
//未加密的数据直接丢弃
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "not encrypt"));
|
||||
}
|
||||
if net_packet.payload().len() < 16 {
|
||||
log::error!("数据异常,长度小于16");
|
||||
if net_packet.payload().len() < ENCRYPTION_RESERVED {
|
||||
log::error!("数据异常,长度小于{}",ENCRYPTION_RESERVED);
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "data err"));
|
||||
}
|
||||
let mut nonce = [0; 12];
|
||||
nonce[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce[8] = protocol::Protocol::IpTurn.into();
|
||||
nonce[9] = ip_turn_packet::Protocol::Ipv4.into();
|
||||
let nonce = aead::Nonce::assume_unique_for_key(nonce);
|
||||
let payload_len = net_packet.payload().len() - 16;
|
||||
let rs = match &self {
|
||||
Cipher::AesGCM128(cipher, _) => {
|
||||
cipher.open_in_place(nonce, aead::Aad::empty(), net_packet.payload_mut())
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let nonce = aead::Nonce::assume_unique_for_key(nonce_raw);
|
||||
let mut secret_body = SecretBody::new(net_packet.payload_mut())?;
|
||||
let tag = secret_body.tag();
|
||||
if tag.len() != 16 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "tag err"));
|
||||
}
|
||||
let finger = self.finger.calculate_finger(&nonce_raw, &secret_body);
|
||||
if &finger != secret_body.finger() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "finger err"));
|
||||
}
|
||||
|
||||
let rs = match &self.cipher {
|
||||
AesGcmEnum::AesGCM128(cipher, _) => {
|
||||
cipher.open_in_place(nonce, aead::Aad::empty(), secret_body.en_body_mut())
|
||||
}
|
||||
Cipher::AesGCM256(cipher, _) => {
|
||||
cipher.open_in_place(nonce, aead::Aad::empty(), net_packet.payload_mut())
|
||||
}
|
||||
Cipher::None => {
|
||||
return Ok(None);
|
||||
AesGcmEnum::AesGCM256(cipher, _) => {
|
||||
cipher.open_in_place(nonce, aead::Aad::empty(), secret_body.en_body_mut())
|
||||
}
|
||||
};
|
||||
if let Err(e) = rs {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("解密失败:{}", e)));
|
||||
}
|
||||
return Ok(Some(payload_len));
|
||||
net_packet.set_encrypt_flag(false);
|
||||
net_packet.set_data_len(net_packet.data_len() - ENCRYPTION_RESERVED)?;
|
||||
return Ok(());
|
||||
}
|
||||
/// net_packet 必须预留足够长度
|
||||
/// data_len是有效载荷的长度
|
||||
/// 返回加密后载荷的长度
|
||||
pub fn encrypt_ipv4(&self, payload_len: usize, net_packet: &mut NetPacket<&mut [u8]>) -> io::Result<Option<usize>> {
|
||||
match &self {
|
||||
Cipher::None => {
|
||||
return Ok(None);
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<()> {
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
let nonce = aead::Nonce::assume_unique_for_key(nonce_raw);
|
||||
let data_len = net_packet.data_len() + ENCRYPTION_RESERVED;
|
||||
net_packet.set_data_len(data_len)?;
|
||||
let mut secret_body = SecretBody::new(net_packet.payload_mut())?;
|
||||
secret_body.set_random(rand::thread_rng().next_u32());
|
||||
|
||||
let rs = match &self.cipher {
|
||||
AesGcmEnum::AesGCM128(cipher, _) => {
|
||||
cipher.seal_in_place_separate_tag(nonce, aead::Aad::empty(), secret_body.body_mut())
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let mut nonce = [0; 12];
|
||||
nonce[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce[8] = protocol::Protocol::IpTurn.into();
|
||||
nonce[9] = ip_turn_packet::Protocol::Ipv4.into();
|
||||
let nonce = aead::Nonce::assume_unique_for_key(nonce);
|
||||
let rs = match &self {
|
||||
Cipher::AesGCM128(cipher, _) => {
|
||||
cipher.seal_in_place_separate_tag(nonce, aead::Aad::empty(), &mut net_packet.payload_mut()[..payload_len])
|
||||
}
|
||||
Cipher::AesGCM256(cipher, _) => {
|
||||
cipher.seal_in_place_separate_tag(nonce, aead::Aad::empty(), &mut net_packet.payload_mut()[..payload_len])
|
||||
}
|
||||
Cipher::None => {
|
||||
return Ok(None);
|
||||
AesGcmEnum::AesGCM256(cipher, _) => {
|
||||
cipher.seal_in_place_separate_tag(nonce, aead::Aad::empty(), secret_body.body_mut())
|
||||
}
|
||||
};
|
||||
return match rs {
|
||||
@@ -120,9 +121,11 @@ impl Cipher {
|
||||
if tag.len() != 16 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("加密tag长度错误:{}", tag.len())));
|
||||
}
|
||||
secret_body.set_tag(tag)?;
|
||||
let finger = self.finger.calculate_finger(&nonce_raw, &secret_body);
|
||||
secret_body.set_finger(&finger)?;
|
||||
net_packet.set_encrypt_flag(true);
|
||||
net_packet.payload_mut()[payload_len..payload_len + 16].copy_from_slice(tag);
|
||||
Ok(Some(payload_len + 16))
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
Err(io::Error::new(io::ErrorKind::Other, format!("加密失败:{}", e)))
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
use std::io;
|
||||
use rand::Rng;
|
||||
use rsa::pkcs8::der::Decode;
|
||||
use rsa::{PublicKey, RsaPublicKey};
|
||||
use spki::{DecodePublicKey, EncodePublicKey};
|
||||
use crate::protocol::body::{ENCRYPTION_RESERVED, RsaSecretBody};
|
||||
use crate::protocol::NetPacket;
|
||||
use sha2::Digest;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RsaCipher {
|
||||
inner: Inner,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Inner {
|
||||
public_key: RsaPublicKey,
|
||||
}
|
||||
|
||||
impl RsaCipher {
|
||||
pub fn new(der: &[u8]) -> io::Result<Self> {
|
||||
match RsaPublicKey::from_public_key_der(der) {
|
||||
Ok(public_key) => {
|
||||
let inner = Inner {
|
||||
public_key,
|
||||
};
|
||||
Ok(Self {
|
||||
inner
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
Err(io::Error::new(io::ErrorKind::Other, format!("from_public_key_der failed {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn finger(&self) -> io::Result<String> {
|
||||
match self.inner.public_key.to_public_key_der() {
|
||||
Ok(der) => {
|
||||
match rsa::pkcs8::SubjectPublicKeyInfo::from_der(der.as_bytes()) {
|
||||
Ok(spki) => {
|
||||
match spki.fingerprint_base64() {
|
||||
Ok(finger) => {
|
||||
Ok(finger)
|
||||
}
|
||||
Err(e) => {
|
||||
Err(io::Error::new(io::ErrorKind::Other, format!("fingerprint_base64 error {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
Err(io::Error::new(io::ErrorKind::Other, format!("from_der error {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
Err(io::Error::new(io::ErrorKind::Other, format!("to_public_key_der error {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RsaCipher {
|
||||
/// net_packet 必须预留足够长度
|
||||
pub fn encrypt<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> io::Result<NetPacket<Vec<u8>>> {
|
||||
if net_packet.reserve() < ENCRYPTION_RESERVED {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "too short"));
|
||||
}
|
||||
let data_len = net_packet.data_len() + ENCRYPTION_RESERVED;
|
||||
net_packet.set_data_len(data_len)?;
|
||||
let mut nonce_raw = [0; 12];
|
||||
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
|
||||
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
|
||||
nonce_raw[8] = net_packet.protocol().into();
|
||||
nonce_raw[9] = net_packet.transport_protocol();
|
||||
nonce_raw[10] = net_packet.is_gateway() as u8;
|
||||
nonce_raw[11] = net_packet.source_ttl();
|
||||
|
||||
let mut secret_body = RsaSecretBody::new(net_packet.payload_mut())?;
|
||||
let mut rng = rand::thread_rng();
|
||||
rng.fill(secret_body.random_mut());
|
||||
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(secret_body.body());
|
||||
hasher.update(nonce_raw);
|
||||
let key: [u8; 32] = hasher.finalize().into();
|
||||
secret_body.set_finger(&key[16..])?;
|
||||
match self.inner.public_key.encrypt(&mut rng, rsa::PaddingScheme::PKCS1v15Encrypt, secret_body.buffer()) {
|
||||
Ok(enc_data) => {
|
||||
let mut net_packet_e = NetPacket::new(vec![0; 12 + enc_data.len()])?;
|
||||
net_packet_e.buffer_mut()[..12].copy_from_slice(&net_packet.buffer()[..12]);
|
||||
net_packet_e.set_payload(&enc_data)?;
|
||||
Ok(net_packet_e)
|
||||
}
|
||||
Err(e) => {
|
||||
Err(io::Error::new(io::ErrorKind::Other, format!("encrypt failed {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
-30
@@ -6,6 +6,7 @@ use std::time::Duration;
|
||||
use crossbeam_skiplist::SkipMap;
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use parking_lot::Mutex;
|
||||
use rand::Rng;
|
||||
use tokio::net::{TcpStream, UdpSocket};
|
||||
use tokio::sync::mpsc::channel;
|
||||
|
||||
@@ -14,11 +15,12 @@ use crate::channel::channel::{Channel, Context};
|
||||
use crate::channel::idle::Idle;
|
||||
use crate::channel::punch::{NatInfo, Punch};
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::cipher::Cipher;
|
||||
use crate::cipher::{Cipher, RsaCipher};
|
||||
use crate::core::status::VntStatusManger;
|
||||
use crate::error::Error;
|
||||
use crate::external_route::{AllowExternalRoute, ExternalRoute};
|
||||
use crate::handle::{ConnectStatus, CurrentDeviceInfo, heartbeat_handler, PeerDeviceInfo, punch_handler, registration_handler};
|
||||
use crate::handle::{ConnectStatus, CurrentDeviceInfo, handshake_handler, heartbeat_handler, PeerDeviceInfo, punch_handler, registration_handler};
|
||||
use crate::handle::handshake_handler::HandshakeEnum;
|
||||
use crate::handle::recv_handler::ChannelDataHandler;
|
||||
use crate::handle::registration_handler::{RegResponse, ReqEnum};
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
@@ -35,7 +37,7 @@ pub mod sync;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vnt {
|
||||
name: String,
|
||||
config: Config,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
context: Context,
|
||||
vnt_status_manager: VntStatusManger,
|
||||
@@ -55,33 +57,54 @@ pub struct VntUtil {
|
||||
main_tcp_channel: Option<TcpStream>,
|
||||
response: Option<RegResponse>,
|
||||
iface: Option<(DeviceWriter, DeviceReader)>,
|
||||
server_cipher: Cipher,
|
||||
rsa_cipher: Option<RsaCipher>,
|
||||
}
|
||||
|
||||
impl VntUtil {
|
||||
pub async fn new(config: Config) -> io::Result<VntUtil> {
|
||||
let main_channel = UdpSocket::bind("0.0.0.0:0").await?;
|
||||
let server_cipher = if config.server_encrypt {
|
||||
let mut key = [0 as u8; 32];
|
||||
rand::thread_rng().fill(&mut key);
|
||||
Cipher::new_key(key, config.token.clone())?
|
||||
} else {
|
||||
Cipher::None
|
||||
};
|
||||
Ok(VntUtil {
|
||||
config,
|
||||
main_channel,
|
||||
main_tcp_channel: None,
|
||||
response: None,
|
||||
iface: None,
|
||||
server_cipher,
|
||||
rsa_cipher: None,
|
||||
})
|
||||
}
|
||||
pub async fn connect(&mut self) -> Result<RegResponse, ReqEnum> {
|
||||
///链接
|
||||
pub async fn connect(&mut self) -> io::Result<()> {
|
||||
if self.config.tcp {
|
||||
match TcpStream::connect(self.config.server_address).await {
|
||||
Ok(tcp) => {
|
||||
let _ = self.main_tcp_channel.insert(tcp);
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(ReqEnum::Other(format!("connect error:{}", e)));
|
||||
}
|
||||
}
|
||||
let tcp = TcpStream::connect(self.config.server_address).await?;
|
||||
let _ = self.main_tcp_channel.insert(tcp);
|
||||
}
|
||||
match registration_handler::registration(&self.main_channel, self.main_tcp_channel.as_mut(), self.config.server_address,
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///握手 用于获取公钥
|
||||
pub async fn handshake(&mut self) -> Result<Option<RsaCipher>, HandshakeEnum> {
|
||||
let rsa_cipher = handshake_handler::handshake(&self.main_channel, self.main_tcp_channel.as_mut(), self.config.server_address, self.config.server_encrypt).await?;
|
||||
self.rsa_cipher = rsa_cipher.clone();
|
||||
Ok(rsa_cipher)
|
||||
}
|
||||
/// 加密握手 用于同步密钥
|
||||
pub async fn secret_handshake(&mut self) -> Result<(), HandshakeEnum> {
|
||||
handshake_handler::secret_handshake(&self.main_channel, self.main_tcp_channel.as_mut(), self.config.server_address, self.rsa_cipher.as_ref().unwrap(), &self.server_cipher,self.config.token.clone()).await
|
||||
}
|
||||
/// 注册
|
||||
pub async fn register(&mut self) -> Result<RegResponse, ReqEnum> {
|
||||
match registration_handler::registration(&self.main_channel, self.main_tcp_channel.as_mut(), &self.server_cipher, self.config.server_address,
|
||||
self.config.token.clone(), self.config.device_id.clone(),
|
||||
self.config.name.clone(), self.config.ip.unwrap_or(Ipv4Addr::UNSPECIFIED)).await {
|
||||
self.config.name.clone(), self.config.ip.unwrap_or(Ipv4Addr::UNSPECIFIED),self.config.password.is_some()).await {
|
||||
Ok(res) => {
|
||||
let _ = self.response.insert(res.clone());
|
||||
Ok(res)
|
||||
@@ -149,9 +172,9 @@ impl VntUtil {
|
||||
res
|
||||
}
|
||||
};
|
||||
let config = self.config;
|
||||
let config = self.config.clone();
|
||||
let vnt_status_manager = VntStatusManger::new();
|
||||
let cipher = Cipher::new(config.password.clone());
|
||||
let client_cipher = Cipher::new_password(config.password.clone(), config.token.clone());
|
||||
let virtual_ip = response.virtual_ip;
|
||||
let virtual_gateway = response.virtual_gateway;
|
||||
let virtual_netmask = response.virtual_netmask;
|
||||
@@ -170,9 +193,9 @@ impl VntUtil {
|
||||
let idle = Idle::new(Duration::from_secs(16), context.clone());
|
||||
let channel_sender = ChannelSender::new(context.clone());
|
||||
|
||||
let register = Arc::new(registration_handler::Register::new(channel_sender.clone(),
|
||||
let register = Arc::new(registration_handler::Register::new(self.server_cipher.clone(), channel_sender.clone(),
|
||||
config.server_address, config.token.clone(),
|
||||
config.device_id.clone(), config.name.clone()));
|
||||
config.device_id.clone(), config.name.clone(),config.password.is_some()));
|
||||
let device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>> = Arc::new(Mutex::new((response.epoch, response.device_info_list)));
|
||||
let peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>> = Arc::new(SkipMap::new());
|
||||
let connect_status = Arc::new(AtomicCell::new(ConnectStatus::Connected));
|
||||
@@ -190,7 +213,7 @@ impl VntUtil {
|
||||
let (tcp_proxy, udp_proxy, ip_proxy_map) = if config.out_ips.is_empty() {
|
||||
(None, None, None)
|
||||
} else {
|
||||
let (tcp_proxy, udp_proxy, ip_proxy_map) = crate::ip_proxy::init_proxy(channel_sender.clone(), current_device.clone()).await?;
|
||||
let (tcp_proxy, udp_proxy, ip_proxy_map) = crate::ip_proxy::init_proxy(channel_sender.clone(), current_device.clone(), client_cipher.clone()).await?;
|
||||
(Some(tcp_proxy), Some(udp_proxy), Some(ip_proxy_map))
|
||||
};
|
||||
let out_external_route = AllowExternalRoute::new(config.out_ips);
|
||||
@@ -203,21 +226,22 @@ impl VntUtil {
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
if config.tap {
|
||||
tap_handler::start(vnt_status_manager.worker("tap_handler"), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), client_cipher.clone(), self.server_cipher.clone());
|
||||
} else {
|
||||
tun_handler::start(vnt_status_manager.worker("tun_handler"), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), client_cipher.clone(), self.server_cipher.clone()).await;
|
||||
}
|
||||
#[cfg(any(target_os = "android"))]
|
||||
tun_handler::start(vnt_status_manager.worker("android tun_handler"), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone()).await;
|
||||
|
||||
//外部数据接收处理
|
||||
let channel_recv_handler = ChannelDataHandler::new(current_device.clone(), device_list.clone(),
|
||||
register.clone(), nat_test.clone(), igmp_server,
|
||||
device_writer.clone(), connect_status.clone(),
|
||||
peer_nat_info_map.clone(), ip_proxy_map, out_external_route,
|
||||
cone_sender, symmetric_sender, cipher, config.relay);
|
||||
cone_sender, symmetric_sender, client_cipher.clone(),
|
||||
self.server_cipher.clone(), self.rsa_cipher.clone(), config.relay,config.token.clone());
|
||||
{
|
||||
let channel = Channel::new(context.clone(), channel_recv_handler);
|
||||
let channel_worker = vnt_status_manager.worker("channel_worker");
|
||||
@@ -238,20 +262,21 @@ impl VntUtil {
|
||||
let device_list = device_list.clone();
|
||||
let current_device = current_device.clone();
|
||||
// 定时心跳
|
||||
heartbeat_handler::start_heartbeat(other_worker.worker("heartbeat"), channel_sender.clone(), device_list.clone(), current_device.clone(), config.server_address_str);
|
||||
heartbeat_handler::start_heartbeat(other_worker.worker("heartbeat"), channel_sender.clone(), device_list.clone(),
|
||||
current_device.clone(), config.server_address_str, client_cipher.clone(), self.server_cipher.clone());
|
||||
// 空闲检查
|
||||
heartbeat_handler::start_idle(other_worker.worker("idle"), idle, channel_sender.clone());
|
||||
if !config.relay {
|
||||
// 打洞处理
|
||||
punch_handler::start(other_worker.worker("cone_receiver"), cone_receiver, punch.clone(), current_device.clone());
|
||||
punch_handler::start(other_worker.worker("symmetric_receiver"), symmetric_receiver, punch, current_device.clone());
|
||||
punch_handler::start(other_worker.worker("cone_receiver"), cone_receiver, punch.clone(), current_device.clone(), client_cipher.clone());
|
||||
punch_handler::start(other_worker.worker("symmetric_receiver"), symmetric_receiver, punch, current_device.clone(), client_cipher.clone());
|
||||
tokio::spawn(punch_handler::start_punch(other_worker, nat_test,
|
||||
device_list, channel_sender, current_device));
|
||||
device_list, channel_sender, current_device, client_cipher.clone()));
|
||||
}
|
||||
}
|
||||
context.switch(nat_test.nat_info().nat_type);
|
||||
Ok(Vnt {
|
||||
name: config.name,
|
||||
config:self.config,
|
||||
current_device,
|
||||
context,
|
||||
vnt_status_manager,
|
||||
@@ -266,7 +291,13 @@ impl VntUtil {
|
||||
|
||||
impl Vnt {
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
&self.config.name
|
||||
}
|
||||
pub fn server_encrypt(&self) -> bool {
|
||||
self.config.server_encrypt
|
||||
}
|
||||
pub fn client_encrypt(&self) -> bool {
|
||||
self.config.password.is_some()
|
||||
}
|
||||
pub fn current_device(&self) -> CurrentDeviceInfo {
|
||||
self.current_device.load()
|
||||
@@ -344,6 +375,7 @@ pub struct Config {
|
||||
pub tcp: bool,
|
||||
pub ip: Option<Ipv4Addr>,
|
||||
pub relay: bool,
|
||||
pub server_encrypt: bool,
|
||||
}
|
||||
|
||||
|
||||
@@ -357,7 +389,7 @@ impl Config {
|
||||
in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32)>,
|
||||
password: Option<String>, simulate_multicast: bool, mtu: Option<u16>, tcp: bool,
|
||||
ip: Option<Ipv4Addr>,
|
||||
relay: bool, ) -> Self {
|
||||
relay: bool, server_encrypt: bool, ) -> Self {
|
||||
for x in stun_server.iter_mut() {
|
||||
if !x.contains(":") {
|
||||
x.push_str(":3478");
|
||||
@@ -379,6 +411,7 @@ impl Config {
|
||||
tcp,
|
||||
ip,
|
||||
relay,
|
||||
server_encrypt,
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -2,7 +2,9 @@ use std::io;
|
||||
use std::ops::Deref;
|
||||
use std::time::Duration;
|
||||
use tokio::runtime::Runtime;
|
||||
use crate::cipher::RsaCipher;
|
||||
use crate::core::{Config, Vnt, VntUtil};
|
||||
use crate::handle::handshake_handler::HandshakeEnum;
|
||||
use crate::handle::registration_handler::{RegResponse, ReqEnum};
|
||||
|
||||
pub struct VntUtilSync {
|
||||
@@ -24,9 +26,18 @@ impl VntUtilSync {
|
||||
runtime,
|
||||
})
|
||||
}
|
||||
pub fn connect(&mut self) -> Result<RegResponse, ReqEnum> {
|
||||
pub fn connect(&mut self) -> io::Result<()> {
|
||||
self.runtime.block_on(self.vnt_util.connect())
|
||||
}
|
||||
pub fn handshake(&mut self) -> Result<Option<RsaCipher>, HandshakeEnum> {
|
||||
self.runtime.block_on(self.vnt_util.handshake())
|
||||
}
|
||||
pub fn secret_handshake(&mut self) -> Result<(), HandshakeEnum> {
|
||||
self.runtime.block_on(self.vnt_util.secret_handshake())
|
||||
}
|
||||
pub fn register(&mut self) -> Result<RegResponse, ReqEnum> {
|
||||
self.runtime.block_on(self.vnt_util.register())
|
||||
}
|
||||
#[cfg(any(target_os = "android"))]
|
||||
pub fn create_iface(&mut self, vpn_fd: i32) {
|
||||
self.vnt_util.create_iface(vpn_fd)
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
use std::net::SocketAddr;
|
||||
use std::time::Duration;
|
||||
|
||||
use protobuf::Message;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::{TcpStream, UdpSocket};
|
||||
|
||||
use crate::channel::channel::Context;
|
||||
use crate::cipher::{Cipher, RsaCipher};
|
||||
use crate::proto::message::{HandshakeRequest, HandshakeResponse, SecretHandshakeRequest};
|
||||
use crate::protocol::{MAX_TTL, NetPacket, Protocol, service_packet, Version};
|
||||
use crate::protocol::body::ENCRYPTION_RESERVED;
|
||||
|
||||
const VERSION: &'static str = "1.2.0";
|
||||
|
||||
pub enum HandshakeEnum {
|
||||
NotSecret,
|
||||
KeyError,
|
||||
Timeout,
|
||||
ServerError(String),
|
||||
Other(String),
|
||||
}
|
||||
|
||||
fn handshake_request_packet(secret: bool) -> crate::Result<NetPacket<Vec<u8>>> {
|
||||
let mut request = HandshakeRequest::new();
|
||||
request.secret = secret;
|
||||
request.version = VERSION.to_string();
|
||||
let bytes = request.write_to_bytes()?;
|
||||
let buf = vec![0u8; 12 + bytes.len()];
|
||||
let mut net_packet = NetPacket::new(buf)?;
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_gateway_flag(true);
|
||||
net_packet.set_protocol(Protocol::Service);
|
||||
net_packet.set_transport_protocol(service_packet::Protocol::HandshakeRequest.into());
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
net_packet.set_payload(&bytes)?;
|
||||
Ok(net_packet)
|
||||
}
|
||||
|
||||
fn secret_handshake_request_packet(rsa_cipher: &RsaCipher, token: String, key: &[u8]) -> crate::Result<NetPacket<Vec<u8>>> {
|
||||
let mut request = SecretHandshakeRequest::new();
|
||||
request.token = token;
|
||||
request.key = key.to_vec();
|
||||
let bytes = request.write_to_bytes()?;
|
||||
let mut net_packet = NetPacket::new_encrypt(vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED])?;
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_gateway_flag(true);
|
||||
net_packet.set_protocol(Protocol::Service);
|
||||
net_packet.set_transport_protocol(service_packet::Protocol::SecretHandshakeRequest.into());
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
net_packet.set_payload(&bytes)?;
|
||||
Ok(rsa_cipher.encrypt(&mut net_packet)?)
|
||||
}
|
||||
|
||||
/// 第一次握手,拿到公钥
|
||||
pub async fn handshake(main_channel: &UdpSocket, main_tcp_channel: Option<&mut TcpStream>,
|
||||
server_address: SocketAddr, secret: bool) -> Result<Option<RsaCipher>, HandshakeEnum> {
|
||||
let request_packet = handshake_request_packet(secret).unwrap();
|
||||
let send_buf = request_packet.buffer();
|
||||
let mut recv_buf = [0u8; 10240];
|
||||
let len = send_recv(main_channel, main_tcp_channel, server_address, send_buf, &mut recv_buf).await?;
|
||||
let net_packet = match NetPacket::new(&recv_buf[..len]) {
|
||||
Ok(net_packet) => {
|
||||
net_packet
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(HandshakeEnum::Other(format!("net_packet {}", e)));
|
||||
}
|
||||
};
|
||||
match net_packet.protocol() {
|
||||
Protocol::Service => {
|
||||
match service_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
service_packet::Protocol::HandshakeResponse => {
|
||||
match HandshakeResponse::parse_from_bytes(net_packet.payload()) {
|
||||
Ok(response) => {
|
||||
if !response.secret && secret {
|
||||
//客户端要加密,服务端不支持加密
|
||||
return Err(HandshakeEnum::NotSecret);
|
||||
}
|
||||
if secret {
|
||||
//转换公钥
|
||||
match RsaCipher::new(&response.public_key) {
|
||||
Ok(rsa) => {
|
||||
match rsa.finger() {
|
||||
Ok(finger) => {
|
||||
if finger != response.key_finger {
|
||||
return Err(HandshakeEnum::Other("finger error".to_string()));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(HandshakeEnum::Other(format!("finger {}", e)));
|
||||
}
|
||||
}
|
||||
Ok(Some(rsa))
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(HandshakeEnum::Other(format!("RsaCipher {}", e)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(HandshakeEnum::Other(format!("parse_from_bytes {}", e)));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(HandshakeEnum::Other("not match".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(HandshakeEnum::Other("not match".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_recv(main_channel: &UdpSocket, main_tcp_channel: Option<&mut TcpStream>,
|
||||
server_address: SocketAddr, send_buf: &[u8], recv_buf: &mut [u8]) -> Result<usize, HandshakeEnum> {
|
||||
if let Some(main_tcp_channel) = main_tcp_channel {
|
||||
let mut head = [0; 4];
|
||||
let len = send_buf.len();
|
||||
head[2] = (len >> 8) as u8;
|
||||
head[3] = (len & 0xFF) as u8;
|
||||
if let Err(e) = main_tcp_channel.write_all(&head).await {
|
||||
return Err(HandshakeEnum::Other(format!("send error:{}", e)));
|
||||
}
|
||||
if let Err(e) = main_tcp_channel.write_all(send_buf).await {
|
||||
return Err(HandshakeEnum::Other(format!("send error:{}", e)));
|
||||
}
|
||||
if let Err(e) = main_tcp_channel.read_exact(&mut head).await {
|
||||
return Err(HandshakeEnum::Other(format!("read error:{}", e)));
|
||||
}
|
||||
let len = (((head[2] as u16) << 8) | head[3] as u16) as usize;
|
||||
if len > recv_buf.len() {
|
||||
return Err(HandshakeEnum::Other("too long".to_string()));
|
||||
}
|
||||
if let Err(e) = main_tcp_channel.read_exact(&mut recv_buf[..len]).await {
|
||||
return Err(HandshakeEnum::Other(format!("read error:{}", e)));
|
||||
}
|
||||
Ok(len)
|
||||
} else {
|
||||
if let Err(e) = main_channel.send_to(send_buf, server_address).await {
|
||||
return Err(HandshakeEnum::Other(format!("send error:{}", e)));
|
||||
}
|
||||
match tokio::time::timeout(Duration::from_millis(300), main_channel.recv_from(recv_buf)).await {
|
||||
Ok(rs) => {
|
||||
match rs {
|
||||
Ok((len, addr)) => {
|
||||
if server_address != addr {
|
||||
return Err(HandshakeEnum::Other(format!("invalid data,from {}", addr)));
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(HandshakeEnum::Other(format!("receiver error:{}", e)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
return Err(HandshakeEnum::Timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 第二次握手,同步对称密钥,后续将使用对称加密
|
||||
pub async fn secret_handshake(main_channel: &UdpSocket, main_tcp_channel: Option<&mut TcpStream>,
|
||||
server_address: SocketAddr, rsa_cipher: &RsaCipher, server_cipher: &Cipher, token: String)
|
||||
-> Result<(), HandshakeEnum> {
|
||||
let secret_packet = match secret_handshake_request_packet(rsa_cipher, token, server_cipher.key().unwrap()) {
|
||||
Ok(secret_packet) => {
|
||||
secret_packet
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(HandshakeEnum::Other(format!("secret_handshake_request_packet {}", e)));
|
||||
}
|
||||
};
|
||||
let send_buf = secret_packet.buffer();
|
||||
let mut recv_buf = [0u8; 10240];
|
||||
let len = send_recv(main_channel, main_tcp_channel, server_address, send_buf, &mut recv_buf).await?;
|
||||
let mut net_packet = match NetPacket::new(&mut recv_buf[..len]) {
|
||||
Ok(net_packet) => { net_packet }
|
||||
Err(e) => {
|
||||
return Err(HandshakeEnum::Other(format!("secret_net_packet {}", e)));
|
||||
}
|
||||
};
|
||||
match server_cipher.decrypt_ipv4(&mut net_packet) {
|
||||
Ok(_) => {
|
||||
if net_packet.is_gateway() && net_packet.protocol() == Protocol::Service
|
||||
&& service_packet::Protocol::from(net_packet.transport_protocol()) ==
|
||||
service_packet::Protocol::SecretHandshakeResponse {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(HandshakeEnum::Other("not match".to_string()))
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
Err(HandshakeEnum::Other(format!("decrypt_ipv4 {}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn secret_handshake_req(context: &Context,
|
||||
server_address: SocketAddr, rsa_cipher: &RsaCipher, server_cipher: &Cipher, token: String, ) -> crate::Result<()> {
|
||||
let secret_packet = secret_handshake_request_packet(rsa_cipher, token, server_cipher.key().unwrap())?;
|
||||
context.send_main(secret_packet.buffer(), server_address).await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -9,12 +9,14 @@ use rand::prelude::SliceRandom;
|
||||
use crate::channel::idle::Idle;
|
||||
use crate::channel::Route;
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::cipher::Cipher;
|
||||
use crate::core::status::VntWorker;
|
||||
|
||||
|
||||
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
|
||||
use crate::protocol::control_packet::PingPacket;
|
||||
use crate::protocol::{control_packet, MAX_TTL, NetPacket, Protocol, Version};
|
||||
use crate::protocol::body::ENCRYPTION_RESERVED;
|
||||
|
||||
pub fn start_idle(mut worker: VntWorker, idle: Idle, sender: ChannelSender) {
|
||||
tokio::spawn(async move {
|
||||
@@ -50,13 +52,15 @@ pub fn start_heartbeat(
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
server_address_str: String,
|
||||
client_cipher: Cipher,
|
||||
server_cipher: Cipher,
|
||||
) {
|
||||
tokio::spawn(async move {
|
||||
tokio::select! {
|
||||
_=worker.stop_wait()=>{
|
||||
return;
|
||||
}
|
||||
rs=start_heartbeat_(sender, device_list, current_device,server_address_str)=>{
|
||||
rs=start_heartbeat_(sender, device_list, current_device,server_address_str,client_cipher,server_cipher)=>{
|
||||
if let Err(e) = rs {
|
||||
log::warn!("心跳任务停止:{:?}", e);
|
||||
}
|
||||
@@ -66,11 +70,29 @@ pub fn start_heartbeat(
|
||||
});
|
||||
}
|
||||
|
||||
fn set_now_time(packet: &mut NetPacket<[u8; 16]>) -> io::Result<()> {
|
||||
let current_time = crate::handle::now_time() as u16;
|
||||
let mut ping = PingPacket::new(packet.payload_mut())?;
|
||||
ping.set_time(current_time);
|
||||
Ok(())
|
||||
|
||||
fn heartbeat_packet( device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>,client_cipher: &Cipher, server_cipher: &Cipher, gateway: bool, src: Ipv4Addr, dest: Ipv4Addr) -> NetPacket<[u8; 48]> {
|
||||
let mut net_packet = NetPacket::new_encrypt([0u8; 12 + 4 + ENCRYPTION_RESERVED]).unwrap();
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_protocol(Protocol::Control);
|
||||
net_packet.set_transport_protocol(control_packet::Protocol::Ping.into());
|
||||
//只寻找两跳以内能到的目标
|
||||
net_packet.first_set_ttl(2);
|
||||
net_packet.set_source(src);
|
||||
net_packet.set_destination(dest);
|
||||
{
|
||||
let mut ping = PingPacket::new(net_packet.payload_mut()).unwrap();
|
||||
let epoch = { device_list.lock().0 };
|
||||
ping.set_epoch(epoch);
|
||||
ping.set_time( crate::handle::now_time() as u16);
|
||||
}
|
||||
if gateway {
|
||||
net_packet.set_gateway_flag(true);
|
||||
server_cipher.encrypt_ipv4(&mut net_packet).unwrap();
|
||||
} else {
|
||||
client_cipher.encrypt_ipv4(&mut net_packet).unwrap();
|
||||
}
|
||||
net_packet
|
||||
}
|
||||
|
||||
async fn start_heartbeat_(
|
||||
@@ -78,22 +100,19 @@ async fn start_heartbeat_(
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
server_address_str: String,
|
||||
client_cipher: Cipher,
|
||||
server_cipher: Cipher,
|
||||
) -> io::Result<()> {
|
||||
let mut net_packet = NetPacket::new([0u8; 16])?;
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_protocol(Protocol::Control);
|
||||
net_packet.set_transport_protocol(control_packet::Protocol::Ping.into());
|
||||
//只寻找两跳以内能到的目标
|
||||
net_packet.first_set_ttl(2);
|
||||
let mut count = 0;
|
||||
loop {
|
||||
if sender.is_close() {
|
||||
return Ok(());
|
||||
}
|
||||
let mut current_dev = current_device.load();
|
||||
if count % 10 == 0 {
|
||||
let mut packet = NetPacket::new([0; 12])?;
|
||||
if count % 20 == 2 {
|
||||
let mut packet = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED])?;
|
||||
packet.set_version(Version::V1);
|
||||
packet.set_gateway_flag(true);
|
||||
packet.set_protocol(Protocol::Control);
|
||||
packet.set_transport_protocol(
|
||||
control_packet::Protocol::AddrRequest.into(),
|
||||
@@ -101,6 +120,7 @@ async fn start_heartbeat_(
|
||||
packet.first_set_ttl(MAX_TTL);
|
||||
packet.set_source(current_dev.virtual_ip());
|
||||
packet.set_destination(current_dev.virtual_gateway);
|
||||
server_cipher.encrypt_ipv4(&mut packet)?;
|
||||
let _ = sender.send_main_udp(packet.buffer(), current_dev.connect_server).await;
|
||||
}
|
||||
if count % 20 == 19 {
|
||||
@@ -116,15 +136,9 @@ async fn start_heartbeat_(
|
||||
}
|
||||
}
|
||||
}
|
||||
net_packet.set_source(current_dev.virtual_ip());
|
||||
{
|
||||
let mut ping = PingPacket::new(net_packet.payload_mut())?;
|
||||
let epoch = { device_list.lock().0 };
|
||||
ping.set_epoch(epoch);
|
||||
}
|
||||
set_now_time(&mut net_packet)?;
|
||||
net_packet.set_destination(current_dev.virtual_gateway());
|
||||
if let Err(e) = sender.send_main(net_packet.buffer(), current_dev.connect_server).await
|
||||
let src = current_dev.virtual_ip();
|
||||
let server_packet = heartbeat_packet(&device_list,&client_cipher, &server_cipher, true, src, current_dev.virtual_gateway);
|
||||
if let Err(e) = sender.send_main(server_packet.buffer(), current_dev.connect_server).await
|
||||
{
|
||||
log::warn!(
|
||||
"connect_server:{:?},e:{:?}",
|
||||
@@ -139,16 +153,15 @@ async fn start_heartbeat_(
|
||||
if peer.virtual_ip == current_dev.virtual_ip {
|
||||
continue;
|
||||
}
|
||||
set_now_time(&mut net_packet)?;
|
||||
net_packet.set_destination(peer.virtual_ip);
|
||||
let client_packet = heartbeat_packet(&device_list,&client_cipher, &server_cipher, false, src, peer.virtual_ip);
|
||||
if let Some(route) = sender.route_one(&peer.virtual_ip) {
|
||||
let _ = sender.send_by_key(net_packet.buffer(), &route.route_key()).await;
|
||||
let _ = sender.send_by_key(client_packet.buffer(), &route.route_key()).await;
|
||||
if route.is_p2p() {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
//没有直连路由则发送到网关
|
||||
let _ = sender.send_main(net_packet.buffer(), current_dev.connect_server).await;
|
||||
let _ = sender.send_main(client_packet.buffer(), current_dev.connect_server).await;
|
||||
}
|
||||
|
||||
//再随机发送到其他地址,看有没有客户端符合转发条件
|
||||
@@ -161,8 +174,7 @@ async fn start_heartbeat_(
|
||||
'a: for (peer_ip, route_list) in route_list.iter() {
|
||||
for route in route_list {
|
||||
if peer_ip != &peer.virtual_ip && route.is_p2p() {
|
||||
set_now_time(&mut net_packet)?;
|
||||
let _ = sender.try_send_by_key(net_packet.buffer(), &route.route_key());
|
||||
let _ = sender.try_send_by_key(client_packet.buffer(), &route.route_key());
|
||||
num += 1;
|
||||
break;
|
||||
}
|
||||
@@ -175,10 +187,12 @@ async fn start_heartbeat_(
|
||||
}
|
||||
} else {
|
||||
for (peer_ip, route_list) in sender.route_table().iter() {
|
||||
net_packet.set_destination(*peer_ip);
|
||||
if peer_ip == ¤t_dev.virtual_gateway {
|
||||
continue;
|
||||
}
|
||||
let client_packet = heartbeat_packet(&device_list,&client_cipher, &server_cipher, false, src, *peer_ip);
|
||||
for route in route_list {
|
||||
set_now_time(&mut net_packet)?;
|
||||
if let Err(e) = sender.send_by_key(net_packet.buffer(), &route.route_key()).await {
|
||||
if let Err(e) = sender.send_by_key(client_packet.buffer(), &route.route_key()).await {
|
||||
log::warn!("peer_ip:{:?},route:{:?},e:{:?}", peer_ip, route, e);
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(2)).await;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::net::{Ipv4Addr, SocketAddr};
|
||||
|
||||
pub mod handshake_handler;
|
||||
pub mod heartbeat_handler;
|
||||
pub mod punch_handler;
|
||||
pub mod recv_handler;
|
||||
@@ -26,14 +27,16 @@ pub struct PeerDeviceInfo {
|
||||
pub virtual_ip: Ipv4Addr,
|
||||
pub name: String,
|
||||
pub status: PeerDeviceStatus,
|
||||
pub client_secret: bool,
|
||||
}
|
||||
|
||||
impl PeerDeviceInfo {
|
||||
pub fn new(virtual_ip: Ipv4Addr, name: String, status: u8) -> Self {
|
||||
pub fn new(virtual_ip: Ipv4Addr, name: String, status: u8,client_secret: bool) -> Self {
|
||||
Self {
|
||||
virtual_ip,
|
||||
name,
|
||||
status: PeerDeviceStatus::from(status),
|
||||
client_secret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,16 @@ use std::io;
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
use crate::channel::punch::{NatInfo, Punch};
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::cipher::Cipher;
|
||||
use crate::core::status::VntWorker;
|
||||
use crate::protocol::body::ENCRYPTION_RESERVED;
|
||||
|
||||
pub fn start(mut worker: VntWorker, receiver: Receiver<(Ipv4Addr, NatInfo)>, punch: Punch, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
|
||||
pub fn start(mut worker: VntWorker, receiver: Receiver<(Ipv4Addr, NatInfo)>,
|
||||
punch: Punch, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
client_cipher: Cipher, ) {
|
||||
tokio::spawn(async move {
|
||||
tokio::select! {
|
||||
_=start0(receiver, punch, current_device)=>{}
|
||||
_=start0(receiver, punch, current_device,client_cipher)=>{}
|
||||
_=worker.stop_wait()=>{
|
||||
return;
|
||||
}
|
||||
@@ -27,21 +31,24 @@ pub fn start(mut worker: VntWorker, receiver: Receiver<(Ipv4Addr, NatInfo)>, pun
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn start0(mut receiver: Receiver<(Ipv4Addr, NatInfo)>, mut punch: Punch, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
|
||||
pub async fn start0(mut receiver: Receiver<(Ipv4Addr, NatInfo)>,
|
||||
mut punch: Punch, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
client_cipher: Cipher, ) {
|
||||
while let Some((peer_ip, nat_info)) = receiver.recv().await {
|
||||
if let Err(e) = start_(&mut punch, ¤t_device, peer_ip, nat_info).await {
|
||||
if let Err(e) = start_(&client_cipher, &mut punch, ¤t_device, peer_ip, nat_info).await {
|
||||
log::warn!("网络打洞异常 {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn start_(
|
||||
client_cipher: &Cipher,
|
||||
punch: &mut Punch,
|
||||
current_device: &Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
peer_ip: Ipv4Addr,
|
||||
nat_info: NatInfo,
|
||||
) -> io::Result<()> {
|
||||
let mut packet = NetPacket::new([0u8; 12])?;
|
||||
let mut packet = NetPacket::new_encrypt([0u8; 12 + ENCRYPTION_RESERVED])?;
|
||||
packet.set_version(Version::V1);
|
||||
packet.first_set_ttl(1);
|
||||
packet.set_protocol(Protocol::Control);
|
||||
@@ -49,7 +56,7 @@ async fn start_(
|
||||
packet.set_source(current_device.load().virtual_ip());
|
||||
packet.set_destination(peer_ip);
|
||||
log::info!("发起打洞,目标:{:?},{:?}", peer_ip, nat_info);
|
||||
|
||||
client_cipher.encrypt_ipv4(&mut packet)?;
|
||||
punch.punch(packet.buffer(), peer_ip, nat_info).await
|
||||
}
|
||||
|
||||
@@ -59,6 +66,7 @@ pub async fn start_punch(
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
sender: ChannelSender,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
client_cipher: Cipher,
|
||||
) {
|
||||
let mut num = 0;
|
||||
let sleep_time = [3, 5, 7, 11, 13, 17, 19, 23, 29];
|
||||
@@ -67,7 +75,8 @@ pub async fn start_punch(
|
||||
break;
|
||||
}
|
||||
tokio::select! {
|
||||
rs= start_punch_(Duration::from_secs(sleep_time[num % sleep_time.len()]),&nat_test, &device_list, &sender, ¤t_device)=>{
|
||||
rs= start_punch_(Duration::from_secs(sleep_time[num % sleep_time.len()]),&nat_test, &device_list,
|
||||
&sender, ¤t_device,&client_cipher)=>{
|
||||
if let Err(e) = rs {
|
||||
log::warn!("打洞处理任务异常 {:?}", e);
|
||||
}
|
||||
@@ -86,6 +95,7 @@ async fn start_punch_(
|
||||
device_list: &Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
sender: &ChannelSender,
|
||||
current_device: &Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
client_cipher: &Cipher,
|
||||
) -> crate::Result<()> {
|
||||
let current_device = current_device.load();
|
||||
let nat_info = nat_test.nat_info();
|
||||
@@ -103,7 +113,7 @@ async fn start_punch_(
|
||||
if count > 2 {
|
||||
break;
|
||||
}
|
||||
let buf = punch_packet(current_device.virtual_ip(), &nat_info, info.virtual_ip)?;
|
||||
let buf = punch_packet(client_cipher, current_device.virtual_ip(), &nat_info, info.virtual_ip)?;
|
||||
let _ = sender.send_main(&buf, current_device.connect_server).await;
|
||||
}
|
||||
tokio::time::sleep(sleep_time).await;
|
||||
@@ -111,6 +121,7 @@ async fn start_punch_(
|
||||
}
|
||||
|
||||
pub fn punch_packet(
|
||||
client_cipher: &Cipher,
|
||||
virtual_ip: Ipv4Addr,
|
||||
nat_info: &NatInfo,
|
||||
dest: Ipv4Addr,
|
||||
@@ -128,13 +139,14 @@ pub fn punch_packet(
|
||||
punch_reply.local_port = nat_info.local_port as u32;
|
||||
punch_reply.nat_type = protobuf::EnumOrUnknown::new(PunchNatType::from(nat_info.nat_type));
|
||||
let bytes = punch_reply.write_to_bytes()?;
|
||||
let mut net_packet = NetPacket::new(vec![0u8; 12 + bytes.len()])?;
|
||||
let mut net_packet = NetPacket::new_encrypt(vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED])?;
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_protocol(Protocol::OtherTurn);
|
||||
net_packet.set_transport_protocol(other_turn_packet::Protocol::Punch.into());
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
net_packet.set_source(virtual_ip);
|
||||
net_packet.set_destination(dest);
|
||||
net_packet.set_payload(&bytes);
|
||||
net_packet.set_payload(&bytes)?;
|
||||
client_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
Ok(net_packet.into_buffer())
|
||||
}
|
||||
|
||||
+310
-218
@@ -1,8 +1,8 @@
|
||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use crossbeam_skiplist::SkipMap;
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use parking_lot::Mutex;
|
||||
use protobuf::Message;
|
||||
use tokio::sync::mpsc::Sender;
|
||||
@@ -11,21 +11,23 @@ use packet::icmp::{icmp, Kind};
|
||||
use packet::icmp::icmp::HeaderOther;
|
||||
use packet::ip::ipv4;
|
||||
use packet::ip::ipv4::packet::IpV4Packet;
|
||||
|
||||
use crate::channel::{Route, RouteKey};
|
||||
use crate::channel::channel::Context;
|
||||
use crate::channel::punch::{NatInfo, NatType};
|
||||
use crate::channel::{Route, RouteKey};
|
||||
use crate::cipher::Cipher;
|
||||
|
||||
use crate::cipher::{Cipher, RsaCipher};
|
||||
use crate::error::Error;
|
||||
use crate::external_route::AllowExternalRoute;
|
||||
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, PeerDeviceStatus};
|
||||
use crate::handle::{ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, PeerDeviceStatus};
|
||||
use crate::handle::handshake_handler::secret_handshake_req;
|
||||
use crate::handle::registration_handler::Register;
|
||||
use crate::igmp_server::IgmpServer;
|
||||
use crate::ip_proxy::IpProxyMap;
|
||||
use crate::nat;
|
||||
use crate::nat::NatTest;
|
||||
use crate::proto::message::{DeviceList, PunchInfo, PunchNatType, RegistrationResponse};
|
||||
use crate::protocol::{control_packet, MAX_TTL, NetPacket, Protocol, service_packet, other_turn_packet, Version, ip_turn_packet};
|
||||
use crate::protocol::{control_packet, ip_turn_packet, MAX_TTL, NetPacket, other_turn_packet, Protocol, service_packet, Version};
|
||||
use crate::protocol::body::ENCRYPTION_RESERVED;
|
||||
use crate::protocol::control_packet::ControlPacket;
|
||||
use crate::protocol::error_packet::InErrorPacket;
|
||||
use crate::tun_tap_device::DeviceWriter;
|
||||
@@ -44,8 +46,11 @@ pub struct ChannelDataHandler {
|
||||
out_external_route: AllowExternalRoute,
|
||||
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
|
||||
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
|
||||
cipher: Cipher,
|
||||
client_cipher: Cipher,
|
||||
server_cipher: Cipher,
|
||||
rsa_cipher: Option<RsaCipher>,
|
||||
relay: bool,
|
||||
token: String,
|
||||
}
|
||||
|
||||
impl ChannelDataHandler {
|
||||
@@ -61,8 +66,10 @@ impl ChannelDataHandler {
|
||||
out_external_route: AllowExternalRoute,
|
||||
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
|
||||
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
|
||||
cipher: Cipher,
|
||||
relay: bool, ) -> Self {
|
||||
client_cipher: Cipher,
|
||||
server_cipher: Cipher,
|
||||
rsa_cipher: Option<RsaCipher>,
|
||||
relay: bool, token: String, ) -> Self {
|
||||
Self {
|
||||
current_device,
|
||||
device_list,
|
||||
@@ -76,26 +83,29 @@ impl ChannelDataHandler {
|
||||
out_external_route,
|
||||
cone_sender,
|
||||
symmetric_sender,
|
||||
cipher,
|
||||
client_cipher,
|
||||
server_cipher,
|
||||
rsa_cipher,
|
||||
relay,
|
||||
token,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl ChannelDataHandler {
|
||||
pub async fn handle(&mut self, buf: &mut [u8], start: usize, end: usize, route_key: RouteKey, context: &Context) {
|
||||
pub async fn handle(&self, buf: &mut [u8], start: usize, end: usize, route_key: RouteKey, context: &Context) {
|
||||
assert_eq!(start, 14);
|
||||
match self.handle0(&mut buf[..end], &route_key, context).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::error!("{:?}",e);
|
||||
log::warn!("{:?}",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn handle0(&self, buf: &mut [u8], route_key: &RouteKey, context: &Context) -> crate::Result<()> {
|
||||
let mut net_packet = NetPacket::new(&mut buf[14..])?;
|
||||
if net_packet.ttl() == 0 {
|
||||
if net_packet.ttl() == 0 || net_packet.source_ttl() < net_packet.ttl() {
|
||||
return Ok(());
|
||||
}
|
||||
let source = net_packet.source();
|
||||
@@ -104,16 +114,9 @@ impl ChannelDataHandler {
|
||||
let destination = net_packet.destination();
|
||||
let not_broadcast = !destination.is_broadcast() && !destination.is_multicast() && destination != current_device.broadcast_address;
|
||||
if current_device.virtual_ip() != destination
|
||||
&& not_broadcast && !destination.is_unspecified()
|
||||
&& self.connect_status.load() == ConnectStatus::Connected {
|
||||
if !check_dest(source, current_device.virtual_netmask, current_device.virtual_network) {
|
||||
log::warn!("转发数据,源地址错误:{:?},当前网络:{:?},route_key:{:?}",source,current_device.virtual_network,route_key);
|
||||
return Ok(());
|
||||
}
|
||||
if !check_dest(destination, current_device.virtual_netmask, current_device.virtual_network) {
|
||||
log::warn!("转发数据,目的地址错误:{:?},当前网络:{:?},route_key:{:?}",destination,current_device.virtual_network,route_key);
|
||||
return Ok(());
|
||||
}
|
||||
&& not_broadcast && !destination.is_unspecified() {
|
||||
//校验指纹,不需要解密
|
||||
self.client_cipher.check_finger(&net_packet)?;
|
||||
net_packet.set_ttl(net_packet.ttl() - 1);
|
||||
let ttl = net_packet.ttl();
|
||||
if ttl > 0 {
|
||||
@@ -130,32 +133,25 @@ impl ChannelDataHandler {
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
if net_packet.is_gateway() {
|
||||
if net_packet.protocol() == Protocol::Error && net_packet.transport_protocol() == crate::protocol::error_packet::Protocol::NoKey.into() {
|
||||
if let Some(rsa_cipher) = &self.rsa_cipher {
|
||||
secret_handshake_req(context, current_device.connect_server, rsa_cipher, &self.server_cipher, self.token.clone()).await?;
|
||||
}
|
||||
} else {
|
||||
//服务端解密
|
||||
self.server_cipher.decrypt_ipv4(&mut net_packet)?;
|
||||
let data_len = net_packet.data_len();
|
||||
self.server_packet_handle(context, current_device, buf, data_len, route_key).await?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
self.client_cipher.decrypt_ipv4(&mut net_packet)?;
|
||||
match net_packet.protocol() {
|
||||
Protocol::IpTurn => {
|
||||
match ip_turn_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
ip_turn_packet::Protocol::Icmp => {
|
||||
let ipv4 = IpV4Packet::new(net_packet.payload())?;
|
||||
if ipv4.protocol() == ipv4::protocol::Protocol::Icmp {
|
||||
self.device_writer.write_ipv4(&mut buf[12..])?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
ip_turn_packet::Protocol::Igmp => {
|
||||
if let Some(igmp_server) = &self.igmp_server {
|
||||
let ipv4 = IpV4Packet::new(net_packet.payload())?;
|
||||
if ipv4.protocol() == ipv4::protocol::Protocol::Igmp {
|
||||
igmp_server.handle(ipv4.payload(), source)?;
|
||||
}
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
ip_turn_packet::Protocol::Ipv4 => {
|
||||
let data = if let Some(payload_len) = self.cipher.decrypt_ipv4(&mut net_packet)? {
|
||||
&mut net_packet.payload_mut()[..payload_len]
|
||||
} else {
|
||||
net_packet.payload_mut()
|
||||
};
|
||||
let mut ipv4 = IpV4Packet::new(data)?;
|
||||
let mut ipv4 = IpV4Packet::new(net_packet.payload_mut())?;
|
||||
match ipv4.protocol() {
|
||||
ipv4::protocol::Protocol::Igmp => {
|
||||
if let Some(igmp_server) = &self.igmp_server {
|
||||
@@ -176,7 +172,7 @@ impl ChannelDataHandler {
|
||||
net_packet.set_source(destination);
|
||||
net_packet.set_destination(source);
|
||||
//不管加不加密,和接收到的数据长度都一致
|
||||
let _ = self.cipher.encrypt_ipv4(net_packet.payload().len() - 16, &mut net_packet)?;
|
||||
self.client_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
context.send_by_key(net_packet.buffer(), route_key).await?;
|
||||
return Ok(());
|
||||
}
|
||||
@@ -198,7 +194,11 @@ impl ChannelDataHandler {
|
||||
tcp_packet.update_checksum();
|
||||
ipv4.set_destination_ip(destination);
|
||||
ipv4.update_checksum();
|
||||
ip_proxy_map.tcp_proxy_map.insert(SocketAddrV4::new(source, source_port), SocketAddrV4::new(dest_ip, dest_port));
|
||||
let key = SocketAddrV4::new(source, source_port);
|
||||
//https://github.com/crossbeam-rs/crossbeam/issues/1023
|
||||
if !ip_proxy_map.tcp_proxy_map.contains_key(&key){
|
||||
ip_proxy_map.tcp_proxy_map.insert(key, SocketAddrV4::new(dest_ip, dest_port));
|
||||
}
|
||||
}
|
||||
ipv4::protocol::Protocol::Udp => {
|
||||
let dest_ip = ipv4.destination_ip();
|
||||
@@ -210,7 +210,10 @@ impl ChannelDataHandler {
|
||||
udp_packet.update_checksum();
|
||||
ipv4.set_destination_ip(destination);
|
||||
ipv4.update_checksum();
|
||||
ip_proxy_map.udp_proxy_map.insert(SocketAddrV4::new(source, source_port), SocketAddrV4::new(dest_ip, dest_port));
|
||||
let key = SocketAddrV4::new(source, source_port);
|
||||
if !ip_proxy_map.udp_proxy_map.contains_key(&key){
|
||||
ip_proxy_map.udp_proxy_map.insert(key, SocketAddrV4::new(dest_ip, dest_port));
|
||||
}
|
||||
}
|
||||
ipv4::protocol::Protocol::Icmp => {
|
||||
let dest_ip = ipv4.destination_ip();
|
||||
@@ -222,15 +225,23 @@ impl ChannelDataHandler {
|
||||
ip_proxy_map.send_icmp(ipv4.payload(), &dest_ip)?;
|
||||
}
|
||||
_ => {
|
||||
return Ok(());
|
||||
log::warn!("不支持的ip代理Icmp协议:{}",destination);
|
||||
return Err(Error::Warn("不支持的ip代理Icmp协议".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Ok(());
|
||||
log::warn!("不支持的ip代理ipv4协议:{}",destination);
|
||||
return Err(Error::Warn("不支持的ip代理ipv4协议".to_string()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::warn!("没有ip代理规则:{}",destination);
|
||||
return Err(Error::Warn("没有ip代理规则".to_string()));
|
||||
}
|
||||
} else {
|
||||
log::warn!("不支持ip代理:{}",destination);
|
||||
return Err(Error::Warn("不支持ip代理".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,12 +255,8 @@ impl ChannelDataHandler {
|
||||
ip_turn_packet::Protocol::Unknown(_) => {}
|
||||
}
|
||||
}
|
||||
Protocol::Service => {
|
||||
self.service(context, current_device, source, net_packet, route_key).await?;
|
||||
}
|
||||
Protocol::Error => {
|
||||
self.error(context, current_device, source, net_packet, route_key).await?;
|
||||
}
|
||||
Protocol::Service => {}
|
||||
Protocol::Error => {}
|
||||
Protocol::Control => {
|
||||
self.control(context, current_device, source, net_packet, route_key).await?;
|
||||
}
|
||||
@@ -262,7 +269,249 @@ impl ChannelDataHandler {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn service(&self, context: &Context, current_device: CurrentDeviceInfo, _source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
|
||||
|
||||
async fn pong_packet(&self, gateway: bool, metric: u8, context: &Context, current_device: CurrentDeviceInfo, source: Ipv4Addr, pong_packet: control_packet::PongPacket<&[u8]>, route_key: &RouteKey) -> crate::Result<()> {
|
||||
let current_time = crate::handle::now_time() as u16;
|
||||
if current_time < pong_packet.time() {
|
||||
return Ok(());
|
||||
}
|
||||
let rt = (current_time - pong_packet.time()) as i64;
|
||||
let route = Route::from(*route_key, metric, rt);
|
||||
context.add_route(source, route);
|
||||
if gateway {
|
||||
let epoch = self.device_list.lock().0;
|
||||
if pong_packet.epoch() != epoch {
|
||||
let mut poll_device = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED])?;
|
||||
poll_device.set_source(current_device.virtual_ip());
|
||||
poll_device.set_destination(source);
|
||||
poll_device.set_version(Version::V1);
|
||||
poll_device.set_gateway_flag(true);
|
||||
poll_device.first_set_ttl(MAX_TTL);
|
||||
poll_device.set_protocol(Protocol::Service);
|
||||
poll_device.set_transport_protocol(service_packet::Protocol::PollDeviceList.into());
|
||||
self.server_cipher.encrypt_ipv4(&mut poll_device)?;
|
||||
context.send_main(poll_device.buffer(), current_device.connect_server).await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn control(&self, context: &Context, current_device: CurrentDeviceInfo, source: Ipv4Addr, mut net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
|
||||
let metric = net_packet.source_ttl() - net_packet.ttl() + 1;
|
||||
match ControlPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
|
||||
ControlPacket::PingPacket(_) => {
|
||||
net_packet.set_transport_protocol(control_packet::Protocol::Pong.into());
|
||||
net_packet.set_source(current_device.virtual_ip());
|
||||
net_packet.set_destination(source);
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
self.client_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
context.send_by_key(net_packet.buffer(), route_key).await?;
|
||||
let route = Route::from(*route_key, metric, 199);
|
||||
context.add_route_if_absent(source, route);
|
||||
}
|
||||
ControlPacket::PongPacket(pong_packet) => {
|
||||
self.pong_packet(false, metric, context, current_device, source, pong_packet, route_key).await?;
|
||||
}
|
||||
ControlPacket::PunchRequest => {
|
||||
if self.relay {
|
||||
return Ok(());
|
||||
}
|
||||
//回应
|
||||
net_packet.set_transport_protocol(control_packet::Protocol::PunchResponse.into());
|
||||
net_packet.set_source(current_device.virtual_ip());
|
||||
net_packet.set_destination(source);
|
||||
net_packet.first_set_ttl(1);
|
||||
self.client_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
context.send_by_key(net_packet.buffer(), route_key).await?;
|
||||
let route = Route::from(*route_key, 1, 199);
|
||||
context.add_route_if_absent(source, route);
|
||||
}
|
||||
ControlPacket::PunchResponse => {
|
||||
if self.relay {
|
||||
return Ok(());
|
||||
}
|
||||
let route = Route::from(*route_key, 1, 199);
|
||||
context.add_route_if_absent(source, route);
|
||||
}
|
||||
ControlPacket::AddrRequest => {
|
||||
match route_key.addr.ip() {
|
||||
std::net::IpAddr::V4(ipv4) => {
|
||||
let mut packet = NetPacket::new_encrypt([0; 12 + 6 + ENCRYPTION_RESERVED])?;
|
||||
packet.set_version(Version::V1);
|
||||
packet.set_protocol(Protocol::Control);
|
||||
packet.set_transport_protocol(
|
||||
control_packet::Protocol::AddrResponse.into(),
|
||||
);
|
||||
packet.first_set_ttl(MAX_TTL);
|
||||
packet.set_source(current_device.virtual_ip());
|
||||
packet.set_destination(source);
|
||||
let mut addr_packet = control_packet::AddrPacket::new(packet.payload_mut())?;
|
||||
addr_packet.set_ipv4(ipv4);
|
||||
addr_packet.set_port(route_key.addr.port());
|
||||
self.client_cipher.encrypt_ipv4(&mut packet)?;
|
||||
context.send_by_key(packet.buffer(), route_key).await?;
|
||||
}
|
||||
std::net::IpAddr::V6(_) => {}
|
||||
}
|
||||
}
|
||||
ControlPacket::AddrResponse(addr_packet) => {
|
||||
if !addr_packet.ipv4().is_multicast()
|
||||
&& !addr_packet.ipv4().is_broadcast()
|
||||
&& !addr_packet.ipv4().is_unspecified()
|
||||
&& !addr_packet.ipv4().is_loopback()
|
||||
&& !addr_packet.ipv4().is_private() && addr_packet.port() != 0 {
|
||||
self.nat_test.update_addr(addr_packet.ipv4(), addr_packet.port())
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn other_turn(&self, context: &Context, current_device: CurrentDeviceInfo, source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
|
||||
if self.relay {
|
||||
return Ok(());
|
||||
}
|
||||
match other_turn_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
other_turn_packet::Protocol::Punch => {
|
||||
let punch_info = PunchInfo::parse_from_bytes(net_packet.payload())?;
|
||||
let public_ips = punch_info.public_ip_list.
|
||||
iter().map(|v| { Ipv4Addr::from(v.to_be_bytes()) }).collect();
|
||||
let peer_nat_info = NatInfo::new(public_ips,
|
||||
punch_info.public_port as u16,
|
||||
punch_info.public_port_range as u16,
|
||||
Ipv4Addr::from(punch_info.local_ip.to_be_bytes()),
|
||||
punch_info.local_port as u16,
|
||||
punch_info.nat_type.enum_value_or_default().into());
|
||||
self.peer_nat_info_map.insert(source, peer_nat_info.clone());
|
||||
if !punch_info.reply {
|
||||
let mut punch_reply = PunchInfo::new();
|
||||
punch_reply.reply = true;
|
||||
let nat_info = self.nat_test.nat_info();
|
||||
punch_reply.public_ip_list = nat_info.public_ips.iter().map(|ip| u32::from_be_bytes(ip.octets())).collect();
|
||||
punch_reply.public_port = nat_info.public_port as u32;
|
||||
punch_reply.public_port_range = nat_info.public_port_range as u32;
|
||||
punch_reply.nat_type =
|
||||
protobuf::EnumOrUnknown::new(PunchNatType::from(nat_info.nat_type));
|
||||
punch_reply.local_ip = u32::from_be_bytes(nat_info.local_ip.octets());
|
||||
punch_reply.local_port = nat_info.local_port as u32;
|
||||
let bytes = punch_reply.write_to_bytes()?;
|
||||
let mut punch_packet =
|
||||
NetPacket::new_encrypt(vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED])?;
|
||||
punch_packet.set_version(Version::V1);
|
||||
punch_packet.set_protocol(Protocol::OtherTurn);
|
||||
punch_packet.set_transport_protocol(
|
||||
other_turn_packet::Protocol::Punch.into(),
|
||||
);
|
||||
punch_packet.first_set_ttl(MAX_TTL);
|
||||
punch_packet.set_source(current_device.virtual_ip());
|
||||
punch_packet.set_destination(source);
|
||||
punch_packet.set_payload(&bytes)?;
|
||||
if !peer_nat_info.local_ip.is_unspecified() && peer_nat_info.local_port != 0 {
|
||||
let mut packet = NetPacket::new_encrypt([0u8; 12 + ENCRYPTION_RESERVED])?;
|
||||
packet.set_version(Version::V1);
|
||||
packet.first_set_ttl(1);
|
||||
packet.set_protocol(Protocol::Control);
|
||||
packet.set_transport_protocol(control_packet::Protocol::PunchRequest.into());
|
||||
packet.set_source(current_device.virtual_ip());
|
||||
packet.set_destination(source);
|
||||
self.client_cipher.encrypt_ipv4(&mut packet)?;
|
||||
let _ = context.send_main(packet.buffer(), SocketAddr::V4(SocketAddrV4::new(peer_nat_info.local_ip, peer_nat_info.local_port))).await;
|
||||
}
|
||||
if self.punch(source, peer_nat_info).await {
|
||||
self.client_cipher.encrypt_ipv4(&mut punch_packet)?;
|
||||
context.send_by_key(punch_packet.buffer(), route_key).await?;
|
||||
}
|
||||
} else {
|
||||
self.punch(source, peer_nat_info).await;
|
||||
}
|
||||
}
|
||||
other_turn_packet::Protocol::Unknown(e) => {
|
||||
log::warn!("不支持的转发协议 {:?},source:{:?}",e,source);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn punch(&self, peer_ip: Ipv4Addr, peer_nat_info: NatInfo) -> bool {
|
||||
match peer_nat_info.nat_type {
|
||||
NatType::Symmetric => {
|
||||
self.symmetric_sender.try_send((peer_ip, peer_nat_info)).is_ok()
|
||||
}
|
||||
NatType::Cone => {
|
||||
self.cone_sender.try_send((peer_ip, peer_nat_info)).is_ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 处理服务端数据
|
||||
impl ChannelDataHandler {
|
||||
async fn server_packet_handle(&self, context: &Context, current_device: CurrentDeviceInfo, buf: &mut [u8], data_len: usize, route_key: &RouteKey) -> crate::Result<()> {
|
||||
let net_packet = NetPacket::new0(data_len, &buf[14..])?;
|
||||
let source = net_packet.source();
|
||||
match net_packet.protocol() {
|
||||
Protocol::Service => {
|
||||
self.service(context, current_device, net_packet, route_key).await?;
|
||||
}
|
||||
Protocol::Error => {
|
||||
self.error(context, current_device, source, net_packet, route_key).await?;
|
||||
}
|
||||
Protocol::Control => {
|
||||
self.control_gateway(context, current_device, net_packet, route_key).await?;
|
||||
}
|
||||
Protocol::IpTurn => {
|
||||
match ip_turn_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
ip_turn_packet::Protocol::Ipv4 => {
|
||||
let ipv4 = IpV4Packet::new(net_packet.payload())?;
|
||||
match ipv4.protocol() {
|
||||
ipv4::protocol::Protocol::Igmp => {
|
||||
if let Some(igmp_server) = &self.igmp_server {
|
||||
igmp_server.handle(ipv4.payload(), source)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
ipv4::protocol::Protocol::Icmp => {
|
||||
if ipv4.destination_ip() == current_device.virtual_ip {
|
||||
let icmp_packet = icmp::IcmpPacket::new(ipv4.payload())?;
|
||||
if icmp_packet.kind() == Kind::EchoReply {
|
||||
self.device_writer.write_ipv4(&mut buf[12..])?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
ip_turn_packet::Protocol::Ipv4Broadcast => {}
|
||||
ip_turn_packet::Protocol::Unknown(_) => {}
|
||||
}
|
||||
}
|
||||
Protocol::OtherTurn => {}
|
||||
Protocol::UnKnow(_) => {}
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
async fn control_gateway(&self, context: &Context, current_device: CurrentDeviceInfo, net_packet: NetPacket<&[u8]>, route_key: &RouteKey) -> crate::Result<()> {
|
||||
if net_packet.source() != current_device.virtual_gateway {
|
||||
return Ok(());
|
||||
}
|
||||
match ControlPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
|
||||
ControlPacket::PongPacket(pong_packet) => {
|
||||
let metric = net_packet.source_ttl() - net_packet.ttl() + 1;
|
||||
self.pong_packet(true, metric, context, current_device, net_packet.source(), pong_packet, route_key).await?;
|
||||
}
|
||||
ControlPacket::AddrResponse(addr_packet) => {
|
||||
if addr_packet.port() != 0
|
||||
&& !addr_packet.ipv4().is_multicast()
|
||||
&& !addr_packet.ipv4().is_broadcast()
|
||||
&& !addr_packet.ipv4().is_unspecified()
|
||||
&& !addr_packet.ipv4().is_loopback()
|
||||
&& !addr_packet.ipv4().is_private() {
|
||||
self.nat_test.update_addr(addr_packet.ipv4(), addr_packet.port())
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn service(&self, context: &Context, current_device: CurrentDeviceInfo, net_packet: NetPacket<&[u8]>, route_key: &RouteKey) -> crate::Result<()> {
|
||||
match service_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
service_packet::Protocol::RegistrationRequest => {}
|
||||
service_packet::Protocol::RegistrationResponse => {
|
||||
@@ -305,6 +554,7 @@ impl ChannelDataHandler {
|
||||
Ipv4Addr::from(info.virtual_ip),
|
||||
info.name,
|
||||
info.device_status as u8,
|
||||
info.client_secret,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@@ -323,10 +573,11 @@ impl ChannelDataHandler {
|
||||
service_packet::Protocol::Unknown(u) => {
|
||||
log::warn!("未知服务协议:{}",u);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn error(&self, _context: &Context, current_device: CurrentDeviceInfo, _source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, _route_key: &RouteKey) -> crate::Result<()> {
|
||||
async fn error(&self, _context: &Context, current_device: CurrentDeviceInfo, _source: Ipv4Addr, net_packet: NetPacket<&[u8]>, _route_key: &RouteKey) -> crate::Result<()> {
|
||||
log::info!("current_device:{:?}",current_device);
|
||||
match InErrorPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
|
||||
InErrorPacket::TokenError => {
|
||||
@@ -355,167 +606,8 @@ impl ChannelDataHandler {
|
||||
InErrorPacket::InvalidIp => {
|
||||
log::error!("InvalidIp");
|
||||
}
|
||||
InErrorPacket::NoKey => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn control(&self, context: &Context, current_device: CurrentDeviceInfo, source: Ipv4Addr, mut net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
|
||||
let metric = net_packet.source_ttl() - net_packet.ttl() + 1;
|
||||
match ControlPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
|
||||
ControlPacket::PingPacket(_) => {
|
||||
net_packet.set_transport_protocol(control_packet::Protocol::Pong.into());
|
||||
net_packet.set_source(current_device.virtual_ip());
|
||||
net_packet.set_destination(source);
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
context.send_by_key(net_packet.buffer(), route_key).await?;
|
||||
let route = Route::from(*route_key, metric, 199);
|
||||
context.add_route_if_absent(source, route);
|
||||
}
|
||||
ControlPacket::PongPacket(pong_packet) => {
|
||||
let current_time = crate::handle::now_time() as u16;
|
||||
if current_time < pong_packet.time() {
|
||||
return Ok(());
|
||||
}
|
||||
let rt = (current_time - pong_packet.time()) as i64;
|
||||
let route = Route::from(*route_key, metric, rt);
|
||||
context.add_route(source, route);
|
||||
if source == current_device.virtual_gateway() {
|
||||
let epoch = self.device_list.lock().0;
|
||||
if pong_packet.epoch() != epoch {
|
||||
let mut poll_device = NetPacket::new([0; 12])?;
|
||||
poll_device.set_source(current_device.virtual_ip());
|
||||
poll_device.set_destination(source);
|
||||
poll_device.set_version(Version::V1);
|
||||
poll_device.first_set_ttl(MAX_TTL);
|
||||
poll_device.set_protocol(Protocol::Service);
|
||||
poll_device.set_transport_protocol(service_packet::Protocol::PollDeviceList.into());
|
||||
context.send_main(poll_device.buffer(), current_device.connect_server).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
ControlPacket::PunchRequest => {
|
||||
if self.relay {
|
||||
return Ok(());
|
||||
}
|
||||
//回应
|
||||
net_packet.set_transport_protocol(control_packet::Protocol::PunchResponse.into());
|
||||
net_packet.set_source(current_device.virtual_ip());
|
||||
net_packet.set_destination(source);
|
||||
net_packet.first_set_ttl(1);
|
||||
context.send_by_key(net_packet.buffer(), route_key).await?;
|
||||
let route = Route::from(*route_key, metric, 199);
|
||||
context.add_route_if_absent(source, route);
|
||||
}
|
||||
ControlPacket::PunchResponse => {
|
||||
if self.relay {
|
||||
return Ok(());
|
||||
}
|
||||
// log::info!("PunchResponse route_key:{:?}",route_key);
|
||||
let route = Route::from(*route_key, metric, 199);
|
||||
context.add_route_if_absent(source, route);
|
||||
}
|
||||
ControlPacket::AddrRequest => {
|
||||
match route_key.addr.ip() {
|
||||
std::net::IpAddr::V4(ipv4) => {
|
||||
let mut packet = NetPacket::new([0; 12 + 6])?;
|
||||
packet.set_version(Version::V1);
|
||||
packet.set_protocol(Protocol::Control);
|
||||
packet.set_transport_protocol(
|
||||
control_packet::Protocol::AddrResponse.into(),
|
||||
);
|
||||
packet.first_set_ttl(MAX_TTL);
|
||||
packet.set_source(current_device.virtual_ip());
|
||||
packet.set_destination(source);
|
||||
let mut addr_packet = control_packet::AddrPacket::new(packet.payload_mut())?;
|
||||
addr_packet.set_ipv4(ipv4);
|
||||
addr_packet.set_port(route_key.addr.port());
|
||||
context.send_by_key(packet.buffer(), route_key).await?;
|
||||
}
|
||||
std::net::IpAddr::V6(_) => {}
|
||||
}
|
||||
}
|
||||
ControlPacket::AddrResponse(addr_packet) => {
|
||||
if addr_packet.port() != 0
|
||||
&& !addr_packet.ipv4().is_multicast()
|
||||
&& !addr_packet.ipv4().is_broadcast()
|
||||
&& !addr_packet.ipv4().is_unspecified()
|
||||
&& !addr_packet.ipv4().is_loopback()
|
||||
&& !addr_packet.ipv4().is_private() {
|
||||
self.nat_test.update_addr(addr_packet.ipv4(), addr_packet.port())
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn other_turn(&self, context: &Context, current_device: CurrentDeviceInfo, source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
|
||||
if self.relay {
|
||||
return Ok(());
|
||||
}
|
||||
match other_turn_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
other_turn_packet::Protocol::Punch => {
|
||||
let punch_info = PunchInfo::parse_from_bytes(net_packet.payload())?;
|
||||
let public_ips = punch_info.public_ip_list.
|
||||
iter().map(|v| { Ipv4Addr::from(v.to_be_bytes()) }).collect();
|
||||
let peer_nat_info = NatInfo::new(public_ips,
|
||||
punch_info.public_port as u16,
|
||||
punch_info.public_port_range as u16,
|
||||
Ipv4Addr::from(punch_info.local_ip.to_be_bytes()),
|
||||
punch_info.local_port as u16,
|
||||
punch_info.nat_type.enum_value_or_default().into());
|
||||
self.peer_nat_info_map.insert(source, peer_nat_info.clone());
|
||||
if !punch_info.reply {
|
||||
let mut punch_reply = PunchInfo::new();
|
||||
punch_reply.reply = true;
|
||||
let nat_info = self.nat_test.nat_info();
|
||||
punch_reply.public_ip_list = nat_info.public_ips.iter().map(|ip| u32::from_be_bytes(ip.octets())).collect();
|
||||
punch_reply.public_port = nat_info.public_port as u32;
|
||||
punch_reply.public_port_range = nat_info.public_port_range as u32;
|
||||
punch_reply.nat_type =
|
||||
protobuf::EnumOrUnknown::new(PunchNatType::from(nat_info.nat_type));
|
||||
punch_reply.local_ip = u32::from_be_bytes(nat_info.local_ip.octets());
|
||||
punch_reply.local_port = nat_info.local_port as u32;
|
||||
let bytes = punch_reply.write_to_bytes()?;
|
||||
let mut net_packet =
|
||||
NetPacket::new(vec![0u8; 12 + bytes.len()])?;
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_protocol(Protocol::OtherTurn);
|
||||
net_packet.set_transport_protocol(
|
||||
other_turn_packet::Protocol::Punch.into(),
|
||||
);
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
net_packet.set_source(current_device.virtual_ip());
|
||||
net_packet.set_destination(source);
|
||||
net_packet.set_payload(&bytes);
|
||||
if !peer_nat_info.local_ip.is_unspecified() && peer_nat_info.local_port != 0 {
|
||||
let mut packet = NetPacket::new([0u8; 12])?;
|
||||
packet.set_version(Version::V1);
|
||||
packet.first_set_ttl(1);
|
||||
packet.set_protocol(Protocol::Control);
|
||||
packet.set_transport_protocol(control_packet::Protocol::PunchRequest.into());
|
||||
packet.set_source(current_device.virtual_ip());
|
||||
packet.set_destination(source);
|
||||
let _ = context.send_main(packet.buffer(), SocketAddr::V4(SocketAddrV4::new(peer_nat_info.local_ip, peer_nat_info.local_port))).await;
|
||||
}
|
||||
if self.punch(source, peer_nat_info).await {
|
||||
context.send_by_key(net_packet.buffer(), route_key).await?;
|
||||
}
|
||||
} else {
|
||||
self.punch(source, peer_nat_info).await;
|
||||
}
|
||||
}
|
||||
other_turn_packet::Protocol::Unknown(e) => {
|
||||
log::warn!("不支持的转发协议 {:?},source:{:?}",e,source);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
async fn punch(&self, peer_ip: Ipv4Addr, peer_nat_info: NatInfo) -> bool {
|
||||
match peer_nat_info.nat_type {
|
||||
NatType::Symmetric => {
|
||||
self.symmetric_sender.try_send((peer_ip, peer_nat_info)).is_ok()
|
||||
}
|
||||
NatType::Cone => {
|
||||
self.cone_sender.try_send((peer_ip, peer_nat_info)).is_ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
use std::io;
|
||||
use std::net::{Ipv4Addr, SocketAddr};
|
||||
use std::time::{Duration, Instant};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
@@ -7,11 +6,13 @@ use protobuf::Message;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::{TcpStream, UdpSocket};
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::cipher::Cipher;
|
||||
use crate::handle::PeerDeviceInfo;
|
||||
|
||||
use crate::proto::message::{RegistrationRequest, RegistrationResponse};
|
||||
use crate::protocol::error_packet::InErrorPacket;
|
||||
use crate::protocol::{service_packet, NetPacket, Protocol, Version, MAX_TTL};
|
||||
use crate::protocol::body::ENCRYPTION_RESERVED;
|
||||
|
||||
pub enum ReqEnum {
|
||||
TokenError,
|
||||
@@ -38,14 +39,16 @@ pub struct RegResponse {
|
||||
pub async fn registration(
|
||||
main_channel: &UdpSocket,
|
||||
main_tcp_channel: Option<&mut TcpStream>,
|
||||
server_cipher: &Cipher,
|
||||
server_address: SocketAddr,
|
||||
token: String,
|
||||
device_id: String,
|
||||
name: String,
|
||||
ip: Ipv4Addr,
|
||||
client_secret: bool,
|
||||
) -> Result<RegResponse, ReqEnum> {
|
||||
let request_packet =
|
||||
registration_request_packet(token.clone(), device_id.clone(), name.clone(), ip, false, false).unwrap();
|
||||
registration_request_packet(server_cipher, token.clone(), device_id.clone(), name.clone(), ip, false, false, client_secret).unwrap();
|
||||
let buf = request_packet.buffer();
|
||||
let mut recv_buf = [0u8; 10240];
|
||||
let recv_buf = if let Some(main_tcp_channel) = main_tcp_channel {
|
||||
@@ -61,10 +64,13 @@ pub async fn registration(
|
||||
return Err(ReqEnum::Other(format!("read error:{}", e)));
|
||||
}
|
||||
let len = 4 + (((recv_buf[2] as u16) << 8) | recv_buf[3] as u16) as usize;
|
||||
if len > recv_buf.len() {
|
||||
return Err(ReqEnum::Other("too long".to_string()));
|
||||
}
|
||||
if let Err(e) = main_tcp_channel.read_exact(&mut recv_buf[4..len]).await {
|
||||
return Err(ReqEnum::Other(format!("read error:{}", e)));
|
||||
}
|
||||
&recv_buf[4..len]
|
||||
&mut recv_buf[4..len]
|
||||
} else {
|
||||
if let Err(e) = main_channel.send_to(buf, server_address).await {
|
||||
return Err(ReqEnum::Other(format!("send error:{}", e)));
|
||||
@@ -76,7 +82,7 @@ pub async fn registration(
|
||||
if server_address != addr {
|
||||
return Err(ReqEnum::Other(format!("invalid data,from {}", addr)));
|
||||
}
|
||||
&recv_buf[..len]
|
||||
&mut recv_buf[..len]
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(ReqEnum::Other(format!("receiver error:{}", e)));
|
||||
@@ -88,7 +94,7 @@ pub async fn registration(
|
||||
}
|
||||
}
|
||||
};
|
||||
let net_packet = match NetPacket::new(recv_buf) {
|
||||
let mut net_packet = match NetPacket::new(recv_buf) {
|
||||
Ok(net_packet) => {
|
||||
net_packet
|
||||
}
|
||||
@@ -96,6 +102,9 @@ pub async fn registration(
|
||||
return Err(ReqEnum::ServerError(format!("{}", e)));
|
||||
}
|
||||
};
|
||||
if let Err(e) = server_cipher.decrypt_ipv4(&mut net_packet) {
|
||||
return Err(ReqEnum::ServerError(format!("decrypt_ipv4 {}", e)));
|
||||
}
|
||||
match net_packet.protocol() {
|
||||
Protocol::Service => {
|
||||
match service_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
@@ -110,6 +119,7 @@ pub async fn registration(
|
||||
Ipv4Addr::from(info.virtual_ip),
|
||||
info.name,
|
||||
info.device_status as u8,
|
||||
info.client_secret,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@@ -155,6 +165,9 @@ pub async fn registration(
|
||||
InErrorPacket::InvalidIp => {
|
||||
Err(ReqEnum::InvalidIp)
|
||||
}
|
||||
InErrorPacket::NoKey => {
|
||||
Err(ReqEnum::ServerError("no key".to_string()))
|
||||
}
|
||||
},
|
||||
Err(e) => Err(ReqEnum::Other(format!("{}", e))),
|
||||
}
|
||||
@@ -164,12 +177,14 @@ pub async fn registration(
|
||||
}
|
||||
|
||||
fn registration_request_packet(
|
||||
server_cipher: &Cipher,
|
||||
token: String,
|
||||
device_id: String,
|
||||
name: String,
|
||||
ip: Ipv4Addr,
|
||||
is_fast: bool,
|
||||
allow_ip_change: bool,
|
||||
client_secret: bool,
|
||||
) -> crate::Result<NetPacket<Vec<u8>>> {
|
||||
let mut request = RegistrationRequest::new();
|
||||
request.token = token;
|
||||
@@ -178,45 +193,54 @@ fn registration_request_packet(
|
||||
request.virtual_ip = ip.into();
|
||||
request.allow_ip_change = allow_ip_change;
|
||||
request.is_fast = is_fast;
|
||||
request.version = "1.1.2".to_string();
|
||||
request.version = "1.2.0".to_string();
|
||||
request.client_secret = client_secret;
|
||||
let bytes = request.write_to_bytes()?;
|
||||
let buf = vec![0u8; 12 + bytes.len()];
|
||||
let mut net_packet = NetPacket::new(buf)?;
|
||||
let buf = vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED];
|
||||
let mut net_packet = NetPacket::new_encrypt(buf)?;
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_gateway_flag(true);
|
||||
net_packet.set_protocol(Protocol::Service);
|
||||
net_packet.set_transport_protocol(service_packet::Protocol::RegistrationRequest.into());
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
net_packet.set_payload(&bytes);
|
||||
net_packet.set_payload(&bytes)?;
|
||||
server_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
Ok(net_packet)
|
||||
}
|
||||
|
||||
pub struct Register {
|
||||
server_cipher: Cipher,
|
||||
sender: ChannelSender,
|
||||
server_address: SocketAddr,
|
||||
token: String,
|
||||
device_id: String,
|
||||
name: String,
|
||||
time: AtomicCell<Instant>,
|
||||
client_secret: bool,
|
||||
}
|
||||
|
||||
impl Register {
|
||||
pub fn new(
|
||||
server_cipher: Cipher,
|
||||
sender: ChannelSender,
|
||||
server_address: SocketAddr,
|
||||
token: String,
|
||||
device_id: String,
|
||||
name: String,
|
||||
client_secret: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
server_cipher,
|
||||
sender,
|
||||
server_address,
|
||||
token,
|
||||
device_id,
|
||||
name,
|
||||
time: AtomicCell::new(Instant::now()),
|
||||
client_secret,
|
||||
}
|
||||
}
|
||||
pub async fn fast_register(&self, ip: Ipv4Addr) -> io::Result<()> {
|
||||
pub async fn fast_register(&self, ip: Ipv4Addr) -> crate::Result<()> {
|
||||
let last = self.time.load();
|
||||
if last.elapsed() < Duration::from_secs(2)
|
||||
|| self
|
||||
@@ -229,14 +253,15 @@ impl Register {
|
||||
}
|
||||
log::info!("重新连接");
|
||||
let request_packet = registration_request_packet(
|
||||
&self.server_cipher,
|
||||
self.token.clone(),
|
||||
self.device_id.clone(),
|
||||
self.name.clone(),
|
||||
ip,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
self.client_secret,
|
||||
)?;
|
||||
let buf = request_packet.buffer();
|
||||
self.sender.send_main(buf, self.server_address).await?;
|
||||
Ok(())
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#[derive(Clone)]
|
||||
pub struct BufSenderGroup(usize, Vec<tokio::sync::mpsc::Sender<(Vec<u8>, usize, usize)>>);
|
||||
|
||||
pub struct BufReceiverGroup(pub Vec<tokio::sync::mpsc::Receiver<(Vec<u8>, usize, usize)>>);
|
||||
|
||||
impl BufSenderGroup {
|
||||
pub async fn send(&mut self, val: (Vec<u8>, usize, usize)) -> bool {
|
||||
let index = self.0 % self.1.len();
|
||||
self.0 = self.0.wrapping_add(1);
|
||||
self.1[index].send(val).await.is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buf_channel_group(size: usize) -> (BufSenderGroup, BufReceiverGroup) {
|
||||
let mut buf_sender_group = Vec::with_capacity(size);
|
||||
let mut buf_receiver_group = Vec::with_capacity(size);
|
||||
for _ in 0..size {
|
||||
let (buf_sender, buf_receiver) = tokio::sync::mpsc::channel::<(Vec<u8>, usize, usize)>(10);
|
||||
buf_sender_group.push(buf_sender);
|
||||
buf_receiver_group.push(buf_receiver);
|
||||
}
|
||||
(BufSenderGroup(0, buf_sender_group), BufReceiverGroup(buf_receiver_group))
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||
use std::io;
|
||||
use std::net::SocketAddrV4;
|
||||
use std::sync::Arc;
|
||||
use parking_lot::RwLock;
|
||||
use packet::ip::ipv4::packet::IpV4Packet;
|
||||
use packet::ip::ipv4::protocol::Protocol;
|
||||
use packet::tcp::tcp::TcpPacket;
|
||||
@@ -8,21 +11,22 @@ use crate::cipher::Cipher;
|
||||
use crate::external_route::ExternalRoute;
|
||||
use crate::handle::{check_dest, CurrentDeviceInfo};
|
||||
use crate::ip_proxy::IpProxyMap;
|
||||
use crate::protocol::{ip_turn_packet, NetPacket, Version};
|
||||
use crate::protocol::{ip_turn_packet, MAX_TTL, NetPacket, Version};
|
||||
use crate::error::*;
|
||||
use crate::igmp_server::IgmpServer;
|
||||
use crate::igmp_server::{IgmpServer, Multicast};
|
||||
use crate::protocol;
|
||||
use crate::protocol::ip_turn_packet::BroadcastPacketEnd;
|
||||
|
||||
use crate::protocol::body::ENCRYPTION_RESERVED;
|
||||
use crate::protocol::ip_turn_packet::BroadcastPacket;
|
||||
pub mod channel_group;
|
||||
pub mod tun_handler;
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
pub mod tap_handler;
|
||||
|
||||
async fn broadcast(sender: &ChannelSender, net_packet: &mut NetPacket<&mut [u8]>, data_len: usize, current_device: &CurrentDeviceInfo) -> Result<()> {
|
||||
async fn broadcast(server_cipher: &Cipher, multicast_members: Option<Arc<RwLock<Multicast>>>, sender: &ChannelSender, net_packet: &mut NetPacket<&mut [u8]>, current_device: &CurrentDeviceInfo) -> Result<()> {
|
||||
let mut peer_ips = Vec::with_capacity(8);
|
||||
let vec = sender.route_table_one();
|
||||
let mut relay_count = 0;
|
||||
const MAX_COUNT: usize = u8::MAX as usize;
|
||||
const MAX_COUNT: usize = 8;
|
||||
for (peer_ip, route) in vec {
|
||||
if peer_ip == current_device.virtual_gateway {
|
||||
continue;
|
||||
@@ -30,8 +34,13 @@ async fn broadcast(sender: &ChannelSender, net_packet: &mut NetPacket<&mut [u8]>
|
||||
if peer_ips.len() == MAX_COUNT {
|
||||
break;
|
||||
}
|
||||
if let Some(members) = &multicast_members {
|
||||
if !members.read().is_send(&peer_ip) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if route.is_p2p()
|
||||
&& sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
|
||||
&& sender.send_by_key(net_packet.buffer(), &route.route_key()).await.is_ok() {
|
||||
peer_ips.push(peer_ip);
|
||||
} else {
|
||||
relay_count += 1;
|
||||
@@ -41,78 +50,51 @@ async fn broadcast(sender: &ChannelSender, net_packet: &mut NetPacket<&mut [u8]>
|
||||
//不需要转发
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
//转发到服务端的可选择广播,还要进行服务端加密
|
||||
if peer_ips.is_empty() {
|
||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||
sender.send_main(net_packet.buffer(), current_device.connect_server).await?;
|
||||
} else {
|
||||
let end_len = 1 + peer_ips.len() * 4;
|
||||
let buf = vec![0 as u8; 12 + 1 + peer_ips.len() * 4 + net_packet.data_len() + ENCRYPTION_RESERVED];
|
||||
//剩余的发送到服务端,需要告知哪些已发送过
|
||||
//放在末尾可以减少复制次数
|
||||
let mut broadcast = BroadcastPacketEnd::unchecked(&mut net_packet.buffer_mut()[data_len..data_len + end_len]);
|
||||
broadcast.set_address(&peer_ips)?;
|
||||
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4Broadcast.into());
|
||||
sender.send_main(&net_packet.buffer()[..(data_len + end_len)], current_device.connect_server).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
let mut server_packet = NetPacket::new_encrypt(buf)?;
|
||||
server_packet.set_version(Version::V1);
|
||||
server_packet.set_gateway_flag(true);
|
||||
server_packet.first_set_ttl(MAX_TTL);
|
||||
server_packet.set_source(net_packet.source());
|
||||
server_packet.set_destination(current_device.virtual_gateway);
|
||||
server_packet.set_protocol(protocol::Protocol::IpTurn);
|
||||
server_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4Broadcast.into());
|
||||
|
||||
async fn multicast(igmp_server: &IgmpServer, multicast_addr: Ipv4Addr, sender: &ChannelSender, net_packet: &mut NetPacket<&mut [u8]>, data_len: usize, current_device: &CurrentDeviceInfo) -> Result<()> {
|
||||
let mut peer_ips = Vec::with_capacity(8);
|
||||
let vec = sender.route_table_one();
|
||||
let mut relay_count = 0;
|
||||
const MAX_COUNT: usize = u8::MAX as usize;
|
||||
if let Some(members) = igmp_server.load(&multicast_addr) {
|
||||
for (peer_ip, route) in vec {
|
||||
if peer_ip == current_device.virtual_gateway {
|
||||
continue;
|
||||
}
|
||||
let is_send = { members.read().is_send(&peer_ip) };
|
||||
if is_send {
|
||||
if peer_ips.len() == MAX_COUNT {
|
||||
break;
|
||||
}
|
||||
if route.is_p2p()
|
||||
&& sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
|
||||
peer_ips.push(peer_ip);
|
||||
} else {
|
||||
relay_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if relay_count == 0 && !peer_ips.is_empty() && peer_ips.len() != MAX_COUNT {
|
||||
//不需要转发
|
||||
return Ok(());
|
||||
}
|
||||
if peer_ips.is_empty() {
|
||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||
} else {
|
||||
let end_len = 1 + peer_ips.len() * 4;
|
||||
//剩余的发送到服务端,需要告知哪些已发送过
|
||||
//放在末尾可以减少复制次数
|
||||
let mut broadcast = BroadcastPacketEnd::unchecked(&mut net_packet.buffer_mut()[data_len..data_len + end_len]);
|
||||
let mut broadcast = BroadcastPacket::unchecked(server_packet.payload_mut());
|
||||
broadcast.set_address(&peer_ips)?;
|
||||
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4Broadcast.into());
|
||||
sender.send_main(&net_packet.buffer()[..(data_len + end_len)], current_device.connect_server).await?;
|
||||
broadcast.set_data(net_packet.buffer())?;
|
||||
server_cipher.encrypt_ipv4(&mut server_packet)?;
|
||||
sender.send_main(server_packet.buffer(), current_device.connect_server).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 实现一个原地发送,必须保证是如下结构
|
||||
/// |12字节开头|ip报文|至少1024字节+12字节结尾|
|
||||
/// |12字节开头|ip报文|至少1024字节结尾|
|
||||
///
|
||||
#[inline]
|
||||
pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
|
||||
mut data_len: usize,//数据总长度=ip长度+12
|
||||
data_len: usize,//数据总长度=12+ip包长度
|
||||
igmp_server: &Option<IgmpServer>,
|
||||
current_device: CurrentDeviceInfo,
|
||||
ip_route: &Option<ExternalRoute>, proxy_map: &Option<IpProxyMap>, cipher: &Cipher) -> Result<()> {
|
||||
ip_route: &Option<ExternalRoute>,
|
||||
proxy_map: &Option<IpProxyMap>,
|
||||
client_cipher: &Cipher,
|
||||
server_cipher: &Cipher) -> Result<()> {
|
||||
let ipv4_packet = IpV4Packet::new(&buf[12..data_len])?;
|
||||
let protocol = ipv4_packet.protocol();
|
||||
let ip_head_len = ipv4_packet.header_len() as usize * 4;
|
||||
if 12 + ip_head_len >= data_len {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "ip_head_len err"))?
|
||||
}
|
||||
let src_ip = ipv4_packet.source_ip();
|
||||
let mut dest_ip = ipv4_packet.destination_ip();
|
||||
let mut net_packet = NetPacket::new(buf)?;
|
||||
let mut net_packet = NetPacket::new0(data_len, buf)?;
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_protocol(protocol::Protocol::IpTurn);
|
||||
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4.into());
|
||||
@@ -121,9 +103,9 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
|
||||
net_packet.set_destination(dest_ip);
|
||||
if dest_ip == current_device.virtual_gateway {
|
||||
if protocol == Protocol::Icmp {
|
||||
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Icmp.into());
|
||||
//发送到服务端的不加密
|
||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||
net_packet.set_gateway_flag(true);
|
||||
server_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
sender.send_main(net_packet.buffer(), current_device.connect_server).await?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
@@ -131,39 +113,30 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
|
||||
match protocol {
|
||||
Protocol::Igmp => {
|
||||
if igmp_server.is_some() {
|
||||
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Igmp.into());
|
||||
//发送到服务端
|
||||
net_packet.set_destination(current_device.virtual_gateway);
|
||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||
net_packet.set_gateway_flag(true);
|
||||
server_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
sender.send_main(net_packet.buffer(), current_device.connect_server).await?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
Protocol::Udp => {
|
||||
if let Some(igmp_server) = igmp_server {
|
||||
if let Some(len) = cipher.encrypt_ipv4(data_len - 12, &mut net_packet)? {
|
||||
data_len = 12 + len;
|
||||
}
|
||||
multicast(igmp_server, dest_ip, sender, &mut net_packet, data_len, ¤t_device).await?;
|
||||
return Ok(());
|
||||
client_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
let multicast_members = if let Some(igmp_server) = igmp_server {
|
||||
igmp_server.load(&dest_ip)
|
||||
} else {
|
||||
//当广播
|
||||
dest_ip = Ipv4Addr::BROADCAST;
|
||||
net_packet.set_destination(dest_ip);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Ok(());
|
||||
None
|
||||
};
|
||||
broadcast(server_cipher, multicast_members, sender, &mut net_packet, ¤t_device).await?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
if dest_ip.is_broadcast() || current_device.broadcast_address == dest_ip {
|
||||
// 广播 发送到直连目标
|
||||
if Protocol::Udp == protocol {
|
||||
if let Some(len) = cipher.encrypt_ipv4(data_len - 12, &mut net_packet)? {
|
||||
data_len = 12 + len;
|
||||
}
|
||||
broadcast(sender, &mut net_packet, data_len, ¤t_device).await?;
|
||||
}
|
||||
client_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
broadcast(server_cipher, None, sender, &mut net_packet, ¤t_device).await?;
|
||||
return Ok(());
|
||||
}
|
||||
if !check_dest(dest_ip, current_device.virtual_netmask, current_device.virtual_network) {
|
||||
@@ -186,32 +159,38 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
|
||||
match protocol {
|
||||
Protocol::Tcp => {
|
||||
let dest_addr = {
|
||||
let tcp_packet = TcpPacket::new(src_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
|
||||
let tcp_packet = TcpPacket::new(src_ip, dest_ip,
|
||||
&mut net_packet.payload_mut()[ip_head_len..])?;
|
||||
SocketAddrV4::new(dest_ip, tcp_packet.destination_port())
|
||||
};
|
||||
if let Some(entry) = proxy_map.tcp_proxy_map.get(&dest_addr) {
|
||||
let source_addr = entry.value();
|
||||
let source_ip = *source_addr.ip();
|
||||
let mut tcp_packet = TcpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
|
||||
let mut tcp_packet = TcpPacket::new(source_ip, dest_ip,
|
||||
&mut net_packet.payload_mut()[ip_head_len..])?;
|
||||
tcp_packet.set_source_port(source_addr.port());
|
||||
tcp_packet.update_checksum();
|
||||
let mut ipv4_packet = IpV4Packet::new(&mut net_packet.buffer_mut()[12..data_len])?;
|
||||
let mut ipv4_packet = IpV4Packet::new(net_packet.payload_mut())?;
|
||||
ipv4_packet.set_source_ip(source_ip);
|
||||
ipv4_packet.update_checksum();
|
||||
}else{
|
||||
log::warn!("不存在接口 {:?}",dest_addr);
|
||||
}
|
||||
}
|
||||
Protocol::Udp => {
|
||||
let dest_addr = {
|
||||
let udp_packet = UdpPacket::new(src_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
|
||||
let udp_packet = UdpPacket::new(src_ip, dest_ip,
|
||||
&mut net_packet.payload_mut()[ip_head_len..])?;
|
||||
SocketAddrV4::new(dest_ip, udp_packet.destination_port())
|
||||
};
|
||||
if let Some(entry) = proxy_map.udp_proxy_map.get(&dest_addr) {
|
||||
let source_addr = entry.value();
|
||||
let source_ip = *source_addr.ip();
|
||||
let mut udp_packet = UdpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
|
||||
let mut udp_packet = UdpPacket::new(source_ip, dest_ip,
|
||||
&mut net_packet.payload_mut()[ip_head_len..])?;
|
||||
udp_packet.set_source_port(source_addr.port());
|
||||
udp_packet.update_checksum();
|
||||
let mut ipv4_packet = IpV4Packet::new(&mut net_packet.buffer_mut()[12..data_len])?;
|
||||
let mut ipv4_packet = IpV4Packet::new(net_packet.payload_mut())?;
|
||||
ipv4_packet.set_source_ip(source_ip);
|
||||
ipv4_packet.update_checksum();
|
||||
}
|
||||
@@ -219,13 +198,10 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if let Some(len) = cipher.encrypt_ipv4(data_len - 12, &mut net_packet)? {
|
||||
data_len = 12 + len;
|
||||
}
|
||||
|
||||
client_cipher.encrypt_ipv4(&mut net_packet)?;
|
||||
//优先发到直连到地址
|
||||
if sender.send_by_id(&net_packet.buffer()[..data_len], &dest_ip).await.is_err() {
|
||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||
if sender.send_by_id(net_packet.buffer(), &dest_ip).await.is_err() {
|
||||
sender.send_main(net_packet.buffer(), current_device.connect_server).await?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use crate::cipher::Cipher;
|
||||
use crate::core::status::VntWorker;
|
||||
use crate::external_route::ExternalRoute;
|
||||
use crate::handle::CurrentDeviceInfo;
|
||||
use crate::handle::tun_tap::channel_group::{buf_channel_group, BufSenderGroup};
|
||||
use crate::igmp_server::IgmpServer;
|
||||
use crate::ip_proxy::IpProxyMap;
|
||||
use crate::tun_tap_device::{DeviceReader, DeviceWriter};
|
||||
@@ -27,14 +28,34 @@ pub fn start(worker: VntWorker, sender: ChannelSender,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Cipher) {
|
||||
client_cipher: Cipher, server_cipher: Cipher) {
|
||||
let (buf_sender, buf_receiver) = buf_channel_group(6);
|
||||
for mut buf_receiver in buf_receiver.0 {
|
||||
let sender = sender.clone();
|
||||
let device_writer = device_writer.clone();
|
||||
let igmp_server = igmp_server.clone();
|
||||
let current_device = current_device.clone();
|
||||
let ip_route = ip_route.clone();
|
||||
let ip_proxy_map = ip_proxy_map.clone();
|
||||
let client_cipher = client_cipher.clone();
|
||||
let server_cipher = server_cipher.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some((mut buf, _, len)) = buf_receiver.recv().await {
|
||||
match handle(&mut buf, len, &igmp_server, ¤t_device, &device_writer, &sender,
|
||||
&ip_route, &ip_proxy_map, &client_cipher, &server_cipher).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("{:?}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
thread::Builder::new().name("tap_handler".into()).spawn(move || {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all().build().unwrap()
|
||||
.block_on(async move {
|
||||
if let Err(e) = start_(sender, device_reader,
|
||||
device_writer, igmp_server,
|
||||
current_device, ip_route, ip_proxy_map, cipher).await {
|
||||
if let Err(e) = start_(sender, device_reader, buf_sender).await {
|
||||
log::warn!("tap:{:?}",e);
|
||||
}
|
||||
worker.stop_all();
|
||||
@@ -44,24 +65,23 @@ pub fn start(worker: VntWorker, sender: ChannelSender,
|
||||
|
||||
async fn start_(sender: ChannelSender,
|
||||
device_reader: DeviceReader,
|
||||
device_writer: DeviceWriter,
|
||||
igmp_server: Option<IgmpServer>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Cipher) -> io::Result<()> {
|
||||
let mut buf = [0; 4096];
|
||||
mut buf_sender: BufSenderGroup) -> io::Result<()> {
|
||||
loop {
|
||||
//ip拆包了会直接丢弃?
|
||||
let mut buf = vec![0; 4096];
|
||||
if sender.is_close() {
|
||||
return Ok(());
|
||||
}
|
||||
let start = 0;
|
||||
let len = device_reader.read(&mut buf)?;
|
||||
if let Err(e) = handle(&mut buf, len, &igmp_server, ¤t_device, &device_writer, &sender, &ip_route, &ip_proxy_map, &cipher).await {
|
||||
log::warn!("tap handle{:?}",e);
|
||||
if !buf_sender.send((buf, start, len)).await {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "tap buf_sender发送失败"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle(buf: &mut [u8], len: usize, igmp_server: &Option<IgmpServer>, current_device: &AtomicCell<CurrentDeviceInfo>,
|
||||
device_writer: &DeviceWriter, sender: &ChannelSender, ip_route: &Option<ExternalRoute>, proxy_map: &Option<IpProxyMap>, cipher: &Cipher) -> crate::Result<()> {
|
||||
device_writer: &DeviceWriter, sender: &ChannelSender, ip_route: &Option<ExternalRoute>,
|
||||
proxy_map: &Option<IpProxyMap>, client_cipher: &Cipher, server_cipher: &Cipher) -> crate::Result<()> {
|
||||
let mut ethernet_packet = EthernetPacket::new(&mut buf[..len])?;
|
||||
let current_device = current_device.load();
|
||||
match ethernet_packet.protocol() {
|
||||
@@ -113,7 +133,7 @@ async fn handle(buf: &mut [u8], len: usize, igmp_server: &Option<IgmpServer>, cu
|
||||
}
|
||||
// 以太网帧头部14字节,预留12字节
|
||||
return crate::handle::tun_tap::base_handle(sender, &mut buf[2..], len - 2, igmp_server, current_device,
|
||||
ip_route, proxy_map, cipher).await;
|
||||
ip_route, proxy_map, client_cipher, server_cipher).await;
|
||||
}
|
||||
_ => {
|
||||
// log::warn!("不支持的二层协议:{:?}",p)
|
||||
|
||||
@@ -14,6 +14,7 @@ use crate::core::status::VntWorker;
|
||||
use crate::error::*;
|
||||
use crate::external_route::ExternalRoute;
|
||||
use crate::handle::CurrentDeviceInfo;
|
||||
use crate::handle::tun_tap::channel_group::{buf_channel_group, BufSenderGroup};
|
||||
use crate::igmp_server::IgmpServer;
|
||||
use crate::ip_proxy::IpProxyMap;
|
||||
use crate::tun_tap_device::{DeviceReader, DeviceWriter};
|
||||
@@ -36,8 +37,10 @@ fn icmp(device_writer: &DeviceWriter, mut ipv4_packet: IpV4Packet<&mut [u8]>) ->
|
||||
|
||||
/// 接收tun数据,并且转发到udp上
|
||||
#[inline]
|
||||
async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writer: &DeviceWriter, igmp_server: &Option<IgmpServer>, current_device: CurrentDeviceInfo,
|
||||
ip_route: &Option<ExternalRoute>, proxy_map: &Option<IpProxyMap>, cipher: &Cipher) -> Result<()> {
|
||||
async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writer: &DeviceWriter,
|
||||
igmp_server: &Option<IgmpServer>, current_device: CurrentDeviceInfo,
|
||||
ip_route: &Option<ExternalRoute>, proxy_map: &Option<IpProxyMap>,
|
||||
client_cipher: &Cipher, server_cipher: &Cipher) -> Result<()> {
|
||||
let ipv4_packet = if let Ok(ipv4_packet) = IpV4Packet::new(&mut data[12..len]) {
|
||||
ipv4_packet
|
||||
} else {
|
||||
@@ -51,22 +54,46 @@ async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writ
|
||||
if src_ip == dest_ip {
|
||||
return icmp(&device_writer, ipv4_packet);
|
||||
}
|
||||
return crate::handle::tun_tap::base_handle(sender, data, len, igmp_server, current_device, ip_route, proxy_map, cipher).await;
|
||||
return crate::handle::tun_tap::base_handle(sender, data, len, igmp_server,
|
||||
current_device, ip_route, proxy_map, client_cipher, server_cipher).await;
|
||||
}
|
||||
|
||||
pub fn start(worker: VntWorker, sender: ChannelSender,
|
||||
device_reader: DeviceReader,
|
||||
device_writer: DeviceWriter,
|
||||
igmp_server: Option<IgmpServer>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Cipher) {
|
||||
pub async fn start(worker: VntWorker, sender: ChannelSender,
|
||||
device_reader: DeviceReader,
|
||||
device_writer: DeviceWriter,
|
||||
igmp_server: Option<IgmpServer>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
client_cipher: Cipher, server_cipher: Cipher) {
|
||||
let (buf_sender, buf_receiver) = buf_channel_group(6);
|
||||
for mut buf_receiver in buf_receiver.0 {
|
||||
let sender = sender.clone();
|
||||
let device_writer = device_writer.clone();
|
||||
let igmp_server = igmp_server.clone();
|
||||
let current_device = current_device.clone();
|
||||
let ip_route = ip_route.clone();
|
||||
let ip_proxy_map = ip_proxy_map.clone();
|
||||
let client_cipher = client_cipher.clone();
|
||||
let server_cipher = server_cipher.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some((mut buf, start, len)) = buf_receiver.recv().await {
|
||||
match handle(&sender, &mut buf[start..], len, &device_writer, &igmp_server, current_device.load(),
|
||||
&ip_route, &ip_proxy_map, &client_cipher, &server_cipher).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("{:?}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
thread::Builder::new().name("tun_handler".into()).spawn(move || {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all().build().unwrap()
|
||||
.block_on(async move {
|
||||
if let Err(e) = start_(sender, device_reader, &device_writer, igmp_server, current_device, ip_route, ip_proxy_map, cipher).await {
|
||||
if let Err(e) = start_(sender, device_reader, buf_sender).await {
|
||||
log::warn!("stop:{}",e);
|
||||
}
|
||||
let _ = device_writer.close();
|
||||
@@ -75,27 +102,18 @@ pub fn start(worker: VntWorker, sender: ChannelSender,
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
async fn start_(sender: ChannelSender,
|
||||
device_reader: DeviceReader,
|
||||
device_writer: &DeviceWriter,
|
||||
igmp_server: Option<IgmpServer>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Cipher) -> io::Result<()> {
|
||||
let mut buf = [0; 4096];
|
||||
async fn start_(sender: ChannelSender, device_reader: DeviceReader, mut buf_sender: BufSenderGroup) -> io::Result<()> {
|
||||
loop {
|
||||
let mut buf = vec![0; 4096];
|
||||
if sender.is_close() {
|
||||
return Ok(());
|
||||
}
|
||||
let start = 0;
|
||||
let len = device_reader.read(&mut buf[12..])? + 12;
|
||||
#[cfg(any(target_os = "macos"))]
|
||||
let mut buf = &mut buf[4..];
|
||||
match handle(&sender, &mut buf, len, device_writer, &igmp_server, current_device.load(), &ip_route, &ip_proxy_map, &cipher).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("{:?}", e)
|
||||
}
|
||||
let start = 4;
|
||||
if !buf_sender.send((buf, start, len)).await {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "tun buf_sender发送失败"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,10 @@ use packet::icmp::icmp;
|
||||
use packet::icmp::icmp::HeaderOther;
|
||||
use packet::ip::ipv4;
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::cipher::Cipher;
|
||||
use crate::handle::CurrentDeviceInfo;
|
||||
use crate::protocol::{MAX_TTL, NetPacket, Protocol, Version};
|
||||
use crate::protocol::body::ENCRYPTION_RESERVED;
|
||||
|
||||
pub struct IcmpProxy {
|
||||
icmp_socket: Arc<Socket>,
|
||||
@@ -20,41 +22,20 @@ pub struct IcmpProxy {
|
||||
icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>>,
|
||||
sender: ChannelSender,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
client_cipher: Cipher,
|
||||
}
|
||||
|
||||
impl IcmpProxy {
|
||||
pub fn new(addr: SocketAddrV4, icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>>, sender: ChannelSender, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) -> io::Result<IcmpProxy> {
|
||||
pub fn new(addr: SocketAddrV4, icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>>,
|
||||
sender: ChannelSender, current_device: Arc<AtomicCell<CurrentDeviceInfo>>, client_cipher: Cipher) -> io::Result<IcmpProxy> {
|
||||
let icmp_socket = Arc::new(Socket::new(Domain::IPV4, Type::RAW, Some(socket2::Protocol::ICMPV4))?);
|
||||
icmp_socket.bind(&SockAddr::from(addr))?;
|
||||
// // 设置 SIO_RCVALL 参数
|
||||
// #[cfg(windows)]
|
||||
// {
|
||||
// use std::os::windows::io::AsRawSocket;
|
||||
// let raw_fd = icmp_socket.as_raw_socket();
|
||||
// let mut rcvall: winapi::shared::minwindef::DWORD = 1;
|
||||
// let mut bytes_returned: winapi::shared::minwindef::DWORD = 0;
|
||||
// let result = unsafe {
|
||||
// winapi::um::winsock2::WSAIoctl(
|
||||
// raw_fd as _,
|
||||
// winapi::shared::mstcpip::SIO_RCVALL,
|
||||
// &mut rcvall as *mut winapi::shared::minwindef::DWORD as *mut std::ffi::c_void,
|
||||
// std::mem::size_of::<winapi::shared::minwindef::DWORD>() as winapi::shared::minwindef::DWORD,
|
||||
// std::ptr::null_mut(),
|
||||
// 0,
|
||||
// &mut bytes_returned as winapi::shared::minwindef::LPDWORD,
|
||||
// std::ptr::null_mut(),
|
||||
// None,
|
||||
// )
|
||||
// };
|
||||
// if result != 0 {
|
||||
// return Err(io::Error::from_raw_os_error(unsafe { winapi::um::winsock2::WSAGetLastError() }));
|
||||
// }
|
||||
// }
|
||||
Ok(IcmpProxy {
|
||||
icmp_socket,
|
||||
icmp_proxy_map,
|
||||
sender,
|
||||
current_device,
|
||||
client_cipher,
|
||||
})
|
||||
}
|
||||
pub fn icmp_socket(&self) -> Arc<Socket> {
|
||||
@@ -64,11 +45,7 @@ impl IcmpProxy {
|
||||
let mut buf = [0 as u8; 1500];
|
||||
let data: &mut [MaybeUninit<u8>] =
|
||||
unsafe { std::mem::transmute(&mut buf[..]) };
|
||||
let mut net_packet = NetPacket::new([0u8; 4 + 8 + 1500]).unwrap();
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_protocol(Protocol::IpTurn);
|
||||
net_packet.set_transport_protocol(ipv4::protocol::Protocol::Icmp.into());
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
|
||||
loop {
|
||||
match self.recv(data) {
|
||||
Ok((len, peer_ip)) => {
|
||||
@@ -88,12 +65,20 @@ impl IcmpProxy {
|
||||
let current_device = self.current_device.load();
|
||||
let virtual_ip = current_device.virtual_ip();
|
||||
let connect_server = current_device.connect_server;
|
||||
let mut net_packet = NetPacket::new_encrypt(vec![0u8; 12 + len + ENCRYPTION_RESERVED]).unwrap();
|
||||
net_packet.set_version(Version::V1);
|
||||
net_packet.set_protocol(Protocol::IpTurn);
|
||||
net_packet.set_transport_protocol(crate::protocol::ip_turn_packet::Protocol::Ipv4.into());
|
||||
net_packet.first_set_ttl(MAX_TTL);
|
||||
net_packet.set_source(virtual_ip);
|
||||
net_packet.set_destination(dest_ip);
|
||||
let data_len = ipv4_packet.buffer.len();
|
||||
net_packet.set_payload(ipv4_packet.buffer);
|
||||
if self.sender.try_send_by_id(&net_packet.buffer()[..(12 + data_len)], &dest_ip).is_err() {
|
||||
let _ = self.sender.try_send_main(&net_packet.buffer()[..(12 + data_len)], connect_server);
|
||||
net_packet.set_payload(ipv4_packet.buffer).unwrap();
|
||||
if let Err(e) = self.client_cipher.encrypt_ipv4(&mut net_packet) {
|
||||
log::warn!("加密失败:{}",e);
|
||||
continue;
|
||||
}
|
||||
if self.sender.try_send_by_id(net_packet.buffer(), &dest_ip).is_err() {
|
||||
let _ = self.sender.try_send_main(net_packet.buffer(), connect_server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use crossbeam_skiplist::SkipMap;
|
||||
use socket2::{SockAddr, Socket};
|
||||
use tokio::net::{TcpListener, UdpSocket};
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::cipher::Cipher;
|
||||
use crate::handle::CurrentDeviceInfo;
|
||||
use crate::ip_proxy::icmp_proxy::IcmpProxy;
|
||||
use crate::ip_proxy::tcp_proxy::TcpProxy;
|
||||
@@ -40,7 +41,7 @@ impl IpProxyMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn init_proxy(sender: ChannelSender, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) -> io::Result<(TcpProxy, UdpProxy, IpProxyMap)> {
|
||||
pub async fn init_proxy(sender: ChannelSender, current_device: Arc<AtomicCell<CurrentDeviceInfo>>, client_cipher: Cipher,) -> io::Result<(TcpProxy, UdpProxy, IpProxyMap)> {
|
||||
let tcp_proxy_map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>> = Arc::new(SkipMap::new());
|
||||
let udp_proxy_map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>> = Arc::new(SkipMap::new());
|
||||
let icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>> = Arc::new(SkipMap::new());
|
||||
@@ -51,7 +52,8 @@ pub async fn init_proxy(sender: ChannelSender, current_device: Arc<AtomicCell<Cu
|
||||
let tcp_proxy = TcpProxy::new(tcp_listener, tcp_proxy_map.clone());
|
||||
let udp_proxy = UdpProxy::new(udp_socket, udp_proxy_map.clone());
|
||||
let addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0);
|
||||
let icmp_proxy = IcmpProxy::new(addr, icmp_proxy_map.clone(), sender.clone(), current_device.clone())?;
|
||||
let icmp_proxy = IcmpProxy::new(addr, icmp_proxy_map.clone(),
|
||||
sender.clone(), current_device.clone(),client_cipher)?;
|
||||
let icmp_socket = icmp_proxy.icmp_socket();
|
||||
thread::spawn(move || {
|
||||
icmp_proxy.start();
|
||||
|
||||
@@ -1,59 +1,55 @@
|
||||
use std::io;
|
||||
use std::net::{SocketAddr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crossbeam_skiplist::SkipMap;
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
|
||||
pub struct TcpProxy {
|
||||
tcp_listener: TcpListener,
|
||||
map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>,
|
||||
tcp_proxy_map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>,
|
||||
}
|
||||
|
||||
impl TcpProxy {
|
||||
pub fn new(tcp_listener: TcpListener, map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>) -> Self {
|
||||
pub fn new(tcp_listener: TcpListener, tcp_proxy_map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>) -> Self {
|
||||
Self {
|
||||
tcp_listener,
|
||||
map,
|
||||
tcp_proxy_map,
|
||||
}
|
||||
}
|
||||
pub async fn start(self) {
|
||||
pub async fn start(self) {
|
||||
let tcp_listener = self.tcp_listener;
|
||||
let map = self.map;
|
||||
let tcp_proxy_map = self.tcp_proxy_map;
|
||||
loop {
|
||||
match tcp_listener.accept().await {
|
||||
Ok((tcp_stream, sender_addr)) => {
|
||||
match sender_addr {
|
||||
SocketAddr::V4(sender_addr) => {
|
||||
if let Some(entry) = map.get(&sender_addr) {
|
||||
if let Some(entry) = tcp_proxy_map.get(&sender_addr) {
|
||||
let dest_addr = *entry.value();
|
||||
let peer_tcp_stream = match TcpStream::connect(dest_addr).await {
|
||||
Ok(peer_tcp_stream) => {peer_tcp_stream}
|
||||
Ok(peer_tcp_stream) => { peer_tcp_stream }
|
||||
Err(e) => {
|
||||
log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,sender_addr,dest_addr);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let map = map.clone();
|
||||
let tcp_proxy_map = tcp_proxy_map.clone();
|
||||
tokio::spawn(async move {
|
||||
match proxy(tcp_stream, peer_tcp_stream).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,sender_addr,dest_addr);
|
||||
}
|
||||
if let Err(e) = proxy(tcp_stream, peer_tcp_stream).await {
|
||||
log::warn!("{}->{},{}",sender_addr,dest_addr,e);
|
||||
}
|
||||
map.remove(&sender_addr);
|
||||
tcp_proxy_map.remove(&sender_addr);
|
||||
});
|
||||
}
|
||||
}
|
||||
SocketAddr::V6(_) => {}
|
||||
}
|
||||
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("tcp代理监听:{:?}",e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +61,8 @@ async fn proxy(mut client: TcpStream, mut server: TcpStream) -> io::Result<()> {
|
||||
let client_to_server = tokio::io::copy(&mut client_reader, &mut server_writer);
|
||||
let server_to_client = tokio::io::copy(&mut server_reader, &mut client_writer);
|
||||
|
||||
tokio::try_join!(client_to_server, server_to_client)?;
|
||||
|
||||
let (r1, r2) = tokio::join!(client_to_server, server_to_client);
|
||||
r1?;
|
||||
r2?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+533
-30
@@ -25,6 +25,462 @@
|
||||
/// of protobuf runtime.
|
||||
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_2_0;
|
||||
|
||||
#[derive(PartialEq,Clone,Default,Debug)]
|
||||
// @@protoc_insertion_point(message:HandshakeRequest)
|
||||
pub struct HandshakeRequest {
|
||||
// message fields
|
||||
// @@protoc_insertion_point(field:HandshakeRequest.version)
|
||||
pub version: ::std::string::String,
|
||||
// @@protoc_insertion_point(field:HandshakeRequest.secret)
|
||||
pub secret: bool,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:HandshakeRequest.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a HandshakeRequest {
|
||||
fn default() -> &'a HandshakeRequest {
|
||||
<HandshakeRequest as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl HandshakeRequest {
|
||||
pub fn new() -> HandshakeRequest {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||
let mut fields = ::std::vec::Vec::with_capacity(2);
|
||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"version",
|
||||
|m: &HandshakeRequest| { &m.version },
|
||||
|m: &mut HandshakeRequest| { &mut m.version },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"secret",
|
||||
|m: &HandshakeRequest| { &m.secret },
|
||||
|m: &mut HandshakeRequest| { &mut m.secret },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<HandshakeRequest>(
|
||||
"HandshakeRequest",
|
||||
fields,
|
||||
oneofs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for HandshakeRequest {
|
||||
const NAME: &'static str = "HandshakeRequest";
|
||||
|
||||
fn is_initialized(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
|
||||
while let Some(tag) = is.read_raw_tag_or_eof()? {
|
||||
match tag {
|
||||
10 => {
|
||||
self.version = is.read_string()?;
|
||||
},
|
||||
16 => {
|
||||
self.secret = is.read_bool()?;
|
||||
},
|
||||
tag => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||
},
|
||||
};
|
||||
}
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
// Compute sizes of nested messages
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u64 {
|
||||
let mut my_size = 0;
|
||||
if !self.version.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.version);
|
||||
}
|
||||
if self.secret != false {
|
||||
my_size += 1 + 1;
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||
self.special_fields.cached_size().set(my_size as u32);
|
||||
my_size
|
||||
}
|
||||
|
||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
|
||||
if !self.version.is_empty() {
|
||||
os.write_string(1, &self.version)?;
|
||||
}
|
||||
if self.secret != false {
|
||||
os.write_bool(2, self.secret)?;
|
||||
}
|
||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
fn special_fields(&self) -> &::protobuf::SpecialFields {
|
||||
&self.special_fields
|
||||
}
|
||||
|
||||
fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
|
||||
&mut self.special_fields
|
||||
}
|
||||
|
||||
fn new() -> HandshakeRequest {
|
||||
HandshakeRequest::new()
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.version.clear();
|
||||
self.secret = false;
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static HandshakeRequest {
|
||||
static instance: HandshakeRequest = HandshakeRequest {
|
||||
version: ::std::string::String::new(),
|
||||
secret: false,
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::MessageFull for HandshakeRequest {
|
||||
fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
|
||||
static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
|
||||
descriptor.get(|| file_descriptor().message_by_package_relative_name("HandshakeRequest").unwrap()).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for HandshakeRequest {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for HandshakeRequest {
|
||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default,Debug)]
|
||||
// @@protoc_insertion_point(message:HandshakeResponse)
|
||||
pub struct HandshakeResponse {
|
||||
// message fields
|
||||
// @@protoc_insertion_point(field:HandshakeResponse.version)
|
||||
pub version: ::std::string::String,
|
||||
// @@protoc_insertion_point(field:HandshakeResponse.secret)
|
||||
pub secret: bool,
|
||||
// @@protoc_insertion_point(field:HandshakeResponse.public_key)
|
||||
pub public_key: ::std::vec::Vec<u8>,
|
||||
// @@protoc_insertion_point(field:HandshakeResponse.key_finger)
|
||||
pub key_finger: ::std::string::String,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:HandshakeResponse.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a HandshakeResponse {
|
||||
fn default() -> &'a HandshakeResponse {
|
||||
<HandshakeResponse as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl HandshakeResponse {
|
||||
pub fn new() -> HandshakeResponse {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||
let mut fields = ::std::vec::Vec::with_capacity(4);
|
||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"version",
|
||||
|m: &HandshakeResponse| { &m.version },
|
||||
|m: &mut HandshakeResponse| { &mut m.version },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"secret",
|
||||
|m: &HandshakeResponse| { &m.secret },
|
||||
|m: &mut HandshakeResponse| { &mut m.secret },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"public_key",
|
||||
|m: &HandshakeResponse| { &m.public_key },
|
||||
|m: &mut HandshakeResponse| { &mut m.public_key },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"key_finger",
|
||||
|m: &HandshakeResponse| { &m.key_finger },
|
||||
|m: &mut HandshakeResponse| { &mut m.key_finger },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<HandshakeResponse>(
|
||||
"HandshakeResponse",
|
||||
fields,
|
||||
oneofs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for HandshakeResponse {
|
||||
const NAME: &'static str = "HandshakeResponse";
|
||||
|
||||
fn is_initialized(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
|
||||
while let Some(tag) = is.read_raw_tag_or_eof()? {
|
||||
match tag {
|
||||
10 => {
|
||||
self.version = is.read_string()?;
|
||||
},
|
||||
16 => {
|
||||
self.secret = is.read_bool()?;
|
||||
},
|
||||
26 => {
|
||||
self.public_key = is.read_bytes()?;
|
||||
},
|
||||
34 => {
|
||||
self.key_finger = is.read_string()?;
|
||||
},
|
||||
tag => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||
},
|
||||
};
|
||||
}
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
// Compute sizes of nested messages
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u64 {
|
||||
let mut my_size = 0;
|
||||
if !self.version.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.version);
|
||||
}
|
||||
if self.secret != false {
|
||||
my_size += 1 + 1;
|
||||
}
|
||||
if !self.public_key.is_empty() {
|
||||
my_size += ::protobuf::rt::bytes_size(3, &self.public_key);
|
||||
}
|
||||
if !self.key_finger.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(4, &self.key_finger);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||
self.special_fields.cached_size().set(my_size as u32);
|
||||
my_size
|
||||
}
|
||||
|
||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
|
||||
if !self.version.is_empty() {
|
||||
os.write_string(1, &self.version)?;
|
||||
}
|
||||
if self.secret != false {
|
||||
os.write_bool(2, self.secret)?;
|
||||
}
|
||||
if !self.public_key.is_empty() {
|
||||
os.write_bytes(3, &self.public_key)?;
|
||||
}
|
||||
if !self.key_finger.is_empty() {
|
||||
os.write_string(4, &self.key_finger)?;
|
||||
}
|
||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
fn special_fields(&self) -> &::protobuf::SpecialFields {
|
||||
&self.special_fields
|
||||
}
|
||||
|
||||
fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
|
||||
&mut self.special_fields
|
||||
}
|
||||
|
||||
fn new() -> HandshakeResponse {
|
||||
HandshakeResponse::new()
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.version.clear();
|
||||
self.secret = false;
|
||||
self.public_key.clear();
|
||||
self.key_finger.clear();
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static HandshakeResponse {
|
||||
static instance: HandshakeResponse = HandshakeResponse {
|
||||
version: ::std::string::String::new(),
|
||||
secret: false,
|
||||
public_key: ::std::vec::Vec::new(),
|
||||
key_finger: ::std::string::String::new(),
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::MessageFull for HandshakeResponse {
|
||||
fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
|
||||
static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
|
||||
descriptor.get(|| file_descriptor().message_by_package_relative_name("HandshakeResponse").unwrap()).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for HandshakeResponse {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for HandshakeResponse {
|
||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default,Debug)]
|
||||
// @@protoc_insertion_point(message:SecretHandshakeRequest)
|
||||
pub struct SecretHandshakeRequest {
|
||||
// message fields
|
||||
// @@protoc_insertion_point(field:SecretHandshakeRequest.token)
|
||||
pub token: ::std::string::String,
|
||||
// @@protoc_insertion_point(field:SecretHandshakeRequest.key)
|
||||
pub key: ::std::vec::Vec<u8>,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:SecretHandshakeRequest.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a SecretHandshakeRequest {
|
||||
fn default() -> &'a SecretHandshakeRequest {
|
||||
<SecretHandshakeRequest as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl SecretHandshakeRequest {
|
||||
pub fn new() -> SecretHandshakeRequest {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||
let mut fields = ::std::vec::Vec::with_capacity(2);
|
||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"token",
|
||||
|m: &SecretHandshakeRequest| { &m.token },
|
||||
|m: &mut SecretHandshakeRequest| { &mut m.token },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"key",
|
||||
|m: &SecretHandshakeRequest| { &m.key },
|
||||
|m: &mut SecretHandshakeRequest| { &mut m.key },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SecretHandshakeRequest>(
|
||||
"SecretHandshakeRequest",
|
||||
fields,
|
||||
oneofs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for SecretHandshakeRequest {
|
||||
const NAME: &'static str = "SecretHandshakeRequest";
|
||||
|
||||
fn is_initialized(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
|
||||
while let Some(tag) = is.read_raw_tag_or_eof()? {
|
||||
match tag {
|
||||
10 => {
|
||||
self.token = is.read_string()?;
|
||||
},
|
||||
18 => {
|
||||
self.key = is.read_bytes()?;
|
||||
},
|
||||
tag => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||
},
|
||||
};
|
||||
}
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
// Compute sizes of nested messages
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u64 {
|
||||
let mut my_size = 0;
|
||||
if !self.token.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.token);
|
||||
}
|
||||
if !self.key.is_empty() {
|
||||
my_size += ::protobuf::rt::bytes_size(2, &self.key);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||
self.special_fields.cached_size().set(my_size as u32);
|
||||
my_size
|
||||
}
|
||||
|
||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
|
||||
if !self.token.is_empty() {
|
||||
os.write_string(1, &self.token)?;
|
||||
}
|
||||
if !self.key.is_empty() {
|
||||
os.write_bytes(2, &self.key)?;
|
||||
}
|
||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
fn special_fields(&self) -> &::protobuf::SpecialFields {
|
||||
&self.special_fields
|
||||
}
|
||||
|
||||
fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
|
||||
&mut self.special_fields
|
||||
}
|
||||
|
||||
fn new() -> SecretHandshakeRequest {
|
||||
SecretHandshakeRequest::new()
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.token.clear();
|
||||
self.key.clear();
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static SecretHandshakeRequest {
|
||||
static instance: SecretHandshakeRequest = SecretHandshakeRequest {
|
||||
token: ::std::string::String::new(),
|
||||
key: ::std::vec::Vec::new(),
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::MessageFull for SecretHandshakeRequest {
|
||||
fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
|
||||
static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
|
||||
descriptor.get(|| file_descriptor().message_by_package_relative_name("SecretHandshakeRequest").unwrap()).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for SecretHandshakeRequest {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for SecretHandshakeRequest {
|
||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default,Debug)]
|
||||
// @@protoc_insertion_point(message:RegistrationRequest)
|
||||
pub struct RegistrationRequest {
|
||||
@@ -43,6 +499,8 @@ pub struct RegistrationRequest {
|
||||
pub virtual_ip: u32,
|
||||
// @@protoc_insertion_point(field:RegistrationRequest.allow_ip_change)
|
||||
pub allow_ip_change: bool,
|
||||
// @@protoc_insertion_point(field:RegistrationRequest.client_secret)
|
||||
pub client_secret: bool,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:RegistrationRequest.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
@@ -60,7 +518,7 @@ impl RegistrationRequest {
|
||||
}
|
||||
|
||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||
let mut fields = ::std::vec::Vec::with_capacity(7);
|
||||
let mut fields = ::std::vec::Vec::with_capacity(8);
|
||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"token",
|
||||
@@ -97,6 +555,11 @@ impl RegistrationRequest {
|
||||
|m: &RegistrationRequest| { &m.allow_ip_change },
|
||||
|m: &mut RegistrationRequest| { &mut m.allow_ip_change },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"client_secret",
|
||||
|m: &RegistrationRequest| { &m.client_secret },
|
||||
|m: &mut RegistrationRequest| { &mut m.client_secret },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<RegistrationRequest>(
|
||||
"RegistrationRequest",
|
||||
fields,
|
||||
@@ -136,6 +599,9 @@ impl ::protobuf::Message for RegistrationRequest {
|
||||
56 => {
|
||||
self.allow_ip_change = is.read_bool()?;
|
||||
},
|
||||
64 => {
|
||||
self.client_secret = is.read_bool()?;
|
||||
},
|
||||
tag => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||
},
|
||||
@@ -169,6 +635,9 @@ impl ::protobuf::Message for RegistrationRequest {
|
||||
if self.allow_ip_change != false {
|
||||
my_size += 1 + 1;
|
||||
}
|
||||
if self.client_secret != false {
|
||||
my_size += 1 + 1;
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||
self.special_fields.cached_size().set(my_size as u32);
|
||||
my_size
|
||||
@@ -196,6 +665,9 @@ impl ::protobuf::Message for RegistrationRequest {
|
||||
if self.allow_ip_change != false {
|
||||
os.write_bool(7, self.allow_ip_change)?;
|
||||
}
|
||||
if self.client_secret != false {
|
||||
os.write_bool(8, self.client_secret)?;
|
||||
}
|
||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
@@ -220,6 +692,7 @@ impl ::protobuf::Message for RegistrationRequest {
|
||||
self.version.clear();
|
||||
self.virtual_ip = 0;
|
||||
self.allow_ip_change = false;
|
||||
self.client_secret = false;
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
@@ -232,6 +705,7 @@ impl ::protobuf::Message for RegistrationRequest {
|
||||
version: ::std::string::String::new(),
|
||||
virtual_ip: 0,
|
||||
allow_ip_change: false,
|
||||
client_secret: false,
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
@@ -514,6 +988,8 @@ pub struct DeviceInfo {
|
||||
pub virtual_ip: u32,
|
||||
// @@protoc_insertion_point(field:DeviceInfo.device_status)
|
||||
pub device_status: u32,
|
||||
// @@protoc_insertion_point(field:DeviceInfo.client_secret)
|
||||
pub client_secret: bool,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:DeviceInfo.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
@@ -531,7 +1007,7 @@ impl DeviceInfo {
|
||||
}
|
||||
|
||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||
let mut fields = ::std::vec::Vec::with_capacity(3);
|
||||
let mut fields = ::std::vec::Vec::with_capacity(4);
|
||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"name",
|
||||
@@ -548,6 +1024,11 @@ impl DeviceInfo {
|
||||
|m: &DeviceInfo| { &m.device_status },
|
||||
|m: &mut DeviceInfo| { &mut m.device_status },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
|
||||
"client_secret",
|
||||
|m: &DeviceInfo| { &m.client_secret },
|
||||
|m: &mut DeviceInfo| { &mut m.client_secret },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<DeviceInfo>(
|
||||
"DeviceInfo",
|
||||
fields,
|
||||
@@ -575,6 +1056,9 @@ impl ::protobuf::Message for DeviceInfo {
|
||||
24 => {
|
||||
self.device_status = is.read_uint32()?;
|
||||
},
|
||||
32 => {
|
||||
self.client_secret = is.read_bool()?;
|
||||
},
|
||||
tag => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||
},
|
||||
@@ -596,6 +1080,9 @@ impl ::protobuf::Message for DeviceInfo {
|
||||
if self.device_status != 0 {
|
||||
my_size += ::protobuf::rt::uint32_size(3, self.device_status);
|
||||
}
|
||||
if self.client_secret != false {
|
||||
my_size += 1 + 1;
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||
self.special_fields.cached_size().set(my_size as u32);
|
||||
my_size
|
||||
@@ -611,6 +1098,9 @@ impl ::protobuf::Message for DeviceInfo {
|
||||
if self.device_status != 0 {
|
||||
os.write_uint32(3, self.device_status)?;
|
||||
}
|
||||
if self.client_secret != false {
|
||||
os.write_bool(4, self.client_secret)?;
|
||||
}
|
||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
@@ -631,6 +1121,7 @@ impl ::protobuf::Message for DeviceInfo {
|
||||
self.name.clear();
|
||||
self.virtual_ip = 0;
|
||||
self.device_status = 0;
|
||||
self.client_secret = false;
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
@@ -639,6 +1130,7 @@ impl ::protobuf::Message for DeviceInfo {
|
||||
name: ::std::string::String::new(),
|
||||
virtual_ip: 0,
|
||||
device_status: 0,
|
||||
client_secret: false,
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
@@ -1107,33 +1599,41 @@ impl PunchNatType {
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\rmessage.proto\"\xd6\x01\n\x13RegistrationRequest\x12\x14\n\x05token\
|
||||
\x18\x01\x20\x01(\tR\x05token\x12\x1b\n\tdevice_id\x18\x02\x20\x01(\tR\
|
||||
\x08deviceId\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04name\x12\x17\n\x07\
|
||||
is_fast\x18\x04\x20\x01(\x08R\x06isFast\x12\x18\n\x07version\x18\x05\x20\
|
||||
\x01(\tR\x07version\x12\x1d\n\nvirtual_ip\x18\x06\x20\x01(\x07R\tvirtual\
|
||||
Ip\x12&\n\x0fallow_ip_change\x18\x07\x20\x01(\x08R\rallowIpChange\"\xb3\
|
||||
\x02\n\x14RegistrationResponse\x12\x1d\n\nvirtual_ip\x18\x01\x20\x01(\
|
||||
\x07R\tvirtualIp\x12'\n\x0fvirtual_gateway\x18\x02\x20\x01(\x07R\x0evirt\
|
||||
ualGateway\x12'\n\x0fvirtual_netmask\x18\x03\x20\x01(\x07R\x0evirtualNet\
|
||||
mask\x12\x14\n\x05epoch\x18\x04\x20\x01(\rR\x05epoch\x125\n\x10device_in\
|
||||
fo_list\x18\x05\x20\x03(\x0b2\x0b.DeviceInfoR\x0edeviceInfoList\x12\x1b\
|
||||
\n\tpublic_ip\x18\x06\x20\x01(\x07R\x08publicIp\x12\x1f\n\x0bpublic_port\
|
||||
\x18\x07\x20\x01(\rR\npublicPort\x12\x1f\n\x0bpublic_ipv6\x18\x08\x20\
|
||||
\x01(\x0cR\npublicIpv6\"d\n\nDeviceInfo\x12\x12\n\x04name\x18\x01\x20\
|
||||
\x01(\tR\x04name\x12\x1d\n\nvirtual_ip\x18\x02\x20\x01(\x07R\tvirtualIp\
|
||||
\x12#\n\rdevice_status\x18\x03\x20\x01(\rR\x0cdeviceStatus\"Y\n\nDeviceL\
|
||||
ist\x12\x14\n\x05epoch\x18\x01\x20\x01(\rR\x05epoch\x125\n\x10device_inf\
|
||||
o_list\x18\x02\x20\x03(\x0b2\x0b.DeviceInfoR\x0edeviceInfoList\"\xa2\x02\
|
||||
\n\tPunchInfo\x12$\n\x0epublic_ip_list\x18\x02\x20\x03(\x07R\x0cpublicIp\
|
||||
List\x12\x1f\n\x0bpublic_port\x18\x03\x20\x01(\rR\npublicPort\x12*\n\x11\
|
||||
public_port_range\x18\x04\x20\x01(\rR\x0fpublicPortRange\x12(\n\x08nat_t\
|
||||
ype\x18\x05\x20\x01(\x0e2\r.PunchNatTypeR\x07natType\x12\x14\n\x05reply\
|
||||
\x18\x06\x20\x01(\x08R\x05reply\x12\x19\n\x08local_ip\x18\x07\x20\x01(\
|
||||
\x07R\x07localIp\x12\x1d\n\nlocal_port\x18\x08\x20\x01(\rR\tlocalPort\
|
||||
\x12(\n\x10public_ipv6_list\x18\t\x20\x03(\x0cR\x0epublicIpv6List*'\n\
|
||||
\x0cPunchNatType\x12\r\n\tSymmetric\x10\0\x12\x08\n\x04Cone\x10\x01b\x06\
|
||||
proto3\
|
||||
\n\rmessage.proto\"D\n\x10HandshakeRequest\x12\x18\n\x07version\x18\x01\
|
||||
\x20\x01(\tR\x07version\x12\x16\n\x06secret\x18\x02\x20\x01(\x08R\x06sec\
|
||||
ret\"\x83\x01\n\x11HandshakeResponse\x12\x18\n\x07version\x18\x01\x20\
|
||||
\x01(\tR\x07version\x12\x16\n\x06secret\x18\x02\x20\x01(\x08R\x06secret\
|
||||
\x12\x1d\n\npublic_key\x18\x03\x20\x01(\x0cR\tpublicKey\x12\x1d\n\nkey_f\
|
||||
inger\x18\x04\x20\x01(\tR\tkeyFinger\"@\n\x16SecretHandshakeRequest\x12\
|
||||
\x14\n\x05token\x18\x01\x20\x01(\tR\x05token\x12\x10\n\x03key\x18\x02\
|
||||
\x20\x01(\x0cR\x03key\"\xfb\x01\n\x13RegistrationRequest\x12\x14\n\x05to\
|
||||
ken\x18\x01\x20\x01(\tR\x05token\x12\x1b\n\tdevice_id\x18\x02\x20\x01(\t\
|
||||
R\x08deviceId\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04name\x12\x17\n\
|
||||
\x07is_fast\x18\x04\x20\x01(\x08R\x06isFast\x12\x18\n\x07version\x18\x05\
|
||||
\x20\x01(\tR\x07version\x12\x1d\n\nvirtual_ip\x18\x06\x20\x01(\x07R\tvir\
|
||||
tualIp\x12&\n\x0fallow_ip_change\x18\x07\x20\x01(\x08R\rallowIpChange\
|
||||
\x12#\n\rclient_secret\x18\x08\x20\x01(\x08R\x0cclientSecret\"\xb3\x02\n\
|
||||
\x14RegistrationResponse\x12\x1d\n\nvirtual_ip\x18\x01\x20\x01(\x07R\tvi\
|
||||
rtualIp\x12'\n\x0fvirtual_gateway\x18\x02\x20\x01(\x07R\x0evirtualGatewa\
|
||||
y\x12'\n\x0fvirtual_netmask\x18\x03\x20\x01(\x07R\x0evirtualNetmask\x12\
|
||||
\x14\n\x05epoch\x18\x04\x20\x01(\rR\x05epoch\x125\n\x10device_info_list\
|
||||
\x18\x05\x20\x03(\x0b2\x0b.DeviceInfoR\x0edeviceInfoList\x12\x1b\n\tpubl\
|
||||
ic_ip\x18\x06\x20\x01(\x07R\x08publicIp\x12\x1f\n\x0bpublic_port\x18\x07\
|
||||
\x20\x01(\rR\npublicPort\x12\x1f\n\x0bpublic_ipv6\x18\x08\x20\x01(\x0cR\
|
||||
\npublicIpv6\"\x89\x01\n\nDeviceInfo\x12\x12\n\x04name\x18\x01\x20\x01(\
|
||||
\tR\x04name\x12\x1d\n\nvirtual_ip\x18\x02\x20\x01(\x07R\tvirtualIp\x12#\
|
||||
\n\rdevice_status\x18\x03\x20\x01(\rR\x0cdeviceStatus\x12#\n\rclient_sec\
|
||||
ret\x18\x04\x20\x01(\x08R\x0cclientSecret\"Y\n\nDeviceList\x12\x14\n\x05\
|
||||
epoch\x18\x01\x20\x01(\rR\x05epoch\x125\n\x10device_info_list\x18\x02\
|
||||
\x20\x03(\x0b2\x0b.DeviceInfoR\x0edeviceInfoList\"\xa2\x02\n\tPunchInfo\
|
||||
\x12$\n\x0epublic_ip_list\x18\x02\x20\x03(\x07R\x0cpublicIpList\x12\x1f\
|
||||
\n\x0bpublic_port\x18\x03\x20\x01(\rR\npublicPort\x12*\n\x11public_port_\
|
||||
range\x18\x04\x20\x01(\rR\x0fpublicPortRange\x12(\n\x08nat_type\x18\x05\
|
||||
\x20\x01(\x0e2\r.PunchNatTypeR\x07natType\x12\x14\n\x05reply\x18\x06\x20\
|
||||
\x01(\x08R\x05reply\x12\x19\n\x08local_ip\x18\x07\x20\x01(\x07R\x07local\
|
||||
Ip\x12\x1d\n\nlocal_port\x18\x08\x20\x01(\rR\tlocalPort\x12(\n\x10public\
|
||||
_ipv6_list\x18\t\x20\x03(\x0cR\x0epublicIpv6List*'\n\x0cPunchNatType\x12\
|
||||
\r\n\tSymmetric\x10\0\x12\x08\n\x04Cone\x10\x01b\x06proto3\
|
||||
";
|
||||
|
||||
/// `FileDescriptorProto` object which was a source for this generated file
|
||||
@@ -1151,7 +1651,10 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
|
||||
file_descriptor.get(|| {
|
||||
let generated_file_descriptor = generated_file_descriptor_lazy.get(|| {
|
||||
let mut deps = ::std::vec::Vec::with_capacity(0);
|
||||
let mut messages = ::std::vec::Vec::with_capacity(5);
|
||||
let mut messages = ::std::vec::Vec::with_capacity(8);
|
||||
messages.push(HandshakeRequest::generated_message_descriptor_data());
|
||||
messages.push(HandshakeResponse::generated_message_descriptor_data());
|
||||
messages.push(SecretHandshakeRequest::generated_message_descriptor_data());
|
||||
messages.push(RegistrationRequest::generated_message_descriptor_data());
|
||||
messages.push(RegistrationResponse::generated_message_descriptor_data());
|
||||
messages.push(DeviceInfo::generated_message_descriptor_data());
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
use std::{fmt, io};
|
||||
|
||||
pub const ENCRYPTION_RESERVED: usize = 32;
|
||||
/* aes_gcm加密数据体
|
||||
0 15 31
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 数据体 |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| random(32) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| tag(32) |
|
||||
| tag(32) |
|
||||
| tag(32) |
|
||||
| tag(32) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| finger(32) |
|
||||
| finger(32) |
|
||||
| finger(32) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
注:finger用于快速校验数据是否被修改,上层可使用token、协议头参与计算finger,
|
||||
确保服务端和客户端都能感知修改(服务端不能解密也能校验指纹)
|
||||
*/
|
||||
pub struct SecretBody<B> {
|
||||
buffer: B,
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> SecretBody<B> {
|
||||
pub fn new(buffer: B) -> io::Result<SecretBody<B>> {
|
||||
let len = buffer.as_ref().len();
|
||||
// 不能大于udp最大载荷长度
|
||||
if len < 32 || len > 65535 - 20 - 8 - 12 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"length overflow",
|
||||
));
|
||||
}
|
||||
Ok(SecretBody { buffer })
|
||||
}
|
||||
pub fn data(&self) -> &[u8] {
|
||||
let end = self.buffer.as_ref().len() - 32;
|
||||
&self.buffer.as_ref()[..end]
|
||||
}
|
||||
pub fn random(&self) -> u32 {
|
||||
let end = self.buffer.as_ref().len() - 16 - 12;
|
||||
u32::from_be_bytes(self.buffer.as_ref()[end - 4..end].try_into().unwrap())
|
||||
}
|
||||
pub fn body(&self) -> &[u8] {
|
||||
let end = self.buffer.as_ref().len() - 16 - 12;
|
||||
&self.buffer.as_ref()[..end]
|
||||
}
|
||||
pub fn tag(&self) -> &[u8] {
|
||||
let end = self.buffer.as_ref().len() - 12;
|
||||
&self.buffer.as_ref()[end - 16..end]
|
||||
}
|
||||
pub fn finger(&self) -> &[u8] {
|
||||
let end = self.buffer.as_ref().len();
|
||||
&self.buffer.as_ref()[end - 12..end]
|
||||
}
|
||||
pub fn buffer(&self) -> &[u8] {
|
||||
self.buffer.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> SecretBody<B> {
|
||||
pub fn set_data(&mut self, data: &[u8]) -> io::Result<()> {
|
||||
let end = self.buffer.as_ref().len() - 32;
|
||||
if end - 4 != data.len() {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "end-4 != data.len"));
|
||||
}
|
||||
self.buffer.as_mut()[..end].copy_from_slice(data);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_random(&mut self, random: u32) {
|
||||
let end = self.buffer.as_ref().len() - 16 - 12;
|
||||
self.buffer.as_mut()[end - 4..end].copy_from_slice(&random.to_be_bytes());
|
||||
}
|
||||
|
||||
pub fn set_tag(&mut self, tag: &[u8]) -> io::Result<()> {
|
||||
if tag.len() != 16 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "tag.len != 16"));
|
||||
}
|
||||
let end = self.buffer.as_ref().len() - 12;
|
||||
self.buffer.as_mut()[end - 16..end].copy_from_slice(tag);
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_finger(&mut self, finger: &[u8]) -> io::Result<()> {
|
||||
if finger.len() != 12 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "finger.len != 12"));
|
||||
}
|
||||
let end = self.buffer.as_ref().len();
|
||||
self.buffer.as_mut()[end - 12..end].copy_from_slice(finger);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn data_mut(&mut self) -> &mut [u8] {
|
||||
let end = self.buffer.as_ref().len() - 32;
|
||||
&mut self.buffer.as_mut()[..end]
|
||||
}
|
||||
/// 数据部分
|
||||
pub fn body_mut(&mut self) -> &mut [u8] {
|
||||
let end = self.buffer.as_ref().len() - 12 - 16;
|
||||
&mut self.buffer.as_mut()[..end]
|
||||
}
|
||||
pub fn tag_mut(&mut self) -> &mut [u8] {
|
||||
let end = self.buffer.as_ref().len() - 12;
|
||||
&mut self.buffer.as_mut()[end - 16..end]
|
||||
}
|
||||
/// 数据部分+tag部分
|
||||
pub fn en_body_mut(&mut self) -> &mut [u8] {
|
||||
let end = self.buffer.as_ref().len() - 12;
|
||||
&mut self.buffer.as_mut()[..end]
|
||||
}
|
||||
pub fn buffer_mut(&mut self) -> &mut [u8] {
|
||||
self.buffer.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> fmt::Debug for SecretBody<B> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("SecretBody")
|
||||
.field("random", &self.random())
|
||||
.field("body", &self.body())
|
||||
.field("tag", &self.tag())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/* rsa加密数据体
|
||||
0 15 31
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 数据体(n) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| random(32) |
|
||||
| random(32) |
|
||||
| random(32) |
|
||||
| random(32) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| finger(32) |
|
||||
| finger(32) |
|
||||
| finger(32) |
|
||||
| finger(32) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
pub struct RsaSecretBody<B> {
|
||||
buffer: B,
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> RsaSecretBody<B> {
|
||||
pub fn new(buffer: B) -> io::Result<RsaSecretBody<B>> {
|
||||
let len = buffer.as_ref().len();
|
||||
// 不能大于udp最大载荷长度
|
||||
if len < 32 || len > 65535 - 20 - 8 - 12 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"length overflow",
|
||||
));
|
||||
}
|
||||
Ok(RsaSecretBody { buffer })
|
||||
}
|
||||
pub fn data(&self) -> &[u8] {
|
||||
let end = self.buffer.as_ref().len() - 32;
|
||||
&self.buffer.as_ref()[..end]
|
||||
}
|
||||
pub fn random(&self) -> &[u8] {
|
||||
let end = self.buffer.as_ref().len() - 16;
|
||||
&self.buffer.as_ref()[end - 16..end]
|
||||
}
|
||||
pub fn body(&self) -> &[u8] {
|
||||
let end = self.buffer.as_ref().len() - 16;
|
||||
&self.buffer.as_ref()[..end]
|
||||
}
|
||||
pub fn finger(&self) -> &[u8] {
|
||||
let end = self.buffer.as_ref().len() - 16;
|
||||
&self.buffer.as_ref()[end..]
|
||||
}
|
||||
pub fn buffer(&self) -> &[u8] {
|
||||
&self.buffer.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> RsaSecretBody<B> {
|
||||
pub fn set_random(&mut self, random: &[u8]) -> io::Result<()> {
|
||||
if random.len() != 16 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "random.len != 16"));
|
||||
}
|
||||
let end = self.buffer.as_ref().len() - 16;
|
||||
self.buffer.as_mut()[end - 16..end].copy_from_slice(random);
|
||||
Ok(())
|
||||
}
|
||||
pub fn random_mut(&mut self) -> &mut [u8] {
|
||||
let end = self.buffer.as_ref().len() - 16;
|
||||
&mut self.buffer.as_mut()[end - 16..end]
|
||||
}
|
||||
pub fn set_finger(&mut self, finger: &[u8]) -> io::Result<()> {
|
||||
if finger.len() != 16 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "finger.len != 16"));
|
||||
}
|
||||
let end = self.buffer.as_ref().len();
|
||||
self.buffer.as_mut()[end - 16..end].copy_from_slice(finger);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ pub enum Protocol {
|
||||
AddressExhausted,
|
||||
IpAlreadyExists,
|
||||
InvalidIp,
|
||||
NoKey,
|
||||
Other(u8),
|
||||
}
|
||||
|
||||
@@ -18,6 +19,7 @@ impl From<u8> for Protocol {
|
||||
3 => Self::AddressExhausted,
|
||||
4 => Self::IpAlreadyExists,
|
||||
5 => Self::InvalidIp,
|
||||
6 => Self::NoKey,
|
||||
val => Self::Other(val),
|
||||
}
|
||||
}
|
||||
@@ -31,6 +33,7 @@ impl Into<u8> for Protocol {
|
||||
Protocol::AddressExhausted => 3,
|
||||
Protocol::IpAlreadyExists => 4,
|
||||
Protocol::InvalidIp => 5,
|
||||
Protocol::NoKey => 6,
|
||||
Protocol::Other(val) => val,
|
||||
}
|
||||
}
|
||||
@@ -42,6 +45,7 @@ pub enum InErrorPacket<B> {
|
||||
AddressExhausted,
|
||||
IpAlreadyExists,
|
||||
InvalidIp,
|
||||
NoKey,
|
||||
OtherError(ErrorPacket<B>),
|
||||
}
|
||||
|
||||
@@ -53,6 +57,7 @@ impl<B: AsRef<[u8]>> InErrorPacket<B> {
|
||||
Protocol::AddressExhausted => Ok(InErrorPacket::AddressExhausted),
|
||||
Protocol::IpAlreadyExists => Ok(InErrorPacket::IpAlreadyExists),
|
||||
Protocol::InvalidIp => Ok(InErrorPacket::InvalidIp),
|
||||
Protocol::NoKey => Ok(InErrorPacket::NoKey),
|
||||
Protocol::Other(_) => Ok(InErrorPacket::OtherError(ErrorPacket::new(buffer)?)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ use std::net::Ipv4Addr;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub enum Protocol {
|
||||
Icmp,
|
||||
Igmp,
|
||||
Ipv4,
|
||||
Ipv4Broadcast,
|
||||
Unknown(u8),
|
||||
@@ -13,8 +11,6 @@ pub enum Protocol {
|
||||
impl From<u8> for Protocol {
|
||||
fn from(value: u8) -> Self {
|
||||
match value {
|
||||
1 => Protocol::Icmp,
|
||||
2 => Protocol::Igmp,
|
||||
4 => Protocol::Ipv4,
|
||||
201 => Protocol::Ipv4Broadcast,
|
||||
val => Protocol::Unknown(val),
|
||||
@@ -25,8 +21,6 @@ impl From<u8> for Protocol {
|
||||
impl Into<u8> for Protocol {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
Protocol::Icmp => 1,
|
||||
Protocol::Igmp => 2,
|
||||
Protocol::Ipv4 => 4,
|
||||
Protocol::Ipv4Broadcast => 201,
|
||||
Protocol::Unknown(val) => val,
|
||||
@@ -34,18 +28,18 @@ impl Into<u8> for Protocol {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BroadcastPacketEnd<B> {
|
||||
pub struct BroadcastPacket<B> {
|
||||
buffer: B,
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> BroadcastPacketEnd<B> {
|
||||
impl<B: AsRef<[u8]>> BroadcastPacket<B> {
|
||||
pub fn unchecked(buffer: B) -> Self {
|
||||
Self { buffer }
|
||||
}
|
||||
pub fn new(buffer: B) -> io::Result<Self> {
|
||||
let len = buffer.as_ref().len();
|
||||
let packet = Self::unchecked(buffer);
|
||||
if len < 1 || packet.len() != len {
|
||||
if len < 2 + 4 || packet.addr_num() == 0 {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"InvalidData",
|
||||
@@ -56,31 +50,36 @@ impl<B: AsRef<[u8]>> BroadcastPacketEnd<B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> BroadcastPacketEnd<B> {
|
||||
pub fn len(&self) -> usize {
|
||||
1 + self.num() as usize * 4
|
||||
}
|
||||
pub fn num(&self) -> u8 {
|
||||
let len = self.buffer.as_ref().len();
|
||||
self.buffer.as_ref()[len - 1]
|
||||
impl<B: AsRef<[u8]>> BroadcastPacket<B> {
|
||||
pub fn addr_num(&self) -> u8 {
|
||||
self.buffer.as_ref()[1]
|
||||
}
|
||||
/// 已经发送给了这些地址
|
||||
/// 从尾往头拿
|
||||
pub fn addresses(&self) -> Vec<Ipv4Addr> {
|
||||
let num = self.num() as usize;
|
||||
let num = self.addr_num() as usize;
|
||||
let mut list = Vec::with_capacity(num);
|
||||
let buf = self.buffer.as_ref();
|
||||
let mut offset = buf.len() + 4 - 2;
|
||||
let mut offset = 1;
|
||||
for _ in 0..num {
|
||||
offset -= 4;
|
||||
list.push(Ipv4Addr::new(buf[offset - 3], buf[offset - 2], buf[offset - 1], buf[offset]));
|
||||
list.push(Ipv4Addr::new(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]));
|
||||
offset += 4;
|
||||
}
|
||||
list
|
||||
}
|
||||
pub fn data(&self) -> io::Result<&[u8]> {
|
||||
let start = 1 + self.addr_num() as usize * 4;
|
||||
if start > self.buffer.as_ref().len() {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"InvalidData",
|
||||
))
|
||||
} else {
|
||||
Ok(&self.buffer.as_ref()[start..])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> BroadcastPacketEnd<B> {
|
||||
/// 从头往尾放
|
||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> BroadcastPacket<B> {
|
||||
pub fn set_address(&mut self, addr: &[Ipv4Addr]) -> io::Result<()> {
|
||||
let buf = self.buffer.as_mut();
|
||||
if buf.len() < 1 + addr.len() * 4 || addr.len() > u8::MAX as usize {
|
||||
@@ -89,15 +88,28 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> BroadcastPacketEnd<B> {
|
||||
"InvalidData",
|
||||
))
|
||||
} else {
|
||||
let mut offset = 0;
|
||||
buf[0] = addr.len() as u8;
|
||||
let mut offset = 1;
|
||||
for ip in addr {
|
||||
buf[offset..offset + 4].copy_from_slice(&ip.octets());
|
||||
offset += 4;
|
||||
}
|
||||
self.buffer.as_mut()[offset] = addr.len() as u8;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub fn set_data(&mut self, data: &[u8]) -> io::Result<()> {
|
||||
let num = self.addr_num() as usize;
|
||||
let start = 1 + 4 * num;
|
||||
let buf = self.buffer.as_mut();
|
||||
if start > buf.len() || start + data.len() != buf.len() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"InvalidData",
|
||||
));
|
||||
}
|
||||
buf[start..].copy_from_slice(data);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+69
-10
@@ -1,11 +1,12 @@
|
||||
use std::net::Ipv4Addr;
|
||||
use std::{fmt, io};
|
||||
use std::net::Ipv4Addr;
|
||||
use crate::protocol::body::ENCRYPTION_RESERVED;
|
||||
|
||||
/*
|
||||
0 15 31
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| p|unused| 版本(4) | 协议(8) | 上层协议(8) | 初始ttl(4) | 生存时间(4) |
|
||||
|e|s|unused| 版本(4) | 协议(8) | 上层协议(8) | 初始ttl(4) | 生存时间(4) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 源ip地址(32) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
@@ -13,8 +14,11 @@ use std::{fmt, io};
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| 数据体 |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
注:e为是否加密标志,s为服务端通信包标志
|
||||
*/
|
||||
|
||||
|
||||
pub mod body;
|
||||
pub mod control_packet;
|
||||
pub mod error_packet;
|
||||
pub mod service_packet;
|
||||
@@ -91,33 +95,68 @@ pub const MAX_SOURCE: u8 = 0b11110000;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct NetPacket<B> {
|
||||
data_len: usize,
|
||||
buffer: B,
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> NetPacket<B> {
|
||||
pub fn new(buffer: B) -> io::Result<NetPacket<B>> {
|
||||
let len = buffer.as_ref().len();
|
||||
// 不能大于udp最大载荷长度
|
||||
if len < 12 || len > 65535 - 20 - 8 {
|
||||
let data_len = buffer.as_ref().len();
|
||||
Self::new0(data_len, buffer)
|
||||
}
|
||||
pub fn new_encrypt(buffer: B) -> io::Result<NetPacket<B>> {
|
||||
if 12 + ENCRYPTION_RESERVED > buffer.as_ref().len() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"length overflow",
|
||||
));
|
||||
}
|
||||
Ok(NetPacket { buffer })
|
||||
//加密需要预留32字节
|
||||
let data_len = buffer.as_ref().len() - ENCRYPTION_RESERVED;
|
||||
Self::new0(data_len, buffer)
|
||||
}
|
||||
pub fn new0(data_len: usize, buffer: B) -> io::Result<NetPacket<B>> {
|
||||
if data_len > buffer.as_ref().len() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"length overflow",
|
||||
));
|
||||
}
|
||||
// 不能大于udp最大载荷长度
|
||||
if data_len < 12 || buffer.as_ref().len() > 65535 - 20 - 8 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"length overflow",
|
||||
));
|
||||
}
|
||||
Ok(NetPacket { data_len, buffer })
|
||||
}
|
||||
pub fn buffer(&self) -> &[u8] {
|
||||
&self.buffer.as_ref()[..self.data_len]
|
||||
}
|
||||
pub fn raw_buffer(&self) -> &[u8] {
|
||||
self.buffer.as_ref()
|
||||
}
|
||||
pub fn data_len(&self) -> usize {
|
||||
self.data_len
|
||||
}
|
||||
pub fn reserve(&self) -> usize {
|
||||
self.buffer.as_ref().len() - self.data_len
|
||||
}
|
||||
pub fn into_buffer(self) -> B {
|
||||
self.buffer
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> NetPacket<B> {
|
||||
/// 数据加密
|
||||
pub fn is_encrypt(&self) -> bool {
|
||||
self.buffer.as_ref()[0] & 0x80 == 0x80
|
||||
}
|
||||
/// 网关通信的标识
|
||||
pub fn is_gateway(&self) -> bool {
|
||||
self.buffer.as_ref()[0] & 0x50 == 0x50
|
||||
}
|
||||
pub fn version(&self) -> Version {
|
||||
Version::from(self.buffer.as_ref()[0] & 0x0F)
|
||||
}
|
||||
@@ -142,7 +181,7 @@ impl<B: AsRef<[u8]>> NetPacket<B> {
|
||||
Ipv4Addr::from(tmp)
|
||||
}
|
||||
pub fn payload(&self) -> &[u8] {
|
||||
&self.buffer.as_ref()[12..]
|
||||
&self.buffer.as_ref()[12..self.data_len]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +196,13 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> NetPacket<B> {
|
||||
self.buffer.as_mut()[0] = self.buffer.as_ref()[0] & 0x7F
|
||||
};
|
||||
}
|
||||
pub fn set_gateway_flag(&mut self, is_gateway: bool) {
|
||||
if is_gateway {
|
||||
self.buffer.as_mut()[0] = self.buffer.as_ref()[0] | 0x50
|
||||
} else {
|
||||
self.buffer.as_mut()[0] = self.buffer.as_ref()[0] & 0xBF
|
||||
};
|
||||
}
|
||||
pub fn set_version(&mut self, version: Version) {
|
||||
let v: u8 = version.into();
|
||||
self.buffer.as_mut()[0] = (self.buffer.as_ref()[0] & 0xF0) | (0x0F & v);
|
||||
@@ -182,11 +228,22 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> NetPacket<B> {
|
||||
pub fn set_destination(&mut self, destination: Ipv4Addr) {
|
||||
self.buffer.as_mut()[8..12].copy_from_slice(&destination.octets());
|
||||
}
|
||||
pub fn set_payload(&mut self, payload: &[u8]) {
|
||||
self.buffer.as_mut()[12..payload.len() + 12].copy_from_slice(payload);
|
||||
pub fn set_payload(&mut self, payload: &[u8]) -> io::Result<()> {
|
||||
if self.data_len - 12 != payload.len() {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "data_len - 12 != payload.len"));
|
||||
}
|
||||
self.buffer.as_mut()[12..self.data_len].copy_from_slice(payload);
|
||||
Ok(())
|
||||
}
|
||||
pub fn payload_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.buffer.as_mut()[12..]
|
||||
&mut self.buffer.as_mut()[12..self.data_len]
|
||||
}
|
||||
pub fn set_data_len(&mut self, data_len: usize) -> io::Result<()> {
|
||||
if data_len > self.buffer.as_ref().len() || data_len < 12 {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "data_len invalid"));
|
||||
}
|
||||
self.data_len = data_len;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,6 +251,8 @@ impl<B: AsRef<[u8]>> fmt::Debug for NetPacket<B> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("NetPacket")
|
||||
.field("version", &self.version())
|
||||
.field("gateway", &self.is_gateway())
|
||||
.field("encrypt", &self.is_encrypt())
|
||||
.field("protocol", &self.protocol())
|
||||
.field("transport_protocol", &self.transport_protocol())
|
||||
.field("ttl", &self.ttl())
|
||||
|
||||
@@ -8,6 +8,11 @@ pub enum Protocol {
|
||||
PollDeviceList,
|
||||
/// 推送设备列表
|
||||
PushDeviceList,
|
||||
/// 和服务端握手
|
||||
HandshakeRequest,
|
||||
HandshakeResponse,
|
||||
SecretHandshakeRequest,
|
||||
SecretHandshakeResponse,
|
||||
Unknown(u8),
|
||||
}
|
||||
|
||||
@@ -18,6 +23,10 @@ impl From<u8> for Protocol {
|
||||
2 => Self::RegistrationResponse,
|
||||
3 => Self::PollDeviceList,
|
||||
4 => Self::PushDeviceList,
|
||||
5 => Self::HandshakeRequest,
|
||||
6 => Self::HandshakeResponse,
|
||||
7 => Self::SecretHandshakeRequest,
|
||||
8 => Self::SecretHandshakeResponse,
|
||||
val => Self::Unknown(val),
|
||||
}
|
||||
}
|
||||
@@ -30,6 +39,10 @@ impl Into<u8> for Protocol {
|
||||
Self::RegistrationResponse => 2,
|
||||
Self::PollDeviceList => 3,
|
||||
Self::PushDeviceList => 4,
|
||||
Self::HandshakeRequest => 5,
|
||||
Self::HandshakeResponse => 6,
|
||||
Self::SecretHandshakeRequest => 7,
|
||||
Self::SecretHandshakeResponse => 8,
|
||||
Self::Unknown(val) => val,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,14 @@ impl DeviceWriter {
|
||||
pub fn change_ip(&self, address: Ipv4Addr, netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr, _old_netmask: Ipv4Addr, _old_gateway: Ipv4Addr) -> io::Result<()> {
|
||||
let mut config = tun::Configuration::default();
|
||||
let broadcast_address = (!u32::from_be_bytes(netmask.octets()))
|
||||
| u32::from_be_bytes(gateway.octets());
|
||||
let broadcast_address = Ipv4Addr::from(broadcast_address);
|
||||
config
|
||||
.destination(gateway)
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.broadcast(broadcast_address)
|
||||
// .queues(2)
|
||||
.up();
|
||||
let mut dev = self.lock.lock();
|
||||
@@ -58,12 +62,15 @@ pub fn create_device(device_type: DeviceType,
|
||||
mtu: u16,
|
||||
) -> io::Result<(DeviceWriter, DeviceReader,DriverInfo)> {
|
||||
let mut config = tun::Configuration::default();
|
||||
|
||||
let broadcast_address = (!u32::from_be_bytes(netmask.octets()))
|
||||
| u32::from_be_bytes(gateway.octets());
|
||||
let broadcast_address = Ipv4Addr::from(broadcast_address);
|
||||
config
|
||||
.destination(gateway)
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.mtu(mtu.into())
|
||||
.broadcast(broadcast_address)
|
||||
// .queues(2) 用多个队列有兼容性问题
|
||||
.up();
|
||||
match device_type {
|
||||
|
||||
Reference in New Issue
Block a user