调整打洞
This commit is contained in:
+18
-17
@@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(())
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user