Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ rustls-pki-types = { version = "1", default-features = false }
rustls = { version = "0.23.40", default-features = false, features = ["std", "tls12", "brotli"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["tls12"] }
quinn = { version = "0.11", default-features = false, features = ["runtime-tokio"] }
quinn-proto = { version = "0.11", default-features = false }
quinn-udp = { version = "0.5.9", default-features = false, features = ["fast-apple-datapath"] }
#
openssl = { package = "variant-ssl", version = "0.17.30" }
Expand Down
3 changes: 2 additions & 1 deletion lib/vey-daemon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ tokio-util = { workspace = true, features = ["compat"] }
http = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }
quinn = { workspace = true, optional = true, features = ["runtime-tokio", "ring"] }
quinn-proto = { workspace = true, optional = true }
vey-compat.workspace = true
vey-types = { workspace = true, features = ["async-log", "acl-rule"] }
vey-stdlog.workspace = true
Expand Down Expand Up @@ -63,5 +64,5 @@ mimalloc = ["dep:vey-mimalloc"]
ebpf = ["dep:vey-reuseport"]
event-log = ["dep:vey-fluentd"]
register = ["vey-yaml/http", "dep:http", "dep:serde_json", "dep:vey-http"]
quic = ["dep:quinn"]
quic = ["dep:quinn", "dep:quinn-proto", "vey-types/quinn"]
openssl-async-job = ["vey-runtime/openssl-async-job"]
62 changes: 53 additions & 9 deletions lib/vey-daemon/src/listen/quic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use std::time::Duration;
use anyhow::anyhow;
use async_trait::async_trait;
use log::{info, warn};
use quinn::{Connection, Endpoint, Incoming};
use quinn::{Connection, Endpoint, EndpointConfig, Incoming, ServerConfig};
use quinn_proto::HashedConnectionIdGenerator;
use tokio::runtime::Handle;
use tokio::sync::broadcast;

Expand All @@ -21,7 +22,9 @@ use vey_reuseport::quic::{QuicSocketSelectGuard, QuicSocketSelector};
use vey_socket::RawSocket;
use vey_std_ext::net::SocketAddrExt;
use vey_types::acl::{AclAction, AclNetworkRule};
use vey_types::net::UdpListenConfig;
#[cfg(feature = "ebpf")]
use vey_types::net::QuinnReuseportIdGenerator;
use vey_types::net::{QuinnEndpointConfig, UdpListenConfig};

use crate::listen::{ListenAliveGuard, ListenStats};
use crate::server::{BaseServer, ClientConnectionInfo, ReloadServer, ServerReloadCommand};
Expand All @@ -34,7 +37,7 @@ pub trait AcceptQuicServer: BaseServer {
#[derive(Clone)]
pub enum ListenQuicInPlaceConfig {
ListenConfig(UdpListenConfig),
QuinnConfig(quinn::ServerConfig),
QuinnConfig(ServerConfig),
IngressAcl(Option<Arc<AclNetworkRule>>),
AcceptTimeout(Duration),
}
Expand All @@ -43,6 +46,7 @@ pub struct ListenQuicRuntime<S> {
server: S,
listen_config: UdpListenConfig,
listen_stats: Arc<ListenStats>,
endpoint_config: QuinnEndpointConfig,
#[cfg(feature = "ebpf")]
socket_selector: Option<QuicSocketSelector>,
}
Expand All @@ -51,11 +55,17 @@ impl<S> ListenQuicRuntime<S>
where
S: AcceptQuicServer + ReloadServer + Clone + Send + Sync + 'static,
{
pub fn new(server: S, listen_stats: Arc<ListenStats>, listen_config: UdpListenConfig) -> Self {
pub fn new(
server: S,
listen_stats: Arc<ListenStats>,
listen_config: UdpListenConfig,
endpoint_config: QuinnEndpointConfig,
) -> Self {
ListenQuicRuntime {
server,
listen_config,
listen_stats,
endpoint_config,
#[cfg(feature = "ebpf")]
socket_selector: None,
}
Expand All @@ -64,7 +74,7 @@ where
pub fn run_all_instances(
&mut self,
listen_in_worker: bool,
quic_config: &quinn::ServerConfig,
quic_config: &ServerConfig,
ingress_net_filter: Option<&Arc<AclNetworkRule>>,
accept_timeout: Duration,
server_reload_sender: &broadcast::Sender<ServerReloadCommand<ListenQuicInPlaceConfig>>,
Expand Down Expand Up @@ -107,14 +117,46 @@ where

for i in 0..instance_count {
let socket = vey_socket::udp::new_std_bind_listen(&self.listen_config)?;
let listen_addr = socket.local_addr()?;

let mut endpoint_config = EndpointConfig::default();
if let Some(payload_size) = self.endpoint_config.udp_payload_size()
&& let Err(e) = endpoint_config.max_udp_payload_size(payload_size)
{
warn!("ignored UDP payload size {payload_size}: {e}");
}

#[cfg(feature = "ebpf")]
let guard = if let Some(selector) = &mut self.socket_selector {
let guard = selector.add_socket(RawSocket::from(&socket))?;
let cookie = guard.cookie();
let lifetime = self.endpoint_config.connection_id_lifetime();
endpoint_config.cid_generator(move || {
let mut cid_generator = QuinnReuseportIdGenerator::new(cookie);
if let Some(lifetime) = lifetime {
cid_generator.set_lifetime(lifetime);
}
Box::new(cid_generator)
});
Some(guard)
} else {
if let Some(lifetime) = self.endpoint_config.connection_id_lifetime() {
endpoint_config.cid_generator(move || {
let mut cid_generator = HashedConnectionIdGenerator::new();
cid_generator.set_lifetime(lifetime);
Box::new(cid_generator)
});
}
None
};
let listen_addr = socket.local_addr()?;
#[cfg(not(feature = "ebpf"))]
if let Some(lifetime) = self.endpoint_config.connection_id_lifetime() {
endpoint_config.cid_generator(move || {
let mut cid_generator = HashedConnectionIdGenerator::new();
cid_generator.set_lifetime(lifetime);
Box::new(cid_generator)
});
}

let runtime = ListenQuicRuntimeInstance {
server: self.server.clone(),
Expand All @@ -134,6 +176,7 @@ where
};
runtime.into_running(
socket,
endpoint_config,
quic_config.clone(),
server_reload_sender.subscribe(),
);
Expand Down Expand Up @@ -460,16 +503,17 @@ where
fn into_running(
mut self,
socket: UdpSocket,
config: quinn::ServerConfig,
endpoint_config: EndpointConfig,
server_config: ServerConfig,
server_reload_channel: broadcast::Receiver<ServerReloadCommand<ListenQuicInPlaceConfig>>,
) {
let handle = self.get_rt_handle();
handle.spawn(async move {
let raw_socket = RawSocket::from(&socket);
// make sure the listen socket associated with the correct reactor
match Endpoint::new(
Default::default(),
Some(config),
endpoint_config,
Some(server_config),
socket,
Arc::new(quinn::TokioRuntime),
) {
Expand Down
3 changes: 2 additions & 1 deletion lib/vey-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ radix_trie = { workspace = true, optional = true }
rustls = { workspace = true, optional = true }
rustls-pki-types = { workspace = true, optional = true }
quinn = { workspace = true, optional = true }
quinn-proto = { workspace = true, optional = true }
webpki-roots = { version = "1.0", optional = true }
rustls-native-certs = { version = "0.8", optional = true }
openssl = { workspace = true, optional = true }
Expand All @@ -61,7 +62,7 @@ quic = []
auth-crypt = ["dep:openssl", "dep:blake3", "dep:hex"]
auth-facts = ["dep:ip_network"]
resolve = ["dep:ahash", "dep:radix_trie", "dep:fastrand"]
quinn = ["dep:quinn", "quic"]
quinn = ["dep:quinn", "dep:quinn-proto", "quic"]
rustls = ["dep:rustls", "dep:rustls-pki-types", "dep:webpki-roots", "dep:rustls-native-certs", "dep:lru", "dep:ahash"]
rustls-ring = ["rustls", "rustls/ring", "quinn?/rustls-ring"]
rustls-aws-lc = ["rustls", "rustls/aws-lc-rs", "quinn?/rustls-aws-lc-rs"]
Expand Down
Loading
Loading