修复打洞端口为0的问题

This commit is contained in:
lubeilin
2024-03-06 12:55:07 +08:00
parent a4b5b2a028
commit a910d7a673
4 changed files with 38 additions and 71 deletions
+11 -10
View File
@@ -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 {
//只有一方是对称,则对称方要使用全部端口发送数据,符合上述计算的概率
+1
View File
@@ -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,
+11 -11
View File
@@ -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);
}
};
}
});
}
+15 -50
View File
@@ -78,6 +78,7 @@ impl Into<NatType> for PunchNatType {
impl NatTest {
pub fn new(
channel_num: usize,
mut stun_server: Vec<String>,
local_ipv4: Option<Ipv4Addr>,
ipv6: Option<Ipv6Addr>,
@@ -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<u16>,
local_ipv4: Option<Ipv4Addr>,
ipv6: Option<Ipv6Addr>,
udp_ports: Vec<u16>,
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<String>,
public_ports: Vec<u16>,
local_ipv4: Option<Ipv4Addr>,
ipv6: Option<Ipv6Addr>,
udp_ports: Vec<u16>,
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<NatInfo> {
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())
}
}