mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-12 04:37:23 +08:00
avoid udp hole punch go through tun (#1155)
This commit is contained in:
@@ -314,8 +314,12 @@ impl PunchBothEasySymHoleClient {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
match try_connect_with_socket(socket.socket.clone(), remote_mapped_addr.into())
|
match try_connect_with_socket(
|
||||||
.await
|
global_ctx.clone(),
|
||||||
|
socket.socket.clone(),
|
||||||
|
remote_mapped_addr.into(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
{
|
{
|
||||||
Ok(tunnel) => {
|
Ok(tunnel) => {
|
||||||
return Ok(Some(tunnel));
|
return Ok(Some(tunnel));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
|
net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@@ -582,7 +582,33 @@ pub(crate) async fn send_symmetric_hole_punch_packet(
|
|||||||
Ok(cur_port_idx % ports.len())
|
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(
|
pub(crate) async fn try_connect_with_socket(
|
||||||
|
global_ctx: ArcGlobalCtx,
|
||||||
socket: Arc<UdpSocket>,
|
socket: Arc<UdpSocket>,
|
||||||
remote_mapped_addr: SocketAddr,
|
remote_mapped_addr: SocketAddr,
|
||||||
) -> Result<Box<dyn Tunnel>, Error> {
|
) -> Result<Box<dyn Tunnel>, Error> {
|
||||||
@@ -596,6 +622,9 @@ pub(crate) async fn try_connect_with_socket(
|
|||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
check_udp_socket_local_addr(global_ctx, remote_mapped_addr).await?;
|
||||||
|
|
||||||
connector
|
connector
|
||||||
.try_connect_with_socket(socket, remote_mapped_addr)
|
.try_connect_with_socket(socket, remote_mapped_addr)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -223,8 +223,12 @@ impl PunchConeHoleClient {
|
|||||||
tracing::debug!(?socket, ?tid, "punched socket found, try connect with it");
|
tracing::debug!(?socket, ?tid, "punched socket found, try connect with it");
|
||||||
|
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
match try_connect_with_socket(socket.socket.clone(), remote_mapped_addr.into())
|
match try_connect_with_socket(
|
||||||
.await
|
global_ctx.clone(),
|
||||||
|
socket.socket.clone(),
|
||||||
|
remote_mapped_addr.into(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
{
|
{
|
||||||
Ok(tunnel) => {
|
Ok(tunnel) => {
|
||||||
tracing::info!(?tunnel, "hole punched");
|
tracing::info!(?tunnel, "hole punched");
|
||||||
|
|||||||
@@ -14,11 +14,15 @@ use tokio::{net::UdpSocket, sync::RwLock};
|
|||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{scoped_task::ScopedTask, stun::StunInfoCollectorTrait, PeerId},
|
common::{
|
||||||
connector::udp_hole_punch::common::{
|
global_ctx::ArcGlobalCtx, scoped_task::ScopedTask, stun::StunInfoCollectorTrait, PeerId,
|
||||||
send_symmetric_hole_punch_packet, try_connect_with_socket, HOLE_PUNCH_PACKET_BODY_LEN,
|
},
|
||||||
|
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,
|
defer,
|
||||||
peers::peer_manager::PeerManager,
|
peers::peer_manager::PeerManager,
|
||||||
proto::{
|
proto::{
|
||||||
@@ -350,6 +354,7 @@ impl PunchSymToConeHoleClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn check_hole_punch_result<T>(
|
async fn check_hole_punch_result<T>(
|
||||||
|
global_ctx: ArcGlobalCtx,
|
||||||
udp_array: &Arc<UdpSocketArray>,
|
udp_array: &Arc<UdpSocketArray>,
|
||||||
packet: &[u8],
|
packet: &[u8],
|
||||||
tid: u32,
|
tid: u32,
|
||||||
@@ -376,7 +381,13 @@ impl PunchSymToConeHoleClient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// if hole punched but tunnel creation failed, need to retry entire process.
|
// 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) => {
|
Ok(tunnel) => {
|
||||||
ret_tunnel.replace(tunnel);
|
ret_tunnel.replace(tunnel);
|
||||||
break;
|
break;
|
||||||
@@ -435,6 +446,7 @@ impl PunchSymToConeHoleClient {
|
|||||||
// try direct connect first
|
// try direct connect first
|
||||||
if self.try_direct_connect.load(Ordering::Relaxed) {
|
if self.try_direct_connect.load(Ordering::Relaxed) {
|
||||||
if let Ok(tunnel) = try_connect_with_socket(
|
if let Ok(tunnel) = try_connect_with_socket(
|
||||||
|
global_ctx.clone(),
|
||||||
Arc::new(UdpSocket::bind("0.0.0.0:0").await?),
|
Arc::new(UdpSocket::bind("0.0.0.0:0").await?),
|
||||||
remote_mapped_addr.into(),
|
remote_mapped_addr.into(),
|
||||||
)
|
)
|
||||||
@@ -478,6 +490,7 @@ impl PunchSymToConeHoleClient {
|
|||||||
))
|
))
|
||||||
.into();
|
.into();
|
||||||
let ret_tunnel = Self::check_hole_punch_result(
|
let ret_tunnel = Self::check_hole_punch_result(
|
||||||
|
global_ctx.clone(),
|
||||||
&udp_array,
|
&udp_array,
|
||||||
&packet,
|
&packet,
|
||||||
tid,
|
tid,
|
||||||
@@ -505,6 +518,7 @@ impl PunchSymToConeHoleClient {
|
|||||||
))
|
))
|
||||||
.into();
|
.into();
|
||||||
let ret_tunnel = Self::check_hole_punch_result(
|
let ret_tunnel = Self::check_hole_punch_result(
|
||||||
|
global_ctx,
|
||||||
&udp_array,
|
&udp_array,
|
||||||
&packet,
|
&packet,
|
||||||
tid,
|
tid,
|
||||||
|
|||||||
Reference in New Issue
Block a user