优化代码
This commit is contained in:
@@ -47,16 +47,17 @@
|
||||
|
||||
1. 和远程桌面(如mstsc)搭配,超低延迟的体验
|
||||
2. 安装samba服务,共享磁盘
|
||||
3. 搭配nginx,在公网访问本地文件
|
||||
3. 搭配公网服务器nginx反向代理,在公网访问本地文件
|
||||
|
||||
|
||||
### 使用须知
|
||||
- token的作用是标识一个虚拟局域网,当使用公共服务器时,建议使用一个唯一值当token(比如uuid),否则有可能连接到其他人创建的虚拟局域网中
|
||||
- 建议指定deviceId,默认使用MAC地址,在某些环境下可能发生变化
|
||||
- 公共服务器目前的配置是2核4G 4Mbps,有需要再扩展~
|
||||
- 需要root/管理员权限
|
||||
- 使用命令行运行
|
||||
- Mac和Linux下需要加可执行权限(例如:chmod +x ./switch-macos)
|
||||
|
||||
- 自己搭注册和中继服务器(https://github.com/lbl8603/switch-server)
|
||||
### 编译
|
||||
前提条件:安装rust编译环境(https://www.rust-lang.org/zh-CN/tools/install)
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ crossbeam = "0.8.2"
|
||||
lazy_static = "1.4.0"
|
||||
parking_lot = "0.12.1"
|
||||
|
||||
fd-lock = "3.0.10"
|
||||
fs2 = "0.4.3"
|
||||
|
||||
os_info = "3.5.1"
|
||||
[target.'cfg(any(target_os = "linux",target_os = "macos"))'.dependencies]
|
||||
|
||||
@@ -156,10 +156,9 @@ impl ArgsConfig {
|
||||
}
|
||||
}
|
||||
}
|
||||
use fd_lock::RwLock;
|
||||
pub fn lock_config() -> io::Result<RwLock<File>> {
|
||||
let config_path = SWITCH_HOME_PATH.lock().clone().unwrap().join("config");
|
||||
Ok(RwLock::new(File::open(config_path)?))
|
||||
pub fn lock_file() -> io::Result<File> {
|
||||
let path = SWITCH_HOME_PATH.lock().clone().unwrap().join(".lock");
|
||||
Ok(File::create(path)?)
|
||||
}
|
||||
|
||||
pub fn save_config(config: ArgsConfig) -> io::Result<()> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use console::style;
|
||||
use console::{style, Style};
|
||||
|
||||
use crate::command::entity::{DeviceItem, RouteItem, Status};
|
||||
|
||||
@@ -16,51 +16,118 @@ pub fn console_status(status: Status) {
|
||||
println!("Local ip: {}", style(status.local_ip).green());
|
||||
}
|
||||
|
||||
pub fn console_route_table(list: Vec<RouteItem>) {
|
||||
pub fn console_route_table(mut list: Vec<RouteItem>) {
|
||||
if list.is_empty() {
|
||||
println!("No route found");
|
||||
return;
|
||||
}
|
||||
list.sort_by(|t1, t2| t1.destination.cmp(&t2.destination));
|
||||
let mut out_list = Vec::with_capacity(list.len());
|
||||
//表头
|
||||
out_list.push(vec!["Destination".to_string(), "Next Hop".to_string(), "Metric".to_string(),
|
||||
"Rt".to_string(), "Interface".to_string()]);
|
||||
|
||||
out_list.push(vec![("Destination".to_string(), Style::new()),
|
||||
("Next Hop".to_string(), Style::new()),
|
||||
("Metric".to_string(), Style::new()),
|
||||
("Rt".to_string(), Style::new()),
|
||||
("Interface".to_string(), Style::new()), ]);
|
||||
for item in list {
|
||||
out_list.push(vec![item.destination, item.next_hop, item.metric,
|
||||
item.rt, item.interface]);
|
||||
out_list.push(vec![(item.destination, Style::new().green()),
|
||||
(item.next_hop, Style::new().green()),
|
||||
(item.metric, Style::new().green()),
|
||||
(item.rt, Style::new().green()),
|
||||
(item.interface, Style::new().green())]);
|
||||
}
|
||||
|
||||
table::println_table(out_list)
|
||||
}
|
||||
|
||||
pub fn console_device_list(list: Vec<DeviceItem>) {
|
||||
pub fn console_device_list(mut list: Vec<DeviceItem>) {
|
||||
if list.is_empty() {
|
||||
println!("No other devices found");
|
||||
return;
|
||||
}
|
||||
list.sort_by(|t1, t2| t1.virtual_ip.cmp(&t2.virtual_ip));
|
||||
list.sort_by(|t1, t2| t1.status.cmp(&t2.status));
|
||||
let mut out_list = Vec::with_capacity(list.len());
|
||||
//表头
|
||||
out_list.push(vec!["Name".to_string(), "Virtual Ip".to_string(), "P2P/Relay".to_string(), "Rt".to_string(), "Status".to_string()]);
|
||||
out_list.push(vec![("Name".to_string(), Style::new()),
|
||||
("Virtual Ip".to_string(), Style::new()),
|
||||
("Status".to_string(), Style::new()),
|
||||
("P2P/Relay".to_string(), Style::new()),
|
||||
("Rt".to_string(), Style::new())]);
|
||||
for item in list {
|
||||
out_list.push(vec![item.name, item.virtual_ip, item.nat_traversal_type,
|
||||
item.rt, item.status]);
|
||||
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())]);
|
||||
} 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)),
|
||||
(item.virtual_ip, Style::new().color256(102)),
|
||||
(item.status, Style::new().color256(102)),
|
||||
("".to_string(), Style::new().color256(102)),
|
||||
("".to_string(), Style::new().color256(102))]);
|
||||
}
|
||||
}
|
||||
table::println_table(out_list)
|
||||
}
|
||||
|
||||
pub fn console_device_list_all(list: Vec<DeviceItem>) {
|
||||
pub fn console_device_list_all(mut list: Vec<DeviceItem>) {
|
||||
if list.is_empty() {
|
||||
println!("No other devices found");
|
||||
return;
|
||||
}
|
||||
list.sort_by(|t1, t2| t1.virtual_ip.cmp(&t2.virtual_ip));
|
||||
list.sort_by(|t1, t2| t1.status.cmp(&t2.status));
|
||||
let mut out_list = Vec::with_capacity(list.len());
|
||||
//表头
|
||||
out_list.push(vec!["Name".to_string(), "Virtual Ip".to_string(), "NAT Type".to_string(),
|
||||
"Public Ips".to_string(), "Local Ip".to_string(), "P2P/Relay".to_string(),
|
||||
"Rt".to_string(), "Status".to_string()]);
|
||||
out_list.push(vec![("Name".to_string(), Style::new()),
|
||||
("Virtual Ip".to_string(), Style::new()),
|
||||
("Status".to_string(), Style::new()),
|
||||
("NAT Type".to_string(), Style::new()),
|
||||
("Public Ips".to_string(), Style::new()),
|
||||
("Local Ip".to_string(), Style::new()),
|
||||
("P2P/Relay".to_string(), Style::new()),
|
||||
("Rt".to_string(), Style::new())]);
|
||||
for item in list {
|
||||
out_list.push(vec![item.name, item.virtual_ip, item.nat_type,
|
||||
item.public_ips, item.local_ip, item.nat_traversal_type,
|
||||
item.rt, item.status]);
|
||||
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()),
|
||||
(item.nat_type, Style::new().green()),
|
||||
(item.public_ips, Style::new().green()),
|
||||
(item.local_ip, 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()),
|
||||
(item.nat_type, Style::new().yellow()),
|
||||
(item.public_ips, Style::new().yellow()),
|
||||
(item.local_ip, Style::new().yellow()), ]);
|
||||
}
|
||||
} else {
|
||||
out_list.push(vec![(item.name, Style::new().color256(102)),
|
||||
(item.virtual_ip, Style::new().color256(102)),
|
||||
(item.status, Style::new().color256(102)),
|
||||
("".to_string(), Style::new().color256(102)),
|
||||
("".to_string(), Style::new().color256(102)),
|
||||
("".to_string(), Style::new().color256(102)),
|
||||
("".to_string(), Style::new().color256(102)),
|
||||
("".to_string(), Style::new().color256(102)), ]);
|
||||
}
|
||||
}
|
||||
table::println_table(out_list)
|
||||
}
|
||||
@@ -1,29 +1,23 @@
|
||||
use console::style;
|
||||
use console::Style;
|
||||
|
||||
pub fn println_table(table: Vec<Vec<String>>) {
|
||||
pub fn println_table(table: Vec<Vec<(String, Style)>>) {
|
||||
if table.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut width_list = vec![0; table[0].len()];
|
||||
for in_list in table.iter() {
|
||||
for (index, item) in in_list.iter().enumerate() {
|
||||
for (index, (item, _)) in in_list.iter().enumerate() {
|
||||
let width = console::measure_text_width(item) + 6;
|
||||
if width_list[index] < width {
|
||||
width_list[index] = width;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut head = true;
|
||||
for in_list in table {
|
||||
for (index, item) in in_list.iter().enumerate() {
|
||||
if head {
|
||||
print!("{item:width$}", item = item, width = width_list[index]);
|
||||
} else {
|
||||
let str = format!("{item:width$}", item = item, width = width_list[index]);
|
||||
print!("{}", style(str).green());
|
||||
}
|
||||
for (col, (item, style)) in in_list.iter().enumerate() {
|
||||
let str = format!("{:1$}", item, width_list[col]);
|
||||
print!("{}", style.apply_to(str));
|
||||
}
|
||||
head = false;
|
||||
println!()
|
||||
}
|
||||
}
|
||||
+16
-12
@@ -4,8 +4,6 @@ use console::style;
|
||||
use switch::core::Switch;
|
||||
|
||||
use crate::config::log_config::log_init;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::config::log_config::log_service_init;
|
||||
|
||||
mod command;
|
||||
mod config;
|
||||
@@ -86,13 +84,14 @@ pub struct StartArgs {
|
||||
/// NAT detection service address. Use comma to separate
|
||||
#[arg(long)]
|
||||
nat_test_server: Option<String>,
|
||||
/// 命令服务,开启后可以在其他进程使用 route、list等命令查看信息
|
||||
/// 程序使用后台运行时需要增加此参数
|
||||
/// Command service. After it is enabled, you can use route, list and other commands in other processes to view information.
|
||||
/// This parameter needs to be added when the program is running in the background
|
||||
/// 关闭命令服务,关闭后不能在其他进程直接使用route、list等命令查看信息
|
||||
/// Turn off the command service. After turning off, you cannot directly use the route, list and other commands to view information in other processes
|
||||
#[cfg(any(unix))]
|
||||
#[arg(long)]
|
||||
command_server: bool,
|
||||
off_command_server: bool,
|
||||
/// 记录日志,输出在 home/.switch 目录下,长时间使用时不建议开启
|
||||
/// Output the log in the "home/.switch" directory
|
||||
log: bool,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -124,16 +123,17 @@ fn main() {
|
||||
if args.len() == 3 && args[1] == windows::SERVICE_FLAG {
|
||||
//以服务的方式启动
|
||||
config::set_home(std::path::PathBuf::from(&args[2]));
|
||||
let _ = log_service_init();
|
||||
log::info!("config {:?}", std::path::PathBuf::from(&args[2]));
|
||||
log::info!("config {:?}", config::read_config());
|
||||
windows::service::start();
|
||||
return;
|
||||
} else {
|
||||
let home = dirs::home_dir().unwrap().join(".switch");
|
||||
config::set_home(home);
|
||||
let _ = log_init();
|
||||
let args = BaseArgs::parse();
|
||||
if let Commands::Start(start_args) = &args.command {
|
||||
if start_args.log {
|
||||
let _ = log_init();
|
||||
}
|
||||
}
|
||||
windows::main0(args);
|
||||
}
|
||||
}
|
||||
@@ -142,8 +142,12 @@ fn main() {
|
||||
fn main() {
|
||||
let home = dirs::home_dir().unwrap().join(".switch");
|
||||
config::set_home(home);
|
||||
let _ = log_init();
|
||||
let args = BaseArgs::parse();
|
||||
if let Commands::Start(start_args) = &args.command {
|
||||
if start_args.log {
|
||||
let _ = log_init();
|
||||
}
|
||||
}
|
||||
unix::main0(args);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use console::style;
|
||||
use fs2::FileExt;
|
||||
|
||||
use switch::core::{Config, Switch};
|
||||
|
||||
@@ -11,7 +12,7 @@ use crate::command::{command, CommandEnum};
|
||||
pub fn main0(base_args: BaseArgs) {
|
||||
match base_args.command {
|
||||
Commands::Start(args) => {
|
||||
let open_command_server = args.command_server;
|
||||
let off_command_server = args.off_command_server;
|
||||
match config::default_config(args) {
|
||||
Ok(start_config) => {
|
||||
if sudo::RunningAs::Root != sudo::check() {
|
||||
@@ -37,7 +38,7 @@ pub fn main0(base_args: BaseArgs) {
|
||||
nat_test_server,
|
||||
start_config.device_id.clone(),
|
||||
);
|
||||
let mut lock = match config::lock_config() {
|
||||
let lock = match config::lock_file() {
|
||||
Ok(lock) => {
|
||||
lock
|
||||
}
|
||||
@@ -46,17 +47,13 @@ pub fn main0(base_args: BaseArgs) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let lock_guard = match lock.try_write() {
|
||||
Ok(lock) => {
|
||||
lock
|
||||
}
|
||||
Err(_) => {
|
||||
println!("{}", style("文件被重复打开").red());
|
||||
return;
|
||||
}
|
||||
};
|
||||
if lock.try_lock_exclusive().is_err() {
|
||||
println!("{}", style("文件被重复打开").red());
|
||||
return;
|
||||
}
|
||||
if let Err(e) = config::save_config(args_config) {
|
||||
log::error!("{:?}",e);
|
||||
lock.unlock().unwrap();
|
||||
return;
|
||||
}
|
||||
let switch = match Switch::start(config) {
|
||||
@@ -65,12 +62,16 @@ pub fn main0(base_args: BaseArgs) {
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{:?}", e);
|
||||
lock.unlock().unwrap();
|
||||
return;
|
||||
}
|
||||
};
|
||||
let switch = Arc::new(switch);
|
||||
let command_server = crate::command::server::CommandServer::new();
|
||||
if open_command_server {
|
||||
if off_command_server {
|
||||
crate::console_listen(&switch);
|
||||
log::info!("前台任务结束");
|
||||
} else {
|
||||
if let Err(e) = config::update_pid(std::process::id()) {
|
||||
log::error!("{:?}", e);
|
||||
}
|
||||
@@ -86,11 +87,8 @@ pub fn main0(base_args: BaseArgs) {
|
||||
} else {
|
||||
log::info!("后台任务结束");
|
||||
}
|
||||
} else {
|
||||
crate::console_listen(&switch);
|
||||
log::info!("前台任务结束");
|
||||
}
|
||||
drop(lock_guard)
|
||||
lock.unlock().unwrap();
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{:?}", e);
|
||||
|
||||
@@ -5,6 +5,7 @@ use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
use console::style;
|
||||
use fs2::FileExt;
|
||||
use windows_service::Error;
|
||||
use windows_service::service::{
|
||||
ServiceAccess, ServiceErrorControl, ServiceInfo, ServiceStartType, ServiceState, ServiceType,
|
||||
@@ -61,6 +62,7 @@ pub fn main0(base_args: BaseArgs) {
|
||||
// 允许应用通过防火墙
|
||||
let _udp = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||
}
|
||||
let out_log = args.log;
|
||||
match config::default_config(args) {
|
||||
Ok(start_config) => {
|
||||
match service_state() {
|
||||
@@ -76,7 +78,7 @@ pub fn main0(base_args: BaseArgs) {
|
||||
log::error!("{:?}",e);
|
||||
return;
|
||||
}
|
||||
match start() {
|
||||
match start(out_log) {
|
||||
Ok(_) => {
|
||||
//需要检查启动状态
|
||||
thread::sleep(Duration::from_secs(2));
|
||||
@@ -107,22 +109,19 @@ pub fn main0(base_args: BaseArgs) {
|
||||
start_config.server,
|
||||
start_config.nat_test_server,
|
||||
);
|
||||
let mut lock = match config::lock_config() {
|
||||
Ok(lock) => lock,
|
||||
let lock = match config::lock_file() {
|
||||
Ok(lock) => {
|
||||
lock
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{:?}",e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let lock_guard = match lock.try_write() {
|
||||
Ok(lock) => {
|
||||
lock
|
||||
}
|
||||
Err(_) => {
|
||||
println!("{}", style("程序文件被重复打开").red());
|
||||
return;
|
||||
}
|
||||
};
|
||||
if lock.try_lock_exclusive().is_err() {
|
||||
println!("{}", style("文件被重复打开").red());
|
||||
return;
|
||||
}
|
||||
match Switch::start(config) {
|
||||
Ok(switch) => {
|
||||
crate::console_listen(&switch);
|
||||
@@ -131,7 +130,7 @@ pub fn main0(base_args: BaseArgs) {
|
||||
log::error!("{:?}", e);
|
||||
}
|
||||
}
|
||||
drop(lock_guard);
|
||||
lock.unlock().unwrap();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -329,11 +328,15 @@ fn uninstall() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start() -> Result<(), Error> {
|
||||
fn start(out_log: bool) -> Result<(), Error> {
|
||||
let manager_access = ServiceManagerAccess::CONNECT;
|
||||
let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)?;
|
||||
let service = service_manager.open_service(SERVICE_NAME, ServiceAccess::START)?;
|
||||
service.start(&[""])
|
||||
if out_log {
|
||||
service.start(&["log"])
|
||||
} else {
|
||||
service.start(&[""])
|
||||
}
|
||||
}
|
||||
|
||||
fn service_state() -> Result<ServiceState, Error> {
|
||||
|
||||
@@ -20,7 +20,14 @@ use crate::windows::config::read_config;
|
||||
use crate::windows::SERVICE_NAME;
|
||||
|
||||
define_windows_service!(ffi_service_main, switch_service_main);
|
||||
pub fn switch_service_main(_arguments: Vec<OsString>) {
|
||||
pub fn switch_service_main(arguments: Vec<OsString>) {
|
||||
if !arguments.is_empty() {
|
||||
if let Some(str) = arguments[0].to_str() {
|
||||
if str == "log" {
|
||||
let _ = config::log_config::log_service_init();
|
||||
}
|
||||
}
|
||||
}
|
||||
thread::spawn(|| match service_main() {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
|
||||
+1
-1
Submodule switch/p2p_channel updated: d75c050482...a9c49f79c6
@@ -38,14 +38,10 @@ impl Switch {
|
||||
let virtual_gateway = Ipv4Addr::from(response.virtual_gateway);
|
||||
let virtual_netmask = Ipv4Addr::from(response.virtual_netmask);
|
||||
let current_device = Arc::new(AtomicCell::new(CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, config.server_address)));
|
||||
let local_addr = channel.local_addr()?;
|
||||
let local_ip = if local_addr.ip().is_unspecified() {
|
||||
local_ip_address::local_ip().unwrap_or(local_addr.ip())
|
||||
} else {
|
||||
local_addr.ip()
|
||||
};
|
||||
let local_ip = crate::nat::local_ip()?;
|
||||
let local_port = channel.local_addr()?.port();
|
||||
// NAT检测
|
||||
let nat_test = NatTest::new(config.nat_test_server.clone(), Ipv4Addr::from(response.public_ip), response.public_port as u16, local_ip, local_addr.port());
|
||||
let nat_test = NatTest::new(config.nat_test_server.clone(), Ipv4Addr::from(response.public_ip), response.public_port as u16, local_ip, local_port);
|
||||
// tun通道
|
||||
let (tun_writer, tun_reader) = tun_device::create_tun(virtual_ip, virtual_netmask, virtual_gateway)?;
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ fn start_heartbeat_(sender: Sender<Ipv4Addr>, device_list: Arc<Mutex<(u16, Vec<P
|
||||
let epoch = { device_list.lock().0 };
|
||||
ping.set_epoch(epoch);
|
||||
}
|
||||
if count % 7 == 0 {
|
||||
if count < 7 || count % 7 == 0 {
|
||||
let mut route_list: Option<Vec<(Ipv4Addr, Route)>> = None;
|
||||
let peer_list = device_list.lock().1.clone();
|
||||
for peer in peer_list {
|
||||
|
||||
@@ -17,6 +17,7 @@ use packet::ip::ipv4::packet::IpV4Packet;
|
||||
use crate::error::Error;
|
||||
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo};
|
||||
use crate::handle::registration_handler::Register;
|
||||
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, turn_packet, Version};
|
||||
@@ -179,13 +180,9 @@ impl RecvHandler {
|
||||
service_packet::Protocol::RegistrationRequest => {}
|
||||
service_packet::Protocol::RegistrationResponse => {
|
||||
let response = RegistrationResponse::parse_from_bytes(net_packet.payload())?;
|
||||
let local_addr = self.channel.local_addr()?;
|
||||
let local_ip = if local_addr.ip().is_unspecified() {
|
||||
local_ip_address::local_ip().unwrap_or(local_addr.ip())
|
||||
} else {
|
||||
local_addr.ip()
|
||||
};
|
||||
let nat_info = self.nat_test.re_test(Ipv4Addr::from(response.public_ip), response.public_port as u16, local_ip, local_addr.port());
|
||||
let local_port = self.channel.local_addr()?.port();
|
||||
let local_ip = nat::local_ip()?;
|
||||
let nat_info = self.nat_test.re_test(Ipv4Addr::from(response.public_ip), response.public_port as u16, local_ip, local_port);
|
||||
self.channel.set_nat_type(nat_info.nat_type)?;
|
||||
let new_ip = Ipv4Addr::from(response.virtual_ip);
|
||||
let current_ip = current_device.virtual_ip();
|
||||
@@ -296,7 +293,7 @@ impl RecvHandler {
|
||||
}
|
||||
}
|
||||
ControlPacket::PunchRequest => {
|
||||
log::info!("PunchRequest route_key:{:?}",route_key);
|
||||
// log::info!("PunchRequest route_key:{:?}",route_key);
|
||||
//回应
|
||||
net_packet.set_transport_protocol(control_packet::Protocol::PunchResponse.into());
|
||||
net_packet.set_source(current_device.virtual_ip());
|
||||
@@ -307,7 +304,7 @@ impl RecvHandler {
|
||||
self.channel.add_route(source, route);
|
||||
}
|
||||
ControlPacket::PunchResponse => {
|
||||
log::info!("PunchResponse route_key:{:?}",route_key);
|
||||
// log::info!("PunchResponse route_key:{:?}",route_key);
|
||||
let route = Route::from(*route_key, 1, -1);
|
||||
self.channel.add_route(net_packet.source(), route);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::io;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::sync::Arc;
|
||||
use parking_lot::Mutex;
|
||||
@@ -6,6 +7,14 @@ use crate::proto::message::PunchNatType;
|
||||
|
||||
pub mod check;
|
||||
|
||||
use std::net::UdpSocket;
|
||||
|
||||
pub fn local_ip() -> io::Result<IpAddr> {
|
||||
let socket = UdpSocket::bind("0.0.0.0:0")?;
|
||||
socket.connect("8.8.8.8:80")?;
|
||||
let addr = socket.local_addr()?;
|
||||
Ok(addr.ip())
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NatTest {
|
||||
|
||||
Reference in New Issue
Block a user