1#![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
86pub const QUIC_VERSION: u32 = QUIC_VERSION_V1;
88
89pub const QUIC_VERSION_V1: u32 = 0x0000_0001;
91
92fn generate_grease_version32() -> u32 {
93 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
102pub const MAX_CID_LEN: usize = 20;
105
106const MAX_CID_LIMIT: u64 = 8;
108
109const RESET_TOKEN_LEN: usize = 16;
111
112const MIN_RESET_PACKET_LEN: usize = 21;
116
117const MAX_RESET_PACKET_LEN: usize = 42;
121
122const LENGTH_FIELD_LEN: usize = 2;
124
125pub const MIN_CLIENT_INITIAL_LEN: usize = 1250;
127
128const MIN_PAYLOAD_LEN: usize = 4;
129
130const MAX_ACK_RANGES: usize = 68;
132
133const DEFAULT_SEND_UDP_PAYLOAD_SIZE: usize = 1250;
135
136const ANTI_AMPLIFICATION_FACTOR: usize = 3;
139
140pub const TIMER_GRANULARITY: Duration = Duration::from_millis(1);
143
144const MAX_STREAMS_PER_TYPE: u64 = 1 << 60;
146
147const CONNECTION_WINDOW_FACTOR: f64 = 1.5;
150
151const INITIAL_RTT: Duration = Duration::from_millis(333);
157
158const DEFAULT_HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(10);
160
161const DEFAULT_PTO_LINEAR_FACTOR: u64 = 0;
163
164const MAX_PTO: Duration = Duration::MAX;
166
167pub type Result<T> = std::result::Result<T, Error>;
169
170#[repr(C)]
173#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
174pub struct ConnectionId {
175 len: u8,
177 data: [u8; MAX_CID_LEN],
179}
180
181impl ConnectionId {
182 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 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
224pub trait ConnectionIdGenerator {
226 fn generate(&mut self) -> ConnectionId;
228
229 fn cid_len(&self) -> usize;
231
232 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#[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#[derive(Clone, Copy, Debug)]
268pub struct PacketInfo {
269 pub src: SocketAddr,
271
272 pub dst: SocketAddr,
274
275 pub time: time::Instant,
277}
278
279#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
281pub struct FourTuple {
282 pub local: SocketAddr,
284
285 pub remote: SocketAddr,
287}
288
289#[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
311fn version_is_supported(version: u32) -> bool {
313 matches!(version, QUIC_VERSION_V1)
314}
315
316#[derive(Clone)]
318pub struct Config {
319 local_transport_params: TransportParams,
321
322 max_handshake_timeout: time::Duration,
324
325 max_concurrent_conns: u32,
327
328 max_connection_window: u64,
330
331 max_stream_window: u64,
333
334 retry: bool,
337
338 stateless_reset: bool,
340
341 address_token_lifetime: Duration,
343
344 address_token_key: Vec<LessSafeKey>,
346
347 reset_token_key: hmac::Key,
349
350 cid_len: usize,
352
353 omit_client_initial_scid: bool,
356
357 anti_amplification_factor: usize,
359
360 send_batch_size: usize,
362
363 zerortt_buffer_size: usize,
365
366 max_undecryptable_packets: usize,
368
369 recovery: RecoveryConfig,
371
372 multipath: MultipathConfig,
374
375 tls_config_selector: Option<Arc<dyn tls::TlsConfigSelector>>,
377}
378
379impl Config {
380 pub fn new() -> Result<Self> {
395 let grease_ver = generate_grease_version32();
396 let local_transport_params = TransportParams {
397 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: 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 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 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 pub fn set_max_handshake_timeout(&mut self, v: u64) {
451 self.max_handshake_timeout = time::Duration::from_millis(v);
452 }
453
454 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 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 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 pub fn set_google_quic_version(&mut self, v: u32) {
478 self.local_transport_params.google_quic_version = Some(v);
479 }
480
481 pub fn set_google_initial_rtt_us(&mut self, v: u32) {
483 self.local_transport_params.google_initial_rtt = Some(v);
484 }
485
486 pub fn clear_google_initial_rtt(&mut self) {
488 self.local_transport_params.google_initial_rtt = None;
489 }
490
491 pub fn enable_dplpmtud(&mut self, v: bool) {
494 self.recovery.enable_dplpmtud = v;
495 }
496
497 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 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 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 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 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 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 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 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 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 pub fn set_ack_eliciting_threshold(&mut self, v: u64) {
564 self.recovery.ack_eliciting_threshold = v;
565 }
566
567 pub fn set_congestion_control_algorithm(&mut self, cca: CongestionControlAlgorithm) {
570 self.recovery.congestion_control_algorithm = cca;
571 }
572
573 pub fn set_initial_congestion_window(&mut self, packets: u64) {
576 self.recovery.initial_congestion_window = packets;
577 }
578
579 pub fn set_min_congestion_window(&mut self, packets: u64) {
582 self.recovery.min_congestion_window = packets
583 }
584
585 pub fn set_slow_start_thresh(&mut self, packets: u64) {
588 self.recovery.slow_start_thresh = packets
589 }
590
591 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 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 pub fn set_bbr_probe_rtt_cwnd_gain(&mut self, v: f64) {
609 self.recovery.bbr_probe_rtt_cwnd_gain = v;
610 }
611
612 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 pub fn set_bbr_probe_bw_cwnd_gain(&mut self, v: f64) {
622 self.recovery.bbr_probe_bw_cwnd_gain = v;
623 }
624
625 pub fn set_copa_slow_start_delta(&mut self, v: f64) {
627 self.recovery.copa_slow_start_delta = v;
628 }
629
630 pub fn set_copa_steady_delta(&mut self, v: f64) {
632 self.recovery.copa_steady_delta = v;
633 }
634
635 pub fn enable_copa_use_standing_rtt(&mut self, v: bool) {
637 self.recovery.copa_use_standing_rtt = v;
638 }
639
640 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 pub fn enable_pacing(&mut self, v: bool) {
651 self.recovery.enable_pacing = v;
652 }
653
654 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 pub fn set_pto_linear_factor(&mut self, v: u64) {
667 self.recovery.pto_linear_factor = v;
668 }
669
670 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 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 pub fn enable_multipath(&mut self, v: bool) {
689 self.local_transport_params.enable_multipath = v;
690 }
691
692 pub fn set_multipath_algorithm(&mut self, v: MultipathAlgorithm) {
695 self.multipath.multipath_algorithm = v;
696 }
697
698 pub fn set_max_connection_window(&mut self, v: u64) {
701 self.max_connection_window = cmp::min(v, VINT_MAX);
702 }
703
704 pub fn set_max_stream_window(&mut self, v: u64) {
708 self.max_stream_window = cmp::min(v, VINT_MAX);
709 }
710
711 pub fn set_max_concurrent_conns(&mut self, v: u32) {
714 self.max_concurrent_conns = v;
715 }
716
717 pub fn set_reset_token_key(&mut self, v: [u8; 64]) {
720 self.reset_token_key = hmac::Key::new(hmac::HMAC_SHA256, &v);
722 }
723
724 pub fn set_address_token_lifetime(&mut self, seconds: u64) {
727 self.address_token_lifetime = Duration::from_secs(seconds);
728 }
729
730 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 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 pub fn enable_retry(&mut self, enable_retry: bool) {
752 self.retry = enable_retry;
753 }
754
755 pub fn enable_stateless_reset(&mut self, enable_stateless_reset: bool) {
758 self.stateless_reset = enable_stateless_reset;
759 }
760
761 pub fn set_cid_len(&mut self, v: usize) {
764 self.cid_len = cmp::min(v, MAX_CID_LEN);
765 }
766
767 pub fn set_omit_client_initial_scid(&mut self, v: bool) {
770 self.omit_client_initial_scid = v;
771 }
772
773 pub fn omit_client_initial_scid(&self) -> bool {
775 self.omit_client_initial_scid
776 }
777
778 pub fn set_anti_amplification_factor(&mut self, v: usize) {
783 self.anti_amplification_factor = cmp::max(v, ANTI_AMPLIFICATION_FACTOR);
784 }
785
786 pub fn set_send_batch_size(&mut self, v: usize) {
789 self.send_batch_size = cmp::max(v, 1);
790 }
791
792 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 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 pub fn enable_encryption(&mut self, v: bool) {
818 self.local_transport_params.disable_encryption = !v;
819 }
820
821 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 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 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 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#[doc(hidden)]
863#[derive(Debug, Clone)]
864pub struct RecoveryConfig {
865 pub enable_dplpmtud: bool,
867
868 pub max_datagram_size: usize,
870
871 max_ack_delay: Duration,
874
875 ack_eliciting_threshold: u64,
878
879 pub congestion_control_algorithm: CongestionControlAlgorithm,
881
882 pub min_congestion_window: u64,
886
887 pub initial_congestion_window: u64,
893
894 pub slow_start_thresh: u64,
896
897 pub bbr_probe_rtt_duration: Duration,
899
900 pub bbr_probe_rtt_based_on_bdp: bool,
902
903 pub bbr_probe_rtt_cwnd_gain: f64,
905
906 pub bbr_rtprop_filter_len: Duration,
908
909 pub bbr_probe_bw_cwnd_gain: f64,
911
912 pub copa_slow_start_delta: f64,
914
915 pub copa_steady_delta: f64,
917
918 pub copa_use_standing_rtt: bool,
920
921 pub initial_rtt: Duration,
923
924 pub enable_pacing: bool,
926
927 pub pacing_granularity: Duration,
929
930 pub pto_linear_factor: u64,
932
933 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, 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#[doc(hidden)]
967#[derive(Debug, Clone)]
968pub struct MultipathConfig {
969 multipath_algorithm: MultipathAlgorithm,
971}
972
973impl Default for MultipathConfig {
974 fn default() -> MultipathConfig {
975 MultipathConfig {
976 multipath_algorithm: MultipathAlgorithm::MinRtt,
977 }
978 }
979}
980
981enum Event {
983 ConnectionEstablished,
985
986 NewToken(Vec<u8>),
988
989 ScidToAdvertise(u8),
991
992 ScidRetired(ConnectionId),
994
995 DcidAdvertised(ResetToken),
997
998 DcidRetired(ResetToken),
1000
1001 ResetTokenAdvertised(ResetToken),
1004
1005 StreamCreated(u64),
1007
1008 StreamClosed(u64),
1010}
1011
1012#[derive(Default)]
1013struct EventQueue(Option<VecDeque<Event>>);
1014
1015impl EventQueue {
1016 fn enable(&mut self) {
1018 self.0 = Some(VecDeque::new());
1019 }
1020
1021 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 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 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 tickable: FxHashSet<u64>,
1050
1051 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
1076pub trait TransportHandler {
1079 fn on_conn_created(&mut self, conn: &mut Connection);
1084
1085 fn on_conn_established(&mut self, conn: &mut Connection);
1087
1088 fn on_conn_closed(&mut self, conn: &mut Connection);
1092
1093 fn on_stream_created(&mut self, conn: &mut Connection, stream_id: u64);
1095
1096 fn on_stream_readable(&mut self, conn: &mut Connection, stream_id: u64);
1099
1100 fn on_stream_writable(&mut self, conn: &mut Connection, stream_id: u64);
1102
1103 fn on_stream_closed(&mut self, conn: &mut Connection, stream_id: u64);
1107
1108 fn on_new_token(&mut self, conn: &mut Connection, token: Vec<u8>);
1110}
1111
1112pub trait PacketSendHandler {
1115 fn on_packets_send(&self, pkts: &[(Vec<u8>, PacketInfo)]) -> Result<usize>;
1121}
1122
1123#[repr(C)]
1125#[derive(PartialEq, Eq)]
1126pub enum Shutdown {
1127 Read = 0,
1129
1130 Write = 1,
1132}
1133
1134pub enum PathEvent {
1136 Validated(usize),
1138
1139 Abandoned(usize),
1141}
1142
1143#[repr(C)]
1145#[derive(Default)]
1146pub struct PathStats {
1147 pub recv_count: u64,
1149
1150 pub recv_bytes: u64,
1152
1153 pub sent_count: u64,
1155
1156 pub sent_bytes: u64,
1158
1159 pub lost_count: u64,
1161
1162 pub lost_bytes: u64,
1164
1165 pub acked_count: u64,
1167
1168 pub acked_bytes: u64,
1170
1171 pub init_cwnd: u64,
1173
1174 pub final_cwnd: u64,
1176
1177 pub max_cwnd: u64,
1179
1180 pub min_cwnd: u64,
1182
1183 pub max_inflight: u64,
1185
1186 pub loss_event_count: u64,
1188
1189 pub cwnd_limited_count: u64,
1191
1192 pub cwnd_limited_duration: u64,
1194
1195 pub min_rtt: u64,
1198
1199 pub max_rtt: u64,
1201
1202 pub srtt: u64,
1204
1205 pub rttvar: u64,
1207
1208 pub in_slow_start: bool,
1210
1211 pub pacing_rate: u64,
1213
1214 pub min_pacing_rate: u64,
1216
1217 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#[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;