默认使用广播代替组播、精简依赖

This commit is contained in:
lubeilin
2023-06-29 23:14:59 +08:00
parent be3bf82e35
commit 890e5f7391
31 changed files with 493 additions and 412 deletions
+102 -111
View File
@@ -1,27 +1,32 @@
use std::io;
use std::net::{Ipv4Addr, SocketAddr};
use std::sync::Arc;
use std::sync::atomic::{AtomicI64, AtomicUsize, Ordering};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Instant;
use crossbeam_skiplist::SkipMap;
use dashmap::DashMap;
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use tokio::net::UdpSocket;
use tokio::sync::Notify;
use tokio::sync::watch::{channel, Receiver, Sender};
use crate::channel::{Route, RouteKey, Status};
use crate::channel::punch::NatType;
use crate::handle::recv_handler::ChannelDataHandler;
pub struct ContextInner {
pub(crate) lock:Mutex<()>,
pub(crate) count: AtomicUsize,
pub(crate) main_channel: Arc<UdpSocket>,
pub(crate) route_table: SkipMap<Ipv4Addr, Vec<Route>>,
pub(crate) route_table_time: SkipMap<(RouteKey, Ipv4Addr), AtomicCell<Instant>>,
pub(crate) status_receiver: Receiver<Status>,
pub(crate) status_sender: Sender<Status>,
pub(crate) udp_map: SkipMap<usize, Arc<UdpSocket>>,
pub(crate) channel_num: usize,
}
#[derive(Clone)]
pub struct Context {
pub(crate) count: Arc<AtomicUsize>,
pub(crate) main_channel: Arc<UdpSocket>,
pub(crate) route_table: Arc<DashMap<Ipv4Addr, Vec<Route>>>,
pub(crate) route_table_time: Arc<SkipMap<(RouteKey, Ipv4Addr), AtomicI64>>,
pub(crate) status_receiver: Receiver<Status>,
pub(crate) status_sender: Arc<Sender<Status>>,
pub(crate) udp_map: Arc<SkipMap<usize, Arc<UdpSocket>>>,
pub(crate) channel_num: usize,
pub(crate) notify: Arc<Notify>,
pub(crate) inner: Arc<ContextInner>,
}
impl Context {
@@ -29,30 +34,32 @@ impl Context {
//当前版本只支持一个通道
let channel_num = 1;
let (status_sender, status_receiver) = channel(Status::Cone);
let status_sender = Arc::new(status_sender);
Self {
count: Arc::new(AtomicUsize::new(0)),
let inner = Arc::new(ContextInner {
lock:Mutex::new(()),
count: AtomicUsize::new(0),
main_channel,
route_table: Arc::new(DashMap::with_capacity(16)),
route_table_time: Arc::new(SkipMap::new()),
route_table: SkipMap::new(),
route_table_time: SkipMap::new(),
status_receiver,
status_sender,
udp_map: Arc::new(SkipMap::new()),
udp_map: SkipMap::new(),
channel_num,
notify: Arc::new(Notify::new()),
});
Self {
inner
}
}
}
impl Context {
pub fn is_close(&self) -> bool {
*self.status_receiver.borrow() == Status::Close
*self.inner.status_receiver.borrow() == Status::Close
}
pub fn is_cone(&self) -> bool {
*self.status_receiver.borrow() == Status::Cone
*self.inner.status_receiver.borrow() == Status::Cone
}
pub fn close(&self) {
let _ = self.status_sender.send(Status::Close);
let _ = self.inner.status_sender.send(Status::Close);
}
pub fn switch(&self, nat_type: NatType) {
match nat_type {
@@ -65,62 +72,64 @@ impl Context {
}
}
pub fn switch_to_cone(&self) {
let _ = self.status_sender.send(Status::Cone);
let _ = self.inner.status_sender.send(Status::Cone);
}
pub fn switch_to_symmetric(&self) {
let _ = self.status_sender.send(Status::Symmetric);
let _ = self.inner.status_sender.send(Status::Symmetric);
}
pub fn main_local_port(&self) -> io::Result<u16> {
self.main_channel.local_addr().map(|k| k.port())
self.inner.main_channel.local_addr().map(|k| k.port())
}
pub async fn send_main(&self, buf: &[u8], addr: SocketAddr) -> io::Result<usize> {
self.main_channel.send_to(buf, addr).await
self.inner.main_channel.send_to(buf, addr).await
}
pub(crate) async fn send_all(&self, buf: &[u8], addr: SocketAddr) -> io::Result<()> {
for udp in self.udp_map.iter() {
for udp in self.inner.udp_map.iter() {
udp.value().send_to(buf, addr).await?;
}
Ok(())
}
pub fn try_send_main(&self, buf: &[u8], addr: SocketAddr) -> io::Result<usize> {
self.main_channel.try_send_to(buf, addr)
self.inner.main_channel.try_send_to(buf, addr)
}
pub async fn send_by_id(&self, buf: &[u8], id: &Ipv4Addr) -> io::Result<usize> {
if let Some(v) = self.route_table.get(id) {
let route = match v.len() {
if let Some(v) = self.inner.route_table.get(id) {
let route = match v.value().len() {
0 => {
return Err(io::Error::new(io::ErrorKind::NotFound, "route not found"));
}
1 => &v[0],
len => &v[self.count.fetch_add(1, Ordering::Relaxed) % len]
1 => v.value()[0],
len => v.value()[self.inner.count.fetch_add(1, Ordering::Relaxed) % len]
};
if let Some(udp) = self.udp_map.get(&route.index) {
drop(v);
if let Some(udp) = self.inner.udp_map.get(&route.index) {
return udp.value().send_to(buf, route.addr).await;
}
}
Err(io::Error::new(io::ErrorKind::NotFound, "route not found"))
}
pub fn try_send_by_id(&self, buf: &[u8], id: &Ipv4Addr) -> io::Result<usize> {
if let Some(v) = self.route_table.get(id) {
if v.is_empty() {
if let Some(v) = self.inner.route_table.get(id) {
if v.value().is_empty() {
return Err(io::Error::new(io::ErrorKind::NotFound, "route not found"));
}
let route = &v[self.count.fetch_add(1, Ordering::Relaxed) % v.len()];
if let Some(udp) = self.udp_map.get(&route.index) {
let route = v.value()[self.inner.count.fetch_add(1, Ordering::Relaxed) % v.value().len()];
drop(v);
if let Some(udp) = self.inner.udp_map.get(&route.index) {
return udp.value().try_send_to(buf, route.addr);
}
}
Err(io::Error::new(io::ErrorKind::NotFound, "route not found"))
}
pub async fn send_by_key(&self, buf: &[u8], route_key: &RouteKey) -> io::Result<usize> {
if let Some(udp) = self.udp_map.get(&route_key.index) {
if let Some(udp) = self.inner.udp_map.get(&route_key.index) {
return udp.value().send_to(buf, route_key.addr).await;
}
Err(io::Error::new(io::ErrorKind::NotFound, "route not found"))
}
pub fn try_send_by_key(&self, buf: &[u8], route_key: &RouteKey) -> io::Result<usize> {
if let Some(udp) = self.udp_map.get(&route_key.index) {
if let Some(udp) = self.inner.udp_map.get(&route_key.index) {
return udp.value().try_send_to(buf, route_key.addr);
}
Err(io::Error::new(io::ErrorKind::NotFound, "route not found"))
@@ -133,9 +142,14 @@ impl Context {
}
fn add_route_(&self, id: Ipv4Addr, route: Route, only_if_absent: bool) {
let key = route.route_key();
let mut ref_mut = self.route_table.entry(id.clone()).or_insert(Vec::with_capacity(4));
let guard = self.inner.lock.lock();
let mut list = if let Some(entry) = self.inner.route_table.get(&id){
entry.value().clone()
}else{
Vec::with_capacity(4)
};
let mut exist = false;
for x in ref_mut.iter_mut() {
for x in list.iter_mut() {
if x.metric < route.metric {
//不能比当前的路径更长
return;
@@ -150,37 +164,40 @@ impl Context {
break;
}
}
if !exist {
if exist {
list.sort_by_key(|k| k.sort_key());
} else {
if route.metric == 1 {
//添加了直连的则排除非直连的
ref_mut.retain(|k| k.metric == 1);
list.retain(|k| k.metric == 1);
}
ref_mut.push(route);
let max_len = self.channel_num;
if ref_mut.len() > max_len {
ref_mut.sort_by_key(|k| k.sort_key());
ref_mut.truncate(max_len);
list.push(route);
list.sort_by_key(|k| k.sort_key());
let max_len = self.inner.channel_num + 1;
if list.len() > max_len {
list.truncate(max_len);
}
}
self.route_table_time.insert((key, id), AtomicI64::new(chrono::Local::now().timestamp_millis()));
self.notify.notify_one();
self.inner.route_table.insert(id,list);
self.inner.route_table_time.insert((key, id), AtomicCell::new(Instant::now()));
drop(guard);
}
pub fn route(&self, id: &Ipv4Addr) -> Option<Vec<Route>> {
if let Some(v) = self.route_table.get(id) {
if let Some(v) = self.inner.route_table.get(id) {
Some(v.value().clone())
} else {
None
}
}
pub fn route_one(&self, id: &Ipv4Addr) -> Option<Route> {
if let Some(v) = self.route_table.get(id) {
if let Some(v) = self.inner.route_table.get(id) {
v.value().iter().max_by_key(|k| k.sort_key()).map(|k| *k)
} else {
None
}
}
pub fn route_to_id(&self, route_key: &RouteKey) -> Option<Ipv4Addr> {
for x in self.route_table_time.iter() {
for x in self.inner.route_table_time.iter() {
if &x.key().0 == route_key {
return Some(x.key().1);
}
@@ -188,20 +205,20 @@ impl Context {
None
}
pub fn need_punch(&self, id: &Ipv4Addr) -> bool {
if let Some(v) = self.route_table.get(id) {
if v.iter().filter(|k| k.is_p2p()).count() >= self.channel_num {
if let Some(v) = self.inner.route_table.get(id) {
if v.value().iter().filter(|k| k.is_p2p()).count() >= self.inner.channel_num {
return false;
}
}
true
}
pub fn route_table(&self) -> Vec<(Ipv4Addr, Vec<Route>)> {
self.route_table.iter().map(|k| (k.key().clone(), k.value().clone())).collect()
self.inner.route_table.iter().map(|k| (k.key().clone(), k.value().clone())).collect()
}
pub fn route_table_one(&self) -> Vec<(Ipv4Addr, Route)> {
let mut v = Vec::with_capacity(8);
for x in self.route_table.iter() {
if let Some(route) = x.value().iter().max_by_key(|k| k.sort_key()) {
for x in self.inner.route_table.iter() {
if let Some(route) = x.value().first() {
v.push((*x.key(), *route));
}
}
@@ -209,8 +226,8 @@ impl Context {
}
pub fn direct_route_table_one(&self) -> Vec<(Ipv4Addr, Route)> {
let mut v = Vec::with_capacity(8);
for x in self.route_table.iter() {
if let Some(route) = x.value().iter().max_by_key(|k| k.sort_key()) {
for x in self.inner.route_table.iter() {
if let Some(route) = x.value().first() {
if route.metric == 1 {
v.push((*x.key(), *route));
}
@@ -219,21 +236,28 @@ impl Context {
v
}
pub fn remove_route_all(&self, id: &Ipv4Addr) {
if let Some((_, v)) = self.route_table.remove(id) {
for x in v {
self.route_table_time.remove(&(x.route_key(), id.clone()));
let guard = self.inner.lock.lock();
if let Some(v) = self.inner.route_table.remove(id) {
for x in v.value() {
self.inner.route_table_time.remove(&(x.route_key(), *id));
}
}
drop(guard);
}
pub fn remove_route(&self, id: &Ipv4Addr, route_key: RouteKey) {
if let Some(mut v) = self.route_table.get_mut(id) {
v.retain(|x| x.route_key() != route_key);
self.route_table_time.remove(&(route_key, id.clone()));
let guard = self.inner.lock.lock();
if let Some(v) = self.inner.route_table.get(id) {
let mut routes = v.value().clone();
drop(v);
routes.retain(|x| x.route_key() != route_key);
self.inner.route_table.insert(*id,routes);
self.inner.route_table_time.remove(&(route_key, *id));
}
drop(guard);
}
pub fn update_read_time(&self, id: &Ipv4Addr, route_key: &RouteKey) {
if let Some(time) = self.route_table_time.get(&(*route_key, *id)) {
time.value().store(chrono::Local::now().timestamp_millis(), Ordering::Relaxed);
if let Some(time) = self.inner.route_table_time.get(&(*route_key, *id)) {
time.value().store(Instant::now());
}
}
}
@@ -273,15 +297,17 @@ impl Channel {
head_reserve: usize,//头部预留字节
symmetric_channel_num: usize,//对称网络,则再加一组监听,提升打洞成功率
) {
let mut context = self.context;
let main_channel = context.main_channel.clone();
let context = self.context;
let main_channel = context.inner.main_channel.clone();
let handler = self.handler.clone();
tokio::spawn(Self::start_(context.clone(), handler.clone(), main_channel.clone(), head_reserve, true));
tokio::spawn(Self::start_(context.clone(), handler, main_channel, head_reserve, true));
let mut cur_status = Status::Cone;
let mut status_receiver = context.inner.status_receiver.clone();
loop {
match context.status_receiver.changed().await {
match status_receiver.changed().await {
Ok(_) => {
match *context.status_receiver.borrow() {
match *status_receiver.borrow() {
Status::Cone => {
cur_status = Status::Cone;
}
@@ -320,7 +346,7 @@ impl Channel {
udp: Arc<UdpSocket>,
head_reserve: usize,
is_core: bool) {
let mut status_receiver = context.status_receiver.clone();
let mut status_receiver = context.inner.status_receiver.clone();
#[cfg(target_os = "windows")]
use std::os::windows::io::AsRawSocket;
#[cfg(target_os = "windows")]
@@ -329,8 +355,8 @@ impl Channel {
use std::os::fd::AsRawFd;
#[cfg(any(unix))]
let id = udp.as_raw_fd() as usize;
context.udp_map.insert(id, udp.clone());
let mut buf = [0; 65536];
context.inner.udp_map.insert(id, udp.clone());
let mut buf = [0; 4096];
loop {
tokio::select! {
rs=udp.recv_from(&mut buf[head_reserve..])=>{
@@ -358,41 +384,6 @@ impl Channel {
}
}
}
context.udp_map.remove(&id);
context.inner.udp_map.remove(&id);
}
}
// pub async fn start<H: ChannelDataHandler + Clone>(mut handler: H,
// mut status_receiver: Receiver<Status>,
// head_reserve: usize,
// core_channel_num: usize,
// symmetric_channel_num: usize) -> io::Result<()> {
// for _ in 0..core_channel_num {
// let d = channel(1);
// }
// let udp = UdpSocket::bind("0.0.0.0:0").await?;
// let d = status_receiver.changed().await;
// match d {
// Ok(_) => {
// match *status_receiver.borrow() {
// Status::Cone => {}
// Status::Symmetric => {}
// Status::Close => {}
// }
// }
// Err(_) => {}
// }
// let mut buf = [0; 65546];
// let result = udp.recv_from(&mut buf[head_reserve..]).await;
// match result {
// Ok((len, addr)) => {}
// Err(e) => {}
// }
// Ok(())
// }
//
// pub struct Channel<H: ChannelDataHandler + Clone> {
// handler: H,
//
// }
+12 -28
View File
@@ -1,19 +1,18 @@
use std::io;
use std::io::{Error, ErrorKind};
use std::net::Ipv4Addr;
use std::sync::atomic::Ordering;
use std::time::Duration;
use crate::channel::channel::Context;
use crate::channel::RouteKey;
pub struct Idle {
read_idle: i64,
read_idle: Duration,
context: Context,
}
impl Idle {
pub fn new(read_idle: i64,
pub fn new(read_idle: Duration,
context: Context, ) -> Self {
Self {
read_idle,
@@ -26,34 +25,19 @@ impl Idle {
/// 获取空闲路由
pub async fn next_idle(&self) -> io::Result<(Ipv4Addr, RouteKey)> {
loop {
let now = chrono::Local::now().timestamp_millis();
let last_read_idle = now - self.read_idle;
let mut min = i64::MAX;
for entry in self.context.route_table_time.iter() {
let mut is_read_idle = false;
if self.read_idle > 0 {
let last_read = entry.value().load(Ordering::Relaxed);
if last_read < last_read_idle {
is_read_idle = true;
} else {
if min > last_read {
min = last_read;
}
let mut max = Duration::from_secs(10);
for entry in self.context.inner.route_table_time.iter() {
let last_read = entry.value().load().elapsed();
if last_read >= self.read_idle {
return Ok((entry.key().1.clone(), entry.key().0.clone()));
} else {
if max < last_read {
max = last_read;
}
}
if is_read_idle {
return Ok((entry.key().1.clone(), entry.key().0.clone()));
}
}
if self.context.route_table_time.is_empty() {
self.context.notify.notified().await;
} else {
let sleep_time = chrono::Local::now().timestamp_millis() - min;
if sleep_time > 0 {
tokio::time::sleep(Duration::from_millis(sleep_time as u64)).await;
// let _ = tokio::time::timeout(Duration::from_millis(sleep_time as u64), self.context.notify.notified()).await;
}
}
let sleep_time = self.read_idle - max;
tokio::time::sleep(sleep_time).await;
if self.context.is_close() {
return Err(Error::new(ErrorKind::Other, "closed"));
}
+27 -7
View File
@@ -1,9 +1,10 @@
use std::{io, thread};
use std::net::{Ipv4Addr, SocketAddr};
use std::sync::Arc;
use std::time::Duration;
use aes_gcm::{Aes256Gcm, Key, KeyInit};
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use crossbeam_skiplist::SkipMap;
use parking_lot::Mutex;
use tokio::net::UdpSocket;
@@ -54,7 +55,7 @@ impl Switch {
let (symmetric_sender, symmetric_receiver) = channel(2);
let context = Context::new(main_channel, 1);
let punch = Punch::new(context.clone());
let idle = Idle::new(16000, context.clone());
let idle = Idle::new(Duration::from_secs(16), context.clone());
let channel_sender = ChannelSender::new(context.clone());
let register = Arc::new(registration_handler::Register::new(channel_sender.clone(), config.server_address, config.token.clone(), config.device_id.clone(), config.name.clone()));
@@ -73,9 +74,17 @@ impl Switch {
let out_ips = config.out_ips.iter().map(|(_, _, ip)| *ip).collect::<Vec<Ipv4Addr>>();
let out_external_route = ExternalRoute::new(config.out_ips);
let in_external_route = ExternalRoute::new(config.in_ips);
let in_external_route = if config.in_ips.is_empty() {
None
} else {
Some(ExternalRoute::new(config.in_ips))
};
let current_device = Arc::new(AtomicCell::new(CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, config.server_address)));
let ip_proxy_map = crate::ip_proxy::init_proxy(channel_sender.clone(), out_ips, current_device.clone()).await?;
let ip_proxy_map = if out_ips.is_empty(){
None
}else{
Some(crate::ip_proxy::init_proxy(channel_sender.clone(), out_ips, current_device.clone()).await?)
};
let (device_writer, igmp_server) = if config.tap {
#[cfg(windows)]
{
@@ -83,7 +92,11 @@ impl Switch {
tun_tap_device::delete_device(tun_tap_device::DeviceType::Tap);
}
let (tap_writer, tap_reader) = tun_tap_device::create_device(tun_tap_device::DeviceType::Tap, virtual_ip, virtual_netmask, virtual_gateway, in_ips)?;
let igmp_server = IgmpServer::new(tap_writer.clone());
let igmp_server = if config.simulate_multicast {
Some(IgmpServer::new(tap_writer.clone()))
} else {
None
};
//tap数据处理
tap_handler::start(channel_sender.clone(), tap_reader.clone(), tap_writer.clone(),
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
@@ -96,7 +109,11 @@ impl Switch {
}
// tun通道
let (tun_writer, tun_reader) = tun_tap_device::create_device(tun_tap_device::DeviceType::Tun, virtual_ip, virtual_netmask, virtual_gateway, in_ips)?;
let igmp_server = IgmpServer::new(tun_writer.clone());
let igmp_server = if config.simulate_multicast {
Some(IgmpServer::new(tun_writer.clone()))
} else {
None
};
//tun数据接收处理
tun_handler::start(channel_sender.clone(), tun_reader.clone(), tun_writer.clone(),
igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), cipher.clone());
@@ -188,6 +205,7 @@ pub struct Config {
pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
pub out_ips: Vec<(u32, u32, Ipv4Addr)>,
pub key: Option<[u8; 32]>,
pub simulate_multicast: bool,
}
use sha2::Digest;
@@ -198,7 +216,8 @@ impl Config {
name: String,
server_address: SocketAddr,
nat_test_server: Vec<SocketAddr>,
in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32, Ipv4Addr)>, password: Option<String>, ) -> Self {
in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32, Ipv4Addr)>,
password: Option<String>, simulate_multicast: bool, ) -> Self {
let key = if let Some(password) = password {
let mut hasher = sha2::Sha256::new();
hasher.update(password.as_bytes());
@@ -217,6 +236,7 @@ impl Config {
in_ips,
out_ips,
key,
simulate_multicast,
}
}
}
-3
View File
@@ -1,14 +1,11 @@
use std::io;
use crossbeam::channel::RecvError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("Io error")]
Io(#[from] io::Error),
#[error("Channel error")]
Channel(#[from] RecvError),
#[error("Protobuf error")]
Protobuf(#[from] protobuf::Error),
#[error("Invalid packet")]
+33 -28
View File
@@ -3,8 +3,7 @@ use std::sync::Arc;
use std::time::Duration;
use std::io;
use chrono::Local;
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use rand::prelude::SliceRandom;
use crate::channel::idle::Idle;
@@ -52,7 +51,7 @@ pub async fn start_heartbeat(
}
fn set_now_time(packet: &mut NetPacket<[u8; 16]>) -> io::Result<()> {
let current_time = Local::now().timestamp_millis() as u16;
let current_time = crate::handle::now_time() as u16;
let mut ping = PingPacket::new(packet.payload_mut())?;
ping.set_time(current_time);
Ok(())
@@ -90,40 +89,46 @@ async fn start_heartbeat_(
}
if count < 7 || count % 7 == 0 {
let mut route_list: Option<Vec<(Ipv4Addr, Vec<Route>)>> = None;
let peer_list = {device_list.lock().1.clone()};
let peer_list = { device_list.lock().1.clone() };
for peer in peer_list {
if peer.virtual_ip == current_device.virtual_ip {
continue;
}
set_now_time(&mut net_packet)?;
net_packet.set_destination(peer.virtual_ip);
if sender
.send_by_id(net_packet.buffer(), &peer.virtual_ip).await
.is_err()
{
//没有路由则发送到网关
if let Some(route) = sender.route_one(&peer.virtual_ip) {
let _ = sender.send_by_key(net_packet.buffer(), &route.route_key()).await;
if route.is_p2p() {
continue;
}
} else {
//没有直连路由则发送到网关
let _ = sender.try_send_main(net_packet.buffer(), current_device.connect_server);
//再随机发送到其他地址,看有没有客户端符合转发条件
let route_list = route_list.get_or_insert_with(|| {
let mut l = sender.route_table();
l.shuffle(&mut rand::thread_rng());
l
});
let mut num = 0;
'a: for (peer_ip, route_list) in route_list.iter() {
for route in route_list {
if peer_ip != &peer.virtual_ip && route.metric == 1 {
set_now_time(&mut net_packet)?;
let _ = sender.try_send_by_key(net_packet.buffer(), &route.route_key());
num += 1;
break;
}
if num >= 3 {
break 'a;
}
continue;
}
//再随机发送到其他地址,看有没有客户端符合转发条件
let route_list = route_list.get_or_insert_with(|| {
let mut l = sender.route_table();
l.shuffle(&mut rand::thread_rng());
l
});
let mut num = 0;
'a: for (peer_ip, route_list) in route_list.iter() {
for route in route_list {
if peer_ip != &peer.virtual_ip && route.is_p2p() {
set_now_time(&mut net_packet)?;
let _ = sender.try_send_by_key(net_packet.buffer(), &route.route_key());
num += 1;
break;
}
if num >= 3 {
break 'a;
}
}
}
tokio::time::sleep(Duration::from_millis(1)).await;
}
} else {
for (peer_ip, route_list) in sender.route_table().iter() {
set_now_time(&mut net_packet)?;
+9
View File
@@ -6,6 +6,15 @@ pub mod recv_handler;
pub mod registration_handler;
pub mod tun_tap;
pub fn now_time() -> u64 {
let now = std::time::SystemTime::now();
if let Ok(timestamp) = now.duration_since(std::time::UNIX_EPOCH) {
timestamp.as_secs() * 1000 + u64::from(timestamp.subsec_millis())
} else {
0
}
}
/// 是否在一个网段
fn check_dest(dest: Ipv4Addr, virtual_netmask: Ipv4Addr, virtual_network: Ipv4Addr) -> bool {
u32::from_be_bytes(dest.octets()) & u32::from_be_bytes(virtual_netmask.octets())
+2 -2
View File
@@ -2,7 +2,7 @@ use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest;
use crate::proto::message::{PunchInfo, PunchNatType};
use crate::protocol::{control_packet, other_turn_packet, NetPacket, Protocol, Version, MAX_TTL};
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use protobuf::Message;
use rand::prelude::SliceRandom;
@@ -89,7 +89,7 @@ async fn start_punch_(
break;
}
let buf = punch_packet(current_device.virtual_ip(), &nat_info, info.virtual_ip)?;
sender.send_main(&buf, current_device.connect_server).await?;
let _ = sender.send_main(&buf, current_device.connect_server).await;
}
}
num += 1;
+61 -55
View File
@@ -4,8 +4,7 @@ use aes_gcm::{AeadInPlace, Aes256Gcm, Nonce, Tag};
use aes_gcm::aead::consts::{U12, U16};
use aes_gcm::aead::generic_array::GenericArray;
use chrono::Local;
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use crossbeam_skiplist::SkipMap;
use parking_lot::Mutex;
use protobuf::Message;
@@ -40,11 +39,11 @@ pub struct ChannelDataHandler {
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
register: Arc<Register>,
nat_test: NatTest,
igmp_server: IgmpServer,
igmp_server: Option<IgmpServer>,
device_writer: DeviceWriter,
connect_status: Arc<AtomicCell<ConnectStatus>>,
peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>,
ip_proxy_map: IpProxyMap,
ip_proxy_map: Option<IpProxyMap>,
out_external_route: ExternalRoute,
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
@@ -56,11 +55,11 @@ impl ChannelDataHandler {
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
register: Arc<Register>,
nat_test: NatTest,
igmp_server: IgmpServer,
igmp_server: Option<IgmpServer>,
device_writer: DeviceWriter,
connect_status: Arc<AtomicCell<ConnectStatus>>,
peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>,
ip_proxy_map: IpProxyMap,
ip_proxy_map: Option<IpProxyMap>,
out_external_route: ExternalRoute,
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
@@ -103,8 +102,9 @@ impl ChannelDataHandler {
let source = net_packet.source();
let current_device = self.current_device.load();
let destination = net_packet.destination();
let not_broadcast = !destination.is_broadcast() && !destination.is_multicast() && destination != current_device.broadcast_address;
if current_device.virtual_ip() != destination
&& !destination.is_broadcast() && !destination.is_multicast() && destination != current_device.broadcast_address
&& not_broadcast
&& self.connect_status.load() == ConnectStatus::Connected {
if !check_dest(source, current_device.virtual_netmask, current_device.virtual_network) {
log::warn!("转发数据,源地址错误:{:?},当前网络:{:?},route_key:{:?}",source,current_device.virtual_network,route_key);
@@ -141,9 +141,11 @@ impl ChannelDataHandler {
}
}
ip_turn_packet::Protocol::Igmp => {
let ipv4 = IpV4Packet::new(net_packet.payload())?;
if ipv4.protocol() == ipv4::protocol::Protocol::Igmp {
self.igmp_server.handle(ipv4.payload(), source)?;
if let Some(igmp_server) = &self.igmp_server {
let ipv4 = IpV4Packet::new(net_packet.payload())?;
if ipv4.protocol() == ipv4::protocol::Protocol::Igmp {
igmp_server.handle(ipv4.payload(), source)?;
}
}
return Ok(());
}
@@ -180,7 +182,9 @@ impl ChannelDataHandler {
let mut ipv4 = IpV4Packet::new(data)?;
match ipv4.protocol() {
ipv4::protocol::Protocol::Igmp => {
self.igmp_server.handle(ipv4.payload(), source)?;
if let Some(igmp_server) = &self.igmp_server {
igmp_server.handle(ipv4.payload(), source)?;
}
return Ok(());
}
ipv4::protocol::Protocol::Icmp => {
@@ -226,51 +230,53 @@ impl ChannelDataHandler {
}
_ => {}
}
if ipv4.destination_ip() != destination {
if let Some(gate_way) = self.out_external_route.route(&ipv4.destination_ip()) {
match ipv4.protocol() {
ipv4::protocol::Protocol::Tcp => {
let dest_ip = ipv4.destination_ip();
//转发到代理目标地址
let mut tcp_packet = packet::tcp::tcp::TcpPacket::new(source, destination, ipv4.payload_mut())?;
let source_port = tcp_packet.source_port();
let dest_port = tcp_packet.destination_port();
tcp_packet.set_destination_port(self.ip_proxy_map.tcp_proxy_port);
tcp_packet.update_checksum();
ipv4.set_destination_ip(destination);
ipv4.update_checksum();
self.ip_proxy_map.tcp_proxy_map.insert(SocketAddrV4::new(source, source_port),
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
}
ipv4::protocol::Protocol::Udp => {
let dest_ip = ipv4.destination_ip();
//转发到代理目标地址
let mut udp_packet = packet::udp::udp::UdpPacket::new(source, destination, ipv4.payload_mut())?;
let source_port = udp_packet.source_port();
let dest_port = udp_packet.destination_port();
udp_packet.set_destination_port(self.ip_proxy_map.udp_proxy_port);
udp_packet.update_checksum();
ipv4.set_destination_ip(destination);
ipv4.update_checksum();
self.ip_proxy_map.udp_proxy_map.insert(SocketAddrV4::new(source, source_port),
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
}
ipv4::protocol::Protocol::Icmp => {
let dest_ip = ipv4.destination_ip();
//转发到代理目标地址
let icmp_packet = icmp::IcmpPacket::new(ipv4.payload())?;
match icmp_packet.header_other() {
HeaderOther::Identifier(id, seq) => {
self.ip_proxy_map.icmp_proxy_map.insert((dest_ip, id, seq), source);
self.ip_proxy_map.send_icmp(ipv4.payload(), &gate_way, &dest_ip)?;
}
_ => {
return Ok(());
if not_broadcast && ipv4.destination_ip() != destination {
if let Some(ip_proxy_map) = &self.ip_proxy_map {
if let Some(gate_way) = self.out_external_route.route(&ipv4.destination_ip()) {
match ipv4.protocol() {
ipv4::protocol::Protocol::Tcp => {
let dest_ip = ipv4.destination_ip();
//转发到代理目标地址
let mut tcp_packet = packet::tcp::tcp::TcpPacket::new(source, destination, ipv4.payload_mut())?;
let source_port = tcp_packet.source_port();
let dest_port = tcp_packet.destination_port();
tcp_packet.set_destination_port(ip_proxy_map.tcp_proxy_port);
tcp_packet.update_checksum();
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)));
}
ipv4::protocol::Protocol::Udp => {
let dest_ip = ipv4.destination_ip();
//转发到代理目标地址
let mut udp_packet = packet::udp::udp::UdpPacket::new(source, destination, ipv4.payload_mut())?;
let source_port = udp_packet.source_port();
let dest_port = udp_packet.destination_port();
udp_packet.set_destination_port(ip_proxy_map.udp_proxy_port);
udp_packet.update_checksum();
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)));
}
ipv4::protocol::Protocol::Icmp => {
let dest_ip = ipv4.destination_ip();
//转发到代理目标地址
let icmp_packet = icmp::IcmpPacket::new(ipv4.payload())?;
match icmp_packet.header_other() {
HeaderOther::Identifier(id, seq) => {
ip_proxy_map.icmp_proxy_map.insert((dest_ip, id, seq), source);
ip_proxy_map.send_icmp(ipv4.payload(), &gate_way, &dest_ip)?;
}
_ => {
return Ok(());
}
}
}
}
_ => {
return Ok(());
_ => {
return Ok(());
}
}
}
}
@@ -406,7 +412,7 @@ impl ChannelDataHandler {
}
ControlPacket::PongPacket(pong_packet) => {
context.update_read_time(&source, route_key);
let current_time = Local::now().timestamp_millis() as u16;
let current_time = crate::handle::now_time() as u16;
if current_time < pong_packet.time() {
return Ok(());
}
+8 -10
View File
@@ -1,9 +1,8 @@
use std::io;
use std::net::SocketAddr;
use std::sync::atomic::{AtomicI64, Ordering};
use std::time::Duration;
use std::time::{Duration, Instant};
use crossbeam_utils::atomic::AtomicCell;
use chrono::Local;
use protobuf::Message;
use tokio::net::UdpSocket;
use crate::channel::sender::ChannelSender;
@@ -105,7 +104,7 @@ fn registration_request_packet(
request.device_id = device_id;
request.name = name;
request.is_fast = is_fast;
request.version = "1.0.6".to_string();
request.version = "1.0.7".to_string();
let bytes = request.write_to_bytes()?;
let buf = vec![0u8; 12 + bytes.len()];
let mut net_packet = NetPacket::new(buf)?;
@@ -123,7 +122,7 @@ pub struct Register {
token: String,
device_id: String,
name: String,
time: AtomicI64,
time: AtomicCell<Instant>,
}
impl Register {
@@ -140,16 +139,15 @@ impl Register {
token,
device_id,
name,
time: AtomicI64::new(0),
time: AtomicCell::new(Instant::now()),
}
}
pub async fn fast_register(&self) -> io::Result<()> {
let last = self.time.load(Ordering::Relaxed);
let new = Local::now().timestamp_millis();
if new - last < 1000
let last = self.time.load();
if last.elapsed() < Duration::from_secs(2)
|| self
.time
.compare_exchange(last, new, Ordering::Relaxed, Ordering::Relaxed)
.compare_exchange(last, Instant::now())
.is_err()
{
//短时间不重复注册
+121 -58
View File
@@ -22,11 +22,36 @@ 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.direct_route_table_one();
let vec = sender.route_table_one();
let mut relay_count = 0;
let mut last_peer = None;
for (peer_ip, route) in vec {
if sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
peer_ips.push(peer_ip);
if peer_ip == current_device.virtual_gateway {
continue;
}
if peer_ips.len() < u8::MAX as usize && 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() {
//不需要转发
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?;
@@ -44,20 +69,42 @@ async fn broadcast(sender: &ChannelSender, net_packet: &mut NetPacket<&mut [u8]>
async fn multicast(igmp_server: &IgmpServer, multicast_addr: Ipv4Addr, 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.direct_route_table_one();
let vec = sender.route_table_one();
let mut relay_count = 0;
let mut last_peer = None;
if let Some(members) = igmp_server.load(&multicast_addr) {
for (peer_ip, route) in vec {
let is_send = {members.read().is_send(&peer_ip)};
if peer_ip == current_device.virtual_gateway {
continue;
}
let is_send = { members.read().is_send(&peer_ip) };
if is_send {
if sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
if peer_ips.len() < u8::MAX as usize && route.is_p2p()
&& sender.send_by_key(&net_packet.buffer()[..data_len], &route.route_key()).await.is_ok() {
peer_ips.push(peer_ip);
if peer_ips.len() == u8::MAX as usize {
} 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() {
//不需要转发
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 {
@@ -78,9 +125,9 @@ async fn multicast(igmp_server: &IgmpServer, multicast_addr: Ipv4Addr, sender: &
#[inline]
pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
mut data_len: usize,//数据总长度=ip长度+12
igmp_server: &IgmpServer,
igmp_server: &Option<IgmpServer>,
current_device: CurrentDeviceInfo,
ip_route: &ExternalRoute, proxy_map: &IpProxyMap, cipher: &Option<Aes256Gcm>) -> Result<()> {
ip_route: &Option<ExternalRoute>, proxy_map: &Option<IpProxyMap>, cipher: &Option<Aes256Gcm>) -> Result<()> {
let ipv4_packet = IpV4Packet::new(&buf[12..data_len])?;
let protocol = ipv4_packet.protocol();
let ip_head_len = ipv4_packet.header_len() as usize * 4;
@@ -102,11 +149,33 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
return Ok(());
}
if dest_ip.is_multicast() {
if protocol == Protocol::Igmp {
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Igmp.into());
//发送到服务端
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
return Ok(());
match protocol {
Protocol::Igmp => {
if igmp_server.is_some() {
net_packet.set_transport_protocol(ip_turn_packet::Protocol::Igmp.into());
//发送到服务端
net_packet.set_destination(current_device.virtual_gateway);
sender.send_main(&net_packet.buffer()[..data_len], current_device.connect_server).await?;
}
return Ok(());
}
Protocol::Udp => {
if let Some(igmp_server) = igmp_server {
if let Some(cipher) = cipher {
//需要加密
encrypt(cipher, &mut data_len, &mut net_packet)?;
}
multicast(igmp_server, dest_ip, sender, &mut net_packet, data_len, &current_device).await?;
return Ok(());
} else {
//当广播
dest_ip = Ipv4Addr::BROADCAST;
net_packet.set_destination(dest_ip);
}
}
_ => {
return Ok(());
}
}
}
if dest_ip.is_broadcast() || current_device.broadcast_address == dest_ip {
@@ -119,17 +188,9 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
broadcast(sender, &mut net_packet, data_len, &current_device).await?;
}
return Ok(());
} else if dest_ip.is_multicast() {
if protocol == Protocol::Udp {
if let Some(cipher) = cipher {
//需要加密
encrypt(cipher, &mut data_len, &mut net_packet)?;
}
multicast(igmp_server, dest_ip, sender, &mut net_packet, data_len, &current_device).await?;
}
return Ok(());
} else {
if !check_dest(dest_ip, current_device.virtual_netmask, current_device.virtual_network) {
}
if !check_dest(dest_ip, current_device.virtual_netmask, current_device.virtual_network) {
if let Some(ip_route) = ip_route {
if let Some(r_dest_ip) = ip_route.route(&dest_ip) {
//路由的目标不能是自己
if r_dest_ip == src_ip {
@@ -142,41 +203,43 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
return Ok(());
}
} else {
match protocol {
Protocol::Tcp => {
let dest_addr = {
let tcp_packet = TcpPacket::new(src_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
SocketAddrV4::new(dest_ip, tcp_packet.destination_port())
};
if let Some(entry) = proxy_map.tcp_proxy_map.get(&dest_addr) {
let source_addr = entry.value().1;
let source_ip = *source_addr.ip();
let mut tcp_packet = TcpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
tcp_packet.set_source_port(source_addr.port());
tcp_packet.update_checksum();
let mut ipv4_packet = IpV4Packet::new(&mut net_packet.buffer_mut()[12..data_len])?;
ipv4_packet.set_source_ip(source_ip);
ipv4_packet.update_checksum();
}
return Ok(());
}
} else if let Some(proxy_map) = proxy_map {
match protocol {
Protocol::Tcp => {
let dest_addr = {
let tcp_packet = TcpPacket::new(src_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
SocketAddrV4::new(dest_ip, tcp_packet.destination_port())
};
if let Some(entry) = proxy_map.tcp_proxy_map.get(&dest_addr) {
let source_addr = entry.value().1;
let source_ip = *source_addr.ip();
let mut tcp_packet = TcpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
tcp_packet.set_source_port(source_addr.port());
tcp_packet.update_checksum();
let mut ipv4_packet = IpV4Packet::new(&mut net_packet.buffer_mut()[12..data_len])?;
ipv4_packet.set_source_ip(source_ip);
ipv4_packet.update_checksum();
}
Protocol::Udp => {
let dest_addr = {
let udp_packet = UdpPacket::new(src_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
SocketAddrV4::new(dest_ip, udp_packet.destination_port())
};
if let Some(entry) = proxy_map.udp_proxy_map.get(&dest_addr) {
let source_addr = entry.value().1;
let source_ip = *source_addr.ip();
let mut udp_packet = UdpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
udp_packet.set_source_port(source_addr.port());
udp_packet.update_checksum();
let mut ipv4_packet = IpV4Packet::new(&mut net_packet.buffer_mut()[12..data_len])?;
ipv4_packet.set_source_ip(source_ip);
ipv4_packet.update_checksum();
}
}
_ => {}
}
Protocol::Udp => {
let dest_addr = {
let udp_packet = UdpPacket::new(src_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
SocketAddrV4::new(dest_ip, udp_packet.destination_port())
};
if let Some(entry) = proxy_map.udp_proxy_map.get(&dest_addr) {
let source_addr = entry.value().1;
let source_ip = *source_addr.ip();
let mut udp_packet = UdpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
udp_packet.set_source_port(source_addr.port());
udp_packet.update_checksum();
let mut ipv4_packet = IpV4Packet::new(&mut net_packet.buffer_mut()[12..data_len])?;
ipv4_packet.set_source_ip(source_ip);
ipv4_packet.update_checksum();
}
}
_ => {}
}
}
if let Some(cipher) = cipher {
+11 -11
View File
@@ -1,7 +1,7 @@
use std::sync::Arc;
use std::{io, thread};
use aes_gcm::Aes256Gcm;
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use packet::arp::arp::ArpPacket;
use packet::ethernet;
use packet::ethernet::packet::EthernetPacket;
@@ -19,10 +19,10 @@ use crate::tun_tap_device::{DeviceReader, DeviceWriter};
pub fn start(sender: ChannelSender,
device_reader: DeviceReader,
device_writer: DeviceWriter,
igmp_server: IgmpServer,
igmp_server: Option<IgmpServer>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap,
ip_route: Option<ExternalRoute>,
ip_proxy_map: Option<IpProxyMap>,
cipher: Option<Aes256Gcm>) {
thread::Builder::new().name("tap-handler".into()).spawn(move || {
tokio::runtime::Builder::new_current_thread()
@@ -40,23 +40,23 @@ pub fn start(sender: ChannelSender,
async fn start_(sender: ChannelSender,
device_reader: DeviceReader,
device_writer: DeviceWriter,
igmp_server: IgmpServer,
igmp_server: Option<IgmpServer>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap,
ip_route: Option<ExternalRoute>,
ip_proxy_map: Option<IpProxyMap>,
cipher: Option<Aes256Gcm>) -> io::Result<()> {
let mut buf = [0; 2048];
let mut buf = [0; 4096];
loop {
//ip拆包了会直接丢弃?
let len = device_reader.read(&mut buf)?;
if let Err(e) = handle(&mut buf, len, &igmp_server, &current_device, &device_writer, &sender, &ip_route, &ip_proxy_map, &cipher).await {
log::error!("tap handle{:?}",e);
log::warn!("tap handle{:?}",e);
}
}
}
async fn handle(buf: &mut [u8], len: usize, igmp_server: &IgmpServer, current_device: &AtomicCell<CurrentDeviceInfo>,
device_writer: &DeviceWriter, sender: &ChannelSender, ip_route: &ExternalRoute, proxy_map: &IpProxyMap, cipher: &Option<Aes256Gcm>) -> crate::Result<()> {
async fn handle(buf: &mut [u8], len: usize, igmp_server: &Option<IgmpServer>, current_device: &AtomicCell<CurrentDeviceInfo>,
device_writer: &DeviceWriter, sender: &ChannelSender, ip_route: &Option<ExternalRoute>, proxy_map: &Option<IpProxyMap>, cipher: &Option<Aes256Gcm>) -> crate::Result<()> {
let mut ethernet_packet = EthernetPacket::new(&mut buf[..len])?;
let current_device = current_device.load();
match ethernet_packet.protocol() {
+26 -16
View File
@@ -2,7 +2,7 @@ use std::{io, thread};
use std::sync::Arc;
use aes_gcm::Aes256Gcm;
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use packet::icmp::Kind;
use packet::icmp::icmp::IcmpPacket;
@@ -35,8 +35,8 @@ 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: &IgmpServer, current_device: CurrentDeviceInfo,
ip_route: &ExternalRoute, proxy_map: &IpProxyMap,cipher: &Option<Aes256Gcm>) -> Result<()> {
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<()> {
let ipv4_packet = if let Ok(ipv4_packet) = IpV4Packet::new(&mut data[12..len]) {
ipv4_packet
} else {
@@ -56,13 +56,13 @@ async fn handle(sender: &ChannelSender, data: &mut [u8], len: usize, device_writ
pub fn start(sender: ChannelSender,
device_reader: DeviceReader,
device_writer: DeviceWriter,
igmp_server: IgmpServer,
igmp_server: Option<IgmpServer>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap,
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_current_thread()
tokio::runtime::Builder::new_multi_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 {
@@ -75,19 +75,29 @@ pub fn start(sender: ChannelSender,
async fn start_(sender: ChannelSender,
device_reader: DeviceReader,
device_writer: DeviceWriter,
igmp_server: IgmpServer,
igmp_server: Option<IgmpServer>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap,
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();
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 {
Ok(_) => {}
Err(e) => {
log::warn!("{:?}", e)
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)
}
}
}
});
}
}
+40 -52
View File
@@ -1,8 +1,8 @@
use std::collections::{HashMap, HashSet};
use std::net::Ipv4Addr;
use std::sync::Arc;
use std::time::Duration;
use moka::sync::Cache;
use std::time::{Duration, Instant};
use crossbeam_skiplist::SkipMap;
use parking_lot::RwLock;
use packet::igmp::igmp_v2::IgmpV2Packet;
use packet::igmp::igmp_v3::{IgmpV3QueryPacket, IgmpV3RecordType, IgmpV3ReportPacket};
@@ -15,7 +15,7 @@ use crate::tun_tap_device::DeviceWriter;
#[derive(Clone, Debug)]
pub struct Multicast {
//成员虚拟ip
members: HashSet<Ipv4Addr>,
members: HashMap<Ipv4Addr, Instant>,
//是否是过滤模式
//成员过滤或包含的源ip
map: HashMap<Ipv4Addr, (bool, HashSet<Ipv4Addr>)>,
@@ -29,7 +29,7 @@ impl Multicast {
}
}
pub fn is_send(&self, ip: &Ipv4Addr) -> bool {
if self.members.contains(ip) {
if self.members.contains_key(ip) {
if let Some((is_include, set)) = self.map.get(ip) {
if *is_include {
set.contains(ip)
@@ -47,30 +47,13 @@ impl Multicast {
#[derive(Clone)]
pub struct IgmpServer {
multicast: Cache<Ipv4Addr, Arc<RwLock<Multicast>>>,
members: Cache<(Ipv4Addr, Ipv4Addr), ()>,
multicast: Arc<SkipMap<Ipv4Addr, Arc<RwLock<Multicast>>>>,
}
impl IgmpServer {
pub fn new(device_writer: DeviceWriter) -> Self {
let multicast: Cache<Ipv4Addr, Arc<RwLock<Multicast>>> = Cache::builder()
.time_to_idle(Duration::from_secs(30 * 60)).build();
let m = multicast.clone();
let members: Cache<(Ipv4Addr, Ipv4Addr), ()> = Cache::builder()
.time_to_idle(Duration::from_secs(20 * 60)).eviction_listener(move |k: Arc<(Ipv4Addr, Ipv4Addr)>, _, cause| {
if cause == moka::notification::RemovalCause::Replaced {
return;
}
log::info!("MULTICAST_MEMBER eviction {:?}", k);
if let Some(v) = m.get(&k.0) {
let mut lock = v.write();
lock.members.remove(&k.1);
lock.map.remove(&k.1);
}
}).build();
let multicast: Arc<SkipMap<Ipv4Addr, Arc<RwLock<Multicast>>>> = Arc::new(SkipMap::new());
std::thread::spawn(move || {
//定时发送query,启动时20秒一次,连发3次,之后125秒一次
let mut count = 0;
//预留以太网帧头和ip头
let mut buf = [0; 14 + 24 + 12];
let dest = Ipv4Addr::new(224, 0, 0, 1);
@@ -96,31 +79,42 @@ impl IgmpServer {
{
let mut igmp_query = IgmpV3QueryPacket::unchecked(&mut buf[14 + 24..]);
igmp_query.set_igmp_type();
igmp_query.set_max_resp_code(100);
igmp_query.set_max_resp_code(50);
igmp_query.set_group_address(Ipv4Addr::UNSPECIFIED);
igmp_query.set_qrv(2);
igmp_query.set_qqic(125);
igmp_query.set_qqic(10);
igmp_query.update_checksum();
}
loop {
let _ = device_writer.write_ipv4(&mut buf);
if count < 3 {
count += 1;
std::thread::sleep(Duration::from_secs(20))
} else {
std::thread::sleep(Duration::from_secs(125))
}
std::thread::sleep(Duration::from_secs(20))
}
});
Self {
multicast,
members,
}
}
pub fn load(&self, multicast_addr: &Ipv4Addr) -> Option<Arc<RwLock<Multicast>>> {
self.multicast.get(multicast_addr)
if let Some(entry) = self.multicast.get(multicast_addr) {
Some(entry.value().clone())
} else {
None
}
}
pub fn handle(&self, buf: &[u8], source: Ipv4Addr) -> crate::Result<()> {
for x in self.multicast.iter() {
let mut list = Vec::new();
let mut write_guard = x.value().write();
for (ip, time) in &write_guard.members {
if time.elapsed() > Duration::from_secs(30) {
list.push(*ip);
}
}
for ip in list {
write_guard.members.remove(&ip);
write_guard.map.remove(&ip);
}
}
match IgmpType::from(buf[0]) {
IgmpType::Query => {}
IgmpType::ReportV1 | IgmpType::ReportV2 => {
@@ -130,13 +124,11 @@ impl IgmpServer {
if !multicast_addr.is_multicast() {
return Ok(());
}
let multi = self.multicast.get_with(multicast_addr, || {
let multi = self.multicast.get_or_insert_with(multicast_addr, || {
Arc::new(RwLock::new(Multicast::new()))
});
let mut guard = multi.write();
guard.members.insert(source);
drop(guard);
self.members.insert((multicast_addr, source), ());
let mut guard = multi.value().write();
guard.members.insert(source, Instant::now());
}
IgmpType::LeaveV2 => {
//退出组播
@@ -145,7 +137,11 @@ impl IgmpServer {
if !multicast_addr.is_multicast() {
return Ok(());
}
self.members.invalidate(&(multicast_addr, source));
if let Some(entry) = self.multicast.get(&multicast_addr) {
let mut guard = entry.value().write();
guard.map.remove(&source);
guard.members.remove(&source);
}
}
IgmpType::ReportV3 => {
let report = IgmpV3ReportPacket::new(buf)?;
@@ -155,10 +151,10 @@ impl IgmpServer {
if !multicast_addr.is_multicast() {
return Ok(());
}
let multi = self.multicast.get_with(multicast_addr, || {
let multi = self.multicast.get_or_insert_with(multicast_addr, || {
Arc::new(RwLock::new(Multicast::new()))
});
let mut guard = multi.write();
let mut guard = multi.value().write();
match group_record.record_type() {
IgmpV3RecordType::ModeIsInclude | IgmpV3RecordType::ChangeToIncludeMode => {
@@ -169,10 +165,8 @@ impl IgmpServer {
guard.map.remove(&source);
}
Some(src) => {
guard.members.insert(source);
guard.members.insert(source, Instant::now());
guard.map.insert(source, (true, HashSet::from_iter(src)));
drop(guard);
self.members.insert((multicast_addr, source), ());
}
}
}
@@ -181,16 +175,14 @@ impl IgmpServer {
match group_record.source_addresses() {
None => {
//接收所有
guard.members.insert(source);
guard.members.insert(source, Instant::now());
guard.map.remove(&source);
}
Some(src) => {
guard.members.insert(source);
guard.members.insert(source, Instant::now());
guard.map.insert(source, (false, HashSet::from_iter(src)));
}
}
drop(guard);
self.members.insert((multicast_addr, source), ());
}
IgmpV3RecordType::AllowNewSources => {
//在已有源的基础上,接收目标源,如果是排除模式,则删除;是包含模式则添加
@@ -211,8 +203,6 @@ impl IgmpServer {
}
}
}
drop(guard);
self.members.insert((multicast_addr, source), ());
}
IgmpV3RecordType::BlockOldSources => {
//在已有源的基础上,不接收目标源
@@ -233,8 +223,6 @@ impl IgmpServer {
}
}
}
drop(guard);
self.members.insert((multicast_addr, source), ());
}
IgmpV3RecordType::Unknown(_) => {}
}
+2 -2
View File
@@ -2,7 +2,7 @@ use std::io;
use std::mem::MaybeUninit;
use std::net::{IpAddr, Ipv4Addr, SocketAddrV4};
use std::sync::Arc;
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use crossbeam_skiplist::SkipMap;
use socket2::{Domain, SockAddr, Socket, Type};
@@ -68,7 +68,7 @@ impl IcmpProxy {
net_packet.set_version(Version::V1);
net_packet.set_protocol(Protocol::IpTurn);
net_packet.set_transport_protocol(ipv4::protocol::Protocol::Icmp.into());
net_packet.set_ttl(MAX_TTL);
net_packet.first_set_ttl(MAX_TTL);
loop {
match self.recv(data) {
Ok((len, peer_ip)) => {
+1 -1
View File
@@ -2,7 +2,7 @@ use std::{io, thread};
use std::collections::HashMap;
use std::net::{Ipv4Addr, SocketAddrV4};
use std::sync::Arc;
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use crossbeam_skiplist::SkipMap;
use socket2::{SockAddr, Socket};
use tokio::net::{TcpListener, UdpSocket};
+2 -1
View File
@@ -6,7 +6,6 @@ use tokio::net::{TcpListener, TcpStream};
pub struct TcpProxy {
tcp_listener: TcpListener,
// todo 怎么过期
map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>,
}
@@ -34,6 +33,7 @@ impl TcpProxy {
continue;
}
};
let map = map.clone();
tokio::spawn(async move {
match proxy(tcp_stream, peer_tcp_stream).await {
Ok(_) => {}
@@ -41,6 +41,7 @@ impl TcpProxy {
log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr);
}
}
map.remove(&sender_addr);
});
}
}
+2 -1
View File
@@ -8,7 +8,6 @@ use tokio::net::UdpSocket;
/// 一个udp代理,作用是利用系统协议栈,将udp数据报解析出来再转发到目的地址
pub struct UdpProxy {
udp_socket: Arc<UdpSocket>,
// todo 过期处理
map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>,
}
@@ -61,6 +60,7 @@ async fn start0(buf: &[u8], sender_addr: SocketAddrV4, inner_map: &Arc<SkipMap<S
let inner_map = inner_map.clone();
inner_map.insert(sender_addr, peer_udp_socket.clone());
let udp_socket = udp_socket.clone();
let map = map.clone();
tokio::spawn(async move {
let mut buf = [0u8; 65536];
loop {
@@ -90,6 +90,7 @@ async fn start0(buf: &[u8], sender_addr: SocketAddrV4, inner_map: &Arc<SkipMap<S
}
}
inner_map.remove(&sender_addr);
map.remove(&sender_addr);
});
}
Ok(())
-14
View File
@@ -4,20 +4,6 @@ use std::time::Duration;
use std::{io, thread};
use crate::channel::punch::NatType;
// #[derive(Debug, Copy, Clone, PartialEq)]
// pub enum NatType {
// Symmetric,
// Cone,
// }
//
// impl Into<u8> for NatType {
// fn into(self) -> u8 {
// match self {
// NatType::Symmetric => 0,
// NatType::Cone => 1,
// }
// }
// }
/// 返回所有公网ip和端口变化范围
pub fn public_ip_list(addrs: &Vec<SocketAddr>) -> io::Result<(NatType, Vec<Ipv4Addr>, u16)> {
+1 -1
View File
@@ -5,7 +5,7 @@ use bytes::BufMut;
use tun::platform::posix::{Reader, Writer};
use std::net::Ipv4Addr;
use std::os::unix::io::AsRawFd;
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
#[cfg(any(target_os = "linux", target_os = "android"))]
use tun::platform::linux::Device;
#[cfg(any(target_os = "macos", target_os = "ios"))]
+1 -1
View File
@@ -2,7 +2,7 @@ use std::{io, thread};
use std::net::Ipv4Addr;
use std::sync::Arc;
use std::time::Duration;
use crossbeam::atomic::AtomicCell;
use crossbeam_utils::atomic::AtomicCell;
use libloading::Library;
use parking_lot::Mutex;
use packet::ethernet;