diff --git a/vnt/src/channel/punch.rs b/vnt/src/channel/punch.rs index bb20834..cff86db 100644 --- a/vnt/src/channel/punch.rs +++ b/vnt/src/channel/punch.rs @@ -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, max: usize, - ) -> io::Result<()> { + ) -> io::Result { 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()) } } diff --git a/vnt/src/handle/maintain/punch.rs b/vnt/src/handle/maintain/punch.rs index 1beb64b..9b8e688 100644 --- a/vnt/src/handle/maintain/punch.rs +++ b/vnt/src/handle/maintain/punch.rs @@ -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(()) diff --git a/vnt/src/handle/recv_data/client.rs b/vnt/src/handle/recv_data/client.rs index d1459fe..314e02f 100644 --- a/vnt/src/handle/recv_data/client.rs +++ b/vnt/src/handle/recv_data/client.rs @@ -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 {