增加安卓端支持、优化广播、增加停止监听

This commit is contained in:
lubeilin
2023-07-05 23:36:41 +08:00
parent 890e5f7391
commit 50e97fd95f
25 changed files with 768 additions and 350 deletions
+27 -9
View File
@@ -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;
}
+1 -1
View File
@@ -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,
+50 -35
View File
@@ -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, &current_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(
+12 -6
View File
@@ -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());
+87 -57
View File
@@ -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)))
}
};
}
+14 -32
View File
@@ -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 {
+5 -3
View File
@@ -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,
+18 -23
View File
@@ -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)
}
});
}
}
}