修复打洞端口为0的问题
This commit is contained in:
+11
-10
@@ -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 {
|
||||
//只有一方是对称,则对称方要使用全部端口发送数据,符合上述计算的概率
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user