[mio] 去除多余代码

This commit is contained in:
lubeilin
2024-02-29 22:31:08 +08:00
parent 8d7eb5ba1b
commit 55a510aa34
6 changed files with 0 additions and 1979 deletions
-262
View File
@@ -1,262 +0,0 @@
use std::net::{SocketAddr, SocketAddrV6};
use crate::channel::channel::Context;
use crate::channel::RouteKey;
use crate::cipher::{Cipher, RsaCipher};
use crate::proto::message::{HandshakeRequest, HandshakeResponse, SecretHandshakeRequest};
use crate::protocol::body::RSA_ENCRYPTION_RESERVED;
use crate::protocol::{service_packet, NetPacket, Protocol, Version, MAX_TTL};
use protobuf::Message;
use std::io::{Read, Write};
use std::net::TcpStream;
use std::net::UdpSocket;
pub enum HandshakeEnum {
NotSecret,
KeyError,
Timeout,
ServerError(String),
Other(String),
}
fn handshake_request_packet(secret: bool) -> crate::Result<NetPacket<Vec<u8>>> {
let mut request = HandshakeRequest::new();
request.secret = secret;
request.version = crate::VNT_VERSION.to_string();
let bytes = request.write_to_bytes()?;
let buf = vec![0u8; 12 + bytes.len()];
let mut net_packet = NetPacket::new(buf)?;
net_packet.set_version(Version::V1);
net_packet.set_gateway_flag(true);
net_packet.set_protocol(Protocol::Service);
net_packet.set_transport_protocol(service_packet::Protocol::HandshakeRequest.into());
net_packet.first_set_ttl(MAX_TTL);
net_packet.set_payload(&bytes)?;
Ok(net_packet)
}
fn secret_handshake_request_packet(
rsa_cipher: &RsaCipher,
token: String,
key: &[u8],
) -> crate::Result<NetPacket<Vec<u8>>> {
let mut request = SecretHandshakeRequest::new();
request.token = token;
request.key = key.to_vec();
let bytes = request.write_to_bytes()?;
let mut net_packet = NetPacket::new0(
12 + bytes.len(),
vec![0u8; 12 + bytes.len() + RSA_ENCRYPTION_RESERVED],
)?;
net_packet.set_version(Version::V1);
net_packet.set_gateway_flag(true);
net_packet.set_protocol(Protocol::Service);
net_packet.set_transport_protocol(service_packet::Protocol::SecretHandshakeRequest.into());
net_packet.first_set_ttl(MAX_TTL);
net_packet.set_payload(&bytes)?;
Ok(rsa_cipher.encrypt(&mut net_packet)?)
}
/// 第一次握手,拿到公钥
pub fn handshake(
main_channel: &UdpSocket,
main_tcp_channel: Option<&mut TcpStream>,
server_address: SocketAddr,
secret: bool,
) -> Result<Option<RsaCipher>, HandshakeEnum> {
let request_packet = handshake_request_packet(secret).unwrap();
let send_buf = request_packet.buffer();
let mut recv_buf = [0u8; 10240];
let len = send_recv(
main_channel,
main_tcp_channel,
server_address,
send_buf,
&mut recv_buf,
)?;
let net_packet = match NetPacket::new(&recv_buf[..len]) {
Ok(net_packet) => net_packet,
Err(e) => {
return Err(HandshakeEnum::Other(format!("net_packet {}", e)));
}
};
match net_packet.protocol() {
Protocol::Service => {
match service_packet::Protocol::from(net_packet.transport_protocol()) {
service_packet::Protocol::HandshakeResponse => {
match HandshakeResponse::parse_from_bytes(net_packet.payload()) {
Ok(response) => {
if !response.secret && secret {
//客户端要加密,服务端不支持加密
return Err(HandshakeEnum::NotSecret);
}
if secret {
//转换公钥
match RsaCipher::new(&response.public_key) {
Ok(rsa) => {
match rsa.finger() {
Ok(finger) => {
if finger != response.key_finger {
return Err(HandshakeEnum::Other(
"finger error".to_string(),
));
}
}
Err(e) => {
return Err(HandshakeEnum::Other(format!(
"finger {}",
e
)));
}
}
Ok(Some(rsa))
}
Err(e) => {
return Err(HandshakeEnum::Other(format!(
"RsaCipher {}",
e
)));
}
}
} else {
Ok(None)
}
}
Err(e) => {
return Err(HandshakeEnum::Other(format!("parse_from_bytes {}", e)));
}
}
}
_ => {
return Err(HandshakeEnum::Other("not match".to_string()));
}
}
}
_ => {
return Err(HandshakeEnum::Other("not match".to_string()));
}
}
}
fn send_recv(
main_channel: &UdpSocket,
main_tcp_channel: Option<&mut TcpStream>,
server_address: SocketAddr,
send_buf: &[u8],
recv_buf: &mut [u8],
) -> Result<usize, HandshakeEnum> {
if let Some(main_tcp_channel) = main_tcp_channel {
let mut head = [0; 4];
let len = send_buf.len();
head[2] = (len >> 8) as u8;
head[3] = (len & 0xFF) as u8;
if let Err(e) = main_tcp_channel.write_all(&head) {
return Err(HandshakeEnum::Other(format!("send error:{}", e)));
}
if let Err(e) = main_tcp_channel.write_all(send_buf) {
return Err(HandshakeEnum::Other(format!("send error:{}", e)));
}
if let Err(e) = main_tcp_channel.read_exact(&mut head) {
return Err(HandshakeEnum::Other(format!("read error:{}", e)));
}
let len = (((head[2] as u16) << 8) | head[3] as u16) as usize;
if len > recv_buf.len() {
return Err(HandshakeEnum::Other("too long".to_string()));
}
if let Err(e) = main_tcp_channel.read_exact(&mut recv_buf[..len]) {
return Err(HandshakeEnum::Other(format!("read error:{}", e)));
}
Ok(len)
} else {
let server_address = if let SocketAddr::V4(ipv4) = server_address {
SocketAddr::V6(SocketAddrV6::new(
ipv4.ip().to_ipv6_mapped(),
ipv4.port(),
0,
0,
))
} else {
server_address
};
if let Err(e) = main_channel.send_to(send_buf, server_address) {
return Err(HandshakeEnum::Other(format!("send error:{}", e)));
}
match main_channel.recv_from(recv_buf) {
Ok((len, addr)) => {
if server_address != addr {
log::warn!("请求{:?}和响应{:?}地址不一致", server_address, addr);
}
Ok(len)
}
Err(e) => Err(HandshakeEnum::Other(format!("receiver error:{}", e))),
}
}
}
/// 第二次握手,同步对称密钥,后续将使用对称加密
pub fn secret_handshake(
main_channel: &UdpSocket,
main_tcp_channel: Option<&mut TcpStream>,
server_address: SocketAddr,
rsa_cipher: &RsaCipher,
server_cipher: &Cipher,
token: String,
) -> Result<(), HandshakeEnum> {
let secret_packet =
match secret_handshake_request_packet(rsa_cipher, token, server_cipher.key().unwrap()) {
Ok(secret_packet) => secret_packet,
Err(e) => {
return Err(HandshakeEnum::Other(format!(
"secret_handshake_request_packet {}",
e
)));
}
};
let send_buf = secret_packet.buffer();
let mut recv_buf = [0u8; 10240];
let len = send_recv(
main_channel,
main_tcp_channel,
server_address,
send_buf,
&mut recv_buf,
)?;
let mut net_packet = match NetPacket::new(&mut recv_buf[..len]) {
Ok(net_packet) => net_packet,
Err(e) => {
return Err(HandshakeEnum::Other(format!("secret_net_packet {}", e)));
}
};
match server_cipher.decrypt_ipv4(&mut net_packet) {
Ok(_) => {
if net_packet.is_gateway()
&& net_packet.protocol() == Protocol::Service
&& service_packet::Protocol::from(net_packet.transport_protocol())
== service_packet::Protocol::SecretHandshakeResponse
{
Ok(())
} else {
Err(HandshakeEnum::Other("not match".to_string()))
}
}
Err(e) => Err(HandshakeEnum::Other(format!("decrypt_ipv4 {}", e))),
}
}
pub fn secret_handshake_req(
context: &Context,
server_address: SocketAddr,
rsa_cipher: &RsaCipher,
server_cipher: &Cipher,
token: String,
route_key: &RouteKey,
) -> crate::Result<()> {
let secret_packet =
secret_handshake_request_packet(rsa_cipher, token, server_cipher.key().unwrap())?;
if route_key.is_tcp() {
context.send_main(secret_packet.buffer(), server_address)?;
} else {
context.send_main_udp(secret_packet.buffer(), server_address)?;
}
Ok(())
}
-301
View File
@@ -1,301 +0,0 @@
use std::io;
use std::net::{Ipv4Addr, ToSocketAddrs};
use std::sync::Arc;
use std::time::Duration;
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use rand::prelude::SliceRandom;
use crate::channel::idle::Idle;
use crate::channel::sender::ChannelSender;
use crate::channel::Route;
use crate::cipher::Cipher;
use crate::core::status::VntWorker;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::control_packet::PingPacket;
use crate::protocol::{control_packet, NetPacket, Protocol, Version, MAX_TTL};
pub fn start_idle(mut worker: VntWorker, idle: Idle, sender: ChannelSender) {
tokio::spawn(async move {
tokio::select! {
_=worker.stop_wait()=>{
return;
}
rs=start_idle_(idle, sender)=>{
if let Err(e) = rs {
log::warn!("空闲检测任务停止:{:?}", e);
}
}
}
worker.stop_all();
});
}
async fn start_idle_(idle: Idle, sender: ChannelSender) -> io::Result<()> {
log::info!("启动空闲检查任务");
loop {
let (peer_ip, route) = idle.next_idle().await?;
log::info!("路由空闲 peer_ip:{:?},route:{:?}", peer_ip, route);
sender.remove_route(&peer_ip, route);
}
}
pub fn start_heartbeat(
mut worker: VntWorker,
sender: ChannelSender,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher,
server_cipher: Cipher,
) {
tokio::spawn(async move {
tokio::select! {
_=worker.stop_wait()=>{
return;
}
rs=start_heartbeat_(sender, device_list, current_device,client_cipher,server_cipher)=>{
if let Err(e) = rs {
log::warn!("心跳任务停止:{:?}", e);
}
}
}
worker.stop_all();
});
}
pub fn start_heartbeat_main(
mut worker: VntWorker,
sender: ChannelSender,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
server_address_str: String,
client_cipher: Cipher,
server_cipher: Cipher,
) {
tokio::spawn(async move {
tokio::select! {
_=worker.stop_wait()=>{
return;
}
rs=start_heartbeat_main_(sender, device_list, current_device,server_address_str,client_cipher,server_cipher)=>{
if let Err(e) = rs {
log::warn!("主心跳任务停止:{:?}", e);
}
}
}
worker.stop_all();
});
}
fn heartbeat_packet(
ttl: u8,
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>,
client_cipher: &Cipher,
server_cipher: &Cipher,
gateway: bool,
src: Ipv4Addr,
dest: Ipv4Addr,
) -> NetPacket<[u8; 12 + 4 + ENCRYPTION_RESERVED]> {
let mut net_packet = NetPacket::new_encrypt([0u8; 12 + 4 + ENCRYPTION_RESERVED]).unwrap();
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(ttl);
net_packet.set_source(src);
net_packet.set_destination(dest);
{
let mut ping = PingPacket::new(net_packet.payload_mut()).unwrap();
let epoch = { device_list.lock().0 };
ping.set_epoch(epoch);
ping.set_time(crate::handle::now_time() as u16);
}
if gateway {
net_packet.set_gateway_flag(true);
server_cipher.encrypt_ipv4(&mut net_packet).unwrap();
} else {
client_cipher.encrypt_ipv4(&mut net_packet).unwrap();
}
net_packet
}
async fn start_heartbeat_main_(
sender: ChannelSender,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
server_address_str: String,
client_cipher: Cipher,
server_cipher: Cipher,
) -> io::Result<()> {
let mut count = 0;
log::info!("启动主心跳任务");
loop {
if sender.is_close() {
return Ok(());
}
let mut current_dev = current_device.load();
let src = current_dev.virtual_ip();
if count % 40 == 19 {
if let Ok(mut addr) = server_address_str.to_socket_addrs() {
if let Some(addr) = addr.next() {
if addr != current_dev.connect_server {
let mut tmp = current_dev.clone();
tmp.connect_server = addr;
log::info!(
"服务端地址变化,旧地址:{},新地址:{}",
current_dev.connect_server,
addr
);
if current_device.compare_exchange(current_dev, tmp).is_ok() {
current_dev.connect_server = addr;
}
}
}
}
}
let server_packet = heartbeat_packet(
MAX_TTL,
&device_list,
&client_cipher,
&server_cipher,
true,
src,
current_dev.virtual_gateway,
);
if let Err(e) = sender.send_main(server_packet.buffer(), current_dev.connect_server) {
log::warn!("connect_server:{:?},e:{:?}", current_dev.connect_server, e);
}
count += 1;
tokio::time::sleep(Duration::from_millis(3000)).await;
}
}
async fn start_heartbeat_(
sender: ChannelSender,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher,
server_cipher: Cipher,
) -> io::Result<()> {
let mut count = 0;
log::info!("启动心跳任务");
loop {
if sender.is_close() {
return Ok(());
}
let current_dev = current_device.load();
//如果和服务端使用tcp连接,则维持udp洞的频率要更高些
if (sender.is_main_tcp() && count % 4 == 0) || (!sender.is_main_tcp() && count % 40 == 1) {
let mut packet = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED])?;
packet.set_version(Version::V1);
packet.set_gateway_flag(true);
packet.set_protocol(Protocol::Control);
packet.set_transport_protocol(control_packet::Protocol::AddrRequest.into());
packet.first_set_ttl(MAX_TTL);
packet.set_source(current_dev.virtual_ip());
packet.set_destination(current_dev.virtual_gateway);
server_cipher.encrypt_ipv4(&mut packet)?;
let _ = sender.send_main_udp(packet.buffer(), current_dev.connect_server);
}
let src = current_dev.virtual_ip();
if count % 10 == 7 {
let mut route_list: Option<Vec<(Ipv4Addr, Vec<Route>)>> = None;
let peer_list = { device_list.lock().1.clone() };
for peer in peer_list {
if peer.virtual_ip == current_dev.virtual_ip {
continue;
}
let client_packet = heartbeat_packet(
MAX_TTL,
&device_list,
&client_cipher,
&server_cipher,
false,
src,
peer.virtual_ip,
);
if let Some(route) = sender.route_one(&peer.virtual_ip) {
if let Err(e) =
sender.try_send_by_key(client_packet.buffer(), &route.route_key())
{
log::warn!("virtual_ip:{},route:{:?},e:{:?}", peer.virtual_ip, route, e);
}
if route.is_p2p() && !sender.is_first_latency() {
continue;
}
} else {
//没有直连路由则发送到网关
if let Err(e) =
sender.send_main(client_packet.buffer(), current_dev.connect_server)
{
log::warn!(
"virtual_ip:{},connect_server:{:?},e:{:?}",
peer.virtual_ip,
current_dev.connect_server,
e
);
}
}
//再随机发送到其他地址,看有没有客户端符合转发条件
let route_list = route_list.get_or_insert_with(|| {
let mut l = sender.route_table();
l.shuffle(&mut rand::thread_rng());
l
});
let mut num = 0;
'a: for (peer_ip, route_list) in route_list.iter() {
for route in route_list {
if peer_ip != &peer.virtual_ip && route.is_p2p() {
if let Err(e) =
sender.try_send_by_key(client_packet.buffer(), &route.route_key())
{
log::warn!(
"virtual_ip:{},route:{:?},e:{:?}",
peer.virtual_ip,
route,
e
);
}
num += 1;
break;
}
if num >= 2 {
break 'a;
}
}
}
tokio::time::sleep(Duration::from_millis(1)).await;
}
} else {
for (peer_ip, route_list) in sender.route_table().iter() {
if peer_ip == &current_dev.virtual_gateway {
continue;
}
let client_packet = heartbeat_packet(
MAX_TTL,
&device_list,
&client_cipher,
&server_cipher,
false,
src,
*peer_ip,
);
for route in route_list {
if let Err(e) =
sender.try_send_by_key(client_packet.buffer(), &route.route_key())
{
log::warn!("peer_ip:{:?},route:{:?},e:{:?}", peer_ip, route, e);
}
tokio::time::sleep(Duration::from_millis(2)).await;
}
}
}
count += 1;
tokio::time::sleep(Duration::from_millis(3000)).await;
}
}
-180
View File
@@ -1,180 +0,0 @@
use crate::channel::punch::{NatInfo, Punch};
use crate::channel::sender::ChannelSender;
use crate::cipher::Cipher;
use crate::core::status::VntWorker;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest;
use crate::proto::message::{PunchInfo, PunchNatType};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::{control_packet, other_turn_packet, NetPacket, Protocol, Version, MAX_TTL};
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::Mutex;
use protobuf::Message;
use rand::prelude::SliceRandom;
use std::io;
use std::net::Ipv4Addr;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::mpsc::Receiver;
pub fn start(
mut worker: VntWorker,
receiver: Receiver<(Ipv4Addr, NatInfo)>,
punch: Punch,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher,
) {
tokio::spawn(async move {
tokio::select! {
_=start0(receiver, punch, current_device,client_cipher)=>{}
_=worker.stop_wait()=>{
return;
}
}
worker.stop_all();
});
}
pub async fn start0(
mut receiver: Receiver<(Ipv4Addr, NatInfo)>,
mut punch: Punch,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher,
) {
log::info!("启动打洞任务");
while let Some((peer_ip, nat_info)) = receiver.recv().await {
if let Err(e) = start_(
&client_cipher,
&mut punch,
&current_device,
peer_ip,
nat_info,
)
.await
{
log::warn!("网络打洞异常 {:?}", e);
}
}
}
async fn start_(
client_cipher: &Cipher,
punch: &mut Punch,
current_device: &Arc<AtomicCell<CurrentDeviceInfo>>,
peer_ip: Ipv4Addr,
nat_info: NatInfo,
) -> io::Result<()> {
let mut packet = NetPacket::new_encrypt([0u8; 12 + ENCRYPTION_RESERVED])?;
packet.set_version(Version::V1);
packet.first_set_ttl(1);
packet.set_protocol(Protocol::Control);
packet.set_transport_protocol(control_packet::Protocol::PunchRequest.into());
packet.set_source(current_device.load().virtual_ip());
packet.set_destination(peer_ip);
log::info!("发起打洞,目标:{:?},{:?}", peer_ip, nat_info);
client_cipher.encrypt_ipv4(&mut packet)?;
punch.punch(packet.buffer(), peer_ip, nat_info).await
}
pub async fn start_punch(
mut worker: VntWorker,
nat_test: NatTest,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
sender: ChannelSender,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: Cipher,
) {
let mut num = 0;
let sleep_time = [3, 5, 7, 11, 13, 17, 19, 23, 29];
log::info!("启动发起打洞请求任务");
loop {
if sender.is_close() {
break;
}
tokio::select! {
rs= start_punch_(Duration::from_secs(sleep_time[num % sleep_time.len()]),&nat_test, &device_list,
&sender, &current_device,&client_cipher)=>{
if let Err(e) = rs {
log::warn!("打洞处理任务异常 {:?}", e);
}
}
_=worker.stop_wait()=>{
break;
}
}
num += 1;
}
}
async fn start_punch_(
sleep_time: Duration,
nat_test: &NatTest,
device_list: &Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
sender: &ChannelSender,
current_device: &Arc<AtomicCell<CurrentDeviceInfo>>,
client_cipher: &Cipher,
) -> crate::Result<()> {
let current_device = current_device.load();
let nat_info = nat_test.nat_info();
let mut list = device_list.lock().clone().1;
list.shuffle(&mut rand::thread_rng());
let mut count = 0;
for info in list {
if info.virtual_ip <= current_device.virtual_ip {
continue;
}
if !sender.need_punch(&info.virtual_ip) {
continue;
}
count += 1;
if count > 2 {
break;
}
let packet = punch_packet(
client_cipher,
current_device.virtual_ip(),
&nat_info,
info.virtual_ip,
)
.unwrap();
let _ = sender.send_main(packet.buffer(), current_device.connect_server);
}
tokio::time::sleep(sleep_time).await;
Ok(())
}
pub fn punch_packet(
client_cipher: &Cipher,
virtual_ip: Ipv4Addr,
nat_info: &NatInfo,
dest: Ipv4Addr,
) -> crate::Result<NetPacket<Vec<u8>>> {
let mut punch_reply = PunchInfo::new();
punch_reply.reply = false;
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.local_ip = u32::from(nat_info.local_ipv4().unwrap_or(Ipv4Addr::UNSPECIFIED));
punch_reply.local_port = nat_info.udp_port as u32;
punch_reply.tcp_port = nat_info.tcp_port as u32;
if let Some(ipv6) = nat_info.ipv6 {
punch_reply.ipv6_port = nat_info.udp_port as u32;
punch_reply.ipv6 = ipv6.octets().to_vec();
}
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_encrypt(vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED])?;
net_packet.set_version(Version::V1);
net_packet.set_protocol(Protocol::OtherTurn);
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);
net_packet.set_payload(&bytes)?;
client_cipher.encrypt_ipv4(&mut net_packet)?;
Ok(net_packet)
}
-714
View File
@@ -1,714 +0,0 @@
use std::collections::HashMap;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::sync::Arc;
use std::time::{Duration, Instant};
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::{Mutex, RwLock};
use protobuf::Message;
use tokio::sync::mpsc::Sender;
use packet::icmp::{icmp, Kind};
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::cipher::{Cipher, RsaCipher};
use crate::error::Error;
use crate::external_route::AllowExternalRoute;
use crate::handle::handshake_handler::secret_handshake_req;
use crate::handle::registration_handler::Register;
use crate::handle::{ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, PeerDeviceStatus};
use crate::igmp_server::IgmpServer;
#[cfg(feature = "ip_proxy")]
use crate::ip_proxy::{IpProxyMap, ProxyHandler};
use crate::nat;
use crate::nat::NatTest;
use crate::proto::message::{DeviceList, PunchInfo, PunchNatType, RegistrationResponse};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::control_packet::ControlPacket;
use crate::protocol::error_packet::InErrorPacket;
use crate::protocol::{
control_packet, ip_turn_packet, other_turn_packet, service_packet, NetPacket, Protocol,
Version, MAX_TTL,
};
use crate::tun_tap_device::DeviceWriter;
#[derive(Clone)]
pub struct ChannelDataHandler {
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
register: Arc<Register>,
nat_test: NatTest,
igmp_server: Option<IgmpServer>,
device_writer: DeviceWriter,
connect_status: Arc<AtomicCell<ConnectStatus>>,
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
#[cfg(feature = "ip_proxy")]
ip_proxy_map: Option<IpProxyMap>,
out_external_route: AllowExternalRoute,
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
client_cipher: Cipher,
server_cipher: Cipher,
rsa_cipher: Option<RsaCipher>,
relay: bool,
token: String,
time: Arc<AtomicCell<Instant>>,
pub head_reserve: usize,
}
impl ChannelDataHandler {
pub fn new(
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
device_list: Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
register: Arc<Register>,
nat_test: NatTest,
igmp_server: Option<IgmpServer>,
device_writer: DeviceWriter,
connect_status: Arc<AtomicCell<ConnectStatus>>,
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
out_external_route: AllowExternalRoute,
cone_sender: Sender<(Ipv4Addr, NatInfo)>,
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
client_cipher: Cipher,
server_cipher: Cipher,
rsa_cipher: Option<RsaCipher>,
relay: bool,
token: String,
head_reserve: usize,
) -> Self {
Self {
current_device,
device_list,
register,
nat_test,
igmp_server,
device_writer,
connect_status,
peer_nat_info_map,
#[cfg(feature = "ip_proxy")]
ip_proxy_map,
out_external_route,
cone_sender,
symmetric_sender,
client_cipher,
server_cipher,
rsa_cipher,
relay,
token,
time: Arc::new(AtomicCell::new(Instant::now())),
head_reserve,
}
}
}
impl ChannelDataHandler {
pub fn handle(
&self,
buf: &mut [u8],
start: usize,
end: usize,
route_key: RouteKey,
context: &Context,
) {
assert_eq!(start, 14);
match self.handle0(&mut buf[..end], &route_key, context) {
Ok(_) => {}
Err(e) => {
log::warn!("{:?}", e);
}
}
}
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 || net_packet.source_ttl() < net_packet.ttl() {
return Ok(());
}
let source = net_packet.source();
context.update_read_time(&source, route_key);
let current_device = self.current_device.load();
let destination = net_packet.destination();
let not_broadcast = !destination.is_broadcast()
&& !destination.is_multicast()
&& destination != current_device.broadcast_address;
if current_device.virtual_ip() != destination
&& !net_packet.is_gateway()
&& not_broadcast
&& !destination.is_unspecified()
{
//校验指纹,不需要解密
self.client_cipher.check_finger(&net_packet)?;
net_packet.set_ttl(net_packet.ttl() - 1);
let ttl = net_packet.ttl();
if ttl > 0 {
// 转发
if let Some(route) = context.route_one(&destination) {
if route.metric <= net_packet.ttl() {
context.try_send_by_key(net_packet.buffer(), &route.route_key())?;
}
} else if (ttl > 1 || destination == current_device.virtual_gateway())
&& source != current_device.virtual_gateway()
{
//网关默认要转发一次,生存时间不够的发到网关也会被丢弃
context.send_main(net_packet.buffer(), current_device.connect_server)?;
}
}
return Ok(());
}
if net_packet.is_gateway() {
if net_packet.protocol() == Protocol::Error
&& net_packet.transport_protocol()
== crate::protocol::error_packet::Protocol::NoKey.into()
{
if let Some(rsa_cipher) = &self.rsa_cipher {
let last = self.time.load();
if last.elapsed() < Duration::from_secs(3)
|| self.time.compare_exchange(last, Instant::now()).is_err()
{
//短时间不重复上传服务端密钥
return Ok(());
}
log::warn!("上传服务端密钥");
secret_handshake_req(
context,
current_device.connect_server,
rsa_cipher,
&self.server_cipher,
self.token.clone(),
route_key,
)?;
}
} else {
//服务端解密
self.server_cipher.decrypt_ipv4(&mut net_packet)?;
let data_len = net_packet.data_len();
self.server_packet_handle(context, current_device, buf, data_len, route_key)?;
}
return Ok(());
}
self.client_cipher.decrypt_ipv4(&mut net_packet)?;
match net_packet.protocol() {
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::Igmp => {
if let Some(igmp_server) = &self.igmp_server {
igmp_server.handle(ipv4.payload(), source)?;
}
return Ok(());
}
ipv4::protocol::Protocol::Icmp => {
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);
//不管加不加密,和接收到的数据长度都一致
self.client_cipher.encrypt_ipv4(&mut net_packet)?;
context.try_send_by_key(net_packet.buffer(), route_key)?;
return Ok(());
}
}
}
_ => {}
}
if not_broadcast && ipv4.destination_ip() != destination {
if self.out_external_route.allow(&ipv4.destination_ip()) {
#[cfg(feature = "ip_proxy")]
if let Some(ip_proxy_map) = &self.ip_proxy_map {
if ip_proxy_map.recv_handle(&mut ipv4, source, destination)? {
return Ok(());
}
}
} else {
log::warn!(
"没有ip代理规则{:?}:{}->{}->{}",
ipv4.protocol(),
source,
destination,
ipv4.destination_ip()
);
return Err(Error::Warn("没有ip代理规则".to_string()));
}
}
//传输协议12字节
self.device_writer.write_ipv4(&mut buf[12..])?;
return Ok(());
}
ip_turn_packet::Protocol::Ipv4Broadcast => {
//客户端不帮忙转发广播包,所以不会出现这种类型的数据
}
ip_turn_packet::Protocol::Unknown(_) => {}
}
}
Protocol::Service => {}
Protocol::Error => {}
Protocol::Control => {
self.control(context, current_device, source, net_packet, route_key)?;
}
Protocol::OtherTurn => {
self.other_turn(context, current_device, source, net_packet, route_key)?;
}
Protocol::UnKnow(e) => {
log::info!("不支持的协议:{}", e);
}
}
Ok(())
}
fn pong_packet(
&self,
gateway: bool,
metric: u8,
context: &Context,
current_device: CurrentDeviceInfo,
source: Ipv4Addr,
pong_packet: control_packet::PongPacket<&[u8]>,
route_key: &RouteKey,
) -> crate::Result<()> {
let current_time = crate::handle::now_time() as u16;
if current_time < pong_packet.time() {
return Ok(());
}
let rt = (current_time - pong_packet.time()) as i64;
let route = Route::from(*route_key, metric, rt);
context.add_route(source, route);
if gateway {
let epoch = self.device_list.lock().0;
if pong_packet.epoch() != epoch {
let mut poll_device = NetPacket::new_encrypt([0; 12 + ENCRYPTION_RESERVED])?;
poll_device.set_source(current_device.virtual_ip());
poll_device.set_destination(source);
poll_device.set_version(Version::V1);
poll_device.set_gateway_flag(true);
poll_device.first_set_ttl(MAX_TTL);
poll_device.set_protocol(Protocol::Service);
poll_device.set_transport_protocol(service_packet::Protocol::PollDeviceList.into());
self.server_cipher.encrypt_ipv4(&mut poll_device)?;
context.send_main(poll_device.buffer(), current_device.connect_server)?;
}
}
Ok(())
}
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(_) => {
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.client_cipher.encrypt_ipv4(&mut net_packet)?;
context.try_send_by_key(net_packet.buffer(), route_key)?;
let route = Route::from(*route_key, metric, 199);
context.add_route_if_absent(source, route);
}
ControlPacket::PongPacket(pong_packet) => {
self.pong_packet(
false,
metric,
context,
current_device,
source,
pong_packet,
route_key,
)?;
}
ControlPacket::PunchRequest => {
if self.relay {
return Ok(());
}
//回应
net_packet.set_transport_protocol(control_packet::Protocol::PunchResponse.into());
net_packet.set_source(current_device.virtual_ip());
net_packet.set_destination(source);
net_packet.first_set_ttl(1);
self.client_cipher.encrypt_ipv4(&mut net_packet)?;
context.try_send_by_key(net_packet.buffer(), route_key)?;
let route = Route::from(*route_key, 1, 199);
context.add_route_if_absent(source, route);
}
ControlPacket::PunchResponse => {
if self.relay {
return Ok(());
}
let route = Route::from(*route_key, 1, 199);
context.add_route_if_absent(source, route);
}
ControlPacket::AddrRequest => match route_key.addr.ip() {
std::net::IpAddr::V4(ipv4) => {
let mut packet = NetPacket::new_encrypt([0; 12 + 6 + ENCRYPTION_RESERVED])?;
packet.set_version(Version::V1);
packet.set_protocol(Protocol::Control);
packet.set_transport_protocol(control_packet::Protocol::AddrResponse.into());
packet.first_set_ttl(MAX_TTL);
packet.set_source(current_device.virtual_ip());
packet.set_destination(source);
let mut addr_packet = control_packet::AddrPacket::new(packet.payload_mut())?;
addr_packet.set_ipv4(ipv4);
addr_packet.set_port(route_key.addr.port());
self.client_cipher.encrypt_ipv4(&mut packet)?;
context.try_send_by_key(packet.buffer(), route_key)?;
}
std::net::IpAddr::V6(_) => {}
},
ControlPacket::AddrResponse(addr_packet) => self
.nat_test
.update_addr(addr_packet.ipv4(), addr_packet.port()),
}
Ok(())
}
fn other_turn(
&self,
context: &Context,
current_device: CurrentDeviceInfo,
source: Ipv4Addr,
net_packet: NetPacket<&mut [u8]>,
route_key: &RouteKey,
) -> crate::Result<()> {
if self.relay {
return Ok(());
}
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| Ipv4Addr::from(v.to_be_bytes()))
.collect();
let local_ipv4 = Some(Ipv4Addr::from(punch_info.local_ip.to_be_bytes()));
let udp_port = punch_info.local_port as u16;
let tcp_port = punch_info.tcp_port as u16;
let ipv6 = if punch_info.ipv6.len() == 16 {
let ipv6: [u8; 16] = punch_info.ipv6.try_into().unwrap();
Some(Ipv6Addr::from(ipv6))
} else {
None
};
let peer_nat_info = NatInfo::new(
public_ips,
punch_info.public_port as u16,
punch_info.public_port_range as u16,
local_ipv4,
ipv6,
udp_port,
tcp_port,
punch_info.nat_type.enum_value_or_default().into(),
);
{
let peer_nat_info = peer_nat_info.clone();
self.peer_nat_info_map.write().insert(source, peer_nat_info);
}
if !punch_info.reply {
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(|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 =
u32::from(nat_info.local_ipv4().unwrap_or(Ipv4Addr::UNSPECIFIED));
punch_reply.local_port = nat_info.udp_port as u32;
if let Some(ipv6) = nat_info.ipv6() {
punch_reply.ipv6 = ipv6.octets().to_vec();
punch_reply.ipv6_port = nat_info.udp_port as u32;
}
let bytes = punch_reply.write_to_bytes()?;
let mut punch_packet =
NetPacket::new_encrypt(vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED])?;
punch_packet.set_version(Version::V1);
punch_packet.set_protocol(Protocol::OtherTurn);
punch_packet.set_transport_protocol(other_turn_packet::Protocol::Punch.into());
punch_packet.first_set_ttl(MAX_TTL);
punch_packet.set_source(current_device.virtual_ip());
punch_packet.set_destination(source);
punch_packet.set_payload(&bytes)?;
if self.punch(source, peer_nat_info) {
self.client_cipher.encrypt_ipv4(&mut punch_packet)?;
context.try_send_by_key(punch_packet.buffer(), route_key)?;
}
} else {
self.punch(source, peer_nat_info);
}
}
other_turn_packet::Protocol::Unknown(e) => {
log::warn!("不支持的转发协议 {:?},source:{:?}", e, source);
}
}
Ok(())
}
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(),
}
}
}
/// 处理服务端数据
impl ChannelDataHandler {
fn server_packet_handle(
&self,
context: &Context,
current_device: CurrentDeviceInfo,
buf: &mut [u8],
data_len: usize,
route_key: &RouteKey,
) -> crate::Result<()> {
let net_packet = NetPacket::new0(data_len, &buf[14..])?;
let source = net_packet.source();
match net_packet.protocol() {
Protocol::Service => {
self.service(context, current_device, net_packet, route_key)?;
}
Protocol::Error => {
self.error(context, current_device, source, net_packet, route_key)?;
}
Protocol::Control => {
self.control_gateway(context, current_device, net_packet, route_key)?;
}
Protocol::IpTurn => {
match ip_turn_packet::Protocol::from(net_packet.transport_protocol()) {
ip_turn_packet::Protocol::Ipv4 => {
let ipv4 = IpV4Packet::new(net_packet.payload())?;
match ipv4.protocol() {
ipv4::protocol::Protocol::Igmp => {
if let Some(igmp_server) = &self.igmp_server {
igmp_server.handle(ipv4.payload(), source)?;
}
return Ok(());
}
ipv4::protocol::Protocol::Icmp => {
if ipv4.destination_ip() == current_device.virtual_ip {
let icmp_packet = icmp::IcmpPacket::new(ipv4.payload())?;
if icmp_packet.kind() == Kind::EchoReply {
self.device_writer.write_ipv4(&mut buf[12..])?;
return Ok(());
}
}
}
_ => {}
}
}
ip_turn_packet::Protocol::Ipv4Broadcast => {}
ip_turn_packet::Protocol::Unknown(_) => {}
}
}
Protocol::OtherTurn => {}
Protocol::UnKnow(_) => {}
}
return Ok(());
}
fn control_gateway(
&self,
context: &Context,
current_device: CurrentDeviceInfo,
net_packet: NetPacket<&[u8]>,
route_key: &RouteKey,
) -> crate::Result<()> {
match ControlPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
ControlPacket::PongPacket(pong_packet) => {
let metric = net_packet.source_ttl() - net_packet.ttl() + 1;
self.pong_packet(
true,
metric,
context,
current_device,
net_packet.source(),
pong_packet,
route_key,
)?;
}
ControlPacket::AddrResponse(addr_packet) => self
.nat_test
.update_addr(addr_packet.ipv4(), addr_packet.port()),
_ => {}
}
Ok(())
}
fn service(
&self,
context: &Context,
current_device: CurrentDeviceInfo,
net_packet: NetPacket<&[u8]>,
route_key: &RouteKey,
) -> crate::Result<()> {
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())?;
if self.nat_test.can_update() {
let context = context.clone();
let nat_test = self.nat_test.clone();
std::thread::spawn(move || {
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(async move {
let local_ipv4 = nat::local_ipv4();
let ipv6 = nat::local_ipv6();
let udp_port = nat_test.nat_info().udp_port;
let tcp_port = nat_test.nat_info().tcp_port;
let nat_info = nat_test
.re_test(
Ipv4Addr::from(response.public_ip),
response.public_port as u16,
local_ipv4,
ipv6,
udp_port,
tcp_port,
)
.await;
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 {
// ip发生变化
log::info!("ip发生变化,old_ip:{:?},new_ip:{:?}", current_ip, new_ip);
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
let old_netmask = current_device.virtual_netmask;
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
let old_gateway = current_device.virtual_gateway();
let virtual_ip = Ipv4Addr::from(response.virtual_ip);
let virtual_gateway = Ipv4Addr::from(response.virtual_gateway);
let virtual_netmask = Ipv4Addr::from(response.virtual_netmask);
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
self.device_writer.change_ip(
virtual_ip,
virtual_netmask,
virtual_gateway,
old_netmask,
old_gateway,
)?;
let new_current_device = CurrentDeviceInfo::new(
virtual_ip,
virtual_gateway,
virtual_netmask,
current_device.connect_server,
);
if let Err(e) = self
.current_device
.compare_exchange(current_device, new_current_device)
{
log::warn!("替换失败:{:?}", e);
}
}
self.connect_status.store(ConnectStatus::Connected);
}
service_packet::Protocol::PollDeviceList => {}
service_packet::Protocol::PushDeviceList => {
let device_list_t = DeviceList::parse_from_bytes(net_packet.payload())?;
let ip_list: Vec<PeerDeviceInfo> = device_list_t
.device_info_list
.into_iter()
.map(|info| {
PeerDeviceInfo::new(
Ipv4Addr::from(info.virtual_ip),
info.name,
info.device_status as u8,
info.client_secret,
)
})
.collect();
let route = Route::from(*route_key, 2, 199);
for x in &ip_list {
if x.status == PeerDeviceStatus::Online {
context.add_route_if_absent(x.virtual_ip, route);
}
}
let mut dev = self.device_list.lock();
if dev.0 != device_list_t.epoch as u16 {
dev.0 = device_list_t.epoch as u16;
dev.1 = ip_list;
}
}
service_packet::Protocol::Unknown(u) => {
log::warn!("未知服务协议:{}", u);
}
_ => {}
}
Ok(())
}
fn error(
&self,
_context: &Context,
current_device: CurrentDeviceInfo,
_source: Ipv4Addr,
net_packet: NetPacket<&[u8]>,
_route_key: &RouteKey,
) -> crate::Result<()> {
log::info!("current_device:{:?}", current_device);
match InErrorPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
InErrorPacket::TokenError => {
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(current_device.virtual_ip)?;
}
InErrorPacket::AddressExhausted => {
//地址用尽
return Err(Error::Stop("IP address has been exhausted".to_string()));
}
InErrorPacket::OtherError(e) => {
log::error!("OtherError {:?}", e.message());
}
InErrorPacket::IpAlreadyExists => {
log::error!("IpAlreadyExists");
}
InErrorPacket::InvalidIp => {
log::error!("InvalidIp");
}
InErrorPacket::NoKey => {}
}
Ok(())
}
}
-262
View File
@@ -1,262 +0,0 @@
use crossbeam_utils::atomic::AtomicCell;
use std::io::{Read, Write};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV6};
use std::time::{Duration, Instant};
use crate::channel::sender::ChannelSender;
use crate::cipher::Cipher;
use crate::handle::PeerDeviceInfo;
use protobuf::Message;
use std::net::TcpStream;
use std::net::UdpSocket;
use crate::proto::message::{RegistrationRequest, RegistrationResponse};
use crate::protocol::body::ENCRYPTION_RESERVED;
use crate::protocol::error_packet::InErrorPacket;
use crate::protocol::{service_packet, NetPacket, Protocol, Version, MAX_TTL};
pub enum ReqEnum {
TokenError,
AddressExhausted,
IpAlreadyExists,
InvalidIp,
Timeout,
ServerError(String),
Other(String),
}
#[derive(Clone, Debug)]
pub struct RegResponse {
pub virtual_ip: Ipv4Addr,
pub virtual_gateway: Ipv4Addr,
pub virtual_netmask: Ipv4Addr,
pub epoch: u16,
pub device_info_list: Vec<PeerDeviceInfo>,
pub public_ip: Ipv4Addr,
pub public_port: u16,
}
///向中继服务器注册,token标识一个虚拟网关,device_id防止多次注册时得到的ip不一致
pub fn registration(
main_channel: &UdpSocket,
main_tcp_channel: Option<&mut TcpStream>,
server_cipher: &Cipher,
server_address: SocketAddr,
token: String,
device_id: String,
name: String,
ip: Ipv4Addr,
client_secret: bool,
) -> Result<RegResponse, ReqEnum> {
let request_packet = registration_request_packet(
server_cipher,
token.clone(),
device_id.clone(),
name.clone(),
ip,
false,
false,
client_secret,
)
.unwrap();
let buf = request_packet.buffer();
let mut recv_buf = [0u8; 10240];
let recv_buf = if let Some(main_tcp_channel) = main_tcp_channel {
let mut vec = vec![0; 4 + buf.len()];
let len = buf.len();
vec[2] = (len >> 8) as u8;
vec[3] = (len & 0xFF) as u8;
vec[4..].copy_from_slice(buf);
if let Err(e) = main_tcp_channel.write_all(&vec) {
return Err(ReqEnum::Other(format!("send error:{}", e)));
}
if let Err(e) = main_tcp_channel.read_exact(&mut recv_buf[..4]) {
return Err(ReqEnum::Other(format!("read error:{}", e)));
}
let len = 4 + (((recv_buf[2] as u16) << 8) | recv_buf[3] as u16) as usize;
if len > recv_buf.len() {
return Err(ReqEnum::Other("too long".to_string()));
}
if let Err(e) = main_tcp_channel.read_exact(&mut recv_buf[4..len]) {
return Err(ReqEnum::Other(format!("read error:{}", e)));
}
&mut recv_buf[4..len]
} else {
let server_address = match server_address {
SocketAddr::V4(ipv4) => SocketAddr::V6(SocketAddrV6::new(
ipv4.ip().to_ipv6_mapped(),
ipv4.port(),
0,
0,
)),
SocketAddr::V6(_) => server_address,
};
if let Err(e) = main_channel.send_to(buf, server_address) {
return Err(ReqEnum::Other(format!("send error:{}", e)));
}
match main_channel.recv_from(&mut recv_buf) {
Ok((len, addr)) => {
if server_address != addr {
log::warn!("请求{:?}和响应{:?}地址不一致", server_address, addr);
}
&mut recv_buf[..len]
}
Err(e) => {
return Err(ReqEnum::Other(format!("receiver error:{}", e)));
}
}
};
let mut net_packet = match NetPacket::new(recv_buf) {
Ok(net_packet) => net_packet,
Err(e) => {
return Err(ReqEnum::ServerError(format!("{}", e)));
}
};
if let Err(e) = server_cipher.decrypt_ipv4(&mut net_packet) {
return Err(ReqEnum::ServerError(format!("decrypt_ipv4 {}", e)));
}
match net_packet.protocol() {
Protocol::Service => {
match service_packet::Protocol::from(net_packet.transport_protocol()) {
service_packet::Protocol::RegistrationResponse => {
match RegistrationResponse::parse_from_bytes(net_packet.payload()) {
Ok(response) => {
let device_info_list: Vec<PeerDeviceInfo> = response
.device_info_list
.into_iter()
.map(|info| {
PeerDeviceInfo::new(
Ipv4Addr::from(info.virtual_ip),
info.name,
info.device_status as u8,
info.client_secret,
)
})
.collect();
Ok(RegResponse {
virtual_ip: Ipv4Addr::from(response.virtual_ip),
virtual_gateway: Ipv4Addr::from(response.virtual_gateway),
virtual_netmask: Ipv4Addr::from(response.virtual_netmask),
epoch: response.epoch as u16,
device_info_list,
public_ip: Ipv4Addr::from(response.public_ip),
public_port: response.public_port as u16,
})
}
Err(_) => Err(ReqEnum::ServerError("invalid data".to_string())),
}
}
_ => Err(ReqEnum::ServerError("invalid data".to_string())),
}
}
Protocol::Error => {
match InErrorPacket::new(net_packet.transport_protocol(), net_packet.payload()) {
Ok(e) => match e {
InErrorPacket::TokenError => Err(ReqEnum::TokenError),
InErrorPacket::Disconnect => {
Err(ReqEnum::ServerError("disconnect".to_string()))
}
InErrorPacket::AddressExhausted => Err(ReqEnum::AddressExhausted),
InErrorPacket::OtherError(e) => match e.message() {
Ok(str) => Err(ReqEnum::ServerError(str)),
Err(e) => Err(ReqEnum::Other(format!("{}", e))),
},
InErrorPacket::IpAlreadyExists => Err(ReqEnum::IpAlreadyExists),
InErrorPacket::InvalidIp => Err(ReqEnum::InvalidIp),
InErrorPacket::NoKey => Err(ReqEnum::ServerError("no key".to_string())),
},
Err(e) => Err(ReqEnum::Other(format!("{}", e))),
}
}
_ => Err(ReqEnum::ServerError("invalid data".to_string())),
}
}
fn registration_request_packet(
server_cipher: &Cipher,
token: String,
device_id: String,
name: String,
ip: Ipv4Addr,
is_fast: bool,
allow_ip_change: bool,
client_secret: bool,
) -> crate::Result<NetPacket<Vec<u8>>> {
let mut request = RegistrationRequest::new();
request.token = token;
request.device_id = device_id;
request.name = name;
request.virtual_ip = ip.into();
request.allow_ip_change = allow_ip_change;
request.is_fast = is_fast;
request.version = crate::VNT_VERSION.to_string();
request.client_secret = client_secret;
let bytes = request.write_to_bytes()?;
let buf = vec![0u8; 12 + bytes.len() + ENCRYPTION_RESERVED];
let mut net_packet = NetPacket::new_encrypt(buf)?;
net_packet.set_version(Version::V1);
net_packet.set_gateway_flag(true);
net_packet.set_protocol(Protocol::Service);
net_packet.set_transport_protocol(service_packet::Protocol::RegistrationRequest.into());
net_packet.first_set_ttl(MAX_TTL);
net_packet.set_payload(&bytes)?;
server_cipher.encrypt_ipv4(&mut net_packet)?;
Ok(net_packet)
}
pub struct Register {
server_cipher: Cipher,
sender: ChannelSender,
server_address: SocketAddr,
token: String,
device_id: String,
name: String,
time: AtomicCell<Instant>,
client_secret: bool,
}
impl Register {
pub fn new(
server_cipher: Cipher,
sender: ChannelSender,
server_address: SocketAddr,
token: String,
device_id: String,
name: String,
client_secret: bool,
) -> Self {
Self {
server_cipher,
sender,
server_address,
token,
device_id,
name,
time: AtomicCell::new(Instant::now()),
client_secret,
}
}
pub fn fast_register(&self, ip: Ipv4Addr) -> crate::Result<()> {
let last = self.time.load();
if last.elapsed() < Duration::from_secs(3)
|| self.time.compare_exchange(last, Instant::now()).is_err()
{
//短时间不重复注册
return Ok(());
}
log::info!("重新连接");
let request_packet = registration_request_packet(
&self.server_cipher,
self.token.clone(),
self.device_id.clone(),
self.name.clone(),
ip,
false,
true,
self.client_secret,
)?;
let buf = request_packet.buffer();
self.sender.send_main(buf, self.server_address)?;
Ok(())
}
}
-260
View File
@@ -1,260 +0,0 @@
use std::sync::Arc;
use std::{io, thread};
use crossbeam_utils::atomic::AtomicCell;
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::channel::sender::ChannelSender;
use crate::cipher::Cipher;
use crate::core::status::VntWorker;
use crate::external_route::ExternalRoute;
use crate::handle::tun_tap::channel_group::{buf_channel_group, BufSenderGroup};
use crate::handle::CurrentDeviceInfo;
use crate::igmp_server::IgmpServer;
#[cfg(feature = "ip_proxy")]
use crate::ip_proxy::IpProxyMap;
use crate::tun_tap_device::{DeviceReader, DeviceWriter};
pub fn start(
worker: VntWorker,
sender: ChannelSender,
device_reader: DeviceReader,
device_writer: DeviceWriter,
igmp_server: Option<IgmpServer>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: Option<ExternalRoute>,
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher,
server_cipher: Cipher,
parallel: usize,
) {
if parallel == 1 {
thread::Builder::new()
.name("tap_handler".into())
.spawn(move || {
if let Err(e) = start_simple(
&sender,
device_reader,
&device_writer,
igmp_server,
current_device,
ip_route,
#[cfg(feature = "ip_proxy")]
ip_proxy_map,
client_cipher,
server_cipher,
) {
log::warn!("tap:{:?}", e);
}
let _ = sender.close();
let _ = device_writer.close();
worker.stop_all();
})
.unwrap();
} else {
let (buf_sender, buf_receiver) = buf_channel_group(parallel);
for buf_receiver in buf_receiver.0 {
let sender = sender.clone();
let device_writer = device_writer.clone();
let igmp_server = igmp_server.clone();
let current_device = current_device.clone();
let ip_route = ip_route.clone();
#[cfg(feature = "ip_proxy")]
let ip_proxy_map = ip_proxy_map.clone();
let client_cipher = client_cipher.clone();
let server_cipher = server_cipher.clone();
thread::spawn(move || {
while let Ok((mut buf, _, len)) = buf_receiver.recv() {
match handle(
&mut buf,
len,
&igmp_server,
&current_device,
&device_writer,
&sender,
&ip_route,
#[cfg(feature = "ip_proxy")]
&ip_proxy_map,
&client_cipher,
&server_cipher,
) {
Ok(_) => {}
Err(e) => {
log::warn!("{:?}", e)
}
}
}
let _ = sender.close();
let _ = device_writer.close();
});
}
thread::Builder::new()
.name("tap_handler".into())
.spawn(move || {
if let Err(e) = start_(&sender, device_reader, buf_sender) {
log::warn!("tap:{:?}", e);
}
let _ = sender.close();
let _ = device_writer.close();
worker.stop_all();
})
.unwrap();
}
}
fn start_(
sender: &ChannelSender,
device_reader: DeviceReader,
mut buf_sender: BufSenderGroup,
) -> io::Result<()> {
loop {
let mut buf = vec![0; 4096];
if sender.is_close() {
return Ok(());
}
let start = 0;
let len = device_reader.read(&mut buf)?;
if !buf_sender.send((buf, start, len)) {
return Err(io::Error::new(
io::ErrorKind::Other,
"tap buf_sender发送失败",
));
}
}
}
fn start_simple(
sender: &ChannelSender,
device_reader: DeviceReader,
device_writer: &DeviceWriter,
igmp_server: Option<IgmpServer>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
ip_route: Option<ExternalRoute>,
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
client_cipher: Cipher,
server_cipher: Cipher,
) -> io::Result<()> {
let mut buf = [0; 4096];
loop {
if sender.is_close() {
return Ok(());
}
let len = device_reader.read(&mut buf)?;
if let Err(e) = handle(
&mut buf,
len,
&igmp_server,
&current_device,
device_writer,
sender,
&ip_route,
#[cfg(feature = "ip_proxy")]
&ip_proxy_map,
&client_cipher,
&server_cipher,
) {
log::warn!("tap handle{:?}", e);
}
}
}
fn handle(
buf: &mut [u8],
len: usize,
igmp_server: &Option<IgmpServer>,
current_device: &AtomicCell<CurrentDeviceInfo>,
device_writer: &DeviceWriter,
sender: &ChannelSender,
ip_route: &Option<ExternalRoute>,
#[cfg(feature = "ip_proxy")] proxy_map: &Option<IpProxyMap>,
client_cipher: &Cipher,
server_cipher: &Cipher,
) -> crate::Result<()> {
let mut ethernet_packet = EthernetPacket::new(&mut buf[..len])?;
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],
!sender_h[5],
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],
!sender_h[5],
234,
]);
out_ethernet_packet.set_destination(sender_h);
device_writer.write_ethernet_tap(&out_ethernet_packet.buffer)?;
}
ethernet::protocol::Protocol::Ipv4 => {
let mut ipv4_packet = IpV4Packet::unchecked(ethernet_packet.payload_mut());
let src_ip = ipv4_packet.source_ip();
let dest_ip = ipv4_packet.destination_ip();
let protocol = ipv4_packet.protocol();
if src_ip == dest_ip {
if 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();
ipv4_packet.set_source_ip(dest_ip);
ipv4_packet.set_destination_ip(src_ip);
ipv4_packet.update_checksum();
let source = ethernet_packet.source().to_vec();
let dest = ethernet_packet.destination().to_vec();
ethernet_packet.set_source(&dest);
ethernet_packet.set_destination(&source);
device_writer.write_ethernet_tap(&ethernet_packet.buffer)?;
}
}
return Ok(());
}
// 以太网帧头部14字节,预留12字节
return crate::handle::tun_tap::base_handle(
sender,
&mut buf[2..],
len - 2,
igmp_server,
current_device,
ip_route,
#[cfg(feature = "ip_proxy")]
proxy_map,
client_cipher,
server_cipher,
);
}
_ => {
// log::warn!("不支持的二层协议:{:?}",p)
}
}
Ok(())
}