avoid udp hole punch go through tun (#1155)
Some checks failed
EasyTier Core / pre_job (push) Has been cancelled
EasyTier GUI / pre_job (push) Has been cancelled
EasyTier Mobile / pre_job (push) Has been cancelled
EasyTier OHOS / pre_job (push) Has been cancelled
EasyTier Test / pre_job (push) Has been cancelled
EasyTier Core / build_web (push) Has been cancelled
EasyTier Core / build (freebsd-13.2-x86_64, 13.2, ubuntu-22.04, x86_64-unknown-freebsd) (push) Has been cancelled
EasyTier Core / build (linux-aarch64, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-arm, ubuntu-22.04, arm-unknown-linux-musleabi) (push) Has been cancelled
EasyTier Core / build (linux-armhf, ubuntu-22.04, arm-unknown-linux-musleabihf) (push) Has been cancelled
EasyTier Core / build (linux-armv7, ubuntu-22.04, armv7-unknown-linux-musleabi) (push) Has been cancelled
EasyTier Core / build (linux-armv7hf, ubuntu-22.04, armv7-unknown-linux-musleabihf) (push) Has been cancelled
EasyTier Core / build (linux-loongarch64, ubuntu-24.04, loongarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-mips, ubuntu-22.04, mips-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-mipsel, ubuntu-22.04, mipsel-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-x86_64, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (macos-aarch64, macos-latest, aarch64-apple-darwin) (push) Has been cancelled
EasyTier Core / build (macos-x86_64, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
EasyTier Core / build (windows-arm64, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / build (windows-i686, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / build (windows-x86_64, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / core-result (push) Has been cancelled
EasyTier Core / magisk_build (push) Has been cancelled
EasyTier GUI / build-gui (linux-aarch64, aarch64-unknown-linux-gnu, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier GUI / build-gui (linux-x86_64, x86_64-unknown-linux-gnu, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Has been cancelled
EasyTier GUI / build-gui (macos-aarch64, aarch64-apple-darwin, macos-latest, aarch64-apple-darwin) (push) Has been cancelled
EasyTier GUI / build-gui (macos-x86_64, x86_64-apple-darwin, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
EasyTier GUI / build-gui (windows-arm64, aarch64-pc-windows-msvc, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / build-gui (windows-i686, i686-pc-windows-msvc, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / build-gui (windows-x86_64, x86_64-pc-windows-msvc, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / gui-result (push) Has been cancelled
EasyTier Mobile / build-mobile (android, ubuntu-22.04, android) (push) Has been cancelled
EasyTier Mobile / mobile-result (push) Has been cancelled
EasyTier OHOS / build-ohos (push) Has been cancelled
EasyTier Test / test (push) Has been cancelled

This commit is contained in:
Sijie.Sun
2025-07-26 14:39:03 +08:00
committed by GitHub
parent 354a4e1d7b
commit 7dc5988620
4 changed files with 61 additions and 10 deletions

View File

@@ -314,8 +314,12 @@ impl PunchBothEasySymHoleClient {
);
for _ in 0..2 {
match try_connect_with_socket(socket.socket.clone(), remote_mapped_addr.into())
.await
match try_connect_with_socket(
global_ctx.clone(),
socket.socket.clone(),
remote_mapped_addr.into(),
)
.await
{
Ok(tunnel) => {
return Ok(Some(tunnel));

View File

@@ -1,5 +1,5 @@
use std::{
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4},
sync::Arc,
time::Duration,
};
@@ -582,7 +582,33 @@ pub(crate) async fn send_symmetric_hole_punch_packet(
Ok(cur_port_idx % ports.len())
}
async fn check_udp_socket_local_addr(
global_ctx: ArcGlobalCtx,
remote_mapped_addr: SocketAddr,
) -> Result<(), Error> {
let socket = UdpSocket::bind("0.0.0.0:0").await?;
socket.connect(remote_mapped_addr).await?;
if let Ok(local_addr) = socket.local_addr() {
// local_addr should not be equal to virtual ipv4 or virtual ipv6
match local_addr.ip() {
IpAddr::V4(ip) => {
if global_ctx.get_ipv4().map(|ip| ip.address()) == Some(ip) {
return Err(anyhow::anyhow!("local address is virtual ipv4").into());
}
}
IpAddr::V6(ip) => {
if global_ctx.get_ipv6().map(|ip| ip.address()) == Some(ip) {
return Err(anyhow::anyhow!("local address is virtual ipv6").into());
}
}
}
}
Ok(())
}
pub(crate) async fn try_connect_with_socket(
global_ctx: ArcGlobalCtx,
socket: Arc<UdpSocket>,
remote_mapped_addr: SocketAddr,
) -> Result<Box<dyn Tunnel>, Error> {
@@ -596,6 +622,9 @@ pub(crate) async fn try_connect_with_socket(
.parse()
.unwrap(),
);
check_udp_socket_local_addr(global_ctx, remote_mapped_addr).await?;
connector
.try_connect_with_socket(socket, remote_mapped_addr)
.await

View File

@@ -223,8 +223,12 @@ impl PunchConeHoleClient {
tracing::debug!(?socket, ?tid, "punched socket found, try connect with it");
for _ in 0..2 {
match try_connect_with_socket(socket.socket.clone(), remote_mapped_addr.into())
.await
match try_connect_with_socket(
global_ctx.clone(),
socket.socket.clone(),
remote_mapped_addr.into(),
)
.await
{
Ok(tunnel) => {
tracing::info!(?tunnel, "hole punched");

View File

@@ -14,11 +14,15 @@ use tokio::{net::UdpSocket, sync::RwLock};
use tracing::Level;
use crate::{
common::{scoped_task::ScopedTask, stun::StunInfoCollectorTrait, PeerId},
connector::udp_hole_punch::common::{
send_symmetric_hole_punch_packet, try_connect_with_socket, HOLE_PUNCH_PACKET_BODY_LEN,
common::{
global_ctx::ArcGlobalCtx, scoped_task::ScopedTask, stun::StunInfoCollectorTrait, PeerId,
},
connector::udp_hole_punch::{
common::{
send_symmetric_hole_punch_packet, try_connect_with_socket, HOLE_PUNCH_PACKET_BODY_LEN,
},
handle_rpc_result,
},
connector::udp_hole_punch::handle_rpc_result,
defer,
peers::peer_manager::PeerManager,
proto::{
@@ -350,6 +354,7 @@ impl PunchSymToConeHoleClient {
}
async fn check_hole_punch_result<T>(
global_ctx: ArcGlobalCtx,
udp_array: &Arc<UdpSocketArray>,
packet: &[u8],
tid: u32,
@@ -376,7 +381,13 @@ impl PunchSymToConeHoleClient {
};
// if hole punched but tunnel creation failed, need to retry entire process.
match try_connect_with_socket(socket.socket.clone(), remote_mapped_addr.into()).await {
match try_connect_with_socket(
global_ctx.clone(),
socket.socket.clone(),
remote_mapped_addr.into(),
)
.await
{
Ok(tunnel) => {
ret_tunnel.replace(tunnel);
break;
@@ -435,6 +446,7 @@ impl PunchSymToConeHoleClient {
// try direct connect first
if self.try_direct_connect.load(Ordering::Relaxed) {
if let Ok(tunnel) = try_connect_with_socket(
global_ctx.clone(),
Arc::new(UdpSocket::bind("0.0.0.0:0").await?),
remote_mapped_addr.into(),
)
@@ -478,6 +490,7 @@ impl PunchSymToConeHoleClient {
))
.into();
let ret_tunnel = Self::check_hole_punch_result(
global_ctx.clone(),
&udp_array,
&packet,
tid,
@@ -505,6 +518,7 @@ impl PunchSymToConeHoleClient {
))
.into();
let ret_tunnel = Self::check_hole_punch_result(
global_ctx,
&udp_array,
&packet,
tid,