#[cfg(feature = "qlog")]
use std::path::Path;
use std::{sync::Arc, time::Duration};
pub use noq::{
AcceptBi, AcceptUni, AckFrequencyConfig, ClosedStream, ConnectionError, ConnectionStats, Dir, IdleTimeout, MtuDiscoveryConfig, OpenBi, OpenUni, PathStats, ReadDatagram, ReadError, ReadExactError, ReadToEndError, RecvStream, ResetError, SendDatagram, SendDatagramError, SendStream, Side, StoppedError, StreamId, UnorderedRecvStream, VarInt, VarIntBoundsExceeded, WriteError, Written, };
#[cfg(feature = "qlog")]
pub use noq::{QlogConfig, QlogFactory, QlogFileFactory};
pub use noq_proto::{
ApplicationClose, Chunk, ConnectError as QuicConnectError, ConnectionClose, DecryptedInitial, FrameStats, FrameType, IncomingAlpns, PathId, RttEstimator, TimeSource, TokenLog, TokenReuseError, TransportError, TransportErrorCode, UdpStats, ValidationTokenConfig, congestion::{
Controller, ControllerFactory, ControllerMetrics, },
crypto::{
CryptoError, ExportKeyingMaterialError, HandshakeTokenKey, HeaderKey, Keys, PacketKey, UnsupportedVersion, },
transport_parameters::TransportParameters, };
use tracing::warn;
use crate::socket::{HEARTBEAT_INTERVAL, MAX_MULTIPATH_PATHS, PATH_MAX_IDLE_TIMEOUT};
#[derive(Debug, Clone)]
pub struct QuicTransportConfigBuilder(noq::TransportConfig);
#[derive(Debug, Clone)]
pub struct QuicTransportConfig(Arc<noq::TransportConfig>);
impl QuicTransportConfig {
pub fn builder() -> QuicTransportConfigBuilder {
QuicTransportConfigBuilder::new()
}
}
impl Default for QuicTransportConfig {
fn default() -> Self {
QuicTransportConfigBuilder::new().build()
}
}
impl QuicTransportConfig {
pub(crate) fn to_inner_arc(&self) -> Arc<noq::TransportConfig> {
self.0.clone()
}
}
impl QuicTransportConfigBuilder {
fn new() -> Self {
let mut cfg = noq::TransportConfig::default();
cfg.keep_alive_interval(Some(HEARTBEAT_INTERVAL));
cfg.default_path_keep_alive_interval(Some(HEARTBEAT_INTERVAL));
cfg.default_path_max_idle_timeout(Some(PATH_MAX_IDLE_TIMEOUT));
cfg.max_concurrent_multipath_paths(MAX_MULTIPATH_PATHS + 1);
cfg.set_max_remote_nat_traversal_addresses(MAX_MULTIPATH_PATHS as u8);
Self(cfg)
}
pub fn build(self) -> QuicTransportConfig {
QuicTransportConfig(Arc::new(self.0))
}
pub fn max_concurrent_bidi_streams(mut self, value: VarInt) -> Self {
self.0.max_concurrent_bidi_streams(value);
self
}
pub fn max_concurrent_uni_streams(mut self, value: VarInt) -> Self {
self.0.max_concurrent_uni_streams(value);
self
}
pub fn max_idle_timeout(mut self, value: Option<IdleTimeout>) -> Self {
self.0.max_idle_timeout(value);
self
}
pub fn stream_receive_window(mut self, value: VarInt) -> Self {
self.0.stream_receive_window(value);
self
}
pub fn receive_window(mut self, value: VarInt) -> Self {
self.0.receive_window(value);
self
}
pub fn send_window(mut self, value: u64) -> Self {
self.0.send_window(value);
self
}
pub fn send_fairness(mut self, value: bool) -> Self {
self.0.send_fairness(value);
self
}
pub fn packet_threshold(mut self, value: u32) -> Self {
self.0.packet_threshold(value);
self
}
pub fn time_threshold(mut self, value: f32) -> Self {
self.0.time_threshold(value);
self
}
pub fn initial_rtt(mut self, value: Duration) -> Self {
self.0.initial_rtt(value);
self
}
pub fn initial_mtu(mut self, value: u16) -> Self {
self.0.initial_mtu(value);
self
}
pub fn min_mtu(mut self, value: u16) -> Self {
self.0.min_mtu(value);
self
}
pub fn mtu_discovery_config(mut self, value: Option<MtuDiscoveryConfig>) -> Self {
self.0.mtu_discovery_config(value);
self
}
pub fn pad_to_mtu(mut self, value: bool) -> Self {
self.0.pad_to_mtu(value);
self
}
pub fn ack_frequency_config(mut self, value: Option<AckFrequencyConfig>) -> Self {
self.0.ack_frequency_config(value);
self
}
pub fn persistent_congestion_threshold(mut self, value: u32) -> Self {
self.0.persistent_congestion_threshold(value);
self
}
pub fn keep_alive_interval(mut self, value: Duration) -> Self {
self.0.keep_alive_interval(Some(value));
self
}
pub fn crypto_buffer_size(mut self, value: usize) -> Self {
self.0.crypto_buffer_size(value);
self
}
pub fn allow_spin(mut self, value: bool) -> Self {
self.0.allow_spin(value);
self
}
pub fn datagram_receive_buffer_size(mut self, value: Option<usize>) -> Self {
self.0.datagram_receive_buffer_size(value);
self
}
pub fn datagram_send_buffer_size(mut self, value: usize) -> Self {
self.0.datagram_send_buffer_size(value);
self
}
pub fn congestion_controller_factory(
mut self,
factory: Arc<dyn ControllerFactory + Send + Sync + 'static>,
) -> Self {
self.0.congestion_controller_factory(factory);
self
}
pub fn enable_segmentation_offload(mut self, enabled: bool) -> Self {
self.0.enable_segmentation_offload(enabled);
self
}
pub fn send_observed_address_reports(mut self, enabled: bool) -> Self {
self.0.send_observed_address_reports(enabled);
self
}
pub fn receive_observed_address_reports(mut self, enabled: bool) -> Self {
self.0.receive_observed_address_reports(enabled);
self
}
pub fn max_concurrent_multipath_paths(mut self, max_concurrent: u32) -> Self {
if max_concurrent < MAX_MULTIPATH_PATHS + 1 {
warn!(
"QuicTransportConfig::max_concurrent_multipath_paths must be at minimum {}, ignoring user supplied value",
MAX_MULTIPATH_PATHS + 1
);
return self;
}
self.0.max_concurrent_multipath_paths(max_concurrent);
self
}
pub fn default_path_max_idle_timeout(mut self, timeout: Duration) -> Self {
if timeout > PATH_MAX_IDLE_TIMEOUT {
warn!(
"QuicTransportConfig::default_path_max_idle must be at most {:?}, clamping",
PATH_MAX_IDLE_TIMEOUT
);
self.0
.default_path_max_idle_timeout(Some(PATH_MAX_IDLE_TIMEOUT));
return self;
}
self.0.default_path_max_idle_timeout(Some(timeout));
self
}
pub fn default_path_keep_alive_interval(mut self, interval: Duration) -> Self {
if interval > HEARTBEAT_INTERVAL {
warn!(
"QuicTransportConfig::default_path_keep_alive must be at most {:?}, ignoring user supplied value",
HEARTBEAT_INTERVAL
);
return self;
}
self.0.default_path_keep_alive_interval(Some(interval));
self
}
pub fn set_max_remote_nat_traversal_addresses(mut self, max_addresses: u8) -> Self {
if max_addresses < MAX_MULTIPATH_PATHS as u8 {
warn!(
"QuicTransportConfig::max_remote_nat_traversal_addresses must be at least {}, ignoring user supplied value",
MAX_MULTIPATH_PATHS
);
return self;
}
self.0.set_max_remote_nat_traversal_addresses(max_addresses);
self
}
#[cfg(feature = "qlog")]
pub fn qlog_factory(mut self, factory: Arc<dyn QlogFactory>) -> Self {
self.0.qlog_factory(factory);
self
}
#[cfg(feature = "qlog")]
pub fn qlog_from_env(mut self, prefix: &str) -> Self {
self.0.qlog_from_env(prefix);
self
}
#[cfg(feature = "qlog")]
pub fn qlog_from_path(mut self, path: impl AsRef<Path>, prefix: &str) -> Self {
self.0.qlog_from_path(path, prefix);
self
}
}
#[derive(Debug, Clone)]
pub struct ServerConfigBuilder {
inner: noq::ServerConfig,
transport: QuicTransportConfig,
}
#[derive(Debug, Clone)]
pub struct ServerConfig(Arc<noq::ServerConfig>);
impl ServerConfig {
pub(crate) fn to_inner_arc(&self) -> Arc<noq::ServerConfig> {
self.0.clone()
}
}
impl ServerConfigBuilder {
pub fn build(self) -> ServerConfig {
ServerConfig(Arc::new(self.inner))
}
pub(crate) fn new(inner: noq::ServerConfig, transport: QuicTransportConfig) -> Self {
Self { inner, transport }
}
pub fn set_transport_config(mut self, transport: QuicTransportConfig) -> Self {
self.inner.transport_config(transport.to_inner_arc());
self.transport = transport;
self
}
pub fn set_validation_token_config(mut self, validation_token: ValidationTokenConfig) -> Self {
self.inner.validation_token_config(validation_token);
self
}
pub fn set_token_key(mut self, value: Arc<dyn HandshakeTokenKey>) -> Self {
self.inner.token_key(value);
self
}
pub fn set_retry_token_lifetime(mut self, value: Duration) -> Self {
self.inner.retry_token_lifetime(value);
self
}
pub fn set_max_incoming(mut self, max_incoming: usize) -> Self {
self.inner.max_incoming(max_incoming);
self
}
pub fn set_incoming_buffer_size(mut self, incoming_buffer_size: u64) -> Self {
self.inner.incoming_buffer_size(incoming_buffer_size);
self
}
pub fn set_incoming_buffer_size_total(mut self, incoming_buffer_size_total: u64) -> Self {
self.inner
.incoming_buffer_size_total(incoming_buffer_size_total);
self
}
pub fn set_time_source(mut self, time_source: Arc<dyn TimeSource>) -> Self {
self.inner.time_source(time_source);
self
}
}