mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-06 17:59:11 +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:
Generated
+60
-2
@@ -491,6 +491,12 @@ version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "atomic_refcell"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c"
|
||||
|
||||
[[package]]
|
||||
name = "auto_impl"
|
||||
version = "1.2.1"
|
||||
@@ -1499,6 +1505,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.18.1"
|
||||
@@ -1918,6 +1933,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-new"
|
||||
version = "0.6.0"
|
||||
@@ -1977,13 +2003,36 @@ version = "0.99.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"convert_case 0.4.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
|
||||
dependencies = [
|
||||
"derive_more-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more-impl"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
||||
dependencies = [
|
||||
"convert_case 0.10.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 2.0.87",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
@@ -2153,6 +2202,7 @@ dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"atomic-shim",
|
||||
"atomic_refcell",
|
||||
"auto_impl",
|
||||
"base64 0.22.1",
|
||||
"bitflags 2.8.0",
|
||||
@@ -2171,7 +2221,9 @@ dependencies = [
|
||||
"dashmap",
|
||||
"dbus",
|
||||
"defguard_wireguard_rs",
|
||||
"derivative",
|
||||
"derive_builder",
|
||||
"derive_more 2.1.1",
|
||||
"easytier-rpc-build",
|
||||
"encoding",
|
||||
"flume 0.12.0",
|
||||
@@ -7567,7 +7619,7 @@ checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cssparser",
|
||||
"derive_more",
|
||||
"derive_more 0.99.18",
|
||||
"fxhash",
|
||||
"log",
|
||||
"phf 0.8.0",
|
||||
@@ -9855,6 +9907,12 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_categories"
|
||||
version = "0.1.1"
|
||||
|
||||
+7
-3
@@ -36,6 +36,8 @@ tracing-subscriber = { version = "0.3", features = [
|
||||
"local-time",
|
||||
"time",
|
||||
] }
|
||||
derivative = "2.2.0"
|
||||
derive_more = {version = "2.1.1", features = ["full"]}
|
||||
console-subscriber = { version = "0.4.1", optional = true }
|
||||
thiserror = "1.0"
|
||||
auto_impl = "1.1.0"
|
||||
@@ -64,8 +66,10 @@ zerocopy = { version = "0.7.32", features = ["derive", "simd"] }
|
||||
bytes = "1.5.0"
|
||||
pin-project-lite = "0.2.13"
|
||||
|
||||
atomic_refcell = "0.1.13"
|
||||
|
||||
quinn = { version = "0.11.8", optional = true, features = ["ring"] }
|
||||
quinn-plaintext = { version = "0.3.0", optional = true}
|
||||
quinn-plaintext = { version = "0.3.0", optional = true }
|
||||
|
||||
rustls = { version = "0.23.0", features = [
|
||||
"ring",
|
||||
@@ -86,7 +90,7 @@ http = { version = "1", default-features = false, features = [
|
||||
tokio-rustls = { version = "0.26", default-features = false, optional = true }
|
||||
|
||||
# for tap device
|
||||
tun = { package = "tun-easytier", git="https://github.com/EasyTier/rust-tun", features = [
|
||||
tun = { package = "tun-easytier", git = "https://github.com/EasyTier/rust-tun", features = [
|
||||
"async",
|
||||
], optional = true }
|
||||
# for net ns
|
||||
@@ -266,7 +270,7 @@ windows-sys = { version = "0.52", features = [
|
||||
"Win32_NetworkManagement_Ndis",
|
||||
"Win32_Networking_WinSock",
|
||||
"Win32_Foundation"
|
||||
]}
|
||||
] }
|
||||
winapi = { version = "0.3.9", features = ["impl-default"] }
|
||||
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
|
||||
@@ -196,9 +196,6 @@ core_clap:
|
||||
disable_quic_input:
|
||||
en: "do not allow other nodes to use QUIC to proxy tcp streams to this node. when a node with QUIC proxy enabled accesses this node, the original tcp connection is preserved."
|
||||
zh-CN: "不允许其他节点使用 QUIC 代理 TCP 流到此节点。开启 QUIC 代理的节点访问此节点时,依然使用原始 TCP 连接。"
|
||||
quic_listen_port:
|
||||
en: "the port to listen for quic connections, default is 0 (random port)"
|
||||
zh-CN: "监听 QUIC 连接的端口,默认值为0(随机端口)。"
|
||||
port_forward:
|
||||
en: "forward local port to remote port in virtual network. e.g.: udp://0.0.0.0:12345/10.126.126.1:23456, means forward local udp port 12345 to 10.126.126.1:23456 in the virtual network. can specify multiple."
|
||||
zh-CN: "将本地端口转发到虚拟网络中的远程端口。例如:udp://0.0.0.0:12345/10.126.126.1:23456,表示将本地UDP端口12345转发到虚拟网络中的10.126.126.1:23456。可以指定多个。"
|
||||
@@ -223,9 +220,15 @@ core_clap:
|
||||
disable_relay_kcp:
|
||||
en: "if true, disable relay kcp packets. avoid consuming too many bandwidth. default is false"
|
||||
zh-CN: "如果为true,则禁止节点转发 KCP 数据包,防止过度消耗流量。默认值为false"
|
||||
disable_relay_quic:
|
||||
en: "if true, disable relay quic packets. avoid consuming too many bandwidth. default is false"
|
||||
zh-CN: "如果为true,则禁止节点转发 QUIC 数据包,防止过度消耗流量。默认值为false"
|
||||
enable_relay_foreign_network_kcp:
|
||||
en: "if true, allow relay kcp packets from foreign network. default is false (not forward foreign network kcp packets)"
|
||||
zh-CN: "如果为true,则作为共享节点时也可以转发其他网络的 KCP 数据包。默认值为false(不转发)"
|
||||
enable_relay_foreign_network_quic:
|
||||
en: "if true, allow relay quic packets from foreign network. default is false (not forward foreign network quic packets)"
|
||||
zh-CN: "如果为true,则作为共享节点时也可以转发其他网络的 QUIC 数据包。默认值为false(不转发)"
|
||||
stun_servers:
|
||||
en: "Override default STUN servers; If configured but empty, STUN servers are not used"
|
||||
zh-CN: "覆盖内置的默认 STUN server 列表;如果设置了但是为空,则不使用 STUN servers;如果没设置,则使用默认 STUN server 列表"
|
||||
|
||||
@@ -24,6 +24,7 @@ use super::env_parser;
|
||||
pub type Flags = crate::proto::common::FlagsInConfig;
|
||||
|
||||
pub fn gen_default_flags() -> Flags {
|
||||
#[allow(deprecated)]
|
||||
Flags {
|
||||
default_protocol: "tcp".to_string(),
|
||||
dev_name: "".to_string(),
|
||||
@@ -52,12 +53,15 @@ pub fn gen_default_flags() -> Flags {
|
||||
private_mode: false,
|
||||
enable_quic_proxy: false,
|
||||
disable_quic_input: false,
|
||||
quic_listen_port: 0,
|
||||
disable_relay_quic: false,
|
||||
enable_relay_foreign_network_quic: false,
|
||||
foreign_relay_bps_limit: u64::MAX,
|
||||
multi_thread_count: 2,
|
||||
encryption_algorithm: "aes-gcm".to_string(),
|
||||
disable_sym_hole_punching: false,
|
||||
tld_dns_zone: DEFAULT_ET_DNS_ZONE.to_string(),
|
||||
|
||||
quic_listen_port: u32::MAX,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1584,7 +1588,6 @@ enable_ipv6 = ${ENABLE_IPV6}
|
||||
async fn test_numeric_type_env_vars() {
|
||||
// 设置数字类型的环境变量
|
||||
std::env::set_var("MTU_VALUE", "1400");
|
||||
std::env::set_var("QUIC_PORT", "8080");
|
||||
std::env::set_var("THREAD_COUNT", "4");
|
||||
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
@@ -1597,7 +1600,6 @@ network_secret = "secret"
|
||||
|
||||
[flags]
|
||||
mtu = ${MTU_VALUE}
|
||||
quic_listen_port = ${QUIC_PORT}
|
||||
multi_thread_count = ${THREAD_COUNT}
|
||||
"#;
|
||||
temp_file.write_all(config_content.as_bytes()).unwrap();
|
||||
@@ -1611,10 +1613,6 @@ multi_thread_count = ${THREAD_COUNT}
|
||||
// 验证数字值被正确解析
|
||||
let flags = config.get_flags();
|
||||
assert_eq!(flags.mtu, 1400, "mtu should be 1400");
|
||||
assert_eq!(
|
||||
flags.quic_listen_port, 8080,
|
||||
"quic_listen_port should be 8080"
|
||||
);
|
||||
assert_eq!(
|
||||
flags.multi_thread_count, 4,
|
||||
"multi_thread_count should be 4"
|
||||
@@ -1626,7 +1624,6 @@ multi_thread_count = ${THREAD_COUNT}
|
||||
|
||||
// 清理
|
||||
std::env::remove_var("MTU_VALUE");
|
||||
std::env::remove_var("QUIC_PORT");
|
||||
std::env::remove_var("THREAD_COUNT");
|
||||
}
|
||||
|
||||
|
||||
@@ -92,8 +92,6 @@ pub struct GlobalCtx {
|
||||
|
||||
feature_flags: AtomicCell<PeerFeatureFlag>,
|
||||
|
||||
quic_proxy_port: AtomicCell<Option<u16>>,
|
||||
|
||||
token_bucket_manager: TokenBucketManager,
|
||||
|
||||
stats_manager: Arc<StatsManager>,
|
||||
@@ -149,6 +147,8 @@ impl GlobalCtx {
|
||||
kcp_input: !config_fs.get_flags().disable_kcp_input,
|
||||
no_relay_kcp: config_fs.get_flags().disable_relay_kcp,
|
||||
support_conn_list_sync: true, // Enable selective peer list sync by default
|
||||
quic_input: !config_fs.get_flags().disable_quic_input,
|
||||
no_relay_quic: config_fs.get_flags().disable_relay_quic,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -181,7 +181,6 @@ impl GlobalCtx {
|
||||
p2p_only,
|
||||
|
||||
feature_flags: AtomicCell::new(feature_flags),
|
||||
quic_proxy_port: AtomicCell::new(None),
|
||||
|
||||
token_bucket_manager: TokenBucketManager::new(),
|
||||
|
||||
@@ -393,15 +392,6 @@ impl GlobalCtx {
|
||||
self.feature_flags.store(flags);
|
||||
}
|
||||
|
||||
pub fn get_quic_proxy_port(&self) -> Option<u16> {
|
||||
self.quic_proxy_port.load()
|
||||
}
|
||||
|
||||
pub fn set_quic_proxy_port(&self, port: Option<u16>) {
|
||||
self.acl_filter.set_quic_udp_port(port.unwrap_or(0));
|
||||
self.quic_proxy_port.store(port);
|
||||
}
|
||||
|
||||
pub fn token_bucket_manager(&self) -> &TokenBucketManager {
|
||||
&self.token_bucket_manager
|
||||
}
|
||||
|
||||
+22
-11
@@ -507,14 +507,6 @@ struct NetworkOptions {
|
||||
)]
|
||||
disable_quic_input: Option<bool>,
|
||||
|
||||
#[arg(
|
||||
long,
|
||||
env = "ET_QUIC_LISTEN_PORT",
|
||||
help = t!("core_clap.quic_listen_port").to_string(),
|
||||
num_args = 0..=1,
|
||||
)]
|
||||
quic_listen_port: Option<u16>,
|
||||
|
||||
#[arg(
|
||||
long,
|
||||
env = "ET_PORT_FORWARD",
|
||||
@@ -576,6 +568,15 @@ struct NetworkOptions {
|
||||
)]
|
||||
disable_relay_kcp: Option<bool>,
|
||||
|
||||
#[arg(
|
||||
long,
|
||||
env = "ET_DISABLE_RELAY_QUIC",
|
||||
help = t!("core_clap.disable_relay_quic").to_string(),
|
||||
num_args = 0..=1,
|
||||
default_missing_value = "true"
|
||||
)]
|
||||
disable_relay_quic: Option<bool>,
|
||||
|
||||
#[arg(
|
||||
long,
|
||||
env = "ET_ENABLE_RELAY_FOREIGN_NETWORK_KCP",
|
||||
@@ -585,6 +586,15 @@ struct NetworkOptions {
|
||||
)]
|
||||
enable_relay_foreign_network_kcp: Option<bool>,
|
||||
|
||||
#[arg(
|
||||
long,
|
||||
env = "ET_ENABLE_RELAY_FOREIGN_NETWORK_QUIC",
|
||||
help = t!("core_clap.enable_relay_foreign_network_quic").to_string(),
|
||||
num_args = 0..=1,
|
||||
default_missing_value = "true"
|
||||
)]
|
||||
enable_relay_foreign_network_quic: Option<bool>,
|
||||
|
||||
#[arg(
|
||||
long,
|
||||
env = "ET_STUN_SERVERS",
|
||||
@@ -1030,9 +1040,6 @@ impl NetworkOptions {
|
||||
f.disable_kcp_input = self.disable_kcp_input.unwrap_or(f.disable_kcp_input);
|
||||
f.enable_quic_proxy = self.enable_quic_proxy.unwrap_or(f.enable_quic_proxy);
|
||||
f.disable_quic_input = self.disable_quic_input.unwrap_or(f.disable_quic_input);
|
||||
if let Some(quic_listen_port) = self.quic_listen_port {
|
||||
f.quic_listen_port = quic_listen_port as u32;
|
||||
}
|
||||
f.accept_dns = self.accept_dns.unwrap_or(f.accept_dns);
|
||||
f.private_mode = self.private_mode.unwrap_or(f.private_mode);
|
||||
f.foreign_relay_bps_limit = self
|
||||
@@ -1040,9 +1047,13 @@ impl NetworkOptions {
|
||||
.unwrap_or(f.foreign_relay_bps_limit);
|
||||
f.multi_thread_count = self.multi_thread_count.unwrap_or(f.multi_thread_count);
|
||||
f.disable_relay_kcp = self.disable_relay_kcp.unwrap_or(f.disable_relay_kcp);
|
||||
f.disable_relay_quic = self.disable_relay_quic.unwrap_or(f.disable_relay_quic);
|
||||
f.enable_relay_foreign_network_kcp = self
|
||||
.enable_relay_foreign_network_kcp
|
||||
.unwrap_or(f.enable_relay_foreign_network_kcp);
|
||||
f.enable_relay_foreign_network_quic = self
|
||||
.enable_relay_foreign_network_quic
|
||||
.unwrap_or(f.enable_relay_foreign_network_quic);
|
||||
f.disable_sym_hole_punching = self.disable_sym_hole_punching.unwrap_or(false);
|
||||
// Configure tld_dns_zone: use provided value if set
|
||||
if let Some(tld_dns_zone) = &self.tld_dns_zone {
|
||||
|
||||
@@ -213,6 +213,10 @@ impl TcpProxyForWrappedSrcTrait for TcpProxyForKcpSrc {
|
||||
&self.0
|
||||
}
|
||||
|
||||
fn set_src_modified(hdr: &mut PeerManagerHeader, modified: bool) -> &mut PeerManagerHeader {
|
||||
hdr.set_kcp_src_modified(modified)
|
||||
}
|
||||
|
||||
async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool {
|
||||
let Some(peer_manager) = self.0.get_peer_manager() else {
|
||||
return false;
|
||||
|
||||
+1175
-352
File diff suppressed because it is too large
Load Diff
@@ -12,14 +12,12 @@ use pnet::packet::{
|
||||
use tokio::io::{copy_bidirectional, AsyncRead, AsyncWrite};
|
||||
use tokio_util::io::InspectReader;
|
||||
|
||||
use crate::tunnel::packet_def::PeerManagerHeader;
|
||||
use crate::{
|
||||
common::{acl_processor::PacketInfo, error::Result},
|
||||
gateway::tcp_proxy::{NatDstConnector, TcpProxy},
|
||||
peers::{acl_filter::AclFilter, NicPacketFilter},
|
||||
proto::{
|
||||
acl::{Action, ChainType},
|
||||
api::instance::TcpProxyEntryTransportType,
|
||||
},
|
||||
proto::acl::{Action, ChainType},
|
||||
tunnel::packet_def::ZCPacket,
|
||||
};
|
||||
|
||||
@@ -71,6 +69,7 @@ impl ProxyAclHandler {
|
||||
pub(crate) trait TcpProxyForWrappedSrcTrait: Send + Sync + 'static {
|
||||
type Connector: NatDstConnector;
|
||||
fn get_tcp_proxy(&self) -> &Arc<TcpProxy<Self::Connector>>;
|
||||
fn set_src_modified(hdr: &mut PeerManagerHeader, modified: bool) -> &mut PeerManagerHeader;
|
||||
async fn check_dst_allow_wrapped_input(&self, dst_ip: &Ipv4Addr) -> bool;
|
||||
}
|
||||
|
||||
@@ -142,9 +141,7 @@ impl<C: NatDstConnector, T: TcpProxyForWrappedSrcTrait<Connector = C>> NicPacket
|
||||
|
||||
let hdr = zc_packet.mut_peer_manager_header().unwrap();
|
||||
hdr.to_peer_id = self.get_tcp_proxy().get_my_peer_id().into();
|
||||
if self.get_tcp_proxy().get_transport_type() == TcpProxyEntryTransportType::Kcp {
|
||||
hdr.set_kcp_src_modified(true);
|
||||
}
|
||||
Self::set_src_modified(hdr, true);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ use crate::gateway::icmp_proxy::IcmpProxy;
|
||||
#[cfg(feature = "kcp")]
|
||||
use crate::gateway::kcp_proxy::{KcpProxyDst, KcpProxyDstRpcService, KcpProxySrc};
|
||||
#[cfg(feature = "quic")]
|
||||
use crate::gateway::quic_proxy::{QUICProxyDst, QUICProxyDstRpcService, QUICProxySrc};
|
||||
use crate::gateway::quic_proxy::{QuicProxy, QuicProxyDstRpcService};
|
||||
use crate::gateway::tcp_proxy::{NatDstTcpConnector, TcpProxy, TcpProxyRpcService};
|
||||
use crate::gateway::udp_proxy::UdpProxy;
|
||||
use crate::peer_center::instance::PeerCenterInstance;
|
||||
@@ -541,9 +541,7 @@ pub struct Instance {
|
||||
kcp_proxy_dst: Option<KcpProxyDst>,
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
quic_proxy_src: Option<QUICProxySrc>,
|
||||
#[cfg(feature = "quic")]
|
||||
quic_proxy_dst: Option<QUICProxyDst>,
|
||||
quic_proxy: Option<QuicProxy>,
|
||||
|
||||
peer_center: Arc<PeerCenterInstance>,
|
||||
|
||||
@@ -627,9 +625,7 @@ impl Instance {
|
||||
kcp_proxy_dst: None,
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
quic_proxy_src: None,
|
||||
#[cfg(feature = "quic")]
|
||||
quic_proxy_dst: None,
|
||||
quic_proxy: None,
|
||||
|
||||
peer_center,
|
||||
|
||||
@@ -927,21 +923,6 @@ impl Instance {
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
async fn run_quic_dst(&mut self) -> Result<(), Error> {
|
||||
if self.global_ctx.get_flags().disable_quic_input {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let route = Arc::new(self.peer_manager.get_route());
|
||||
let quic_dst = QUICProxyDst::new(self.global_ctx.clone(), route)?;
|
||||
quic_dst.start().await?;
|
||||
self.global_ctx
|
||||
.set_quic_proxy_port(Some(quic_dst.local_addr()?.port()));
|
||||
self.quic_proxy_dst = Some(quic_dst);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) -> Result<(), Error> {
|
||||
self.listener_manager
|
||||
.lock()
|
||||
@@ -982,19 +963,13 @@ impl Instance {
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
if self.global_ctx.get_flags().enable_quic_proxy {
|
||||
let quic_src = QUICProxySrc::new(self.get_peer_manager()).await;
|
||||
quic_src.start().await;
|
||||
self.quic_proxy_src = Some(quic_src);
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
if !self.global_ctx.get_flags().disable_quic_input {
|
||||
if let Err(e) = self.run_quic_dst().await {
|
||||
eprintln!(
|
||||
"quic input start failed: {:?} (some platforms may not support)",
|
||||
e
|
||||
);
|
||||
{
|
||||
let quic_src = self.global_ctx.get_flags().enable_quic_proxy;
|
||||
let quic_dst = !self.global_ctx.get_flags().disable_quic_input;
|
||||
if quic_src || quic_dst {
|
||||
let mut quic_proxy = QuicProxy::new(self.get_peer_manager());
|
||||
quic_proxy.run(quic_src, quic_dst).await;
|
||||
self.quic_proxy = Some(quic_proxy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1423,20 +1398,21 @@ impl Instance {
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
if let Some(quic_proxy) = self.quic_proxy_src.as_ref() {
|
||||
if let Some(quic_proxy) = self.quic_proxy.as_ref() {
|
||||
if let Some(quic_src) = quic_proxy.src() {
|
||||
tcp_proxy_rpc_services.insert(
|
||||
"quic_src".to_string(),
|
||||
Arc::new(TcpProxyRpcService::new(quic_proxy.get_tcp_proxy())),
|
||||
Arc::new(TcpProxyRpcService::new(quic_src.get_tcp_proxy())),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
if let Some(quic_proxy) = self.quic_proxy_dst.as_ref() {
|
||||
if let Some(quic_dst) = quic_proxy.dst() {
|
||||
tcp_proxy_rpc_services.insert(
|
||||
"quic_dst".to_string(),
|
||||
Arc::new(QUICProxyDstRpcService::new(quic_proxy)),
|
||||
Arc::new(QuicProxyDstRpcService::new(quic_dst)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
tcp_proxy_rpc_services
|
||||
},
|
||||
|
||||
@@ -710,10 +710,6 @@ impl NetworkConfig {
|
||||
flags.disable_quic_input = disable_quic_input;
|
||||
}
|
||||
|
||||
if let Some(quic_listen_port) = self.quic_listen_port {
|
||||
flags.quic_listen_port = quic_listen_port as u32;
|
||||
}
|
||||
|
||||
if let Some(disable_p2p) = self.disable_p2p {
|
||||
flags.disable_p2p = disable_p2p;
|
||||
}
|
||||
@@ -912,7 +908,6 @@ impl NetworkConfig {
|
||||
result.disable_kcp_input = Some(flags.disable_kcp_input);
|
||||
result.enable_quic_proxy = Some(flags.enable_quic_proxy);
|
||||
result.disable_quic_input = Some(flags.disable_quic_input);
|
||||
result.quic_listen_port = Some(flags.quic_listen_port as i32);
|
||||
result.disable_p2p = Some(flags.disable_p2p);
|
||||
result.p2p_only = Some(flags.p2p_only);
|
||||
result.bind_device = Some(flags.bind_device);
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ message NetworkConfig {
|
||||
|
||||
optional bool enable_quic_proxy = 45;
|
||||
optional bool disable_quic_input = 46;
|
||||
optional int32 quic_listen_port = 50;
|
||||
optional int32 quic_listen_port = 50 [deprecated = true];
|
||||
repeated PortForwardConfig port_forwards = 48;
|
||||
|
||||
optional bool disable_sym_hole_punching = 49;
|
||||
|
||||
@@ -41,8 +41,11 @@ message FlagsInConfig {
|
||||
bool enable_quic_proxy = 24;
|
||||
// does this peer allow quic input
|
||||
bool disable_quic_input = 25;
|
||||
// disable relay local network quic packets
|
||||
bool disable_relay_quic = 35;
|
||||
|
||||
// quic listen port
|
||||
uint32 quic_listen_port = 33;
|
||||
uint32 quic_listen_port = 33 [deprecated = true];
|
||||
|
||||
// a global relay limit, only work for foreign network
|
||||
uint64 foreign_relay_bps_limit = 26;
|
||||
@@ -52,6 +55,9 @@ message FlagsInConfig {
|
||||
// enable relay foreign network kcp packets
|
||||
bool enable_relay_foreign_network_kcp = 28;
|
||||
|
||||
// enable relay foreign network quic packets
|
||||
bool enable_relay_foreign_network_quic = 36;
|
||||
|
||||
// encryption algorithm to use, empty string means default (aes-gcm)
|
||||
string encryption_algorithm = 29;
|
||||
|
||||
@@ -208,6 +214,8 @@ message PeerFeatureFlag {
|
||||
bool kcp_input = 3;
|
||||
bool no_relay_kcp = 4;
|
||||
bool support_conn_list_sync = 5;
|
||||
bool quic_input = 6;
|
||||
bool no_relay_quic = 7;
|
||||
}
|
||||
|
||||
enum SocketType {
|
||||
|
||||
@@ -23,7 +23,7 @@ message RoutePeerInfo {
|
||||
|
||||
uint32 network_length = 13;
|
||||
|
||||
optional uint32 quic_port = 14;
|
||||
optional uint32 quic_port = 14 [deprecated = true];
|
||||
optional common.Ipv6Inet ipv6_addr = 15;
|
||||
|
||||
repeated PeerGroupInfo groups = 16;
|
||||
|
||||
@@ -634,22 +634,7 @@ pub async fn subnet_proxy_three_node_test(
|
||||
subnet_proxy_test_tcp(listen_ip, target_ip).await;
|
||||
subnet_proxy_test_udp(listen_ip, target_ip).await;
|
||||
}
|
||||
|
||||
if enable_kcp_proxy && !disable_kcp_input {
|
||||
let metrics = insts[0]
|
||||
.get_global_ctx()
|
||||
.stats_manager()
|
||||
.get_metrics_by_prefix(&MetricName::TcpProxyConnect.to_string());
|
||||
assert_eq!(metrics.len(), 3);
|
||||
for metric in metrics {
|
||||
assert_eq!(1, metric.value);
|
||||
assert!(metric.labels.labels().iter().any(|l| {
|
||||
let t =
|
||||
LabelType::Protocol(TcpProxyEntryTransportType::Kcp.as_str_name().to_string());
|
||||
t.key() == l.key && t.value() == l.value
|
||||
}));
|
||||
}
|
||||
} else if enable_quic_proxy && !disable_quic_input {
|
||||
if enable_quic_proxy && !disable_quic_input {
|
||||
let metrics = insts[0]
|
||||
.get_global_ctx()
|
||||
.stats_manager()
|
||||
@@ -663,6 +648,20 @@ pub async fn subnet_proxy_three_node_test(
|
||||
t.key() == l.key && t.value() == l.value
|
||||
}));
|
||||
}
|
||||
} else if enable_kcp_proxy && !disable_kcp_input {
|
||||
let metrics = insts[0]
|
||||
.get_global_ctx()
|
||||
.stats_manager()
|
||||
.get_metrics_by_prefix(&MetricName::TcpProxyConnect.to_string());
|
||||
assert_eq!(metrics.len(), 3);
|
||||
for metric in metrics {
|
||||
assert_eq!(1, metric.value);
|
||||
assert!(metric.labels.labels().iter().any(|l| {
|
||||
let t =
|
||||
LabelType::Protocol(TcpProxyEntryTransportType::Kcp.as_str_name().to_string());
|
||||
t.key() == l.key && t.value() == l.value
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
// tcp subnet proxy
|
||||
let metrics = insts[2]
|
||||
|
||||
@@ -72,6 +72,8 @@ pub enum PacketType {
|
||||
ForeignNetworkPacket = 10,
|
||||
KcpSrc = 11,
|
||||
KcpDst = 12,
|
||||
QuicSrc = 16,
|
||||
QuicDst = 17,
|
||||
NoiseHandshakeMsg1 = 13,
|
||||
NoiseHandshakeMsg2 = 14,
|
||||
NoiseHandshakeMsg3 = 15,
|
||||
@@ -85,6 +87,7 @@ bitflags::bitflags! {
|
||||
const NO_PROXY = 0b0000_1000;
|
||||
const COMPRESSED = 0b0001_0000;
|
||||
const KCP_SRC_MODIFIED = 0b0010_0000;
|
||||
const QUIC_SRC_MODIFIED = 0b1000_0000;
|
||||
const NOT_SEND_TO_TUN = 0b0100_0000;
|
||||
|
||||
const _ = !0;
|
||||
@@ -206,6 +209,23 @@ impl PeerManagerHeader {
|
||||
.contains(PeerManagerHeaderFlags::KCP_SRC_MODIFIED)
|
||||
}
|
||||
|
||||
pub fn set_quic_src_modified(&mut self, modified: bool) -> &mut Self {
|
||||
let mut flags = PeerManagerHeaderFlags::from_bits(self.flags).unwrap();
|
||||
if modified {
|
||||
flags.insert(PeerManagerHeaderFlags::QUIC_SRC_MODIFIED);
|
||||
} else {
|
||||
flags.remove(PeerManagerHeaderFlags::QUIC_SRC_MODIFIED);
|
||||
}
|
||||
self.flags = flags.bits();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn is_quic_src_modified(&self) -> bool {
|
||||
PeerManagerHeaderFlags::from_bits(self.flags)
|
||||
.unwrap()
|
||||
.contains(PeerManagerHeaderFlags::QUIC_SRC_MODIFIED)
|
||||
}
|
||||
|
||||
pub fn set_not_send_to_tun(&mut self, not_send_to_tun: bool) -> &mut Self {
|
||||
let mut flags = PeerManagerHeaderFlags::from_bits(self.flags).unwrap();
|
||||
if not_send_to_tun {
|
||||
|
||||
@@ -26,12 +26,12 @@ pub fn transport_config() -> Arc<TransportConfig> {
|
||||
let mut config = TransportConfig::default();
|
||||
|
||||
config
|
||||
// .max_concurrent_bidi_streams(VarInt::MAX)
|
||||
.max_concurrent_bidi_streams(u8::MAX.into())
|
||||
.max_concurrent_uni_streams(0u8.into())
|
||||
.keep_alive_interval(Some(Duration::from_secs(5)))
|
||||
.initial_mtu(1200)
|
||||
.min_mtu(1200)
|
||||
.enable_segmentation_offload(false)
|
||||
.enable_segmentation_offload(true)
|
||||
.congestion_controller_factory(Arc::new(BbrConfig::default()));
|
||||
|
||||
Arc::new(config)
|
||||
|
||||
Reference in New Issue
Block a user