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