支持点对网
This commit is contained in:
+32
-15
@@ -1,15 +1,19 @@
|
||||
use std::io;
|
||||
use std::net::{Ipv4Addr, SocketAddr};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
use crossbeam_skiplist::SkipMap;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use p2p_channel::boot::Boot;
|
||||
use p2p_channel::channel::{Channel, Route, RouteKey};
|
||||
use p2p_channel::punch::NatInfo;
|
||||
use crate::handle::{ConnectStatus, CurrentDeviceInfo, heartbeat_handler, PeerDeviceInfo, punch_handler, recv_handler, registration_handler, tap_handler, tun_handler};
|
||||
use crate::nat::NatTest;
|
||||
|
||||
use crate::{tap_device, tun_device};
|
||||
use crate::external_route::ExternalRoute;
|
||||
use crate::handle::{ConnectStatus, CurrentDeviceInfo, CurrentDeviceInfoExt, heartbeat_handler, PeerDeviceInfo, punch_handler, recv_handler, registration_handler, tap_handler, tun_handler};
|
||||
use crate::nat::NatTest;
|
||||
use crate::tap_device::TapWriter;
|
||||
use crate::tun_device::TunWriter;
|
||||
|
||||
@@ -29,8 +33,9 @@ pub struct Switch {
|
||||
}
|
||||
|
||||
impl Switch {
|
||||
pub fn start(config: Config) -> crate::Result<Switch> {
|
||||
pub async fn start(config: Config) -> crate::Result<Switch> {
|
||||
log::info!("config:{:?}",config);
|
||||
|
||||
let (mut channel, punch, idle) = Boot::new::<Ipv4Addr>(80, 15000, 0)?;
|
||||
let response = registration_handler::registration(&mut channel, config.server_address, config.token.clone(), config.device_id.clone(), config.name.clone())?;
|
||||
let register = Arc::new(registration_handler::Register::new(channel.sender()?, config.server_address, config.token.clone(), config.device_id.clone(), config.name.clone()));
|
||||
@@ -45,18 +50,24 @@ impl Switch {
|
||||
let local_port = channel.local_addr()?.port();
|
||||
// NAT检测
|
||||
let nat_test = NatTest::new(config.nat_test_server.clone(), Ipv4Addr::from(response.public_ip), response.public_port as u16, local_ip, local_port);
|
||||
let (current_device, tun_writer, tap_writer) = if config.tap {
|
||||
let in_ips = config.in_ips.iter().map(|(dest, mask, _)| { (Ipv4Addr::from(*dest), Ipv4Addr::from(*mask)) }).collect::<Vec<(Ipv4Addr, Ipv4Addr)>>();
|
||||
|
||||
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 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()?,out_ips,current_device.clone()).await?;
|
||||
let ( current_device_ext,tun_writer, tap_writer) = if config.tap {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
//删除switch的tun网卡避免ip冲突,因为非正常退出会保留网卡
|
||||
tun_device::delete_tun();
|
||||
}
|
||||
let (tap_writer, tap_reader, mac) = tap_device::create_tap(virtual_ip, virtual_netmask, virtual_gateway)?;
|
||||
let current_device = Arc::new(AtomicCell::new(CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask,
|
||||
config.server_address, mac)));
|
||||
let current_device_ext = Arc::new(AtomicCell::new(CurrentDeviceInfoExt::new( mac)));
|
||||
//tap数据处理
|
||||
tap_handler::start(channel.sender()?, tap_reader.clone(), tap_writer.clone(), current_device.clone());
|
||||
(current_device, None, Some(tap_writer))
|
||||
tap_handler::start(channel.sender()?, tap_reader.clone(), tap_writer.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone());
|
||||
(current_device_ext, None, Some(tap_writer))
|
||||
} else {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
@@ -64,15 +75,16 @@ impl Switch {
|
||||
tap_device::delete_tap();
|
||||
}
|
||||
// tun通道
|
||||
let (tun_writer, tun_reader) = tun_device::create_tun(virtual_ip, virtual_netmask, virtual_gateway)?;
|
||||
let current_device = Arc::new(AtomicCell::new(CurrentDeviceInfo::new(virtual_ip, virtual_gateway, virtual_netmask, config.server_address, [0, 0, 0, 0, 0, 0])));
|
||||
let (tun_writer, tun_reader) = tun_device::create_tun(virtual_ip, virtual_netmask, virtual_gateway,in_ips)?;
|
||||
let current_device_ext = Arc::new(AtomicCell::new(CurrentDeviceInfoExt::new( [0, 0, 0, 0, 0, 0])));
|
||||
//tun数据接收处理
|
||||
tun_handler::start(channel.sender()?, tun_reader.clone(), tun_writer.clone(), current_device.clone());
|
||||
(current_device, Some(tun_writer), None)
|
||||
tun_handler::start(channel.sender()?, tun_reader.clone(), tun_writer.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone());
|
||||
(current_device_ext,Some(tun_writer), None)
|
||||
};
|
||||
//外部数据接收处理
|
||||
let channel_recv_handler = recv_handler::RecvHandler::new(channel.try_clone()?, current_device.clone(), device_list.clone(), register.clone(),
|
||||
nat_test.clone(), tun_writer.clone(), tap_writer.clone(), connect_status.clone(), peer_nat_info_map.clone());
|
||||
let channel_recv_handler = recv_handler::RecvHandler::new(channel.try_clone()?, current_device.clone(), current_device_ext,device_list.clone(), register.clone(),
|
||||
nat_test.clone(), tun_writer.clone(), tap_writer.clone(),
|
||||
connect_status.clone(), peer_nat_info_map.clone(), ip_proxy_map, out_external_route);
|
||||
recv_handler::start(channel_recv_handler);
|
||||
// 定时心跳
|
||||
heartbeat_handler::start_heartbeat(channel.sender()?, device_list.clone(), current_device.clone());
|
||||
@@ -148,6 +160,8 @@ pub struct Config {
|
||||
pub name: String,
|
||||
pub server_address: SocketAddr,
|
||||
pub nat_test_server: Vec<SocketAddr>,
|
||||
pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||
pub out_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@@ -155,7 +169,8 @@ impl Config {
|
||||
device_id: String,
|
||||
name: String,
|
||||
server_address: SocketAddr,
|
||||
nat_test_server: Vec<SocketAddr>, ) -> Self {
|
||||
nat_test_server: Vec<SocketAddr>,
|
||||
in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32, Ipv4Addr)>, ) -> Self {
|
||||
Self {
|
||||
tap,
|
||||
token,
|
||||
@@ -163,6 +178,8 @@ impl Config {
|
||||
name,
|
||||
server_address,
|
||||
nat_test_server,
|
||||
in_ips,
|
||||
out_ips,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
// 目标ip,子网掩码,网关
|
||||
|
||||
pub struct ExternalRoute {
|
||||
route_table: Vec<(u32, u32, Ipv4Addr)>,
|
||||
}
|
||||
|
||||
impl ExternalRoute {
|
||||
pub fn new(route_table: Vec<(u32, u32, Ipv4Addr)>) -> Self {
|
||||
Self {
|
||||
route_table
|
||||
}
|
||||
}
|
||||
pub fn route(&self, ip: &Ipv4Addr) -> Option<Ipv4Addr> {
|
||||
let ip = u32::from_be_bytes(ip.octets());
|
||||
for (dest, mask, gateway) in &self.route_table {
|
||||
if *mask & ip == *mask & *dest {
|
||||
return Some(*gateway);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,19 @@ 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,
|
||||
@@ -71,7 +84,7 @@ pub struct CurrentDeviceInfo {
|
||||
pub broadcast_address: Ipv4Addr,
|
||||
//链接的服务器地址
|
||||
pub connect_server: SocketAddr,
|
||||
pub mac:[u8;6]
|
||||
|
||||
}
|
||||
|
||||
impl CurrentDeviceInfo {
|
||||
@@ -80,7 +93,6 @@ impl CurrentDeviceInfo {
|
||||
virtual_gateway: Ipv4Addr,
|
||||
virtual_netmask: Ipv4Addr,
|
||||
connect_server: SocketAddr,
|
||||
mac:[u8;6],
|
||||
) -> Self {
|
||||
let broadcast_address = (!u32::from_be_bytes(virtual_netmask.octets()))
|
||||
| u32::from_be_bytes(virtual_gateway.octets());
|
||||
@@ -95,7 +107,6 @@ impl CurrentDeviceInfo {
|
||||
virtual_network,
|
||||
broadcast_address,
|
||||
connect_server,
|
||||
mac
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::{io, thread};
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::thread;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::Local;
|
||||
@@ -12,12 +12,15 @@ 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::error::Error;
|
||||
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo};
|
||||
use crate::external_route::ExternalRoute;
|
||||
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, CurrentDeviceInfoExt, PeerDeviceInfo};
|
||||
use crate::handle::registration_handler::Register;
|
||||
use crate::ip_proxy::IpProxyMap;
|
||||
use crate::nat;
|
||||
use crate::nat::NatTest;
|
||||
use crate::proto::message::{DeviceList, PunchInfo, PunchNatType, RegistrationResponse};
|
||||
@@ -56,6 +59,7 @@ pub fn start(mut handler: RecvHandler) {
|
||||
pub struct RecvHandler {
|
||||
channel: Channel<Ipv4Addr>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
current_device_ext: Arc<AtomicCell<CurrentDeviceInfoExt>>,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
register: Arc<Register>,
|
||||
nat_test: NatTest,
|
||||
@@ -63,11 +67,14 @@ pub struct RecvHandler {
|
||||
tap_writer: Option<TapWriter>,
|
||||
connect_status: Arc<AtomicCell<ConnectStatus>>,
|
||||
peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>,
|
||||
ip_proxy_map: IpProxyMap,
|
||||
out_external_route: ExternalRoute,
|
||||
}
|
||||
|
||||
impl RecvHandler {
|
||||
pub fn new(channel: Channel<Ipv4Addr>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
current_device_ext: Arc<AtomicCell<CurrentDeviceInfoExt>>,
|
||||
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
|
||||
register: Arc<Register>,
|
||||
nat_test: NatTest,
|
||||
@@ -75,10 +82,13 @@ impl RecvHandler {
|
||||
tap_writer: Option<TapWriter>,
|
||||
connect_status: Arc<AtomicCell<ConnectStatus>>,
|
||||
peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>,
|
||||
ip_proxy_map: IpProxyMap,
|
||||
out_external_route: ExternalRoute,
|
||||
) -> Self {
|
||||
Self {
|
||||
channel,
|
||||
current_device,
|
||||
current_device_ext,
|
||||
device_list,
|
||||
register,
|
||||
nat_test,
|
||||
@@ -86,21 +96,23 @@ impl RecvHandler {
|
||||
tap_writer,
|
||||
connect_status,
|
||||
peer_nat_info_map,
|
||||
ip_proxy_map,
|
||||
out_external_route,
|
||||
}
|
||||
}
|
||||
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(),
|
||||
})
|
||||
}
|
||||
// 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 {
|
||||
@@ -144,36 +156,82 @@ impl RecvHandler {
|
||||
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 {
|
||||
//todo 外部数据转发
|
||||
} else {
|
||||
if 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 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();
|
||||
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::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(());
|
||||
}
|
||||
}
|
||||
}
|
||||
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(¤t_device.mac);
|
||||
ethernet_packet.set_protocol(ethernet::protocol::Protocol::Ipv4);
|
||||
ethernet_packet.payload_mut().copy_from_slice(ipv4.buffer);
|
||||
tap_writer.write(ðernet_packet.buffer)?;
|
||||
}
|
||||
}
|
||||
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(ðernet_packet.buffer)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,7 +283,7 @@ impl RecvHandler {
|
||||
}
|
||||
}
|
||||
let new_current_device = CurrentDeviceInfo::new(virtual_ip, virtual_gateway,
|
||||
virtual_netmask, current_device.connect_server, current_device.mac);
|
||||
virtual_netmask, current_device.connect_server);
|
||||
if let Err(e) = self.current_device.compare_exchange(current_device, new_current_device) {
|
||||
log::warn!("替换失败:{:?}",e);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::net::Ipv4Addr;
|
||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
use std::{io, thread};
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
@@ -10,16 +10,20 @@ 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>>, ) {
|
||||
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) {
|
||||
if let Err(e) = start_(sender, tap_reader, tap_writer, current_device,ip_route,ip_proxy_map) {
|
||||
log::warn!("{:?}",e);
|
||||
}
|
||||
}).unwrap();
|
||||
@@ -28,7 +32,9 @@ pub fn start(sender: Sender<Ipv4Addr>,
|
||||
fn start_(sender: Sender<Ipv4Addr>,
|
||||
tap_reader: TapReader,
|
||||
tap_writer: TapWriter,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, ) -> io::Result<()> {
|
||||
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);
|
||||
@@ -41,17 +47,17 @@ fn start_(sender: Sender<Ipv4Addr>,
|
||||
continue;
|
||||
}
|
||||
let mut ethernet_packet = EthernetPacket::unchecked(&mut buf[..len]);
|
||||
if let Err(e) = handle(&mut net_packet, ¤t_device, &tap_writer, &mut ethernet_packet, &sender) {
|
||||
if let Err(e) = handle(&mut net_packet, ¤t_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>) -> io::Result<()> {
|
||||
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 = ethernet::packet::EthernetPacket::unchecked(ethernet_packet.buffer.to_vec());
|
||||
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();
|
||||
@@ -75,10 +81,55 @@ fn handle(net_packet: &mut NetPacket<Vec<u8>>, current_device: &AtomicCell<Curre
|
||||
// println!("in ethernet_packet {:?}", ethernet_packet);
|
||||
let mut ipv4_packet = IpV4Packet::unchecked(ethernet_packet.payload_mut());
|
||||
let src_ip = ipv4_packet.source_ip();
|
||||
let dest_ip = ipv4_packet.destination_ip();
|
||||
if src_ip != current_device.virtual_ip() || (!check_dest(dest_ip, current_device.virtual_netmask, current_device.virtual_network) && !dest_ip.is_broadcast()) {
|
||||
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());
|
||||
@@ -103,8 +154,8 @@ fn handle(net_packet: &mut NetPacket<Vec<u8>>, current_device: &AtomicCell<Curre
|
||||
sender.send_to_addr(&net_packet.buffer()[..(12 + data_len)], current_device.connect_server)?;
|
||||
}
|
||||
}
|
||||
p => {
|
||||
log::warn!("不支持的二层协议:{:?}",p)
|
||||
_ => {
|
||||
// log::warn!("不支持的二层协议:{:?}",p)
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
use std::{io, thread};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
|
||||
use p2p_channel::channel::sender::Sender;
|
||||
use packet::icmp::icmp::IcmpPacket;
|
||||
use packet::icmp::Kind;
|
||||
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};
|
||||
|
||||
@@ -33,9 +35,9 @@ fn icmp(tun_writer: &TunWriter, mut ipv4_packet: IpV4Packet<&mut [u8]>) -> Resul
|
||||
|
||||
/// 接收tun数据,并且转发到udp上
|
||||
#[inline]
|
||||
fn handle(sender: &Sender<Ipv4Addr>, data: &mut [u8], tun_writer: &TunWriter, current_device: CurrentDeviceInfo, net_packet: &mut NetPacket<Vec<u8>>) -> Result<()> {
|
||||
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 ipv4_packet = match IpV4Packet::new(data) {
|
||||
let mut ipv4_packet = match IpV4Packet::new(data) {
|
||||
Ok(ipv4_packet) => ipv4_packet,
|
||||
Err(packet::error::Error::Unimplemented) => {
|
||||
return Ok(());
|
||||
@@ -43,18 +45,65 @@ fn handle(sender: &Sender<Ipv4Addr>, data: &mut [u8], tun_writer: &TunWriter, cu
|
||||
Err(e) => Err(e)?,
|
||||
};
|
||||
let src_ip = ipv4_packet.source_ip();
|
||||
let dest_ip = ipv4_packet.destination_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() || (!check_dest(dest_ip, current_device.virtual_netmask, current_device.virtual_network) && !dest_ip.is_broadcast()) {
|
||||
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);
|
||||
@@ -68,9 +117,11 @@ fn handle(sender: &Sender<Ipv4Addr>, data: &mut [u8], tun_writer: &TunWriter, cu
|
||||
pub fn start(sender: Sender<Ipv4Addr>,
|
||||
tun_reader: TunReader,
|
||||
tun_writer: TunWriter,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>) {
|
||||
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) {
|
||||
if let Err(e) = start_(sender, tun_reader, tun_writer, current_device, ip_route, ip_proxy_map) {
|
||||
log::warn!("{:?}",e);
|
||||
}
|
||||
}).unwrap();
|
||||
@@ -80,15 +131,17 @@ pub fn start(sender: Sender<Ipv4Addr>,
|
||||
fn start_(sender: Sender<Ipv4Addr>,
|
||||
tun_reader: TunReader,
|
||||
tun_writer: TunWriter,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>) -> io::Result<()> {
|
||||
let mut net_packet = NetPacket::new(vec![0u8; 4 + 8 + 1500])?;
|
||||
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) {
|
||||
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)
|
||||
@@ -101,8 +154,10 @@ fn start_(sender: Sender<Ipv4Addr>,
|
||||
fn start_(sender: Sender<Ipv4Addr>,
|
||||
tun_reader: TunReader,
|
||||
tun_writer: TunWriter,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, ) -> io::Result<()> {
|
||||
let mut net_packet = NetPacket::new(vec![0u8; 4 + 8 + 1500])?;
|
||||
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());
|
||||
@@ -110,7 +165,7 @@ fn start_(sender: Sender<Ipv4Addr>,
|
||||
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) {
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
use std::io;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
|
||||
use crossbeam_skiplist::SkipMap;
|
||||
use socket2::{Domain, SockAddr, Socket, Type};
|
||||
use p2p_channel::channel::sender::Sender;
|
||||
|
||||
use packet::icmp::icmp;
|
||||
use packet::icmp::icmp::HeaderOther;
|
||||
use packet::ip::ipv4;
|
||||
use crate::handle::CurrentDeviceInfo;
|
||||
use crate::protocol::{MAX_TTL, NetPacket, Protocol, Version};
|
||||
|
||||
pub struct IcmpProxy {
|
||||
icmp_socket: Arc<Socket>,
|
||||
// 对端-> 真实来源
|
||||
icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>>,
|
||||
sender: Sender<Ipv4Addr>,
|
||||
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
|
||||
}
|
||||
|
||||
impl IcmpProxy {
|
||||
pub fn new(addr: SocketAddrV4, icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>>, sender: Sender<Ipv4Addr>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) -> io::Result<IcmpProxy> {
|
||||
let icmp_socket = Arc::new(Socket::new(Domain::IPV4, Type::RAW, Some(socket2::Protocol::ICMPV4))?);
|
||||
icmp_socket.bind(&SockAddr::from(addr))?;
|
||||
// // 设置 SIO_RCVALL 参数
|
||||
// #[cfg(windows)]
|
||||
// {
|
||||
// use std::os::windows::io::AsRawSocket;
|
||||
// let raw_fd = icmp_socket.as_raw_socket();
|
||||
// let mut rcvall: winapi::shared::minwindef::DWORD = 1;
|
||||
// let mut bytes_returned: winapi::shared::minwindef::DWORD = 0;
|
||||
// let result = unsafe {
|
||||
// winapi::um::winsock2::WSAIoctl(
|
||||
// raw_fd as _,
|
||||
// winapi::shared::mstcpip::SIO_RCVALL,
|
||||
// &mut rcvall as *mut winapi::shared::minwindef::DWORD as *mut std::ffi::c_void,
|
||||
// std::mem::size_of::<winapi::shared::minwindef::DWORD>() as winapi::shared::minwindef::DWORD,
|
||||
// std::ptr::null_mut(),
|
||||
// 0,
|
||||
// &mut bytes_returned as winapi::shared::minwindef::LPDWORD,
|
||||
// std::ptr::null_mut(),
|
||||
// None,
|
||||
// )
|
||||
// };
|
||||
// if result != 0 {
|
||||
// return Err(io::Error::from_raw_os_error(unsafe { winapi::um::winsock2::WSAGetLastError() }));
|
||||
// }
|
||||
// }
|
||||
Ok(IcmpProxy {
|
||||
icmp_socket,
|
||||
icmp_proxy_map,
|
||||
sender,
|
||||
current_device,
|
||||
})
|
||||
}
|
||||
pub fn icmp_socket(&self) ->Arc<Socket>{
|
||||
self.icmp_socket.clone()
|
||||
}
|
||||
pub fn start(self) {
|
||||
let mut buf = [0 as u8; 1500];
|
||||
let data: &mut [MaybeUninit<u8>] =
|
||||
unsafe { std::mem::transmute(&mut buf[..]) };
|
||||
let mut net_packet = NetPacket::new([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);
|
||||
loop {
|
||||
match self.recv(data) {
|
||||
Ok((len, peer_ip)) => {
|
||||
match peer_ip {
|
||||
IpAddr::V4(peer_ip) => {
|
||||
match ipv4::packet::IpV4Packet::new(&mut buf[..len]) {
|
||||
Ok(mut ipv4_packet) => {
|
||||
match icmp::IcmpPacket::new(ipv4_packet.payload()) {
|
||||
Ok(icmp_packet) => {
|
||||
match icmp_packet.header_other() {
|
||||
HeaderOther::Identifier(id, seq) => {
|
||||
if let Some(entry) = self.icmp_proxy_map.get(&(peer_ip, id, seq)) {
|
||||
//将数据发送到真实的来源
|
||||
let dest_ip = *entry.value();
|
||||
ipv4_packet.set_destination_ip(dest_ip);
|
||||
ipv4_packet.update_checksum();
|
||||
let virtual_ip = self.current_device.load().virtual_ip();
|
||||
net_packet.set_source(virtual_ip);
|
||||
net_packet.set_destination(dest_ip);
|
||||
let data_len = ipv4_packet.buffer.len();
|
||||
net_packet.set_payload(ipv4_packet.buffer);
|
||||
let _ = self.sender.send_to_id(&net_packet.buffer()[..(12 + data_len)], &dest_ip);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {}
|
||||
};
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
IpAddr::V6(_) => {}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("icmp代理异常:{:?}",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn recv(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<(usize, IpAddr)> {
|
||||
let (size, addr) = self.icmp_socket.recv_from(buf)?;
|
||||
let addr = match addr.as_socket() {
|
||||
None => {
|
||||
IpAddr::V4(Ipv4Addr::UNSPECIFIED)
|
||||
}
|
||||
Some(add) => {
|
||||
add.ip()
|
||||
}
|
||||
};
|
||||
Ok((size, addr))
|
||||
}
|
||||
// fn send_to(&self, buf: &[u8], addr: SocketAddrV4) -> io::Result<usize> {
|
||||
// self.icmp_socket.send_to(buf, &SockAddr::from(addr))
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
use std::{io, thread};
|
||||
use std::collections::HashMap;
|
||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
use crossbeam_skiplist::SkipMap;
|
||||
use socket2::{SockAddr, Socket};
|
||||
use tokio::net::{TcpListener, UdpSocket};
|
||||
use p2p_channel::channel::sender::Sender;
|
||||
use crate::handle::CurrentDeviceInfo;
|
||||
use crate::ip_proxy::icmp_proxy::IcmpProxy;
|
||||
use crate::ip_proxy::tcp_proxy::TcpProxy;
|
||||
use crate::ip_proxy::udp_proxy::UdpProxy;
|
||||
|
||||
pub mod icmp_proxy;
|
||||
pub mod tcp_proxy;
|
||||
pub mod udp_proxy;
|
||||
|
||||
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug)]
|
||||
pub enum Protocol {
|
||||
Icmp,
|
||||
Tcp,
|
||||
Udp,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct IpProxyMap {
|
||||
pub(crate) tcp_proxy_port: u16,
|
||||
pub(crate) udp_proxy_port: u16,
|
||||
//真实源地址 -> (绑定地址,目的地址)
|
||||
pub(crate) tcp_proxy_map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>,
|
||||
pub(crate) udp_proxy_map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>,
|
||||
// icmp用Identifier来区分,没有Identifier的一律不转发
|
||||
pub(crate) icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>>,
|
||||
icmp_sockets: HashMap<Ipv4Addr, Arc<Socket>>,
|
||||
}
|
||||
|
||||
impl IpProxyMap {
|
||||
pub fn send_icmp(&self, buf: &[u8], src: &Ipv4Addr, dest: &Ipv4Addr) -> io::Result<usize> {
|
||||
if let Some(socket) = self.icmp_sockets.get(src) {
|
||||
socket.send_to(buf, &SockAddr::from(SocketAddrV4::new(*dest, 0)))
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Other, format!("not found src:{},dest:{}", src, dest)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn init_proxy(sender: Sender<Ipv4Addr>, bind_ips: Vec<Ipv4Addr>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) -> io::Result<IpProxyMap> {
|
||||
let mut icmp_sockets = HashMap::new();
|
||||
let tcp_proxy_map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>> = Arc::new(SkipMap::new());
|
||||
let udp_proxy_map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>> = Arc::new(SkipMap::new());
|
||||
let icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>> = Arc::new(SkipMap::new());
|
||||
let tcp_listener = TcpListener::bind("0.0.0.0:0").await?;
|
||||
let udp_socket = UdpSocket::bind("0.0.0.0:0").await?;
|
||||
let tcp_proxy_port = tcp_listener.local_addr()?.port();
|
||||
let udp_proxy_port = udp_socket.local_addr()?.port();
|
||||
|
||||
{
|
||||
let tcp_proxy_map = tcp_proxy_map.clone();
|
||||
tokio::spawn(async {
|
||||
let tcp_proxy = TcpProxy::new(tcp_listener, tcp_proxy_map);
|
||||
tcp_proxy.start().await
|
||||
});
|
||||
}
|
||||
{
|
||||
let udp_proxy_map = udp_proxy_map.clone();
|
||||
tokio::spawn(async {
|
||||
let udp_proxy = UdpProxy::new(udp_socket, udp_proxy_map);
|
||||
udp_proxy.start().await
|
||||
});
|
||||
}
|
||||
for ip in bind_ips {
|
||||
let addr = SocketAddrV4::new(ip, 0);
|
||||
let icmp_proxy_map = icmp_proxy_map.clone();
|
||||
let icmp_proxy = IcmpProxy::new(addr, icmp_proxy_map, sender.try_clone()?, current_device.clone())?;
|
||||
icmp_sockets.insert(ip, icmp_proxy.icmp_socket());
|
||||
thread::spawn(move || {
|
||||
icmp_proxy.start();
|
||||
});
|
||||
}
|
||||
|
||||
Ok(IpProxyMap {
|
||||
tcp_proxy_port,
|
||||
udp_proxy_port,
|
||||
tcp_proxy_map,
|
||||
udp_proxy_map,
|
||||
icmp_proxy_map,
|
||||
icmp_sockets,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
use std::io;
|
||||
use std::net::{SocketAddr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
use crossbeam_skiplist::SkipMap;
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
|
||||
pub struct TcpProxy {
|
||||
tcp_listener: TcpListener,
|
||||
// todo 怎么过期
|
||||
map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>,
|
||||
}
|
||||
|
||||
impl TcpProxy {
|
||||
pub fn new(tcp_listener: TcpListener, map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>) -> Self {
|
||||
Self {
|
||||
tcp_listener,
|
||||
map,
|
||||
}
|
||||
}
|
||||
pub async fn start(self) {
|
||||
let tcp_listener = self.tcp_listener;
|
||||
let map = self.map;
|
||||
loop {
|
||||
match tcp_listener.accept().await {
|
||||
Ok((tcp_stream, sender_addr)) => {
|
||||
match sender_addr {
|
||||
SocketAddr::V4(sender_addr) => {
|
||||
if let Some(entry) = map.get(&sender_addr) {
|
||||
let (src_addr, dest_addr) = *entry.value();
|
||||
let peer_tcp_stream = match TcpStream::connect(dest_addr).await {
|
||||
Ok(peer_tcp_stream) => {peer_tcp_stream}
|
||||
Err(e) => {
|
||||
log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
tokio::spawn(async move {
|
||||
match proxy(tcp_stream, peer_tcp_stream).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
SocketAddr::V6(_) => {}
|
||||
}
|
||||
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("tcp代理监听:{:?}",e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn proxy(mut client: TcpStream, mut server: TcpStream) -> io::Result<()> {
|
||||
let (mut client_reader, mut client_writer) = client.split();
|
||||
let (mut server_reader, mut server_writer) = server.split();
|
||||
|
||||
let client_to_server = tokio::io::copy(&mut client_reader, &mut server_writer);
|
||||
let server_to_client = tokio::io::copy(&mut server_reader, &mut client_writer);
|
||||
|
||||
tokio::try_join!(client_to_server, server_to_client)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
use std::io;
|
||||
use std::net::{SocketAddr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use crossbeam_skiplist::SkipMap;
|
||||
use tokio::net::UdpSocket;
|
||||
|
||||
/// 一个udp代理,作用是利用系统协议栈,将udp数据报解析出来再转发到目的地址
|
||||
pub struct UdpProxy {
|
||||
udp_socket: Arc<UdpSocket>,
|
||||
// todo 过期处理
|
||||
map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>,
|
||||
}
|
||||
|
||||
impl UdpProxy {
|
||||
pub fn new(udp_socket: UdpSocket, map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>) -> Self {
|
||||
let udp_socket = Arc::new(udp_socket);
|
||||
Self {
|
||||
udp_socket,
|
||||
map,
|
||||
}
|
||||
}
|
||||
pub async fn start(self) {
|
||||
let map = self.map;
|
||||
let udp_socket = self.udp_socket;
|
||||
let mut buf = [0u8; 65536];
|
||||
let inner_map: Arc<SkipMap<SocketAddrV4, Arc<UdpSocket>>> = Arc::new(SkipMap::new());
|
||||
|
||||
loop {
|
||||
match udp_socket.recv_from(&mut buf).await {
|
||||
Ok((len, sender_addr)) => {
|
||||
match sender_addr {
|
||||
SocketAddr::V4(sender_addr) => {
|
||||
match start0(&buf[..len], sender_addr, &inner_map, &map, &udp_socket).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("udp代理异常:{:?},来源:{}",e,sender_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
SocketAddr::V6(_) => {}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("udp代理异常:{:?}",e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn start0(buf: &[u8], sender_addr: SocketAddrV4, inner_map: &Arc<SkipMap<SocketAddrV4, Arc<UdpSocket>>>, map: &Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>, udp_socket: &Arc<UdpSocket>) -> io::Result<()> {
|
||||
if let Some(entry) = inner_map.get(&sender_addr) {
|
||||
entry.value().send(buf).await?;
|
||||
} else if let Some(entry) = map.get(&sender_addr) {
|
||||
let (src_addr, dest_addr) = *entry.value();
|
||||
let peer_udp_socket = UdpSocket::bind("0.0.0.0:0").await?;
|
||||
peer_udp_socket.connect(dest_addr).await?;
|
||||
peer_udp_socket.send(buf).await?;
|
||||
let peer_udp_socket = Arc::new(peer_udp_socket);
|
||||
let inner_map = inner_map.clone();
|
||||
inner_map.insert(sender_addr, peer_udp_socket.clone());
|
||||
let udp_socket = udp_socket.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut buf = [0u8; 65536];
|
||||
loop {
|
||||
match tokio::time::timeout(Duration::from_secs(300), peer_udp_socket.recv(&mut buf)).await {
|
||||
Ok(rs) => {
|
||||
match rs {
|
||||
Ok(len) => {
|
||||
match udp_socket.send_to(&buf[..len], sender_addr).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("udp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("udp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
//超时关闭
|
||||
log::warn!("udp代理超时关闭,来源:{},目标:{}",src_addr,dest_addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
inner_map.remove(&sender_addr);
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -11,4 +11,6 @@ pub mod proto;
|
||||
pub mod protocol;
|
||||
pub mod tun_device;
|
||||
pub mod tap_device;
|
||||
pub mod ip_proxy;
|
||||
pub mod external_route;
|
||||
pub mod core;
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
use std::io;
|
||||
use crate::tun_device::{TunReader, TunWriter};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::Arc;
|
||||
use tun::Device;
|
||||
use parking_lot::Mutex;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn create_tun(
|
||||
address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
) -> crate::error::Result<(TunWriter, TunReader)> {
|
||||
println!("========TUN网卡配置========");
|
||||
let mut config = tun::Configuration::default();
|
||||
@@ -19,20 +22,36 @@ pub fn create_tun(
|
||||
.mtu(1420)
|
||||
// .queues(2) 用多个队列有兼容性问题
|
||||
.up();
|
||||
//
|
||||
// config.platform(|config| {
|
||||
// config.packet_information(true);
|
||||
// });
|
||||
|
||||
let dev = tun::create(&config).unwrap();
|
||||
let packet_information = dev.has_packet_information();
|
||||
let queue = dev.queue(0).unwrap();
|
||||
let reader = queue.reader();
|
||||
let writer = queue.writer();
|
||||
println!("name:{:?}", dev.name());
|
||||
let name = dev.name();
|
||||
println!("name:{:?}", name);
|
||||
for (address, netmask) in in_ips {
|
||||
add_route(name, address, netmask)?;
|
||||
}
|
||||
println!("========TUN网卡配置========");
|
||||
Ok((
|
||||
TunWriter(writer, packet_information, Arc::new(Mutex::new(dev))),
|
||||
TunReader(reader, packet_information),
|
||||
))
|
||||
}
|
||||
|
||||
fn add_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
||||
let route_add_str: String = format!(
|
||||
"ip route add {:?}/{:?} dev {}",
|
||||
address, netmask, name
|
||||
);
|
||||
let route_add_out = Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(route_add_str)
|
||||
.output()
|
||||
.expect("sh exec error!");
|
||||
if !route_add_out.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("添加路由失败: {:?}", route_add_out)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ pub fn create_tun(
|
||||
address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
in_ips: Vec<(Ipv4Addr, Ipv4Addr)>,
|
||||
) -> crate::error::Result<(TunWriter, TunReader)> {
|
||||
println!("========TUN网卡配置========");
|
||||
let mut config = tun::Configuration::default();
|
||||
@@ -23,13 +24,17 @@ pub fn create_tun(
|
||||
.up();
|
||||
|
||||
let dev = tun::create(&config).unwrap();
|
||||
config_ip(dev.name(), address, netmask, gateway)?;
|
||||
|
||||
let name = dev.name();
|
||||
config_ip(name, address, netmask, gateway)?;
|
||||
add_route(name, address, netmask)?;
|
||||
for (address, netmask) in in_ips {
|
||||
add_route(name, address, netmask)?;
|
||||
}
|
||||
let packet_information = dev.has_packet_information();
|
||||
let queue = dev.queue(0).unwrap();
|
||||
let reader = queue.reader();
|
||||
let writer = queue.writer();
|
||||
println!("name:{:?}", dev.name());
|
||||
println!("name:{:?}", name);
|
||||
println!("========TUN网卡配置========");
|
||||
Ok((
|
||||
TunWriter(writer, packet_information, Arc::new(Mutex::new(dev))),
|
||||
@@ -37,12 +42,24 @@ pub fn create_tun(
|
||||
))
|
||||
}
|
||||
|
||||
fn add_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> {
|
||||
let route_add_str: String = format!(
|
||||
"sudo route -n add -net {:?}/{:?} -interface {}",
|
||||
address, netmask, name
|
||||
);
|
||||
let route_add_out = Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(route_add_str)
|
||||
.output()
|
||||
.expect("sh exec error!");
|
||||
if !route_add_out.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("添加路由失败: {:?}", route_add_out)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn config_ip(name: &str, address: Ipv4Addr, netmask: Ipv4Addr, gateway: Ipv4Addr) -> io::Result<()> {
|
||||
let up_eth_str: String = format!("ifconfig {} {:?} {:?} up ", name, address, gateway);
|
||||
let route_add_str: String = format!(
|
||||
"sudo route -n add -net {:?} -netmask {:?} {:?}",
|
||||
address, netmask, gateway
|
||||
);
|
||||
let up_eth_out = Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(up_eth_str)
|
||||
@@ -51,13 +68,5 @@ pub(crate) fn config_ip(name: &str, address: Ipv4Addr, netmask: Ipv4Addr, gatewa
|
||||
if !up_eth_out.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("设置网络地址失败: {:?}", up_eth_out)));
|
||||
}
|
||||
let if_config_out = Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(route_add_str)
|
||||
.output()
|
||||
.expect("sh exec error!");
|
||||
if !if_config_out.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("添加路由失败: {:?}", if_config_out)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ pub fn create_tun(
|
||||
address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
in_ips:Vec<(Ipv4Addr,Ipv4Addr)>
|
||||
) -> io::Result<(TunWriter, TunReader)> {
|
||||
unsafe {
|
||||
println!("========TUN网卡配置========");
|
||||
@@ -103,6 +104,9 @@ pub fn create_tun(
|
||||
log::error!("创建tun成功 {:?}",tun_device.get_name()?);
|
||||
tun_device.set_ip(address, netmask)?;
|
||||
tun_device.set_mtu(1420)?;
|
||||
for (address, netmask) in in_ips {
|
||||
tun_device.add_route(address, netmask, gateway)?;
|
||||
}
|
||||
tun_device.add_route(address, netmask, gateway)?;
|
||||
let device = Arc::new(tun_device);
|
||||
println!("========TUN网卡配置========");
|
||||
|
||||
Reference in New Issue
Block a user