Skip to main content

tquic_mimic_chromium_client/
lib.rs

1// Copyright (c) 2023 The TQUIC Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! TQUIC is an implementation of the [IETF QUIC protocol](https://quicwg.org/).
16//! It is a high-performance, lightweight, and cross-platform QUIC library.
17//!
18//! ## Features and Advantages
19//!
20//! * **High Performance**: TQUIC is designed for high performance and low
21//!   latency.
22//! * **High Throughput**: TQUIC supports various congtestion control algorithms
23//!   (CUBIC, BBR, COPA), and Multipath QUIC for utilizing multiple paths within
24//!   a single connection.
25//! * **High Quality**: TQUIC employs extensive testing techniques, including
26//!   unit testing, integration testing,
27//!   interoperability testing, and protocol conformance testing.
28//! * **Easy to Use**: TQUIC is easy to use, supporting flexible configuration
29//!   and detailed observability. It offers APIs for Rust/C/C++.
30//! * **Powered by Rust**: TQUIC is written in a memory-safe language, making it
31//!   immune to Buffer Overflow vulnerability and other memory-related bugs.
32//! * **Rich Features**: TQUIC supports all big features conforming with QUIC,
33//!   HTTP/3 RFCs.
34//!
35//! The [TQUIC project website](https://tquic.net/docs/intro) offers a
36//! comprehensive introduction to TQUIC.
37//!
38//! ## Get started
39//!
40//! See the [documents](https://tquic.net/docs/category/getting-started) and
41//! [examples](https://github.com/tencent/tquic/tree/master/tools/) to get
42//! started with TQUIC.
43//!
44//! ## Feature flags
45//!
46//! TQUIC defines several feature flags to reduce the amount of compiled code
47//! and dependencies:
48//!
49//! * `ffi`: Build and expose the FFI API
50//! * `qlog`: Enable support for qlog
51//! * `h3`: Enable support for HTTP/3
52
53#![allow(unused_imports)]
54#![allow(dead_code)]
55#![allow(unexpected_cfgs)]
56#![allow(mismatched_lifetime_syntaxes)]
57#![allow(clippy::uninlined_format_args)]
58
59use std::cmp;
60use std::collections::VecDeque;
61use std::fmt;
62use std::net::IpAddr;
63use std::net::SocketAddr;
64use std::sync::Arc;
65use std::time;
66use std::time::Duration;
67use std::time::Instant;
68
69use bytes::Buf;
70use bytes::BufMut;
71use log::debug;
72use rand::RngCore;
73use ring::aead;
74use ring::aead::LessSafeKey;
75use ring::aead::UnboundKey;
76use ring::hmac;
77use rustc_hash::FxHashSet;
78
79use crate::codec::VINT_MAX;
80use crate::connection::stream;
81use crate::tls::TlsSession;
82use crate::token::ResetToken;
83use crate::trans_param::TransportParams;
84use rand::Rng;
85
86/// The current QUIC wire version.
87pub const QUIC_VERSION: u32 = QUIC_VERSION_V1;
88
89/// The QUIC Version 1
90pub const QUIC_VERSION_V1: u32 = 0x0000_0001;
91
92fn generate_grease_version32() -> u32 {
93    // Generate GREASE version where each byte is 0x?A (0x0a, 0x1a, ..., 0xfa).
94    let mut bytes = [0u8; 4];
95    for b in &mut bytes {
96        let hi = (rand::rng().next_u32() & 0x0f) as u8;
97        *b = (hi << 4) | 0x0a;
98    }
99    u32::from_be_bytes(bytes)
100}
101
102/// The Connection ID MUST NOT exceed 20 bytes in QUIC version 1.
103/// See RFC 9000 Section 17.2
104pub const MAX_CID_LEN: usize = 20;
105
106/// Max number of cid that are allowed to advertised to the peer.
107const MAX_CID_LIMIT: u64 = 8;
108
109/// The Stateless Reset Token is a 16-byte value.
110const RESET_TOKEN_LEN: usize = 16;
111
112/// For the Stateless Reset to appear as a valid QUIC packet, the Unpredictable
113/// Bits field needs to include at least 38 bits of data. The minimum length of
114/// a Stateless Reset Packet is 21 bytes.
115const MIN_RESET_PACKET_LEN: usize = 21;
116
117/// Assuming the maximum possible connection ID and packet number size, the 1RTT
118/// packet size is:
119/// 1 (header) + 20 (cid) + 4 (pkt num) + 1 (payload) + 16 (AEAD tag) = 42 bytes
120const MAX_RESET_PACKET_LEN: usize = 42;
121
122/// The encoded size of length field in long header.
123const LENGTH_FIELD_LEN: usize = 2;
124
125/// The minimum length of Initial packets sent by a client.
126pub const MIN_CLIENT_INITIAL_LEN: usize = 1250;
127
128const MIN_PAYLOAD_LEN: usize = 4;
129
130/// Ensure the ACK frame can fit in a single minimum-MTU packet.
131const MAX_ACK_RANGES: usize = 68;
132
133/// Default outgoing udp datagram payloads size.
134const DEFAULT_SEND_UDP_PAYLOAD_SIZE: usize = 1250;
135
136/// An endpoint MUST limit the amount of data it sends to the unvalidated
137/// address to three times the amount of data received from that address.
138const ANTI_AMPLIFICATION_FACTOR: usize = 3;
139
140/// The RECOMMENDED value of the timer granularity is 1 millisecond.
141/// See RFC 9002 Section 6.1
142pub const TIMER_GRANULARITY: Duration = Duration::from_millis(1);
143
144/// The largest count of streams for each type.
145const MAX_STREAMS_PER_TYPE: u64 = 1 << 60;
146
147/// Represents the minimum multiple by which the connection flow control window
148/// needs to be greater than the stream flow control window.
149const CONNECTION_WINDOW_FACTOR: f64 = 1.5;
150
151/// Resumed connections over the same network MAY use the previous connection's
152/// final smoothed RTT value as the resumed connection's initial RTT. When no
153/// previous RTT is available, the initial RTT SHOULD be set to 333 milliseconds.
154/// This results in handshakes starting with a PTO of 1 second, as recommended
155/// for TCP's initial RTO
156const INITIAL_RTT: Duration = Duration::from_millis(333);
157
158/// Default handshake timeout is 10 seconds.
159const DEFAULT_HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(10);
160
161///  Default linear factor for calculating the probe timeout.
162const DEFAULT_PTO_LINEAR_FACTOR: u64 = 0;
163
164/// Default upper limit of probe timeout.
165const MAX_PTO: Duration = Duration::MAX;
166
167/// Result type for quic operations.
168pub type Result<T> = std::result::Result<T, Error>;
169
170/// Connection Id is an identifier used to identify a QUIC connection
171/// at an endpoint.
172#[repr(C)]
173#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
174pub struct ConnectionId {
175    /// length of cid
176    len: u8,
177    /// octets of cid
178    data: [u8; MAX_CID_LEN],
179}
180
181impl ConnectionId {
182    /// Construct cid from byte slice
183    pub fn new(bytes: &[u8]) -> Self {
184        let len = cmp::min(bytes.len(), MAX_CID_LEN);
185        let mut cid = Self {
186            len: len as u8,
187            data: [0; MAX_CID_LEN],
188        };
189        cid.data[..len].copy_from_slice(&bytes[..len]);
190        cid
191    }
192
193    /// Construct a random cid.
194    pub fn random() -> Self {
195        Self {
196            len: MAX_CID_LEN as u8,
197            data: rand::random::<[u8; MAX_CID_LEN]>(),
198        }
199    }
200}
201
202impl std::ops::Deref for ConnectionId {
203    type Target = [u8];
204    fn deref(&self) -> &[u8] {
205        &self.data[0..self.len as usize]
206    }
207}
208
209impl fmt::Debug for ConnectionId {
210    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211        for b in self.iter() {
212            write!(f, "{b:02x}")?;
213        }
214        Ok(())
215    }
216}
217
218impl fmt::Display for ConnectionId {
219    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
220        fmt::Debug::fmt(self, f)
221    }
222}
223
224/// Generate QUIC connection ID
225pub trait ConnectionIdGenerator {
226    /// Generate a new CID
227    fn generate(&mut self) -> ConnectionId;
228
229    /// Return the length of a CID
230    fn cid_len(&self) -> usize;
231
232    /// Generate a new CID and associated reset token.
233    fn generate_cid_and_token(&mut self, reset_token_key: &hmac::Key) -> (ConnectionId, u128) {
234        let scid = self.generate();
235        let reset_token = ResetToken::generate(reset_token_key, &scid);
236        (scid, reset_token.to_u128())
237    }
238}
239
240/// Generates purely random connection IDs of a certain length
241#[derive(Debug, Clone, Copy)]
242pub struct RandomConnectionIdGenerator {
243    cid_len: usize,
244}
245
246impl RandomConnectionIdGenerator {
247    pub fn new(cid_len: usize) -> Self {
248        Self {
249            cid_len: cmp::min(cid_len, MAX_CID_LEN),
250        }
251    }
252}
253
254impl ConnectionIdGenerator for RandomConnectionIdGenerator {
255    fn generate(&mut self) -> ConnectionId {
256        let mut bytes = [0; MAX_CID_LEN];
257        rand::rng().fill_bytes(&mut bytes[..self.cid_len]);
258        ConnectionId::new(&bytes[..self.cid_len])
259    }
260
261    fn cid_len(&self) -> usize {
262        self.cid_len
263    }
264}
265
266/// Meta information about a packet.
267#[derive(Clone, Copy, Debug)]
268pub struct PacketInfo {
269    /// The source address of the packet
270    pub src: SocketAddr,
271
272    /// The destination address of the packet
273    pub dst: SocketAddr,
274
275    /// The time when the packet arrived or the time to send the packet
276    pub time: time::Instant,
277}
278
279/// Address tuple.
280#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
281pub struct FourTuple {
282    /// The local address
283    pub local: SocketAddr,
284
285    /// The remote address
286    pub remote: SocketAddr,
287}
288
289/// An iterator over FourTuple.
290#[derive(Default)]
291pub struct FourTupleIter {
292    pub(crate) addrs: Vec<FourTuple>,
293}
294
295impl Iterator for FourTupleIter {
296    type Item = FourTuple;
297
298    #[inline]
299    fn next(&mut self) -> Option<Self::Item> {
300        self.addrs.pop()
301    }
302}
303
304impl ExactSizeIterator for FourTupleIter {
305    #[inline]
306    fn len(&self) -> usize {
307        self.addrs.len()
308    }
309}
310
311/// Check whether the protocol version is supported.
312fn version_is_supported(version: u32) -> bool {
313    matches!(version, QUIC_VERSION_V1)
314}
315
316/// Configurations about QUIC endpoint.
317#[derive(Clone)]
318pub struct Config {
319    /// QUIC transport configuration.
320    local_transport_params: TransportParams,
321
322    /// Handshake timeout in microseconds.
323    max_handshake_timeout: time::Duration,
324
325    /// Maximum number of concurrent connections.
326    max_concurrent_conns: u32,
327
328    /// Maximum size of the receiver connection flow control window.
329    max_connection_window: u64,
330
331    /// Maximum size of the receiver stream flow control window.
332    max_stream_window: u64,
333
334    /// Uses Retry packets to reduce load on servers by forcing the client to
335    /// prove ownership of its address
336    retry: bool,
337
338    /// Enable stateless reset or not.
339    stateless_reset: bool,
340
341    /// Duration after a retry token was issued for which it's considered valid.
342    address_token_lifetime: Duration,
343
344    /// Key for address token generation.
345    address_token_key: Vec<LessSafeKey>,
346
347    /// Key for stateless reset token generation.
348    reset_token_key: hmac::Key,
349
350    /// Length of source cid.
351    cid_len: usize,
352
353    /// Omit SCID in client Initial packet headers.
354    /// Applicable to Client only.
355    omit_client_initial_scid: bool,
356
357    /// Anti-amplification factor.
358    anti_amplification_factor: usize,
359
360    /// Maximum numbers of packets sent in a batch.
361    send_batch_size: usize,
362
363    /// Buffer size for early incoming zero rtt packets, in packets.
364    zerortt_buffer_size: usize,
365
366    /// The maximum number of undecryptable packets that can be stored by one connection, in packets.
367    max_undecryptable_packets: usize,
368
369    /// Configurations about loss recovery, congestion control, and pmtu discovery.
370    recovery: RecoveryConfig,
371
372    /// Multipath transport configurations.
373    multipath: MultipathConfig,
374
375    /// Find TLS config according to server name.
376    tls_config_selector: Option<Arc<dyn tls::TlsConfigSelector>>,
377}
378
379impl Config {
380    /// Create default configuration.
381    ///
382    /// The configuration may be customized by calling related set methods.
383    ///
384    /// ## Examples:
385    ///
386    /// ```
387    /// let mut conf = tquic_mimic_chromium_client::Config::new()?;
388    /// conf.set_max_idle_timeout(30000);
389    /// let alpn =  vec![b"h3".to_vec()];
390    /// let mut tls_config = tquic_mimic_chromium_client::TlsConfig::new_client_config(alpn, true)?;
391    /// conf.set_tls_config(tls_config);
392    /// # Ok::<(), tquic_mimic_chromium_client::error::Error>(())
393    /// ```
394    pub fn new() -> Result<Self> {
395        let grease_ver = generate_grease_version32();
396        let local_transport_params = TransportParams {
397            // Defaults aligned with requested parameters
398            max_idle_timeout: 30000,
399            max_udp_payload_size: 1472,
400            initial_max_data: 15728640,
401            initial_max_stream_data_bidi_local: 6291456,
402            initial_max_stream_data_bidi_remote: 6291456,
403            initial_max_stream_data_uni: 6291456,
404            initial_max_streams_bidi: 100,
405            initial_max_streams_uni: 103,
406            max_datagram_frame_size: 65536,
407            // Version information and Google QUIC parameters
408            version_information: Some(crate::trans_param::VersionInformation {
409                chosen_version: QUIC_VERSION_V1,
410                other_versions: vec![grease_ver, QUIC_VERSION_V1],
411            }),
412            google_quic_version: Some(QUIC_VERSION_V1),
413            // If not explicitly set by user, this will be randomized per-encode.
414            google_initial_rtt: None,
415            ..TransportParams::default()
416        };
417
418        let reset_token_key = hmac::Key::new(hmac::HMAC_SHA256, &[]);
419
420        Ok(Self {
421            local_transport_params,
422            max_handshake_timeout: DEFAULT_HANDSHAKE_TIMEOUT,
423            max_concurrent_conns: 1000000,
424            max_connection_window: stream::MAX_CONNECTION_WINDOW,
425            max_stream_window: stream::MAX_STREAM_WINDOW,
426            retry: false,
427            stateless_reset: true,
428            address_token_lifetime: Duration::from_secs(86400),
429            address_token_key: Self::rand_address_token_key()?,
430            reset_token_key,
431            cid_len: 8,
432            omit_client_initial_scid: true,
433            anti_amplification_factor: ANTI_AMPLIFICATION_FACTOR,
434            send_batch_size: 64,
435            zerortt_buffer_size: 1000,
436            max_undecryptable_packets: 10,
437            recovery: RecoveryConfig::default(),
438            multipath: MultipathConfig::default(),
439            tls_config_selector: None,
440        })
441    }
442
443    /// Set the `max_idle_timeout` transport parameter in milliseconds.
444    /// Idle timeout is disabled by default.
445    pub fn set_max_idle_timeout(&mut self, v: u64) {
446        self.local_transport_params.max_idle_timeout = cmp::min(v, VINT_MAX);
447    }
448
449    /// Set handshake timeout in milliseconds. Zero turns the timeout off.
450    pub fn set_max_handshake_timeout(&mut self, v: u64) {
451        self.max_handshake_timeout = time::Duration::from_millis(v);
452    }
453
454    /// Set the `max_udp_payload_size` transport parameter in bytes. It limits
455    /// the size of UDP payloads that the endpoint is willing to receive. The
456    /// default value is `65527`.
457    pub fn set_recv_udp_payload_size(&mut self, v: u16) {
458        self.local_transport_params.max_udp_payload_size = cmp::min(v as u64, VINT_MAX);
459    }
460
461    /// Set the `max_datagram_frame_size` transport parameter (QUIC DATAGRAM/RFC 9221).
462    /// A value of 0 disables DATAGRAM.
463    pub fn set_max_datagram_frame_size(&mut self, v: u64) {
464        self.local_transport_params.max_datagram_frame_size = cmp::min(v, VINT_MAX);
465    }
466
467    /// Set the `version_information` transport parameter (draft-ietf-quic-version-negotiation).
468    pub fn set_version_information(&mut self, chosen_version: u32, other_versions: Vec<u32>) {
469        self.local_transport_params.version_information =
470            Some(crate::trans_param::VersionInformation {
471                chosen_version,
472                other_versions,
473            });
474    }
475
476    /// Set the Google QUIC version transport parameter (0x4752).
477    pub fn set_google_quic_version(&mut self, v: u32) {
478        self.local_transport_params.google_quic_version = Some(v);
479    }
480
481    /// Set the Google Initial RTT transport parameter in microseconds (0x3127).
482    pub fn set_google_initial_rtt_us(&mut self, v: u32) {
483        self.local_transport_params.google_initial_rtt = Some(v);
484    }
485
486    /// Disable randomization and clear google_initial_rtt so it is randomized again.
487    pub fn clear_google_initial_rtt(&mut self) {
488        self.local_transport_params.google_initial_rtt = None;
489    }
490
491    /// Enable the Datagram Packetization Layer Path MTU Discovery
492    /// default value is true.
493    pub fn enable_dplpmtud(&mut self, v: bool) {
494        self.recovery.enable_dplpmtud = v;
495    }
496
497    /// Set the maximum outgoing UDP payload size in bytes.
498    /// It corresponds to the maximum datagram size that DPLPMTUD tries to discovery.
499    /// The default value is `1200` which means let DPLPMTUD choose a value.
500    pub fn set_send_udp_payload_size(&mut self, v: usize) {
501        self.recovery.max_datagram_size = cmp::max(v, DEFAULT_SEND_UDP_PAYLOAD_SIZE);
502    }
503
504    /// Set the `initial_max_data` transport parameter. It means the initial
505    /// value for the maximum amount of data that can be sent on the connection.
506    /// The value is capped by the setting `max_connection_window`.
507    /// The default value is `10485760`.
508    pub fn set_initial_max_data(&mut self, v: u64) {
509        self.local_transport_params.initial_max_data = cmp::min(v, self.max_connection_window);
510    }
511
512    /// Set the `initial_max_stream_data_bidi_local` transport parameter.
513    /// The value is capped by the setting `max_stream_window`.
514    /// The default value is `5242880`.
515    pub fn set_initial_max_stream_data_bidi_local(&mut self, v: u64) {
516        self.local_transport_params
517            .initial_max_stream_data_bidi_local = cmp::min(v, self.max_stream_window);
518    }
519
520    /// Set the `initial_max_stream_data_bidi_remote` transport parameter.
521    /// The value is capped by the setting `max_stream_window`.
522    /// The default value is `2097152`.
523    pub fn set_initial_max_stream_data_bidi_remote(&mut self, v: u64) {
524        self.local_transport_params
525            .initial_max_stream_data_bidi_remote = cmp::min(v, self.max_stream_window);
526    }
527
528    /// Set the `initial_max_stream_data_uni` transport parameter.
529    /// The value is capped by the setting `max_stream_window`.
530    /// The default value is `1048576`.
531    pub fn set_initial_max_stream_data_uni(&mut self, v: u64) {
532        self.local_transport_params.initial_max_stream_data_uni =
533            cmp::min(v, self.max_stream_window);
534    }
535
536    /// Set the `initial_max_streams_bidi` transport parameter.
537    /// The default value is `200`.
538    pub fn set_initial_max_streams_bidi(&mut self, v: u64) {
539        self.local_transport_params.initial_max_streams_bidi = cmp::min(v, VINT_MAX);
540    }
541
542    /// Set the `initial_max_streams_uni` transport parameter.
543    /// The default value is `100`.
544    pub fn set_initial_max_streams_uni(&mut self, v: u64) {
545        self.local_transport_params.initial_max_streams_uni = cmp::min(v, VINT_MAX);
546    }
547
548    /// Set the `ack_delay_exponent` transport parameter.
549    /// The default value is `3`.
550    pub fn set_ack_delay_exponent(&mut self, v: u64) {
551        self.local_transport_params.ack_delay_exponent = cmp::min(v, VINT_MAX);
552    }
553
554    /// Set the `max_ack_delay` transport parameter.
555    /// The default value is `25`.
556    pub fn set_max_ack_delay(&mut self, v: u64) {
557        self.local_transport_params.max_ack_delay = cmp::min(v, VINT_MAX);
558    }
559
560    /// Set the maximum number of ack-eliciting packets the endpoint receives before
561    /// sending an acknowledgment.
562    /// The default value is `2`.
563    pub fn set_ack_eliciting_threshold(&mut self, v: u64) {
564        self.recovery.ack_eliciting_threshold = v;
565    }
566
567    /// Set congestion control algorithm that the connection would use.
568    /// The default value is Bbr.
569    pub fn set_congestion_control_algorithm(&mut self, cca: CongestionControlAlgorithm) {
570        self.recovery.congestion_control_algorithm = cca;
571    }
572
573    /// Set the initial congestion window in packets.
574    /// The default value is 10.
575    pub fn set_initial_congestion_window(&mut self, packets: u64) {
576        self.recovery.initial_congestion_window = packets;
577    }
578
579    /// Set the minimal congestion window in packets.
580    /// The default value is 2.
581    pub fn set_min_congestion_window(&mut self, packets: u64) {
582        self.recovery.min_congestion_window = packets
583    }
584
585    /// Set the threshold for slow start in packets.
586    /// The default value is the maximum value of u64.
587    pub fn set_slow_start_thresh(&mut self, packets: u64) {
588        self.recovery.slow_start_thresh = packets
589    }
590
591    /// Set the minimum duration for BBR ProbeRTT state in milliseconds.
592    /// The default value is 200 milliseconds.
593    pub fn set_bbr_probe_rtt_duration(&mut self, millis: u64) {
594        self.recovery.bbr_probe_rtt_duration =
595            cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
596    }
597
598    /// Enable using a cwnd based on bdp during ProbeRTT state.
599    /// The default value is false.
600    pub fn enable_bbr_probe_rtt_based_on_bdp(&mut self, v: bool) {
601        self.recovery.bbr_probe_rtt_based_on_bdp = v;
602    }
603
604    /// Set the cwnd gain for BBR ProbeRTT state.
605    /// This option is meaningful only when `bbr_probe_rtt_based_on_bdp` option
606    /// is set to true.
607    /// The default value is 0.75
608    pub fn set_bbr_probe_rtt_cwnd_gain(&mut self, v: f64) {
609        self.recovery.bbr_probe_rtt_cwnd_gain = v;
610    }
611
612    /// Set the length of the BBR RTProp min filter window in milliseconds.
613    /// The default value is 10000 milliseconds.
614    pub fn set_bbr_rtprop_filter_len(&mut self, millis: u64) {
615        self.recovery.bbr_rtprop_filter_len =
616            cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
617    }
618
619    /// Set the cwnd gain for BBR ProbeBW state.
620    /// The default value is 2.0
621    pub fn set_bbr_probe_bw_cwnd_gain(&mut self, v: f64) {
622        self.recovery.bbr_probe_bw_cwnd_gain = v;
623    }
624
625    /// Set the delta in copa slow start state.
626    pub fn set_copa_slow_start_delta(&mut self, v: f64) {
627        self.recovery.copa_slow_start_delta = v;
628    }
629
630    /// Set the delta in coap steady state.
631    pub fn set_copa_steady_delta(&mut self, v: f64) {
632        self.recovery.copa_steady_delta = v;
633    }
634
635    /// Enable Using the rtt standing instead of the latest rtt to calculate queueing delay.
636    pub fn enable_copa_use_standing_rtt(&mut self, v: bool) {
637        self.recovery.copa_use_standing_rtt = v;
638    }
639
640    /// Set the initial RTT in milliseconds. The default value is 333ms.
641    ///
642    /// The configuration should be changed with caution. Setting a value less than the default
643    /// will cause retransmission of handshake packets to be more aggressive.
644    pub fn set_initial_rtt(&mut self, millis: u64) {
645        self.recovery.initial_rtt = cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
646    }
647
648    /// Enable pacing to smooth the flow of packets sent onto the network.
649    /// The default value is true.
650    pub fn enable_pacing(&mut self, v: bool) {
651        self.recovery.enable_pacing = v;
652    }
653
654    /// Set clock granularity used by the pacer.
655    /// The default value is 1 milliseconds.
656    pub fn set_pacing_granularity(&mut self, millis: u64) {
657        self.recovery.pacing_granularity =
658            cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
659    }
660
661    /// Set the linear factor for calculating the probe timeout.
662    /// The endpoint do not backoff the first `v` consecutive probe timeouts.
663    /// The default value is `0`.
664    /// The configuration should be changed with caution. Setting a value greater than the default
665    /// will cause retransmission to be more aggressive.
666    pub fn set_pto_linear_factor(&mut self, v: u64) {
667        self.recovery.pto_linear_factor = v;
668    }
669
670    /// Set the upper limit of probe timeout in milliseconds.
671    /// A Probe Timeout (PTO) triggers the sending of one or two probe datagrams and enables a
672    /// connection to recover from loss of tail packets or acknowledgments.
673    /// See RFC 9002 Section 6.2.
674    pub fn set_max_pto(&mut self, millis: u64) {
675        self.recovery.max_pto = cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
676    }
677
678    /// Set the `active_connection_id_limit` transport parameter.
679    /// The default value is `2`. Lower values will be ignored.
680    pub fn set_active_connection_id_limit(&mut self, v: u64) {
681        if v >= 2 {
682            self.local_transport_params.active_conn_id_limit = cmp::min(v, VINT_MAX);
683        }
684    }
685
686    /// Set the `enable_multipath` transport parameter.
687    /// The default value is false. (Experimental)
688    pub fn enable_multipath(&mut self, v: bool) {
689        self.local_transport_params.enable_multipath = v;
690    }
691
692    /// Set the multipath scheduling algorithm
693    /// The default value is MultipathAlgorithm::MinRtt
694    pub fn set_multipath_algorithm(&mut self, v: MultipathAlgorithm) {
695        self.multipath.multipath_algorithm = v;
696    }
697
698    /// Set the maximum size of the connection flow control window.
699    /// The default value is MAX_CONNECTION_WINDOW (15 MB).
700    pub fn set_max_connection_window(&mut self, v: u64) {
701        self.max_connection_window = cmp::min(v, VINT_MAX);
702    }
703
704    /// Set the maximum size of the stream flow control window.
705    /// The value should not be greater than the setting `max_connection_window`.
706    /// The default value is MAX_STREAM_WINDOW (6 MB).
707    pub fn set_max_stream_window(&mut self, v: u64) {
708        self.max_stream_window = cmp::min(v, VINT_MAX);
709    }
710
711    /// Set the maximum number of concurrent connections.
712    /// The default value is `1000000`
713    pub fn set_max_concurrent_conns(&mut self, v: u32) {
714        self.max_concurrent_conns = v;
715    }
716
717    /// Set the key for reset token generation.
718    /// Applicable to Server only.
719    pub fn set_reset_token_key(&mut self, v: [u8; 64]) {
720        // HMAC-SHA256 use a 512-bit block length
721        self.reset_token_key = hmac::Key::new(hmac::HMAC_SHA256, &v);
722    }
723
724    /// Set the lifetime of address token.
725    /// Applicable to Server only.
726    pub fn set_address_token_lifetime(&mut self, seconds: u64) {
727        self.address_token_lifetime = Duration::from_secs(seconds);
728    }
729
730    /// Set the key for address token generation.
731    /// Applicable to Server only.
732    pub fn set_address_token_key(&mut self, keys: Vec<[u8; 16]>) -> Result<()> {
733        if keys.is_empty() {
734            return Err(Error::InvalidConfig("address token key empty".into()));
735        }
736
737        let mut address_token_key = vec![];
738        for key in keys {
739            // AES-128 uses a 128-bit key length
740            let key = UnboundKey::new(&aead::AES_128_GCM, &key).map_err(|_| Error::CryptoFail)?;
741            let key = LessSafeKey::new(key);
742            address_token_key.push(key);
743        }
744        self.address_token_key = address_token_key;
745
746        Ok(())
747    }
748
749    /// Set whether stateless retry is allowed. Default is not allowed.
750    /// Applicable to Server only.
751    pub fn enable_retry(&mut self, enable_retry: bool) {
752        self.retry = enable_retry;
753    }
754
755    /// Set whether stateless reset is allowed.
756    /// Applicable to Endpoint only.
757    pub fn enable_stateless_reset(&mut self, enable_stateless_reset: bool) {
758        self.stateless_reset = enable_stateless_reset;
759    }
760
761    /// Set the length of source cid.
762    /// Applicable to Endpoint only.
763    pub fn set_cid_len(&mut self, v: usize) {
764        self.cid_len = cmp::min(v, MAX_CID_LEN);
765    }
766
767    /// Omit SCID in client Initial headers (DCID still present).
768    /// Applicable to Client only.
769    pub fn set_omit_client_initial_scid(&mut self, v: bool) {
770        self.omit_client_initial_scid = v;
771    }
772
773    /// Return whether client should omit SCID in Initial.
774    pub fn omit_client_initial_scid(&self) -> bool {
775        self.omit_client_initial_scid
776    }
777
778    /// Set the anti-amplification factor.
779    ///
780    /// The server limits the data sent to an unvalidated address to
781    /// `anti_amplification_factor` times the received data.
782    pub fn set_anti_amplification_factor(&mut self, v: usize) {
783        self.anti_amplification_factor = cmp::max(v, ANTI_AMPLIFICATION_FACTOR);
784    }
785
786    /// Set the batch size for sending packets.
787    /// Applicable to Endpoint only.
788    pub fn set_send_batch_size(&mut self, v: usize) {
789        self.send_batch_size = cmp::max(v, 1);
790    }
791
792    /// Set the buffer size for disordered zerortt packets on the server.
793    /// The default value is `1000`. A value of 0 will be treated as default value.
794    /// Applicable to Server only.
795    pub fn set_zerortt_buffer_size(&mut self, v: usize) {
796        if v > 0 {
797            self.zerortt_buffer_size = v;
798        } else {
799            self.zerortt_buffer_size = 1000;
800        }
801    }
802
803    /// Set the maximum number of undecryptable packets that can be stored by one connection.
804    /// The default value is `10`. A value of 0 will be treated as default value.
805    pub fn set_max_undecryptable_packets(&mut self, v: usize) {
806        if v > 0 {
807            self.max_undecryptable_packets = v;
808        } else {
809            self.max_undecryptable_packets = 10;
810        }
811    }
812
813    /// Enable or disable encryption on 1-RTT packets. (Experimental)
814    /// The default value is true.
815    /// WARN: The The disable_1rtt_encryption extension is not meant to be used
816    /// for any practical application protocol on the open internet.
817    pub fn enable_encryption(&mut self, v: bool) {
818        self.local_transport_params.disable_encryption = !v;
819    }
820
821    /// Set TLS config.
822    pub fn set_tls_config(&mut self, tls_config: tls::TlsConfig) {
823        self.set_tls_config_selector(Arc::new(tls::DefaultTlsConfigSelector {
824            tls_config: Arc::new(tls_config),
825        }));
826    }
827
828    /// Set TLS config selector. Used for selecting TLS config according to SNI.
829    pub fn set_tls_config_selector(
830        &mut self,
831        tls_config_selector: Arc<dyn tls::TlsConfigSelector>,
832    ) {
833        self.tls_config_selector = Some(tls_config_selector);
834    }
835
836    /// Generate random address token key.
837    fn rand_address_token_key() -> Result<Vec<LessSafeKey>> {
838        let mut key = [0_u8; 16];
839        rand::rng().fill_bytes(&mut key);
840        Ok(vec![LessSafeKey::new(
841            UnboundKey::new(&aead::AES_128_GCM, &key).map_err(|_| Error::CryptoFail)?,
842        )])
843    }
844
845    /// Create new tls session.
846    fn new_tls_session(&self, server_name: Option<&str>) -> Result<TlsSession> {
847        if self.tls_config_selector.is_none() {
848            debug!("tls config selector is not set");
849            return Err(Error::TlsFail("tls config selector is not set".into()));
850        }
851        match self.tls_config_selector.as_ref().unwrap().get_default() {
852            Some(tls_config) => {
853                debug!("new tls session");
854                tls_config.new_session(server_name)
855            }
856            None => Err(Error::TlsFail("get tls config failed".into())),
857        }
858    }
859}
860
861/// Configurations about loss recovery, congestion control, and pmtu discovery.
862#[doc(hidden)]
863#[derive(Debug, Clone)]
864pub struct RecoveryConfig {
865    /// Enable Datagram Packetization Layer Path MTU Discovery.
866    pub enable_dplpmtud: bool,
867
868    /// The maximum size of outgoing UDP payloads.
869    pub max_datagram_size: usize,
870
871    /// The maximum amount of time the endpoint intends to delay acknowledgments
872    /// for packets in the Application Data packet number space.
873    max_ack_delay: Duration,
874
875    /// The maximum number of ack-eliciting packets the endpoint receives before
876    /// sending an acknowledgment.
877    ack_eliciting_threshold: u64,
878
879    /// The congestion control algorithm used for a path.
880    pub congestion_control_algorithm: CongestionControlAlgorithm,
881
882    /// The minimal congestion window in packets.
883    /// The RECOMMENDED value is 2 * max_datagram_size.
884    /// See RFC 9002 Section 7.2
885    pub min_congestion_window: u64,
886
887    /// The initial congestion window in packets.
888    /// Endpoints SHOULD use an initial congestion window of ten times the
889    /// maximum datagram size (max_datagram_size), while limiting the window to
890    /// the larger of 14,720 bytes or twice the maximum datagram size.
891    /// See RFC 9002 Section 7.2
892    pub initial_congestion_window: u64,
893
894    /// The threshold for slow start in packets.
895    pub slow_start_thresh: u64,
896
897    /// The minimum duration for BBR ProbeRTT state
898    pub bbr_probe_rtt_duration: Duration,
899
900    /// Enable using a cwnd based on bdp during ProbeRTT state.
901    pub bbr_probe_rtt_based_on_bdp: bool,
902
903    /// The cwnd gain for BBR ProbeRTT state
904    pub bbr_probe_rtt_cwnd_gain: f64,
905
906    /// The length of the RTProp min filter window
907    pub bbr_rtprop_filter_len: Duration,
908
909    /// The cwnd gain for ProbeBW state
910    pub bbr_probe_bw_cwnd_gain: f64,
911
912    /// Delta in copa slow start state.
913    pub copa_slow_start_delta: f64,
914
915    /// Delta in coap steady state.
916    pub copa_steady_delta: f64,
917
918    /// Use rtt standing instead of latest rtt to calculate queueing delay
919    pub copa_use_standing_rtt: bool,
920
921    /// The initial rtt, used before real rtt is estimated.
922    pub initial_rtt: Duration,
923
924    /// Enable pacing to smooth the flow of packets sent onto the network.
925    pub enable_pacing: bool,
926
927    /// Clock granularity used by the pacer.
928    pub pacing_granularity: Duration,
929
930    /// Linear factor for calculating the probe timeout.
931    pub pto_linear_factor: u64,
932
933    /// Upper limit of probe timeout.
934    pub max_pto: Duration,
935}
936
937impl Default for RecoveryConfig {
938    fn default() -> RecoveryConfig {
939        RecoveryConfig {
940            enable_dplpmtud: true,
941            max_datagram_size: DEFAULT_SEND_UDP_PAYLOAD_SIZE, // The upper limit is determined by DPLPMTUD
942            max_ack_delay: time::Duration::from_millis(0),
943            ack_eliciting_threshold: 2,
944            congestion_control_algorithm: CongestionControlAlgorithm::Bbr,
945            min_congestion_window: 2_u64,
946            initial_congestion_window: 10_u64,
947            slow_start_thresh: u64::MAX,
948            bbr_probe_rtt_duration: Duration::from_millis(200),
949            bbr_probe_rtt_based_on_bdp: false,
950            bbr_probe_rtt_cwnd_gain: 0.75,
951            bbr_rtprop_filter_len: Duration::from_secs(10),
952            bbr_probe_bw_cwnd_gain: 2.0,
953            copa_slow_start_delta: congestion_control::COPA_DELTA,
954            copa_steady_delta: congestion_control::COPA_DELTA,
955            copa_use_standing_rtt: true,
956            initial_rtt: INITIAL_RTT,
957            enable_pacing: true,
958            pacing_granularity: time::Duration::from_millis(1),
959            pto_linear_factor: DEFAULT_PTO_LINEAR_FACTOR,
960            max_pto: MAX_PTO,
961        }
962    }
963}
964
965/// Configurations about multipath transport.
966#[doc(hidden)]
967#[derive(Debug, Clone)]
968pub struct MultipathConfig {
969    /// Multipath scheduling algorithm.
970    multipath_algorithm: MultipathAlgorithm,
971}
972
973impl Default for MultipathConfig {
974    fn default() -> MultipathConfig {
975        MultipathConfig {
976            multipath_algorithm: MultipathAlgorithm::MinRtt,
977        }
978    }
979}
980
981/// Events sent from a Connection to an Endpoint.
982enum Event {
983    /// The connection handshake is complete.
984    ConnectionEstablished,
985
986    /// The client connection has received a NEW_TOKEN frame.
987    NewToken(Vec<u8>),
988
989    /// The connection need to advertise new scids via NEW_CONNECTION_ID frame.
990    ScidToAdvertise(u8),
991
992    /// The connection has received a RETIRE_CONNECTION_ID frame.
993    ScidRetired(ConnectionId),
994
995    /// The connection has received a dcid via NEW_CONNECTION_ID frame.
996    DcidAdvertised(ResetToken),
997
998    /// The connection has send a RETIRE_CONNECTION_ID frame.
999    DcidRetired(ResetToken),
1000
1001    /// The client connection has received a stateless reset token from transport
1002    /// parameters extension.
1003    ResetTokenAdvertised(ResetToken),
1004
1005    /// The stream is created.
1006    StreamCreated(u64),
1007
1008    /// The stream is closed.
1009    StreamClosed(u64),
1010}
1011
1012#[derive(Default)]
1013struct EventQueue(Option<VecDeque<Event>>);
1014
1015impl EventQueue {
1016    /// Enable the event queue.
1017    fn enable(&mut self) {
1018        self.0 = Some(VecDeque::new());
1019    }
1020
1021    /// Add an endpoint-faceing event.
1022    fn add(&mut self, e: Event) -> bool {
1023        if let Some(events) = &mut self.0 {
1024            events.push_back(e);
1025            return true;
1026        }
1027        false
1028    }
1029
1030    /// Return an endpoint-facing event.
1031    fn poll(&mut self) -> Option<Event> {
1032        if let Some(events) = &mut self.0 {
1033            return events.pop_front();
1034        }
1035        None
1036    }
1037
1038    /// Check whether the event queue is empty.
1039    fn is_empty(&self) -> bool {
1040        if let Some(events) = &self.0 {
1041            return events.is_empty();
1042        }
1043        true
1044    }
1045}
1046
1047struct ConnectionQueues {
1048    /// Connections with timer or other events to process.
1049    tickable: FxHashSet<u64>,
1050
1051    /// Connections with packets to be send.
1052    sendable: FxHashSet<u64>,
1053}
1054
1055impl ConnectionQueues {
1056    fn new() -> Self {
1057        Self {
1058            tickable: FxHashSet::default(),
1059            sendable: FxHashSet::default(),
1060        }
1061    }
1062
1063    fn is_empty(&self) -> bool {
1064        self.tickable.is_empty() && self.sendable.is_empty()
1065    }
1066
1067    fn tickable_next(&self) -> Option<u64> {
1068        self.tickable.iter().next().copied()
1069    }
1070
1071    fn sendable_next(&self) -> Option<u64> {
1072        self.sendable.iter().next().copied()
1073    }
1074}
1075
1076/// The TransportHandler lists the callbacks used by the endpoint to
1077/// communicate with the user application code.
1078pub trait TransportHandler {
1079    /// Called when a new connection has been created. This callback is called
1080    /// as soon as connection object is created inside the endpoint, but
1081    /// before the handshake is done. The connection has progressed enough to
1082    /// send early data if possible.
1083    fn on_conn_created(&mut self, conn: &mut Connection);
1084
1085    /// Called when the handshake is completed.
1086    fn on_conn_established(&mut self, conn: &mut Connection);
1087
1088    /// Called when the connection is closed. The connection is no longer
1089    /// accessible after this callback returns. It is a good time to clean up
1090    /// the connection context.
1091    fn on_conn_closed(&mut self, conn: &mut Connection);
1092
1093    /// Called when the stream is created.
1094    fn on_stream_created(&mut self, conn: &mut Connection, stream_id: u64);
1095
1096    /// Called when the stream is readable. This callback is called when either
1097    /// there are bytes to be read or an error is ready to be collected.
1098    fn on_stream_readable(&mut self, conn: &mut Connection, stream_id: u64);
1099
1100    /// Called when the stream is writable.
1101    fn on_stream_writable(&mut self, conn: &mut Connection, stream_id: u64);
1102
1103    /// Called when the stream is closed. The stream is no longer accessible
1104    /// after this callback returns. It is a good time to clean up the stream
1105    /// context.
1106    fn on_stream_closed(&mut self, conn: &mut Connection, stream_id: u64);
1107
1108    /// Called when client receives a token in NEW_TOKEN frame.
1109    fn on_new_token(&mut self, conn: &mut Connection, token: Vec<u8>);
1110}
1111
1112/// The PacketSendHandler lists the callbacks used by the endpoint to
1113/// send packet out.
1114pub trait PacketSendHandler {
1115    /// Called when the connection is sending packets out.
1116    ///
1117    /// On success, `on_packets_send()` returns the number of messages sent. If
1118    /// this is less than `pkts.len()`, the connection will retry with a further
1119    /// `on_packets_send()` call to send the remaining messages.
1120    fn on_packets_send(&self, pkts: &[(Vec<u8>, PacketInfo)]) -> Result<usize>;
1121}
1122
1123/// The stream's side to shutdown.
1124#[repr(C)]
1125#[derive(PartialEq, Eq)]
1126pub enum Shutdown {
1127    /// Stop receiving data on the stream.
1128    Read = 0,
1129
1130    /// Stop sending data on the stream.
1131    Write = 1,
1132}
1133
1134/// Important events about path
1135pub enum PathEvent {
1136    /// The path has been validated.
1137    Validated(usize),
1138
1139    /// The path has been abandoned.
1140    Abandoned(usize),
1141}
1142
1143/// Statistics about path
1144#[repr(C)]
1145#[derive(Default)]
1146pub struct PathStats {
1147    /// The number of QUIC packets received.
1148    pub recv_count: u64,
1149
1150    /// The number of received bytes.
1151    pub recv_bytes: u64,
1152
1153    /// The number of QUIC packets sent.
1154    pub sent_count: u64,
1155
1156    /// The number of sent bytes.
1157    pub sent_bytes: u64,
1158
1159    /// The number of QUIC packets lost.
1160    pub lost_count: u64,
1161
1162    /// The number of lost bytes.
1163    pub lost_bytes: u64,
1164
1165    /// Total number of packets acked.
1166    pub acked_count: u64,
1167
1168    /// Total number of bytes acked.
1169    pub acked_bytes: u64,
1170
1171    /// Initial congestion window in bytes.
1172    pub init_cwnd: u64,
1173
1174    /// Final congestion window in bytes.
1175    pub final_cwnd: u64,
1176
1177    /// Maximum congestion window in bytes.
1178    pub max_cwnd: u64,
1179
1180    /// Minimum congestion window in bytes.
1181    pub min_cwnd: u64,
1182
1183    /// Maximum inflight data in bytes.
1184    pub max_inflight: u64,
1185
1186    /// Total loss events.
1187    pub loss_event_count: u64,
1188
1189    /// Total congestion window limited events.
1190    pub cwnd_limited_count: u64,
1191
1192    /// Total duration of congestion windowlimited events in microseconds.
1193    pub cwnd_limited_duration: u64,
1194
1195    /* Note: the following fields are lazily updated from Recovery */
1196    /// Minimum roundtrip time in microseconds.
1197    pub min_rtt: u64,
1198
1199    /// Maximum roundtrip time in microseconds.
1200    pub max_rtt: u64,
1201
1202    /// Smoothed roundtrip time in microseconds.
1203    pub srtt: u64,
1204
1205    /// Roundtrip time variation in microseconds.
1206    pub rttvar: u64,
1207
1208    /// Whether the congestion controller is in slow start status.
1209    pub in_slow_start: bool,
1210
1211    /// Pacing rate estimated by congestion control algorithm.
1212    pub pacing_rate: u64,
1213
1214    /// Min pacing rate estimated by congestion control algorithm.
1215    pub min_pacing_rate: u64,
1216
1217    /// Record the total number of times the PTO is triggered on this path
1218    pub pto_count: u64,
1219}
1220
1221#[cfg(test)]
1222mod tests {
1223    use super::*;
1224
1225    #[ctor::ctor]
1226    fn init() {
1227        env_logger::builder()
1228            .filter_level(log::LevelFilter::Trace)
1229            .format_timestamp_millis()
1230            .is_test(true)
1231            .init();
1232    }
1233
1234    #[test]
1235    fn connection_id() {
1236        let mut cid_gen = RandomConnectionIdGenerator::new(8);
1237        let cid = cid_gen.generate();
1238        assert_eq!(cid.len(), cid_gen.cid_len());
1239
1240        let cid = ConnectionId {
1241            len: 4,
1242            data: [0xa8; 20],
1243        };
1244        assert_eq!(format!("{}", cid), "a8a8a8a8");
1245    }
1246
1247    #[test]
1248    fn initial_rtt() -> Result<()> {
1249        let mut config = Config::new()?;
1250
1251        config.set_initial_rtt(0);
1252        assert_eq!(config.recovery.initial_rtt, TIMER_GRANULARITY);
1253
1254        config.set_initial_rtt(100);
1255        assert_eq!(config.recovery.initial_rtt, Duration::from_millis(100));
1256
1257        Ok(())
1258    }
1259
1260    #[test]
1261    fn pto_linear_factor() -> Result<()> {
1262        let mut config = Config::new()?;
1263        assert_eq!(config.recovery.pto_linear_factor, DEFAULT_PTO_LINEAR_FACTOR);
1264
1265        config.set_pto_linear_factor(0);
1266        assert_eq!(config.recovery.pto_linear_factor, 0);
1267
1268        config.set_pto_linear_factor(100);
1269        assert_eq!(config.recovery.pto_linear_factor, 100);
1270
1271        Ok(())
1272    }
1273
1274    #[test]
1275    fn max_pto() -> Result<()> {
1276        let mut config = Config::new()?;
1277        assert_eq!(config.recovery.max_pto, MAX_PTO);
1278
1279        config.set_max_pto(0);
1280        assert_eq!(config.recovery.max_pto, TIMER_GRANULARITY);
1281
1282        config.set_max_pto(300000);
1283        assert_eq!(config.recovery.max_pto, Duration::from_millis(300000));
1284
1285        Ok(())
1286    }
1287
1288    #[test]
1289    fn initial_max_streams_bidi() -> Result<()> {
1290        let mut config = Config::new()?;
1291        config.set_initial_max_streams_bidi(u64::MAX);
1292        assert_eq!(
1293            config.local_transport_params.initial_max_streams_bidi,
1294            VINT_MAX
1295        );
1296
1297        Ok(())
1298    }
1299}
1300
1301pub use crate::congestion_control::CongestionControlAlgorithm;
1302pub use crate::connection::Connection;
1303pub use crate::connection::path::Path;
1304pub use crate::endpoint::Endpoint;
1305pub use crate::error::Error;
1306pub use crate::multipath_scheduler::MultipathAlgorithm;
1307pub use crate::packet::PacketHeader;
1308pub use crate::tls::CertCompressionAlgorithm;
1309pub use crate::tls::TlsConfig;
1310pub use crate::tls::TlsConfigSelector;
1311
1312#[path = "connection/connection.rs"]
1313pub mod connection;
1314
1315#[path = "congestion_control/congestion_control.rs"]
1316mod congestion_control;
1317
1318#[path = "multipath_scheduler/multipath_scheduler.rs"]
1319mod multipath_scheduler;
1320
1321#[path = "tls/tls.rs"]
1322mod tls;
1323
1324#[path = "h3/h3.rs"]
1325pub mod h3;
1326
1327#[cfg(feature = "qlog")]
1328#[path = "qlog/qlog.rs"]
1329mod qlog;
1330
1331#[cfg(feature = "ffi")]
1332mod ffi;
1333
1334// Note: Workaround for the module path issue in cbindgen.
1335// DON'T enable this feature when building with cargo.
1336#[cfg(feature = "cbindgen")]
1337#[path = "h3/connection.rs"]
1338mod h3_connection;
1339
1340pub mod client;
1341mod codec;
1342pub mod endpoint;
1343pub mod error;
1344mod frame;
1345mod packet;
1346mod ranges;
1347#[doc(hidden)]
1348pub mod timer_queue;
1349mod token;
1350mod trans_param;
1351mod window;