mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 02:09:06 +00:00
prevent EasyTier-managed IPv6 from being used as underlay connections (#2181)
When a node has public IPv6 addresses allocated by EasyTier, those addresses are installed on the host's network interfaces. The system would then pick them up as candidate source/destination addresses for underlay connections (direct peer, UDP hole punch, bind addresses), causing overlay traffic to loop back into the overlay itself. Add a central predicate is_ip_easytier_managed_ipv6() and apply it at every point where IPv6 addresses are selected for underlay use: - Filter managed IPv6 from DNS-resolved connector addresses, including a UDP socket getsockname check to detect whether the OS would route through the overlay to reach a destination - Skip managed IPv6 in bind address selection and STUN candidate filtering - Strip managed IPv6 from GetIpListResponse RPC so peers never learn them - Pass pre-resolved addresses to tunnel connectors to avoid re-resolution Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -281,6 +281,7 @@ impl TunnelListener for FakeTcpTunnelListener {
|
||||
pub struct FakeTcpTunnelConnector {
|
||||
addr: url::Url,
|
||||
ip_to_if_name: IpToIfNameCache,
|
||||
resolved_addr: Option<SocketAddr>,
|
||||
}
|
||||
|
||||
impl FakeTcpTunnelConnector {
|
||||
@@ -288,6 +289,7 @@ impl FakeTcpTunnelConnector {
|
||||
FakeTcpTunnelConnector {
|
||||
addr,
|
||||
ip_to_if_name: IpToIfNameCache::new(),
|
||||
resolved_addr: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,7 +316,10 @@ fn get_local_ip_for_destination(destination: IpAddr) -> Option<IpAddr> {
|
||||
#[async_trait::async_trait]
|
||||
impl TunnelConnector for FakeTcpTunnelConnector {
|
||||
async fn connect(&mut self) -> Result<Box<dyn Tunnel>, TunnelError> {
|
||||
let remote_addr = SocketAddr::from_url(self.addr.clone(), IpVersion::Both).await?;
|
||||
let remote_addr = match self.resolved_addr {
|
||||
Some(addr) => addr,
|
||||
None => SocketAddr::from_url(self.addr.clone(), IpVersion::Both).await?,
|
||||
};
|
||||
let local_ip = get_local_ip_for_destination(remote_addr.ip())
|
||||
.ok_or(TunnelError::InternalError("Failed to get local ip".into()))?;
|
||||
|
||||
@@ -390,6 +395,10 @@ impl TunnelConnector for FakeTcpTunnelConnector {
|
||||
fn remote_url(&self) -> url::Url {
|
||||
self.addr.clone()
|
||||
}
|
||||
|
||||
fn set_resolved_addr(&mut self, addr: SocketAddr) {
|
||||
self.resolved_addr = Some(addr);
|
||||
}
|
||||
}
|
||||
|
||||
type RecvFut = Pin<Box<dyn Future<Output = Option<(BytesMut, usize)>> + Send + Sync>>;
|
||||
|
||||
Reference in New Issue
Block a user