调整stun处理

This commit is contained in:
lbl8603
2024-05-08 20:20:09 +08:00
parent ff2bbdd837
commit d3dce7a3cc
2 changed files with 54 additions and 61 deletions
+3 -2
View File
@@ -89,8 +89,9 @@ impl NatTest {
udp_ports: Vec<u16>, udp_ports: Vec<u16>,
tcp_port: u16, tcp_port: u16,
) -> NatTest { ) -> NatTest {
let server = stun_server[0].clone(); if stun_server.len() > 5 {
stun_server.resize(3, server); stun_server.truncate(5);
}
let ports = vec![0; udp_ports.len()]; let ports = vec![0; udp_ports.len()];
let nat_info = NatInfo::new( let nat_info = NatInfo::new(
Vec::new(), Vec::new(),
+51 -59
View File
@@ -1,11 +1,12 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::io; use std::io;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::time::Duration; use std::time::Duration;
use crate::channel::punch::NatType; use crate::channel::punch::NatType;
use std::net::UdpSocket; use std::net::UdpSocket;
use stun_format::Attr; use stun_format::Attr;
pub fn stun_test_nat(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv4Addr>, u16)> { pub fn stun_test_nat(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv4Addr>, u16)> {
let mut th = Vec::new(); let mut th = Vec::new();
for _ in 0..2 { for _ in 0..2 {
@@ -36,26 +37,19 @@ pub fn stun_test_nat(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv4
} }
Ok((nat_type, hash_set.into_iter().collect(), port_range)) Ok((nat_type, hash_set.into_iter().collect(), port_range))
} }
pub fn stun_test_nat0(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv4Addr>, u16)> { pub fn stun_test_nat0(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv4Addr>, u16)> {
let udp = UdpSocket::bind("0.0.0.0:0")?; let udp = UdpSocket::bind("0.0.0.0:0")?;
udp.set_read_timeout(Some(Duration::from_millis(500)))?; udp.set_read_timeout(Some(Duration::from_millis(500)))?;
let mut nat_type = NatType::Cone; let mut nat_type = NatType::Cone;
let mut port_range = 0; let mut min_port = u16::MAX;
let mut max_port = 0;
let mut hash_set = HashSet::new(); let mut hash_set = HashSet::new();
let mut pub_addrs = HashSet::new(); let mut pub_addrs = HashSet::new();
for x in &stun_servers { for x in &stun_servers {
match test_nat(&udp, x) { match test_nat(&udp, x) {
Ok((addr, nat_type_t, ip_list_t, port_range_t)) => { Ok(addr) => {
if nat_type_t == NatType::Symmetric { pub_addrs.extend(addr);
nat_type = NatType::Symmetric;
}
for x in ip_list_t {
hash_set.insert(x);
}
if port_range < port_range_t {
port_range = port_range_t;
}
pub_addrs.insert(addr);
} }
Err(e) => { Err(e) => {
log::warn!("stun {} error {:?} ", x, e); log::warn!("stun {} error {:?} ", x, e);
@@ -65,65 +59,63 @@ pub fn stun_test_nat0(stun_servers: Vec<String>) -> io::Result<(NatType, Vec<Ipv
if pub_addrs.len() > 1 { if pub_addrs.len() > 1 {
nat_type = NatType::Symmetric; nat_type = NatType::Symmetric;
} }
Ok((nat_type, hash_set.into_iter().collect(), port_range)) for addr in &pub_addrs {
} if let SocketAddr::V4(addr) = addr {
hash_set.insert(*addr.ip());
fn test_nat( if min_port > addr.port() {
udp: &UdpSocket, min_port = addr.port()
stun_server: &String,
) -> io::Result<(SocketAddr, NatType, Vec<Ipv4Addr>, u16)> {
udp.connect(stun_server)?;
let mut port_range = 0;
let mut hash_set = HashSet::new();
let mut nat_type = NatType::Cone;
// 随便搞个当id
let tid = stun_server.as_ptr() as u128;
let (mapped_addr1, changed_addr1) = test_nat_(&udp, true, true, tid)?;
match mapped_addr1.ip() {
IpAddr::V4(ip) => {
hash_set.insert(ip);
}
IpAddr::V6(_) => {}
}
if udp.connect(changed_addr1).is_ok() {
match test_nat_(&udp, false, false, tid + 1) {
Ok((mapped_addr2, _)) => {
match mapped_addr2.ip() {
IpAddr::V4(ip) => {
hash_set.insert(ip);
if mapped_addr1 != mapped_addr2 {
nat_type = NatType::Symmetric;
}
}
IpAddr::V6(_) => {}
}
port_range = mapped_addr2.port().abs_diff(mapped_addr1.port());
} }
Err(e) => { if max_port < addr.port() {
log::warn!("stun {} error {:?} ", stun_server, e); max_port = addr.port()
} }
} }
} }
log::warn!(
"stun {} mapped_addr {:?} nat_type {:?}",
stun_server,
mapped_addr1,
nat_type
);
Ok(( Ok((
mapped_addr1,
nat_type, nat_type,
hash_set.into_iter().collect(), hash_set.into_iter().collect(),
port_range, max_port - min_port,
)) ))
} }
fn test_nat(udp: &UdpSocket, stun_server: &String) -> io::Result<HashSet<SocketAddr>> {
udp.connect(stun_server)?;
// 随便搞个当id
let tid = stun_server.as_ptr() as u128;
let mut addr = HashSet::new();
let (mapped_addr1, changed_addr1) = test_nat_(&udp, true, true, tid)?;
if mapped_addr1.is_ipv4() {
addr.insert(mapped_addr1);
}
if let Some(changed_addr1) = changed_addr1 {
if udp.connect(changed_addr1).is_ok() {
match test_nat_(&udp, false, false, tid + 1) {
Ok((mapped_addr2, _)) => {
if mapped_addr2.is_ipv4() {
addr.insert(mapped_addr1);
}
}
Err(e) => {
log::warn!("stun {} error {:?} ", stun_server, e);
}
}
}
}
log::info!(
"stun {} mapped_addr {:?} changed_addr {:?}",
stun_server,
addr,
changed_addr1,
);
Ok(addr)
}
fn test_nat_( fn test_nat_(
udp: &UdpSocket, udp: &UdpSocket,
change_ip: bool, change_ip: bool,
change_port: bool, change_port: bool,
tid: u128, tid: u128,
) -> io::Result<(SocketAddr, SocketAddr)> { ) -> io::Result<(SocketAddr, Option<SocketAddr>)> {
for _ in 0..2 { for _ in 0..2 {
let mut buf = [0u8; 28]; let mut buf = [0u8; 28];
let mut msg = stun_format::MsgBuilder::from(buf.as_mut_slice()); let mut msg = stun_format::MsgBuilder::from(buf.as_mut_slice());
@@ -166,11 +158,11 @@ fn test_nat_(
_ => {} _ => {}
} }
if changed_addr.is_some() && mapped_addr.is_some() { if changed_addr.is_some() && mapped_addr.is_some() {
return Ok((mapped_addr.unwrap(), changed_addr.unwrap())); return Ok((mapped_addr.unwrap(), changed_addr));
} }
} }
if let Some(addr) = mapped_addr { if let Some(addr) = mapped_addr {
return Ok((addr, changed_addr.unwrap_or(addr))); return Ok((addr, changed_addr));
} }
} }
Err(io::Error::new(io::ErrorKind::Other, "stun response err")) Err(io::Error::new(io::ErrorKind::Other, "stun response err"))