[mio] 去除多余代码
This commit is contained in:
@@ -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(())
|
||||
}
|
||||
@@ -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 == ¤t_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;
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
¤t_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, ¤t_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)
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
¤t_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,
|
||||
¤t_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(ðernet_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(())
|
||||
}
|
||||
Reference in New Issue
Block a user