使用tokio改写处理逻辑

This commit is contained in:
lubeilin
2023-06-23 15:32:49 +08:00
parent 17f3fcf9b0
commit ba2c792e2a
24 changed files with 617 additions and 895 deletions
+65 -67
View File
@@ -1,60 +1,54 @@
use std::net::Ipv4Addr;
use std::sync::Arc;
use std::time::Duration;
use std::{io, thread};
use std::io;
use chrono::Local;
use crossbeam::atomic::AtomicCell;
use parking_lot::Mutex;
use rand::prelude::SliceRandom;
use crate::channel::idle::Idle;
use crate::channel::Route;
use crate::channel::sender::ChannelSender;
use p2p_channel::channel::sender::Sender;
use p2p_channel::channel::Route;
use p2p_channel::idle::Idle;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::protocol::control_packet::PingPacket;
use crate::protocol::{control_packet, NetPacket, Protocol, Version, MAX_TTL};
use crate::protocol::{control_packet, NetPacket, Protocol, Version};
pub fn start_idle(idle: Idle<Ipv4Addr>, sender: Sender<Ipv4Addr>) {
thread::Builder::new()
.name("idle".into())
.spawn(move || {
if let Err(e) = start_idle_(idle, sender) {
log::info!("空闲检测线程停止:{:?}", e);
pub async fn start_idle(idle: Idle, sender: ChannelSender) {
tokio::spawn(async move {
match start_idle_(idle, sender).await {
Ok(_) => {}
Err(e) => {
log::warn!("空闲检测任务停止:{:?}", e);
}
})
.unwrap();
}
});
}
fn start_idle_(idle: Idle<Ipv4Addr>, sender: Sender<Ipv4Addr>) -> io::Result<()> {
async fn start_idle_(idle: Idle, sender: ChannelSender) -> io::Result<()> {
loop {
let (idle_status, peer_ips, route) = idle.next_idle()?;
log::warn!(
"peer_ip:{:?},route:{:?},idle_status:{:?}",
peer_ips,
route,
idle_status
let (peer_ip, route) = idle.next_idle().await?;
log::info!(
"peer_ip:{:?},route:{:?}",
peer_ip,
route
);
for peer_ip in peer_ips {
sender.remove_route(&peer_ip);
}
sender.remove_route(&peer_ip, route);
}
}
pub fn start_heartbeat(
sender: Sender<Ipv4Addr>,
pub async fn start_heartbeat(
sender: ChannelSender,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
) {
thread::Builder::new()
.name("heartbeat".into())
.spawn(move || {
if let Err(e) = start_heartbeat_(sender, device_list, current_device) {
log::info!("空闲检测线程停止:{:?}", e);
}
})
.unwrap();
tokio::spawn(async move {
if let Err(e) = start_heartbeat_(sender, device_list, current_device).await {
log::warn!("心跳任务停止:{:?}", e);
}
});
}
fn set_now_time(packet: &mut NetPacket<[u8; 16]>) -> io::Result<()> {
@@ -64,8 +58,8 @@ fn set_now_time(packet: &mut NetPacket<[u8; 16]>) -> io::Result<()> {
Ok(())
}
fn start_heartbeat_(
sender: Sender<Ipv4Addr>,
async fn start_heartbeat_(
sender: ChannelSender,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
) -> io::Result<()> {
@@ -73,7 +67,8 @@ fn start_heartbeat_(
net_packet.set_version(Version::V1);
net_packet.set_protocol(Protocol::Control);
net_packet.set_transport_protocol(control_packet::Protocol::Ping.into());
net_packet.first_set_ttl(MAX_TTL);
//只寻找两跳以内能到的目标
net_packet.first_set_ttl(2);
let mut count = 0;
loop {
let current_device = current_device.load();
@@ -83,19 +78,28 @@ fn start_heartbeat_(
let epoch = { device_list.lock().0 };
ping.set_epoch(epoch);
}
set_now_time(&mut net_packet)?;
net_packet.set_destination(current_device.virtual_gateway());
if let Err(e) = sender.send_main(net_packet.buffer(), current_device.connect_server).await
{
log::warn!(
"connect_server:{:?},e:{:?}",
current_device.connect_server,
e
);
}
if count < 7 || count % 7 == 0 {
let mut route_list: Option<Vec<(Ipv4Addr, Route)>> = None;
let peer_list = device_list.lock().1.clone();
let mut route_list: Option<Vec<(Ipv4Addr, Vec<Route>)>> = None;
let peer_list = {device_list.lock().1.clone()};
for peer in peer_list {
set_now_time(&mut net_packet)?;
net_packet.first_set_ttl(2);
net_packet.set_destination(peer.virtual_ip);
if sender
.send_to_id(net_packet.buffer(), &peer.virtual_ip)
.send_by_id(net_packet.buffer(), &peer.virtual_ip).await
.is_err()
{
//没有路由则发送到网关
let _ = sender.send_to_addr(net_packet.buffer(), current_device.connect_server);
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();
@@ -103,43 +107,37 @@ fn start_heartbeat_(
l
});
let mut num = 0;
//只寻找两跳以内能到的目标
net_packet.first_set_ttl(2);
for (peer_ip, route) in route_list.iter() {
if peer_ip != &peer.virtual_ip && route.metric == 1 {
set_now_time(&mut net_packet)?;
let _ = sender.send_to_route(net_packet.buffer(), &route.route_key());
num += 1;
}
if num >= 3 {
break;
'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;
}
}
}
}
thread::sleep(Duration::from_millis(1));
}
set_now_time(&mut net_packet)?;
net_packet.set_destination(current_device.virtual_gateway());
if let Err(e) = sender.send_to_addr(net_packet.buffer(), current_device.connect_server)
{
log::warn!(
"connect_server:{:?},e:{:?}",
current_device.connect_server,
e
);
tokio::time::sleep(Duration::from_millis(1)).await;
}
} else {
for (peer_ip, route) in sender.route_table().iter() {
for (peer_ip, route_list) in sender.route_table().iter() {
set_now_time(&mut net_packet)?;
net_packet.set_destination(*peer_ip);
if let Err(e) = sender.send_to_route(net_packet.buffer(), &route.route_key()) {
log::warn!("peer_ip:{:?},route:{:?},e:{:?}", peer_ip, route, e);
for route in route_list {
if let Err(e) = sender.send_by_key(net_packet.buffer(), &route.route_key()).await {
log::warn!("peer_ip:{:?},route:{:?},e:{:?}", peer_ip, route, e);
}
tokio::time::sleep(Duration::from_millis(2)).await;
}
thread::sleep(Duration::from_millis(1));
}
}
count += 1;
thread::sleep(Duration::from_millis(5000));
tokio::time::sleep(Duration::from_millis(5000)).await;
}
}
+1 -15
View File
@@ -1,11 +1,10 @@
use std::net::{Ipv4Addr, SocketAddr};
pub mod heartbeat_handler;
pub mod tun_handler;
pub mod tap_handler;
pub mod punch_handler;
pub mod recv_handler;
pub mod registration_handler;
pub mod tun_tap;
/// 是否在一个网段
fn check_dest(dest: Ipv4Addr, virtual_netmask: Ipv4Addr, virtual_network: Ipv4Addr) -> bool {
@@ -60,19 +59,6 @@ pub enum ConnectStatus {
Connected,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct CurrentDeviceInfoExt {
pub mac: [u8; 6],
}
impl CurrentDeviceInfoExt {
pub fn new(mac: [u8; 6]) -> Self {
Self {
mac,
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct CurrentDeviceInfo {
virtual_ip: Ipv4Addr,
+46 -86
View File
@@ -1,93 +1,72 @@
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest;
use crate::proto::message::{PunchInfo, PunchNatType};
use crate::protocol::{control_packet, turn_packet, NetPacket, Protocol, Version, MAX_TTL};
use crate::protocol::{control_packet, other_turn_packet, NetPacket, Protocol, Version, MAX_TTL};
use crossbeam::atomic::AtomicCell;
use p2p_channel::channel::sender::Sender;
use p2p_channel::punch::{NatInfo, NatType, Punch};
use parking_lot::Mutex;
use protobuf::Message;
use rand::prelude::SliceRandom;
use std::net::{IpAddr, Ipv4Addr};
use std::net::Ipv4Addr;
use std::sync::Arc;
use std::time::Duration;
use std::{io, thread};
use std::io;
use tokio::sync::mpsc::Receiver;
use crate::channel::punch::{NatInfo, Punch};
use crate::channel::sender::ChannelSender;
pub fn start_cone(punch: Punch<Ipv4Addr>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
thread::Builder::new()
.name("punch-cone".into())
.spawn(move || {
if let Err(e) = start_(true, punch, current_device) {
log::warn!("锥形网络打洞处理线程停止 {:?}", e);
}
})
.unwrap();
pub async fn start(receiver: Receiver<(Ipv4Addr, NatInfo)>, punch: Punch, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
tokio::spawn(async move {
start0(receiver, punch, current_device).await;
});
}
pub fn start_symmetric(punch: Punch<Ipv4Addr>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
thread::Builder::new()
.name("punch-symmetric".into())
.spawn(move || {
if let Err(e) = start_(false, punch, current_device) {
log::warn!("对称网络打洞处理线程停止 {:?}", e);
}
})
.unwrap();
pub async fn start0(mut receiver: Receiver<(Ipv4Addr, NatInfo)>, mut punch: Punch, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
while let Some((peer_ip, nat_info)) = receiver.recv().await {
if let Err(e) = start_(&mut punch, &current_device, peer_ip, nat_info).await {
log::warn!("网络打洞异常 {:?}", e);
}
}
}
fn start_(
is_cone: bool,
mut punch: Punch<Ipv4Addr>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
async fn start_(
punch: &mut Punch,
current_device: &Arc<AtomicCell<CurrentDeviceInfo>>,
peer_ip: Ipv4Addr,
nat_info: NatInfo,
) -> io::Result<()> {
let mut packet = NetPacket::new([0u8; 12])?;
packet.set_version(Version::V1);
packet.first_set_ttl(1);
packet.set_protocol(Protocol::Control);
packet.set_transport_protocol(control_packet::Protocol::PunchRequest.into());
loop {
let (peer_ip, nat_info) = if is_cone {
punch.next_cone(None)?
} else {
punch.next_symmetric(None)?
};
if let Some(route) = punch.sender().route(&peer_ip) {
if route.metric == 1 {
//直连地址不需要打洞
continue;
}
}
packet.set_source(current_device.load().virtual_ip());
packet.set_destination(peer_ip);
log::info!("发起打洞,目标:{:?},{:?}", peer_ip, nat_info);
if let Err(e) = punch.punch(packet.buffer(), peer_ip, nat_info) {
log::warn!("peer_ip:{:?},e:{:?}", peer_ip, e);
}
}
packet.set_source(current_device.load().virtual_ip());
packet.set_destination(peer_ip);
log::info!("发起打洞,目标:{:?},{:?}", peer_ip, nat_info);
punch.punch(packet.buffer(), peer_ip, nat_info).await
}
pub fn start_punch(
pub async fn start_punch(
nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
sender: Sender<Ipv4Addr>,
sender: ChannelSender,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
) {
thread::Builder::new()
.name("punch-send-request".into())
.spawn(move || {
if let Err(e) = start_punch_(nat_test, device_list, sender, current_device) {
log::warn!("对称网络打洞处理线程停止 {:?}", e);
}
})
.unwrap();
tokio::spawn(async move {
if let Err(e) = start_punch_(nat_test, device_list, sender, current_device).await {
log::warn!("打洞处理任务停止 {:?}", e);
}
});
}
fn start_punch_(
async fn start_punch_(
nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
sender: Sender<Ipv4Addr>,
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(());
@@ -102,28 +81,19 @@ fn start_punch_(
if info.virtual_ip <= current_device.virtual_ip {
continue;
}
if let Some(route) = sender.route(&info.virtual_ip) {
if route.metric == 1 {
//直连地址不需要打洞
continue;
}
if !sender.need_punch(&info.virtual_ip) {
continue;
}
count += 1;
if count > 3 {
if count > 2 {
break;
}
let buf = punch_packet(current_device.virtual_ip(), &nat_info, info.virtual_ip)?;
sender.send_to_addr(&buf, current_device.connect_server)?;
}
}
match nat_info.nat_type {
NatType::Symmetric => {
thread::sleep(Duration::from_secs(28));
}
NatType::Cone => {
thread::sleep(Duration::from_secs(20));
sender.send_main(&buf, current_device.connect_server).await?;
}
}
num += 1;
tokio::time::sleep(Duration::from_secs(sleep_time[num % sleep_time.len()])).await;
}
}
@@ -137,28 +107,18 @@ pub fn punch_packet(
punch_reply.public_ip_list = nat_info
.public_ips
.iter()
.map(|i| match i {
IpAddr::V4(ip) => u32::from_be_bytes(ip.octets()),
IpAddr::V6(_) => {
panic!()
}
})
.map(|ip| u32::from_be_bytes(ip.octets()))
.collect();
punch_reply.public_port = nat_info.public_port as u32;
punch_reply.public_port_range = nat_info.public_port_range as u32;
punch_reply.local_ip = match nat_info.local_ip {
IpAddr::V4(ip) => u32::from_be_bytes(ip.octets()),
IpAddr::V6(_) => {
panic!()
}
};
punch_reply.local_ip = u32::from_be_bytes(nat_info.local_ip.octets());
punch_reply.local_port = nat_info.local_port as u32;
punch_reply.nat_type = protobuf::EnumOrUnknown::new(PunchNatType::from(nat_info.nat_type));
let bytes = punch_reply.write_to_bytes()?;
let mut net_packet = NetPacket::new(vec![0u8; 12 + bytes.len()])?;
net_packet.set_version(Version::V1);
net_packet.set_protocol(Protocol::OtherTurn);
net_packet.set_transport_protocol(turn_packet::Protocol::Punch.into());
net_packet.set_transport_protocol(other_turn_packet::Protocol::Punch.into());
net_packet.first_set_ttl(MAX_TTL);
net_packet.set_source(virtual_ip);
net_packet.set_destination(dest);
+180 -214
View File
@@ -1,5 +1,4 @@
use std::thread;
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::sync::Arc;
use chrono::Local;
@@ -7,128 +6,100 @@ use crossbeam::atomic::AtomicCell;
use crossbeam_skiplist::SkipMap;
use parking_lot::Mutex;
use protobuf::Message;
use tokio::net::UdpSocket;
use tokio::sync::mpsc::Sender;
use p2p_channel::channel::{Channel, Route, RouteKey};
use p2p_channel::punch::NatInfo;
use packet::ethernet;
use packet::icmp::{icmp, Kind};
use packet::icmp::icmp::HeaderOther;
use packet::ip::ipv4;
use packet::ip::ipv4::packet::IpV4Packet;
use crate::channel::channel::Context;
use crate::channel::punch::{NatInfo, NatType};
use crate::channel::{Route, RouteKey};
use crate::error::Error;
use crate::external_route::ExternalRoute;
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, CurrentDeviceInfoExt, PeerDeviceInfo};
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo};
use crate::handle::registration_handler::Register;
use crate::igmp_server::IgmpServer;
use crate::ip_proxy::IpProxyMap;
use crate::nat;
use crate::nat::NatTest;
use crate::proto::message::{DeviceList, PunchInfo, PunchNatType, RegistrationResponse};
use crate::protocol::{control_packet, MAX_TTL, NetPacket, Protocol, service_packet, turn_packet, Version};
use crate::protocol::{control_packet, MAX_TTL, NetPacket, Protocol, service_packet, other_turn_packet, Version, ip_turn_packet};
use crate::protocol::control_packet::ControlPacket;
use crate::protocol::error_packet::InErrorPacket;
use crate::tap_device::TapWriter;
use crate::tun_device::TunWriter;
use crate::tun_tap_device::DeviceWriter;
pub fn start(mut handler: RecvHandler) {
thread::Builder::new().name("udp-recv-handler".into()).spawn(move || {
let mut buf = [0; 4096];
loop {
match handler.channel.recv_from(&mut buf, None) {
Ok((len, route)) => {
if let Err(e) = handler.handle(&mut buf[..len], &route) {
log::warn!("数据处理失败:{:?},e:{:?}",route,e);
if let Error::Stop(_) = e {
let _ = handler.channel.close();
break;
}
}
}
Err(e) => {
log::warn!("{:?}",e);
// 检查关闭状态
if handler.channel.is_close() {
break;
}
}
}
}
}).unwrap();
}
pub struct RecvHandler {
channel: Channel<Ipv4Addr>,
#[derive(Clone)]
pub struct ChannelDataHandler {
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
current_device_ext: Arc<AtomicCell<CurrentDeviceInfoExt>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
register: Arc<Register>,
nat_test: NatTest,
tun_writer: Option<TunWriter>,
tap_writer: Option<TapWriter>,
igmp_server: IgmpServer,
device_writer: DeviceWriter,
connect_status: Arc<AtomicCell<ConnectStatus>>,
peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>,
ip_proxy_map: IpProxyMap,
out_external_route: ExternalRoute,
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
}
impl RecvHandler {
pub fn new(channel: Channel<Ipv4Addr>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
current_device_ext: Arc<AtomicCell<CurrentDeviceInfoExt>>,
impl ChannelDataHandler {
pub fn new(current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
register: Arc<Register>,
nat_test: NatTest,
tun_writer: Option<TunWriter>,
tap_writer: Option<TapWriter>,
igmp_server: IgmpServer,
device_writer: DeviceWriter,
connect_status: Arc<AtomicCell<ConnectStatus>>,
peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>,
ip_proxy_map: IpProxyMap,
out_external_route: ExternalRoute,
) -> Self {
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>, ) -> Self {
Self {
channel,
current_device,
current_device_ext,
device_list,
register,
nat_test,
tun_writer,
tap_writer,
igmp_server,
device_writer,
connect_status,
peer_nat_info_map,
ip_proxy_map,
out_external_route,
cone_sender,
symmetric_sender,
}
}
// pub fn try_clone(&self) -> io::Result<Self> {
// Ok(Self {
// channel: self.channel.try_clone()?,
// current_device: self.current_device.clone(),
// device_list: self.device_list.clone(),
// register: self.register.clone(),
// nat_test: self.nat_test.clone(),
// tun_writer: self.tun_writer.clone(),
// tap_writer: self.tap_writer.clone(),
// connect_status: self.connect_status.clone(),
// peer_nat_info_map: self.peer_nat_info_map.clone(),
// })
// }
}
impl RecvHandler {
fn handle(&self, buf: &mut [u8], route_key: &RouteKey) -> crate::Result<()> {
let mut net_packet = NetPacket::new(buf)?;
impl ChannelDataHandler {
pub async fn handle(&mut self, buf: &mut [u8], start: usize, end: usize, route_key: RouteKey, _udp: &Arc<UdpSocket>,
context: &Context, ) {
assert_eq!(start, 14);
match self.handle0(&mut buf[..end], &route_key, context).await {
Ok(_) => {}
Err(e) => {
log::error!("{:?}",e);
}
}
}
async fn handle0(&self, buf: &mut [u8], route_key: &RouteKey, context: &Context) -> crate::Result<()> {
let mut net_packet = NetPacket::new(&mut buf[14..])?;
if net_packet.ttl() == 0 {
return Ok(());
}
let source = net_packet.source();
let current_device = self.current_device.load();
if source == current_device.virtual_ip() {
return Ok(());
}
let destination = net_packet.destination();
if !destination.is_broadcast() && destination != current_device.broadcast_address
&& current_device.virtual_ip() != destination && self.connect_status.load() == ConnectStatus::Connected {
if current_device.virtual_ip() != destination
&& !destination.is_broadcast() && !destination.is_multicast() && destination != current_device.broadcast_address
&& 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);
return Ok(());
@@ -141,111 +112,118 @@ impl RecvHandler {
let ttl = net_packet.ttl();
if ttl > 0 {
// 转发
if let Some(route) = self.channel.route(&destination) {
if let Some(route) = context.route_one(&destination) {
if route.metric <= net_packet.ttl() {
self.channel.send_to_route(net_packet.buffer(), &route.route_key())?;
context.send_by_key(net_packet.buffer(), &route.route_key()).await?;
}
} else if (ttl > 1 || destination == current_device.virtual_gateway())
&& source != current_device.virtual_gateway() {
//网关默认要转发一次,生存时间不够的发到网关也会被丢弃
self.channel.send_to_addr(net_packet.buffer(), current_device.connect_server)?;
context.send_main(net_packet.buffer(), current_device.connect_server).await?;
}
}
return Ok(());
}
match net_packet.protocol() {
Protocol::Ipv4Turn => {
let mut ipv4 = IpV4Packet::new(net_packet.payload_mut())?;
if ipv4.destination_ip() == destination && ipv4.protocol() == ipv4::protocol::Protocol::Icmp {
let mut icmp_packet = icmp::IcmpPacket::new(ipv4.payload_mut())?;
if icmp_packet.kind() == Kind::EchoRequest {
//开启ping
icmp_packet.set_kind(Kind::EchoReply);
icmp_packet.update_checksum();
ipv4.set_source_ip(destination);
ipv4.set_destination_ip(source);
ipv4.update_checksum();
net_packet.set_source(destination);
net_packet.set_destination(source);
self.channel.send_to_route(net_packet.buffer(), route_key)?;
return Ok(());
}
}
if ipv4.destination_ip() != destination {
if let Some(gate_way) = self.out_external_route.route(&ipv4.destination_ip()) {
Protocol::IpTurn => {
match ip_turn_packet::Protocol::from(net_packet.transport_protocol()) {
ip_turn_packet::Protocol::Ipv4 => {
let mut ipv4 = IpV4Packet::new(net_packet.payload_mut())?;
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();
println!("{:?}",ipv4);
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::Igmp => {
self.igmp_server.handle(ipv4.payload(), source)?;
return Ok(());
}
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)?;
}
_ => {
if ipv4.destination_ip() == destination {
let mut icmp_packet = icmp::IcmpPacket::new(ipv4.payload_mut())?;
if icmp_packet.kind() == Kind::EchoRequest {
//开启ping
icmp_packet.set_kind(Kind::EchoReply);
icmp_packet.update_checksum();
ipv4.set_source_ip(destination);
ipv4.set_destination_ip(source);
ipv4.update_checksum();
net_packet.set_source(destination);
net_packet.set_destination(source);
context.send_by_key(net_packet.buffer(), route_key).await?;
return Ok(());
}
}
}
_ => {
return Ok(());
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(());
}
}
}
_ => {
return Ok(());
}
}
}
}
}
}
//传输协议12字节
self.device_writer.write_ipv4(&mut buf[12..])?;
return Ok(());
}
}
if let Some(tun_writer) = &self.tun_writer {
tun_writer.write(net_packet.payload())?;
} else {
if let Some(tap_writer) = &self.tap_writer {
let mut ethernet_packet = ethernet::packet::EthernetPacket::unchecked(vec![0; 14 + ipv4.buffer.len()]);
let source = source.octets();
ethernet_packet.set_source(&[source[0], source[1], source[2], source[3], 123, 234]);
ethernet_packet.set_destination(&self.current_device_ext.load().mac);
ethernet_packet.set_protocol(ethernet::protocol::Protocol::Ipv4);
ethernet_packet.payload_mut().copy_from_slice(ipv4.buffer);
tap_writer.write(&ethernet_packet.buffer)?;
ip_turn_packet::Protocol::Ipv4Broadcast => {
//客户端不帮忙转发广播包,所以不会出现这种类型的数据
}
ip_turn_packet::Protocol::Unknown(_) => {}
}
}
Protocol::Service => {
self.service(current_device, source, net_packet, route_key)?;
self.service(context, current_device, source, net_packet, route_key).await?;
}
Protocol::Error => {
self.error(current_device, source, net_packet, route_key)?;
self.error(context, current_device, source, net_packet, route_key).await?;
}
Protocol::Control => {
self.control(current_device, source, net_packet, route_key)?;
self.control(context, current_device, source, net_packet, route_key).await?;
}
Protocol::OtherTurn => {
self.other_turn(current_device, source, net_packet, route_key)?;
self.other_turn(context, current_device, source, net_packet, route_key).await?;
}
Protocol::UnKnow(e) => {
log::info!("不支持的协议:{}",e);
@@ -253,18 +231,20 @@ impl RecvHandler {
}
Ok(())
}
fn service(&self, current_device: CurrentDeviceInfo, source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
if route_key.addr != current_device.connect_server || source != current_device.virtual_gateway() {
async fn service(&self, context: &Context, current_device: CurrentDeviceInfo, _source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
//todo 校验来源
if route_key.addr != current_device.connect_server {
return Ok(());
}
match service_packet::Protocol::from(net_packet.transport_protocol()) {
service_packet::Protocol::RegistrationRequest => {}
service_packet::Protocol::RegistrationResponse => {
let response = RegistrationResponse::parse_from_bytes(net_packet.payload())?;
let local_port = self.channel.local_addr()?.port();
let local_port = context.main_local_port()?;
let local_ip = nat::local_ip()?;
let nat_info = self.nat_test.re_test(Ipv4Addr::from(response.public_ip), response.public_port as u16, local_ip, local_port);
self.channel.set_nat_type(nat_info.nat_type)?;
let nat_info = self.nat_test.re_test(Ipv4Addr::from(response.public_ip),
response.public_port as u16, local_ip, local_port);
context.switch(nat_info.nat_type);
let new_ip = Ipv4Addr::from(response.virtual_ip);
let current_ip = current_device.virtual_ip();
if current_ip != new_ip {
@@ -275,13 +255,7 @@ impl RecvHandler {
let virtual_ip = Ipv4Addr::from(response.virtual_ip);
let virtual_gateway = Ipv4Addr::from(response.virtual_gateway);
let virtual_netmask = Ipv4Addr::from(response.virtual_netmask);
if let Some(tun_writer) = &self.tun_writer {
tun_writer.change_ip(virtual_ip, virtual_netmask, virtual_gateway, old_netmask, old_gateway)?;
} else {
if let Some(tap_writer) = &self.tap_writer {
tap_writer.change_ip(virtual_ip, virtual_netmask, virtual_gateway, old_netmask, old_gateway)?;
}
}
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);
if let Err(e) = self.current_device.compare_exchange(current_device, new_current_device) {
@@ -310,14 +284,14 @@ impl RecvHandler {
dev.1 = ip_list;
}
}
service_packet::Protocol::UnKnow(u) => {
service_packet::Protocol::Unknown(u) => {
log::warn!("未知服务协议:{}",u);
}
}
Ok(())
}
fn error(&self, current_device: CurrentDeviceInfo, source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
if route_key.addr != current_device.connect_server || source != current_device.virtual_gateway() {
async fn error(&self, _context: &Context, current_device: CurrentDeviceInfo, _source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
if route_key.addr != current_device.connect_server {
return Ok(());
}
match InErrorPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
@@ -325,8 +299,14 @@ impl RecvHandler {
return Err(Error::Stop("Token error".to_string()));
}
InErrorPacket::Disconnect => {
{
//掉线epoch要归零
let mut dev = self.device_list.lock();
dev.0 = 0;
}
self.connect_status.store(ConnectStatus::Connecting);
self.register.fast_register()?;
self.register.fast_register().await?;
}
InErrorPacket::AddressExhausted => {
//地址用尽
@@ -338,42 +318,28 @@ impl RecvHandler {
}
Ok(())
}
fn control(&self, current_device: CurrentDeviceInfo, source: Ipv4Addr, mut net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
async fn control(&self, context: &Context, current_device: CurrentDeviceInfo, source: Ipv4Addr, mut net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
let metric = net_packet.source_ttl() - net_packet.ttl() + 1;
match ControlPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
ControlPacket::PingPacket(_) => {
let metric = net_packet.source_ttl() - net_packet.ttl() + 1;
context.update_read_time(&source, route_key);
net_packet.set_transport_protocol(control_packet::Protocol::Pong.into());
net_packet.set_source(current_device.virtual_ip());
net_packet.set_destination(source);
net_packet.first_set_ttl(MAX_TTL);
self.channel.send_to_route(net_packet.buffer(), route_key)?;
if metric == 1 {
if let Some(current_route) = self.channel.route(&source) {
if current_route.metric > 1 {
let route = Route::from(*route_key, 1, -1);
self.channel.add_route(source, route);
}
}
}
context.send_by_key(net_packet.buffer(), route_key).await?;
let route = Route::from(*route_key, metric, 99);
context.add_route_if_absent(source, route);
}
ControlPacket::PongPacket(pong_packet) => {
context.update_read_time(&source, route_key);
let current_time = Local::now().timestamp_millis() as u16;
if current_time < pong_packet.time() {
return Ok(());
}
let rt = (current_time - pong_packet.time()) as i64;
let metric = net_packet.source_ttl() - net_packet.ttl() + 1;
if let Some(current_route) = self.channel.route(&source) {
if &current_route.route_key() == route_key {
self.channel.update_route(&source, metric, rt);
} else if current_route.metric >= metric && current_route.rt > rt {
let route = Route::from(*route_key, metric, rt);
self.channel.add_route(source, route);
}
} else {
let route = Route::from(*route_key, metric, rt);
self.channel.add_route(source, route);
}
let route = Route::from(*route_key, metric, rt);
context.add_route(source, route);
if route_key.addr == current_device.connect_server && source == current_device.virtual_gateway() {
let epoch = self.device_list.lock().0;
if pong_packet.epoch() != epoch {
@@ -384,7 +350,7 @@ impl RecvHandler {
poll_device.first_set_ttl(MAX_TTL);
poll_device.set_protocol(Protocol::Service);
poll_device.set_transport_protocol(service_packet::Protocol::PollDeviceList.into());
self.channel.send_to_route(poll_device.buffer(), route_key)?;
context.send_by_key(poll_device.buffer(), route_key).await?;
}
}
}
@@ -395,28 +361,28 @@ impl RecvHandler {
net_packet.set_source(current_device.virtual_ip());
net_packet.set_destination(source);
net_packet.first_set_ttl(1);
self.channel.send_to_route(net_packet.buffer(), route_key)?;
let route = Route::from(*route_key, 1, -1);
self.channel.add_route(source, route);
context.send_by_key(net_packet.buffer(), route_key).await?;
let route = Route::from(*route_key, metric, 99);
context.add_route_if_absent(source, route);
}
ControlPacket::PunchResponse => {
// log::info!("PunchResponse route_key:{:?}",route_key);
let route = Route::from(*route_key, 1, -1);
self.channel.add_route(net_packet.source(), route);
let route = Route::from(*route_key, metric, 99);
context.add_route_if_absent(source, route);
}
}
Ok(())
}
fn other_turn(&self, current_device: CurrentDeviceInfo, source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
match turn_packet::Protocol::from(net_packet.transport_protocol()) {
turn_packet::Protocol::Punch => {
async fn other_turn(&self, context: &Context, current_device: CurrentDeviceInfo, source: Ipv4Addr, net_packet: NetPacket<&mut [u8]>, route_key: &RouteKey) -> crate::Result<()> {
match other_turn_packet::Protocol::from(net_packet.transport_protocol()) {
other_turn_packet::Protocol::Punch => {
let punch_info = PunchInfo::parse_from_bytes(net_packet.payload())?;
let public_ips = punch_info.public_ip_list.
iter().map(|v| { IpAddr::from(v.to_be_bytes()) }).collect();
iter().map(|v| { Ipv4Addr::from(v.to_be_bytes()) }).collect();
let peer_nat_info = NatInfo::new(public_ips,
punch_info.public_port as u16,
punch_info.public_port_range as u16,
IpAddr::from(punch_info.local_ip.to_be_bytes()),
Ipv4Addr::from(punch_info.local_ip.to_be_bytes()),
punch_info.local_port as u16,
punch_info.nat_type.enum_value_or_default().into());
self.peer_nat_info_map.insert(source, peer_nat_info.clone());
@@ -424,20 +390,12 @@ impl RecvHandler {
let mut punch_reply = PunchInfo::new();
punch_reply.reply = true;
let nat_info = self.nat_test.nat_info();
punch_reply.public_ip_list = nat_info.public_ips.iter().map(|i| {
match i {
IpAddr::V4(ip) => u32::from_be_bytes(ip.octets()),
IpAddr::V6(_) => 0
}
}).collect();
punch_reply.public_ip_list = nat_info.public_ips.iter().map(|ip| u32::from_be_bytes(ip.octets())).collect();
punch_reply.public_port = nat_info.public_port as u32;
punch_reply.public_port_range = nat_info.public_port_range as u32;
punch_reply.nat_type =
protobuf::EnumOrUnknown::new(PunchNatType::from(nat_info.nat_type));
punch_reply.local_ip = match nat_info.local_ip {
IpAddr::V4(ip) => u32::from_be_bytes(ip.octets()),
IpAddr::V6(_) => 0
};
punch_reply.local_ip = u32::from_be_bytes(nat_info.local_ip.octets());
punch_reply.local_port = nat_info.local_port as u32;
let bytes = punch_reply.write_to_bytes()?;
let mut net_packet =
@@ -445,7 +403,7 @@ impl RecvHandler {
net_packet.set_version(Version::V1);
net_packet.set_protocol(Protocol::OtherTurn);
net_packet.set_transport_protocol(
turn_packet::Protocol::Punch.into(),
other_turn_packet::Protocol::Punch.into(),
);
net_packet.first_set_ttl(MAX_TTL);
net_packet.set_source(current_device.virtual_ip());
@@ -459,21 +417,29 @@ impl RecvHandler {
packet.set_transport_protocol(control_packet::Protocol::PunchRequest.into());
packet.set_source(current_device.virtual_ip());
packet.set_destination(source);
let _ = self.channel.send_to_addr(packet.buffer(), SocketAddr::new(peer_nat_info.local_ip, peer_nat_info.local_port));
let _ = context.send_main(packet.buffer(), SocketAddr::V4(SocketAddrV4::new(peer_nat_info.local_ip, peer_nat_info.local_port))).await;
}
if let Err(e) = self.channel.punch(source, peer_nat_info) {
log::warn!("发送到打洞通道失败 {:?}",e);
return Ok(());
if self.punch(source, peer_nat_info).await {
context.send_by_key(net_packet.buffer(), route_key).await?;
}
self.channel.send_to_route(net_packet.buffer(), route_key)?;
} else {
let _ = self.channel.punch(source, peer_nat_info);
self.punch(source, peer_nat_info).await;
}
}
turn_packet::Protocol::UnKnow(e) => {
other_turn_packet::Protocol::Unknown(e) => {
log::warn!("不支持的转发协议 {:?},source:{:?}",e,source);
}
}
Ok(())
}
async fn punch(&self, peer_ip: Ipv4Addr, peer_nat_info: NatInfo) -> bool {
match peer_nat_info.nat_type {
NatType::Symmetric => {
self.symmetric_sender.try_send((peer_ip, peer_nat_info)).is_ok()
}
NatType::Cone => {
self.cone_sender.try_send((peer_ip, peer_nat_info)).is_ok()
}
}
}
}
+58 -49
View File
@@ -1,12 +1,12 @@
use std::io;
use std::net::{Ipv4Addr, SocketAddr};
use std::net::SocketAddr;
use std::sync::atomic::{AtomicI64, Ordering};
use std::time::Duration;
use chrono::Local;
use p2p_channel::channel::sender::Sender;
use p2p_channel::channel::Channel;
use protobuf::Message;
use tokio::net::UdpSocket;
use crate::channel::sender::ChannelSender;
use crate::error::*;
use crate::proto::message::{RegistrationRequest, RegistrationResponse};
@@ -14,8 +14,8 @@ use crate::protocol::error_packet::InErrorPacket;
use crate::protocol::{service_packet, NetPacket, Protocol, Version, MAX_TTL};
///向中继服务器注册,token标识一个虚拟网关,device_id防止多次注册时得到的ip不一致
pub fn registration(
channel: &mut Channel<Ipv4Addr>,
pub async fn registration(
main_channel: &UdpSocket,
server_address: SocketAddr,
token: String,
device_id: String,
@@ -26,52 +26,60 @@ pub fn registration(
let buf = request_packet.buffer();
let mut recv_buf = [0u8; 10240];
let mut count = 0;
let len = loop {
match channel.send_to_addr(buf, server_address) {
loop {
match main_channel.send_to(buf, server_address).await {
Ok(_) => {
match channel.recv_from(&mut recv_buf, Some(Duration::from_millis(300))) {
Ok((len, route)) => {
if server_address == route.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);
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);
}
_ => println!("响应数据错误"),
}
}
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!("断开连接");
}
InErrorPacket::AddressExhausted => {
println!("地址用尽");
log::warn!("地址用尽");
}
InErrorPacket::OtherError(e) => match e.message() {
Ok(str) => {
println!("其他异常:{:?}", str);
log::warn!("其他异常{:?}",str);
}
Err(e) => println!("其他异常:{:?}", e),
},
},
Err(e) => println!("数据解析异常:{:?}", e),
}
}
_ => println!("响应数据错误"),
}
};
}
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!("断开连接");
}
InErrorPacket::AddressExhausted => {
println!("地址用尽");
log::warn!("地址用尽");
}
InErrorPacket::OtherError(e) => match e.message() {
Ok(str) => {
println!("其他异常:{:?}", str);
log::warn!("其他异常{:?}",str);
}
Err(e) => println!("其他异常:{:?}", e),
},
},
Err(e) => println!("数据解析异常:{:?}", e),
}
}
_ => println!("响应数据错误"),
};
}
Err(e) => {
println!("接收服务器数据失败:{:?}", e);
log::warn!("接收服务器数据失败:{:?}",e);
}
}
}
Err(e) => {
println!("接收服务器数据失败:{:?}", e);
log::warn!("接收服务器数据失败:{:?}",e);
Err(_) => {
println!("接收超时");
log::warn!("接收超时");
}
}
}
@@ -97,6 +105,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();
let bytes = request.write_to_bytes()?;
let buf = vec![0u8; 12 + bytes.len()];
let mut net_packet = NetPacket::new(buf)?;
@@ -109,7 +118,7 @@ fn registration_request_packet(
}
pub struct Register {
sender: Sender<Ipv4Addr>,
sender: ChannelSender,
server_address: SocketAddr,
token: String,
device_id: String,
@@ -119,7 +128,7 @@ pub struct Register {
impl Register {
pub fn new(
sender: Sender<Ipv4Addr>,
sender: ChannelSender,
server_address: SocketAddr,
token: String,
device_id: String,
@@ -134,7 +143,7 @@ impl Register {
time: AtomicI64::new(0),
}
}
pub fn fast_register(&self) -> io::Result<()> {
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
@@ -155,7 +164,7 @@ impl Register {
)
.unwrap();
let buf = request_packet.buffer();
self.sender.send_to_addr(buf, self.server_address)?;
self.sender.send_main(buf, self.server_address).await?;
Ok(())
}
}
-163
View File
@@ -1,163 +0,0 @@
use std::net::{Ipv4Addr, SocketAddrV4};
use std::sync::Arc;
use std::{io, thread};
use crossbeam::atomic::AtomicCell;
use p2p_channel::channel::sender::Sender;
use packet::arp::arp::ArpPacket;
use packet::ethernet;
use packet::ethernet::packet::EthernetPacket;
use packet::icmp::icmp::IcmpPacket;
use packet::icmp::Kind;
use packet::ip::ipv4;
use packet::ip::ipv4::packet::IpV4Packet;
use crate::external_route::ExternalRoute;
use crate::handle::{check_dest, CurrentDeviceInfo};
use crate::ip_proxy::IpProxyMap;
use crate::protocol::{MAX_TTL, NetPacket, Protocol, Version};
use crate::tap_device::{TapReader, TapWriter};
pub fn start(sender: Sender<Ipv4Addr>,
tap_reader: TapReader,
tap_writer: TapWriter,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap) {
thread::Builder::new().name("tap-handler".into()).spawn(move || {
if let Err(e) = start_(sender, tap_reader, tap_writer, current_device,ip_route,ip_proxy_map) {
log::warn!("{:?}",e);
}
}).unwrap();
}
fn start_(sender: Sender<Ipv4Addr>,
tap_reader: TapReader,
tap_writer: TapWriter,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap) -> io::Result<()> {
let mut net_packet = NetPacket::new(vec![0u8; 4 + 8 + 1500]).unwrap();
net_packet.set_version(Version::V1);
net_packet.set_protocol(Protocol::Ipv4Turn);
net_packet.set_transport_protocol(ipv4::protocol::Protocol::Ipv4.into());
net_packet.set_ttl(MAX_TTL);
let mut buf = [0; 2048];
loop {
let len = tap_reader.read(&mut buf)?;
if len == 0 {
continue;
}
let mut ethernet_packet = EthernetPacket::unchecked(&mut buf[..len]);
if let Err(e) = handle(&mut net_packet, &current_device, &tap_writer, &mut ethernet_packet, &sender,&ip_route,&ip_proxy_map) {
log::error!("tap handle{:?}",e);
}
}
}
fn handle(net_packet: &mut NetPacket<Vec<u8>>, current_device: &AtomicCell<CurrentDeviceInfo>, tap_writer: &TapWriter, ethernet_packet: &mut EthernetPacket<&mut [u8]>, sender: &Sender<Ipv4Addr>, ip_route: &ExternalRoute, proxy_map: &IpProxyMap) -> crate::Result<()> {
let current_device = current_device.load();
match ethernet_packet.protocol() {
ethernet::protocol::Protocol::Arp => {
let mut out_ethernet_packet = EthernetPacket::unchecked(ethernet_packet.buffer.to_vec());
let arp_packet = ArpPacket::unchecked(ethernet_packet.payload());
let mut out_arp_packet = ArpPacket::unchecked(out_ethernet_packet.payload_mut());
let sender_h = arp_packet.sender_hardware_addr();
let sender_p = arp_packet.sender_protocol_addr();
let target_p = arp_packet.target_protocol_addr();
if target_p == &[0, 0, 0, 0] || sender_p == &[0, 0, 0, 0] || target_p == sender_p {
return Ok(());
}
//回复一个虚假的MAC地址
out_arp_packet.set_sender_hardware_addr(&[target_p[0], target_p[1], target_p[2], target_p[3], 123, 234]);
out_arp_packet.set_sender_protocol_addr(target_p);
out_arp_packet.set_target_hardware_addr(sender_h);
out_arp_packet.set_target_protocol_addr(sender_p);
out_arp_packet.set_op_code(2);
out_ethernet_packet.set_source(&[target_p[0], target_p[1], target_p[2], target_p[3], 123, 234]);
out_ethernet_packet.set_destination(sender_h);
tap_writer.write(&out_ethernet_packet.buffer)?;
}
ethernet::protocol::Protocol::Ipv4 => {
// println!("in ethernet_packet {:?}", ethernet_packet);
let mut ipv4_packet = IpV4Packet::unchecked(ethernet_packet.payload_mut());
let src_ip = ipv4_packet.source_ip();
let mut dest_ip = ipv4_packet.destination_ip();
if src_ip != current_device.virtual_ip() {
return Ok(());
}
if !check_dest(dest_ip, current_device.virtual_netmask, current_device.virtual_network) && !dest_ip.is_broadcast() {
if let Some(r_dest_ip) = ip_route.route(&dest_ip) {
//路由的目标不能是自己
if r_dest_ip == src_ip {
return Ok(());
}
dest_ip = r_dest_ip;
} else {
return Ok(());
}
}else{
match ipv4_packet.protocol() {
ipv4::protocol::Protocol::Tcp => {
let dest_addr = {
let tcp_packet = packet::tcp::tcp::TcpPacket::new(src_ip, dest_ip, ipv4_packet.payload())?;
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 = packet::tcp::tcp::TcpPacket::new(source_ip, dest_ip, ipv4_packet.payload_mut())?;
tcp_packet.set_source_port(source_addr.port());
tcp_packet.update_checksum();
ipv4_packet.set_source_ip(source_ip);
ipv4_packet.update_checksum();
}
}
ipv4::protocol::Protocol::Udp => {
let dest_addr = {
let udp_packet = packet::udp::udp::UdpPacket::new(src_ip, dest_ip, ipv4_packet.payload())?;
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 = packet::udp::udp::UdpPacket::new(src_ip, dest_ip, ipv4_packet.payload_mut())?;
udp_packet.set_source_port(source_addr.port());
udp_packet.update_checksum();
ipv4_packet.set_source_ip(source_ip);
ipv4_packet.update_checksum();
}
}
_ => {}
}
}
if src_ip == dest_ip {
if ipv4_packet.protocol() == ipv4::protocol::Protocol::Icmp {
let mut icmp = IcmpPacket::unchecked(ipv4_packet.payload_mut());
if icmp.kind() == Kind::EchoRequest {
icmp.set_kind(Kind::EchoReply);
icmp.update_checksum();
let src = ipv4_packet.source_ip();
ipv4_packet.set_source_ip(ipv4_packet.destination_ip());
ipv4_packet.set_destination_ip(src);
ipv4_packet.update_checksum();
tap_writer.write(ethernet_packet.buffer)?;
return Ok(());
}
}
}
net_packet.set_source(src_ip);
net_packet.set_destination(dest_ip);
let data_len = ipv4_packet.buffer.len();
net_packet.set_payload(ipv4_packet.buffer);
//优先发到直连到地址
if sender.send_to_id(&net_packet.buffer()[..(12 + data_len)], &dest_ip).is_err() {
sender.send_to_addr(&net_packet.buffer()[..(12 + data_len)], current_device.connect_server)?;
}
}
_ => {
// log::warn!("不支持的二层协议:{:?}",p)
}
}
Ok(())
}
-175
View File
@@ -1,175 +0,0 @@
use std::{io, thread};
use std::net::{Ipv4Addr, SocketAddrV4};
use std::sync::Arc;
use crossbeam::atomic::AtomicCell;
use p2p_channel::channel::sender::Sender;
use packet::icmp:: Kind;
use packet::icmp::icmp:: IcmpPacket;
use packet::ip::ipv4;
use packet::ip::ipv4::packet::IpV4Packet;
use crate::error::*;
use crate::external_route::ExternalRoute;
use crate::handle::{check_dest, CurrentDeviceInfo};
use crate::ip_proxy::IpProxyMap;
use crate::protocol::{MAX_TTL, NetPacket, Protocol, Version};
use crate::tun_device::{TunReader, TunWriter};
fn icmp(tun_writer: &TunWriter, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> Result<()> {
if ipv4_packet.protocol() == ipv4::protocol::Protocol::Icmp {
let mut icmp = IcmpPacket::new(ipv4_packet.payload_mut())?;
if icmp.kind() == Kind::EchoRequest {
icmp.set_kind(Kind::EchoReply);
icmp.update_checksum();
let src = ipv4_packet.source_ip();
ipv4_packet.set_source_ip(ipv4_packet.destination_ip());
ipv4_packet.set_destination_ip(src);
ipv4_packet.update_checksum();
tun_writer.write(ipv4_packet.buffer)?;
}
}
Ok(())
}
/// 接收tun数据,并且转发到udp上
#[inline]
fn handle(sender: &Sender<Ipv4Addr>, data: &mut [u8], tun_writer: &TunWriter, current_device: CurrentDeviceInfo, net_packet: &mut NetPacket<[u8; 1512]>, ip_route: &ExternalRoute, proxy_map: &IpProxyMap) -> Result<()> {
let data_len = data.len();
let mut ipv4_packet = match IpV4Packet::new(data) {
Ok(ipv4_packet) => ipv4_packet,
Err(packet::error::Error::Unimplemented) => {
return Ok(());
}
Err(e) => Err(e)?,
};
let src_ip = ipv4_packet.source_ip();
let mut dest_ip = ipv4_packet.destination_ip();
// if dest_ip == cur_info.broadcast_address {
// // 启动服务后会收到对137端口的广播
// // 137端口是在局域网中提供计算机的名字或IP地址查询服务
// return Ok(());
// }
if src_ip != current_device.virtual_ip() {
return Ok(());
}
if src_ip == dest_ip {
return icmp(&tun_writer, ipv4_packet);
}
if !check_dest(dest_ip, current_device.virtual_netmask, current_device.virtual_network) && !dest_ip.is_broadcast() {
// println!("非目标 {:?}",ipv4_packet);
if let Some(r_dest_ip) = ip_route.route(&dest_ip) {
//路由的目标不能是自己
if r_dest_ip == src_ip {
return Ok(());
}
dest_ip = r_dest_ip;
} else {
return Ok(());
}
} else {
match ipv4_packet.protocol() {
ipv4::protocol::Protocol::Tcp => {
let dest_addr = {
let tcp_packet = packet::tcp::tcp::TcpPacket::new(src_ip, dest_ip, ipv4_packet.payload())?;
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 = packet::tcp::tcp::TcpPacket::new(source_ip, dest_ip, ipv4_packet.payload_mut())?;
tcp_packet.set_source_port(source_addr.port());
tcp_packet.update_checksum();
ipv4_packet.set_source_ip(source_ip);
ipv4_packet.update_checksum();
}
}
ipv4::protocol::Protocol::Udp => {
let dest_addr = {
let udp_packet = packet::udp::udp::UdpPacket::new(src_ip, dest_ip, ipv4_packet.payload())?;
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 = packet::udp::udp::UdpPacket::new(source_ip, dest_ip, ipv4_packet.payload_mut())?;
udp_packet.set_source_port(source_addr.port());
udp_packet.update_checksum();
ipv4_packet.set_source_ip(source_ip);
ipv4_packet.update_checksum();
}
}
_ => {}
}
}
net_packet.set_source(src_ip);
net_packet.set_destination(dest_ip);
net_packet.set_payload(ipv4_packet.buffer);
//优先发到直连到地址
if sender.send_to_id(&net_packet.buffer()[..(12 + data_len)], &dest_ip).is_err() {
sender.send_to_addr(&net_packet.buffer()[..(12 + data_len)], current_device.connect_server)?;
}
return Ok(());
}
pub fn start(sender: Sender<Ipv4Addr>,
tun_reader: TunReader,
tun_writer: TunWriter,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap) {
thread::Builder::new().name("tun-handler".into()).spawn(move || {
if let Err(e) = start_(sender, tun_reader, tun_writer, current_device, ip_route, ip_proxy_map) {
log::warn!("{:?}",e);
}
}).unwrap();
}
#[cfg(target_os = "windows")]
fn start_(sender: Sender<Ipv4Addr>,
tun_reader: TunReader,
tun_writer: TunWriter,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap) -> io::Result<()> {
let mut net_packet = NetPacket::new([0u8; 4 + 8 + 1500])?;
net_packet.set_version(Version::V1);
net_packet.set_protocol(Protocol::Ipv4Turn);
net_packet.set_transport_protocol(ipv4::protocol::Protocol::Ipv4.into());
net_packet.set_ttl(MAX_TTL);
loop {
let mut data = tun_reader.next()?;
match handle(&sender, data.bytes_mut(), &tun_writer, current_device.load(), &mut net_packet, &ip_route, &ip_proxy_map) {
Ok(_) => {}
Err(e) => {
log::warn!("{:?}", e)
}
}
}
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
fn start_(sender: Sender<Ipv4Addr>,
tun_reader: TunReader,
tun_writer: TunWriter,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: ExternalRoute,
ip_proxy_map: IpProxyMap) -> io::Result<()> {
let mut net_packet = NetPacket::new([0u8; 4 + 8 + 1500])?;
net_packet.set_version(Version::V1);
net_packet.set_protocol(Protocol::Ipv4Turn);
net_packet.set_transport_protocol(ipv4::protocol::Protocol::Ipv4.into());
net_packet.set_ttl(MAX_TTL);
let mut buf = [0; 4096];
loop {
let len = tun_reader.read(&mut buf)?;
match handle(&sender, &mut buf[..len], &tun_writer, current_device.load(), &mut net_packet, &ip_route, &ip_proxy_map) {
Ok(_) => {}
Err(e) => {
log::warn!("{:?}", e)
}
}
}
}