Compare commits

...
14 Commits
Author SHA1 Message Date
lubeilin b26c4b97b2 上报状态 2024-03-24 21:50:47 +08:00
lubeilin 5569c67ba4 增加日志 2024-03-24 21:50:39 +08:00
lubeilin 69da6de1ed 离线时才检测服务器地址 2024-03-24 09:18:12 +08:00
lubeilin ae983f014b 降低地址探测频率 2024-03-23 12:46:20 +08:00
lubeilin 499e3bbfdf 去除重复逻辑 2024-03-21 23:08:48 +08:00
lubeilin 01f6890fd3 减少离线时发包 2024-03-21 21:25:24 +08:00
lubeilin 9badbe180c 不转发来源和目的相同的数据 2024-03-20 12:21:19 +08:00
lubeilin 30b1e71aa1 fmt 2024-03-19 23:54:33 +08:00
lubeilin b36cc352d5 兼容纯ipv4 2024-03-19 23:53:16 +08:00
lubeilin 12d888cefc 忽略跃点设置失败的异常 2024-03-18 21:35:22 +08:00
lubeilin ad1df41029 调整打洞 2024-03-17 15:41:25 +08:00
lubeilin 67498dfc82 增加序列号 2024-03-17 14:28:03 +08:00
lubeilin cf52fdde57 修改线程名称 2024-03-17 14:27:49 +08:00
lubeilin a20082d40b 已支持ipv6 2024-03-14 23:31:40 +08:00
34 changed files with 883 additions and 256 deletions
-1
View File
@@ -213,7 +213,6 @@ sudo pfctl -f /etc/pf.conf -e
### Todo
- 桌面UI(测试中)
- 支持Ipv6(1.2.2已支持客户端之间的ipv6,待支持客户端和服务端之间的ipv6通信)
### 常见问题
+2 -1
View File
@@ -40,4 +40,5 @@ aes_gcm=["vnt/aes_gcm"]
server_encrypt=["vnt/server_encrypt"]
ip_proxy=["vnt/ip_proxy"]
[build-dependencies]
embed-manifest = "1.4.0"
embed-manifest = "1.4.0"
rand = "0.9.0-alpha.0"
+14 -7
View File
@@ -1,10 +1,17 @@
// use embed_manifest::{embed_manifest, new_manifest};
// use embed_manifest::manifest::ExecutionLevel;
use rand::Rng;
use std::fs::File;
use std::io::Write;
fn main() {
////强制用管理员运行貌似体验更差了
// if std::env::var_os("CARGO_CFG_WINDOWS").is_some() {
// embed_manifest(new_manifest("vnt")
// .requested_execution_level(ExecutionLevel::RequireAdministrator)).expect("unable to embed manifest file");
// }
// 生成随机序列号
let serial_number = format!(
"{}-{}-{}",
rand::thread_rng().gen_range(100..1000),
rand::thread_rng().gen_range(100..1000),
rand::thread_rng().gen_range(100..1000)
);
let generated_code = format!(r#"pub const SERIAL_NUMBER: &str = "{}";"#, serial_number);
let dest_path = "src/generated_serial_number.rs";
let mut file = File::create(&dest_path).unwrap();
file.write_all(generated_code.as_bytes()).unwrap();
}
+1
View File
@@ -31,6 +31,7 @@ impl VntCallback for VntHandler {
}
fn error(&self, info: ErrorInfo) {
log::error!("error {:?}", info);
println!("{}", style(format!("error {}", info)).red());
match info.code {
ErrorType::TokenError
+11 -6
View File
@@ -15,6 +15,7 @@ use vnt::core::{Config, Vnt};
mod command;
mod config;
mod console_out;
mod generated_serial_number;
mod root_check;
pub fn app_home() -> io::Result<PathBuf> {
@@ -336,7 +337,7 @@ fn main() {
(config, cmd)
};
println!("version {}", vnt::VNT_VERSION);
println!("Serial:{}", generated_serial_number::SERIAL_NUMBER);
main0(config, cmd);
std::process::exit(0);
}
@@ -346,11 +347,14 @@ mod callback;
fn main0(config: Config, show_cmd: bool) {
let vnt_util = Vnt::new(config, callback::VntHandler {}).unwrap();
let vnt_c = vnt_util.clone();
thread::spawn(move || {
if let Err(e) = command::server::CommandServer::new().start(vnt_c) {
log::warn!("cmd:{:?}", e);
}
});
thread::Builder::new()
.name("CommandServer".into())
.spawn(move || {
if let Err(e) = command::server::CommandServer::new().start(vnt_c) {
log::warn!("cmd:{:?}", e);
}
})
.expect("CommandServer");
if show_cmd {
let mut cmd = String::new();
loop {
@@ -406,6 +410,7 @@ fn command(cmd: &str, vnt: &Vnt) -> bool {
fn print_usage(program: &str, _opts: Options) {
println!("Usage: {} [options]", program);
println!("version:{}", vnt::VNT_VERSION);
println!("Serial:{}", generated_serial_number::SERIAL_NUMBER);
println!("Options:");
println!(
" -k <token> {}",
+65 -53
View File
@@ -1,66 +1,78 @@
syntax = "proto3";
message HandshakeRequest{
string version = 1;
bool secret = 2;
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 HandshakeResponse {
string version = 1;
bool secret = 2;
bytes public_key = 3;
string key_finger = 4;
}
message SecretHandshakeRequest{
string token = 1;
bytes key = 2;
message SecretHandshakeRequest {
string token = 1;
bytes key = 2;
}
message RegistrationRequest{
string token = 1;
string device_id = 2;
string name = 3;
bool is_fast = 4;
string version = 5;
fixed32 virtual_ip = 6;
bool allow_ip_change = 7;
bool client_secret = 8;
message RegistrationRequest {
string token = 1;
string device_id = 2;
string name = 3;
bool is_fast = 4;
string version = 5;
fixed32 virtual_ip = 6;
bool allow_ip_change = 7;
bool client_secret = 8;
}
message RegistrationResponse{
fixed32 virtual_ip = 1;
fixed32 virtual_gateway = 2;
fixed32 virtual_netmask = 3;
uint32 epoch = 4;
repeated DeviceInfo device_info_list = 5;
fixed32 public_ip = 6;
uint32 public_port = 7;
bytes public_ipv6 = 8;
message RegistrationResponse {
fixed32 virtual_ip = 1;
fixed32 virtual_gateway = 2;
fixed32 virtual_netmask = 3;
uint32 epoch = 4;
repeated DeviceInfo device_info_list = 5;
fixed32 public_ip = 6;
uint32 public_port = 7;
bytes public_ipv6 = 8;
}
message DeviceInfo{
string name = 1;
fixed32 virtual_ip = 2;
uint32 device_status = 3;
bool client_secret = 4;
message DeviceInfo {
string name = 1;
fixed32 virtual_ip = 2;
uint32 device_status = 3;
bool client_secret = 4;
}
message DeviceList{
uint32 epoch = 1;
repeated DeviceInfo device_info_list = 2;
message DeviceList {
uint32 epoch = 1;
repeated DeviceInfo device_info_list = 2;
}
message PunchInfo{
repeated fixed32 public_ip_list = 2;
uint32 public_port = 3;
uint32 public_port_range = 4;
PunchNatType nat_type = 5;
bool reply = 6;
fixed32 local_ip = 7;
uint32 local_port = 8;
bytes ipv6 = 9;
uint32 ipv6_port = 10;
uint32 tcp_port = 11;
repeated uint32 udp_ports = 12;
repeated uint32 public_ports = 13;
message PunchInfo {
repeated fixed32 public_ip_list = 2;
uint32 public_port = 3;
uint32 public_port_range = 4;
PunchNatType nat_type = 5;
bool reply = 6;
fixed32 local_ip = 7;
uint32 local_port = 8;
bytes ipv6 = 9;
uint32 ipv6_port = 10;
uint32 tcp_port = 11;
repeated uint32 udp_ports = 12;
repeated uint32 public_ports = 13;
}
enum PunchNatType{
Symmetric = 0;
Cone = 1;
enum PunchNatType {
Symmetric = 0;
Cone = 1;
}
/// 向服务器上报客户端状态信息
message ClientStatusInfo {
fixed32 source = 1;
repeated RouteItem p2p_list = 2;
uint64 up_stream = 3;
uint64 down_stream = 4;
PunchNatType nat_type = 5;
}
message RouteItem {
fixed32 next_ip = 1;
}
+21 -23
View File
@@ -28,6 +28,7 @@ impl Context {
is_tcp: bool,
packet_loss_rate: Option<f64>,
packet_delay: u32,
use_ipv6: bool,
) -> Self {
let channel_num = main_udp_socket.len();
assert_ne!(channel_num, 0, "not channel");
@@ -51,6 +52,7 @@ impl Context {
packet_loss_rate,
packet_delay,
main_index: AtomicUsize::new(0),
use_ipv6,
};
Self {
inner: Arc::new(inner),
@@ -70,7 +72,7 @@ impl Deref for Context {
}
/// 对称网络增加的udp socket数目,有助于增加打洞成功率
pub const SYMMETRIC_CHANNEL_NUM: usize = 64;
pub const SYMMETRIC_CHANNEL_NUM: usize = 100;
const PACKET_LOSS_RATE_DENOMINATOR: u32 = 100_0000;
pub struct ContextInner {
// 核心udp socket
@@ -90,6 +92,7 @@ pub struct ContextInner {
//控制延迟
packet_delay: u32,
main_index: AtomicUsize,
use_ipv6: bool,
}
impl ContextInner {
@@ -172,15 +175,16 @@ impl ContextInner {
}
}
pub fn send_main_udp(&self, index: usize, buf: &[u8], mut addr: SocketAddr) -> io::Result<()> {
//核心udp socket都是ipv6模式,如果是v4地址则需要转换成v6
//只有服务器地址可能需要这样转换
if let SocketAddr::V4(ipv4) = addr {
addr = SocketAddr::V6(SocketAddrV6::new(
ipv4.ip().to_ipv6_mapped(),
ipv4.port(),
0,
0,
));
if self.use_ipv6 {
//如果是v4地址则需要转换成v6
if let SocketAddr::V4(ipv4) = addr {
addr = SocketAddr::V6(SocketAddrV6::new(
ipv4.ip().to_ipv6_mapped(),
ipv4.port(),
0,
0,
));
}
}
self.main_udp_socket[index].send_to(buf, addr)?;
Ok(())
@@ -208,17 +212,9 @@ impl ContextInner {
thread::sleep(Duration::from_millis(1));
}
}
pub fn try_send_all_main(&self, buf: &[u8], mut addr: SocketAddr) {
if let SocketAddr::V4(ipv4) = addr {
addr = SocketAddr::V6(SocketAddrV6::new(
ipv4.ip().to_ipv6_mapped(),
ipv4.port(),
0,
0,
));
}
for udp in &self.main_udp_socket {
if let Err(e) = udp.send_to(buf, addr) {
pub fn try_send_all_main(&self, buf: &[u8], addr: SocketAddr) {
for index in 0..self.channel_num() {
if let Err(e) = self.send_main_udp(index, buf, addr) {
log::warn!("{:?},add={:?}", e, addr);
}
}
@@ -229,6 +225,7 @@ impl ContextInner {
buf: &[u8],
id: &Ipv4Addr,
server_addr: SocketAddr,
send_default: bool,
) -> io::Result<()> {
if self.packet_loss_rate > 0 {
if rand::thread_rng().gen_ratio(self.packet_loss_rate, PACKET_LOSS_RATE_DENOMINATOR) {
@@ -243,7 +240,7 @@ impl ContextInner {
if e.kind() != io::ErrorKind::NotFound {
log::warn!("{}:{:?}", id, e);
}
if !self.route_table.use_channel_type.is_only_p2p() {
if !self.route_table.use_channel_type.is_only_p2p() && send_default {
//符合条件再发到服务器转发
self.send_default(buf, server_addr)?;
}
@@ -485,9 +482,10 @@ impl RouteTable {
let table = self.route_table.read();
let mut list = Vec::with_capacity(8);
for (ip, (_, routes)) in table.iter() {
if let Some((route, _)) = routes.first() {
for (route, _) in routes.iter() {
if route.is_p2p() {
list.push((*ip, *route));
break;
}
}
}
+42 -11
View File
@@ -154,13 +154,31 @@ pub fn init_context(
) -> io::Result<(Context, mio::net::TcpListener)> {
assert!(!ports.is_empty(), "not channel");
let mut udps = Vec::with_capacity(ports.len());
//检查系统是否支持ipv6
let use_ipv6 = match socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::DGRAM, None) {
Ok(_) => true,
Err(e) => {
log::warn!("{:?}", e);
false
}
};
for port in &ports {
//监听v6+v4双栈
let address: SocketAddr = format!("[::]:{}", port).parse().unwrap();
let socket = socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::DGRAM, None)?;
io_convert(socket.set_only_v6(false), |_| {
format!("set_only_v6 failed: {}", &address)
})?;
let (socket, address) = if use_ipv6 {
let address: SocketAddr = format!("[::]:{}", port).parse().unwrap();
let socket = socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::DGRAM, None)?;
io_convert(socket.set_only_v6(false), |_| {
format!("set_only_v6 failed: {}", &address)
})?;
(socket, address)
} else {
let address: SocketAddr = format!("0.0.0.0:{}", port).parse().unwrap();
(
socket2::Socket::new(socket2::Domain::IPV4, socket2::Type::DGRAM, None)?,
address,
)
};
io_convert(socket.set_reuse_address(true), |_| {
format!("set_reuse_address failed: {}", &address)
})?;
@@ -184,15 +202,24 @@ pub fn init_context(
is_tcp,
packet_loss_rate,
packet_delay,
use_ipv6,
);
let port = context.main_local_udp_port()?[0];
//监听v6+v4双栈,tcp通道使用异步io
let address: SocketAddr = format!("[::]:{}", port).parse().unwrap();
let socket = socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::STREAM, None)?;
io_convert(socket.set_only_v6(false), |_| {
format!("set_only_v6 failed: {}", &address)
})?;
let (socket, address) = if use_ipv6 {
let address: SocketAddr = format!("[::]:{}", port).parse().unwrap();
let socket = socket2::Socket::new(socket2::Domain::IPV6, socket2::Type::STREAM, None)?;
io_convert(socket.set_only_v6(false), |_| {
format!("set_only_v6 failed: {}", &address)
})?;
(socket, address)
} else {
let address: SocketAddr = format!("0.0.0.0:{}", port).parse().unwrap();
let socket = socket2::Socket::new(socket2::Domain::IPV4, socket2::Type::STREAM, None)?;
(socket, address)
};
io_convert(socket.set_reuse_address(true), |_| {
format!("set_reuse_address failed: {}", &address)
})?;
@@ -200,7 +227,11 @@ pub fn init_context(
if ports[0] == 0 {
//端口可能冲突,则使用任意端口
log::warn!("监听tcp端口失败 {:?},重试一次", address);
let address: SocketAddr = format!("[::]:{}", 0).parse().unwrap();
let address: SocketAddr = if use_ipv6 {
format!("[::]:{}", 0).parse().unwrap()
} else {
format!("0.0.0.0:{}", port).parse().unwrap()
};
io_convert(socket.bind(&address.into()), |_| {
format!("bind failed: {}", &address)
})?;
+18 -17
View File
@@ -226,9 +226,9 @@ impl Punch {
}
pub fn punch(&mut self, buf: &[u8], id: Ipv4Addr, nat_info: NatInfo) -> io::Result<()> {
if !self.context.route_table.need_punch(&id) {
log::info!("已打洞成功,无需打洞:{:?}", id);
return Ok(());
}
if self.is_tcp && nat_info.tcp_port != 0 {
//向tcp发起连接
if let Some(ipv6_addr) = nat_info.local_tcp_ipv6addr() {
@@ -301,25 +301,26 @@ impl Punch {
}
let start = *self.port_index.entry(id.clone()).or_insert(0);
let mut end = start + max_k2;
let mut index = end;
if end >= self.port_vec.len() {
if end > self.port_vec.len() {
end = self.port_vec.len();
}
let mut index = start
+ self.punch_symmetric(
&self.port_vec[start..end],
buf,
&nat_info.public_ips,
max_k2,
)?;
if index >= self.port_vec.len() {
index = 0
}
self.punch_symmetric(
&self.port_vec[start..end],
buf,
&nat_info.public_ips,
max_k2,
)?;
self.port_index.insert(id, index);
}
NatType::Cone => {
let is_cone = self.context.is_cone();
for index in 0..channel_num {
let len = nat_info.public_ports.len();
'a: for index in 0..nat_info.public_ports.len().min(channel_num) {
for ip in &nat_info.public_ips {
let port = nat_info.public_ports[index % len];
let port = nat_info.public_ports[index];
if port == 0 || ip.is_unspecified() {
continue;
}
@@ -334,7 +335,7 @@ impl Punch {
}
if !is_cone {
//对称网络数据只发一遍
break;
break 'a;
}
}
}
@@ -348,19 +349,19 @@ impl Punch {
buf: &[u8],
ips: &Vec<Ipv4Addr>,
max: usize,
) -> io::Result<()> {
) -> io::Result<usize> {
let mut count = 0;
for port in ports {
for (index, port) in ports.iter().enumerate() {
for pub_ip in ips {
count += 1;
if count == max {
return Ok(());
return Ok(index);
}
let addr = SocketAddr::V4(SocketAddrV4::new(*pub_ip, *port));
self.context.send_main_udp(0, buf, addr)?;
thread::sleep(Duration::from_millis(2));
}
}
Ok(())
Ok(ports.len())
}
}
+2 -2
View File
@@ -49,7 +49,7 @@ where
};
thread::Builder::new()
.name("tcp读事件处理线程".into())
.name("tcpRead".into())
.spawn(move || {
if let Err(e) = tcp_listen0(
poll,
@@ -173,7 +173,7 @@ fn init_writable_handler(
{
let writable_notify = writable_notify.clone();
thread::Builder::new()
.name("tcp-writeable-listen".into())
.name("tcpWriteableListen".into())
.spawn(move || {
if let Err(e) = tcp_writable_listen(receiver, poll, writable_notify, &context) {
log::error!("{:?}", e);
+9 -3
View File
@@ -49,7 +49,7 @@ where
};
let accept = AcceptSocketSender::new(waker.clone(), udp_sender);
thread::Builder::new()
.name("sub_udp读事件处理线程".into())
.name("subUdp".into())
.spawn(move || {
if let Err(e) = sub_udp_listen0(poll, recv_handler, context, waker, udp_receiver) {
log::error!("{:?}", e);
@@ -153,7 +153,7 @@ where
}
})?;
thread::Builder::new()
.name("main_udp".into())
.name("mainUdp".into())
.spawn(move || {
if let Err(e) = main_udp_listen0(poll, recv_handler, context) {
log::error!("{:?}", e);
@@ -188,8 +188,14 @@ where
NOTIFY => return Ok(()),
Token(index) => index - 1,
};
let udp = if let Some(udp) = udps.get(index) {
udp
} else {
log::error!("{:?}", x);
continue;
};
loop {
match udps[index].recv_from(&mut buf) {
match udp.recv_from(&mut buf) {
Ok((len, addr)) => {
recv_handler.handle(
&mut buf[..len],
+13
View File
@@ -205,6 +205,8 @@ impl Vnt {
let context = context.clone();
let nat_test = nat_test.clone();
let device_list = device_list.clone();
let down_count_watcher = down_count_watcher.clone();
let up_count_watcher = up_count_watcher.clone();
let current_device = current_device.clone();
if !config.use_channel_type.is_only_relay() {
// 定时nat探测
@@ -229,6 +231,8 @@ impl Vnt {
config_info,
punch,
callback,
down_count_watcher,
up_count_watcher,
);
});
}
@@ -259,6 +263,8 @@ pub fn start<Call: VntCallback>(
config_info: BaseConfigInfo,
punch: Punch,
callback: Call,
down_count_watcher: WatchU64Adder,
up_count_watcher: WatchSingleU64Adder,
) {
// 定时心跳
maintain::heartbeat(
@@ -310,6 +316,13 @@ pub fn start<Call: VntCallback>(
punch,
);
}
maintain::up_status(
scheduler,
context.clone(),
current_device.clone(),
down_count_watcher,
up_count_watcher,
)
}
impl Vnt {
+1 -1
View File
@@ -37,7 +37,7 @@ impl Handshake {
pub fn send(&self, context: &Context, secret: bool, addr: SocketAddr) -> io::Result<()> {
let last = self.time.load();
//短时间不重复发送
if last.elapsed() < Duration::from_secs(5) {
if last.elapsed() < Duration::from_secs(3) {
return Ok(());
}
let request_packet = handshake_request_packet(secret)?;
+20 -26
View File
@@ -1,4 +1,3 @@
use std::net::ToSocketAddrs;
use std::sync::Arc;
use std::time::Duration;
@@ -16,12 +15,25 @@ pub fn addr_request(
context: Context,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
server_cipher: Cipher,
config: BaseConfigInfo,
_config: BaseConfigInfo,
) {
addr_request0(&context, &current_device_info, &server_cipher, &config);
// 9秒发送一次
let rs = scheduler.timeout(Duration::from_secs(9), |s| {
addr_request(s, context, current_device_info, server_cipher, config)
pub_address_request(
scheduler,
context,
current_device_info.clone(),
server_cipher,
);
}
pub fn pub_address_request(
scheduler: &Scheduler,
context: Context,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
server_cipher: Cipher,
) {
addr_request0(&context, &current_device_info, &server_cipher);
// 17秒发送一次
let rs = scheduler.timeout(Duration::from_secs(17), |s| {
pub_address_request(s, context, current_device_info, server_cipher)
});
if !rs {
log::info!("定时任务停止");
@@ -32,27 +44,9 @@ pub fn addr_request0(
context: &Context,
current_device: &AtomicCell<CurrentDeviceInfo>,
server_cipher: &Cipher,
config: &BaseConfigInfo,
) {
let mut current_dev = current_device.load();
// 探测服务端地址变化
if let Ok(mut addr) = config.server_addr.to_socket_addrs() {
if let Some(addr) = addr.next() {
if addr != current_dev.connect_server {
let mut tmp = current_dev.clone();
tmp.connect_server = addr;
let rs = current_device.compare_exchange(current_dev, tmp);
current_dev.connect_server = addr;
log::info!(
"服务端地址变化,旧地址:{},新地址:{},替换结果:{}",
current_dev.connect_server,
addr,
rs.is_ok()
);
}
}
}
if current_dev.connect_server.is_ipv4() {
let current_dev = current_device.load();
if current_dev.connect_server.is_ipv4() && current_dev.status.online() {
// 如果连接的是ipv4服务,则探测公网端口
let gateway_ip = current_dev.virtual_gateway;
let src_ip = current_dev.virtual_ip;
+2 -2
View File
@@ -12,7 +12,7 @@ use crate::cipher::Cipher;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::control_packet::PingPacket;
use crate::protocol::{control_packet, NetPacket, Protocol, Version, MAX_TTL};
use crate::protocol::{control_packet, NetPacket, Protocol, Version};
use crate::util::Scheduler;
/// 定时发送心跳包
@@ -216,7 +216,7 @@ fn heartbeat_packet(
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(MAX_TTL);
net_packet.first_set_ttl(5);
net_packet.set_source(src);
net_packet.set_destination(dest);
let mut ping = PingPacket::new(net_packet.payload_mut())?;
+69 -10
View File
@@ -1,3 +1,11 @@
use std::io;
use std::net::{SocketAddr, ToSocketAddrs};
use std::sync::Arc;
use std::time::{Duration, Instant};
use crossbeam_utils::atomic::AtomicCell;
use mio::net::TcpStream;
use crate::channel::context::Context;
use crate::channel::idle::{Idle, IdleType};
use crate::channel::sender::AcceptSocketSender;
@@ -6,12 +14,6 @@ use crate::handle::handshaker::Handshake;
use crate::handle::{handshaker, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo};
use crate::util::Scheduler;
use crate::{ErrorInfo, VntCallback};
use crossbeam_utils::atomic::AtomicCell;
use mio::net::TcpStream;
use std::io;
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
pub fn idle_route<Call: VntCallback>(
scheduler: &Scheduler,
@@ -29,6 +31,29 @@ pub fn idle_route<Call: VntCallback>(
}
}
pub fn idle_gateway<Call: VntCallback>(
scheduler: &Scheduler,
context: Context,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
config: BaseConfigInfo,
tcp_socket_sender: AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
call: Call,
connect_count: usize,
handshake: Handshake,
) {
let time = Instant::now();
idle_gateway_(
scheduler,
context,
current_device_info,
config,
tcp_socket_sender,
call,
connect_count,
handshake,
time,
);
}
pub fn idle_gateway_<Call: VntCallback>(
scheduler: &Scheduler,
context: Context,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
@@ -37,6 +62,7 @@ pub fn idle_gateway<Call: VntCallback>(
call: Call,
mut connect_count: usize,
handshake: Handshake,
mut time: Instant,
) {
idle_gateway0(
&context,
@@ -46,9 +72,10 @@ pub fn idle_gateway<Call: VntCallback>(
&call,
&mut connect_count,
&handshake,
&mut time,
);
let rs = scheduler.timeout(Duration::from_secs(5), move |s| {
idle_gateway(
idle_gateway_(
s,
context,
current_device_info,
@@ -57,6 +84,7 @@ pub fn idle_gateway<Call: VntCallback>(
call,
connect_count,
handshake,
time,
)
});
if !rs {
@@ -71,6 +99,7 @@ fn idle_gateway0<Call: VntCallback>(
call: &Call,
connect_count: &mut usize,
handshake: &Handshake,
time: &mut Instant,
) {
if let Err(e) = check_gateway_channel(
context,
@@ -80,13 +109,13 @@ fn idle_gateway0<Call: VntCallback>(
call,
connect_count,
handshake,
time,
) {
let cur = current_device.load();
call.error(ErrorInfo::new_msg(
ErrorType::Disconnect,
format!("connect:{},error:{:?}", cur.connect_server, e),
));
log::warn!("{:?}", e);
}
}
fn idle_route0<Call: VntCallback>(
@@ -114,16 +143,22 @@ fn idle_route0<Call: VntCallback>(
fn check_gateway_channel<Call: VntCallback>(
context: &Context,
current_device: &AtomicCell<CurrentDeviceInfo>,
current_device_info: &AtomicCell<CurrentDeviceInfo>,
config: &BaseConfigInfo,
tcp_socket_sender: &AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
call: &Call,
count: &mut usize,
handshake: &Handshake,
time: &mut Instant,
) -> io::Result<()> {
let current_device = current_device.load();
let mut current_device = current_device_info.load();
if current_device.status.offline() {
*count += 1;
if time.elapsed() < Duration::from_secs(6 * 60) {
// 探测服务器地址
current_device = domain_request0(current_device_info, config);
*time = Instant::now()
}
//需要重连
call.connect(ConnectInfo::new(*count, current_device.connect_server));
log::info!("发送握手请求,{:?}", config);
@@ -150,3 +185,27 @@ fn check_gateway_channel<Call: VntCallback>(
}
Ok(())
}
pub fn domain_request0(
current_device: &AtomicCell<CurrentDeviceInfo>,
config: &BaseConfigInfo,
) -> CurrentDeviceInfo {
let mut current_dev = current_device.load();
// 探测服务端地址变化
if let Ok(mut addr) = config.server_addr.to_socket_addrs() {
if let Some(addr) = addr.next() {
if addr != current_dev.connect_server {
let mut tmp = current_dev.clone();
tmp.connect_server = addr;
let rs = current_device.compare_exchange(current_dev, tmp);
current_dev.connect_server = addr;
log::info!(
"服务端地址变化,旧地址:{},新地址:{},替换结果:{}",
current_dev.connect_server,
addr,
rs.is_ok()
);
}
}
}
current_dev
}
+3
View File
@@ -14,3 +14,6 @@ pub use punch::*;
mod idle;
pub use idle::idle_gateway;
pub use idle::idle_route;
mod up_status;
pub use up_status::*;
+61 -29
View File
@@ -1,4 +1,3 @@
use std::cmp::Ordering;
use std::net::Ipv4Addr;
use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use std::sync::Arc;
@@ -11,7 +10,7 @@ use protobuf::Message;
use rand::prelude::SliceRandom;
use crate::channel::context::Context;
use crate::channel::punch::{NatInfo, Punch};
use crate::channel::punch::{NatInfo, NatType, Punch};
use crate::cipher::Cipher;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest;
@@ -24,32 +23,59 @@ use crate::util::Scheduler;
pub struct PunchSender {
sender_self: SyncSender<(Ipv4Addr, NatInfo)>,
sender_peer: SyncSender<(Ipv4Addr, NatInfo)>,
sender_cone_self: SyncSender<(Ipv4Addr, NatInfo)>,
sender_cone_peer: SyncSender<(Ipv4Addr, NatInfo)>,
}
impl PunchSender {
pub fn send(&self, src_peer: bool, ip: Ipv4Addr, info: NatInfo) -> bool {
log::info!("发送打洞协商消息,是否对端发起:{},ip:{},info:{:?}",src_peer,ip, info);
if src_peer {
self.sender_peer.send((ip, info)).is_ok()
} else {
self.sender_self.send((ip, info)).is_ok()
}
log::info!(
"发送打洞协商消息,是否对端发起:{},ip:{},info:{:?}",
src_peer,
ip,
info
);
let sender = match info.nat_type {
NatType::Symmetric => {
if src_peer {
&self.sender_peer
} else {
&self.sender_self
}
}
NatType::Cone => {
if src_peer {
&self.sender_cone_peer
} else {
&self.sender_cone_self
}
}
};
sender.try_send((ip, info)).is_ok()
}
}
pub struct PunchReceiver {
receiver_peer: Receiver<(Ipv4Addr, NatInfo)>,
receiver_self: Receiver<(Ipv4Addr, NatInfo)>,
receiver_cone_peer: Receiver<(Ipv4Addr, NatInfo)>,
receiver_cone_self: Receiver<(Ipv4Addr, NatInfo)>,
}
pub fn punch_channel() -> (PunchSender, PunchReceiver) {
let (sender_self, receiver_self) = sync_channel(1);
let (sender_peer, receiver_peer) = sync_channel(1);
let (sender_cone_peer, receiver_cone_peer) = sync_channel(1);
let (sender_cone_self, receiver_cone_self) = sync_channel(1);
(
PunchSender {
sender_self,
sender_peer,
sender_cone_peer,
sender_cone_self,
},
PunchReceiver {
receiver_peer,
receiver_self,
receiver_cone_peer,
receiver_cone_self,
},
)
}
@@ -73,19 +99,21 @@ pub fn punch(
client_cipher.clone(),
0,
);
let receiver_peer = receiver.receiver_peer;
let receiver_self = receiver.receiver_self;
{
let f = |receiver: Receiver<(Ipv4Addr, NatInfo)>| {
let punch = punch.clone();
let current_device = current_device.clone();
let client_cipher = client_cipher.clone();
thread::spawn(move || {
punch_start(receiver_peer, punch, current_device, client_cipher);
});
}
thread::spawn(move || {
punch_start(receiver_self, punch, current_device, client_cipher);
});
thread::Builder::new()
.name("punch".into())
.spawn(move || {
punch_start(receiver, punch, current_device, client_cipher);
})
.expect("punch");
};
f(receiver.receiver_peer);
f(receiver.receiver_self);
f(receiver.receiver_cone_peer);
f(receiver.receiver_cone_self);
}
/// 接收打洞消息,配合对端打洞
@@ -169,16 +197,16 @@ fn punch0(
.collect();
list.shuffle(&mut rand::thread_rng());
let mut count = 0;
// 优先没打洞的
list.sort_by(|v1, v2| {
if context.route_table.route_one_p2p(&v1.virtual_ip).is_none() {
Ordering::Less
} else if context.route_table.route_one_p2p(&v2.virtual_ip).is_none() {
Ordering::Greater
} else {
Ordering::Equal
}
});
// // 优先没打洞的 need_punch会过滤掉已经打洞成功的
// list.sort_by(|v1, v2| {
// if context.route_table.route_one_p2p(&v1.virtual_ip).is_none() {
// Ordering::Less
// } else if context.route_table.route_one_p2p(&v2.virtual_ip).is_none() {
// Ordering::Greater
// } else {
// Ordering::Equal
// }
// });
for info in list {
if !info.status.is_online() {
continue;
@@ -199,7 +227,11 @@ fn punch0(
&nat_info,
info.virtual_ip,
)?;
log::info!("发起打洞协商请求,目标:{:?},{:?}", info.virtual_ip, nat_info);
log::info!(
"发起打洞协商请求,目标:{:?},{:?}",
info.virtual_ip,
nat_info
);
context.send_default(packet.buffer(), current_device.connect_server)?;
}
Ok(())
+19 -16
View File
@@ -25,21 +25,24 @@ fn retrieve_nat_type0(
nat_test: NatTest,
udp_socket_sender: AcceptSocketSender<Option<Vec<mio::net::UdpSocket>>>,
) {
thread::spawn(move || {
if nat_test.can_update() {
let local_ipv4 = nat::local_ipv4();
let local_ipv6 = nat::local_ipv6();
match nat_test.re_test(local_ipv4, local_ipv6) {
Ok(nat_info) => {
log::info!("当前nat信息:{:?}", nat_info);
if let Err(e) = context.switch(nat_info.nat_type, &udp_socket_sender) {
log::warn!("{:?}", e);
thread::Builder::new()
.name("natTest".into())
.spawn(move || {
if nat_test.can_update() {
let local_ipv4 = nat::local_ipv4();
let local_ipv6 = nat::local_ipv6();
match nat_test.re_test(local_ipv4, local_ipv6) {
Ok(nat_info) => {
log::info!("当前nat信息:{:?}", nat_info);
if let Err(e) = context.switch(nat_info.nat_type, &udp_socket_sender) {
log::warn!("{:?}", e);
}
}
}
Err(e) => {
log::warn!("nat re_test {:?}", e);
}
};
}
});
Err(e) => {
log::warn!("nat re_test {:?}", e);
}
};
}
})
.expect("natTest");
}
+104
View File
@@ -0,0 +1,104 @@
use crate::channel::context::Context;
use crate::handle::CurrentDeviceInfo;
use crate::proto::message::{ClientStatusInfo, PunchNatType, RouteItem};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::{service_packet, NetPacket, Protocol, Version, HEAD_LEN, MAX_TTL};
use crate::util::{Scheduler, WatchSingleU64Adder, WatchU64Adder};
use crossbeam_utils::atomic::AtomicCell;
use protobuf::Message;
use std::io;
use std::sync::Arc;
use std::time::Duration;
/// 上报状态给服务器
pub fn up_status(
scheduler: &Scheduler,
context: Context,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
down_count_watcher: WatchU64Adder,
up_count_watcher: WatchSingleU64Adder,
) {
let _ = scheduler.timeout(Duration::from_secs(60), move |x| {
up_status0(
x,
context,
current_device_info,
down_count_watcher,
up_count_watcher,
)
});
}
fn up_status0(
scheduler: &Scheduler,
context: Context,
current_device_info: Arc<AtomicCell<CurrentDeviceInfo>>,
down_count_watcher: WatchU64Adder,
up_count_watcher: WatchSingleU64Adder,
) {
if let Err(e) = send_up_status_packet(
&context,
&current_device_info,
&down_count_watcher,
&up_count_watcher,
) {
log::warn!("{:?}", e)
}
let rs = scheduler.timeout(Duration::from_secs(10 * 60), move |x| {
up_status0(
x,
context,
current_device_info,
down_count_watcher,
up_count_watcher,
)
});
if !rs {
log::info!("定时任务停止");
}
}
fn send_up_status_packet(
context: &Context,
current_device_info: &AtomicCell<CurrentDeviceInfo>,
down_count_watcher: &WatchU64Adder,
up_count_watcher: &WatchSingleU64Adder,
) -> io::Result<()> {
let device_info = current_device_info.load();
if device_info.status.offline() {
return Ok(());
}
let routes = context.route_table.route_table_p2p();
if routes.is_empty() {
return Ok(());
}
let mut message = ClientStatusInfo::new();
message.source = device_info.virtual_ip.into();
for (ip, _) in routes {
let mut item = RouteItem::new();
item.next_ip = ip.into();
message.p2p_list.push(item);
}
message.up_stream = up_count_watcher.get();
message.down_stream = down_count_watcher.get();
message.nat_type = protobuf::EnumOrUnknown::new(if context.is_cone() {
PunchNatType::Cone
} else {
PunchNatType::Symmetric
});
let buf = message
.write_to_bytes()
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("up_status_packet {:?}", e)))?;
let mut net_packet =
NetPacket::new_encrypt(vec![0; HEAD_LEN + buf.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_into(service_packet::Protocol::ClientStatusInfo);
net_packet.first_set_ttl(MAX_TTL);
net_packet.set_source(device_info.virtual_ip);
net_packet.set_destination(device_info.virtual_gateway);
net_packet.set_payload(&buf)?;
context.send_default(net_packet.buffer(), device_info.connect_server)?;
Ok(())
}
+1 -1
View File
@@ -320,8 +320,8 @@ impl ClientPacketHandler {
punch_packet.set_source(current_device.virtual_ip());
punch_packet.set_destination(source);
punch_packet.set_payload(&bytes)?;
self.client_cipher.encrypt_ipv4(&mut punch_packet)?;
if self.punch_sender.send(true, source, peer_nat_info) {
self.client_cipher.encrypt_ipv4(&mut punch_packet)?;
context.send_by_key(punch_packet.buffer(), route_key)?;
}
} else {
+10 -12
View File
@@ -268,6 +268,7 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
log::info!("ip发生变化,old:{:?},response={:?}", old, response);
}
if let Err(e) = self.device.set_ip(virtual_ip, virtual_netmask) {
log::error!("LocalIpExists {:?}", e);
self.callback.error(ErrorInfo::new_msg(
ErrorType::LocalIpExists,
format!("set_ip {:?}", e),
@@ -319,26 +320,22 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
self.set_device_info_list(response.device_info_list, response.epoch as _);
}
}
service_packet::Protocol::RegistrationRequest => {
//不处理注册包
}
service_packet::Protocol::PollDeviceList => {}
service_packet::Protocol::PushDeviceList => {
let response = DeviceList::parse_from_bytes(net_packet.payload()).map_err(|e| {
io::Error::new(io::ErrorKind::Other, format!("PushDeviceList {:?}", e))
})?;
self.set_device_info_list(response.device_info_list, response.epoch as _);
}
service_packet::Protocol::HandshakeRequest => {}
service_packet::Protocol::HandshakeResponse => {}
service_packet::Protocol::SecretHandshakeRequest => {}
service_packet::Protocol::SecretHandshakeResponse => {
log::info!("SecretHandshakeResponse");
//加密握手结束,发送注册数据
self.register(current_device, context)?;
}
service_packet::Protocol::Unknown(e) => {
log::warn!("service_packet::Protocol::Unknown = {}", e);
_ => {
log::warn!(
"service_packet::Protocol::Unknown = {:?}",
net_packet.head()
);
}
}
Ok(())
@@ -369,7 +366,10 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
let device_id = self.config_info.device_id.clone();
let name = self.config_info.name.clone();
let client_secret = self.config_info.client_secret;
let ip = self.config_info.ip;
let mut ip = self.config_info.ip;
if ip.is_none() {
ip = Some(current_device.virtual_ip)
}
let response = registrar::registration_request_packet(
&self.server_cipher,
token,
@@ -421,12 +421,10 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
self.callback.error(err);
}
InErrorPacket::IpAlreadyExists => {
log::error!("IpAlreadyExists");
let err = ErrorInfo::new(ErrorType::IpAlreadyExists);
self.callback.error(err);
}
InErrorPacket::InvalidIp => {
log::error!("InvalidIp");
let err = ErrorInfo::new(ErrorType::InvalidIp);
self.callback.error(err);
}
+6 -1
View File
@@ -18,7 +18,7 @@ impl PacketHandler for TurnPacketHandler {
fn handle(
&self,
mut net_packet: NetPacket<&mut [u8]>,
_route_key: RouteKey,
route_key: RouteKey,
context: &Context,
_current_device: &CurrentDeviceInfo,
) -> std::io::Result<()> {
@@ -27,6 +27,11 @@ impl PacketHandler for TurnPacketHandler {
if ttl > 0 {
let destination = net_packet.destination();
if let Some(route) = context.route_table.route_one(&destination) {
if route.addr == route_key.addr {
//防止环路
log::warn!("来源和目标相同 {:?},{:?}", route_key, net_packet.head());
return Ok(());
}
if route.metric <= ttl {
context.send_by_key(net_packet.buffer(), route.route_key())?;
}
+9 -3
View File
@@ -33,6 +33,7 @@ fn broadcast(
continue;
}
if peer_ips.len() == MAX_COUNT {
relay_count += 1;
break;
}
if route.is_p2p()
@@ -45,7 +46,7 @@ fn broadcast(
relay_count += 1;
}
}
if relay_count == 0 && !peer_ips.is_empty() && peer_ips.len() != MAX_COUNT {
if (relay_count == 0 && !peer_ips.is_empty()) || current_device.status.offline() {
//不需要转发
return Ok(());
}
@@ -97,7 +98,7 @@ pub fn base_handle(
net_packet.set_version(Version::V1);
net_packet.set_protocol(protocol::Protocol::IpTurn);
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4.into());
net_packet.first_set_ttl(3);
net_packet.first_set_ttl(6);
net_packet.set_source(src_ip);
net_packet.set_destination(dest_ip);
if dest_ip == current_device.virtual_gateway {
@@ -143,5 +144,10 @@ pub fn base_handle(
proxy_map.send_handle(&mut ipv4_packet)?;
}
client_cipher.encrypt_ipv4(&mut net_packet)?;
context.send_ipv4_by_id(net_packet.buffer(), &dest_ip, current_device.connect_server)
context.send_ipv4_by_id(
net_packet.buffer(),
&dest_ip,
current_device.connect_server,
current_device.status.online(),
)
}
+3 -3
View File
@@ -111,7 +111,7 @@ pub fn start(
let client_cipher = client_cipher.clone();
let server_cipher = server_cipher.clone();
thread::Builder::new()
.name(format!("tun_handler_{}", index))
.name(format!("tunHandler-{}", index))
.spawn(move || {
while let Ok((mut buf, len)) = receiver.recv() {
#[cfg(not(target_os = "macos"))]
@@ -139,7 +139,7 @@ pub fn start(
})?;
}
thread::Builder::new()
.name("tun_handler".into())
.name("tunHandlerM".into())
.spawn(move || {
if let Err(e) = start_multi(stop_manager, device, sender, &mut up_counter) {
log::warn!("stop:{}", e);
@@ -148,7 +148,7 @@ pub fn start(
})?;
} else {
thread::Builder::new()
.name("tun_handler".into())
.name("tunHandlerS".into())
.spawn(move || {
if let Err(e) = start_simple(
stop_manager,
+16 -12
View File
@@ -47,18 +47,21 @@ impl IcmpProxy {
Arc::new(Mutex::new(HashMap::with_capacity(16)));
{
let nat_map = nat_map.clone();
thread::spawn(move || {
if let Err(e) = icmp_proxy(
mio_icmp_socket,
nat_map,
context,
stop_manager,
current_device,
client_cipher,
) {
log::warn!("icmp_proxy:{:?}", e);
}
});
thread::Builder::new()
.name("icmpProxy".into())
.spawn(move || {
if let Err(e) = icmp_proxy(
mio_icmp_socket,
nat_map,
context,
stop_manager,
current_device,
client_cipher,
) {
log::warn!("icmp_proxy:{:?}", e);
}
})
.expect("icmpProxy");
}
Ok(Self {
icmp_socket: Arc::new(std_socket),
@@ -185,6 +188,7 @@ fn recv_handle(
net_packet.buffer(),
&dest_ip,
current_device.connect_server,
current_device.status.online(),
) {
log::warn!("发送到目标失败:{}", e);
}
+8 -5
View File
@@ -38,11 +38,14 @@ impl TcpProxy {
let port = tcp_listener.local_addr()?.port();
{
let nat_map = nat_map.clone();
thread::spawn(move || {
if let Err(e) = tcp_proxy(tcp_listener, nat_map, stop_manager) {
log::warn!("tcp_proxy:{:?}", e);
}
});
thread::Builder::new()
.name("tcpProxy".into())
.spawn(move || {
if let Err(e) = tcp_proxy(tcp_listener, nat_map, stop_manager) {
log::warn!("tcp_proxy:{:?}", e);
}
})
.expect("tcpProxy");
}
Ok(Self { port, nat_map })
}
+8 -5
View File
@@ -40,11 +40,14 @@ impl UdpProxy {
let port = udp.local_addr()?.port();
{
let nat_map = nat_map.clone();
thread::spawn(move || {
if let Err(e) = udp_proxy(udp, nat_map, scheduler, stop_manager) {
log::warn!("udp_proxy:{:?}", e);
}
});
thread::Builder::new()
.name("udpProxy".into())
.spawn(move || {
if let Err(e) = udp_proxy(udp, nat_map, scheduler, stop_manager) {
log::warn!("udp_proxy:{:?}", e);
}
})
.expect("udpProxy");
}
Ok(Self { port, nat_map })
}
+328 -3
View File
@@ -1622,6 +1622,323 @@ impl ::protobuf::reflect::ProtobufValue for PunchInfo {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}
#[derive(PartialEq,Clone,Default,Debug)]
// @@protoc_insertion_point(message:ClientStatusInfo)
pub struct ClientStatusInfo {
// message fields
// @@protoc_insertion_point(field:ClientStatusInfo.source)
pub source: u32,
// @@protoc_insertion_point(field:ClientStatusInfo.p2p_list)
pub p2p_list: ::std::vec::Vec<RouteItem>,
// @@protoc_insertion_point(field:ClientStatusInfo.up_stream)
pub up_stream: u64,
// @@protoc_insertion_point(field:ClientStatusInfo.down_stream)
pub down_stream: u64,
// @@protoc_insertion_point(field:ClientStatusInfo.nat_type)
pub nat_type: ::protobuf::EnumOrUnknown<PunchNatType>,
// special fields
// @@protoc_insertion_point(special_field:ClientStatusInfo.special_fields)
pub special_fields: ::protobuf::SpecialFields,
}
impl<'a> ::std::default::Default for &'a ClientStatusInfo {
fn default() -> &'a ClientStatusInfo {
<ClientStatusInfo as ::protobuf::Message>::default_instance()
}
}
impl ClientStatusInfo {
pub fn new() -> ClientStatusInfo {
::std::default::Default::default()
}
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
let mut fields = ::std::vec::Vec::with_capacity(5);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
"source",
|m: &ClientStatusInfo| { &m.source },
|m: &mut ClientStatusInfo| { &mut m.source },
));
fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
"p2p_list",
|m: &ClientStatusInfo| { &m.p2p_list },
|m: &mut ClientStatusInfo| { &mut m.p2p_list },
));
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
"up_stream",
|m: &ClientStatusInfo| { &m.up_stream },
|m: &mut ClientStatusInfo| { &mut m.up_stream },
));
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
"down_stream",
|m: &ClientStatusInfo| { &m.down_stream },
|m: &mut ClientStatusInfo| { &mut m.down_stream },
));
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
"nat_type",
|m: &ClientStatusInfo| { &m.nat_type },
|m: &mut ClientStatusInfo| { &mut m.nat_type },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ClientStatusInfo>(
"ClientStatusInfo",
fields,
oneofs,
)
}
}
impl ::protobuf::Message for ClientStatusInfo {
const NAME: &'static str = "ClientStatusInfo";
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 {
13 => {
self.source = is.read_fixed32()?;
},
18 => {
self.p2p_list.push(is.read_message()?);
},
24 => {
self.up_stream = is.read_uint64()?;
},
32 => {
self.down_stream = is.read_uint64()?;
},
40 => {
self.nat_type = is.read_enum_or_unknown()?;
},
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.source != 0 {
my_size += 1 + 4;
}
for value in &self.p2p_list {
let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
};
if self.up_stream != 0 {
my_size += ::protobuf::rt::uint64_size(3, self.up_stream);
}
if self.down_stream != 0 {
my_size += ::protobuf::rt::uint64_size(4, self.down_stream);
}
if self.nat_type != ::protobuf::EnumOrUnknown::new(PunchNatType::Symmetric) {
my_size += ::protobuf::rt::int32_size(5, self.nat_type.value());
}
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.source != 0 {
os.write_fixed32(1, self.source)?;
}
for v in &self.p2p_list {
::protobuf::rt::write_message_field_with_cached_size(2, v, os)?;
};
if self.up_stream != 0 {
os.write_uint64(3, self.up_stream)?;
}
if self.down_stream != 0 {
os.write_uint64(4, self.down_stream)?;
}
if self.nat_type != ::protobuf::EnumOrUnknown::new(PunchNatType::Symmetric) {
os.write_enum(5, ::protobuf::EnumOrUnknown::value(&self.nat_type))?;
}
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() -> ClientStatusInfo {
ClientStatusInfo::new()
}
fn clear(&mut self) {
self.source = 0;
self.p2p_list.clear();
self.up_stream = 0;
self.down_stream = 0;
self.nat_type = ::protobuf::EnumOrUnknown::new(PunchNatType::Symmetric);
self.special_fields.clear();
}
fn default_instance() -> &'static ClientStatusInfo {
static instance: ClientStatusInfo = ClientStatusInfo {
source: 0,
p2p_list: ::std::vec::Vec::new(),
up_stream: 0,
down_stream: 0,
nat_type: ::protobuf::EnumOrUnknown::from_i32(0),
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
}
}
impl ::protobuf::MessageFull for ClientStatusInfo {
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("ClientStatusInfo").unwrap()).clone()
}
}
impl ::std::fmt::Display for ClientStatusInfo {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for ClientStatusInfo {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}
#[derive(PartialEq,Clone,Default,Debug)]
// @@protoc_insertion_point(message:RouteItem)
pub struct RouteItem {
// message fields
// @@protoc_insertion_point(field:RouteItem.next_ip)
pub next_ip: u32,
// special fields
// @@protoc_insertion_point(special_field:RouteItem.special_fields)
pub special_fields: ::protobuf::SpecialFields,
}
impl<'a> ::std::default::Default for &'a RouteItem {
fn default() -> &'a RouteItem {
<RouteItem as ::protobuf::Message>::default_instance()
}
}
impl RouteItem {
pub fn new() -> RouteItem {
::std::default::Default::default()
}
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
let mut fields = ::std::vec::Vec::with_capacity(1);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>(
"next_ip",
|m: &RouteItem| { &m.next_ip },
|m: &mut RouteItem| { &mut m.next_ip },
));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<RouteItem>(
"RouteItem",
fields,
oneofs,
)
}
}
impl ::protobuf::Message for RouteItem {
const NAME: &'static str = "RouteItem";
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 {
13 => {
self.next_ip = is.read_fixed32()?;
},
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.next_ip != 0 {
my_size += 1 + 4;
}
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.next_ip != 0 {
os.write_fixed32(1, self.next_ip)?;
}
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() -> RouteItem {
RouteItem::new()
}
fn clear(&mut self) {
self.next_ip = 0;
self.special_fields.clear();
}
fn default_instance() -> &'static RouteItem {
static instance: RouteItem = RouteItem {
next_ip: 0,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
}
}
impl ::protobuf::MessageFull for RouteItem {
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("RouteItem").unwrap()).clone()
}
}
impl ::std::fmt::Display for RouteItem {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for RouteItem {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}
#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
// @@protoc_insertion_point(enum:PunchNatType)
pub enum PunchNatType {
@@ -1713,8 +2030,14 @@ static file_descriptor_proto_data: &'static [u8] = b"\
6\x18\t\x20\x01(\x0cR\x04ipv6\x12\x1b\n\tipv6_port\x18\n\x20\x01(\rR\x08\
ipv6Port\x12\x19\n\x08tcp_port\x18\x0b\x20\x01(\rR\x07tcpPort\x12\x1b\n\
\tudp_ports\x18\x0c\x20\x03(\rR\x08udpPorts\x12!\n\x0cpublic_ports\x18\r\
\x20\x03(\rR\x0bpublicPorts*'\n\x0cPunchNatType\x12\r\n\tSymmetric\x10\0\
\x12\x08\n\x04Cone\x10\x01b\x06proto3\
\x20\x03(\rR\x0bpublicPorts\"\xb9\x01\n\x10ClientStatusInfo\x12\x16\n\
\x06source\x18\x01\x20\x01(\x07R\x06source\x12%\n\x08p2p_list\x18\x02\
\x20\x03(\x0b2\n.RouteItemR\x07p2pList\x12\x1b\n\tup_stream\x18\x03\x20\
\x01(\x04R\x08upStream\x12\x1f\n\x0bdown_stream\x18\x04\x20\x01(\x04R\nd\
ownStream\x12(\n\x08nat_type\x18\x05\x20\x01(\x0e2\r.PunchNatTypeR\x07na\
tType\"$\n\tRouteItem\x12\x17\n\x07next_ip\x18\x01\x20\x01(\x07R\x06next\
Ip*'\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
@@ -1732,7 +2055,7 @@ 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(8);
let mut messages = ::std::vec::Vec::with_capacity(10);
messages.push(HandshakeRequest::generated_message_descriptor_data());
messages.push(HandshakeResponse::generated_message_descriptor_data());
messages.push(SecretHandshakeRequest::generated_message_descriptor_data());
@@ -1741,6 +2064,8 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
messages.push(DeviceInfo::generated_message_descriptor_data());
messages.push(DeviceList::generated_message_descriptor_data());
messages.push(PunchInfo::generated_message_descriptor_data());
messages.push(ClientStatusInfo::generated_message_descriptor_data());
messages.push(RouteItem::generated_message_descriptor_data());
let mut enums = ::std::vec::Vec::with_capacity(1);
enums.push(PunchNatType::generated_enum_descriptor_data());
::protobuf::reflect::GeneratedFileDescriptor::new_generated(
+6
View File
@@ -183,6 +183,9 @@ impl<B: AsRef<[u8]>> NetPacket<B> {
pub fn payload(&self) -> &[u8] {
&self.buffer.as_ref()[12..self.data_len]
}
pub fn head(&self) -> &[u8] {
&self.buffer.as_ref()[..12]
}
}
impl<B: AsRef<[u8]> + AsMut<[u8]>> NetPacket<B> {
@@ -214,6 +217,9 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> NetPacket<B> {
pub fn set_transport_protocol(&mut self, transport_protocol: u8) {
self.buffer.as_mut()[2] = transport_protocol;
}
pub fn set_transport_protocol_into<P: Into<u8>>(&mut self, transport_protocol: P) {
self.buffer.as_mut()[2] = transport_protocol.into();
}
pub fn first_set_ttl(&mut self, ttl: u8) {
self.buffer.as_mut()[3] = ttl << 4 | ttl;
}
+4
View File
@@ -13,6 +13,8 @@ pub enum Protocol {
HandshakeResponse,
SecretHandshakeRequest,
SecretHandshakeResponse,
/// 客户端上报状态
ClientStatusInfo,
Unknown(u8),
}
@@ -27,6 +29,7 @@ impl From<u8> for Protocol {
6 => Self::HandshakeResponse,
7 => Self::SecretHandshakeRequest,
8 => Self::SecretHandshakeResponse,
9 => Self::ClientStatusInfo,
val => Self::Unknown(val),
}
}
@@ -43,6 +46,7 @@ impl Into<u8> for Protocol {
Self::HandshakeResponse => 6,
Self::SecretHandshakeRequest => 7,
Self::SecretHandshakeResponse => 8,
Self::ClientStatusInfo => 9,
Self::Unknown(val) => val,
}
}
+1 -1
View File
@@ -52,7 +52,7 @@ impl Scheduler {
run(receiver, s_inner);
worker.stop_all();
})
.unwrap();
.expect("Scheduler");
Ok(s)
}
pub fn timeout<F>(&self, time: Duration, f: F) -> bool
+3 -1
View File
@@ -96,7 +96,9 @@ impl Device {
.map_err(|e| io::Error::new(e.kind(), format!("TAP_WIN_IOCTL_GET_MAC,err={:?}", e)))?;
let index = ffi::luid_to_index(&luid).map(|index| index as u32)?;
// 设置网卡跃点
netsh::set_interface_metric(index, 0)?;
if let Err(e) = netsh::set_interface_metric(index, 0) {
log::warn!("{:?}",e);
}
let device = Self {
handle,
index,
+3 -1
View File
@@ -117,7 +117,9 @@ impl Device {
win_tun.WintunGetAdapterLUID(adapter, &mut luid as *mut wintun_raw::NET_LUID);
let index = ffi::luid_to_index(&std::mem::transmute(luid)).map(|index| index as u32)?;
// 设置网卡跃点
netsh::set_interface_metric(index, 0)?;
if let Err(e) = netsh::set_interface_metric(index, 0) {
log::warn!("{:?}",e);
}
Ok(Self {
luid: std::mem::transmute(luid),
index,