mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 02:09:06 +00:00
refactor: handle quic proxy internally instead of use external udp port (#1743)
* deprecate quic_listen_port, add disable_relay_quic and enable_relay_foreign_network_quic * add set_src_modified to TcpProxyForWrappedSrcTrait * prioritize quic over kcp
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::sync::atomic::{AtomicU16, Ordering};
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::time::Instant;
|
||||
use std::{
|
||||
net::IpAddr,
|
||||
@@ -59,7 +59,6 @@ pub struct AclFilter {
|
||||
// Use ArcSwap for lock-free atomic replacement during hot reload
|
||||
acl_processor: ArcSwap<AclProcessor>,
|
||||
acl_enabled: Arc<AtomicBool>,
|
||||
quic_udp_port: AtomicU16,
|
||||
|
||||
// Track allowed outbound packets and automatically allow their corresponding inbound response
|
||||
// packets, even if they would normally be dropped by ACL rules
|
||||
@@ -80,7 +79,6 @@ impl AclFilter {
|
||||
Self {
|
||||
acl_processor: ArcSwap::from(Arc::new(AclProcessor::new(Acl::default()))),
|
||||
acl_enabled: Arc::new(AtomicBool::new(false)),
|
||||
quic_udp_port: AtomicU16::new(0),
|
||||
outbound_allow_records,
|
||||
clean_task: tokio::spawn(async move {
|
||||
let max_life = std::time::Duration::from_secs(30);
|
||||
@@ -295,40 +293,6 @@ impl AclFilter {
|
||||
processor.increment_stat(AclStatKey::PacketsTotal);
|
||||
}
|
||||
|
||||
fn check_is_quic_packet(
|
||||
&self,
|
||||
packet_info: &PacketInfo,
|
||||
my_ipv4: &Option<Ipv4Addr>,
|
||||
my_ipv6: &Option<Ipv6Addr>,
|
||||
) -> bool {
|
||||
if packet_info.protocol != Protocol::Udp {
|
||||
return false;
|
||||
}
|
||||
|
||||
let quic_port = self.get_quic_udp_port();
|
||||
if quic_port == 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// quic input
|
||||
if packet_info.dst_port == Some(quic_port)
|
||||
&& (packet_info.dst_ip == my_ipv4.unwrap_or(Ipv4Addr::UNSPECIFIED)
|
||||
|| packet_info.dst_ip == my_ipv6.unwrap_or(Ipv6Addr::UNSPECIFIED))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// quic output
|
||||
if packet_info.src_port == Some(quic_port)
|
||||
&& (packet_info.src_ip == my_ipv4.unwrap_or(Ipv4Addr::UNSPECIFIED)
|
||||
|| packet_info.src_ip == my_ipv6.unwrap_or(Ipv6Addr::UNSPECIFIED))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Common ACL processing logic
|
||||
pub fn process_packet_with_acl(
|
||||
&self,
|
||||
@@ -360,10 +324,6 @@ impl AclFilter {
|
||||
}
|
||||
};
|
||||
|
||||
if self.check_is_quic_packet(&packet_info, &my_ipv4, &my_ipv6) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let chain_type = if is_in {
|
||||
if packet_info.dst_ip == my_ipv4.unwrap_or(Ipv4Addr::UNSPECIFIED)
|
||||
|| packet_info.dst_ip == my_ipv6.unwrap_or(Ipv6Addr::UNSPECIFIED)
|
||||
@@ -424,12 +384,4 @@ impl AclFilter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_quic_udp_port(&self) -> u16 {
|
||||
self.quic_udp_port.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub fn set_quic_udp_port(&self, port: u16) {
|
||||
self.quic_udp_port.store(port, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,7 @@ impl ForeignNetworkEntry {
|
||||
|
||||
let mut flags = config.get_flags();
|
||||
flags.disable_relay_kcp = !global_ctx.get_flags().enable_relay_foreign_network_kcp;
|
||||
flags.disable_relay_quic = !global_ctx.get_flags().enable_relay_foreign_network_quic;
|
||||
config.set_flags(flags);
|
||||
|
||||
config.set_mapped_listeners(Some(global_ctx.config.get_mapped_listeners()));
|
||||
|
||||
@@ -1489,6 +1489,54 @@ impl PeerManager {
|
||||
true
|
||||
}
|
||||
|
||||
pub async fn check_allow_quic_to_dst(&self, dst_ip: &IpAddr) -> bool {
|
||||
let route = self.get_route();
|
||||
let Some(dst_peer_id) = route.get_peer_id_by_ip(dst_ip).await else {
|
||||
return false;
|
||||
};
|
||||
let Some(peer_info) = route.get_peer_info(dst_peer_id).await else {
|
||||
return false;
|
||||
};
|
||||
|
||||
// check dst allow quic input
|
||||
if !peer_info
|
||||
.feature_flag
|
||||
.map(|x| x.quic_input)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let next_hop_policy = Self::get_next_hop_policy(self.global_ctx.get_flags().latency_first);
|
||||
// check relay node allow relay quic.
|
||||
let Some(next_hop_id) = route
|
||||
.get_next_hop_with_policy(dst_peer_id, next_hop_policy)
|
||||
.await
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if next_hop_id == dst_peer_id {
|
||||
// dst p2p, no need to relay
|
||||
return true;
|
||||
}
|
||||
|
||||
let Some(next_hop_info) = route.get_peer_info(next_hop_id).await else {
|
||||
return false;
|
||||
};
|
||||
|
||||
// check next hop allow quic relay
|
||||
if next_hop_info
|
||||
.feature_flag
|
||||
.map(|x| x.no_relay_quic)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub async fn update_exit_nodes(&self) {
|
||||
let exit_nodes = self.global_ctx.config.get_exit_nodes();
|
||||
*self.exit_nodes.write().await = exit_nodes;
|
||||
|
||||
@@ -123,6 +123,7 @@ fn is_foreign_network_info_newer(
|
||||
}
|
||||
|
||||
impl RoutePeerInfo {
|
||||
#[allow(deprecated)]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
peer_id: 0,
|
||||
@@ -141,9 +142,10 @@ impl RoutePeerInfo {
|
||||
feature_flag: None,
|
||||
peer_route_id: 0,
|
||||
network_length: 24,
|
||||
quic_port: None,
|
||||
ipv6_addr: None,
|
||||
groups: Vec::new(),
|
||||
|
||||
quic_port: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,10 +193,11 @@ impl RoutePeerInfo {
|
||||
.map(|x| x.network_length() as u32)
|
||||
.unwrap_or(24),
|
||||
|
||||
quic_port: global_ctx.get_quic_proxy_port().map(|x| x as u32),
|
||||
ipv6_addr: global_ctx.get_ipv6().map(|x| x.into()),
|
||||
|
||||
groups: global_ctx.get_acl_groups(my_peer_id),
|
||||
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user