调整jni模块、优化cmd模块展示
This commit is contained in:
+2
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "switch"
|
||||
version = "1.0.7"
|
||||
version = "1.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@@ -32,3 +32,4 @@ libloading = "0.7.4"
|
||||
[build-dependencies]
|
||||
protobuf-codegen = "3.2.0"
|
||||
protoc-bin-vendored = "3.0.0"
|
||||
|
||||
|
||||
@@ -107,11 +107,11 @@ impl<B: AsRef<[u8]>> UdpPacket<B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> UdpPacket<B> {
|
||||
fn header_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.buffer.as_mut()[..8]
|
||||
}
|
||||
}
|
||||
// impl<B: AsRef<[u8]> + AsMut<[u8]>> UdpPacket<B> {
|
||||
// fn header_mut(&mut self) -> &mut [u8] {
|
||||
// &mut self.buffer.as_mut()[..8]
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> UdpPacket<B> {
|
||||
/// 设置源端口
|
||||
|
||||
@@ -302,8 +302,8 @@ impl Channel {
|
||||
let context = self.context;
|
||||
let main_channel = context.inner.main_channel.clone();
|
||||
let handler = self.handler.clone();
|
||||
tokio::spawn(Self::start_(worker.clone(), context.clone(), handler.clone(), main_channel.clone(), head_reserve, true));
|
||||
tokio::spawn(Self::start_(worker.clone(), context.clone(), handler, main_channel, head_reserve, true));
|
||||
tokio::spawn(Self::start_(worker.worker("main_channel_1"), context.clone(), handler.clone(), main_channel.clone(), head_reserve, true));
|
||||
tokio::spawn(Self::start_(worker.worker("main_channel_2"), context.clone(), handler, main_channel, head_reserve, true));
|
||||
let mut cur_status = Status::Cone;
|
||||
let mut status_receiver = context.inner.status_receiver.clone();
|
||||
loop {
|
||||
@@ -314,7 +314,8 @@ impl Channel {
|
||||
rs=status_receiver.changed()=>{
|
||||
match rs {
|
||||
Ok(_) => {
|
||||
match *status_receiver.borrow() {
|
||||
let s = status_receiver.borrow().clone();
|
||||
match s {
|
||||
Status::Cone => {
|
||||
cur_status = Status::Cone;
|
||||
}
|
||||
@@ -329,7 +330,7 @@ impl Channel {
|
||||
let udp = Arc::new(udp);
|
||||
let context = context.clone();
|
||||
let handler = self.handler.clone();
|
||||
tokio::spawn(Self::start_(worker.clone(),context, handler, udp, head_reserve, false));
|
||||
tokio::spawn(Self::start_(worker.worker("symmetric_channel"),context, handler, udp, head_reserve, false));
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{}",e);
|
||||
|
||||
+59
-47
@@ -1,5 +1,5 @@
|
||||
use std::{io, thread};
|
||||
use std::net::{Ipv4Addr, SocketAddr};
|
||||
use std::io;
|
||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -34,12 +34,12 @@ pub mod status;
|
||||
pub mod sync;
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Switch {
|
||||
name: String,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
context: Context,
|
||||
switch_status_manager: SwitchStatusManger,
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
device_writer: DeviceWriter,
|
||||
/// 0. 机器纪元,每一次上线或者下线都会增1,用于感知网络中机器变化
|
||||
/// 服务端和客户端的不一致,则服务端会推送新的设备列表
|
||||
@@ -113,9 +113,11 @@ impl SwitchUtil {
|
||||
}
|
||||
tun_tap_device::DeviceType::Tun
|
||||
};
|
||||
let mtu = self.config.mtu.unwrap_or(1430);
|
||||
let in_ips = self.config.in_ips.iter().map(|(dest, mask, _)| { (Ipv4Addr::from(*dest & *mask), Ipv4Addr::from(*mask)) }).collect::<Vec<(Ipv4Addr, Ipv4Addr)>>();
|
||||
|
||||
let (device_writer, device_reader, driver_info) = tun_tap_device::create_device(device_type, response.virtual_ip, response.virtual_netmask, response.virtual_gateway, in_ips)?;
|
||||
let (device_writer, device_reader, driver_info) = tun_tap_device::create_device(device_type, response.virtual_ip,
|
||||
response.virtual_netmask, response.virtual_gateway, in_ips, mtu)?;
|
||||
let _ = self.iface.insert((device_writer, device_reader));
|
||||
Ok(driver_info)
|
||||
}
|
||||
@@ -154,7 +156,7 @@ impl SwitchUtil {
|
||||
let register = Arc::new(registration_handler::Register::new(channel_sender.clone(),
|
||||
config.server_address, config.token.clone(),
|
||||
config.device_id.clone(), config.name.clone()));
|
||||
let device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>> = Arc::new(Mutex::new((0, Vec::new())));
|
||||
let device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>> = Arc::new(Mutex::new((response.epoch, response.device_info_list)));
|
||||
let peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>> = Arc::new(SkipMap::new());
|
||||
let connect_status = Arc::new(AtomicCell::new(ConnectStatus::Connected));
|
||||
let virtual_ip = response.virtual_ip;
|
||||
@@ -188,14 +190,14 @@ impl SwitchUtil {
|
||||
};
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
if config.tap {
|
||||
tap_handler::start(switch_status_manager.worker(), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
tap_handler::start(switch_status_manager.worker("tap_handler"), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
|
||||
} else {
|
||||
tun_handler::start(switch_status_manager.worker(), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
tun_handler::start(switch_status_manager.worker("tun_handler"), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
|
||||
}
|
||||
#[cfg(any(target_os = "android"))]
|
||||
tun_handler::start(switch_status_manager.worker(), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
tun_handler::start(switch_status_manager.worker("android tun_handler"), channel_sender.clone(), device_reader, device_writer.clone(),
|
||||
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
|
||||
|
||||
//外部数据接收处理
|
||||
@@ -204,46 +206,33 @@ impl SwitchUtil {
|
||||
device_writer.clone(), connect_status.clone(),
|
||||
peer_nat_info_map.clone(), ip_proxy_map, out_external_route,
|
||||
cone_sender, symmetric_sender, cipher);
|
||||
let channel = Channel::new(context.clone(), channel_recv_handler);
|
||||
let channel_worker = switch_status_manager.worker();
|
||||
//数据接收
|
||||
thread::spawn(move || {
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build().unwrap()
|
||||
.block_on(async move {
|
||||
if let Some(tcp_proxy) = tcp_proxy {
|
||||
tokio::spawn(tcp_proxy.start());
|
||||
}
|
||||
if let Some(udp_proxy) = udp_proxy {
|
||||
tokio::spawn(udp_proxy.start());
|
||||
}
|
||||
channel.start(channel_worker, 14, 65).await;
|
||||
});
|
||||
});
|
||||
{
|
||||
let other_worker = switch_status_manager.worker();
|
||||
let channel = Channel::new(context.clone(), channel_recv_handler);
|
||||
let channel_worker = switch_status_manager.worker("channel_worker");
|
||||
if let Some(tcp_proxy) = tcp_proxy {
|
||||
tokio::spawn(tcp_proxy.start());
|
||||
}
|
||||
if let Some(udp_proxy) = udp_proxy {
|
||||
tokio::spawn(udp_proxy.start());
|
||||
}
|
||||
tokio::spawn(async move {
|
||||
channel.start(channel_worker, 14, 65).await
|
||||
});
|
||||
}
|
||||
{
|
||||
let other_worker = switch_status_manager.worker("punch_handler");
|
||||
let nat_test = nat_test.clone();
|
||||
let device_list = device_list.clone();
|
||||
let current_device = current_device.clone();
|
||||
//其他任务处理
|
||||
thread::spawn(move || {
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build().unwrap()
|
||||
.block_on(async move {
|
||||
// 定时心跳
|
||||
heartbeat_handler::start_heartbeat(other_worker.clone(), channel_sender.clone(), device_list.clone(), current_device.clone());
|
||||
// 空闲检查
|
||||
heartbeat_handler::start_idle(other_worker.clone(), idle, channel_sender.clone());
|
||||
// 打洞处理
|
||||
punch_handler::start(other_worker.clone(), cone_receiver, punch.clone(), current_device.clone());
|
||||
punch_handler::start(other_worker.clone(), symmetric_receiver, punch, current_device.clone());
|
||||
punch_handler::start_punch(other_worker.clone(), nat_test.clone(),
|
||||
device_list.clone(), channel_sender.clone(),
|
||||
current_device.clone()).await;
|
||||
});
|
||||
});
|
||||
// 定时心跳
|
||||
heartbeat_handler::start_heartbeat(other_worker.worker("heartbeat"), channel_sender.clone(), device_list.clone(), current_device.clone(), config.server_address_str);
|
||||
// 空闲检查
|
||||
heartbeat_handler::start_idle(other_worker.worker("idle"), idle, channel_sender.clone());
|
||||
// 打洞处理
|
||||
punch_handler::start(other_worker.worker("cone_receiver"), cone_receiver, punch.clone(), current_device.clone());
|
||||
punch_handler::start(other_worker.worker("symmetric_receiver"), symmetric_receiver, punch, current_device.clone());
|
||||
tokio::spawn(punch_handler::start_punch(other_worker, nat_test,
|
||||
device_list, channel_sender, current_device));
|
||||
}
|
||||
context.switch(nat_test.nat_info().nat_type);
|
||||
Ok(Switch {
|
||||
@@ -251,7 +240,6 @@ impl SwitchUtil {
|
||||
current_device,
|
||||
context,
|
||||
switch_status_manager,
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
device_writer,
|
||||
nat_test,
|
||||
device_list,
|
||||
@@ -295,14 +283,33 @@ impl Switch {
|
||||
pub fn stop(&self) -> io::Result<()> {
|
||||
self.context.close();
|
||||
self.switch_status_manager.stop_all();
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
self.device_writer.close()?;
|
||||
let virtual_gateway = self.current_device.load().virtual_gateway;
|
||||
let _ = std::net::UdpSocket::bind("0.0.0.0:0")?.send_to(&[0],
|
||||
SocketAddr::V4(SocketAddrV4::new(virtual_gateway, 10000)));
|
||||
Ok(())
|
||||
}
|
||||
pub async fn wait_stop(&mut self) {
|
||||
self.switch_status_manager.wait().await;
|
||||
let _ = self.stop();
|
||||
}
|
||||
pub async fn wait_stop_ms(&mut self, ms: Duration) -> bool {
|
||||
tokio::select! {
|
||||
_=self.switch_status_manager.wait()=>{
|
||||
let _ = self.stop();
|
||||
return true;
|
||||
}
|
||||
_=tokio::time::sleep(ms)=>{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Switch {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.stop();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -312,11 +319,13 @@ pub struct Config {
|
||||
pub device_id: String,
|
||||
pub name: String,
|
||||
pub server_address: SocketAddr,
|
||||
pub server_address_str: String,
|
||||
pub nat_test_server: Vec<SocketAddr>,
|
||||
pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||
pub out_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||
pub key: Option<[u8; 32]>,
|
||||
pub simulate_multicast: bool,
|
||||
pub mtu: Option<u16>,
|
||||
}
|
||||
|
||||
|
||||
@@ -325,9 +334,10 @@ impl Config {
|
||||
device_id: String,
|
||||
name: String,
|
||||
server_address: SocketAddr,
|
||||
server_address_str: String,
|
||||
nat_test_server: Vec<SocketAddr>,
|
||||
in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||
password: Option<String>, simulate_multicast: bool, ) -> Self {
|
||||
password: Option<String>, simulate_multicast: bool, mtu: Option<u16>, ) -> Self {
|
||||
let key = if let Some(password) = password {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(password.as_bytes());
|
||||
@@ -342,11 +352,13 @@ impl Config {
|
||||
device_id,
|
||||
name,
|
||||
server_address,
|
||||
server_address_str,
|
||||
nat_test_server,
|
||||
in_ips,
|
||||
out_ips,
|
||||
key,
|
||||
simulate_multicast,
|
||||
mtu,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,15 +10,17 @@ pub enum SwitchStatus {
|
||||
}
|
||||
|
||||
pub struct SwitchWorker {
|
||||
_name: String,
|
||||
wg: WaitGroup,
|
||||
status_s: Arc<Sender<SwitchStatus>>,
|
||||
status_r: Receiver<SwitchStatus>,
|
||||
}
|
||||
|
||||
impl Clone for SwitchWorker {
|
||||
fn clone(&self) -> Self {
|
||||
impl SwitchWorker {
|
||||
pub fn worker(&self, name: &str) -> Self {
|
||||
self.wg.add();
|
||||
SwitchWorker {
|
||||
_name: name.to_string(),
|
||||
wg: self.wg.clone(),
|
||||
status_s: self.status_s.clone(),
|
||||
status_r: self.status_r.clone(),
|
||||
@@ -53,6 +55,7 @@ impl SwitchWorker {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SwitchStatusManger {
|
||||
wg: WaitGroup,
|
||||
status_s: Arc<Sender<SwitchStatus>>,
|
||||
@@ -74,9 +77,10 @@ impl SwitchStatusManger {
|
||||
pub async fn wait(&mut self) {
|
||||
self.wg.wait().await
|
||||
}
|
||||
pub fn worker(&self) -> SwitchWorker {
|
||||
pub fn worker(&self, name: &str) -> SwitchWorker {
|
||||
self.wg.add();
|
||||
SwitchWorker {
|
||||
_name: name.to_string(),
|
||||
wg: self.wg.clone(),
|
||||
status_s: self.status_s.clone(),
|
||||
status_r: self.status_r.clone(),
|
||||
|
||||
@@ -17,7 +17,7 @@ pub struct SwitchSync {
|
||||
|
||||
impl SwitchUtilSync {
|
||||
pub fn new(config: Config) -> io::Result<SwitchUtilSync> {
|
||||
let runtime = tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap();
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap();
|
||||
let switch_util = runtime.block_on(SwitchUtil::new(config))?;
|
||||
Ok(SwitchUtilSync {
|
||||
switch_util,
|
||||
@@ -38,9 +38,15 @@ impl SwitchUtilSync {
|
||||
pub fn build(self) -> crate::Result<SwitchSync> {
|
||||
let runtime = self.runtime;
|
||||
let switch = runtime.block_on(self.switch_util.build())?;
|
||||
{
|
||||
let mut switch = switch.clone();
|
||||
std::thread::spawn(move || {
|
||||
runtime.block_on(switch.wait_stop())
|
||||
});
|
||||
}
|
||||
Ok(SwitchSync {
|
||||
switch,
|
||||
runtime,
|
||||
runtime: tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -50,8 +56,7 @@ impl SwitchSync {
|
||||
self.runtime.block_on(self.switch.wait_stop())
|
||||
}
|
||||
pub fn wait_stop_ms(&mut self, ms: u64) -> bool {
|
||||
self.runtime.block_on(tokio::time::timeout(Duration::from_millis(ms),
|
||||
self.switch.wait_stop())).is_ok()
|
||||
self.runtime.block_on(self.switch.wait_stop_ms(Duration::from_millis(ms)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::Arc;
|
||||
|
||||
// 目标ip,子网掩码,网关
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExternalRoute {
|
||||
route_table: Vec<(u32, u32, Ipv4Addr)>,
|
||||
route_table: Arc<Vec<(u32, u32, Ipv4Addr)>>,
|
||||
}
|
||||
|
||||
impl ExternalRoute {
|
||||
pub fn new(route_table: Vec<(u32, u32, Ipv4Addr)>) -> Self {
|
||||
Self {
|
||||
route_table
|
||||
route_table:Arc::new(route_table)
|
||||
}
|
||||
}
|
||||
pub fn route(&self, ip: &Ipv4Addr) -> Option<Ipv4Addr> {
|
||||
let ip = u32::from_be_bytes(ip.octets());
|
||||
for (dest, mask, gateway) in &self.route_table {
|
||||
for (dest, mask, gateway) in self.route_table.iter() {
|
||||
if *mask & ip == *mask & *dest {
|
||||
return Some(*gateway);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::net::Ipv4Addr;
|
||||
use std::net::{Ipv4Addr, ToSocketAddrs};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::io;
|
||||
@@ -49,13 +49,14 @@ pub fn start_heartbeat(
|
||||
sender: ChannelSender,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
server_address_str: String,
|
||||
) {
|
||||
tokio::spawn(async move {
|
||||
tokio::select! {
|
||||
_=worker.stop_wait()=>{
|
||||
return;
|
||||
}
|
||||
rs=start_heartbeat_(sender, device_list, current_device)=>{
|
||||
rs=start_heartbeat_(sender, device_list, current_device,server_address_str)=>{
|
||||
if let Err(e) = rs {
|
||||
log::warn!("心跳任务停止:{:?}", e);
|
||||
}
|
||||
@@ -76,6 +77,7 @@ async fn start_heartbeat_(
|
||||
sender: ChannelSender,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
server_address_str: String,
|
||||
) -> io::Result<()> {
|
||||
let mut net_packet = NetPacket::new([0u8; 16])?;
|
||||
net_packet.set_version(Version::V1);
|
||||
@@ -88,20 +90,33 @@ async fn start_heartbeat_(
|
||||
if sender.is_close() {
|
||||
return Ok(());
|
||||
}
|
||||
let current_device = current_device.load();
|
||||
net_packet.set_source(current_device.virtual_ip());
|
||||
let mut current_dev = current_device.load();
|
||||
if count % 6 == 0 {
|
||||
if let Ok(mut addr) = server_address_str.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;
|
||||
if current_device.compare_exchange(current_dev, tmp).is_ok() {
|
||||
current_dev.connect_server = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
net_packet.set_source(current_dev.virtual_ip());
|
||||
{
|
||||
let mut ping = PingPacket::new(net_packet.payload_mut())?;
|
||||
let epoch = { device_list.lock().0 };
|
||||
ping.set_epoch(epoch);
|
||||
}
|
||||
set_now_time(&mut net_packet)?;
|
||||
net_packet.set_destination(current_device.virtual_gateway());
|
||||
if let Err(e) = sender.send_main(net_packet.buffer(), current_device.connect_server).await
|
||||
net_packet.set_destination(current_dev.virtual_gateway());
|
||||
if let Err(e) = sender.send_main(net_packet.buffer(), current_dev.connect_server).await
|
||||
{
|
||||
log::warn!(
|
||||
"connect_server:{:?},e:{:?}",
|
||||
current_device.connect_server,
|
||||
current_dev.connect_server,
|
||||
e
|
||||
);
|
||||
}
|
||||
@@ -109,7 +124,7 @@ async fn start_heartbeat_(
|
||||
let mut route_list: Option<Vec<(Ipv4Addr, Vec<Route>)>> = None;
|
||||
let peer_list = { device_list.lock().1.clone() };
|
||||
for peer in peer_list {
|
||||
if peer.virtual_ip == current_device.virtual_ip {
|
||||
if peer.virtual_ip == current_dev.virtual_ip {
|
||||
continue;
|
||||
}
|
||||
set_now_time(&mut net_packet)?;
|
||||
@@ -121,7 +136,7 @@ async fn start_heartbeat_(
|
||||
}
|
||||
} else {
|
||||
//没有直连路由则发送到网关
|
||||
let _ = sender.send_main(net_packet.buffer(), current_device.connect_server).await;
|
||||
let _ = sender.send_main(net_packet.buffer(), current_dev.connect_server).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,8 +78,6 @@ pub async fn start_punch(
|
||||
}
|
||||
num += 1;
|
||||
}
|
||||
|
||||
worker.stop_all();
|
||||
}
|
||||
|
||||
async fn start_punch_(
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::channel::{Route, RouteKey};
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::external_route::ExternalRoute;
|
||||
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo};
|
||||
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, PeerDeviceStatus};
|
||||
use crate::handle::registration_handler::Register;
|
||||
use crate::igmp_server::IgmpServer;
|
||||
use crate::ip_proxy::IpProxyMap;
|
||||
@@ -362,7 +362,9 @@ impl ChannelDataHandler {
|
||||
.collect();
|
||||
let route = Route::from(*route_key, 2, 99);
|
||||
for x in &ip_list {
|
||||
context.add_route_if_absent(x.virtual_ip, route);
|
||||
if x.status == PeerDeviceStatus::Online {
|
||||
context.add_route_if_absent(x.virtual_ip, route);
|
||||
}
|
||||
}
|
||||
let mut dev = self.device_list.lock();
|
||||
if dev.0 != device_list_t.epoch as u16 {
|
||||
|
||||
@@ -6,6 +6,7 @@ use crossbeam_utils::atomic::AtomicCell;
|
||||
use protobuf::Message;
|
||||
use tokio::net::UdpSocket;
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::handle::PeerDeviceInfo;
|
||||
|
||||
use crate::proto::message::{RegistrationRequest, RegistrationResponse};
|
||||
use crate::protocol::error_packet::InErrorPacket;
|
||||
@@ -24,7 +25,8 @@ pub struct RegResponse {
|
||||
pub virtual_ip: Ipv4Addr,
|
||||
pub virtual_gateway: Ipv4Addr,
|
||||
pub virtual_netmask: Ipv4Addr,
|
||||
pub epoch: u32,
|
||||
pub epoch: u16,
|
||||
pub device_info_list: Vec<PeerDeviceInfo>,
|
||||
pub public_ip: Ipv4Addr,
|
||||
pub public_port: u16,
|
||||
}
|
||||
@@ -62,11 +64,23 @@ pub async fn registration(
|
||||
service_packet::Protocol::RegistrationResponse => {
|
||||
match RegistrationResponse::parse_from_bytes(net_packet.payload()) {
|
||||
Ok(response) => {
|
||||
let device_info_list: Vec<PeerDeviceInfo> = response
|
||||
.device_info_list
|
||||
.into_iter()
|
||||
.map(|info| {
|
||||
PeerDeviceInfo::new(
|
||||
Ipv4Addr::from(info.virtual_ip),
|
||||
info.name,
|
||||
info.device_status as u8,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
Ok(RegResponse {
|
||||
virtual_ip: Ipv4Addr::from(response.virtual_ip),
|
||||
virtual_gateway: Ipv4Addr::from(response.virtual_gateway),
|
||||
virtual_netmask: Ipv4Addr::from(response.virtual_netmask),
|
||||
epoch: response.epoch,
|
||||
epoch: response.epoch as u16,
|
||||
device_info_list,
|
||||
public_ip: Ipv4Addr::from(response.public_ip),
|
||||
public_port: response.public_port as u16,
|
||||
})
|
||||
@@ -134,7 +148,7 @@ fn registration_request_packet(
|
||||
request.device_id = device_id;
|
||||
request.name = name;
|
||||
request.is_fast = is_fast;
|
||||
request.version = "1.0.7".to_string();
|
||||
request.version = "1.1.0".to_string();
|
||||
let bytes = request.write_to_bytes()?;
|
||||
let buf = vec![0u8; 12 + bytes.len()];
|
||||
let mut net_packet = NetPacket::new(buf)?;
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn start(worker: SwitchWorker, sender: ChannelSender,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Option<Aes256Gcm>) {
|
||||
thread::spawn(move || {
|
||||
thread::Builder::new().name("tap_handler".into()).spawn(move || {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all().build().unwrap()
|
||||
.block_on(async move {
|
||||
@@ -36,7 +36,7 @@ pub fn start(worker: SwitchWorker, sender: ChannelSender,
|
||||
}
|
||||
worker.stop_all();
|
||||
});
|
||||
});
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
async fn start_(sender: ChannelSender,
|
||||
|
||||
@@ -62,21 +62,22 @@ pub fn start(worker: SwitchWorker, sender: ChannelSender,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Option<Aes256Gcm>) {
|
||||
thread::spawn(move || {
|
||||
thread::Builder::new().name("tun_handler".into()).spawn(move || {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all().build().unwrap()
|
||||
.block_on(async move {
|
||||
if let Err(e) = start_(sender, device_reader, device_writer, igmp_server, current_device, ip_route, ip_proxy_map, cipher).await {
|
||||
log::warn!("tun:{:?}",e);
|
||||
if let Err(e) = start_(sender, device_reader, &device_writer, igmp_server, current_device, ip_route, ip_proxy_map, cipher).await {
|
||||
log::warn!("stop:{}",e);
|
||||
}
|
||||
let _ = device_writer.close();
|
||||
worker.stop_all();
|
||||
})
|
||||
});
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
async fn start_(sender: ChannelSender,
|
||||
device_reader: DeviceReader,
|
||||
device_writer: DeviceWriter,
|
||||
device_writer: &DeviceWriter,
|
||||
igmp_server: Option<IgmpServer>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
@@ -88,7 +89,7 @@ async fn start_(sender: ChannelSender,
|
||||
return Ok(());
|
||||
}
|
||||
let len = device_reader.read(&mut buf[12..])? + 12;
|
||||
match handle(&sender, &mut buf, len, &device_writer, &igmp_server,current_device.load(), &ip_route, &ip_proxy_map, &cipher).await {
|
||||
match handle(&sender, &mut buf, len, device_writer, &igmp_server, current_device.load(), &ip_route, &ip_proxy_map, &cipher).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("{:?}", e)
|
||||
|
||||
@@ -9,7 +9,7 @@ pub struct DeviceReader(RawFd);
|
||||
impl DeviceWriter {
|
||||
pub fn write_ipv4_tun(&self, buf: &[u8]) -> io::Result<()> {
|
||||
unsafe {
|
||||
let amount = libc::write(self.0, buf.as_ptr() as *const _, buf.len() );
|
||||
let amount = libc::write(self.0, buf.as_ptr() as *const _, buf.len());
|
||||
if amount < 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
@@ -21,12 +21,18 @@ impl DeviceWriter {
|
||||
let buf = &buf[14..];
|
||||
self.write_ipv4_tun(buf)
|
||||
}
|
||||
pub fn close(&self) -> io::Result<()> {
|
||||
// unsafe {
|
||||
// libc::close(self.0);
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl DeviceReader {
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
unsafe {
|
||||
let amount = libc::read(self.0, buf.as_mut_ptr() as *mut _, buf.len() );
|
||||
let amount = libc::read(self.0, buf.as_mut_ptr() as *mut _, buf.len());
|
||||
|
||||
if amount < 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
|
||||
@@ -15,7 +15,6 @@ impl DeviceWriter {
|
||||
.destination(gateway)
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.mtu(1420)
|
||||
// .queues(2)
|
||||
.up();
|
||||
let mut dev = self.lock.lock();
|
||||
@@ -56,6 +55,7 @@ pub fn create_device(device_type: DeviceType,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
mtu: u16,
|
||||
) -> io::Result<(DeviceWriter, DeviceReader,DriverInfo)> {
|
||||
let mut config = tun::Configuration::default();
|
||||
|
||||
@@ -63,7 +63,7 @@ pub fn create_device(device_type: DeviceType,
|
||||
.destination(gateway)
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.mtu(1420)
|
||||
.mtu(mtu.into())
|
||||
// .queues(2) 用多个队列有兼容性问题
|
||||
.up();
|
||||
match device_type {
|
||||
|
||||
@@ -5,7 +5,6 @@ use bytes::BufMut;
|
||||
use tun::platform::posix::{Reader, Writer};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
#[cfg(any(target_os = "linux"))]
|
||||
use tun::platform::linux::Device;
|
||||
#[cfg(any(target_os = "macos"))]
|
||||
@@ -38,17 +37,15 @@ pub struct DeviceWriter {
|
||||
writer: DeviceW,
|
||||
pub lock: Arc<Mutex<Device>>,
|
||||
pub in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
ip: Arc<AtomicCell<Ipv4Addr>>,
|
||||
packet_information: bool,
|
||||
}
|
||||
|
||||
impl DeviceWriter {
|
||||
pub fn new(writer: DeviceW,lock: Arc<Mutex<Device>>, in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, ip: Ipv4Addr, packet_information: bool) -> Self {
|
||||
pub fn new(writer: DeviceW,lock: Arc<Mutex<Device>>, in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, _ip: Ipv4Addr, packet_information: bool) -> Self {
|
||||
Self {
|
||||
writer,
|
||||
lock,
|
||||
in_ips,
|
||||
ip: Arc::new(AtomicCell::new(ip)),
|
||||
packet_information,
|
||||
}
|
||||
}
|
||||
@@ -107,9 +104,6 @@ impl DeviceWriter {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn ip(&self) -> Ipv4Addr {
|
||||
self.ip.load()
|
||||
}
|
||||
pub fn close(&self) -> io::Result<()> {
|
||||
unsafe {
|
||||
match &self.writer {
|
||||
|
||||
@@ -15,7 +15,6 @@ impl DeviceWriter {
|
||||
.destination(gateway)
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.mtu(1420)
|
||||
.up();
|
||||
let mut dev = self.lock.lock();
|
||||
if let Err(e) = dev.configure(&config) {
|
||||
@@ -42,7 +41,8 @@ pub fn create_device(device_type: DeviceType,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
) -> io::Result<(DeviceWriter, DeviceReader,DriverInfo)> {
|
||||
mtu: u16,
|
||||
) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> {
|
||||
match device_type {
|
||||
DeviceType::Tun => {}
|
||||
DeviceType::Tap => {
|
||||
@@ -55,7 +55,7 @@ pub fn create_device(device_type: DeviceType,
|
||||
.destination(gateway)
|
||||
.address(address)
|
||||
.netmask(netmask)
|
||||
.mtu(1420)
|
||||
.mtu(mtu.into())
|
||||
.up();
|
||||
|
||||
let dev = tun::create(&config).unwrap();
|
||||
@@ -75,8 +75,8 @@ pub fn create_device(device_type: DeviceType,
|
||||
let writer = queue.writer();
|
||||
let driver_info = DriverInfo {
|
||||
device_type,
|
||||
name:name.to_string(),
|
||||
version:String::new(),
|
||||
name: name.to_string(),
|
||||
version: String::new(),
|
||||
mac: None,
|
||||
};
|
||||
Ok((
|
||||
|
||||
@@ -44,6 +44,7 @@ impl DeviceType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DriverInfo {
|
||||
pub device_type: DeviceType,
|
||||
pub name: String,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::{io, thread};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::os::windows::process::CommandExt;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use libloading::Library;
|
||||
use parking_lot::Mutex;
|
||||
use packet::ethernet;
|
||||
@@ -37,16 +37,14 @@ pub struct DeviceWriter {
|
||||
device: Arc<Device>,
|
||||
lock: Arc<Mutex<()>>,
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
ip: Arc<AtomicCell<Ipv4Addr>>,
|
||||
}
|
||||
|
||||
impl DeviceWriter {
|
||||
pub fn new(device: Arc<Device>, in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, ip: Ipv4Addr) -> Self {
|
||||
pub fn new(device: Arc<Device>, in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, _ip: Ipv4Addr) -> Self {
|
||||
Self {
|
||||
device,
|
||||
lock: Arc::new(Default::default()),
|
||||
in_ips,
|
||||
ip: Arc::new(AtomicCell::new(ip)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +118,6 @@ impl DeviceWriter {
|
||||
log::warn!("{:?}", e);
|
||||
}
|
||||
dev.set_ip(address, netmask)?;
|
||||
self.ip.store(address);
|
||||
for (address, netmask) in &self.in_ips {
|
||||
dev.add_route(*address, *netmask, gateway, 1)?;
|
||||
}
|
||||
@@ -132,9 +129,6 @@ impl DeviceWriter {
|
||||
delete_cache();
|
||||
Ok(())
|
||||
}
|
||||
pub fn ip(&self) -> Ipv4Addr {
|
||||
self.ip.load()
|
||||
}
|
||||
pub fn close(&self) -> io::Result<()> {
|
||||
match self.device.as_ref() {
|
||||
Device::Tun(dev) => {
|
||||
@@ -198,6 +192,7 @@ fn create_tun(
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
mtu: u16,
|
||||
) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> {
|
||||
unsafe {
|
||||
match Library::new("wintun.dll") {
|
||||
@@ -241,7 +236,7 @@ fn create_tun(
|
||||
let version = format!("{:?}", tun_device.version()?);
|
||||
tun_device.set_ip(address, netmask)?;
|
||||
tun_device.set_metric(1)?;
|
||||
tun_device.set_mtu(1420)?;
|
||||
tun_device.set_mtu(mtu)?;
|
||||
// ip代理路由
|
||||
for (address, netmask) in &in_ips {
|
||||
tun_device.add_route(*address, *netmask, gateway, 1)?;
|
||||
@@ -271,6 +266,7 @@ fn delete_cache() {
|
||||
//清除路由缓存
|
||||
let delete_cache = "netsh interface ip delete destinationcache";
|
||||
let out = std::process::Command::new("cmd")
|
||||
.creation_flags(0x08000000)
|
||||
.arg("/C")
|
||||
.arg(delete_cache)
|
||||
.output()
|
||||
@@ -297,6 +293,7 @@ fn create_tap(
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
mtu: u16,
|
||||
) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> {
|
||||
let tap_device = match TapDevice::open(TAP_INTERFACE_NAME) {
|
||||
Ok(tap_device) => tap_device,
|
||||
@@ -313,7 +310,7 @@ fn create_tap(
|
||||
let mac_str = format!("mac:{:x?}", mac);
|
||||
tap_device.set_ip(address, netmask)?;
|
||||
tap_device.set_metric(1)?;
|
||||
tap_device.set_mtu(1420)?;
|
||||
tap_device.set_mtu(mtu)?;
|
||||
tap_device.set_status(true)?;
|
||||
tap_device.add_route(address, netmask, gateway, 1)?;
|
||||
for (address, netmask) in &in_ips {
|
||||
@@ -350,13 +347,14 @@ fn delete_tap() {
|
||||
pub fn create_device(device_type: DeviceType, address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, ) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> {
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
mtu: u16) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> {
|
||||
match device_type {
|
||||
DeviceType::Tun => {
|
||||
create_tun(address, netmask, gateway, in_ips)
|
||||
create_tun(address, netmask, gateway, in_ips, mtu)
|
||||
}
|
||||
DeviceType::Tap => {
|
||||
create_tap(address, netmask, gateway, in_ips)
|
||||
create_tap(address, netmask, gateway, in_ips, mtu)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use std::io;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
/// 设置网卡名称
|
||||
pub fn set_interface_name(old_name: &str, new_name: &str) -> io::Result<()> {
|
||||
let cmd = format!(" netsh interface set interface name={:?} newname={:?}", old_name, new_name);
|
||||
let out = std::process::Command::new("cmd")
|
||||
.creation_flags(0x08000000) //winapi-0.3.9/src/um/winbase.rs:283
|
||||
.arg("/C")
|
||||
.arg(&cmd)
|
||||
.output()?;
|
||||
@@ -21,6 +23,7 @@ pub fn set_interface_ip(index: u32, address: &Ipv4Addr, netmask: &Ipv4Addr) -> i
|
||||
index, address, netmask,
|
||||
);
|
||||
let out = std::process::Command::new("cmd")
|
||||
.creation_flags(0x08000000)
|
||||
.arg("/C")
|
||||
.arg(&set_address)
|
||||
.output()?;
|
||||
@@ -37,6 +40,7 @@ pub fn set_interface_mtu(index: u32, mtu: u16) -> io::Result<()> {
|
||||
index, mtu
|
||||
);
|
||||
let out = std::process::Command::new("cmd")
|
||||
.creation_flags(0x08000000)
|
||||
.arg("/C")
|
||||
.arg(&set_mtu)
|
||||
.output()?;
|
||||
@@ -49,6 +53,7 @@ pub fn set_interface_mtu(index: u32, mtu: u16) -> io::Result<()> {
|
||||
pub fn set_interface_metric(index: u32, metric: u16) -> io::Result<()> {
|
||||
let set_metric = format!("netsh interface ip set interface {} metric={}", index,metric);
|
||||
let out = std::process::Command::new("cmd")
|
||||
.creation_flags(0x08000000)
|
||||
.arg("/C")
|
||||
.arg(&set_metric)
|
||||
.output()?;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::io;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
/// 添加路由
|
||||
pub fn add_route(index: u32, dest: Ipv4Addr,
|
||||
@@ -11,6 +12,7 @@ pub fn add_route(index: u32, dest: Ipv4Addr,
|
||||
);
|
||||
// 执行添加路由命令
|
||||
let out = std::process::Command::new("cmd")
|
||||
.creation_flags(0x08000000)
|
||||
.arg("/C")
|
||||
.arg(&set_route)
|
||||
.output()
|
||||
@@ -33,6 +35,7 @@ pub fn delete_route(index: u32, dest: Ipv4Addr, netmask: Ipv4Addr, gateway: Ipv4
|
||||
);
|
||||
// 删除路由
|
||||
let out = std::process::Command::new("cmd")
|
||||
.creation_flags(0x08000000)
|
||||
.arg("/C")
|
||||
.arg(delete_route)
|
||||
.output()
|
||||
|
||||
Reference in New Issue
Block a user