调整打洞

This commit is contained in:
lubeilin
2024-03-17 15:41:25 +08:00
parent 67498dfc82
commit ad1df41029
3 changed files with 70 additions and 36 deletions
+18 -17
View File
@@ -226,9 +226,9 @@ impl Punch {
} }
pub fn punch(&mut self, buf: &[u8], id: Ipv4Addr, nat_info: NatInfo) -> io::Result<()> { pub fn punch(&mut self, buf: &[u8], id: Ipv4Addr, nat_info: NatInfo) -> io::Result<()> {
if !self.context.route_table.need_punch(&id) { if !self.context.route_table.need_punch(&id) {
log::info!("已打洞成功,无需打洞:{:?}",id);
return Ok(()); return Ok(());
} }
if self.is_tcp && nat_info.tcp_port != 0 { if self.is_tcp && nat_info.tcp_port != 0 {
//向tcp发起连接 //向tcp发起连接
if let Some(ipv6_addr) = nat_info.local_tcp_ipv6addr() { if let Some(ipv6_addr) = nat_info.local_tcp_ipv6addr() {
@@ -301,25 +301,26 @@ impl Punch {
} }
let start = *self.port_index.entry(id.clone()).or_insert(0); let start = *self.port_index.entry(id.clone()).or_insert(0);
let mut end = start + max_k2; let mut end = start + max_k2;
let mut index = end; if end > self.port_vec.len() {
if end >= self.port_vec.len() {
end = self.port_vec.len(); end = self.port_vec.len();
}
let mut index = start
+ self.punch_symmetric(
&self.port_vec[start..end],
buf,
&nat_info.public_ips,
max_k2,
)?;
if index >= self.port_vec.len() {
index = 0 index = 0
} }
self.punch_symmetric(
&self.port_vec[start..end],
buf,
&nat_info.public_ips,
max_k2,
)?;
self.port_index.insert(id, index); self.port_index.insert(id, index);
} }
NatType::Cone => { NatType::Cone => {
let is_cone = self.context.is_cone(); let is_cone = self.context.is_cone();
for index in 0..channel_num { 'a: for index in 0..nat_info.public_ports.len().min(channel_num) {
let len = nat_info.public_ports.len();
for ip in &nat_info.public_ips { for ip in &nat_info.public_ips {
let port = nat_info.public_ports[index % len]; let port = nat_info.public_ports[index];
if port == 0 || ip.is_unspecified() { if port == 0 || ip.is_unspecified() {
continue; continue;
} }
@@ -334,7 +335,7 @@ impl Punch {
} }
if !is_cone { if !is_cone {
//对称网络数据只发一遍 //对称网络数据只发一遍
break; break 'a;
} }
} }
} }
@@ -348,19 +349,19 @@ impl Punch {
buf: &[u8], buf: &[u8],
ips: &Vec<Ipv4Addr>, ips: &Vec<Ipv4Addr>,
max: usize, max: usize,
) -> io::Result<()> { ) -> io::Result<usize> {
let mut count = 0; let mut count = 0;
for port in ports { for (index, port) in ports.iter().enumerate() {
for pub_ip in ips { for pub_ip in ips {
count += 1; count += 1;
if count == max { if count == max {
return Ok(()); return Ok(index);
} }
let addr = SocketAddr::V4(SocketAddrV4::new(*pub_ip, *port)); let addr = SocketAddr::V4(SocketAddrV4::new(*pub_ip, *port));
self.context.send_main_udp(0, buf, addr)?; self.context.send_main_udp(0, buf, addr)?;
thread::sleep(Duration::from_millis(2)); thread::sleep(Duration::from_millis(2));
} }
} }
Ok(()) Ok(ports.len())
} }
} }
+51 -18
View File
@@ -11,7 +11,7 @@ use protobuf::Message;
use rand::prelude::SliceRandom; use rand::prelude::SliceRandom;
use crate::channel::context::Context; use crate::channel::context::Context;
use crate::channel::punch::{NatInfo, Punch}; use crate::channel::punch::{NatInfo, NatType, Punch};
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo}; use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest; use crate::nat::NatTest;
@@ -24,32 +24,59 @@ use crate::util::Scheduler;
pub struct PunchSender { pub struct PunchSender {
sender_self: SyncSender<(Ipv4Addr, NatInfo)>, sender_self: SyncSender<(Ipv4Addr, NatInfo)>,
sender_peer: SyncSender<(Ipv4Addr, NatInfo)>, sender_peer: SyncSender<(Ipv4Addr, NatInfo)>,
sender_cone_self: SyncSender<(Ipv4Addr, NatInfo)>,
sender_cone_peer: SyncSender<(Ipv4Addr, NatInfo)>,
} }
impl PunchSender { impl PunchSender {
pub fn send(&self, src_peer: bool, ip: Ipv4Addr, info: NatInfo) -> bool { pub fn send(&self, src_peer: bool, ip: Ipv4Addr, info: NatInfo) -> bool {
log::info!("发送打洞协商消息,是否对端发起:{},ip:{},info:{:?}",src_peer,ip, info); log::info!(
if src_peer { "发送打洞协商消息,是否对端发起:{},ip:{},info:{:?}",
self.sender_peer.send((ip, info)).is_ok() src_peer,
} else { ip,
self.sender_self.send((ip, info)).is_ok() info
} );
let sender = match info.nat_type {
NatType::Symmetric => {
if src_peer {
&self.sender_peer
} else {
&self.sender_self
}
}
NatType::Cone => {
if src_peer {
&self.sender_cone_peer
} else {
&self.sender_cone_self
}
}
};
sender.try_send((ip, info)).is_ok()
} }
} }
pub struct PunchReceiver { pub struct PunchReceiver {
receiver_peer: Receiver<(Ipv4Addr, NatInfo)>, receiver_peer: Receiver<(Ipv4Addr, NatInfo)>,
receiver_self: Receiver<(Ipv4Addr, NatInfo)>, receiver_self: Receiver<(Ipv4Addr, NatInfo)>,
receiver_cone_peer: Receiver<(Ipv4Addr, NatInfo)>,
receiver_cone_self: Receiver<(Ipv4Addr, NatInfo)>,
} }
pub fn punch_channel() -> (PunchSender, PunchReceiver) { pub fn punch_channel() -> (PunchSender, PunchReceiver) {
let (sender_self, receiver_self) = sync_channel(1); let (sender_self, receiver_self) = sync_channel(1);
let (sender_peer, receiver_peer) = sync_channel(1); let (sender_peer, receiver_peer) = sync_channel(1);
let (sender_cone_peer, receiver_cone_peer) = sync_channel(1);
let (sender_cone_self, receiver_cone_self) = sync_channel(1);
( (
PunchSender { PunchSender {
sender_self, sender_self,
sender_peer, sender_peer,
sender_cone_peer,
sender_cone_self,
}, },
PunchReceiver { PunchReceiver {
receiver_peer, receiver_peer,
receiver_self, receiver_self,
receiver_cone_peer,
receiver_cone_self,
}, },
) )
} }
@@ -73,19 +100,21 @@ pub fn punch(
client_cipher.clone(), client_cipher.clone(),
0, 0,
); );
let receiver_peer = receiver.receiver_peer; let f = |receiver: Receiver<(Ipv4Addr, NatInfo)>| {
let receiver_self = receiver.receiver_self;
{
let punch = punch.clone(); let punch = punch.clone();
let current_device = current_device.clone(); let current_device = current_device.clone();
let client_cipher = client_cipher.clone(); let client_cipher = client_cipher.clone();
thread::spawn(move || { thread::Builder::new()
punch_start(receiver_peer, punch, current_device, client_cipher); .name("punch".into())
}); .spawn(move || {
} punch_start(receiver, punch, current_device, client_cipher);
thread::spawn(move || { })
punch_start(receiver_self, punch, current_device, client_cipher); .expect("punch");
}); };
f(receiver.receiver_peer);
f(receiver.receiver_self);
f(receiver.receiver_cone_peer);
f(receiver.receiver_cone_self);
} }
/// 接收打洞消息,配合对端打洞 /// 接收打洞消息,配合对端打洞
@@ -199,7 +228,11 @@ fn punch0(
&nat_info, &nat_info,
info.virtual_ip, info.virtual_ip,
)?; )?;
log::info!("发起打洞协商请求,目标:{:?},{:?}", info.virtual_ip, nat_info); log::info!(
"发起打洞协商请求,目标:{:?},{:?}",
info.virtual_ip,
nat_info
);
context.send_default(packet.buffer(), current_device.connect_server)?; context.send_default(packet.buffer(), current_device.connect_server)?;
} }
Ok(()) Ok(())
+1 -1
View File
@@ -320,8 +320,8 @@ impl ClientPacketHandler {
punch_packet.set_source(current_device.virtual_ip()); punch_packet.set_source(current_device.virtual_ip());
punch_packet.set_destination(source); punch_packet.set_destination(source);
punch_packet.set_payload(&bytes)?; punch_packet.set_payload(&bytes)?;
self.client_cipher.encrypt_ipv4(&mut punch_packet)?;
if self.punch_sender.send(true, source, peer_nat_info) { if self.punch_sender.send(true, source, peer_nat_info) {
self.client_cipher.encrypt_ipv4(&mut punch_packet)?;
context.send_by_key(punch_packet.buffer(), route_key)?; context.send_by_key(punch_packet.buffer(), route_key)?;
} }
} else { } else {