调整stun处理
This commit is contained in:
+3
-2
@@ -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
@@ -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"))
|
||||||
|
|||||||
Reference in New Issue
Block a user