1#![allow(unused_imports)]
54#![allow(dead_code)]
55#![allow(unexpected_cfgs)]
56
57use std::cmp;
58use std::collections::VecDeque;
59use std::fmt;
60use std::net::IpAddr;
61use std::net::SocketAddr;
62use std::sync::Arc;
63use std::time;
64use std::time::Duration;
65use std::time::Instant;
66
67use bytes::Buf;
68use bytes::BufMut;
69use rand::RngCore;
70use ring::aead;
71use ring::aead::LessSafeKey;
72use ring::aead::UnboundKey;
73use ring::hmac;
74use rustc_hash::FxHashSet;
75
76use crate::codec::VINT_MAX;
77use crate::connection::stream;
78use crate::tls::TlsSession;
79use crate::token::ResetToken;
80use crate::trans_param::TransportParams;
81
82pub const QUIC_VERSION: u32 = QUIC_VERSION_V1;
84
85pub const QUIC_VERSION_V1: u32 = 0x0000_0001;
87
88pub const MAX_CID_LEN: usize = 20;
91
92const MAX_CID_LIMIT: u64 = 8;
94
95const RESET_TOKEN_LEN: usize = 16;
97
98const MIN_RESET_PACKET_LEN: usize = 21;
102
103const MAX_RESET_PACKET_LEN: usize = 42;
107
108const LENGTH_FIELD_LEN: usize = 2;
110
111pub const MIN_CLIENT_INITIAL_LEN: usize = 1200;
113
114const MIN_PAYLOAD_LEN: usize = 4;
115
116const MAX_ACK_RANGES: usize = 68;
118
119const DEFAULT_SEND_UDP_PAYLOAD_SIZE: usize = 1200;
121
122const ANTI_AMPLIFICATION_FACTOR: usize = 3;
125
126pub const TIMER_GRANULARITY: Duration = Duration::from_millis(1);
129
130const MAX_STREAMS_PER_TYPE: u64 = 1 << 60;
132
133const CONNECTION_WINDOW_FACTOR: f64 = 1.5;
136
137const INITIAL_RTT: Duration = Duration::from_millis(333);
143
144const DEFAULT_HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(30);
146
147const DEFAULT_PTO_LINEAR_FACTOR: u64 = 0;
149
150const MAX_PTO: Duration = Duration::MAX;
152
153pub type Result<T> = std::result::Result<T, Error>;
155
156#[repr(C)]
159#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
160pub struct ConnectionId {
161 len: u8,
163 data: [u8; MAX_CID_LEN],
165}
166
167impl ConnectionId {
168 pub fn new(bytes: &[u8]) -> Self {
170 let len = cmp::min(bytes.len(), MAX_CID_LEN);
171 let mut cid = Self {
172 len: len as u8,
173 data: [0; MAX_CID_LEN],
174 };
175 cid.data[..len].copy_from_slice(&bytes[..len]);
176 cid
177 }
178
179 pub fn random() -> Self {
181 Self {
182 len: MAX_CID_LEN as u8,
183 data: rand::random::<[u8; MAX_CID_LEN]>(),
184 }
185 }
186}
187
188impl std::ops::Deref for ConnectionId {
189 type Target = [u8];
190 fn deref(&self) -> &[u8] {
191 &self.data[0..self.len as usize]
192 }
193}
194
195impl fmt::Debug for ConnectionId {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 for b in self.iter() {
198 write!(f, "{b:02x}")?;
199 }
200 Ok(())
201 }
202}
203
204impl fmt::Display for ConnectionId {
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 fmt::Debug::fmt(self, f)
207 }
208}
209
210pub trait ConnectionIdGenerator {
212 fn generate(&mut self) -> ConnectionId;
214
215 fn cid_len(&self) -> usize;
217
218 fn generate_cid_and_token(&mut self, reset_token_key: &hmac::Key) -> (ConnectionId, u128) {
220 let scid = self.generate();
221 let reset_token = ResetToken::generate(reset_token_key, &scid);
222 (scid, reset_token.to_u128())
223 }
224}
225
226#[derive(Debug, Clone, Copy)]
228pub struct RandomConnectionIdGenerator {
229 cid_len: usize,
230}
231
232impl RandomConnectionIdGenerator {
233 pub fn new(cid_len: usize) -> Self {
234 Self {
235 cid_len: cmp::min(cid_len, MAX_CID_LEN),
236 }
237 }
238}
239
240impl ConnectionIdGenerator for RandomConnectionIdGenerator {
241 fn generate(&mut self) -> ConnectionId {
242 let mut bytes = [0; MAX_CID_LEN];
243 rand::thread_rng().fill_bytes(&mut bytes[..self.cid_len]);
244 ConnectionId::new(&bytes[..self.cid_len])
245 }
246
247 fn cid_len(&self) -> usize {
248 self.cid_len
249 }
250}
251
252#[derive(Clone, Copy, Debug)]
254pub struct PacketInfo {
255 pub src: SocketAddr,
257
258 pub dst: SocketAddr,
260
261 pub time: time::Instant,
263}
264
265#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
267pub struct FourTuple {
268 pub local: SocketAddr,
270
271 pub remote: SocketAddr,
273}
274
275#[derive(Default)]
277pub struct FourTupleIter {
278 pub(crate) addrs: Vec<FourTuple>,
279}
280
281impl Iterator for FourTupleIter {
282 type Item = FourTuple;
283
284 #[inline]
285 fn next(&mut self) -> Option<Self::Item> {
286 self.addrs.pop()
287 }
288}
289
290impl ExactSizeIterator for FourTupleIter {
291 #[inline]
292 fn len(&self) -> usize {
293 self.addrs.len()
294 }
295}
296
297fn version_is_supported(version: u32) -> bool {
299 matches!(version, QUIC_VERSION_V1)
300}
301
302#[derive(Clone)]
304pub struct Config {
305 local_transport_params: TransportParams,
307
308 max_handshake_timeout: time::Duration,
310
311 max_concurrent_conns: u32,
313
314 max_connection_window: u64,
316
317 max_stream_window: u64,
319
320 retry: bool,
323
324 stateless_reset: bool,
326
327 address_token_lifetime: Duration,
329
330 address_token_key: Vec<LessSafeKey>,
332
333 reset_token_key: hmac::Key,
335
336 cid_len: usize,
338
339 anti_amplification_factor: usize,
341
342 send_batch_size: usize,
344
345 zerortt_buffer_size: usize,
347
348 max_undecryptable_packets: usize,
350
351 recovery: RecoveryConfig,
353
354 multipath: MultipathConfig,
356
357 tls_config_selector: Option<Arc<dyn tls::TlsConfigSelector>>,
359}
360
361impl Config {
362 pub fn new() -> Result<Self> {
377 let local_transport_params = TransportParams {
378 initial_max_data: 10485760,
379 initial_max_stream_data_bidi_local: 5242880,
380 initial_max_stream_data_bidi_remote: 2097152,
381 initial_max_stream_data_uni: 1048576,
382 initial_max_streams_bidi: 200,
383 initial_max_streams_uni: 100,
384 ..TransportParams::default()
385 };
386
387 let reset_token_key = hmac::Key::new(hmac::HMAC_SHA256, &[]);
388
389 Ok(Self {
390 local_transport_params,
391 max_handshake_timeout: DEFAULT_HANDSHAKE_TIMEOUT,
392 max_concurrent_conns: 1000000,
393 max_connection_window: stream::MAX_CONNECTION_WINDOW,
394 max_stream_window: stream::MAX_STREAM_WINDOW,
395 retry: false,
396 stateless_reset: true,
397 address_token_lifetime: Duration::from_secs(86400),
398 address_token_key: Self::rand_address_token_key()?,
399 reset_token_key,
400 cid_len: 8,
401 anti_amplification_factor: ANTI_AMPLIFICATION_FACTOR,
402 send_batch_size: 64,
403 zerortt_buffer_size: 1000,
404 max_undecryptable_packets: 10,
405 recovery: RecoveryConfig::default(),
406 multipath: MultipathConfig::default(),
407 tls_config_selector: None,
408 })
409 }
410
411 pub fn set_max_idle_timeout(&mut self, v: u64) {
414 self.local_transport_params.max_idle_timeout = cmp::min(v, VINT_MAX);
415 }
416
417 pub fn set_max_handshake_timeout(&mut self, v: u64) {
419 self.max_handshake_timeout = time::Duration::from_millis(v);
420 }
421
422 pub fn set_recv_udp_payload_size(&mut self, v: u16) {
426 self.local_transport_params.max_udp_payload_size = cmp::min(v as u64, VINT_MAX);
427 }
428
429 pub fn enable_dplpmtud(&mut self, v: bool) {
432 self.recovery.enable_dplpmtud = v;
433 }
434
435 pub fn set_send_udp_payload_size(&mut self, v: usize) {
439 self.recovery.max_datagram_size = cmp::max(v, DEFAULT_SEND_UDP_PAYLOAD_SIZE);
440 }
441
442 pub fn set_initial_max_data(&mut self, v: u64) {
447 self.local_transport_params.initial_max_data = cmp::min(v, self.max_connection_window);
448 }
449
450 pub fn set_initial_max_stream_data_bidi_local(&mut self, v: u64) {
454 self.local_transport_params
455 .initial_max_stream_data_bidi_local = cmp::min(v, self.max_stream_window);
456 }
457
458 pub fn set_initial_max_stream_data_bidi_remote(&mut self, v: u64) {
462 self.local_transport_params
463 .initial_max_stream_data_bidi_remote = cmp::min(v, self.max_stream_window);
464 }
465
466 pub fn set_initial_max_stream_data_uni(&mut self, v: u64) {
470 self.local_transport_params.initial_max_stream_data_uni =
471 cmp::min(v, self.max_stream_window);
472 }
473
474 pub fn set_initial_max_streams_bidi(&mut self, v: u64) {
477 self.local_transport_params.initial_max_streams_bidi = cmp::min(v, VINT_MAX);
478 }
479
480 pub fn set_initial_max_streams_uni(&mut self, v: u64) {
483 self.local_transport_params.initial_max_streams_uni = cmp::min(v, VINT_MAX);
484 }
485
486 pub fn set_ack_delay_exponent(&mut self, v: u64) {
489 self.local_transport_params.ack_delay_exponent = cmp::min(v, VINT_MAX);
490 }
491
492 pub fn set_max_ack_delay(&mut self, v: u64) {
495 self.local_transport_params.max_ack_delay = cmp::min(v, VINT_MAX);
496 }
497
498 pub fn set_ack_eliciting_threshold(&mut self, v: u64) {
502 self.recovery.ack_eliciting_threshold = v;
503 }
504
505 pub fn set_congestion_control_algorithm(&mut self, cca: CongestionControlAlgorithm) {
508 self.recovery.congestion_control_algorithm = cca;
509 }
510
511 pub fn set_initial_congestion_window(&mut self, packets: u64) {
514 self.recovery.initial_congestion_window = packets;
515 }
516
517 pub fn set_min_congestion_window(&mut self, packets: u64) {
520 self.recovery.min_congestion_window = packets
521 }
522
523 pub fn set_slow_start_thresh(&mut self, packets: u64) {
526 self.recovery.slow_start_thresh = packets
527 }
528
529 pub fn set_bbr_probe_rtt_duration(&mut self, millis: u64) {
532 self.recovery.bbr_probe_rtt_duration =
533 cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
534 }
535
536 pub fn enable_bbr_probe_rtt_based_on_bdp(&mut self, v: bool) {
539 self.recovery.bbr_probe_rtt_based_on_bdp = v;
540 }
541
542 pub fn set_bbr_probe_rtt_cwnd_gain(&mut self, v: f64) {
547 self.recovery.bbr_probe_rtt_cwnd_gain = v;
548 }
549
550 pub fn set_bbr_rtprop_filter_len(&mut self, millis: u64) {
553 self.recovery.bbr_rtprop_filter_len =
554 cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
555 }
556
557 pub fn set_bbr_probe_bw_cwnd_gain(&mut self, v: f64) {
560 self.recovery.bbr_probe_bw_cwnd_gain = v;
561 }
562
563 pub fn set_copa_slow_start_delta(&mut self, v: f64) {
565 self.recovery.copa_slow_start_delta = v;
566 }
567
568 pub fn set_copa_steady_delta(&mut self, v: f64) {
570 self.recovery.copa_steady_delta = v;
571 }
572
573 pub fn enable_copa_use_standing_rtt(&mut self, v: bool) {
575 self.recovery.copa_use_standing_rtt = v;
576 }
577
578 pub fn set_initial_rtt(&mut self, millis: u64) {
583 self.recovery.initial_rtt = cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
584 }
585
586 pub fn enable_pacing(&mut self, v: bool) {
589 self.recovery.enable_pacing = v;
590 }
591
592 pub fn set_pacing_granularity(&mut self, millis: u64) {
595 self.recovery.pacing_granularity =
596 cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
597 }
598
599 pub fn set_pto_linear_factor(&mut self, v: u64) {
605 self.recovery.pto_linear_factor = v;
606 }
607
608 pub fn set_max_pto(&mut self, millis: u64) {
613 self.recovery.max_pto = cmp::max(Duration::from_millis(millis), TIMER_GRANULARITY);
614 }
615
616 pub fn set_active_connection_id_limit(&mut self, v: u64) {
619 if v >= 2 {
620 self.local_transport_params.active_conn_id_limit = cmp::min(v, VINT_MAX);
621 }
622 }
623
624 pub fn enable_multipath(&mut self, v: bool) {
627 self.local_transport_params.enable_multipath = v;
628 }
629
630 pub fn set_multipath_algorithm(&mut self, v: MultipathAlgorithm) {
633 self.multipath.multipath_algorithm = v;
634 }
635
636 pub fn set_max_connection_window(&mut self, v: u64) {
639 self.max_connection_window = cmp::min(v, VINT_MAX);
640 }
641
642 pub fn set_max_stream_window(&mut self, v: u64) {
646 self.max_stream_window = cmp::min(v, VINT_MAX);
647 }
648
649 pub fn set_max_concurrent_conns(&mut self, v: u32) {
652 self.max_concurrent_conns = v;
653 }
654
655 pub fn set_reset_token_key(&mut self, v: [u8; 64]) {
658 self.reset_token_key = hmac::Key::new(hmac::HMAC_SHA256, &v);
660 }
661
662 pub fn set_address_token_lifetime(&mut self, seconds: u64) {
665 self.address_token_lifetime = Duration::from_secs(seconds);
666 }
667
668 pub fn set_address_token_key(&mut self, keys: Vec<[u8; 16]>) -> Result<()> {
671 if keys.is_empty() {
672 return Err(Error::InvalidConfig("address token key empty".into()));
673 }
674
675 let mut address_token_key = vec![];
676 for key in keys {
677 let key = UnboundKey::new(&aead::AES_128_GCM, &key).map_err(|_| Error::CryptoFail)?;
679 let key = LessSafeKey::new(key);
680 address_token_key.push(key);
681 }
682 self.address_token_key = address_token_key;
683
684 Ok(())
685 }
686
687 pub fn enable_retry(&mut self, enable_retry: bool) {
690 self.retry = enable_retry;
691 }
692
693 pub fn enable_stateless_reset(&mut self, enable_stateless_reset: bool) {
696 self.stateless_reset = enable_stateless_reset;
697 }
698
699 pub fn set_cid_len(&mut self, v: usize) {
702 self.cid_len = cmp::min(v, MAX_CID_LEN);
703 }
704
705 pub fn set_anti_amplification_factor(&mut self, v: usize) {
710 self.anti_amplification_factor = cmp::max(v, ANTI_AMPLIFICATION_FACTOR);
711 }
712
713 pub fn set_send_batch_size(&mut self, v: usize) {
716 self.send_batch_size = cmp::max(v, 1);
717 }
718
719 pub fn set_zerortt_buffer_size(&mut self, v: usize) {
723 if v > 0 {
724 self.zerortt_buffer_size = v;
725 } else {
726 self.zerortt_buffer_size = 1000;
727 }
728 }
729
730 pub fn set_max_undecryptable_packets(&mut self, v: usize) {
733 if v > 0 {
734 self.max_undecryptable_packets = v;
735 } else {
736 self.max_undecryptable_packets = 10;
737 }
738 }
739
740 pub fn enable_encryption(&mut self, v: bool) {
745 self.local_transport_params.disable_encryption = !v;
746 }
747
748 pub fn set_tls_config(&mut self, tls_config: tls::TlsConfig) {
750 self.set_tls_config_selector(Arc::new(tls::DefaultTlsConfigSelector {
751 tls_config: Arc::new(tls_config),
752 }));
753 }
754
755 pub fn set_tls_config_selector(
757 &mut self,
758 tls_config_selector: Arc<dyn tls::TlsConfigSelector>,
759 ) {
760 self.tls_config_selector = Some(tls_config_selector);
761 }
762
763 fn rand_address_token_key() -> Result<Vec<LessSafeKey>> {
765 let mut key = [0_u8; 16];
766 rand::thread_rng().fill_bytes(&mut key);
767 Ok(vec![LessSafeKey::new(
768 UnboundKey::new(&aead::AES_128_GCM, &key).map_err(|_| Error::CryptoFail)?,
769 )])
770 }
771
772 fn new_tls_session(&self, server_name: Option<&str>, is_server: bool) -> Result<TlsSession> {
774 if self.tls_config_selector.is_none() {
775 return Err(Error::TlsFail("tls config selector is not set".into()));
776 }
777 match self.tls_config_selector.as_ref().unwrap().get_default() {
778 Some(tls_config) => tls_config.new_session(server_name, is_server),
779 None => Err(Error::TlsFail("get tls config failed".into())),
780 }
781 }
782}
783
784#[doc(hidden)]
786#[derive(Debug, Clone)]
787pub struct RecoveryConfig {
788 pub enable_dplpmtud: bool,
790
791 pub max_datagram_size: usize,
793
794 max_ack_delay: Duration,
797
798 ack_eliciting_threshold: u64,
801
802 pub congestion_control_algorithm: CongestionControlAlgorithm,
804
805 pub min_congestion_window: u64,
809
810 pub initial_congestion_window: u64,
816
817 pub slow_start_thresh: u64,
819
820 pub bbr_probe_rtt_duration: Duration,
822
823 pub bbr_probe_rtt_based_on_bdp: bool,
825
826 pub bbr_probe_rtt_cwnd_gain: f64,
828
829 pub bbr_rtprop_filter_len: Duration,
831
832 pub bbr_probe_bw_cwnd_gain: f64,
834
835 pub copa_slow_start_delta: f64,
837
838 pub copa_steady_delta: f64,
840
841 pub copa_use_standing_rtt: bool,
843
844 pub initial_rtt: Duration,
846
847 pub enable_pacing: bool,
849
850 pub pacing_granularity: Duration,
852
853 pub pto_linear_factor: u64,
855
856 pub max_pto: Duration,
858}
859
860impl Default for RecoveryConfig {
861 fn default() -> RecoveryConfig {
862 RecoveryConfig {
863 enable_dplpmtud: true,
864 max_datagram_size: DEFAULT_SEND_UDP_PAYLOAD_SIZE, max_ack_delay: time::Duration::from_millis(0),
866 ack_eliciting_threshold: 2,
867 congestion_control_algorithm: CongestionControlAlgorithm::Bbr,
868 min_congestion_window: 2_u64,
869 initial_congestion_window: 10_u64,
870 slow_start_thresh: u64::MAX,
871 bbr_probe_rtt_duration: Duration::from_millis(200),
872 bbr_probe_rtt_based_on_bdp: false,
873 bbr_probe_rtt_cwnd_gain: 0.75,
874 bbr_rtprop_filter_len: Duration::from_secs(10),
875 bbr_probe_bw_cwnd_gain: 2.0,
876 copa_slow_start_delta: congestion_control::COPA_DELTA,
877 copa_steady_delta: congestion_control::COPA_DELTA,
878 copa_use_standing_rtt: true,
879 initial_rtt: INITIAL_RTT,
880 enable_pacing: true,
881 pacing_granularity: time::Duration::from_millis(1),
882 pto_linear_factor: DEFAULT_PTO_LINEAR_FACTOR,
883 max_pto: MAX_PTO,
884 }
885 }
886}
887
888#[doc(hidden)]
890#[derive(Debug, Clone)]
891pub struct MultipathConfig {
892 multipath_algorithm: MultipathAlgorithm,
894}
895
896impl Default for MultipathConfig {
897 fn default() -> MultipathConfig {
898 MultipathConfig {
899 multipath_algorithm: MultipathAlgorithm::MinRtt,
900 }
901 }
902}
903
904enum Event {
906 ConnectionEstablished,
908
909 NewToken(Vec<u8>),
911
912 ScidToAdvertise(u8),
914
915 ScidRetired(ConnectionId),
917
918 DcidAdvertised(ResetToken),
920
921 DcidRetired(ResetToken),
923
924 ResetTokenAdvertised(ResetToken),
927
928 StreamCreated(u64),
930
931 StreamClosed(u64),
933}
934
935#[derive(Default)]
936struct EventQueue(Option<VecDeque<Event>>);
937
938impl EventQueue {
939 fn enable(&mut self) {
941 self.0 = Some(VecDeque::new());
942 }
943
944 fn add(&mut self, e: Event) -> bool {
946 if let Some(events) = &mut self.0 {
947 events.push_back(e);
948 return true;
949 }
950 false
951 }
952
953 fn poll(&mut self) -> Option<Event> {
955 if let Some(events) = &mut self.0 {
956 return events.pop_front();
957 }
958 None
959 }
960
961 fn is_empty(&self) -> bool {
963 if let Some(events) = &self.0 {
964 return events.is_empty();
965 }
966 true
967 }
968}
969
970struct ConnectionQueues {
971 tickable: FxHashSet<u64>,
973
974 sendable: FxHashSet<u64>,
976}
977
978impl ConnectionQueues {
979 fn new() -> Self {
980 Self {
981 tickable: FxHashSet::default(),
982 sendable: FxHashSet::default(),
983 }
984 }
985
986 fn is_empty(&self) -> bool {
987 self.tickable.is_empty() && self.sendable.is_empty()
988 }
989
990 fn tickable_next(&self) -> Option<u64> {
991 self.tickable.iter().next().copied()
992 }
993
994 fn sendable_next(&self) -> Option<u64> {
995 self.sendable.iter().next().copied()
996 }
997}
998
999pub trait TransportHandler {
1002 fn on_conn_created(&mut self, conn: &mut Connection);
1007
1008 fn on_conn_established(&mut self, conn: &mut Connection);
1010
1011 fn on_conn_closed(&mut self, conn: &mut Connection);
1015
1016 fn on_stream_created(&mut self, conn: &mut Connection, stream_id: u64);
1018
1019 fn on_stream_readable(&mut self, conn: &mut Connection, stream_id: u64);
1022
1023 fn on_stream_writable(&mut self, conn: &mut Connection, stream_id: u64);
1025
1026 fn on_stream_closed(&mut self, conn: &mut Connection, stream_id: u64);
1030
1031 fn on_new_token(&mut self, conn: &mut Connection, token: Vec<u8>);
1033}
1034
1035pub trait PacketSendHandler {
1038 fn on_packets_send(&self, pkts: &[(Vec<u8>, PacketInfo)]) -> Result<usize>;
1044}
1045
1046#[repr(C)]
1048#[derive(PartialEq, Eq)]
1049pub enum Shutdown {
1050 Read = 0,
1052
1053 Write = 1,
1055}
1056
1057pub enum PathEvent {
1059 Validated(usize),
1061
1062 Abandoned(usize),
1064}
1065
1066#[repr(C)]
1068#[derive(Default)]
1069pub struct PathStats {
1070 pub recv_count: u64,
1072
1073 pub recv_bytes: u64,
1075
1076 pub sent_count: u64,
1078
1079 pub sent_bytes: u64,
1081
1082 pub lost_count: u64,
1084
1085 pub lost_bytes: u64,
1087
1088 pub acked_count: u64,
1090
1091 pub acked_bytes: u64,
1093
1094 pub init_cwnd: u64,
1096
1097 pub final_cwnd: u64,
1099
1100 pub max_cwnd: u64,
1102
1103 pub min_cwnd: u64,
1105
1106 pub max_inflight: u64,
1108
1109 pub loss_event_count: u64,
1111
1112 pub cwnd_limited_count: u64,
1114
1115 pub cwnd_limited_duration: u64,
1117
1118 pub min_rtt: u64,
1121
1122 pub max_rtt: u64,
1124
1125 pub srtt: u64,
1127
1128 pub rttvar: u64,
1130
1131 pub in_slow_start: bool,
1133
1134 pub pacing_rate: u64,
1136}
1137
1138#[cfg(test)]
1139mod tests {
1140 use super::*;
1141
1142 #[ctor::ctor]
1143 fn init() {
1144 env_logger::builder()
1145 .filter_level(log::LevelFilter::Trace)
1146 .format_timestamp_millis()
1147 .is_test(true)
1148 .init();
1149 }
1150
1151 #[test]
1152 fn connection_id() {
1153 let mut cid_gen = RandomConnectionIdGenerator::new(8);
1154 let cid = cid_gen.generate();
1155 assert_eq!(cid.len(), cid_gen.cid_len());
1156
1157 let cid = ConnectionId {
1158 len: 4,
1159 data: [0xa8; 20],
1160 };
1161 assert_eq!(format!("{}", cid), "a8a8a8a8");
1162 }
1163
1164 #[test]
1165 fn initial_rtt() -> Result<()> {
1166 let mut config = Config::new()?;
1167
1168 config.set_initial_rtt(0);
1169 assert_eq!(config.recovery.initial_rtt, TIMER_GRANULARITY);
1170
1171 config.set_initial_rtt(100);
1172 assert_eq!(config.recovery.initial_rtt, Duration::from_millis(100));
1173
1174 Ok(())
1175 }
1176
1177 #[test]
1178 fn pto_linear_factor() -> Result<()> {
1179 let mut config = Config::new()?;
1180 assert_eq!(config.recovery.pto_linear_factor, DEFAULT_PTO_LINEAR_FACTOR);
1181
1182 config.set_pto_linear_factor(0);
1183 assert_eq!(config.recovery.pto_linear_factor, 0);
1184
1185 config.set_pto_linear_factor(100);
1186 assert_eq!(config.recovery.pto_linear_factor, 100);
1187
1188 Ok(())
1189 }
1190
1191 #[test]
1192 fn max_pto() -> Result<()> {
1193 let mut config = Config::new()?;
1194 assert_eq!(config.recovery.max_pto, MAX_PTO);
1195
1196 config.set_max_pto(0);
1197 assert_eq!(config.recovery.max_pto, TIMER_GRANULARITY);
1198
1199 config.set_max_pto(300000);
1200 assert_eq!(config.recovery.max_pto, Duration::from_millis(300000));
1201
1202 Ok(())
1203 }
1204
1205 #[test]
1206 fn initial_max_streams_bidi() -> Result<()> {
1207 let mut config = Config::new()?;
1208 config.set_initial_max_streams_bidi(u64::MAX);
1209 assert_eq!(
1210 config.local_transport_params.initial_max_streams_bidi,
1211 VINT_MAX
1212 );
1213
1214 Ok(())
1215 }
1216}
1217
1218pub use crate::congestion_control::CongestionControlAlgorithm;
1219pub use crate::connection::path::Path;
1220pub use crate::connection::Connection;
1221pub use crate::endpoint::Endpoint;
1222pub use crate::error::Error;
1223pub use crate::multipath_scheduler::MultipathAlgorithm;
1224pub use crate::packet::PacketHeader;
1225pub use crate::tls::TlsConfig;
1226pub use crate::tls::TlsConfigSelector;
1227
1228#[path = "connection/connection.rs"]
1229pub mod connection;
1230
1231#[path = "congestion_control/congestion_control.rs"]
1232mod congestion_control;
1233
1234#[path = "multipath_scheduler/multipath_scheduler.rs"]
1235mod multipath_scheduler;
1236
1237#[path = "tls/tls.rs"]
1238mod tls;
1239
1240#[cfg(feature = "h3")]
1241#[path = "h3/h3.rs"]
1242pub mod h3;
1243
1244#[cfg(feature = "qlog")]
1245#[path = "qlog/qlog.rs"]
1246mod qlog;
1247
1248#[cfg(feature = "ffi")]
1249mod ffi;
1250
1251#[cfg(feature = "cbindgen")]
1254#[path = "h3/connection.rs"]
1255mod h3_connection;
1256
1257mod codec;
1258pub mod endpoint;
1259pub mod error;
1260mod frame;
1261mod packet;
1262mod ranges;
1263#[doc(hidden)]
1264pub mod timer_queue;
1265mod token;
1266mod trans_param;
1267mod window;