修复打洞端口为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) {
|
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()
|
if !ip.is_multicast()
|
||||||
&& !ip.is_broadcast()
|
&& !ip.is_broadcast()
|
||||||
&& !ip.is_unspecified()
|
&& !ip.is_unspecified()
|
||||||
&& !ip.is_loopback()
|
&& !ip.is_loopback()
|
||||||
&& !ip.is_private()
|
&& !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) {
|
if !self.public_ips.contains(&ip) {
|
||||||
self.public_ips.push(ip);
|
self.public_ips.push(ip);
|
||||||
}
|
}
|
||||||
@@ -226,9 +227,8 @@ impl Punch {
|
|||||||
if !self.context.route_table.need_punch(&id) {
|
if !self.context.route_table.need_punch(&id) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
log::info!("nat_info={:?}", nat_info);
|
|
||||||
|
|
||||||
if self.is_tcp {
|
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() {
|
||||||
if self.connect_tcp(buf, ipv6_addr) {
|
if self.connect_tcp(buf, ipv6_addr) {
|
||||||
@@ -321,10 +321,11 @@ impl Punch {
|
|||||||
let is_cone = self.context.is_cone();
|
let is_cone = self.context.is_cone();
|
||||||
let len = nat_info.public_ports.len();
|
let len = nat_info.public_ports.len();
|
||||||
for ip in &nat_info.public_ips {
|
for ip in &nat_info.public_ips {
|
||||||
let addr = SocketAddr::V4(SocketAddrV4::new(
|
let port = nat_info.public_ports[index % len];
|
||||||
*ip,
|
if port == 0 || ip.is_unspecified() {
|
||||||
nat_info.public_ports[index % len],
|
continue;
|
||||||
));
|
}
|
||||||
|
let addr = SocketAddr::V4(SocketAddrV4::new(*ip, port));
|
||||||
self.context.send_main_udp(index, buf, addr)?;
|
self.context.send_main_udp(index, buf, addr)?;
|
||||||
if !is_cone {
|
if !is_cone {
|
||||||
//只有一方是对称,则对称方要使用全部端口发送数据,符合上述计算的概率
|
//只有一方是对称,则对称方要使用全部端口发送数据,符合上述计算的概率
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ impl Vnt {
|
|||||||
let tcp_port = tcp_listener.local_addr()?.port();
|
let tcp_port = tcp_listener.local_addr()?.port();
|
||||||
//nat检测工具
|
//nat检测工具
|
||||||
let nat_test = NatTest::new(
|
let nat_test = NatTest::new(
|
||||||
|
context.channel_num(),
|
||||||
config.stun_server.clone(),
|
config.stun_server.clone(),
|
||||||
local_ipv4,
|
local_ipv4,
|
||||||
local_ipv6,
|
local_ipv6,
|
||||||
|
|||||||
@@ -27,19 +27,19 @@ fn retrieve_nat_type0(
|
|||||||
) {
|
) {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
if nat_test.can_update() {
|
if nat_test.can_update() {
|
||||||
let nat_info = nat_test.nat_info();
|
|
||||||
let local_ipv4 = nat::local_ipv4();
|
let local_ipv4 = nat::local_ipv4();
|
||||||
let local_ipv6 = nat::local_ipv6();
|
let local_ipv6 = nat::local_ipv6();
|
||||||
let nat_info = nat_test.re_test(
|
match nat_test.re_test(local_ipv4, local_ipv6) {
|
||||||
nat_info.public_ports,
|
Ok(nat_info) => {
|
||||||
local_ipv4,
|
log::info!("当前nat信息:{:?}", nat_info);
|
||||||
local_ipv6,
|
if let Err(e) = context.switch(nat_info.nat_type, &udp_socket_sender) {
|
||||||
nat_info.udp_ports,
|
log::warn!("{:?}", e);
|
||||||
nat_info.tcp_port,
|
}
|
||||||
);
|
}
|
||||||
if let Err(e) = context.switch(nat_info.nat_type, &udp_socket_sender) {
|
Err(e) => {
|
||||||
log::warn!("{:?}", e);
|
log::warn!("nat re_test {:?}", e);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-50
@@ -78,6 +78,7 @@ impl Into<NatType> for PunchNatType {
|
|||||||
|
|
||||||
impl NatTest {
|
impl NatTest {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
channel_num: usize,
|
||||||
mut stun_server: Vec<String>,
|
mut stun_server: Vec<String>,
|
||||||
local_ipv4: Option<Ipv4Addr>,
|
local_ipv4: Option<Ipv4Addr>,
|
||||||
ipv6: Option<Ipv6Addr>,
|
ipv6: Option<Ipv6Addr>,
|
||||||
@@ -86,9 +87,11 @@ impl NatTest {
|
|||||||
) -> NatTest {
|
) -> NatTest {
|
||||||
let server = stun_server[0].clone();
|
let server = stun_server[0].clone();
|
||||||
stun_server.resize(3, server);
|
stun_server.resize(3, server);
|
||||||
|
let mut ports = udp_ports.clone();
|
||||||
|
ports.resize(channel_num, 0);
|
||||||
let nat_info = NatInfo::new(
|
let nat_info = NatInfo::new(
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
Vec::new(),
|
ports,
|
||||||
0,
|
0,
|
||||||
local_ipv4,
|
local_ipv4,
|
||||||
ipv6,
|
ipv6,
|
||||||
@@ -115,61 +118,23 @@ impl NatTest {
|
|||||||
self.info.lock().clone()
|
self.info.lock().clone()
|
||||||
}
|
}
|
||||||
pub fn update_addr(&self, index: usize, ip: Ipv4Addr, port: u16) {
|
pub fn update_addr(&self, index: usize, ip: Ipv4Addr, port: u16) {
|
||||||
|
log::info!("update_addr={},{}:{}", index, ip, port);
|
||||||
let mut guard = self.info.lock();
|
let mut guard = self.info.lock();
|
||||||
guard.update_addr(index, ip, port)
|
guard.update_addr(index, ip, port)
|
||||||
}
|
}
|
||||||
pub fn re_test(
|
pub fn re_test(
|
||||||
&self,
|
&self,
|
||||||
public_ports: Vec<u16>,
|
|
||||||
local_ipv4: Option<Ipv4Addr>,
|
local_ipv4: Option<Ipv4Addr>,
|
||||||
ipv6: Option<Ipv6Addr>,
|
ipv6: Option<Ipv6Addr>,
|
||||||
udp_ports: Vec<u16>,
|
) -> io::Result<NatInfo> {
|
||||||
tcp_port: u16,
|
let (nat_type, public_ips, port_range) = stun::stun_test_nat(self.stun_server.clone())?;
|
||||||
) -> NatInfo {
|
let mut guard = self.info.lock();
|
||||||
let info = NatTest::re_test_(
|
guard.nat_type = nat_type;
|
||||||
&self.stun_server,
|
guard.public_ips = public_ips;
|
||||||
public_ports,
|
guard.public_port_range = port_range;
|
||||||
local_ipv4,
|
guard.local_ipv4 = local_ipv4;
|
||||||
ipv6,
|
guard.ipv6 = ipv6;
|
||||||
udp_ports,
|
|
||||||
tcp_port,
|
Ok(guard.clone())
|
||||||
);
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user