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>
This commit is contained in:
Luna Yao
2026-01-30 03:21:59 +01:00
committed by GitHub
parent ffe5644ddc
commit cdedaf3f63
4 changed files with 62 additions and 46 deletions
Generated
+13
View File
@@ -2217,6 +2217,7 @@ dependencies = [
"prost-reflect-build", "prost-reflect-build",
"prost-types", "prost-types",
"quinn", "quinn",
"quinn-plaintext",
"rand 0.8.5", "rand 0.8.5",
"rcgen", "rcgen",
"regex", "regex",
@@ -6508,6 +6509,18 @@ dependencies = [
"web-time", "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]] [[package]]
name = "quinn-proto" name = "quinn-proto"
version = "0.11.12" version = "0.11.12"
+3 -1
View File
@@ -65,6 +65,7 @@ bytes = "1.5.0"
pin-project-lite = "0.2.13" pin-project-lite = "0.2.13"
quinn = { version = "0.11.8", optional = true, features = ["ring"] } quinn = { version = "0.11.8", optional = true, features = ["ring"] }
quinn-plaintext = { version = "0.3.0", optional = true}
rustls = { version = "0.23.0", features = [ rustls = { version = "0.23.0", features = [
"ring", "ring",
@@ -328,10 +329,11 @@ full = [
"smoltcp", "smoltcp",
"tun", "tun",
"socks5", "socks5",
"quic",
"magic-dns", "magic-dns",
] ]
wireguard = ["dep:boringtun", "dep:ring"] 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"] kcp = ["dep:kcp-sys"]
mimalloc = ["dep:mimalloc"] mimalloc = ["dep:mimalloc"]
aes-gcm = ["dep:aes-gcm"] aes-gcm = ["dep:aes-gcm"]
+3 -3
View File
@@ -30,7 +30,7 @@ use crate::proto::common::ProxyDstInfo;
use crate::proto::rpc_types; use crate::proto::rpc_types;
use crate::proto::rpc_types::controller::BaseController; use crate::proto::rpc_types::controller::BaseController;
use crate::tunnel::packet_def::PeerManagerHeader; 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 { pub struct QUICStream {
endpoint: Option<quinn::Endpoint>, endpoint: Option<quinn::Endpoint>,
@@ -115,7 +115,7 @@ impl NatDstConnector for NatDstQUICConnector {
let mut endpoint = Endpoint::client("0.0.0.0:0".parse().unwrap()) let mut endpoint = Endpoint::client("0.0.0.0:0".parse().unwrap())
.with_context(|| format!("failed to create QUIC endpoint for src: {}", src))?; .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 // connect to server
let connection = { let connection = {
@@ -263,7 +263,7 @@ impl QUICProxyDst {
route: Arc<dyn crate::peers::route_trait::Route + Send + Sync + 'static>, route: Arc<dyn crate::peers::route_trait::Route + Send + Sync + 'static>,
) -> Result<Self> { ) -> Result<Self> {
let _g = global_ctx.net_ns.guard(); 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) format!("0.0.0.0:{}", global_ctx.config.get_flags().quic_listen_port)
.parse() .parse()
.unwrap(), .unwrap(),
+43 -42
View File
@@ -13,28 +13,46 @@ use crate::tunnel::{
use anyhow::Context; use anyhow::Context;
use quinn::{ use quinn::{
congestion::BbrConfig, crypto::rustls::QuicClientConfig, udp::RecvMeta, AsyncUdpSocket, congestion::BbrConfig, udp::RecvMeta, AsyncUdpSocket, ClientConfig, Connection, Endpoint,
ClientConfig, Connection, Endpoint, EndpointConfig, ServerConfig, TransportConfig, UdpPoller, EndpointConfig, ServerConfig, TransportConfig, UdpPoller,
}; };
use super::{ use super::{
check_scheme_and_get_socket_addr, check_scheme_and_get_socket_addr, IpVersion, Tunnel, TunnelConnector, TunnelError,
insecure_tls::{get_insecure_tls_cert, get_insecure_tls_client_config}, TunnelListener,
IpVersion, Tunnel, TunnelConnector, TunnelError, TunnelListener,
}; };
pub fn configure_client() -> ClientConfig { pub fn transport_config() -> Arc<TransportConfig> {
let client_crypto = QuicClientConfig::try_from(get_insecure_tls_client_config()).unwrap(); let mut config = TransportConfig::default();
let mut client_config = ClientConfig::new(Arc::new(client_crypto));
// // Create a new TransportConfig and set BBR config
let mut transport_config = TransportConfig::default(); // .max_concurrent_bidi_streams(VarInt::MAX)
transport_config.congestion_controller_factory(Arc::new(BbrConfig::default())); .max_concurrent_uni_streams(0u8.into())
transport_config.keep_alive_interval(Some(Duration::from_secs(5))); .keep_alive_interval(Some(Duration::from_secs(5)))
// Replace the default TransportConfig with the transport_config() method .initial_mtu(1200)
client_config.transport_config(Arc::new(transport_config)); .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)] #[derive(Clone, Debug)]
@@ -84,11 +102,12 @@ impl AsyncUdpSocket for NoGroAsyncUdpSocket {
/// ///
/// ## Returns /// ## Returns
/// ///
/// - a stream of incoming QUIC connections /// - an [`Endpoint`] configured to accept incoming QUIC connections
/// - server certificate serialized into DER format
#[allow(unused)] #[allow(unused)]
pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<(Endpoint, Vec<u8>), Box<dyn Error>> { pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<Endpoint, Box<dyn Error>> {
let (server_config, server_cert) = configure_server()?; let server_config = server_config();
let client_config = client_config();
let endpoint_config = endpoint_config();
let socket2_socket = socket2::Socket::new( let socket2_socket = socket2::Socket::new(
socket2::Domain::for_address(bind_addr), socket2::Domain::for_address(bind_addr),
@@ -100,32 +119,17 @@ pub fn make_server_endpoint(bind_addr: SocketAddr) -> Result<(Endpoint, Vec<u8>)
let runtime = let runtime =
quinn::default_runtime().ok_or_else(|| std::io::Error::other("no async runtime found"))?; 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 { let socket: NoGroAsyncUdpSocket = NoGroAsyncUdpSocket {
inner: runtime.wrap_udp_socket(socket)?, inner: runtime.wrap_udp_socket(socket)?,
}; };
let endpoint = Endpoint::new_with_abstract_socket( let mut endpoint = Endpoint::new_with_abstract_socket(
endpoint_config, endpoint_config,
Some(server_config), Some(server_config),
Arc::new(socket), Arc::new(socket),
runtime, runtime,
)?; )?;
Ok((endpoint, server_cert)) endpoint.set_default_client_config(client_config);
} Ok(endpoint)
/// Returns default server configuration along with its certificate.
pub fn configure_server() -> Result<(ServerConfig, Vec<u8>), Box<dyn Error>> {
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()))
} }
#[allow(unused)] #[allow(unused)]
@@ -144,7 +148,6 @@ impl Drop for ConnWrapper {
pub struct QUICTunnelListener { pub struct QUICTunnelListener {
addr: url::Url, addr: url::Url,
endpoint: Option<Endpoint>, endpoint: Option<Endpoint>,
server_cert: Option<Vec<u8>>,
} }
impl QUICTunnelListener { impl QUICTunnelListener {
@@ -152,7 +155,6 @@ impl QUICTunnelListener {
QUICTunnelListener { QUICTunnelListener {
addr, addr,
endpoint: None, endpoint: None,
server_cert: None,
} }
} }
@@ -193,10 +195,9 @@ impl TunnelListener for QUICTunnelListener {
let addr = let addr =
check_scheme_and_get_socket_addr::<SocketAddr>(&self.addr, "quic", IpVersion::Both) check_scheme_and_get_socket_addr::<SocketAddr>(&self.addr, "quic", IpVersion::Both)
.await?; .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))?; .map_err(|e| anyhow::anyhow!("make server endpoint error: {:?}", e))?;
self.endpoint = Some(endpoint); self.endpoint = Some(endpoint);
self.server_cert = Some(server_cert);
self.addr self.addr
.set_port(Some(self.endpoint.as_ref().unwrap().local_addr()?.port())) .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())?; 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 // connect to server
let connection = endpoint let connection = endpoint