调整打洞

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<()> {
if !self.context.route_table.need_punch(&id) {
log::info!("已打洞成功,无需打洞:{:?}",id);
return Ok(());
}
if self.is_tcp && nat_info.tcp_port != 0 {
//向tcp发起连接
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 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();
}
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
}
self.punch_symmetric(
&self.port_vec[start..end],
buf,
&nat_info.public_ips,
max_k2,
)?;
self.port_index.insert(id, index);
}
NatType::Cone => {
let is_cone = self.context.is_cone();
for index in 0..channel_num {
let len = nat_info.public_ports.len();
'a: for index in 0..nat_info.public_ports.len().min(channel_num) {
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() {
continue;
}
@@ -334,7 +335,7 @@ impl Punch {
}
if !is_cone {
//对称网络数据只发一遍
break;
break 'a;
}
}
}
@@ -348,19 +349,19 @@ impl Punch {
buf: &[u8],
ips: &Vec<Ipv4Addr>,
max: usize,
) -> io::Result<()> {
) -> io::Result<usize> {
let mut count = 0;
for port in ports {
for (index, port) in ports.iter().enumerate() {
for pub_ip in ips {
count += 1;
if count == max {
return Ok(());
return Ok(index);
}
let addr = SocketAddr::V4(SocketAddrV4::new(*pub_ip, *port));
self.context.send_main_udp(0, buf, addr)?;
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 crate::channel::context::Context;
use crate::channel::punch::{NatInfo, Punch};
use crate::channel::punch::{NatInfo, NatType, Punch};
use crate::cipher::Cipher;
use crate::handle::{CurrentDeviceInfo, PeerDeviceInfo};
use crate::nat::NatTest;
@@ -24,32 +24,59 @@ use crate::util::Scheduler;
pub struct PunchSender {
sender_self: SyncSender<(Ipv4Addr, NatInfo)>,
sender_peer: SyncSender<(Ipv4Addr, NatInfo)>,
sender_cone_self: SyncSender<(Ipv4Addr, NatInfo)>,
sender_cone_peer: SyncSender<(Ipv4Addr, NatInfo)>,
}
impl PunchSender {
pub fn send(&self, src_peer: bool, ip: Ipv4Addr, info: NatInfo) -> bool {
log::info!("发送打洞协商消息,是否对端发起:{},ip:{},info:{:?}",src_peer,ip, info);
if src_peer {
self.sender_peer.send((ip, info)).is_ok()
} else {
self.sender_self.send((ip, info)).is_ok()
}
log::info!(
"发送打洞协商消息,是否对端发起:{},ip:{},info:{:?}",
src_peer,
ip,
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 {
receiver_peer: 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) {
let (sender_self, receiver_self) = 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 {
sender_self,
sender_peer,
sender_cone_peer,
sender_cone_self,
},
PunchReceiver {
receiver_peer,
receiver_self,
receiver_cone_peer,
receiver_cone_self,
},
)
}
@@ -73,19 +100,21 @@ pub fn punch(
client_cipher.clone(),
0,
);
let receiver_peer = receiver.receiver_peer;
let receiver_self = receiver.receiver_self;
{
let f = |receiver: Receiver<(Ipv4Addr, NatInfo)>| {
let punch = punch.clone();
let current_device = current_device.clone();
let client_cipher = client_cipher.clone();
thread::spawn(move || {
punch_start(receiver_peer, punch, current_device, client_cipher);
});
}
thread::spawn(move || {
punch_start(receiver_self, punch, current_device, client_cipher);
});
thread::Builder::new()
.name("punch".into())
.spawn(move || {
punch_start(receiver, 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,
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)?;
}
Ok(())
+1 -1
View File
@@ -320,8 +320,8 @@ impl ClientPacketHandler {
punch_packet.set_source(current_device.virtual_ip());
punch_packet.set_destination(source);
punch_packet.set_payload(&bytes)?;
self.client_cipher.encrypt_ipv4(&mut punch_packet)?;
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)?;
}
} else {