增加安卓端支持、优化广播、增加停止监听
This commit is contained in:
@@ -9,20 +9,26 @@ use rand::prelude::SliceRandom;
|
||||
use crate::channel::idle::Idle;
|
||||
use crate::channel::Route;
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::core::status::SwitchWorker;
|
||||
|
||||
|
||||
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
|
||||
use crate::protocol::control_packet::PingPacket;
|
||||
use crate::protocol::{control_packet, NetPacket, Protocol, Version};
|
||||
|
||||
pub async fn start_idle(idle: Idle, sender: ChannelSender) {
|
||||
pub fn start_idle(mut worker: SwitchWorker, idle: Idle, sender: ChannelSender) {
|
||||
tokio::spawn(async move {
|
||||
match start_idle_(idle, sender).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("空闲检测任务停止:{:?}", e);
|
||||
tokio::select! {
|
||||
_=worker.stop_wait()=>{
|
||||
return;
|
||||
}
|
||||
rs=start_idle_(idle, sender)=>{
|
||||
if let Err(e) = rs {
|
||||
log::warn!("空闲检测任务停止:{:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
worker.stop_all();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,15 +44,24 @@ async fn start_idle_(idle: Idle, sender: ChannelSender) -> io::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start_heartbeat(
|
||||
pub fn start_heartbeat(
|
||||
mut worker: SwitchWorker,
|
||||
sender: ChannelSender,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
) {
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = start_heartbeat_(sender, device_list, current_device).await {
|
||||
log::warn!("心跳任务停止:{:?}", e);
|
||||
tokio::select! {
|
||||
_=worker.stop_wait()=>{
|
||||
return;
|
||||
}
|
||||
rs=start_heartbeat_(sender, device_list, current_device)=>{
|
||||
if let Err(e) = rs {
|
||||
log::warn!("心跳任务停止:{:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
worker.stop_all();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,6 +85,9 @@ async fn start_heartbeat_(
|
||||
net_packet.first_set_ttl(2);
|
||||
let mut count = 0;
|
||||
loop {
|
||||
if sender.is_close() {
|
||||
return Ok(());
|
||||
}
|
||||
let current_device = current_device.load();
|
||||
net_packet.set_source(current_device.virtual_ip());
|
||||
{
|
||||
@@ -103,7 +121,7 @@ async fn start_heartbeat_(
|
||||
}
|
||||
} else {
|
||||
//没有直连路由则发送到网关
|
||||
let _ = sender.try_send_main(net_packet.buffer(), current_device.connect_server);
|
||||
let _ = sender.send_main(net_packet.buffer(), current_device.connect_server).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ impl PeerDeviceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq,Ord, PartialOrd)]
|
||||
pub enum PeerDeviceStatus {
|
||||
Online,
|
||||
Offline,
|
||||
|
||||
@@ -13,10 +13,17 @@ use std::io;
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
use crate::channel::punch::{NatInfo, Punch};
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::core::status::SwitchWorker;
|
||||
|
||||
pub async fn start(receiver: Receiver<(Ipv4Addr, NatInfo)>, punch: Punch, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
|
||||
pub fn start(mut worker: SwitchWorker, receiver: Receiver<(Ipv4Addr, NatInfo)>, punch: Punch, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
|
||||
tokio::spawn(async move {
|
||||
start0(receiver, punch, current_device).await;
|
||||
tokio::select! {
|
||||
_=start0(receiver, punch, current_device)=>{}
|
||||
_=worker.stop_wait()=>{
|
||||
return;
|
||||
}
|
||||
}
|
||||
worker.stop_all();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -47,54 +54,62 @@ async fn start_(
|
||||
}
|
||||
|
||||
pub async fn start_punch(
|
||||
mut worker: SwitchWorker,
|
||||
nat_test: NatTest,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
sender: ChannelSender,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
) {
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = start_punch_(nat_test, device_list, sender, current_device).await {
|
||||
log::warn!("打洞处理任务停止 {:?}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async fn start_punch_(
|
||||
nat_test: NatTest,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
sender: ChannelSender,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
) -> crate::Result<()> {
|
||||
let mut num = 0;
|
||||
let sleep_time = [3, 5, 7, 11, 13, 17, 19, 23, 29];
|
||||
loop {
|
||||
if sender.is_close() {
|
||||
return Ok(());
|
||||
break;
|
||||
}
|
||||
let current_device = current_device.load();
|
||||
let nat_info = nat_test.nat_info();
|
||||
{
|
||||
let mut list = device_list.lock().clone().1;
|
||||
list.shuffle(&mut rand::thread_rng());
|
||||
let mut count = 0;
|
||||
for info in list {
|
||||
if info.virtual_ip <= current_device.virtual_ip {
|
||||
continue;
|
||||
tokio::select! {
|
||||
rs= start_punch_(Duration::from_secs(sleep_time[num % sleep_time.len()]),&nat_test, &device_list, &sender, ¤t_device)=>{
|
||||
if let Err(e) = rs {
|
||||
log::warn!("打洞处理任务异常 {:?}", e);
|
||||
}
|
||||
if !sender.need_punch(&info.virtual_ip) {
|
||||
continue;
|
||||
}
|
||||
count += 1;
|
||||
if count > 2 {
|
||||
break;
|
||||
}
|
||||
let buf = punch_packet(current_device.virtual_ip(), &nat_info, info.virtual_ip)?;
|
||||
let _ = sender.send_main(&buf, current_device.connect_server).await;
|
||||
}
|
||||
_=worker.stop_wait()=>{
|
||||
break;
|
||||
}
|
||||
}
|
||||
num += 1;
|
||||
tokio::time::sleep(Duration::from_secs(sleep_time[num % sleep_time.len()])).await;
|
||||
}
|
||||
|
||||
worker.stop_all();
|
||||
}
|
||||
|
||||
async fn start_punch_(
|
||||
sleep_time: Duration,
|
||||
nat_test: &NatTest,
|
||||
device_list: &Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
sender: &ChannelSender,
|
||||
current_device: &Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
) -> crate::Result<()> {
|
||||
let current_device = current_device.load();
|
||||
let nat_info = nat_test.nat_info();
|
||||
let mut list = device_list.lock().clone().1;
|
||||
list.shuffle(&mut rand::thread_rng());
|
||||
let mut count = 0;
|
||||
for info in list {
|
||||
if info.virtual_ip <= current_device.virtual_ip {
|
||||
continue;
|
||||
}
|
||||
if !sender.need_punch(&info.virtual_ip) {
|
||||
continue;
|
||||
}
|
||||
count += 1;
|
||||
if count > 2 {
|
||||
break;
|
||||
}
|
||||
let buf = punch_packet(current_device.virtual_ip(), &nat_info, info.virtual_ip)?;
|
||||
let _ = sender.send_main(&buf, current_device.connect_server).await;
|
||||
}
|
||||
tokio::time::sleep(sleep_time).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn punch_packet(
|
||||
|
||||
@@ -245,7 +245,7 @@ impl ChannelDataHandler {
|
||||
ipv4.set_destination_ip(destination);
|
||||
ipv4.update_checksum();
|
||||
ip_proxy_map.tcp_proxy_map.insert(SocketAddrV4::new(source, source_port),
|
||||
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
|
||||
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
|
||||
}
|
||||
ipv4::protocol::Protocol::Udp => {
|
||||
let dest_ip = ipv4.destination_ip();
|
||||
@@ -258,7 +258,7 @@ impl ChannelDataHandler {
|
||||
ipv4.set_destination_ip(destination);
|
||||
ipv4.update_checksum();
|
||||
ip_proxy_map.udp_proxy_map.insert(SocketAddrV4::new(source, source_port),
|
||||
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
|
||||
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
|
||||
}
|
||||
ipv4::protocol::Protocol::Icmp => {
|
||||
let dest_ip = ipv4.destination_ip();
|
||||
@@ -329,11 +329,14 @@ impl ChannelDataHandler {
|
||||
if current_ip != new_ip {
|
||||
// ip发生变化
|
||||
log::info!("ip发生变化,old_ip:{:?},new_ip:{:?}",current_ip,new_ip);
|
||||
let old_netmask = current_device.virtual_netmask;
|
||||
let old_gateway = current_device.virtual_gateway();
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
let old_netmask = current_device.virtual_netmask;
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
let old_gateway = current_device.virtual_gateway();
|
||||
let virtual_ip = Ipv4Addr::from(response.virtual_ip);
|
||||
let virtual_gateway = Ipv4Addr::from(response.virtual_gateway);
|
||||
let virtual_netmask = Ipv4Addr::from(response.virtual_netmask);
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
self.device_writer.change_ip(virtual_ip, virtual_netmask, virtual_gateway, old_netmask, old_gateway)?;
|
||||
let new_current_device = CurrentDeviceInfo::new(virtual_ip, virtual_gateway,
|
||||
virtual_netmask, current_device.connect_server);
|
||||
@@ -346,7 +349,7 @@ impl ChannelDataHandler {
|
||||
service_packet::Protocol::PollDeviceList => {}
|
||||
service_packet::Protocol::PushDeviceList => {
|
||||
let device_list_t = DeviceList::parse_from_bytes(net_packet.payload())?;
|
||||
let ip_list = device_list_t
|
||||
let ip_list: Vec<PeerDeviceInfo> = device_list_t
|
||||
.device_info_list
|
||||
.into_iter()
|
||||
.map(|info| {
|
||||
@@ -357,6 +360,10 @@ 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);
|
||||
}
|
||||
let mut dev = self.device_list.lock();
|
||||
if dev.0 != device_list_t.epoch as u16 {
|
||||
dev.0 = device_list_t.epoch as u16;
|
||||
@@ -434,7 +441,6 @@ impl ChannelDataHandler {
|
||||
}
|
||||
}
|
||||
ControlPacket::PunchRequest => {
|
||||
// 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());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
use std::net::{Ipv4Addr, SocketAddr};
|
||||
use std::time::{Duration, Instant};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
|
||||
@@ -7,11 +7,28 @@ use protobuf::Message;
|
||||
use tokio::net::UdpSocket;
|
||||
use crate::channel::sender::ChannelSender;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::proto::message::{RegistrationRequest, RegistrationResponse};
|
||||
use crate::protocol::error_packet::InErrorPacket;
|
||||
use crate::protocol::{service_packet, NetPacket, Protocol, Version, MAX_TTL};
|
||||
|
||||
pub enum ReqEnum {
|
||||
TokenError,
|
||||
AddressExhausted,
|
||||
Timeout,
|
||||
ServerError(String),
|
||||
Other(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RegResponse {
|
||||
pub virtual_ip: Ipv4Addr,
|
||||
pub virtual_gateway: Ipv4Addr,
|
||||
pub virtual_netmask: Ipv4Addr,
|
||||
pub epoch: u32,
|
||||
pub public_ip: Ipv4Addr,
|
||||
pub public_port: u16,
|
||||
}
|
||||
|
||||
///向中继服务器注册,token标识一个虚拟网关,device_id防止多次注册时得到的ip不一致
|
||||
pub async fn registration(
|
||||
main_channel: &UdpSocket,
|
||||
@@ -19,77 +36,90 @@ pub async fn registration(
|
||||
token: String,
|
||||
device_id: String,
|
||||
name: String,
|
||||
) -> Result<RegistrationResponse> {
|
||||
) -> Result<RegResponse, ReqEnum> {
|
||||
let request_packet =
|
||||
registration_request_packet(token.clone(), device_id.clone(), name.clone(), false)?;
|
||||
registration_request_packet(token.clone(), device_id.clone(), name.clone(), false).unwrap();
|
||||
let buf = request_packet.buffer();
|
||||
let mut recv_buf = [0u8; 10240];
|
||||
let mut count = 0;
|
||||
loop {
|
||||
match main_channel.send_to(buf, server_address).await {
|
||||
Ok(_) => {
|
||||
match tokio::time::timeout(Duration::from_millis(300), main_channel.recv_from(&mut recv_buf)).await {
|
||||
Ok(rs) => {
|
||||
match rs {
|
||||
Ok((len, addr)) => {
|
||||
if server_address == addr {
|
||||
let net_packet = NetPacket::new(&recv_buf[..len])?;
|
||||
match net_packet.protocol() {
|
||||
Protocol::Service => {
|
||||
match service_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
service_packet::Protocol::RegistrationResponse => {
|
||||
let response = RegistrationResponse::parse_from_bytes(net_packet.payload())?;
|
||||
return Ok(response);
|
||||
return match main_channel.send_to(buf, server_address).await {
|
||||
Ok(_) => {
|
||||
match tokio::time::timeout(Duration::from_millis(300), main_channel.recv_from(&mut recv_buf)).await {
|
||||
Ok(rs) => {
|
||||
match rs {
|
||||
Ok((len, addr)) => {
|
||||
if server_address == addr {
|
||||
let net_packet = match NetPacket::new(&recv_buf[..len]) {
|
||||
Ok(net_packet) => {
|
||||
net_packet
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(ReqEnum::ServerError(format!("{}",e)))
|
||||
}
|
||||
};
|
||||
match net_packet.protocol() {
|
||||
Protocol::Service => {
|
||||
match service_packet::Protocol::from(net_packet.transport_protocol()) {
|
||||
service_packet::Protocol::RegistrationResponse => {
|
||||
match RegistrationResponse::parse_from_bytes(net_packet.payload()) {
|
||||
Ok(response) => {
|
||||
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,
|
||||
public_ip: Ipv4Addr::from(response.public_ip),
|
||||
public_port: response.public_port as u16,
|
||||
})
|
||||
}
|
||||
Err(_) => {
|
||||
Err(ReqEnum::ServerError("invalid data".to_string()))
|
||||
}
|
||||
}
|
||||
_ => println!("响应数据错误"),
|
||||
}
|
||||
_ => {
|
||||
Err(ReqEnum::ServerError("invalid data".to_string()))
|
||||
}
|
||||
}
|
||||
Protocol::Error => {
|
||||
match InErrorPacket::new(net_packet.transport_protocol(), net_packet.payload()) {
|
||||
Ok(e) => match e {
|
||||
InErrorPacket::TokenError => return Err(Error::Stop("token错误".to_string())),
|
||||
InErrorPacket::Disconnect => {
|
||||
println!("断开连接");
|
||||
}
|
||||
Protocol::Error => {
|
||||
match InErrorPacket::new(net_packet.transport_protocol(), net_packet.payload()) {
|
||||
Ok(e) => match e {
|
||||
InErrorPacket::TokenError => Err(ReqEnum::TokenError),
|
||||
InErrorPacket::Disconnect => {
|
||||
Err(ReqEnum::ServerError("disconnect".to_string()))
|
||||
}
|
||||
InErrorPacket::AddressExhausted => {
|
||||
Err(ReqEnum::AddressExhausted)
|
||||
}
|
||||
InErrorPacket::OtherError(e) => match e.message() {
|
||||
Ok(str) => {
|
||||
Err(ReqEnum::ServerError(str))
|
||||
}
|
||||
InErrorPacket::AddressExhausted => {
|
||||
println!("地址用尽");
|
||||
log::warn!("地址用尽");
|
||||
}
|
||||
InErrorPacket::OtherError(e) => match e.message() {
|
||||
Ok(str) => {
|
||||
println!("其他异常:{:?}", str);
|
||||
log::warn!("其他异常{:?}",str);
|
||||
}
|
||||
Err(e) => println!("其他异常:{:?}", e),
|
||||
},
|
||||
Err(e) => Err(ReqEnum::Other(format!("{}", e))),
|
||||
},
|
||||
Err(e) => println!("数据解析异常:{:?}", e),
|
||||
}
|
||||
},
|
||||
Err(e) => Err(ReqEnum::Other(format!("{}", e))),
|
||||
}
|
||||
_ => println!("响应数据错误"),
|
||||
};
|
||||
}
|
||||
_ => Err(ReqEnum::ServerError("invalid data".to_string())),
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
println!("接收服务器数据失败:{:?}", e);
|
||||
log::warn!("接收服务器数据失败:{:?}",e);
|
||||
} else {
|
||||
Err(ReqEnum::Other(format!("invalid data,from {}", addr)))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
println!("接收超时");
|
||||
log::warn!("接收超时");
|
||||
Err(e) => {
|
||||
Err(ReqEnum::Other(format!("receiver error:{}", e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
println!("发送数据到服务器失败:{:?}", e);
|
||||
log::warn!("发送数据到服务器失败:{:?}",e);
|
||||
Err(_) => {
|
||||
Err(ReqEnum::Timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
println!("重试中(retrying)...");
|
||||
std::thread::sleep(Duration::from_secs(count % 10 + 1));
|
||||
Err(e) => {
|
||||
Err(ReqEnum::Other(format!("send error:{}", e)))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,41 +18,33 @@ use crate::protocol;
|
||||
use crate::protocol::ip_turn_packet::BroadcastPacketEnd;
|
||||
|
||||
pub mod tun_handler;
|
||||
#[cfg(any(target_os = "linux", target_os = "macos",target_os = "windows"))]
|
||||
pub mod tap_handler;
|
||||
|
||||
async fn broadcast(sender: &ChannelSender, net_packet: &mut NetPacket<&mut [u8]>, data_len: usize, current_device: &CurrentDeviceInfo) -> Result<()> {
|
||||
let mut peer_ips = Vec::with_capacity(8);
|
||||
let vec = sender.route_table_one();
|
||||
let mut relay_count = 0;
|
||||
let mut last_peer = None;
|
||||
const MAX_COUNT: usize = u8::MAX as usize;
|
||||
for (peer_ip, route) in vec {
|
||||
if peer_ip == current_device.virtual_gateway {
|
||||
continue;
|
||||
}
|
||||
if peer_ips.len() < u8::MAX as usize && route.is_p2p()
|
||||
if peer_ips.len() == MAX_COUNT {
|
||||
break;
|
||||
}
|
||||
if route.is_p2p()
|
||||
&& sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
|
||||
peer_ips.push(peer_ip);
|
||||
} else {
|
||||
relay_count += 1;
|
||||
if relay_count == 1 {
|
||||
last_peer = Some((peer_ip, route));
|
||||
}
|
||||
if relay_count > 1 && peer_ips.len() == u8::MAX as usize {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if relay_count == 0 && !peer_ips.is_empty() {
|
||||
if relay_count == 0 && !peer_ips.is_empty() && peer_ips.len() != MAX_COUNT {
|
||||
//不需要转发
|
||||
return Ok(());
|
||||
}
|
||||
if relay_count == 1 && !net_packet.is_encrypt() {
|
||||
//只有一个目标,并且没加密
|
||||
let (peer_ip, route) = last_peer.unwrap();
|
||||
net_packet.set_destination(peer_ip);
|
||||
sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if peer_ips.is_empty() {
|
||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||
} else {
|
||||
@@ -71,7 +63,7 @@ async fn multicast(igmp_server: &IgmpServer, multicast_addr: Ipv4Addr, sender: &
|
||||
let mut peer_ips = Vec::with_capacity(8);
|
||||
let vec = sender.route_table_one();
|
||||
let mut relay_count = 0;
|
||||
let mut last_peer = None;
|
||||
const MAX_COUNT: usize = u8::MAX as usize;
|
||||
if let Some(members) = igmp_server.load(&multicast_addr) {
|
||||
for (peer_ip, route) in vec {
|
||||
if peer_ip == current_device.virtual_gateway {
|
||||
@@ -79,32 +71,22 @@ async fn multicast(igmp_server: &IgmpServer, multicast_addr: Ipv4Addr, sender: &
|
||||
}
|
||||
let is_send = { members.read().is_send(&peer_ip) };
|
||||
if is_send {
|
||||
if peer_ips.len() < u8::MAX as usize && route.is_p2p()
|
||||
if peer_ips.len() == MAX_COUNT {
|
||||
break;
|
||||
}
|
||||
if route.is_p2p()
|
||||
&& sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
|
||||
peer_ips.push(peer_ip);
|
||||
} else {
|
||||
relay_count += 1;
|
||||
if relay_count == 1 {
|
||||
last_peer = Some((peer_ip, route));
|
||||
}
|
||||
if relay_count > 1 && peer_ips.len() == u8::MAX as usize {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if relay_count == 0 && !peer_ips.is_empty() {
|
||||
if relay_count == 0 && !peer_ips.is_empty() && peer_ips.len() != MAX_COUNT {
|
||||
//不需要转发
|
||||
return Ok(());
|
||||
}
|
||||
if relay_count == 1 && !net_packet.is_encrypt() {
|
||||
//只有一个目标,并且没加密
|
||||
let (peer_ip, route) = last_peer.unwrap();
|
||||
net_packet.set_destination(peer_ip);
|
||||
sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await?;
|
||||
return Ok(());
|
||||
}
|
||||
if peer_ips.is_empty() {
|
||||
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
|
||||
} else {
|
||||
|
||||
@@ -10,13 +10,14 @@ use packet::icmp::Kind;
|
||||
use packet::ip::ipv4;
|
||||
use packet::ip::ipv4::packet::IpV4Packet;
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::core::status::SwitchWorker;
|
||||
use crate::external_route::ExternalRoute;
|
||||
use crate::handle::CurrentDeviceInfo;
|
||||
use crate::igmp_server::IgmpServer;
|
||||
use crate::ip_proxy::IpProxyMap;
|
||||
use crate::tun_tap_device::{DeviceReader, DeviceWriter};
|
||||
|
||||
pub fn start(sender: ChannelSender,
|
||||
pub fn start(worker: SwitchWorker, sender: ChannelSender,
|
||||
device_reader: DeviceReader,
|
||||
device_writer: DeviceWriter,
|
||||
igmp_server: Option<IgmpServer>,
|
||||
@@ -24,7 +25,7 @@ pub fn start(sender: ChannelSender,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Option<Aes256Gcm>) {
|
||||
thread::Builder::new().name("tap-handler".into()).spawn(move || {
|
||||
thread::spawn(move || {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all().build().unwrap()
|
||||
.block_on(async move {
|
||||
@@ -33,8 +34,9 @@ pub fn start(sender: ChannelSender,
|
||||
current_device, ip_route, ip_proxy_map, cipher).await {
|
||||
log::warn!("tap:{:?}",e);
|
||||
}
|
||||
worker.stop_all();
|
||||
});
|
||||
}).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
async fn start_(sender: ChannelSender,
|
||||
|
||||
@@ -9,6 +9,7 @@ use packet::icmp::icmp::IcmpPacket;
|
||||
use packet::ip::ipv4;
|
||||
use packet::ip::ipv4::packet::IpV4Packet;
|
||||
use crate::channel::sender::ChannelSender;
|
||||
use crate::core::status::SwitchWorker;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::external_route::ExternalRoute;
|
||||
@@ -36,7 +37,7 @@ fn icmp(device_writer: &DeviceWriter, mut ipv4_packet: IpV4Packet<&mut [u8]>) ->
|
||||
/// 接收tun数据,并且转发到udp上
|
||||
#[inline]
|
||||
async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writer: &DeviceWriter, igmp_server: &Option<IgmpServer>, current_device: CurrentDeviceInfo,
|
||||
ip_route: &Option<ExternalRoute>, proxy_map: &Option<IpProxyMap>,cipher: &Option<Aes256Gcm>) -> Result<()> {
|
||||
ip_route: &Option<ExternalRoute>, proxy_map: &Option<IpProxyMap>, cipher: &Option<Aes256Gcm>) -> Result<()> {
|
||||
let ipv4_packet = if let Ok(ipv4_packet) = IpV4Packet::new(&mut data[12..len]) {
|
||||
ipv4_packet
|
||||
} else {
|
||||
@@ -50,10 +51,10 @@ async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writ
|
||||
if src_ip == dest_ip {
|
||||
return icmp(&device_writer, ipv4_packet);
|
||||
}
|
||||
return crate::handle::tun_tap::base_handle(sender, data, len, igmp_server, current_device, ip_route, proxy_map,cipher).await;
|
||||
return crate::handle::tun_tap::base_handle(sender, data, len, igmp_server, current_device, ip_route, proxy_map, cipher).await;
|
||||
}
|
||||
|
||||
pub fn start(sender: ChannelSender,
|
||||
pub fn start(worker: SwitchWorker, sender: ChannelSender,
|
||||
device_reader: DeviceReader,
|
||||
device_writer: DeviceWriter,
|
||||
igmp_server: Option<IgmpServer>,
|
||||
@@ -61,15 +62,16 @@ pub fn start(sender: ChannelSender,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Option<Aes256Gcm>) {
|
||||
thread::Builder::new().name("tun-handler".into()).spawn(move || {
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
thread::spawn(move || {
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all().build().unwrap()
|
||||
.block_on(async move {
|
||||
if let Err(e) = start_(sender, device_reader, device_writer, igmp_server, current_device, ip_route, ip_proxy_map,cipher).await {
|
||||
if let Err(e) = start_(sender, device_reader, device_writer, igmp_server, current_device, ip_route, ip_proxy_map, cipher).await {
|
||||
log::warn!("tun:{:?}",e);
|
||||
}
|
||||
worker.stop_all();
|
||||
})
|
||||
}).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
async fn start_(sender: ChannelSender,
|
||||
@@ -80,24 +82,17 @@ async fn start_(sender: ChannelSender,
|
||||
ip_route: Option<ExternalRoute>,
|
||||
ip_proxy_map: Option<IpProxyMap>,
|
||||
cipher: Option<Aes256Gcm>) -> io::Result<()> {
|
||||
let mut buf = [0; 4096];
|
||||
loop {
|
||||
let mut buf = [0; 4096];
|
||||
let sender = sender.clone();
|
||||
let device_writer = device_writer.clone();
|
||||
let igmp_server = igmp_server.clone();
|
||||
let ip_route = ip_route.clone();
|
||||
let ip_proxy_map = ip_proxy_map.clone();
|
||||
let cipher = cipher.clone();
|
||||
if sender.is_close() {
|
||||
return Ok(());
|
||||
}
|
||||
let len = device_reader.read(&mut buf[12..])? + 12;
|
||||
let current_device = current_device.load();
|
||||
tokio::spawn(async move {
|
||||
match handle(&sender, &mut buf, len, &device_writer, &igmp_server, current_device, &ip_route, &ip_proxy_map,&cipher).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("{:?}", e)
|
||||
}
|
||||
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)
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user