diff --git a/vnt/src/channel/punch.rs b/vnt/src/channel/punch.rs index 1028d06..36de987 100644 --- a/vnt/src/channel/punch.rs +++ b/vnt/src/channel/punch.rs @@ -97,16 +97,17 @@ impl NatInfo { } } pub fn update_addr(&mut self, index: usize, ip: Ipv4Addr, port: u16) { + if port != 0 { + if let Some(public_port) = self.public_ports.get_mut(index) { + *public_port = port; + } + } if !ip.is_multicast() && !ip.is_broadcast() && !ip.is_unspecified() && !ip.is_loopback() && !ip.is_private() - && port != 0 { - if let Some(public_port) = self.public_ports.get_mut(index) { - *public_port = port; - } if !self.public_ips.contains(&ip) { self.public_ips.push(ip); } @@ -226,9 +227,8 @@ impl Punch { if !self.context.route_table.need_punch(&id) { return Ok(()); } - log::info!("nat_info={:?}", nat_info); - if self.is_tcp { + if self.is_tcp && nat_info.tcp_port != 0 { //向tcp发起连接 if let Some(ipv6_addr) = nat_info.local_tcp_ipv6addr() { if self.connect_tcp(buf, ipv6_addr) { @@ -321,10 +321,11 @@ impl Punch { let is_cone = self.context.is_cone(); let len = nat_info.public_ports.len(); for ip in &nat_info.public_ips { - let addr = SocketAddr::V4(SocketAddrV4::new( - *ip, - nat_info.public_ports[index % len], - )); + let port = nat_info.public_ports[index % len]; + if port == 0 || ip.is_unspecified() { + continue; + } + let addr = SocketAddr::V4(SocketAddrV4::new(*ip, port)); self.context.send_main_udp(index, buf, addr)?; if !is_cone { //只有一方是对称,则对称方要使用全部端口发送数据,符合上述计算的概率 diff --git a/vnt/src/core/conn.rs b/vnt/src/core/conn.rs index c424d7f..1370a02 100644 --- a/vnt/src/core/conn.rs +++ b/vnt/src/core/conn.rs @@ -102,6 +102,7 @@ impl Vnt { let tcp_port = tcp_listener.local_addr()?.port(); //nat检测工具 let nat_test = NatTest::new( + context.channel_num(), config.stun_server.clone(), local_ipv4, local_ipv6, diff --git a/vnt/src/handle/maintain/re_nat_type.rs b/vnt/src/handle/maintain/re_nat_type.rs index 7645626..cc8811c 100644 --- a/vnt/src/handle/maintain/re_nat_type.rs +++ b/vnt/src/handle/maintain/re_nat_type.rs @@ -27,19 +27,19 @@ fn retrieve_nat_type0( ) { thread::spawn(move || { if nat_test.can_update() { - let nat_info = nat_test.nat_info(); let local_ipv4 = nat::local_ipv4(); let local_ipv6 = nat::local_ipv6(); - let nat_info = nat_test.re_test( - nat_info.public_ports, - local_ipv4, - local_ipv6, - nat_info.udp_ports, - nat_info.tcp_port, - ); - if let Err(e) = context.switch(nat_info.nat_type, &udp_socket_sender) { - log::warn!("{:?}", e); - } + match nat_test.re_test(local_ipv4, local_ipv6) { + Ok(nat_info) => { + log::info!("当前nat信息:{:?}", nat_info); + if let Err(e) = context.switch(nat_info.nat_type, &udp_socket_sender) { + log::warn!("{:?}", e); + } + } + Err(e) => { + log::warn!("nat re_test {:?}", e); + } + }; } }); } diff --git a/vnt/src/nat/mod.rs b/vnt/src/nat/mod.rs index eeba527..8a7b42b 100644 --- a/vnt/src/nat/mod.rs +++ b/vnt/src/nat/mod.rs @@ -78,6 +78,7 @@ impl Into for PunchNatType { impl NatTest { pub fn new( + channel_num: usize, mut stun_server: Vec, local_ipv4: Option, ipv6: Option, @@ -86,9 +87,11 @@ impl NatTest { ) -> NatTest { let server = stun_server[0].clone(); stun_server.resize(3, server); + let mut ports = udp_ports.clone(); + ports.resize(channel_num, 0); let nat_info = NatInfo::new( Vec::new(), - Vec::new(), + ports, 0, local_ipv4, ipv6, @@ -115,61 +118,23 @@ impl NatTest { self.info.lock().clone() } pub fn update_addr(&self, index: usize, ip: Ipv4Addr, port: u16) { + log::info!("update_addr={},{}:{}", index, ip, port); let mut guard = self.info.lock(); guard.update_addr(index, ip, port) } pub fn re_test( &self, - public_ports: Vec, local_ipv4: Option, ipv6: Option, - udp_ports: Vec, - tcp_port: u16, - ) -> NatInfo { - let info = NatTest::re_test_( - &self.stun_server, - public_ports, - local_ipv4, - ipv6, - udp_ports, - tcp_port, - ); - log::info!("探测nat类型={:?}", info); - *self.info.lock() = info.clone(); - info - } - fn re_test_( - stun_server: &Vec, - public_ports: Vec, - local_ipv4: Option, - ipv6: Option, - udp_ports: Vec, - tcp_port: u16, - ) -> NatInfo { - return match stun::stun_test_nat(stun_server.clone()) { - Ok((nat_type, public_ips, port_range)) => NatInfo::new( - public_ips, - public_ports, - port_range, - local_ipv4, - ipv6, - udp_ports, - tcp_port, - nat_type, - ), - Err(e) => { - log::warn!("{:?}", e); - NatInfo::new( - Vec::new(), - public_ports, - 0, - local_ipv4, - ipv6, - udp_ports, - tcp_port, - NatType::Cone, - ) - } - }; + ) -> io::Result { + let (nat_type, public_ips, port_range) = stun::stun_test_nat(self.stun_server.clone())?; + let mut guard = self.info.lock(); + guard.nat_type = nat_type; + guard.public_ips = public_ips; + guard.public_port_range = port_range; + guard.local_ipv4 = local_ipv4; + guard.ipv6 = ipv6; + + Ok(guard.clone()) } }