From cdedaf3f63b27828ad537310071f39e3976a60e4 Mon Sep 17 00:00:00 2001 From: Luna Yao <40349250+ZnqbuZ@users.noreply.github.com> Date: Fri, 30 Jan 2026 03:21:59 +0100 Subject: [PATCH] refactor(quic): remove quinn encryption (#1831) * use quinn-plaintext * remove server_cert in QUICTunnelListener * remove some customized transport config * leave max_concurrent_bidi_streams as default Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Cargo.lock | 13 +++++ easytier/Cargo.toml | 4 +- easytier/src/gateway/quic_proxy.rs | 6 +-- easytier/src/tunnel/quic.rs | 85 +++++++++++++++--------------- 4 files changed, 62 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1496055c..8053697f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2217,6 +2217,7 @@ dependencies = [ "prost-reflect-build", "prost-types", "quinn", + "quinn-plaintext", "rand 0.8.5", "rcgen", "regex", @@ -6508,6 +6509,18 @@ dependencies = [ "web-time", ] +[[package]] +name = "quinn-plaintext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e617feaeb6493018fa35fc47ae8b630ac8903d8159e9e747018841b99bad3d" +dependencies = [ + "bytes", + "quinn-proto", + "seahash", + "tracing", +] + [[package]] name = "quinn-proto" version = "0.11.12" diff --git a/easytier/Cargo.toml b/easytier/Cargo.toml index 7daf1602..82cd82ad 100644 --- a/easytier/Cargo.toml +++ b/easytier/Cargo.toml @@ -65,6 +65,7 @@ bytes = "1.5.0" pin-project-lite = "0.2.13" quinn = { version = "0.11.8", optional = true, features = ["ring"] } +quinn-plaintext = { version = "0.3.0", optional = true} rustls = { version = "0.23.0", features = [ "ring", @@ -328,10 +329,11 @@ full = [ "smoltcp", "tun", "socks5", + "quic", "magic-dns", ] wireguard = ["dep:boringtun", "dep:ring"] -quic = ["dep:quinn", "dep:rustls", "dep:rcgen"] +quic = ["dep:quinn", "dep:quinn-plaintext", "dep:rustls", "dep:rcgen"] kcp = ["dep:kcp-sys"] mimalloc = ["dep:mimalloc"] aes-gcm = ["dep:aes-gcm"] diff --git a/easytier/src/gateway/quic_proxy.rs b/easytier/src/gateway/quic_proxy.rs index 471d3837..7303801a 100644 --- a/easytier/src/gateway/quic_proxy.rs +++ b/easytier/src/gateway/quic_proxy.rs @@ -30,7 +30,7 @@ use crate::proto::common::ProxyDstInfo; use crate::proto::rpc_types; use crate::proto::rpc_types::controller::BaseController; use crate::tunnel::packet_def::PeerManagerHeader; -use crate::tunnel::quic::{configure_client, make_server_endpoint}; +use crate::tunnel::quic::{client_config, make_server_endpoint}; pub struct QUICStream { endpoint: Option, @@ -115,7 +115,7 @@ impl NatDstConnector for NatDstQUICConnector { let mut endpoint = Endpoint::client("0.0.0.0:0".parse().unwrap()) .with_context(|| format!("failed to create QUIC endpoint for src: {}", src))?; - endpoint.set_default_client_config(configure_client()); + endpoint.set_default_client_config(client_config()); // connect to server let connection = { @@ -263,7 +263,7 @@ impl QUICProxyDst { route: Arc, ) -> Result { let _g = global_ctx.net_ns.guard(); - let (endpoint, _) = make_server_endpoint( + let endpoint = make_server_endpoint( format!("0.0.0.0:{}", global_ctx.config.get_flags().quic_listen_port) .parse() .unwrap(), diff --git a/easytier/src/tunnel/quic.rs b/easytier/src/tunnel/quic.rs index d3707e75..e8772f42 100644 --- a/easytier/src/tunnel/quic.rs +++ b/easytier/src/tunnel/quic.rs @@ -13,28 +13,46 @@ use crate::tunnel::{ use anyhow::Context; use quinn::{ - congestion::BbrConfig, crypto::rustls::QuicClientConfig, udp::RecvMeta, AsyncUdpSocket, - ClientConfig, Connection, Endpoint, EndpointConfig, ServerConfig, TransportConfig, UdpPoller, + congestion::BbrConfig, udp::RecvMeta, AsyncUdpSocket, ClientConfig, Connection, Endpoint, + EndpointConfig, ServerConfig, TransportConfig, UdpPoller, }; use super::{ - check_scheme_and_get_socket_addr, - insecure_tls::{get_insecure_tls_cert, get_insecure_tls_client_config}, - IpVersion, Tunnel, TunnelConnector, TunnelError, TunnelListener, + check_scheme_and_get_socket_addr, IpVersion, Tunnel, TunnelConnector, TunnelError, + TunnelListener, }; -pub fn configure_client() -> ClientConfig { - let client_crypto = QuicClientConfig::try_from(get_insecure_tls_client_config()).unwrap(); - let mut client_config = ClientConfig::new(Arc::new(client_crypto)); +pub fn transport_config() -> Arc { + let mut config = TransportConfig::default(); - // // Create a new TransportConfig and set BBR - let mut transport_config = TransportConfig::default(); - transport_config.congestion_controller_factory(Arc::new(BbrConfig::default())); - transport_config.keep_alive_interval(Some(Duration::from_secs(5))); - // Replace the default TransportConfig with the transport_config() method - client_config.transport_config(Arc::new(transport_config)); + config + // .max_concurrent_bidi_streams(VarInt::MAX) + .max_concurrent_uni_streams(0u8.into()) + .keep_alive_interval(Some(Duration::from_secs(5))) + .initial_mtu(1200) + .min_mtu(1200) + .enable_segmentation_offload(false) + .congestion_controller_factory(Arc::new(BbrConfig::default())); - client_config + Arc::new(config) +} + +pub fn server_config() -> ServerConfig { + let mut config = quinn_plaintext::server_config(); + config.transport_config(transport_config()); + config +} + +pub fn client_config() -> ClientConfig { + let mut config = quinn_plaintext::client_config(); + config.transport_config(transport_config()); + config +} + +pub fn endpoint_config() -> EndpointConfig { + let mut config = EndpointConfig::default(); + config.max_udp_payload_size(65527).unwrap(); + config } #[derive(Clone, Debug)] @@ -84,11 +102,12 @@ impl AsyncUdpSocket for NoGroAsyncUdpSocket { /// /// ## Returns /// -/// - a stream of incoming QUIC connections -/// - server certificate serialized into DER format +/// - an [`Endpoint`] configured to accept incoming QUIC connections #[allow(unused)] -pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<(Endpoint, Vec), Box> { - let (server_config, server_cert) = configure_server()?; +pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result> { + let server_config = server_config(); + let client_config = client_config(); + let endpoint_config = endpoint_config(); let socket2_socket = socket2::Socket::new( socket2::Domain::for_address(bind_addr), @@ -100,32 +119,17 @@ pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<(Endpoint, Vec) let runtime = quinn::default_runtime().ok_or_else(|| std::io::Error::other("no async runtime found"))?; - let mut endpoint_config = EndpointConfig::default(); - endpoint_config.max_udp_payload_size(1200)?; let socket: NoGroAsyncUdpSocket = NoGroAsyncUdpSocket { inner: runtime.wrap_udp_socket(socket)?, }; - let endpoint = Endpoint::new_with_abstract_socket( + let mut endpoint = Endpoint::new_with_abstract_socket( endpoint_config, Some(server_config), Arc::new(socket), runtime, )?; - Ok((endpoint, server_cert)) -} - -/// Returns default server configuration along with its certificate. -pub fn configure_server() -> Result<(ServerConfig, Vec), Box> { - let (certs, key) = get_insecure_tls_cert(); - - let mut server_config = ServerConfig::with_single_cert(certs.clone(), key)?; - let transport_config = Arc::get_mut(&mut server_config.transport).unwrap(); - transport_config.max_concurrent_uni_streams(10_u8.into()); - transport_config.max_concurrent_bidi_streams(10_u8.into()); - // Setting BBR congestion control - transport_config.congestion_controller_factory(Arc::new(BbrConfig::default())); - - Ok((server_config, certs[0].to_vec())) + endpoint.set_default_client_config(client_config); + Ok(endpoint) } #[allow(unused)] @@ -144,7 +148,6 @@ impl Drop for ConnWrapper { pub struct QUICTunnelListener { addr: url::Url, endpoint: Option, - server_cert: Option>, } impl QUICTunnelListener { @@ -152,7 +155,6 @@ impl QUICTunnelListener { QUICTunnelListener { addr, endpoint: None, - server_cert: None, } } @@ -193,10 +195,9 @@ impl TunnelListener for QUICTunnelListener { let addr = check_scheme_and_get_socket_addr::(&self.addr, "quic", IpVersion::Both) .await?; - let (endpoint, server_cert) = make_server_endpoint(addr) + let endpoint = make_server_endpoint(addr) .map_err(|e| anyhow::anyhow!("make server endpoint error: {:?}", e))?; self.endpoint = Some(endpoint); - self.server_cert = Some(server_cert); self.addr .set_port(Some(self.endpoint.as_ref().unwrap().local_addr()?.port())) @@ -251,7 +252,7 @@ impl TunnelConnector for QUICTunnelConnector { }; let mut endpoint = Endpoint::client(local_addr.parse().unwrap())?; - endpoint.set_default_client_config(configure_client()); + endpoint.set_default_client_config(client_config()); // connect to server let connection = endpoint