1#![allow(clippy::upper_case_acronyms)]
379#![warn(missing_docs)]
380#![cfg_attr(docsrs, feature(doc_cfg))]
381
382#[macro_use]
383extern crate log;
384
385use octets::BufferTooShortError;
386#[cfg(feature = "qlog")]
387use qlog::events::connectivity::ConnectivityEventType;
388#[cfg(feature = "qlog")]
389use qlog::events::connectivity::TransportOwner;
390#[cfg(feature = "qlog")]
391use qlog::events::quic::RecoveryEventType;
392#[cfg(feature = "qlog")]
393use qlog::events::quic::TransportEventType;
394#[cfg(feature = "qlog")]
395use qlog::events::DataRecipient;
396#[cfg(feature = "qlog")]
397use qlog::events::Event;
398#[cfg(feature = "qlog")]
399use qlog::events::EventData;
400#[cfg(feature = "qlog")]
401use qlog::events::EventImportance;
402#[cfg(feature = "qlog")]
403use qlog::events::EventType;
404#[cfg(feature = "qlog")]
405use qlog::events::RawInfo;
406use recovery::OnLossDetectionTimeoutOutcome;
407use stream::StreamPriorityKey;
408
409use std::cmp;
410use std::convert::TryInto;
411use std::time;
412
413use std::sync::Arc;
414
415use std::net::SocketAddr;
416
417use std::str::FromStr;
418
419use std::collections::HashSet;
420use std::collections::VecDeque;
421use std::time::Duration;
422
423use range_buf::DefaultBufFactory;
424use smallvec::SmallVec;
425
426use crate::recovery::OnAckReceivedOutcome;
427use crate::recovery::ReleaseDecision;
428
429pub const PROTOCOL_VERSION: u32 = PROTOCOL_VERSION_V1;
431
432const PROTOCOL_VERSION_V1: u32 = 0x0000_0001;
434
435pub const MAX_CONN_ID_LEN: usize = crate::packet::MAX_CID_LEN as usize;
437
438pub const MIN_CLIENT_INITIAL_LEN: usize = 1200;
440
441#[cfg(not(feature = "fuzzing"))]
442const PAYLOAD_MIN_LEN: usize = 4;
443
444#[cfg(feature = "fuzzing")]
445const PAYLOAD_MIN_LEN: usize = 20;
449
450const MIN_PROBING_SIZE: usize = 25;
452
453const MAX_AMPLIFICATION_FACTOR: usize = 3;
454
455const MAX_ACK_RANGES: usize = 68;
459
460const MAX_STREAM_ID: u64 = 1 << 60;
462
463const MAX_SEND_UDP_PAYLOAD_SIZE: usize = 1200;
465
466const DEFAULT_MAX_DGRAM_QUEUE_LEN: usize = 0;
468
469const DEFAULT_MAX_PATH_CHALLENGE_RX_QUEUE_LEN: usize = 3;
471
472const MAX_DGRAM_FRAME_SIZE: u64 = 65536;
475
476const PAYLOAD_LENGTH_LEN: usize = 2;
478
479const MAX_UNDECRYPTABLE_PACKETS: usize = 10;
481
482const RESERVED_VERSION_MASK: u32 = 0xfafafafa;
483
484const DEFAULT_CONNECTION_WINDOW: u64 = 48 * 1024;
486
487const MAX_CONNECTION_WINDOW: u64 = 24 * 1024 * 1024;
489
490const CONNECTION_WINDOW_FACTOR: f64 = 1.5;
493
494const MAX_PROBING_TIMEOUTS: usize = 3;
497
498const DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS: usize = 10;
500
501const MAX_CRYPTO_STREAM_OFFSET: u64 = 1 << 16;
503
504const TX_CAP_FACTOR: f64 = 1.0;
506
507pub type Result<T> = std::result::Result<T, Error>;
514
515#[derive(Clone, Copy, Debug, PartialEq, Eq)]
517pub enum Error {
518 Done,
520
521 BufferTooShort,
523
524 UnknownVersion,
526
527 InvalidFrame,
530
531 InvalidPacket,
533
534 InvalidState,
537
538 InvalidStreamState(u64),
543
544 InvalidTransportParam,
546
547 CryptoFail,
549
550 TlsFail,
552
553 FlowControl,
555
556 StreamLimit,
558
559 StreamStopped(u64),
564
565 StreamReset(u64),
570
571 FinalSize,
573
574 CongestionControl,
576
577 IdLimit,
579
580 OutOfIdentifiers,
582
583 KeyUpdate,
585
586 CryptoBufferExceeded,
588}
589
590#[derive(Copy, Clone, Debug, Eq, PartialEq)]
594pub enum WireErrorCode {
595 NoError = 0x0,
598 InternalError = 0x1,
601 ConnectionRefused = 0x2,
603 FlowControlError = 0x3,
606 StreamLimitError = 0x4,
609 StreamStateError = 0x5,
612 FinalSizeError = 0x6,
619 FrameEncodingError = 0x7,
623 TransportParameterError = 0x8,
628 ConnectionIdLimitError = 0x9,
633 ProtocolViolation = 0xa,
636 InvalidToken = 0xb,
639 ApplicationError = 0xc,
642 CryptoBufferExceeded = 0xd,
644 KeyUpdateError = 0xe,
646 AeadLimitReached = 0xf,
649 NoViablePath = 0x10,
654}
655
656impl Error {
657 fn to_wire(self) -> u64 {
658 match self {
659 Error::Done => WireErrorCode::NoError as u64,
660 Error::InvalidFrame => WireErrorCode::FrameEncodingError as u64,
661 Error::InvalidStreamState(..) =>
662 WireErrorCode::StreamStateError as u64,
663 Error::InvalidTransportParam =>
664 WireErrorCode::TransportParameterError as u64,
665 Error::FlowControl => WireErrorCode::FlowControlError as u64,
666 Error::StreamLimit => WireErrorCode::StreamLimitError as u64,
667 Error::IdLimit => WireErrorCode::ConnectionIdLimitError as u64,
668 Error::FinalSize => WireErrorCode::FinalSizeError as u64,
669 Error::CryptoBufferExceeded =>
670 WireErrorCode::CryptoBufferExceeded as u64,
671 Error::KeyUpdate => WireErrorCode::KeyUpdateError as u64,
672 _ => WireErrorCode::ProtocolViolation as u64,
673 }
674 }
675
676 #[cfg(feature = "ffi")]
677 fn to_c(self) -> libc::ssize_t {
678 match self {
679 Error::Done => -1,
680 Error::BufferTooShort => -2,
681 Error::UnknownVersion => -3,
682 Error::InvalidFrame => -4,
683 Error::InvalidPacket => -5,
684 Error::InvalidState => -6,
685 Error::InvalidStreamState(_) => -7,
686 Error::InvalidTransportParam => -8,
687 Error::CryptoFail => -9,
688 Error::TlsFail => -10,
689 Error::FlowControl => -11,
690 Error::StreamLimit => -12,
691 Error::FinalSize => -13,
692 Error::CongestionControl => -14,
693 Error::StreamStopped { .. } => -15,
694 Error::StreamReset { .. } => -16,
695 Error::IdLimit => -17,
696 Error::OutOfIdentifiers => -18,
697 Error::KeyUpdate => -19,
698 Error::CryptoBufferExceeded => -20,
699 }
700 }
701}
702
703impl std::fmt::Display for Error {
704 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
705 write!(f, "{self:?}")
706 }
707}
708
709impl std::error::Error for Error {
710 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
711 None
712 }
713}
714
715impl std::convert::From<octets::BufferTooShortError> for Error {
716 fn from(_err: octets::BufferTooShortError) -> Self {
717 Error::BufferTooShort
718 }
719}
720
721#[derive(Clone, Copy, Debug, PartialEq, Eq)]
723pub struct RecvInfo {
724 pub from: SocketAddr,
726
727 pub to: SocketAddr,
729}
730
731#[derive(Clone, Copy, Debug, PartialEq, Eq)]
733pub struct SendInfo {
734 pub from: SocketAddr,
736
737 pub to: SocketAddr,
739
740 pub at: time::Instant,
746}
747
748#[derive(Clone, Debug, PartialEq, Eq)]
750pub struct ConnectionError {
751 pub is_app: bool,
753
754 pub error_code: u64,
756
757 pub reason: Vec<u8>,
759}
760
761#[repr(C)]
767#[derive(PartialEq, Eq)]
768pub enum Shutdown {
769 Read = 0,
771
772 Write = 1,
774}
775
776#[repr(C)]
778#[cfg(feature = "qlog")]
779#[cfg_attr(docsrs, doc(cfg(feature = "qlog")))]
780pub enum QlogLevel {
781 Core = 0,
783
784 Base = 1,
786
787 Extra = 2,
789}
790
791pub struct Config {
793 local_transport_params: TransportParams,
794
795 version: u32,
796
797 tls_ctx: tls::Context,
798
799 application_protos: Vec<Vec<u8>>,
800
801 grease: bool,
802
803 cc_algorithm: CongestionControlAlgorithm,
804 custom_bbr_params: Option<BbrParams>,
805 initial_congestion_window_packets: usize,
806
807 pmtud: bool,
808
809 hystart: bool,
810
811 pacing: bool,
812 max_pacing_rate: Option<u64>,
814
815 tx_cap_factor: f64,
816
817 dgram_recv_max_queue_len: usize,
818 dgram_send_max_queue_len: usize,
819
820 path_challenge_recv_max_queue_len: usize,
821
822 max_send_udp_payload_size: usize,
823
824 max_connection_window: u64,
825 max_stream_window: u64,
826
827 max_amplification_factor: usize,
828
829 disable_dcid_reuse: bool,
830
831 track_unknown_transport_params: Option<usize>,
832}
833
834fn is_reserved_version(version: u32) -> bool {
836 version & RESERVED_VERSION_MASK == version
837}
838
839impl Config {
840 pub fn new(version: u32) -> Result<Config> {
849 Self::with_tls_ctx(version, tls::Context::new()?)
850 }
851
852 #[cfg(feature = "boringssl-boring-crate")]
860 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
861 pub fn with_boring_ssl_ctx_builder(
862 version: u32, tls_ctx_builder: boring::ssl::SslContextBuilder,
863 ) -> Result<Config> {
864 Self::with_tls_ctx(version, tls::Context::from_boring(tls_ctx_builder))
865 }
866
867 fn with_tls_ctx(version: u32, tls_ctx: tls::Context) -> Result<Config> {
868 if !is_reserved_version(version) && !version_is_supported(version) {
869 return Err(Error::UnknownVersion);
870 }
871
872 Ok(Config {
873 local_transport_params: TransportParams::default(),
874 version,
875 tls_ctx,
876 application_protos: Vec::new(),
877 grease: true,
878 cc_algorithm: CongestionControlAlgorithm::CUBIC,
879 custom_bbr_params: None,
880 initial_congestion_window_packets:
881 DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS,
882 pmtud: false,
883 hystart: true,
884 pacing: true,
885 max_pacing_rate: None,
886
887 tx_cap_factor: TX_CAP_FACTOR,
888
889 dgram_recv_max_queue_len: DEFAULT_MAX_DGRAM_QUEUE_LEN,
890 dgram_send_max_queue_len: DEFAULT_MAX_DGRAM_QUEUE_LEN,
891
892 path_challenge_recv_max_queue_len:
893 DEFAULT_MAX_PATH_CHALLENGE_RX_QUEUE_LEN,
894
895 max_send_udp_payload_size: MAX_SEND_UDP_PAYLOAD_SIZE,
896
897 max_connection_window: MAX_CONNECTION_WINDOW,
898 max_stream_window: stream::MAX_STREAM_WINDOW,
899
900 max_amplification_factor: MAX_AMPLIFICATION_FACTOR,
901
902 disable_dcid_reuse: false,
903
904 track_unknown_transport_params: None,
905 })
906 }
907
908 pub fn load_cert_chain_from_pem_file(&mut self, file: &str) -> Result<()> {
921 self.tls_ctx.use_certificate_chain_file(file)
922 }
923
924 pub fn load_priv_key_from_pem_file(&mut self, file: &str) -> Result<()> {
936 self.tls_ctx.use_privkey_file(file)
937 }
938
939 pub fn load_verify_locations_from_file(&mut self, file: &str) -> Result<()> {
952 self.tls_ctx.load_verify_locations_from_file(file)
953 }
954
955 pub fn load_verify_locations_from_directory(
968 &mut self, dir: &str,
969 ) -> Result<()> {
970 self.tls_ctx.load_verify_locations_from_directory(dir)
971 }
972
973 pub fn verify_peer(&mut self, verify: bool) {
989 self.tls_ctx.set_verify(verify);
990 }
991
992 pub fn discover_pmtu(&mut self, discover: bool) {
996 self.pmtud = discover;
997 }
998
999 pub fn grease(&mut self, grease: bool) {
1003 self.grease = grease;
1004 }
1005
1006 pub fn log_keys(&mut self) {
1015 self.tls_ctx.enable_keylog();
1016 }
1017
1018 pub fn set_ticket_key(&mut self, key: &[u8]) -> Result<()> {
1029 self.tls_ctx.set_ticket_key(key)
1030 }
1031
1032 pub fn enable_early_data(&mut self) {
1034 self.tls_ctx.set_early_data_enabled(true);
1035 }
1036
1037 pub fn set_application_protos(
1055 &mut self, protos_list: &[&[u8]],
1056 ) -> Result<()> {
1057 self.application_protos =
1058 protos_list.iter().map(|s| s.to_vec()).collect();
1059
1060 self.tls_ctx.set_alpn(protos_list)
1061 }
1062
1063 pub fn set_application_protos_wire_format(
1080 &mut self, protos: &[u8],
1081 ) -> Result<()> {
1082 let mut b = octets::Octets::with_slice(protos);
1083
1084 let mut protos_list = Vec::new();
1085
1086 while let Ok(proto) = b.get_bytes_with_u8_length() {
1087 protos_list.push(proto.buf());
1088 }
1089
1090 self.set_application_protos(&protos_list)
1091 }
1092
1093 pub fn set_max_amplification_factor(&mut self, v: usize) {
1097 self.max_amplification_factor = v;
1098 }
1099
1100 pub fn set_send_capacity_factor(&mut self, v: f64) {
1104 self.tx_cap_factor = v;
1105 }
1106
1107 pub fn set_max_idle_timeout(&mut self, v: u64) {
1111 self.local_transport_params.max_idle_timeout = v;
1112 }
1113
1114 pub fn set_max_recv_udp_payload_size(&mut self, v: usize) {
1118 self.local_transport_params.max_udp_payload_size = v as u64;
1119 }
1120
1121 pub fn set_max_send_udp_payload_size(&mut self, v: usize) {
1125 self.max_send_udp_payload_size = cmp::max(v, MAX_SEND_UDP_PAYLOAD_SIZE);
1126 }
1127
1128 pub fn set_initial_max_data(&mut self, v: u64) {
1141 self.local_transport_params.initial_max_data = v;
1142 }
1143
1144 pub fn set_initial_max_stream_data_bidi_local(&mut self, v: u64) {
1158 self.local_transport_params
1159 .initial_max_stream_data_bidi_local = v;
1160 }
1161
1162 pub fn set_initial_max_stream_data_bidi_remote(&mut self, v: u64) {
1176 self.local_transport_params
1177 .initial_max_stream_data_bidi_remote = v;
1178 }
1179
1180 pub fn set_initial_max_stream_data_uni(&mut self, v: u64) {
1193 self.local_transport_params.initial_max_stream_data_uni = v;
1194 }
1195
1196 pub fn set_initial_max_streams_bidi(&mut self, v: u64) {
1214 self.local_transport_params.initial_max_streams_bidi = v;
1215 }
1216
1217 pub fn set_initial_max_streams_uni(&mut self, v: u64) {
1233 self.local_transport_params.initial_max_streams_uni = v;
1234 }
1235
1236 pub fn set_ack_delay_exponent(&mut self, v: u64) {
1240 self.local_transport_params.ack_delay_exponent = v;
1241 }
1242
1243 pub fn set_max_ack_delay(&mut self, v: u64) {
1247 self.local_transport_params.max_ack_delay = v;
1248 }
1249
1250 pub fn set_active_connection_id_limit(&mut self, v: u64) {
1254 if v >= 2 {
1255 self.local_transport_params.active_conn_id_limit = v;
1256 }
1257 }
1258
1259 pub fn set_disable_active_migration(&mut self, v: bool) {
1263 self.local_transport_params.disable_active_migration = v;
1264 }
1265
1266 pub fn set_cc_algorithm(&mut self, algo: CongestionControlAlgorithm) {
1270 self.cc_algorithm = algo;
1271 }
1272
1273 #[cfg(feature = "internal")]
1282 #[doc(hidden)]
1283 pub fn set_custom_bbr_params(&mut self, custom_bbr_settings: BbrParams) {
1284 self.custom_bbr_params = Some(custom_bbr_settings);
1285 }
1286
1287 pub fn set_cc_algorithm_name(&mut self, name: &str) -> Result<()> {
1300 self.cc_algorithm = CongestionControlAlgorithm::from_str(name)?;
1301
1302 Ok(())
1303 }
1304
1305 pub fn set_initial_congestion_window_packets(&mut self, packets: usize) {
1309 self.initial_congestion_window_packets = packets;
1310 }
1311
1312 pub fn enable_hystart(&mut self, v: bool) {
1316 self.hystart = v;
1317 }
1318
1319 pub fn enable_pacing(&mut self, v: bool) {
1323 self.pacing = v;
1324 }
1325
1326 pub fn set_max_pacing_rate(&mut self, v: u64) {
1330 self.max_pacing_rate = Some(v);
1331 }
1332
1333 pub fn enable_dgram(
1340 &mut self, enabled: bool, recv_queue_len: usize, send_queue_len: usize,
1341 ) {
1342 self.local_transport_params.max_datagram_frame_size = if enabled {
1343 Some(MAX_DGRAM_FRAME_SIZE)
1344 } else {
1345 None
1346 };
1347 self.dgram_recv_max_queue_len = recv_queue_len;
1348 self.dgram_send_max_queue_len = send_queue_len;
1349 }
1350
1351 pub fn set_path_challenge_recv_max_queue_len(&mut self, queue_len: usize) {
1358 self.path_challenge_recv_max_queue_len = queue_len;
1359 }
1360
1361 pub fn set_max_connection_window(&mut self, v: u64) {
1365 self.max_connection_window = v;
1366 }
1367
1368 pub fn set_max_stream_window(&mut self, v: u64) {
1372 self.max_stream_window = v;
1373 }
1374
1375 pub fn set_stateless_reset_token(&mut self, v: Option<u128>) {
1382 self.local_transport_params.stateless_reset_token = v;
1383 }
1384
1385 pub fn set_disable_dcid_reuse(&mut self, v: bool) {
1396 self.disable_dcid_reuse = v;
1397 }
1398
1399 pub fn enable_track_unknown_transport_parameters(&mut self, size: usize) {
1408 self.track_unknown_transport_params = Some(size);
1409 }
1410}
1411
1412pub struct Connection<F = DefaultBufFactory>
1414where
1415 F: BufFactory,
1416{
1417 version: u32,
1419
1420 ids: cid::ConnectionIdentifiers,
1422
1423 trace_id: String,
1425
1426 pkt_num_spaces: [packet::PktNumSpace; packet::Epoch::count()],
1428
1429 crypto_ctx: [packet::CryptoContext; packet::Epoch::count()],
1431
1432 next_pkt_num: u64,
1434
1435 peer_transport_params: TransportParams,
1437
1438 peer_transport_params_track_unknown: Option<usize>,
1441
1442 local_transport_params: TransportParams,
1444
1445 handshake: tls::Handshake,
1447
1448 session: Option<Vec<u8>>,
1453
1454 recovery_config: recovery::RecoveryConfig,
1456
1457 paths: path::PathMap,
1459
1460 path_challenge_recv_max_queue_len: usize,
1462
1463 path_challenge_rx_count: u64,
1465
1466 application_protos: Vec<Vec<u8>>,
1468
1469 recv_count: usize,
1471
1472 sent_count: usize,
1474
1475 lost_count: usize,
1477
1478 spurious_lost_count: usize,
1480
1481 retrans_count: usize,
1483
1484 dgram_sent_count: usize,
1486
1487 dgram_recv_count: usize,
1489
1490 rx_data: u64,
1492
1493 flow_control: flowcontrol::FlowControl,
1495
1496 almost_full: bool,
1498
1499 tx_cap: usize,
1501
1502 tx_cap_factor: f64,
1504
1505 tx_buffered: usize,
1507
1508 tx_data: u64,
1510
1511 max_tx_data: u64,
1513
1514 last_tx_data: u64,
1516
1517 stream_retrans_bytes: u64,
1520
1521 sent_bytes: u64,
1523
1524 recv_bytes: u64,
1526
1527 acked_bytes: u64,
1529
1530 lost_bytes: u64,
1532
1533 streams: stream::StreamMap<F>,
1535
1536 odcid: Option<ConnectionId<'static>>,
1539
1540 rscid: Option<ConnectionId<'static>>,
1543
1544 token: Option<Vec<u8>>,
1546
1547 local_error: Option<ConnectionError>,
1550
1551 peer_error: Option<ConnectionError>,
1554
1555 blocked_limit: Option<u64>,
1557
1558 idle_timer: Option<time::Instant>,
1560
1561 draining_timer: Option<time::Instant>,
1563
1564 undecryptable_pkts: VecDeque<(Vec<u8>, RecvInfo)>,
1566
1567 alpn: Vec<u8>,
1569
1570 is_server: bool,
1572
1573 derived_initial_secrets: bool,
1575
1576 did_version_negotiation: bool,
1579
1580 did_retry: bool,
1582
1583 got_peer_conn_id: bool,
1585
1586 peer_verified_initial_address: bool,
1588
1589 parsed_peer_transport_params: bool,
1591
1592 handshake_completed: bool,
1594
1595 handshake_done_sent: bool,
1597
1598 handshake_done_acked: bool,
1600
1601 handshake_confirmed: bool,
1603
1604 key_phase: bool,
1606
1607 ack_eliciting_sent: bool,
1610
1611 closed: bool,
1613
1614 timed_out: bool,
1616
1617 grease: bool,
1619
1620 keylog: Option<Box<dyn std::io::Write + Send + Sync>>,
1622
1623 #[cfg(feature = "qlog")]
1624 qlog: QlogInfo,
1625
1626 dgram_recv_queue: dgram::DatagramQueue,
1628 dgram_send_queue: dgram::DatagramQueue,
1629
1630 emit_dgram: bool,
1632
1633 disable_dcid_reuse: bool,
1636
1637 reset_stream_local_count: u64,
1639
1640 stopped_stream_local_count: u64,
1642
1643 reset_stream_remote_count: u64,
1645
1646 stopped_stream_remote_count: u64,
1648
1649 max_amplification_factor: usize,
1651}
1652
1653#[inline]
1673pub fn accept(
1674 scid: &ConnectionId, odcid: Option<&ConnectionId>, local: SocketAddr,
1675 peer: SocketAddr, config: &mut Config,
1676) -> Result<Connection> {
1677 let conn = Connection::new(scid, odcid, local, peer, config, true)?;
1678
1679 Ok(conn)
1680}
1681
1682#[inline]
1688pub fn accept_with_buf_factory<F: BufFactory>(
1689 scid: &ConnectionId, odcid: Option<&ConnectionId>, local: SocketAddr,
1690 peer: SocketAddr, config: &mut Config,
1691) -> Result<Connection<F>> {
1692 let conn = Connection::new(scid, odcid, local, peer, config, true)?;
1693
1694 Ok(conn)
1695}
1696
1697#[inline]
1716pub fn connect(
1717 server_name: Option<&str>, scid: &ConnectionId, local: SocketAddr,
1718 peer: SocketAddr, config: &mut Config,
1719) -> Result<Connection> {
1720 let mut conn = Connection::new(scid, None, local, peer, config, false)?;
1721
1722 if let Some(server_name) = server_name {
1723 conn.handshake.set_host_name(server_name)?;
1724 }
1725
1726 Ok(conn)
1727}
1728
1729#[inline]
1735pub fn connect_with_buffer_factory<F: BufFactory>(
1736 server_name: Option<&str>, scid: &ConnectionId, local: SocketAddr,
1737 peer: SocketAddr, config: &mut Config,
1738) -> Result<Connection<F>> {
1739 let mut conn = Connection::new(scid, None, local, peer, config, false)?;
1740
1741 if let Some(server_name) = server_name {
1742 conn.handshake.set_host_name(server_name)?;
1743 }
1744
1745 Ok(conn)
1746}
1747
1748#[inline]
1772pub fn negotiate_version(
1773 scid: &ConnectionId, dcid: &ConnectionId, out: &mut [u8],
1774) -> Result<usize> {
1775 packet::negotiate_version(scid, dcid, out)
1776}
1777
1778#[inline]
1838pub fn retry(
1839 scid: &ConnectionId, dcid: &ConnectionId, new_scid: &ConnectionId,
1840 token: &[u8], version: u32, out: &mut [u8],
1841) -> Result<usize> {
1842 packet::retry(scid, dcid, new_scid, token, version, out)
1843}
1844
1845#[inline]
1847pub fn version_is_supported(version: u32) -> bool {
1848 matches!(version, PROTOCOL_VERSION_V1)
1849}
1850
1851macro_rules! push_frame_to_pkt {
1857 ($out:expr, $frames:expr, $frame:expr, $left:expr) => {{
1858 if $frame.wire_len() <= $left {
1859 $left -= $frame.wire_len();
1860
1861 $frame.to_bytes(&mut $out)?;
1862
1863 $frames.push($frame);
1864
1865 true
1866 } else {
1867 false
1868 }
1869 }};
1870}
1871
1872macro_rules! qlog_with_type {
1876 ($ty:expr, $qlog:expr, $qlog_streamer_ref:ident, $body:block) => {{
1877 #[cfg(feature = "qlog")]
1878 {
1879 if EventImportance::from($ty).is_contained_in(&$qlog.level) {
1880 if let Some($qlog_streamer_ref) = &mut $qlog.streamer {
1881 $body
1882 }
1883 }
1884 }
1885 }};
1886}
1887
1888#[cfg(feature = "qlog")]
1889const QLOG_PARAMS_SET: EventType =
1890 EventType::TransportEventType(TransportEventType::ParametersSet);
1891
1892#[cfg(feature = "qlog")]
1893const QLOG_PACKET_RX: EventType =
1894 EventType::TransportEventType(TransportEventType::PacketReceived);
1895
1896#[cfg(feature = "qlog")]
1897const QLOG_PACKET_TX: EventType =
1898 EventType::TransportEventType(TransportEventType::PacketSent);
1899
1900#[cfg(feature = "qlog")]
1901const QLOG_DATA_MV: EventType =
1902 EventType::TransportEventType(TransportEventType::DataMoved);
1903
1904#[cfg(feature = "qlog")]
1905const QLOG_METRICS: EventType =
1906 EventType::RecoveryEventType(RecoveryEventType::MetricsUpdated);
1907
1908#[cfg(feature = "qlog")]
1909const QLOG_CONNECTION_CLOSED: EventType =
1910 EventType::ConnectivityEventType(ConnectivityEventType::ConnectionClosed);
1911
1912#[cfg(feature = "qlog")]
1913struct QlogInfo {
1914 streamer: Option<qlog::streamer::QlogStreamer>,
1915 logged_peer_params: bool,
1916 level: EventImportance,
1917}
1918
1919#[cfg(feature = "qlog")]
1920impl Default for QlogInfo {
1921 fn default() -> Self {
1922 QlogInfo {
1923 streamer: None,
1924 logged_peer_params: false,
1925 level: EventImportance::Base,
1926 }
1927 }
1928}
1929
1930impl<F: BufFactory> Connection<F> {
1931 fn new(
1932 scid: &ConnectionId, odcid: Option<&ConnectionId>, local: SocketAddr,
1933 peer: SocketAddr, config: &mut Config, is_server: bool,
1934 ) -> Result<Connection<F>> {
1935 let tls = config.tls_ctx.new_handshake()?;
1936 Connection::with_tls(scid, odcid, local, peer, config, tls, is_server)
1937 }
1938
1939 fn with_tls(
1940 scid: &ConnectionId, odcid: Option<&ConnectionId>, local: SocketAddr,
1941 peer: SocketAddr, config: &Config, tls: tls::Handshake, is_server: bool,
1942 ) -> Result<Connection<F>> {
1943 let max_rx_data = config.local_transport_params.initial_max_data;
1944
1945 let scid_as_hex: Vec<String> =
1946 scid.iter().map(|b| format!("{b:02x}")).collect();
1947
1948 let reset_token = if is_server {
1949 config.local_transport_params.stateless_reset_token
1950 } else {
1951 None
1952 };
1953
1954 let recovery_config = recovery::RecoveryConfig::from_config(config);
1955
1956 let mut path = path::Path::new(
1957 local,
1958 peer,
1959 &recovery_config,
1960 config.path_challenge_recv_max_queue_len,
1961 MIN_CLIENT_INITIAL_LEN,
1962 true,
1963 );
1964
1965 path.verified_peer_address = odcid.is_some();
1967 path.peer_verified_local_address = is_server;
1969
1970 let paths = path::PathMap::new(
1972 path,
1973 config.local_transport_params.active_conn_id_limit as usize,
1974 is_server,
1975 config.pmtud,
1976 config.max_send_udp_payload_size,
1977 );
1978
1979 let active_path_id = paths.get_active_path_id()?;
1980
1981 let ids = cid::ConnectionIdentifiers::new(
1982 config.local_transport_params.active_conn_id_limit as usize,
1983 scid,
1984 active_path_id,
1985 reset_token,
1986 );
1987
1988 let mut conn = Connection {
1989 version: config.version,
1990
1991 ids,
1992
1993 trace_id: scid_as_hex.join(""),
1994
1995 pkt_num_spaces: [
1996 packet::PktNumSpace::new(),
1997 packet::PktNumSpace::new(),
1998 packet::PktNumSpace::new(),
1999 ],
2000
2001 crypto_ctx: [
2002 packet::CryptoContext::new(),
2003 packet::CryptoContext::new(),
2004 packet::CryptoContext::new(),
2005 ],
2006
2007 next_pkt_num: 0,
2008
2009 peer_transport_params: TransportParams::default(),
2010
2011 peer_transport_params_track_unknown: config
2012 .track_unknown_transport_params,
2013
2014 local_transport_params: config.local_transport_params.clone(),
2015
2016 handshake: tls,
2017
2018 session: None,
2019
2020 recovery_config,
2021
2022 paths,
2023 path_challenge_recv_max_queue_len: config
2024 .path_challenge_recv_max_queue_len,
2025 path_challenge_rx_count: 0,
2026
2027 application_protos: config.application_protos.clone(),
2028
2029 recv_count: 0,
2030 sent_count: 0,
2031 lost_count: 0,
2032 spurious_lost_count: 0,
2033 retrans_count: 0,
2034 dgram_sent_count: 0,
2035 dgram_recv_count: 0,
2036 sent_bytes: 0,
2037 recv_bytes: 0,
2038 acked_bytes: 0,
2039 lost_bytes: 0,
2040
2041 rx_data: 0,
2042 flow_control: flowcontrol::FlowControl::new(
2043 max_rx_data,
2044 cmp::min(max_rx_data / 2 * 3, DEFAULT_CONNECTION_WINDOW),
2045 config.max_connection_window,
2046 ),
2047 almost_full: false,
2048
2049 tx_cap: 0,
2050 tx_cap_factor: config.tx_cap_factor,
2051
2052 tx_buffered: 0,
2053
2054 tx_data: 0,
2055 max_tx_data: 0,
2056 last_tx_data: 0,
2057
2058 stream_retrans_bytes: 0,
2059
2060 streams: stream::StreamMap::new(
2061 config.local_transport_params.initial_max_streams_bidi,
2062 config.local_transport_params.initial_max_streams_uni,
2063 config.max_stream_window,
2064 ),
2065
2066 odcid: None,
2067
2068 rscid: None,
2069
2070 token: None,
2071
2072 local_error: None,
2073
2074 peer_error: None,
2075
2076 blocked_limit: None,
2077
2078 idle_timer: None,
2079
2080 draining_timer: None,
2081
2082 undecryptable_pkts: VecDeque::new(),
2083
2084 alpn: Vec::new(),
2085
2086 is_server,
2087
2088 derived_initial_secrets: false,
2089
2090 did_version_negotiation: false,
2091
2092 did_retry: false,
2093
2094 got_peer_conn_id: false,
2095
2096 peer_verified_initial_address: is_server,
2098
2099 parsed_peer_transport_params: false,
2100
2101 handshake_completed: false,
2102
2103 handshake_done_sent: false,
2104 handshake_done_acked: false,
2105
2106 handshake_confirmed: false,
2107
2108 key_phase: false,
2109
2110 ack_eliciting_sent: false,
2111
2112 closed: false,
2113
2114 timed_out: false,
2115
2116 grease: config.grease,
2117
2118 keylog: None,
2119
2120 #[cfg(feature = "qlog")]
2121 qlog: Default::default(),
2122
2123 dgram_recv_queue: dgram::DatagramQueue::new(
2124 config.dgram_recv_max_queue_len,
2125 ),
2126
2127 dgram_send_queue: dgram::DatagramQueue::new(
2128 config.dgram_send_max_queue_len,
2129 ),
2130
2131 emit_dgram: true,
2132
2133 disable_dcid_reuse: config.disable_dcid_reuse,
2134
2135 reset_stream_local_count: 0,
2136 stopped_stream_local_count: 0,
2137 reset_stream_remote_count: 0,
2138 stopped_stream_remote_count: 0,
2139
2140 max_amplification_factor: config.max_amplification_factor,
2141 };
2142
2143 if let Some(odcid) = odcid {
2144 conn.local_transport_params
2145 .original_destination_connection_id = Some(odcid.to_vec().into());
2146
2147 conn.local_transport_params.retry_source_connection_id =
2148 Some(conn.ids.get_scid(0)?.cid.to_vec().into());
2149
2150 conn.did_retry = true;
2151 }
2152
2153 conn.local_transport_params.initial_source_connection_id =
2154 Some(conn.ids.get_scid(0)?.cid.to_vec().into());
2155
2156 conn.handshake.init(is_server)?;
2157
2158 conn.handshake
2159 .use_legacy_codepoint(config.version != PROTOCOL_VERSION_V1);
2160
2161 conn.encode_transport_params()?;
2162
2163 if !is_server {
2166 let mut dcid = [0; 16];
2167 rand::rand_bytes(&mut dcid[..]);
2168
2169 let (aead_open, aead_seal) = crypto::derive_initial_key_material(
2170 &dcid,
2171 conn.version,
2172 conn.is_server,
2173 false,
2174 )?;
2175
2176 let reset_token = conn.peer_transport_params.stateless_reset_token;
2177 conn.set_initial_dcid(
2178 dcid.to_vec().into(),
2179 reset_token,
2180 active_path_id,
2181 )?;
2182
2183 conn.crypto_ctx[packet::Epoch::Initial].crypto_open = Some(aead_open);
2184 conn.crypto_ctx[packet::Epoch::Initial].crypto_seal = Some(aead_seal);
2185
2186 conn.derived_initial_secrets = true;
2187 }
2188
2189 Ok(conn)
2190 }
2191
2192 #[inline]
2199 pub fn set_keylog(&mut self, writer: Box<dyn std::io::Write + Send + Sync>) {
2200 self.keylog = Some(writer);
2201 }
2202
2203 #[cfg(feature = "qlog")]
2213 #[cfg_attr(docsrs, doc(cfg(feature = "qlog")))]
2214 pub fn set_qlog(
2215 &mut self, writer: Box<dyn std::io::Write + Send + Sync>, title: String,
2216 description: String,
2217 ) {
2218 self.set_qlog_with_level(writer, title, description, QlogLevel::Base)
2219 }
2220
2221 #[cfg(feature = "qlog")]
2231 #[cfg_attr(docsrs, doc(cfg(feature = "qlog")))]
2232 pub fn set_qlog_with_level(
2233 &mut self, writer: Box<dyn std::io::Write + Send + Sync>, title: String,
2234 description: String, qlog_level: QlogLevel,
2235 ) {
2236 let vp = if self.is_server {
2237 qlog::VantagePointType::Server
2238 } else {
2239 qlog::VantagePointType::Client
2240 };
2241
2242 let level = match qlog_level {
2243 QlogLevel::Core => EventImportance::Core,
2244
2245 QlogLevel::Base => EventImportance::Base,
2246
2247 QlogLevel::Extra => EventImportance::Extra,
2248 };
2249
2250 self.qlog.level = level;
2251
2252 let trace = qlog::TraceSeq::new(
2253 qlog::VantagePoint {
2254 name: None,
2255 ty: vp,
2256 flow: None,
2257 },
2258 Some(title.to_string()),
2259 Some(description.to_string()),
2260 Some(qlog::Configuration {
2261 time_offset: Some(0.0),
2262 original_uris: None,
2263 }),
2264 None,
2265 );
2266
2267 let mut streamer = qlog::streamer::QlogStreamer::new(
2268 qlog::QLOG_VERSION.to_string(),
2269 Some(title),
2270 Some(description),
2271 None,
2272 time::Instant::now(),
2273 trace,
2274 self.qlog.level,
2275 writer,
2276 );
2277
2278 streamer.start_log().ok();
2279
2280 let ev_data = self
2281 .local_transport_params
2282 .to_qlog(TransportOwner::Local, self.handshake.cipher());
2283
2284 streamer.add_event(Event::with_time(0.0, ev_data)).ok();
2286
2287 self.qlog.streamer = Some(streamer);
2288 }
2289
2290 #[cfg(feature = "qlog")]
2292 #[cfg_attr(docsrs, doc(cfg(feature = "qlog")))]
2293 pub fn qlog_streamer(&mut self) -> Option<&mut qlog::streamer::QlogStreamer> {
2294 self.qlog.streamer.as_mut()
2295 }
2296
2297 #[inline]
2307 pub fn set_session(&mut self, session: &[u8]) -> Result<()> {
2308 let mut b = octets::Octets::with_slice(session);
2309
2310 let session_len = b.get_u64()? as usize;
2311 let session_bytes = b.get_bytes(session_len)?;
2312
2313 self.handshake.set_session(session_bytes.as_ref())?;
2314
2315 let raw_params_len = b.get_u64()? as usize;
2316 let raw_params_bytes = b.get_bytes(raw_params_len)?;
2317
2318 let peer_params = TransportParams::decode(
2319 raw_params_bytes.as_ref(),
2320 self.is_server,
2321 self.peer_transport_params_track_unknown,
2322 )?;
2323
2324 self.process_peer_transport_params(peer_params)?;
2325
2326 Ok(())
2327 }
2328
2329 pub fn set_max_idle_timeout(&mut self, v: u64) -> Result<()> {
2337 self.local_transport_params.max_idle_timeout = v;
2338
2339 self.encode_transport_params()
2340 }
2341
2342 #[cfg(feature = "boringssl-boring-crate")]
2352 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2353 pub fn set_cc_algorithm_in_handshake(
2354 ssl: &mut boring::ssl::SslRef, algo: CongestionControlAlgorithm,
2355 ) -> Result<()> {
2356 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2357
2358 ex_data.recovery_config.cc_algorithm = algo;
2359
2360 Ok(())
2361 }
2362
2363 #[cfg(all(feature = "boringssl-boring-crate", feature = "internal"))]
2378 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2379 #[doc(hidden)]
2380 pub fn set_custom_bbr_settings_in_handshake(
2381 ssl: &mut boring::ssl::SslRef, custom_bbr_params: BbrParams,
2382 ) -> Result<()> {
2383 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2384
2385 ex_data.recovery_config.custom_bbr_params = Some(custom_bbr_params);
2386
2387 Ok(())
2388 }
2389
2390 #[cfg(feature = "boringssl-boring-crate")]
2400 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2401 pub fn set_cc_algorithm_name_in_handshake(
2402 ssl: &mut boring::ssl::SslRef, name: &str,
2403 ) -> Result<()> {
2404 let cc_algo = CongestionControlAlgorithm::from_str(name)?;
2405 Self::set_cc_algorithm_in_handshake(ssl, cc_algo)
2406 }
2407
2408 #[cfg(feature = "boringssl-boring-crate")]
2418 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2419 pub fn set_initial_congestion_window_packets_in_handshake(
2420 ssl: &mut boring::ssl::SslRef, packets: usize,
2421 ) -> Result<()> {
2422 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2423
2424 ex_data.recovery_config.initial_congestion_window_packets = packets;
2425
2426 Ok(())
2427 }
2428
2429 #[cfg(feature = "boringssl-boring-crate")]
2439 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2440 pub fn set_hystart_in_handshake(
2441 ssl: &mut boring::ssl::SslRef, v: bool,
2442 ) -> Result<()> {
2443 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2444
2445 ex_data.recovery_config.hystart = v;
2446
2447 Ok(())
2448 }
2449
2450 #[cfg(feature = "boringssl-boring-crate")]
2460 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2461 pub fn set_pacing_in_handshake(
2462 ssl: &mut boring::ssl::SslRef, v: bool,
2463 ) -> Result<()> {
2464 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2465
2466 ex_data.recovery_config.pacing = v;
2467
2468 Ok(())
2469 }
2470
2471 #[cfg(feature = "boringssl-boring-crate")]
2481 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2482 pub fn set_max_pacing_rate_in_handshake(
2483 ssl: &mut boring::ssl::SslRef, v: Option<u64>,
2484 ) -> Result<()> {
2485 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2486
2487 ex_data.recovery_config.max_pacing_rate = v;
2488
2489 Ok(())
2490 }
2491
2492 #[cfg(feature = "boringssl-boring-crate")]
2502 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2503 pub fn set_max_send_udp_payload_size_in_handshake(
2504 ssl: &mut boring::ssl::SslRef, v: usize,
2505 ) -> Result<()> {
2506 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2507
2508 ex_data.recovery_config.max_send_udp_payload_size = v;
2509
2510 Ok(())
2511 }
2512
2513 #[cfg(feature = "boringssl-boring-crate")]
2523 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2524 pub fn set_send_capacity_factor_in_handshake(
2525 ssl: &mut boring::ssl::SslRef, v: f64,
2526 ) -> Result<()> {
2527 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2528
2529 ex_data.tx_cap_factor = v;
2530
2531 Ok(())
2532 }
2533
2534 #[cfg(feature = "boringssl-boring-crate")]
2544 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2545 pub fn set_discover_pmtu_in_handshake(
2546 ssl: &mut boring::ssl::SslRef, discover: bool,
2547 ) -> Result<()> {
2548 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2549
2550 ex_data.pmtud = Some(discover);
2551
2552 Ok(())
2553 }
2554
2555 #[cfg(feature = "boringssl-boring-crate")]
2565 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2566 pub fn set_max_idle_timeout_in_handshake(
2567 ssl: &mut boring::ssl::SslRef, v: u64,
2568 ) -> Result<()> {
2569 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2570
2571 ex_data.local_transport_params.max_idle_timeout = v;
2572
2573 Self::set_transport_parameters_in_hanshake(
2574 ex_data.local_transport_params.clone(),
2575 ex_data.is_server,
2576 ssl,
2577 )
2578 }
2579
2580 #[cfg(feature = "boringssl-boring-crate")]
2590 #[cfg_attr(docsrs, doc(cfg(feature = "boringssl-boring-crate")))]
2591 pub fn set_initial_max_streams_bidi_in_handshake(
2592 ssl: &mut boring::ssl::SslRef, v: u64,
2593 ) -> Result<()> {
2594 let ex_data = tls::ExData::from_ssl_ref(ssl).ok_or(Error::TlsFail)?;
2595
2596 ex_data.local_transport_params.initial_max_streams_bidi = v;
2597
2598 Self::set_transport_parameters_in_hanshake(
2599 ex_data.local_transport_params.clone(),
2600 ex_data.is_server,
2601 ssl,
2602 )
2603 }
2604
2605 #[cfg(feature = "boringssl-boring-crate")]
2606 fn set_transport_parameters_in_hanshake(
2607 params: TransportParams, is_server: bool, ssl: &mut boring::ssl::SslRef,
2608 ) -> Result<()> {
2609 use foreign_types_shared::ForeignTypeRef;
2610
2611 let mut handshake =
2620 unsafe { tls::Handshake::from_ptr(ssl.as_ptr() as _) };
2621 handshake.set_quic_transport_params(¶ms, is_server)?;
2622
2623 std::mem::forget(handshake);
2626
2627 Ok(())
2628 }
2629
2630 pub fn recv(&mut self, buf: &mut [u8], info: RecvInfo) -> Result<usize> {
2673 let len = buf.len();
2674
2675 if len == 0 {
2676 return Err(Error::BufferTooShort);
2677 }
2678
2679 let recv_pid = self.paths.path_id_from_addrs(&(info.to, info.from));
2680
2681 if let Some(recv_pid) = recv_pid {
2682 let recv_path = self.paths.get_mut(recv_pid)?;
2683
2684 if self.is_server && !recv_path.verified_peer_address {
2696 recv_path.max_send_bytes += len * self.max_amplification_factor;
2697 }
2698 } else if !self.is_server {
2699 trace!(
2702 "{} client received packet from unknown address {:?}, dropping",
2703 self.trace_id,
2704 info,
2705 );
2706
2707 return Ok(len);
2708 }
2709
2710 let mut done = 0;
2711 let mut left = len;
2712
2713 while left > 0 {
2715 let read = match self.recv_single(
2716 &mut buf[len - left..len],
2717 &info,
2718 recv_pid,
2719 ) {
2720 Ok(v) => v,
2721
2722 Err(Error::Done) => {
2723 if self.is_stateless_reset(&buf[len - left..len]) {
2726 trace!("{} packet is a stateless reset", self.trace_id);
2727
2728 self.mark_closed();
2729 }
2730
2731 left
2732 },
2733
2734 Err(e) => {
2735 self.close(false, e.to_wire(), b"").ok();
2738 return Err(e);
2739 },
2740 };
2741
2742 done += read;
2743 left -= read;
2744 }
2745
2746 self.process_undecrypted_0rtt_packets()?;
2750
2751 Ok(done)
2752 }
2753
2754 fn process_undecrypted_0rtt_packets(&mut self) -> Result<()> {
2755 if self.crypto_ctx[packet::Epoch::Application]
2758 .crypto_0rtt_open
2759 .is_some()
2760 {
2761 while let Some((mut pkt, info)) = self.undecryptable_pkts.pop_front()
2762 {
2763 if let Err(e) = self.recv(&mut pkt, info) {
2764 self.undecryptable_pkts.clear();
2765
2766 return Err(e);
2767 }
2768 }
2769 }
2770 Ok(())
2771 }
2772
2773 fn is_stateless_reset(&self, buf: &[u8]) -> bool {
2775 let buf_len = buf.len();
2777 if buf_len < 21 {
2778 return false;
2779 }
2780
2781 match self.peer_transport_params.stateless_reset_token {
2784 Some(token) => {
2785 let token_len = 16;
2786
2787 crypto::verify_slices_are_equal(
2788 &token.to_be_bytes(),
2789 &buf[buf_len - token_len..buf_len],
2790 )
2791 .is_ok()
2792 },
2793
2794 None => false,
2795 }
2796 }
2797
2798 fn recv_single(
2813 &mut self, buf: &mut [u8], info: &RecvInfo, recv_pid: Option<usize>,
2814 ) -> Result<usize> {
2815 let now = time::Instant::now();
2816
2817 if buf.is_empty() {
2818 return Err(Error::Done);
2819 }
2820
2821 if self.is_closed() || self.is_draining() {
2822 return Err(Error::Done);
2823 }
2824
2825 let is_closing = self.local_error.is_some();
2826
2827 if is_closing {
2828 return Err(Error::Done);
2829 }
2830
2831 let buf_len = buf.len();
2832
2833 let mut b = octets::OctetsMut::with_slice(buf);
2834
2835 let mut hdr = Header::from_bytes(&mut b, self.source_id().len())
2836 .map_err(|e| {
2837 drop_pkt_on_err(
2838 e,
2839 self.recv_count,
2840 self.is_server,
2841 &self.trace_id,
2842 )
2843 })?;
2844
2845 if hdr.ty == packet::Type::VersionNegotiation {
2846 if self.is_server {
2848 return Err(Error::Done);
2849 }
2850
2851 if self.did_version_negotiation {
2853 return Err(Error::Done);
2854 }
2855
2856 if self.recv_count > 0 {
2859 return Err(Error::Done);
2860 }
2861
2862 if hdr.dcid != self.source_id() {
2863 return Err(Error::Done);
2864 }
2865
2866 if hdr.scid != self.destination_id() {
2867 return Err(Error::Done);
2868 }
2869
2870 trace!("{} rx pkt {:?}", self.trace_id, hdr);
2871
2872 let versions = hdr.versions.ok_or(Error::Done)?;
2873
2874 if versions.contains(&self.version) {
2877 return Err(Error::Done);
2878 }
2879
2880 let supported_versions =
2881 versions.iter().filter(|&&v| version_is_supported(v));
2882
2883 let mut found_version = false;
2884
2885 for &v in supported_versions {
2886 found_version = true;
2887
2888 if v == PROTOCOL_VERSION_V1 {
2890 self.version = v;
2891 break;
2892 }
2893
2894 self.version = cmp::max(self.version, v);
2895 }
2896
2897 if !found_version {
2898 return Err(Error::UnknownVersion);
2906 }
2907
2908 self.did_version_negotiation = true;
2909
2910 let (aead_open, aead_seal) = crypto::derive_initial_key_material(
2912 &self.destination_id(),
2913 self.version,
2914 self.is_server,
2915 true,
2916 )?;
2917
2918 self.drop_epoch_state(packet::Epoch::Initial, now);
2920 self.got_peer_conn_id = false;
2921 self.handshake.clear()?;
2922
2923 self.crypto_ctx[packet::Epoch::Initial].crypto_open = Some(aead_open);
2924 self.crypto_ctx[packet::Epoch::Initial].crypto_seal = Some(aead_seal);
2925
2926 self.handshake
2927 .use_legacy_codepoint(self.version != PROTOCOL_VERSION_V1);
2928
2929 self.encode_transport_params()?;
2932
2933 return Err(Error::Done);
2934 }
2935
2936 if hdr.ty == packet::Type::Retry {
2937 if self.is_server {
2939 return Err(Error::Done);
2940 }
2941
2942 if self.did_retry {
2944 return Err(Error::Done);
2945 }
2946
2947 if packet::verify_retry_integrity(
2949 &b,
2950 &self.destination_id(),
2951 self.version,
2952 )
2953 .is_err()
2954 {
2955 return Err(Error::Done);
2956 }
2957
2958 trace!("{} rx pkt {:?}", self.trace_id, hdr);
2959
2960 self.token = hdr.token;
2961 self.did_retry = true;
2962
2963 self.odcid = Some(self.destination_id().into_owned());
2965
2966 self.set_initial_dcid(
2967 hdr.scid.clone(),
2968 None,
2969 self.paths.get_active_path_id()?,
2970 )?;
2971
2972 self.rscid = Some(self.destination_id().into_owned());
2973
2974 let (aead_open, aead_seal) = crypto::derive_initial_key_material(
2976 &hdr.scid,
2977 self.version,
2978 self.is_server,
2979 true,
2980 )?;
2981
2982 self.drop_epoch_state(packet::Epoch::Initial, now);
2984 self.got_peer_conn_id = false;
2985 self.handshake.clear()?;
2986
2987 self.crypto_ctx[packet::Epoch::Initial].crypto_open = Some(aead_open);
2988 self.crypto_ctx[packet::Epoch::Initial].crypto_seal = Some(aead_seal);
2989
2990 return Err(Error::Done);
2991 }
2992
2993 if self.is_server && !self.did_version_negotiation {
2994 if !version_is_supported(hdr.version) {
2995 return Err(Error::UnknownVersion);
2996 }
2997
2998 self.version = hdr.version;
2999 self.did_version_negotiation = true;
3000
3001 self.handshake
3002 .use_legacy_codepoint(self.version != PROTOCOL_VERSION_V1);
3003
3004 self.encode_transport_params()?;
3007 }
3008
3009 if hdr.ty != packet::Type::Short && hdr.version != self.version {
3010 return Err(Error::Done);
3013 }
3014
3015 let payload_len = if hdr.ty == packet::Type::Short {
3018 b.cap()
3019 } else {
3020 b.get_varint().map_err(|e| {
3021 drop_pkt_on_err(
3022 e.into(),
3023 self.recv_count,
3024 self.is_server,
3025 &self.trace_id,
3026 )
3027 })? as usize
3028 };
3029
3030 if payload_len > b.cap() {
3033 return Err(drop_pkt_on_err(
3034 Error::InvalidPacket,
3035 self.recv_count,
3036 self.is_server,
3037 &self.trace_id,
3038 ));
3039 }
3040
3041 if !self.derived_initial_secrets {
3043 let (aead_open, aead_seal) = crypto::derive_initial_key_material(
3044 &hdr.dcid,
3045 self.version,
3046 self.is_server,
3047 false,
3048 )?;
3049
3050 self.crypto_ctx[packet::Epoch::Initial].crypto_open = Some(aead_open);
3051 self.crypto_ctx[packet::Epoch::Initial].crypto_seal = Some(aead_seal);
3052
3053 self.derived_initial_secrets = true;
3054 }
3055
3056 let epoch = hdr.ty.to_epoch()?;
3058
3059 let aead = if hdr.ty == packet::Type::ZeroRTT {
3061 self.crypto_ctx[epoch].crypto_0rtt_open.as_ref()
3063 } else {
3064 self.crypto_ctx[epoch].crypto_open.as_ref()
3066 };
3067
3068 let mut aead = match aead {
3070 Some(v) => v,
3071
3072 None => {
3073 if hdr.ty == packet::Type::ZeroRTT &&
3074 self.undecryptable_pkts.len() < MAX_UNDECRYPTABLE_PACKETS &&
3075 !self.is_established()
3076 {
3077 let pkt_len = b.off() + payload_len;
3083 let pkt = (b.buf()[..pkt_len]).to_vec();
3084
3085 self.undecryptable_pkts.push_back((pkt, *info));
3086 return Ok(pkt_len);
3087 }
3088
3089 let e = drop_pkt_on_err(
3090 Error::CryptoFail,
3091 self.recv_count,
3092 self.is_server,
3093 &self.trace_id,
3094 );
3095
3096 return Err(e);
3097 },
3098 };
3099
3100 let aead_tag_len = aead.alg().tag_len();
3101
3102 packet::decrypt_hdr(&mut b, &mut hdr, aead).map_err(|e| {
3103 drop_pkt_on_err(e, self.recv_count, self.is_server, &self.trace_id)
3104 })?;
3105
3106 let pn = packet::decode_pkt_num(
3107 self.pkt_num_spaces[epoch].largest_rx_pkt_num,
3108 hdr.pkt_num,
3109 hdr.pkt_num_len,
3110 );
3111
3112 let pn_len = hdr.pkt_num_len;
3113
3114 trace!(
3115 "{} rx pkt {:?} len={} pn={} {}",
3116 self.trace_id,
3117 hdr,
3118 payload_len,
3119 pn,
3120 AddrTupleFmt(info.from, info.to)
3121 );
3122
3123 #[cfg(feature = "qlog")]
3124 let mut qlog_frames = vec![];
3125
3126 let mut aead_next = None;
3128
3129 if self.handshake_confirmed &&
3130 hdr.ty != Type::ZeroRTT &&
3131 hdr.key_phase != self.key_phase
3132 {
3133 if let Some(key_update) = self.crypto_ctx[epoch]
3135 .key_update
3136 .as_ref()
3137 .and_then(|key_update| {
3138 (pn < key_update.pn_on_update).then_some(key_update)
3139 })
3140 {
3141 aead = &key_update.crypto_open;
3142 } else {
3143 trace!("{} peer-initiated key update", self.trace_id);
3144
3145 aead_next = Some((
3146 self.crypto_ctx[epoch]
3147 .crypto_open
3148 .as_ref()
3149 .unwrap()
3150 .derive_next_packet_key()?,
3151 self.crypto_ctx[epoch]
3152 .crypto_seal
3153 .as_ref()
3154 .unwrap()
3155 .derive_next_packet_key()?,
3156 ));
3157
3158 aead = &aead_next.as_ref().unwrap().0;
3161 }
3162 }
3163
3164 let mut payload = packet::decrypt_pkt(
3165 &mut b,
3166 pn,
3167 pn_len,
3168 payload_len,
3169 aead,
3170 )
3171 .map_err(|e| {
3172 drop_pkt_on_err(e, self.recv_count, self.is_server, &self.trace_id)
3173 })?;
3174
3175 if self.pkt_num_spaces[epoch].recv_pkt_num.contains(pn) {
3176 trace!("{} ignored duplicate packet {}", self.trace_id, pn);
3177 return Err(Error::Done);
3178 }
3179
3180 if payload.cap() == 0 {
3182 return Err(Error::InvalidPacket);
3183 }
3184
3185 let recv_pid = if hdr.ty == packet::Type::Short && self.got_peer_conn_id {
3188 let pkt_dcid = ConnectionId::from_ref(&hdr.dcid);
3189 self.get_or_create_recv_path_id(recv_pid, &pkt_dcid, buf_len, info)?
3190 } else {
3191 self.paths.get_active_path_id()?
3193 };
3194
3195 if let Some((open_next, seal_next)) = aead_next {
3198 if !self.crypto_ctx[epoch]
3199 .key_update
3200 .as_ref()
3201 .is_none_or(|prev| prev.update_acked)
3202 {
3203 return Err(Error::KeyUpdate);
3205 }
3206
3207 trace!("{} key update verified", self.trace_id);
3208
3209 let _ = self.crypto_ctx[epoch].crypto_seal.replace(seal_next);
3210
3211 let open_prev = self.crypto_ctx[epoch]
3212 .crypto_open
3213 .replace(open_next)
3214 .unwrap();
3215
3216 let recv_path = self.paths.get_mut(recv_pid)?;
3217
3218 self.crypto_ctx[epoch].key_update = Some(packet::KeyUpdate {
3219 crypto_open: open_prev,
3220 pn_on_update: pn,
3221 update_acked: false,
3222 timer: now + (recv_path.recovery.pto() * 3),
3223 });
3224
3225 self.key_phase = !self.key_phase;
3226
3227 qlog_with_type!(QLOG_PACKET_RX, self.qlog, q, {
3228 let trigger = Some(
3229 qlog::events::security::KeyUpdateOrRetiredTrigger::RemoteUpdate,
3230 );
3231
3232 let ev_data_client =
3233 EventData::KeyUpdated(qlog::events::security::KeyUpdated {
3234 key_type:
3235 qlog::events::security::KeyType::Client1RttSecret,
3236 trigger: trigger.clone(),
3237 ..Default::default()
3238 });
3239
3240 q.add_event_data_with_instant(ev_data_client, now).ok();
3241
3242 let ev_data_server =
3243 EventData::KeyUpdated(qlog::events::security::KeyUpdated {
3244 key_type:
3245 qlog::events::security::KeyType::Server1RttSecret,
3246 trigger,
3247 ..Default::default()
3248 });
3249
3250 q.add_event_data_with_instant(ev_data_server, now).ok();
3251 });
3252 }
3253
3254 if !self.is_server && !self.got_peer_conn_id {
3255 if self.odcid.is_none() {
3256 self.odcid = Some(self.destination_id().into_owned());
3257 }
3258
3259 self.set_initial_dcid(
3262 hdr.scid.clone(),
3263 self.peer_transport_params.stateless_reset_token,
3264 recv_pid,
3265 )?;
3266
3267 self.got_peer_conn_id = true;
3268 }
3269
3270 if self.is_server && !self.got_peer_conn_id {
3271 self.set_initial_dcid(hdr.scid.clone(), None, recv_pid)?;
3272
3273 if !self.did_retry {
3274 self.local_transport_params
3275 .original_destination_connection_id =
3276 Some(hdr.dcid.to_vec().into());
3277
3278 self.encode_transport_params()?;
3279 }
3280
3281 self.got_peer_conn_id = true;
3282 }
3283
3284 let mut ack_elicited = false;
3288
3289 let mut frame_processing_err = None;
3292
3293 let mut probing = true;
3296
3297 while payload.cap() > 0 {
3299 let frame = frame::Frame::from_bytes(&mut payload, hdr.ty)?;
3300
3301 qlog_with_type!(QLOG_PACKET_RX, self.qlog, _q, {
3302 qlog_frames.push(frame.to_qlog());
3303 });
3304
3305 if frame.ack_eliciting() {
3306 ack_elicited = true;
3307 }
3308
3309 if !frame.probing() {
3310 probing = false;
3311 }
3312
3313 if let Err(e) = self.process_frame(frame, &hdr, recv_pid, epoch, now)
3314 {
3315 frame_processing_err = Some(e);
3316 break;
3317 }
3318 }
3319
3320 qlog_with_type!(QLOG_PACKET_RX, self.qlog, q, {
3321 let packet_size = b.len();
3322
3323 let qlog_pkt_hdr = qlog::events::quic::PacketHeader::with_type(
3324 hdr.ty.to_qlog(),
3325 Some(pn),
3326 Some(hdr.version),
3327 Some(&hdr.scid),
3328 Some(&hdr.dcid),
3329 );
3330
3331 let qlog_raw_info = RawInfo {
3332 length: Some(packet_size as u64),
3333 payload_length: Some(payload_len as u64),
3334 data: None,
3335 };
3336
3337 let ev_data =
3338 EventData::PacketReceived(qlog::events::quic::PacketReceived {
3339 header: qlog_pkt_hdr,
3340 frames: Some(qlog_frames),
3341 raw: Some(qlog_raw_info),
3342 ..Default::default()
3343 });
3344
3345 q.add_event_data_with_instant(ev_data, now).ok();
3346 });
3347
3348 qlog_with_type!(QLOG_PACKET_RX, self.qlog, q, {
3349 let recv_path = self.paths.get_mut(recv_pid)?;
3350 if let Some(ev_data) = recv_path.recovery.maybe_qlog() {
3351 q.add_event_data_with_instant(ev_data, now).ok();
3352 }
3353 });
3354
3355 if let Some(e) = frame_processing_err {
3356 return Err(e);
3358 }
3359
3360 if self.is_established() {
3364 qlog_with_type!(QLOG_PARAMS_SET, self.qlog, q, {
3365 if !self.qlog.logged_peer_params {
3366 let ev_data = self
3367 .peer_transport_params
3368 .to_qlog(TransportOwner::Remote, self.handshake.cipher());
3369
3370 q.add_event_data_with_instant(ev_data, now).ok();
3371
3372 self.qlog.logged_peer_params = true;
3373 }
3374 });
3375 }
3376
3377 let mut pmtud_probe = false;
3379
3380 for (_, p) in self.paths.iter_mut() {
3383 for acked in p.recovery.get_acked_frames(epoch) {
3384 match acked {
3385 frame::Frame::Ping {
3386 mtu_probe: Some(mtu_probe),
3387 } => {
3388 let pmtud_next = p.pmtud.get_current();
3389 p.pmtud.set_current(cmp::max(pmtud_next, mtu_probe));
3390
3391 p.pmtud.should_probe(false);
3393 pmtud_probe = true;
3394
3395 trace!(
3396 "{} pmtud acked; pmtu size {:?}",
3397 self.trace_id,
3398 p.pmtud.get_current()
3399 );
3400 },
3401
3402 frame::Frame::ACK { ranges, .. } => {
3403 if let Some(largest_acked) = ranges.last() {
3407 self.pkt_num_spaces[epoch]
3408 .recv_pkt_need_ack
3409 .remove_until(largest_acked);
3410 }
3411 },
3412
3413 frame::Frame::CryptoHeader { offset, length } => {
3414 self.crypto_ctx[epoch]
3415 .crypto_stream
3416 .send
3417 .ack_and_drop(offset, length);
3418 },
3419
3420 frame::Frame::StreamHeader {
3421 stream_id,
3422 offset,
3423 length,
3424 ..
3425 } => {
3426 let stream = match self.streams.get_mut(stream_id) {
3427 Some(v) => v,
3428
3429 None => continue,
3430 };
3431
3432 stream.send.ack_and_drop(offset, length);
3433
3434 self.tx_buffered =
3435 self.tx_buffered.saturating_sub(length);
3436
3437 qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
3438 let ev_data = EventData::DataMoved(
3439 qlog::events::quic::DataMoved {
3440 stream_id: Some(stream_id),
3441 offset: Some(offset),
3442 length: Some(length as u64),
3443 from: Some(DataRecipient::Transport),
3444 to: Some(DataRecipient::Dropped),
3445 ..Default::default()
3446 },
3447 );
3448
3449 q.add_event_data_with_instant(ev_data, now).ok();
3450 });
3451
3452 if stream.is_complete() && !stream.is_readable() {
3456 let local = stream.local;
3457 self.streams.collect(stream_id, local);
3458 }
3459 },
3460
3461 frame::Frame::HandshakeDone => {
3462 self.handshake_done_sent = true;
3465
3466 self.handshake_done_acked = true;
3467 },
3468
3469 frame::Frame::ResetStream { stream_id, .. } => {
3470 let stream = match self.streams.get_mut(stream_id) {
3471 Some(v) => v,
3472
3473 None => continue,
3474 };
3475
3476 if stream.is_complete() && !stream.is_readable() {
3480 let local = stream.local;
3481 self.streams.collect(stream_id, local);
3482 }
3483 },
3484
3485 _ => (),
3486 }
3487 }
3488
3489 if pmtud_probe {
3491 trace!(
3492 "{} updating pmtu {:?}",
3493 p.pmtud.get_current(),
3494 self.trace_id
3495 );
3496
3497 qlog_with_type!(
3498 EventType::ConnectivityEventType(
3499 ConnectivityEventType::MtuUpdated
3500 ),
3501 self.qlog,
3502 q,
3503 {
3504 let pmtu_data = EventData::MtuUpdated(
3505 qlog::events::connectivity::MtuUpdated {
3506 old: Some(p.recovery.max_datagram_size() as u16),
3507 new: p.pmtud.get_current() as u16,
3508 done: Some(pmtud_probe),
3509 },
3510 );
3511
3512 q.add_event_data_with_instant(pmtu_data, now).ok();
3513 }
3514 );
3515
3516 p.recovery
3517 .pmtud_update_max_datagram_size(p.pmtud.get_current());
3518 }
3519 }
3520
3521 let no_dcid = self
3524 .paths
3525 .iter_mut()
3526 .filter(|(_, p)| p.active_dcid_seq.is_none());
3527
3528 for (pid, p) in no_dcid {
3529 if self.ids.zero_length_dcid() {
3530 p.active_dcid_seq = Some(0);
3531 continue;
3532 }
3533
3534 let dcid_seq = match self.ids.lowest_available_dcid_seq() {
3535 Some(seq) => seq,
3536 None => break,
3537 };
3538
3539 self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
3540
3541 p.active_dcid_seq = Some(dcid_seq);
3542 }
3543
3544 if self.pkt_num_spaces[epoch].recv_pkt_need_ack.last() < Some(pn) {
3547 self.pkt_num_spaces[epoch].largest_rx_pkt_time = now;
3548 }
3549
3550 self.pkt_num_spaces[epoch].recv_pkt_num.insert(pn);
3551
3552 self.pkt_num_spaces[epoch].recv_pkt_need_ack.push_item(pn);
3553
3554 self.pkt_num_spaces[epoch].ack_elicited =
3555 cmp::max(self.pkt_num_spaces[epoch].ack_elicited, ack_elicited);
3556
3557 self.pkt_num_spaces[epoch].largest_rx_pkt_num =
3558 cmp::max(self.pkt_num_spaces[epoch].largest_rx_pkt_num, pn);
3559
3560 if !probing {
3561 self.pkt_num_spaces[epoch].largest_rx_non_probing_pkt_num = cmp::max(
3562 self.pkt_num_spaces[epoch].largest_rx_non_probing_pkt_num,
3563 pn,
3564 );
3565
3566 let active_path_id = self.paths.get_active_path_id()?;
3568
3569 if self.is_server &&
3570 recv_pid != active_path_id &&
3571 self.pkt_num_spaces[epoch].largest_rx_non_probing_pkt_num == pn
3572 {
3573 self.on_peer_migrated(recv_pid, self.disable_dcid_reuse, now)?;
3574 }
3575 }
3576
3577 if let Some(idle_timeout) = self.idle_timeout() {
3578 self.idle_timer = Some(now + idle_timeout);
3579 }
3580
3581 self.update_tx_cap();
3583
3584 self.recv_count += 1;
3585 self.paths.get_mut(recv_pid)?.recv_count += 1;
3586
3587 let read = b.off() + aead_tag_len;
3588
3589 self.recv_bytes += read as u64;
3590 self.paths.get_mut(recv_pid)?.recv_bytes += read as u64;
3591
3592 if self.is_server && hdr.ty == packet::Type::Handshake {
3596 self.drop_epoch_state(packet::Epoch::Initial, now);
3597
3598 self.paths.get_mut(recv_pid)?.verified_peer_address = true;
3599 }
3600
3601 self.ack_eliciting_sent = false;
3602
3603 Ok(read)
3604 }
3605
3606 pub fn send(&mut self, out: &mut [u8]) -> Result<(usize, SendInfo)> {
3668 self.send_on_path(out, None, None)
3669 }
3670
3671 pub fn send_on_path(
3755 &mut self, out: &mut [u8], from: Option<SocketAddr>,
3756 to: Option<SocketAddr>,
3757 ) -> Result<(usize, SendInfo)> {
3758 if out.is_empty() {
3759 return Err(Error::BufferTooShort);
3760 }
3761
3762 if self.is_closed() || self.is_draining() {
3763 return Err(Error::Done);
3764 }
3765
3766 let now = time::Instant::now();
3767
3768 if self.local_error.is_none() {
3769 self.do_handshake(now)?;
3770 }
3771
3772 let _ = self.process_undecrypted_0rtt_packets();
3779
3780 if !self.derived_initial_secrets {
3783 return Err(Error::Done);
3784 }
3785
3786 let mut has_initial = false;
3787
3788 let mut done = 0;
3789
3790 let mut left = cmp::min(out.len(), self.max_send_udp_payload_size());
3793
3794 let send_pid = match (from, to) {
3795 (Some(f), Some(t)) => self
3796 .paths
3797 .path_id_from_addrs(&(f, t))
3798 .ok_or(Error::InvalidState)?,
3799
3800 _ => self.get_send_path_id(from, to)?,
3801 };
3802
3803 let send_path = self.paths.get_mut(send_pid)?;
3804
3805 if send_path.pmtud.get_probe_status() {
3807 let size = if self.handshake_confirmed || self.handshake_done_sent {
3808 send_path.pmtud.get_probe_size()
3809 } else {
3810 send_path.pmtud.get_current()
3811 };
3812
3813 send_path.recovery.pmtud_update_max_datagram_size(size);
3814
3815 left = cmp::min(out.len(), send_path.recovery.max_datagram_size());
3816 }
3817
3818 if !send_path.verified_peer_address && self.is_server {
3821 left = cmp::min(left, send_path.max_send_bytes);
3822 }
3823
3824 while left > 0 {
3826 let (ty, written) = match self.send_single(
3827 &mut out[done..done + left],
3828 send_pid,
3829 has_initial,
3830 now,
3831 ) {
3832 Ok(v) => v,
3833
3834 Err(Error::BufferTooShort) | Err(Error::Done) => break,
3835
3836 Err(e) => return Err(e),
3837 };
3838
3839 done += written;
3840 left -= written;
3841
3842 match ty {
3843 packet::Type::Initial => has_initial = true,
3844
3845 packet::Type::Short => break,
3847
3848 _ => (),
3849 };
3850
3851 if let Ok(epoch) = ty.to_epoch() {
3854 if self.paths.get_mut(send_pid)?.recovery.loss_probes(epoch) > 0 {
3855 break;
3856 }
3857 }
3858
3859 if !(from.is_some() && to.is_some()) &&
3861 self.get_send_path_id(from, to)? != send_pid
3862 {
3863 break;
3864 }
3865 }
3866
3867 if done == 0 {
3868 self.last_tx_data = self.tx_data;
3869
3870 return Err(Error::Done);
3871 }
3872
3873 #[cfg(not(feature = "fuzzing"))]
3875 if has_initial && left > 0 && done < MIN_CLIENT_INITIAL_LEN {
3876 let pad_len = cmp::min(left, MIN_CLIENT_INITIAL_LEN - done);
3877
3878 out[done..done + pad_len].fill(0);
3881
3882 done += pad_len;
3883 }
3884
3885 let send_path = self.paths.get(send_pid)?;
3886
3887 let info = SendInfo {
3888 from: send_path.local_addr(),
3889 to: send_path.peer_addr(),
3890
3891 at: send_path.recovery.get_packet_send_time(now),
3892 };
3893
3894 Ok((done, info))
3895 }
3896
3897 fn send_single(
3898 &mut self, out: &mut [u8], send_pid: usize, has_initial: bool,
3899 now: time::Instant,
3900 ) -> Result<(packet::Type, usize)> {
3901 if out.is_empty() {
3902 return Err(Error::BufferTooShort);
3903 }
3904
3905 if self.is_draining() {
3906 return Err(Error::Done);
3907 }
3908
3909 let is_closing = self.local_error.is_some();
3910
3911 let out_len = out.len();
3912
3913 let mut b = octets::OctetsMut::with_slice(out);
3914
3915 let pkt_type = self.write_pkt_type(send_pid)?;
3916
3917 let max_dgram_len = if !self.dgram_send_queue.is_empty() {
3918 self.dgram_max_writable_len()
3919 } else {
3920 None
3921 };
3922
3923 let epoch = pkt_type.to_epoch()?;
3924 let pkt_space = &mut self.pkt_num_spaces[epoch];
3925 let crypto_ctx = &mut self.crypto_ctx[epoch];
3926
3927 for (_, p) in self.paths.iter_mut() {
3929 for lost in p.recovery.get_lost_frames(epoch) {
3930 match lost {
3931 frame::Frame::CryptoHeader { offset, length } => {
3932 crypto_ctx.crypto_stream.send.retransmit(offset, length);
3933
3934 self.stream_retrans_bytes += length as u64;
3935 p.stream_retrans_bytes += length as u64;
3936
3937 self.retrans_count += 1;
3938 p.retrans_count += 1;
3939 },
3940
3941 frame::Frame::StreamHeader {
3942 stream_id,
3943 offset,
3944 length,
3945 fin,
3946 } => {
3947 let stream = match self.streams.get_mut(stream_id) {
3948 Some(v) => v,
3949
3950 None => continue,
3951 };
3952
3953 let was_flushable = stream.is_flushable();
3954
3955 let empty_fin = length == 0 && fin;
3956
3957 stream.send.retransmit(offset, length);
3958
3959 if (stream.is_flushable() || empty_fin) && !was_flushable
3967 {
3968 let priority_key = Arc::clone(&stream.priority_key);
3969 self.streams.insert_flushable(&priority_key);
3970 }
3971
3972 self.stream_retrans_bytes += length as u64;
3973 p.stream_retrans_bytes += length as u64;
3974
3975 self.retrans_count += 1;
3976 p.retrans_count += 1;
3977 },
3978
3979 frame::Frame::ACK { .. } => {
3980 pkt_space.ack_elicited = true;
3981 },
3982
3983 frame::Frame::ResetStream {
3984 stream_id,
3985 error_code,
3986 final_size,
3987 } =>
3988 if self.streams.get(stream_id).is_some() {
3989 self.streams
3990 .insert_reset(stream_id, error_code, final_size);
3991 },
3992
3993 frame::Frame::HandshakeDone if !self.handshake_done_acked => {
3996 self.handshake_done_sent = false;
3997 },
3998
3999 frame::Frame::MaxStreamData { stream_id, .. } => {
4000 if self.streams.get(stream_id).is_some() {
4001 self.streams.insert_almost_full(stream_id);
4002 }
4003 },
4004
4005 frame::Frame::MaxData { .. } => {
4006 self.almost_full = true;
4007 },
4008
4009 frame::Frame::NewConnectionId { seq_num, .. } => {
4010 self.ids.mark_advertise_new_scid_seq(seq_num, true);
4011 },
4012
4013 frame::Frame::RetireConnectionId { seq_num } => {
4014 self.ids.mark_retire_dcid_seq(seq_num, true)?;
4015 },
4016
4017 frame::Frame::Ping { mtu_probe } if mtu_probe.is_some() => {
4018 p.pmtud.pmtu_probe_lost();
4019 },
4020
4021 _ => (),
4022 }
4023 }
4024 }
4025
4026 let is_app_limited = self.delivery_rate_check_if_app_limited();
4027 let n_paths = self.paths.len();
4028 let path = self.paths.get_mut(send_pid)?;
4029 let flow_control = &mut self.flow_control;
4030 let pkt_space = &mut self.pkt_num_spaces[epoch];
4031 let crypto_ctx = &mut self.crypto_ctx[epoch];
4032
4033 let mut left = if path.pmtud.is_enabled() {
4034 cmp::min(path.pmtud.get_current(), b.cap())
4036 } else {
4037 b.cap()
4038 };
4039
4040 let pn = self.next_pkt_num;
4041 let largest_acked_pkt =
4042 path.recovery.get_largest_acked_on_epoch(epoch).unwrap_or(0);
4043 let pn_len = packet::pkt_num_len(pn, largest_acked_pkt);
4044
4045 let crypto_overhead = crypto_ctx.crypto_overhead().ok_or(Error::Done)?;
4047
4048 let dcid_seq = path.active_dcid_seq.ok_or(Error::OutOfIdentifiers)?;
4049
4050 let dcid =
4051 ConnectionId::from_ref(self.ids.get_dcid(dcid_seq)?.cid.as_ref());
4052
4053 let scid = if let Some(scid_seq) = path.active_scid_seq {
4054 ConnectionId::from_ref(self.ids.get_scid(scid_seq)?.cid.as_ref())
4055 } else if pkt_type == packet::Type::Short {
4056 ConnectionId::default()
4057 } else {
4058 return Err(Error::InvalidState);
4059 };
4060
4061 let hdr = Header {
4062 ty: pkt_type,
4063
4064 version: self.version,
4065
4066 dcid,
4067 scid,
4068
4069 pkt_num: 0,
4070 pkt_num_len: pn_len,
4071
4072 token: if pkt_type == packet::Type::Initial {
4076 self.token.clone()
4077 } else {
4078 None
4079 },
4080
4081 versions: None,
4082 key_phase: self.key_phase,
4083 };
4084
4085 hdr.to_bytes(&mut b)?;
4086
4087 let hdr_trace = if log::max_level() == log::LevelFilter::Trace {
4088 Some(format!("{hdr:?}"))
4089 } else {
4090 None
4091 };
4092
4093 let hdr_ty = hdr.ty;
4094
4095 #[cfg(feature = "qlog")]
4096 let qlog_pkt_hdr = self.qlog.streamer.as_ref().map(|_q| {
4097 qlog::events::quic::PacketHeader::with_type(
4098 hdr.ty.to_qlog(),
4099 Some(pn),
4100 Some(hdr.version),
4101 Some(&hdr.scid),
4102 Some(&hdr.dcid),
4103 )
4104 });
4105
4106 let mut overhead = b.off() + pn_len + crypto_overhead;
4109
4110 if pkt_type != packet::Type::Short {
4113 overhead += PAYLOAD_LENGTH_LEN;
4114 }
4115
4116 match left.checked_sub(overhead) {
4118 Some(v) => left = v,
4119
4120 None => {
4121 path.recovery.update_app_limited(false);
4128 return Err(Error::Done);
4129 },
4130 }
4131
4132 if left < PAYLOAD_MIN_LEN {
4134 path.recovery.update_app_limited(false);
4135 return Err(Error::Done);
4136 }
4137
4138 let mut frames: SmallVec<[frame::Frame; 1]> = SmallVec::new();
4139
4140 let mut ack_eliciting = false;
4141 let mut in_flight = false;
4142 let mut pmtud_probe = false;
4144 let mut has_data = false;
4145
4146 let ack_elicit_required = path.recovery.should_elicit_ack(epoch);
4149
4150 let header_offset = b.off();
4151
4152 if pkt_type != packet::Type::Short {
4157 b.skip(PAYLOAD_LENGTH_LEN)?;
4158 }
4159
4160 packet::encode_pkt_num(pn, pn_len, &mut b)?;
4161
4162 let payload_offset = b.off();
4163
4164 let cwnd_available =
4165 path.recovery.cwnd_available().saturating_sub(overhead);
4166
4167 let left_before_packing_ack_frame = left;
4168
4169 if pkt_space.recv_pkt_need_ack.len() > 0 &&
4176 (pkt_space.ack_elicited || ack_elicit_required) &&
4177 (!is_closing ||
4178 (pkt_type == Type::Handshake &&
4179 self.local_error
4180 .as_ref()
4181 .is_some_and(|le| le.is_app))) &&
4182 path.active()
4183 {
4184 let ack_delay = pkt_space.largest_rx_pkt_time.elapsed();
4185
4186 let ack_delay = ack_delay.as_micros() as u64 /
4187 2_u64
4188 .pow(self.local_transport_params.ack_delay_exponent as u32);
4189
4190 let frame = frame::Frame::ACK {
4191 ack_delay,
4192 ranges: pkt_space.recv_pkt_need_ack.clone(),
4193 ecn_counts: None, };
4195
4196 if pkt_space.ack_elicited || frame.wire_len() < cwnd_available {
4201 if push_frame_to_pkt!(b, frames, frame, left) {
4205 pkt_space.ack_elicited = false;
4206 }
4207 }
4208 }
4209
4210 left = cmp::min(
4212 left,
4213 cwnd_available.saturating_sub(left_before_packing_ack_frame - left),
4215 );
4216
4217 let mut challenge_data = None;
4218
4219 let active_path = self.paths.get_active_mut()?;
4220
4221 if pkt_type == packet::Type::Short {
4222 let pmtu_probe = active_path.should_send_pmtu_probe(
4235 self.handshake_confirmed,
4236 self.handshake_done_sent,
4237 out_len,
4238 is_closing,
4239 frames.is_empty(),
4240 );
4241
4242 trace!("{} pmtud probe status {} hs_con={} hs_sent={} cwnd_avail={} out_len={} left={}", self.trace_id, pmtu_probe, self.handshake_confirmed, self.handshake_done_sent,
4243 active_path.recovery.cwnd_available(), out_len, left);
4244
4245 if pmtu_probe {
4246 trace!(
4247 "{} sending pmtud probe pmtu_probe={} next_size={} pmtu={}",
4248 self.trace_id,
4249 active_path.pmtud.get_probe_size(),
4250 active_path.pmtud.get_probe_status(),
4251 active_path.pmtud.get_current(),
4252 );
4253
4254 left = active_path.pmtud.get_probe_size();
4255
4256 match left.checked_sub(overhead) {
4257 Some(v) => left = v,
4258
4259 None => {
4260 active_path.recovery.update_app_limited(false);
4269 return Err(Error::Done);
4270 },
4271 }
4272
4273 let frame = frame::Frame::Padding {
4274 len: active_path.pmtud.get_probe_size() - overhead - 1,
4275 };
4276
4277 if push_frame_to_pkt!(b, frames, frame, left) {
4278 let frame = frame::Frame::Ping {
4279 mtu_probe: Some(active_path.pmtud.get_probe_size()),
4280 };
4281
4282 if push_frame_to_pkt!(b, frames, frame, left) {
4283 ack_eliciting = true;
4284 in_flight = true;
4285 }
4286 }
4287
4288 pmtud_probe = true;
4289 }
4290
4291 let path = self.paths.get_mut(send_pid)?;
4292 while let Some(challenge) = path.pop_received_challenge() {
4295 let frame = frame::Frame::PathResponse { data: challenge };
4296
4297 if push_frame_to_pkt!(b, frames, frame, left) {
4298 ack_eliciting = true;
4299 in_flight = true;
4300 } else {
4301 break;
4304 }
4305 }
4306
4307 if path.validation_requested() {
4309 let data = rand::rand_u64().to_be_bytes();
4311
4312 let frame = frame::Frame::PathChallenge { data };
4313
4314 if push_frame_to_pkt!(b, frames, frame, left) {
4315 challenge_data = Some(data);
4317
4318 ack_eliciting = true;
4319 in_flight = true;
4320 }
4321 }
4322
4323 if let Some(key_update) = crypto_ctx.key_update.as_mut() {
4324 key_update.update_acked = true;
4325 }
4326 }
4327
4328 let path = self.paths.get_mut(send_pid)?;
4329
4330 if pkt_type == packet::Type::Short && !is_closing {
4331 while let Some(seq_num) = self.ids.next_advertise_new_scid_seq() {
4333 let frame = self.ids.get_new_connection_id_frame_for(seq_num)?;
4334
4335 if push_frame_to_pkt!(b, frames, frame, left) {
4336 self.ids.mark_advertise_new_scid_seq(seq_num, false);
4337
4338 ack_eliciting = true;
4339 in_flight = true;
4340 } else {
4341 break;
4342 }
4343 }
4344 }
4345
4346 if pkt_type == packet::Type::Short && !is_closing && path.active() {
4347 if self.handshake_completed &&
4350 !self.handshake_done_sent &&
4351 self.is_server
4352 {
4353 let frame = frame::Frame::HandshakeDone;
4354
4355 if push_frame_to_pkt!(b, frames, frame, left) {
4356 self.handshake_done_sent = true;
4357
4358 ack_eliciting = true;
4359 in_flight = true;
4360 }
4361 }
4362
4363 if self.streams.should_update_max_streams_bidi() {
4365 let frame = frame::Frame::MaxStreamsBidi {
4366 max: self.streams.max_streams_bidi_next(),
4367 };
4368
4369 if push_frame_to_pkt!(b, frames, frame, left) {
4370 self.streams.update_max_streams_bidi();
4371
4372 ack_eliciting = true;
4373 in_flight = true;
4374 }
4375 }
4376
4377 if self.streams.should_update_max_streams_uni() {
4379 let frame = frame::Frame::MaxStreamsUni {
4380 max: self.streams.max_streams_uni_next(),
4381 };
4382
4383 if push_frame_to_pkt!(b, frames, frame, left) {
4384 self.streams.update_max_streams_uni();
4385
4386 ack_eliciting = true;
4387 in_flight = true;
4388 }
4389 }
4390
4391 if let Some(limit) = self.blocked_limit {
4393 let frame = frame::Frame::DataBlocked { limit };
4394
4395 if push_frame_to_pkt!(b, frames, frame, left) {
4396 self.blocked_limit = None;
4397
4398 ack_eliciting = true;
4399 in_flight = true;
4400 }
4401 }
4402
4403 for stream_id in self.streams.almost_full() {
4405 let stream = match self.streams.get_mut(stream_id) {
4406 Some(v) => v,
4407
4408 None => {
4409 self.streams.remove_almost_full(stream_id);
4412 continue;
4413 },
4414 };
4415
4416 stream.recv.autotune_window(now, path.recovery.rtt());
4418
4419 let frame = frame::Frame::MaxStreamData {
4420 stream_id,
4421 max: stream.recv.max_data_next(),
4422 };
4423
4424 if push_frame_to_pkt!(b, frames, frame, left) {
4425 let recv_win = stream.recv.window();
4426
4427 stream.recv.update_max_data(now);
4428
4429 self.streams.remove_almost_full(stream_id);
4430
4431 ack_eliciting = true;
4432 in_flight = true;
4433
4434 flow_control.ensure_window_lower_bound(
4437 (recv_win as f64 * CONNECTION_WINDOW_FACTOR) as u64,
4438 );
4439
4440 self.almost_full = true;
4443 }
4444 }
4445
4446 if self.almost_full &&
4448 flow_control.max_data() < flow_control.max_data_next()
4449 {
4450 flow_control.autotune_window(now, path.recovery.rtt());
4452
4453 let frame = frame::Frame::MaxData {
4454 max: flow_control.max_data_next(),
4455 };
4456
4457 if push_frame_to_pkt!(b, frames, frame, left) {
4458 self.almost_full = false;
4459
4460 flow_control.update_max_data(now);
4462
4463 ack_eliciting = true;
4464 in_flight = true;
4465 }
4466 }
4467
4468 for (stream_id, error_code) in self
4470 .streams
4471 .stopped()
4472 .map(|(&k, &v)| (k, v))
4473 .collect::<Vec<(u64, u64)>>()
4474 {
4475 let frame = frame::Frame::StopSending {
4476 stream_id,
4477 error_code,
4478 };
4479
4480 if push_frame_to_pkt!(b, frames, frame, left) {
4481 self.streams.remove_stopped(stream_id);
4482
4483 ack_eliciting = true;
4484 in_flight = true;
4485 }
4486 }
4487
4488 for (stream_id, (error_code, final_size)) in self
4490 .streams
4491 .reset()
4492 .map(|(&k, &v)| (k, v))
4493 .collect::<Vec<(u64, (u64, u64))>>()
4494 {
4495 let frame = frame::Frame::ResetStream {
4496 stream_id,
4497 error_code,
4498 final_size,
4499 };
4500
4501 if push_frame_to_pkt!(b, frames, frame, left) {
4502 self.streams.remove_reset(stream_id);
4503
4504 ack_eliciting = true;
4505 in_flight = true;
4506 }
4507 }
4508
4509 for (stream_id, limit) in self
4511 .streams
4512 .blocked()
4513 .map(|(&k, &v)| (k, v))
4514 .collect::<Vec<(u64, u64)>>()
4515 {
4516 let frame = frame::Frame::StreamDataBlocked { stream_id, limit };
4517
4518 if push_frame_to_pkt!(b, frames, frame, left) {
4519 self.streams.remove_blocked(stream_id);
4520
4521 ack_eliciting = true;
4522 in_flight = true;
4523 }
4524 }
4525
4526 while let Some(seq_num) = self.ids.next_retire_dcid_seq() {
4528 let dcid_seq = path.active_dcid_seq.ok_or(Error::InvalidState)?;
4532
4533 if seq_num == dcid_seq {
4534 continue;
4535 }
4536
4537 let frame = frame::Frame::RetireConnectionId { seq_num };
4538
4539 if push_frame_to_pkt!(b, frames, frame, left) {
4540 self.ids.mark_retire_dcid_seq(seq_num, false)?;
4541
4542 ack_eliciting = true;
4543 in_flight = true;
4544 } else {
4545 break;
4546 }
4547 }
4548 }
4549
4550 if path.active() || n_paths == 1 {
4553 if let Some(conn_err) = self.local_error.as_ref() {
4554 if conn_err.is_app {
4555 if pkt_type == packet::Type::Short {
4557 let frame = frame::Frame::ApplicationClose {
4558 error_code: conn_err.error_code,
4559 reason: conn_err.reason.clone(),
4560 };
4561
4562 if push_frame_to_pkt!(b, frames, frame, left) {
4563 let pto = path.recovery.pto();
4564 self.draining_timer = Some(now + (pto * 3));
4565
4566 ack_eliciting = true;
4567 in_flight = true;
4568 }
4569 }
4570 } else {
4571 let frame = frame::Frame::ConnectionClose {
4573 error_code: conn_err.error_code,
4574 frame_type: 0,
4575 reason: conn_err.reason.clone(),
4576 };
4577
4578 if push_frame_to_pkt!(b, frames, frame, left) {
4579 let pto = path.recovery.pto();
4580 self.draining_timer = Some(now + (pto * 3));
4581
4582 ack_eliciting = true;
4583 in_flight = true;
4584 }
4585 }
4586 }
4587 }
4588
4589 if crypto_ctx.crypto_stream.is_flushable() &&
4591 left > frame::MAX_CRYPTO_OVERHEAD &&
4592 !is_closing &&
4593 path.active()
4594 {
4595 let crypto_off = crypto_ctx.crypto_stream.send.off_front();
4596
4597 let hdr_off = b.off();
4611 let hdr_len = 1 + octets::varint_len(crypto_off) + 2; if let Some(max_len) = left.checked_sub(hdr_len) {
4616 let (mut crypto_hdr, mut crypto_payload) =
4617 b.split_at(hdr_off + hdr_len)?;
4618
4619 let (len, _) = crypto_ctx
4621 .crypto_stream
4622 .send
4623 .emit(&mut crypto_payload.as_mut()[..max_len])?;
4624
4625 crypto_hdr.skip(hdr_off)?;
4632
4633 frame::encode_crypto_header(
4634 crypto_off,
4635 len as u64,
4636 &mut crypto_hdr,
4637 )?;
4638
4639 b.skip(hdr_len + len)?;
4641
4642 let frame = frame::Frame::CryptoHeader {
4643 offset: crypto_off,
4644 length: len,
4645 };
4646
4647 if push_frame_to_pkt!(b, frames, frame, left) {
4648 ack_eliciting = true;
4649 in_flight = true;
4650 has_data = true;
4651 }
4652 }
4653 }
4654
4655 let mut dgram_emitted = false;
4661 let dgrams_to_emit = max_dgram_len.is_some();
4662 let stream_to_emit = self.streams.has_flushable();
4663
4664 let mut do_dgram = self.emit_dgram && dgrams_to_emit;
4665 let do_stream = !self.emit_dgram && stream_to_emit;
4666
4667 if !do_stream && dgrams_to_emit {
4668 do_dgram = true;
4669 }
4670
4671 if (pkt_type == packet::Type::Short || pkt_type == packet::Type::ZeroRTT) &&
4673 left > frame::MAX_DGRAM_OVERHEAD &&
4674 !is_closing &&
4675 path.active() &&
4676 do_dgram
4677 {
4678 if let Some(max_dgram_payload) = max_dgram_len {
4679 while let Some(len) = self.dgram_send_queue.peek_front_len() {
4680 let hdr_off = b.off();
4681 let hdr_len = 1 + 2; if (hdr_len + len) <= left {
4685 match self.dgram_send_queue.pop() {
4687 Some(data) => {
4688 let (mut dgram_hdr, mut dgram_payload) =
4705 b.split_at(hdr_off + hdr_len)?;
4706
4707 dgram_payload.as_mut()[..len]
4708 .copy_from_slice(&data);
4709
4710 dgram_hdr.skip(hdr_off)?;
4718
4719 frame::encode_dgram_header(
4720 len as u64,
4721 &mut dgram_hdr,
4722 )?;
4723
4724 b.skip(hdr_len + len)?;
4726
4727 let frame =
4728 frame::Frame::DatagramHeader { length: len };
4729
4730 if push_frame_to_pkt!(b, frames, frame, left) {
4731 ack_eliciting = true;
4732 in_flight = true;
4733 dgram_emitted = true;
4734 let _ =
4735 self.dgram_sent_count.saturating_add(1);
4736 let _ =
4737 path.dgram_sent_count.saturating_add(1);
4738 }
4739 },
4740
4741 None => continue,
4742 };
4743 } else if len > max_dgram_payload {
4744 self.dgram_send_queue.pop();
4746 } else {
4747 break;
4748 }
4749 }
4750 }
4751 }
4752
4753 if (pkt_type == packet::Type::Short || pkt_type == packet::Type::ZeroRTT) &&
4755 left > frame::MAX_STREAM_OVERHEAD &&
4756 !is_closing &&
4757 path.active() &&
4758 !dgram_emitted
4759 {
4760 while let Some(priority_key) = self.streams.peek_flushable() {
4761 let stream_id = priority_key.id;
4762 let stream = match self.streams.get_mut(stream_id) {
4763 Some(v) if !v.send.is_stopped() => v,
4768 _ => {
4769 self.streams.remove_flushable(&priority_key);
4770 continue;
4771 },
4772 };
4773
4774 let stream_off = stream.send.off_front();
4775
4776 let hdr_off = b.off();
4790 let hdr_len = 1 + octets::varint_len(stream_id) + octets::varint_len(stream_off) + 2; let max_len = match left.checked_sub(hdr_len) {
4796 Some(v) => v,
4797 None => {
4798 let priority_key = Arc::clone(&stream.priority_key);
4799 self.streams.remove_flushable(&priority_key);
4800
4801 continue;
4802 },
4803 };
4804
4805 let (mut stream_hdr, mut stream_payload) =
4806 b.split_at(hdr_off + hdr_len)?;
4807
4808 let (len, fin) =
4810 stream.send.emit(&mut stream_payload.as_mut()[..max_len])?;
4811
4812 stream_hdr.skip(hdr_off)?;
4819
4820 frame::encode_stream_header(
4821 stream_id,
4822 stream_off,
4823 len as u64,
4824 fin,
4825 &mut stream_hdr,
4826 )?;
4827
4828 b.skip(hdr_len + len)?;
4830
4831 let frame = frame::Frame::StreamHeader {
4832 stream_id,
4833 offset: stream_off,
4834 length: len,
4835 fin,
4836 };
4837
4838 if push_frame_to_pkt!(b, frames, frame, left) {
4839 ack_eliciting = true;
4840 in_flight = true;
4841 has_data = true;
4842 }
4843
4844 let priority_key = Arc::clone(&stream.priority_key);
4845 if !stream.is_flushable() {
4847 self.streams.remove_flushable(&priority_key);
4848 } else if stream.incremental {
4849 self.streams.remove_flushable(&priority_key);
4852 self.streams.insert_flushable(&priority_key);
4853 }
4854
4855 #[cfg(feature = "fuzzing")]
4856 if left > frame::MAX_STREAM_OVERHEAD {
4858 continue;
4859 }
4860
4861 break;
4862 }
4863 }
4864
4865 self.emit_dgram = !dgram_emitted;
4867
4868 if (ack_elicit_required || path.needs_ack_eliciting) &&
4874 !ack_eliciting &&
4875 left >= 1 &&
4876 !is_closing
4877 {
4878 let frame = frame::Frame::Ping { mtu_probe: None };
4879
4880 if push_frame_to_pkt!(b, frames, frame, left) {
4881 ack_eliciting = true;
4882 in_flight = true;
4883 }
4884 }
4885
4886 if ack_eliciting && !pmtud_probe {
4887 path.needs_ack_eliciting = false;
4888 path.recovery.ping_sent(epoch);
4889 }
4890
4891 if !has_data &&
4892 !dgram_emitted &&
4893 cwnd_available > frame::MAX_STREAM_OVERHEAD
4894 {
4895 path.recovery.on_app_limited();
4896 }
4897
4898 if frames.is_empty() {
4899 path.recovery.update_app_limited(false);
4902 return Err(Error::Done);
4903 }
4904
4905 if (has_initial || !path.validated()) &&
4914 pkt_type == packet::Type::Short &&
4915 left >= 1
4916 {
4917 let frame = frame::Frame::Padding { len: left };
4918
4919 if push_frame_to_pkt!(b, frames, frame, left) {
4920 in_flight = true;
4921 }
4922 }
4923
4924 if b.off() - payload_offset < PAYLOAD_MIN_LEN {
4926 let payload_len = b.off() - payload_offset;
4927
4928 let frame = frame::Frame::Padding {
4929 len: PAYLOAD_MIN_LEN - payload_len,
4930 };
4931
4932 #[allow(unused_assignments)]
4933 if push_frame_to_pkt!(b, frames, frame, left) {
4934 in_flight = true;
4935 }
4936 }
4937
4938 let payload_len = b.off() - payload_offset;
4939
4940 if pkt_type != packet::Type::Short {
4942 let len = pn_len + payload_len + crypto_overhead;
4943
4944 let (_, mut payload_with_len) = b.split_at(header_offset)?;
4945 payload_with_len
4946 .put_varint_with_len(len as u64, PAYLOAD_LENGTH_LEN)?;
4947 }
4948
4949 trace!(
4950 "{} tx pkt {} len={} pn={} {}",
4951 self.trace_id,
4952 hdr_trace.unwrap_or_default(),
4953 payload_len,
4954 pn,
4955 AddrTupleFmt(path.local_addr(), path.peer_addr())
4956 );
4957
4958 #[cfg(feature = "qlog")]
4959 let mut qlog_frames: SmallVec<
4960 [qlog::events::quic::QuicFrame; 1],
4961 > = SmallVec::with_capacity(frames.len());
4962
4963 for frame in &mut frames {
4964 trace!("{} tx frm {:?}", self.trace_id, frame);
4965
4966 qlog_with_type!(QLOG_PACKET_TX, self.qlog, _q, {
4967 qlog_frames.push(frame.to_qlog());
4968 });
4969 }
4970
4971 qlog_with_type!(QLOG_PACKET_TX, self.qlog, q, {
4972 if let Some(header) = qlog_pkt_hdr {
4973 let length = payload_len + payload_offset + crypto_overhead;
4978 let qlog_raw_info = RawInfo {
4979 length: Some(length as u64),
4980 payload_length: Some(payload_len as u64),
4981 data: None,
4982 };
4983
4984 let send_at_time =
4985 now.duration_since(q.start_time()).as_secs_f32() * 1000.0;
4986
4987 let ev_data =
4988 EventData::PacketSent(qlog::events::quic::PacketSent {
4989 header,
4990 frames: Some(qlog_frames),
4991 raw: Some(qlog_raw_info),
4992 send_at_time: Some(send_at_time),
4993 ..Default::default()
4994 });
4995
4996 q.add_event_data_with_instant(ev_data, now).ok();
4997 }
4998 });
4999
5000 let aead = match crypto_ctx.crypto_seal {
5001 Some(ref v) => v,
5002 None => return Err(Error::InvalidState),
5003 };
5004
5005 let written = packet::encrypt_pkt(
5006 &mut b,
5007 pn,
5008 pn_len,
5009 payload_len,
5010 payload_offset,
5011 None,
5012 aead,
5013 )?;
5014
5015 let sent_pkt_has_data = if path.recovery.gcongestion_enabled() {
5016 has_data || dgram_emitted
5017 } else {
5018 has_data
5019 };
5020
5021 let sent_pkt = recovery::Sent {
5022 pkt_num: pn,
5023 frames,
5024 time_sent: now,
5025 time_acked: None,
5026 time_lost: None,
5027 size: if ack_eliciting { written } else { 0 },
5028 ack_eliciting,
5029 in_flight,
5030 delivered: 0,
5031 delivered_time: now,
5032 first_sent_time: now,
5033 is_app_limited: false,
5034 tx_in_flight: 0,
5035 lost: 0,
5036 has_data: sent_pkt_has_data,
5037 pmtud: pmtud_probe,
5038 };
5039
5040 if in_flight && is_app_limited {
5041 path.recovery.delivery_rate_update_app_limited(true);
5042 }
5043
5044 self.next_pkt_num += 1;
5045
5046 let handshake_status = recovery::HandshakeStatus {
5047 has_handshake_keys: self.crypto_ctx[packet::Epoch::Handshake]
5048 .has_keys(),
5049 peer_verified_address: self.peer_verified_initial_address,
5050 completed: self.handshake_completed,
5051 };
5052
5053 path.recovery.on_packet_sent(
5054 sent_pkt,
5055 epoch,
5056 handshake_status,
5057 now,
5058 &self.trace_id,
5059 );
5060
5061 qlog_with_type!(QLOG_METRICS, self.qlog, q, {
5062 if let Some(ev_data) = path.recovery.maybe_qlog() {
5063 q.add_event_data_with_instant(ev_data, now).ok();
5064 }
5065 });
5066
5067 if let Some(data) = challenge_data {
5069 path.add_challenge_sent(data, written, now);
5070 }
5071
5072 self.sent_count += 1;
5073 self.sent_bytes += written as u64;
5074 path.sent_count += 1;
5075 path.sent_bytes += written as u64;
5076
5077 if self.dgram_send_queue.byte_size() > path.recovery.cwnd_available() {
5078 path.recovery.update_app_limited(false);
5079 }
5080
5081 path.max_send_bytes = path.max_send_bytes.saturating_sub(written);
5082
5083 if !self.is_server && hdr_ty == packet::Type::Handshake {
5085 self.drop_epoch_state(packet::Epoch::Initial, now);
5086 }
5087
5088 if ack_eliciting && !self.ack_eliciting_sent {
5091 if let Some(idle_timeout) = self.idle_timeout() {
5092 self.idle_timer = Some(now + idle_timeout);
5093 }
5094 }
5095
5096 if ack_eliciting {
5097 self.ack_eliciting_sent = true;
5098 }
5099
5100 let active_path = self.paths.get_active_mut()?;
5101 if active_path.pmtud.is_enabled() {
5102 active_path
5103 .recovery
5104 .pmtud_update_max_datagram_size(active_path.pmtud.get_current());
5105 }
5106
5107 Ok((pkt_type, written))
5108 }
5109
5110 #[inline]
5112 pub fn get_next_release_time(&self) -> Option<ReleaseDecision> {
5113 Some(
5114 self.paths
5115 .get_active()
5116 .ok()?
5117 .recovery
5118 .get_next_release_time(),
5119 )
5120 }
5121
5122 #[inline]
5124 pub fn gcongestion_enabled(&self) -> Option<bool> {
5125 Some(self.paths.get_active().ok()?.recovery.gcongestion_enabled())
5126 }
5127
5128 pub fn max_release_into_future(&self) -> time::Duration {
5133 self.paths
5134 .get_active()
5135 .map(|p| p.recovery.rtt().mul_f64(0.125))
5136 .unwrap_or(time::Duration::from_millis(1))
5137 .max(Duration::from_millis(1))
5138 .min(Duration::from_millis(5))
5139 }
5140
5141 #[inline]
5143 pub fn pacing_enabled(&self) -> bool {
5144 self.recovery_config.pacing
5145 }
5146
5147 #[inline]
5156 pub fn send_quantum(&self) -> usize {
5157 match self.paths.get_active() {
5158 Ok(p) => p.recovery.send_quantum(),
5159 _ => 0,
5160 }
5161 }
5162
5163 pub fn send_quantum_on_path(
5175 &self, local_addr: SocketAddr, peer_addr: SocketAddr,
5176 ) -> usize {
5177 self.paths
5178 .path_id_from_addrs(&(local_addr, peer_addr))
5179 .and_then(|pid| self.paths.get(pid).ok())
5180 .map(|path| path.recovery.send_quantum())
5181 .unwrap_or(0)
5182 }
5183
5184 pub fn stream_recv(
5215 &mut self, stream_id: u64, out: &mut [u8],
5216 ) -> Result<(usize, bool)> {
5217 if !stream::is_bidi(stream_id) &&
5219 stream::is_local(stream_id, self.is_server)
5220 {
5221 return Err(Error::InvalidStreamState(stream_id));
5222 }
5223
5224 let stream = self
5225 .streams
5226 .get_mut(stream_id)
5227 .ok_or(Error::InvalidStreamState(stream_id))?;
5228
5229 if !stream.is_readable() {
5230 return Err(Error::Done);
5231 }
5232
5233 let local = stream.local;
5234 let priority_key = Arc::clone(&stream.priority_key);
5235
5236 #[cfg(feature = "qlog")]
5237 let offset = stream.recv.off_front();
5238
5239 let (read, fin) = match stream.recv.emit(out) {
5240 Ok(v) => v,
5241
5242 Err(e) => {
5243 if stream.is_complete() {
5248 self.streams.collect(stream_id, local);
5249 }
5250
5251 self.streams.remove_readable(&priority_key);
5252 return Err(e);
5253 },
5254 };
5255
5256 self.flow_control.add_consumed(read as u64);
5257
5258 let readable = stream.is_readable();
5259
5260 let complete = stream.is_complete();
5261
5262 if stream.recv.almost_full() {
5263 self.streams.insert_almost_full(stream_id);
5264 }
5265
5266 if !readable {
5267 self.streams.remove_readable(&priority_key);
5268 }
5269
5270 if complete {
5271 self.streams.collect(stream_id, local);
5272 }
5273
5274 qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
5275 let ev_data = EventData::DataMoved(qlog::events::quic::DataMoved {
5276 stream_id: Some(stream_id),
5277 offset: Some(offset),
5278 length: Some(read as u64),
5279 from: Some(DataRecipient::Transport),
5280 to: Some(DataRecipient::Application),
5281 ..Default::default()
5282 });
5283
5284 let now = time::Instant::now();
5285 q.add_event_data_with_instant(ev_data, now).ok();
5286 });
5287
5288 if self.should_update_max_data() {
5289 self.almost_full = true;
5290 }
5291
5292 if priority_key.incremental && readable {
5293 self.streams.remove_readable(&priority_key);
5295 self.streams.insert_readable(&priority_key);
5296 }
5297
5298 Ok((read, fin))
5299 }
5300
5301 pub fn stream_send(
5349 &mut self, stream_id: u64, buf: &[u8], fin: bool,
5350 ) -> Result<usize> {
5351 self.stream_do_send(
5352 stream_id,
5353 buf,
5354 fin,
5355 |stream: &mut stream::Stream<F>,
5356 buf: &[u8],
5357 cap: usize,
5358 fin: bool| {
5359 stream.send.write(&buf[..cap], fin).map(|v| (v, v))
5360 },
5361 )
5362 }
5363
5364 pub fn stream_send_zc(
5373 &mut self, stream_id: u64, buf: F::Buf, len: Option<usize>, fin: bool,
5374 ) -> Result<(usize, Option<F::Buf>)>
5375 where
5376 F::Buf: BufSplit,
5377 {
5378 self.stream_do_send(
5379 stream_id,
5380 buf,
5381 fin,
5382 |stream: &mut stream::Stream<F>,
5383 buf: F::Buf,
5384 cap: usize,
5385 fin: bool| {
5386 let len = len.unwrap_or(usize::MAX).min(cap);
5387 let (sent, remaining) = stream.send.append_buf(buf, len, fin)?;
5388 Ok((sent, (sent, remaining)))
5389 },
5390 )
5391 }
5392
5393 fn stream_do_send<B, R, SND>(
5394 &mut self, stream_id: u64, buf: B, fin: bool, write_fn: SND,
5395 ) -> Result<R>
5396 where
5397 B: AsRef<[u8]>,
5398 SND: FnOnce(&mut stream::Stream<F>, B, usize, bool) -> Result<(usize, R)>,
5399 {
5400 if !stream::is_bidi(stream_id) &&
5402 !stream::is_local(stream_id, self.is_server)
5403 {
5404 return Err(Error::InvalidStreamState(stream_id));
5405 }
5406
5407 let len = buf.as_ref().len();
5408
5409 if self.max_tx_data - self.tx_data < len as u64 {
5415 self.blocked_limit = Some(self.max_tx_data);
5416 }
5417
5418 let cap = self.tx_cap;
5419
5420 let stream = self.get_or_create_stream(stream_id, true)?;
5422
5423 #[cfg(feature = "qlog")]
5424 let offset = stream.send.off_back();
5425
5426 let was_writable = stream.is_writable();
5427
5428 let was_flushable = stream.is_flushable();
5429
5430 let priority_key = Arc::clone(&stream.priority_key);
5431
5432 if cap == 0 && len > 0 {
5438 if was_writable {
5439 self.streams.insert_writable(&priority_key);
5446 }
5447
5448 return Err(Error::Done);
5449 }
5450
5451 let (cap, fin, blocked_by_cap) = if cap < len {
5452 (cap, false, true)
5453 } else {
5454 (len, fin, false)
5455 };
5456
5457 let (sent, ret) = match write_fn(stream, buf, cap, fin) {
5458 Ok(v) => v,
5459
5460 Err(e) => {
5461 self.streams.remove_writable(&priority_key);
5462 return Err(e);
5463 },
5464 };
5465
5466 let incremental = stream.incremental;
5467 let priority_key = Arc::clone(&stream.priority_key);
5468
5469 let flushable = stream.is_flushable();
5470
5471 let writable = stream.is_writable();
5472
5473 let empty_fin = len == 0 && fin;
5474
5475 if sent < cap {
5476 let max_off = stream.send.max_off();
5477
5478 if stream.send.blocked_at() != Some(max_off) {
5479 stream.send.update_blocked_at(Some(max_off));
5480 self.streams.insert_blocked(stream_id, max_off);
5481 }
5482 } else {
5483 stream.send.update_blocked_at(None);
5484 self.streams.remove_blocked(stream_id);
5485 }
5486
5487 if (flushable || empty_fin) && !was_flushable {
5493 self.streams.insert_flushable(&priority_key);
5494 }
5495
5496 if !writable {
5497 self.streams.remove_writable(&priority_key);
5498 } else if was_writable && blocked_by_cap {
5499 self.streams.insert_writable(&priority_key);
5506 }
5507
5508 self.tx_cap -= sent;
5509
5510 self.tx_data += sent as u64;
5511
5512 self.tx_buffered += sent;
5513
5514 qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
5515 let ev_data = EventData::DataMoved(qlog::events::quic::DataMoved {
5516 stream_id: Some(stream_id),
5517 offset: Some(offset),
5518 length: Some(sent as u64),
5519 from: Some(DataRecipient::Application),
5520 to: Some(DataRecipient::Transport),
5521 ..Default::default()
5522 });
5523
5524 let now = time::Instant::now();
5525 q.add_event_data_with_instant(ev_data, now).ok();
5526 });
5527
5528 if sent == 0 && cap > 0 {
5529 return Err(Error::Done);
5530 }
5531
5532 if incremental && writable {
5533 self.streams.remove_writable(&priority_key);
5535 self.streams.insert_writable(&priority_key);
5536 }
5537
5538 Ok(ret)
5539 }
5540
5541 pub fn stream_priority(
5550 &mut self, stream_id: u64, urgency: u8, incremental: bool,
5551 ) -> Result<()> {
5552 let stream = match self.get_or_create_stream(stream_id, true) {
5555 Ok(v) => v,
5556
5557 Err(Error::Done) => return Ok(()),
5558
5559 Err(e) => return Err(e),
5560 };
5561
5562 if stream.urgency == urgency && stream.incremental == incremental {
5563 return Ok(());
5564 }
5565
5566 stream.urgency = urgency;
5567 stream.incremental = incremental;
5568
5569 let new_priority_key = Arc::new(StreamPriorityKey {
5570 urgency: stream.urgency,
5571 incremental: stream.incremental,
5572 id: stream_id,
5573 ..Default::default()
5574 });
5575
5576 let old_priority_key =
5577 std::mem::replace(&mut stream.priority_key, new_priority_key.clone());
5578
5579 self.streams
5580 .update_priority(&old_priority_key, &new_priority_key);
5581
5582 Ok(())
5583 }
5584
5585 pub fn stream_shutdown(
5611 &mut self, stream_id: u64, direction: Shutdown, err: u64,
5612 ) -> Result<()> {
5613 if direction == Shutdown::Read &&
5615 stream::is_local(stream_id, self.is_server) &&
5616 !stream::is_bidi(stream_id)
5617 {
5618 return Err(Error::InvalidStreamState(stream_id));
5619 }
5620
5621 if direction == Shutdown::Write &&
5623 !stream::is_local(stream_id, self.is_server) &&
5624 !stream::is_bidi(stream_id)
5625 {
5626 return Err(Error::InvalidStreamState(stream_id));
5627 }
5628
5629 let stream = self.streams.get_mut(stream_id).ok_or(Error::Done)?;
5631
5632 let priority_key = Arc::clone(&stream.priority_key);
5633
5634 match direction {
5635 Shutdown::Read => {
5636 stream.recv.shutdown()?;
5637
5638 if !stream.recv.is_fin() {
5639 self.streams.insert_stopped(stream_id, err);
5640 }
5641
5642 self.streams.remove_readable(&priority_key);
5644
5645 self.stopped_stream_local_count =
5646 self.stopped_stream_local_count.saturating_add(1);
5647 },
5648
5649 Shutdown::Write => {
5650 let (final_size, unsent) = stream.send.shutdown()?;
5651
5652 self.tx_data = self.tx_data.saturating_sub(unsent);
5655
5656 self.tx_buffered =
5657 self.tx_buffered.saturating_sub(unsent as usize);
5658
5659 self.update_tx_cap();
5661
5662 self.streams.insert_reset(stream_id, err, final_size);
5663
5664 self.streams.remove_writable(&priority_key);
5666
5667 self.reset_stream_local_count =
5668 self.reset_stream_local_count.saturating_add(1);
5669 },
5670 }
5671
5672 Ok(())
5673 }
5674
5675 #[inline]
5688 pub fn stream_capacity(&self, stream_id: u64) -> Result<usize> {
5689 if let Some(stream) = self.streams.get(stream_id) {
5690 let cap = cmp::min(self.tx_cap, stream.send.cap()?);
5691 return Ok(cap);
5692 };
5693
5694 Err(Error::InvalidStreamState(stream_id))
5695 }
5696
5697 pub fn stream_readable_next(&mut self) -> Option<u64> {
5710 let priority_key = self.streams.readable.front().clone_pointer()?;
5711
5712 self.streams.remove_readable(&priority_key);
5713
5714 Some(priority_key.id)
5715 }
5716
5717 pub fn stream_readable(&self, stream_id: u64) -> bool {
5719 let stream = match self.streams.get(stream_id) {
5720 Some(v) => v,
5721
5722 None => return false,
5723 };
5724
5725 stream.is_readable()
5726 }
5727
5728 pub fn stream_writable_next(&mut self) -> Option<u64> {
5744 if self.tx_cap == 0 {
5747 return None;
5748 }
5749
5750 let mut cursor = self.streams.writable.front();
5751
5752 while let Some(priority_key) = cursor.clone_pointer() {
5753 if let Some(stream) = self.streams.get(priority_key.id) {
5754 let cap = match stream.send.cap() {
5755 Ok(v) => v,
5756
5757 Err(_) =>
5760 return {
5761 self.streams.remove_writable(&priority_key);
5762
5763 Some(priority_key.id)
5764 },
5765 };
5766
5767 if cmp::min(self.tx_cap, cap) >= stream.send_lowat {
5768 self.streams.remove_writable(&priority_key);
5769 return Some(priority_key.id);
5770 }
5771 }
5772
5773 cursor.move_next();
5774 }
5775
5776 None
5777 }
5778
5779 #[inline]
5802 pub fn stream_writable(
5803 &mut self, stream_id: u64, len: usize,
5804 ) -> Result<bool> {
5805 if self.stream_capacity(stream_id)? >= len {
5806 return Ok(true);
5807 }
5808
5809 let stream = match self.streams.get_mut(stream_id) {
5810 Some(v) => v,
5811
5812 None => return Err(Error::InvalidStreamState(stream_id)),
5813 };
5814
5815 stream.send_lowat = cmp::max(1, len);
5816
5817 let is_writable = stream.is_writable();
5818
5819 let priority_key = Arc::clone(&stream.priority_key);
5820
5821 if self.max_tx_data - self.tx_data < len as u64 {
5822 self.blocked_limit = Some(self.max_tx_data);
5823 }
5824
5825 if stream.send.cap()? < len {
5826 let max_off = stream.send.max_off();
5827 if stream.send.blocked_at() != Some(max_off) {
5828 stream.send.update_blocked_at(Some(max_off));
5829 self.streams.insert_blocked(stream_id, max_off);
5830 }
5831 } else if is_writable {
5832 self.streams.insert_writable(&priority_key);
5839 }
5840
5841 Ok(false)
5842 }
5843
5844 #[inline]
5853 pub fn stream_finished(&self, stream_id: u64) -> bool {
5854 let stream = match self.streams.get(stream_id) {
5855 Some(v) => v,
5856
5857 None => return true,
5858 };
5859
5860 stream.recv.is_fin()
5861 }
5862
5863 #[inline]
5869 pub fn peer_streams_left_bidi(&self) -> u64 {
5870 self.streams.peer_streams_left_bidi()
5871 }
5872
5873 #[inline]
5879 pub fn peer_streams_left_uni(&self) -> u64 {
5880 self.streams.peer_streams_left_uni()
5881 }
5882
5883 #[inline]
5910 pub fn readable(&self) -> StreamIter {
5911 self.streams.readable()
5912 }
5913
5914 #[inline]
5953 pub fn writable(&self) -> StreamIter {
5954 if self.tx_cap == 0 {
5957 return StreamIter::default();
5958 }
5959
5960 self.streams.writable()
5961 }
5962
5963 pub fn max_send_udp_payload_size(&self) -> usize {
5977 let max_datagram_size = self
5978 .paths
5979 .get_active()
5980 .ok()
5981 .map(|p| p.recovery.max_datagram_size());
5982
5983 if let Some(max_datagram_size) = max_datagram_size {
5984 if self.is_established() {
5985 return cmp::min(16383, max_datagram_size);
5988 }
5989 }
5990
5991 MIN_CLIENT_INITIAL_LEN
5994 }
5995
5996 pub fn send_ack_eliciting(&mut self) -> Result<()> {
6008 if self.is_closed() || self.is_draining() {
6009 return Ok(());
6010 }
6011 self.paths.get_active_mut()?.needs_ack_eliciting = true;
6012 Ok(())
6013 }
6014
6015 pub fn send_ack_eliciting_on_path(
6023 &mut self, local: SocketAddr, peer: SocketAddr,
6024 ) -> Result<()> {
6025 if self.is_closed() || self.is_draining() {
6026 return Ok(());
6027 }
6028 let path_id = self
6029 .paths
6030 .path_id_from_addrs(&(local, peer))
6031 .ok_or(Error::InvalidState)?;
6032 self.paths.get_mut(path_id)?.needs_ack_eliciting = true;
6033 Ok(())
6034 }
6035
6036 #[inline]
6065 pub fn dgram_recv(&mut self, buf: &mut [u8]) -> Result<usize> {
6066 match self.dgram_recv_queue.pop() {
6067 Some(d) => {
6068 if d.len() > buf.len() {
6069 return Err(Error::BufferTooShort);
6070 }
6071
6072 buf[..d.len()].copy_from_slice(&d);
6073 Ok(d.len())
6074 },
6075
6076 None => Err(Error::Done),
6077 }
6078 }
6079
6080 #[inline]
6087 pub fn dgram_recv_vec(&mut self) -> Result<Vec<u8>> {
6088 match self.dgram_recv_queue.pop() {
6089 Some(d) => Ok(d),
6090
6091 None => Err(Error::Done),
6092 }
6093 }
6094
6095 #[inline]
6109 pub fn dgram_recv_peek(&self, buf: &mut [u8], len: usize) -> Result<usize> {
6110 self.dgram_recv_queue.peek_front_bytes(buf, len)
6111 }
6112
6113 #[inline]
6115 pub fn dgram_recv_front_len(&self) -> Option<usize> {
6116 self.dgram_recv_queue.peek_front_len()
6117 }
6118
6119 #[inline]
6121 pub fn dgram_recv_queue_len(&self) -> usize {
6122 self.dgram_recv_queue.len()
6123 }
6124
6125 #[inline]
6127 pub fn dgram_recv_queue_byte_size(&self) -> usize {
6128 self.dgram_recv_queue.byte_size()
6129 }
6130
6131 #[inline]
6133 pub fn dgram_send_queue_len(&self) -> usize {
6134 self.dgram_send_queue.len()
6135 }
6136
6137 #[inline]
6139 pub fn dgram_send_queue_byte_size(&self) -> usize {
6140 self.dgram_send_queue.byte_size()
6141 }
6142
6143 #[inline]
6145 pub fn is_dgram_send_queue_full(&self) -> bool {
6146 self.dgram_send_queue.is_full()
6147 }
6148
6149 #[inline]
6151 pub fn is_dgram_recv_queue_full(&self) -> bool {
6152 self.dgram_recv_queue.is_full()
6153 }
6154
6155 pub fn dgram_send(&mut self, buf: &[u8]) -> Result<()> {
6188 let max_payload_len = match self.dgram_max_writable_len() {
6189 Some(v) => v,
6190
6191 None => return Err(Error::InvalidState),
6192 };
6193
6194 if buf.len() > max_payload_len {
6195 return Err(Error::BufferTooShort);
6196 }
6197
6198 self.dgram_send_queue.push(buf.to_vec())?;
6199
6200 let active_path = self.paths.get_active_mut()?;
6201
6202 if self.dgram_send_queue.byte_size() >
6203 active_path.recovery.cwnd_available()
6204 {
6205 active_path.recovery.update_app_limited(false);
6206 }
6207
6208 Ok(())
6209 }
6210
6211 pub fn dgram_send_vec(&mut self, buf: Vec<u8>) -> Result<()> {
6218 let max_payload_len = match self.dgram_max_writable_len() {
6219 Some(v) => v,
6220
6221 None => return Err(Error::InvalidState),
6222 };
6223
6224 if buf.len() > max_payload_len {
6225 return Err(Error::BufferTooShort);
6226 }
6227
6228 self.dgram_send_queue.push(buf)?;
6229
6230 let active_path = self.paths.get_active_mut()?;
6231
6232 if self.dgram_send_queue.byte_size() >
6233 active_path.recovery.cwnd_available()
6234 {
6235 active_path.recovery.update_app_limited(false);
6236 }
6237
6238 Ok(())
6239 }
6240
6241 #[inline]
6258 pub fn dgram_purge_outgoing<FN: Fn(&[u8]) -> bool>(&mut self, f: FN) {
6259 self.dgram_send_queue.purge(f);
6260 }
6261
6262 #[inline]
6285 pub fn dgram_max_writable_len(&self) -> Option<usize> {
6286 match self.peer_transport_params.max_datagram_frame_size {
6287 None => None,
6288 Some(peer_frame_len) => {
6289 let dcid = self.destination_id();
6290 let mut max_len = self.max_send_udp_payload_size();
6292 max_len = max_len.saturating_sub(1 + dcid.len());
6295 max_len = max_len.saturating_sub(packet::MAX_PKT_NUM_LEN);
6297 max_len = max_len.saturating_sub(
6299 self.crypto_ctx[packet::Epoch::Application]
6300 .crypto_overhead()?,
6301 );
6302 max_len = cmp::min(peer_frame_len as usize, max_len);
6304 max_len.checked_sub(1 + frame::MAX_DGRAM_OVERHEAD)
6307 },
6308 }
6309 }
6310
6311 fn dgram_enabled(&self) -> bool {
6312 self.local_transport_params
6313 .max_datagram_frame_size
6314 .is_some()
6315 }
6316
6317 pub fn timeout_instant(&self) -> Option<time::Instant> {
6325 if self.is_closed() {
6326 return None;
6327 }
6328
6329 if self.is_draining() {
6330 self.draining_timer
6334 } else {
6335 let path_timer = self
6340 .paths
6341 .iter()
6342 .filter_map(|(_, p)| p.recovery.loss_detection_timer())
6343 .min();
6344
6345 let key_update_timer = self.crypto_ctx[packet::Epoch::Application]
6346 .key_update
6347 .as_ref()
6348 .map(|key_update| key_update.timer);
6349
6350 let timers = [self.idle_timer, path_timer, key_update_timer];
6351
6352 timers.iter().filter_map(|&x| x).min()
6353 }
6354 }
6355
6356 pub fn timeout(&self) -> Option<time::Duration> {
6363 self.timeout_instant().map(|timeout| {
6364 let now = time::Instant::now();
6365
6366 if timeout <= now {
6367 time::Duration::ZERO
6368 } else {
6369 timeout.duration_since(now)
6370 }
6371 })
6372 }
6373
6374 pub fn on_timeout(&mut self) {
6378 let now = time::Instant::now();
6379
6380 if let Some(draining_timer) = self.draining_timer {
6381 if draining_timer <= now {
6382 trace!("{} draining timeout expired", self.trace_id);
6383
6384 self.mark_closed();
6385 }
6386
6387 return;
6391 }
6392
6393 if let Some(timer) = self.idle_timer {
6394 if timer <= now {
6395 trace!("{} idle timeout expired", self.trace_id);
6396
6397 self.mark_closed();
6398 self.timed_out = true;
6399 return;
6400 }
6401 }
6402
6403 if let Some(timer) = self.crypto_ctx[packet::Epoch::Application]
6404 .key_update
6405 .as_ref()
6406 .map(|key_update| key_update.timer)
6407 {
6408 if timer <= now {
6409 let _ = self.crypto_ctx[packet::Epoch::Application]
6411 .key_update
6412 .take();
6413 }
6414 }
6415
6416 let handshake_status = self.handshake_status();
6417
6418 for (_, p) in self.paths.iter_mut() {
6419 if let Some(timer) = p.recovery.loss_detection_timer() {
6420 if timer <= now {
6421 trace!("{} loss detection timeout expired", self.trace_id);
6422
6423 let OnLossDetectionTimeoutOutcome {
6424 lost_packets,
6425 lost_bytes,
6426 } = p.on_loss_detection_timeout(
6427 handshake_status,
6428 now,
6429 self.is_server,
6430 &self.trace_id,
6431 );
6432
6433 self.lost_count += lost_packets;
6434 self.lost_bytes += lost_bytes as u64;
6435
6436 qlog_with_type!(QLOG_METRICS, self.qlog, q, {
6437 if let Some(ev_data) = p.recovery.maybe_qlog() {
6438 q.add_event_data_with_instant(ev_data, now).ok();
6439 }
6440 });
6441 }
6442 }
6443 }
6444
6445 self.paths.notify_failed_validations();
6447
6448 if self.paths.get_active_path_id().is_err() {
6450 match self.paths.find_candidate_path() {
6451 Some(pid) => {
6452 if self.set_active_path(pid, now).is_err() {
6453 self.mark_closed();
6455 }
6456 },
6457
6458 None => {
6460 self.mark_closed();
6461 },
6462 }
6463 }
6464 }
6465
6466 pub fn probe_path(
6497 &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
6498 ) -> Result<u64> {
6499 let pid = match self.paths.path_id_from_addrs(&(local_addr, peer_addr)) {
6501 Some(pid) => pid,
6502 None => self.create_path_on_client(local_addr, peer_addr)?,
6503 };
6504
6505 let path = self.paths.get_mut(pid)?;
6506 path.request_validation();
6507
6508 path.active_dcid_seq.ok_or(Error::InvalidState)
6509 }
6510
6511 pub fn migrate_source(&mut self, local_addr: SocketAddr) -> Result<u64> {
6520 let peer_addr = self.paths.get_active()?.peer_addr();
6521 self.migrate(local_addr, peer_addr)
6522 }
6523
6524 pub fn migrate(
6539 &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
6540 ) -> Result<u64> {
6541 if self.is_server {
6542 return Err(Error::InvalidState);
6543 }
6544
6545 let (pid, dcid_seq) = if let Some(pid) =
6547 self.paths.path_id_from_addrs(&(local_addr, peer_addr))
6548 {
6549 let path = self.paths.get_mut(pid)?;
6550
6551 if path.active() {
6553 return path.active_dcid_seq.ok_or(Error::OutOfIdentifiers);
6554 }
6555
6556 if !self.ids.zero_length_scid() &&
6560 path.active_scid_seq.is_none() &&
6561 self.ids.available_scids() == 0
6562 {
6563 return Err(Error::OutOfIdentifiers);
6564 }
6565
6566 let dcid_seq = if let Some(dcid_seq) = path.active_dcid_seq {
6568 dcid_seq
6569 } else {
6570 let dcid_seq = self
6571 .ids
6572 .lowest_available_dcid_seq()
6573 .ok_or(Error::OutOfIdentifiers)?;
6574
6575 self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
6576 path.active_dcid_seq = Some(dcid_seq);
6577
6578 dcid_seq
6579 };
6580
6581 (pid, dcid_seq)
6582 } else {
6583 let pid = self.create_path_on_client(local_addr, peer_addr)?;
6584
6585 let dcid_seq = self
6586 .paths
6587 .get(pid)?
6588 .active_dcid_seq
6589 .ok_or(Error::InvalidState)?;
6590
6591 (pid, dcid_seq)
6592 };
6593
6594 self.set_active_path(pid, time::Instant::now())?;
6596
6597 Ok(dcid_seq)
6598 }
6599
6600 pub fn new_scid(
6633 &mut self, scid: &ConnectionId, reset_token: u128, retire_if_needed: bool,
6634 ) -> Result<u64> {
6635 self.ids.new_scid(
6636 scid.to_vec().into(),
6637 Some(reset_token),
6638 true,
6639 None,
6640 retire_if_needed,
6641 )
6642 }
6643
6644 pub fn active_scids(&self) -> usize {
6647 self.ids.active_source_cids()
6648 }
6649
6650 #[inline]
6662 pub fn scids_left(&self) -> usize {
6663 let max_active_source_cids = cmp::min(
6664 self.peer_transport_params.active_conn_id_limit,
6665 self.local_transport_params.active_conn_id_limit,
6666 ) as usize;
6667
6668 max_active_source_cids - self.active_scids()
6669 }
6670
6671 pub fn retire_dcid(&mut self, dcid_seq: u64) -> Result<()> {
6691 if self.ids.zero_length_dcid() {
6692 return Err(Error::InvalidState);
6693 }
6694
6695 let active_path_dcid_seq = self
6696 .paths
6697 .get_active()?
6698 .active_dcid_seq
6699 .ok_or(Error::InvalidState)?;
6700
6701 let active_path_id = self.paths.get_active_path_id()?;
6702
6703 if active_path_dcid_seq == dcid_seq &&
6704 self.ids.lowest_available_dcid_seq().is_none() &&
6705 !self
6706 .paths
6707 .iter()
6708 .any(|(pid, p)| pid != active_path_id && p.usable())
6709 {
6710 return Err(Error::OutOfIdentifiers);
6711 }
6712
6713 if let Some(pid) = self.ids.retire_dcid(dcid_seq)? {
6714 let path = self.paths.get_mut(pid)?;
6717 let dcid_seq = self.ids.lowest_available_dcid_seq();
6718
6719 if let Some(dcid_seq) = dcid_seq {
6720 self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
6721 }
6722
6723 path.active_dcid_seq = dcid_seq;
6724 }
6725
6726 Ok(())
6727 }
6728
6729 pub fn path_event_next(&mut self) -> Option<PathEvent> {
6741 self.paths.pop_event()
6742 }
6743
6744 pub fn retired_scids(&self) -> usize {
6746 self.ids.retired_source_cids()
6747 }
6748
6749 pub fn retired_scid_next(&mut self) -> Option<ConnectionId<'static>> {
6756 self.ids.pop_retired_scid()
6757 }
6758
6759 pub fn available_dcids(&self) -> usize {
6765 self.ids.available_dcids()
6766 }
6767
6768 #[inline]
6815 pub fn paths_iter(&self, from: SocketAddr) -> SocketAddrIter {
6816 SocketAddrIter {
6819 sockaddrs: self
6820 .paths
6821 .iter()
6822 .filter(|(_, p)| p.active_dcid_seq.is_some())
6823 .filter(|(_, p)| p.usable() || p.probing_required())
6824 .filter(|(_, p)| p.local_addr() == from)
6825 .map(|(_, p)| p.peer_addr())
6826 .collect(),
6827
6828 index: 0,
6829 }
6830 }
6831
6832 pub fn close(&mut self, app: bool, err: u64, reason: &[u8]) -> Result<()> {
6858 if self.is_closed() || self.is_draining() {
6859 return Err(Error::Done);
6860 }
6861
6862 if self.local_error.is_some() {
6863 return Err(Error::Done);
6864 }
6865
6866 let is_safe_to_send_app_data =
6867 self.is_established() || self.is_in_early_data();
6868
6869 if app && !is_safe_to_send_app_data {
6870 self.local_error = Some(ConnectionError {
6872 is_app: false,
6873 error_code: 0x0c,
6874 reason: vec![],
6875 });
6876 } else {
6877 self.local_error = Some(ConnectionError {
6878 is_app: app,
6879 error_code: err,
6880 reason: reason.to_vec(),
6881 });
6882 }
6883
6884 if self.recv_count == 0 {
6886 self.mark_closed();
6887 }
6888
6889 Ok(())
6890 }
6891
6892 #[inline]
6897 pub fn trace_id(&self) -> &str {
6898 &self.trace_id
6899 }
6900
6901 #[inline]
6905 pub fn application_proto(&self) -> &[u8] {
6906 self.alpn.as_ref()
6907 }
6908
6909 #[inline]
6911 pub fn server_name(&self) -> Option<&str> {
6912 self.handshake.server_name()
6913 }
6914
6915 #[inline]
6917 pub fn peer_cert(&self) -> Option<&[u8]> {
6918 self.handshake.peer_cert()
6919 }
6920
6921 #[inline]
6928 pub fn peer_cert_chain(&self) -> Option<Vec<&[u8]>> {
6929 self.handshake.peer_cert_chain()
6930 }
6931
6932 #[inline]
6939 pub fn session(&self) -> Option<&[u8]> {
6940 self.session.as_deref()
6941 }
6942
6943 #[inline]
6951 pub fn source_id(&self) -> ConnectionId {
6952 if let Ok(path) = self.paths.get_active() {
6953 if let Some(active_scid_seq) = path.active_scid_seq {
6954 if let Ok(e) = self.ids.get_scid(active_scid_seq) {
6955 return ConnectionId::from_ref(e.cid.as_ref());
6956 }
6957 }
6958 }
6959
6960 let e = self.ids.oldest_scid();
6961 ConnectionId::from_ref(e.cid.as_ref())
6962 }
6963
6964 #[inline]
6969 pub fn source_ids(&self) -> impl Iterator<Item = &ConnectionId> {
6970 self.ids.scids_iter()
6971 }
6972
6973 #[inline]
6978 pub fn destination_id(&self) -> ConnectionId {
6979 if let Ok(path) = self.paths.get_active() {
6980 if let Some(active_dcid_seq) = path.active_dcid_seq {
6981 if let Ok(e) = self.ids.get_dcid(active_dcid_seq) {
6982 return ConnectionId::from_ref(e.cid.as_ref());
6983 }
6984 }
6985 }
6986
6987 let e = self.ids.oldest_dcid();
6988 ConnectionId::from_ref(e.cid.as_ref())
6989 }
6990
6991 #[inline]
6993 pub fn is_established(&self) -> bool {
6994 self.handshake_completed
6995 }
6996
6997 #[inline]
6999 pub fn is_resumed(&self) -> bool {
7000 self.handshake.is_resumed()
7001 }
7002
7003 #[inline]
7006 pub fn is_in_early_data(&self) -> bool {
7007 self.handshake.is_in_early_data()
7008 }
7009
7010 #[inline]
7012 pub fn is_readable(&self) -> bool {
7013 self.streams.has_readable() || self.dgram_recv_front_len().is_some()
7014 }
7015
7016 pub fn is_path_validated(
7024 &self, from: SocketAddr, to: SocketAddr,
7025 ) -> Result<bool> {
7026 let pid = self
7027 .paths
7028 .path_id_from_addrs(&(from, to))
7029 .ok_or(Error::InvalidState)?;
7030
7031 Ok(self.paths.get(pid)?.validated())
7032 }
7033
7034 #[inline]
7050 pub fn is_draining(&self) -> bool {
7051 self.draining_timer.is_some()
7052 }
7053
7054 #[inline]
7058 pub fn is_closed(&self) -> bool {
7059 self.closed
7060 }
7061
7062 #[inline]
7064 pub fn is_timed_out(&self) -> bool {
7065 self.timed_out
7066 }
7067
7068 #[inline]
7075 pub fn peer_error(&self) -> Option<&ConnectionError> {
7076 self.peer_error.as_ref()
7077 }
7078
7079 #[inline]
7090 pub fn local_error(&self) -> Option<&ConnectionError> {
7091 self.local_error.as_ref()
7092 }
7093
7094 #[inline]
7096 pub fn stats(&self) -> Stats {
7097 Stats {
7098 recv: self.recv_count,
7099 sent: self.sent_count,
7100 lost: self.lost_count,
7101 spurious_lost: self.spurious_lost_count,
7102 retrans: self.retrans_count,
7103 sent_bytes: self.sent_bytes,
7104 recv_bytes: self.recv_bytes,
7105 acked_bytes: self.acked_bytes,
7106 lost_bytes: self.lost_bytes,
7107 stream_retrans_bytes: self.stream_retrans_bytes,
7108 dgram_recv: self.dgram_recv_count,
7109 dgram_sent: self.dgram_sent_count,
7110 paths_count: self.paths.len(),
7111 reset_stream_count_local: self.reset_stream_local_count,
7112 stopped_stream_count_local: self.stopped_stream_local_count,
7113 reset_stream_count_remote: self.reset_stream_remote_count,
7114 stopped_stream_count_remote: self.stopped_stream_remote_count,
7115 path_challenge_rx_count: self.path_challenge_rx_count,
7116 bytes_in_flight_duration: self.bytes_in_flight_duration(),
7117 }
7118 }
7119
7120 fn bytes_in_flight_duration(&self) -> Duration {
7129 self.paths.iter().fold(Duration::ZERO, |acc, (_, path)| {
7130 acc + path.bytes_in_flight_duration()
7131 })
7132 }
7133
7134 pub fn peer_transport_params(&self) -> Option<&TransportParams> {
7137 if !self.parsed_peer_transport_params {
7138 return None;
7139 }
7140
7141 Some(&self.peer_transport_params)
7142 }
7143
7144 pub fn path_stats(&self) -> impl Iterator<Item = PathStats> + '_ {
7147 self.paths.iter().map(|(_, p)| p.stats())
7148 }
7149
7150 pub fn is_server(&self) -> bool {
7152 self.is_server
7153 }
7154
7155 fn encode_transport_params(&mut self) -> Result<()> {
7156 self.handshake.set_quic_transport_params(
7157 &self.local_transport_params,
7158 self.is_server,
7159 )
7160 }
7161
7162 fn parse_peer_transport_params(
7163 &mut self, peer_params: TransportParams,
7164 ) -> Result<()> {
7165 match &peer_params.initial_source_connection_id {
7167 Some(v) if v != &self.destination_id() =>
7168 return Err(Error::InvalidTransportParam),
7169
7170 Some(_) => (),
7171
7172 None => return Err(Error::InvalidTransportParam),
7175 }
7176
7177 if let Some(odcid) = &self.odcid {
7179 match &peer_params.original_destination_connection_id {
7180 Some(v) if v != odcid =>
7181 return Err(Error::InvalidTransportParam),
7182
7183 Some(_) => (),
7184
7185 None if !self.is_server =>
7188 return Err(Error::InvalidTransportParam),
7189
7190 None => (),
7191 }
7192 }
7193
7194 if let Some(rscid) = &self.rscid {
7196 match &peer_params.retry_source_connection_id {
7197 Some(v) if v != rscid =>
7198 return Err(Error::InvalidTransportParam),
7199
7200 Some(_) => (),
7201
7202 None => return Err(Error::InvalidTransportParam),
7205 }
7206 }
7207
7208 self.process_peer_transport_params(peer_params)?;
7209
7210 self.parsed_peer_transport_params = true;
7211
7212 Ok(())
7213 }
7214
7215 fn process_peer_transport_params(
7216 &mut self, peer_params: TransportParams,
7217 ) -> Result<()> {
7218 self.max_tx_data = peer_params.initial_max_data;
7219
7220 self.update_tx_cap();
7222
7223 self.streams
7224 .update_peer_max_streams_bidi(peer_params.initial_max_streams_bidi);
7225 self.streams
7226 .update_peer_max_streams_uni(peer_params.initial_max_streams_uni);
7227
7228 let max_ack_delay =
7229 time::Duration::from_millis(peer_params.max_ack_delay);
7230
7231 self.recovery_config.max_ack_delay = max_ack_delay;
7232
7233 let active_path = self.paths.get_active_mut()?;
7234
7235 active_path.recovery.update_max_ack_delay(max_ack_delay);
7236
7237 if active_path.pmtud.get_probe_status() {
7238 active_path.recovery.pmtud_update_max_datagram_size(
7239 active_path
7240 .pmtud
7241 .get_probe_size()
7242 .min(peer_params.max_udp_payload_size as usize),
7243 );
7244 } else {
7245 active_path.recovery.update_max_datagram_size(
7246 peer_params.max_udp_payload_size as usize,
7247 );
7248 }
7249
7250 self.ids
7252 .set_source_conn_id_limit(peer_params.active_conn_id_limit);
7253
7254 self.peer_transport_params = peer_params;
7255
7256 Ok(())
7257 }
7258
7259 fn do_handshake(&mut self, now: time::Instant) -> Result<()> {
7263 let mut ex_data = tls::ExData {
7264 application_protos: &self.application_protos,
7265
7266 crypto_ctx: &mut self.crypto_ctx,
7267
7268 session: &mut self.session,
7269
7270 local_error: &mut self.local_error,
7271
7272 keylog: self.keylog.as_mut(),
7273
7274 trace_id: &self.trace_id,
7275
7276 local_transport_params: self.local_transport_params.clone(),
7277
7278 recovery_config: self.recovery_config,
7279
7280 tx_cap_factor: self.tx_cap_factor,
7281
7282 pmtud: None,
7283
7284 is_server: self.is_server,
7285 };
7286
7287 if self.handshake_completed {
7288 return self.handshake.process_post_handshake(&mut ex_data);
7289 }
7290
7291 match self.handshake.do_handshake(&mut ex_data) {
7292 Ok(_) => (),
7293
7294 Err(Error::Done) => {
7295 if self.sent_count == 0 {
7298 if ex_data.recovery_config != self.recovery_config {
7299 if let Ok(path) = self.paths.get_active_mut() {
7300 self.recovery_config = ex_data.recovery_config;
7301 path.reinit_recovery(&self.recovery_config);
7302 }
7303 }
7304
7305 if ex_data.tx_cap_factor != self.tx_cap_factor {
7306 self.tx_cap_factor = ex_data.tx_cap_factor;
7307 }
7308
7309 if let Some(discover) = ex_data.pmtud {
7310 self.paths.set_discover_pmtu_on_existing_paths(
7311 discover,
7312 self.recovery_config.max_send_udp_payload_size,
7313 );
7314 }
7315
7316 if ex_data.local_transport_params !=
7317 self.local_transport_params
7318 {
7319 self.streams.set_max_streams_bidi(
7320 ex_data
7321 .local_transport_params
7322 .initial_max_streams_bidi,
7323 );
7324
7325 self.local_transport_params =
7326 ex_data.local_transport_params;
7327 }
7328 }
7329
7330 let raw_params = self.handshake.quic_transport_params();
7337
7338 if !self.parsed_peer_transport_params && !raw_params.is_empty() {
7339 let peer_params = TransportParams::decode(
7340 raw_params,
7341 self.is_server,
7342 self.peer_transport_params_track_unknown,
7343 )?;
7344
7345 self.parse_peer_transport_params(peer_params)?;
7346 }
7347
7348 return Ok(());
7349 },
7350
7351 Err(e) => return Err(e),
7352 };
7353
7354 self.handshake_completed = self.handshake.is_completed();
7355
7356 self.alpn = self.handshake.alpn_protocol().to_vec();
7357
7358 let raw_params = self.handshake.quic_transport_params();
7359
7360 if !self.parsed_peer_transport_params && !raw_params.is_empty() {
7361 let peer_params = TransportParams::decode(
7362 raw_params,
7363 self.is_server,
7364 self.peer_transport_params_track_unknown,
7365 )?;
7366
7367 self.parse_peer_transport_params(peer_params)?;
7368 }
7369
7370 if self.handshake_completed {
7371 if self.is_server {
7375 self.handshake_confirmed = true;
7376
7377 self.drop_epoch_state(packet::Epoch::Handshake, now);
7378 }
7379
7380 self.undecryptable_pkts.clear();
7383
7384 trace!("{} connection established: proto={:?} cipher={:?} curve={:?} sigalg={:?} resumed={} {:?}",
7385 &self.trace_id,
7386 std::str::from_utf8(self.application_proto()),
7387 self.handshake.cipher(),
7388 self.handshake.curve(),
7389 self.handshake.sigalg(),
7390 self.handshake.is_resumed(),
7391 self.peer_transport_params);
7392 }
7393
7394 Ok(())
7395 }
7396
7397 fn write_pkt_type(&self, send_pid: usize) -> Result<packet::Type> {
7399 if self
7402 .local_error
7403 .as_ref()
7404 .is_some_and(|conn_err| !conn_err.is_app)
7405 {
7406 let epoch = match self.handshake.write_level() {
7407 crypto::Level::Initial => packet::Epoch::Initial,
7408 crypto::Level::ZeroRTT => unreachable!(),
7409 crypto::Level::Handshake => packet::Epoch::Handshake,
7410 crypto::Level::OneRTT => packet::Epoch::Application,
7411 };
7412
7413 if !self.handshake_confirmed {
7414 match epoch {
7415 packet::Epoch::Application =>
7418 return Ok(packet::Type::Handshake),
7419
7420 packet::Epoch::Handshake
7423 if self.crypto_ctx[packet::Epoch::Initial].has_keys() =>
7424 return Ok(packet::Type::Initial),
7425
7426 _ => (),
7427 };
7428 }
7429
7430 return Ok(packet::Type::from_epoch(epoch));
7431 }
7432
7433 for &epoch in packet::Epoch::epochs(
7434 packet::Epoch::Initial..=packet::Epoch::Application,
7435 ) {
7436 let crypto_ctx = &self.crypto_ctx[epoch];
7437 let pkt_space = &self.pkt_num_spaces[epoch];
7438
7439 if crypto_ctx.crypto_seal.is_none() {
7441 continue;
7442 }
7443
7444 if crypto_ctx.data_available() || pkt_space.ready() {
7446 return Ok(packet::Type::from_epoch(epoch));
7447 }
7448
7449 for (_, p) in self.paths.iter() {
7451 if p.recovery.has_lost_frames(epoch) {
7452 return Ok(packet::Type::from_epoch(epoch));
7453 }
7454
7455 if p.recovery.loss_probes(epoch) > 0 {
7457 return Ok(packet::Type::from_epoch(epoch));
7458 }
7459 }
7460 }
7461
7462 let send_path = self.paths.get(send_pid)?;
7465 if (self.is_established() || self.is_in_early_data()) &&
7466 (self.should_send_handshake_done() ||
7467 self.almost_full ||
7468 self.blocked_limit.is_some() ||
7469 self.dgram_send_queue.has_pending() ||
7470 self.local_error
7471 .as_ref()
7472 .is_some_and(|conn_err| conn_err.is_app) ||
7473 self.streams.should_update_max_streams_bidi() ||
7474 self.streams.should_update_max_streams_uni() ||
7475 self.streams.has_flushable() ||
7476 self.streams.has_almost_full() ||
7477 self.streams.has_blocked() ||
7478 self.streams.has_reset() ||
7479 self.streams.has_stopped() ||
7480 self.ids.has_new_scids() ||
7481 self.ids.has_retire_dcids() ||
7482 send_path.pmtud.get_probe_status() ||
7483 send_path.needs_ack_eliciting ||
7484 send_path.probing_required())
7485 {
7486 if !self.is_server && self.is_in_early_data() {
7488 return Ok(packet::Type::ZeroRTT);
7489 }
7490
7491 return Ok(packet::Type::Short);
7492 }
7493
7494 Err(Error::Done)
7495 }
7496
7497 fn get_or_create_stream(
7500 &mut self, id: u64, local: bool,
7501 ) -> Result<&mut stream::Stream<F>> {
7502 self.streams.get_or_create(
7503 id,
7504 &self.local_transport_params,
7505 &self.peer_transport_params,
7506 local,
7507 self.is_server,
7508 )
7509 }
7510
7511 fn process_frame(
7513 &mut self, frame: frame::Frame, hdr: &packet::Header,
7514 recv_path_id: usize, epoch: packet::Epoch, now: time::Instant,
7515 ) -> Result<()> {
7516 trace!("{} rx frm {:?}", self.trace_id, frame);
7517
7518 match frame {
7519 frame::Frame::Padding { .. } => (),
7520
7521 frame::Frame::Ping { .. } => (),
7522
7523 frame::Frame::ACK {
7524 ranges, ack_delay, ..
7525 } => {
7526 let ack_delay = ack_delay
7527 .checked_mul(2_u64.pow(
7528 self.peer_transport_params.ack_delay_exponent as u32,
7529 ))
7530 .ok_or(Error::InvalidFrame)?;
7531
7532 if epoch == packet::Epoch::Handshake ||
7533 (epoch == packet::Epoch::Application &&
7534 self.is_established())
7535 {
7536 self.peer_verified_initial_address = true;
7537 }
7538
7539 let handshake_status = self.handshake_status();
7540
7541 let is_app_limited = self.delivery_rate_check_if_app_limited();
7542
7543 for (_, p) in self.paths.iter_mut() {
7544 if is_app_limited {
7545 p.recovery.delivery_rate_update_app_limited(true);
7546 }
7547
7548 let OnAckReceivedOutcome {
7549 lost_packets,
7550 lost_bytes,
7551 acked_bytes,
7552 spurious_losses,
7553 } = p.recovery.on_ack_received(
7554 &ranges,
7555 ack_delay,
7556 epoch,
7557 handshake_status,
7558 now,
7559 &self.trace_id,
7560 );
7561
7562 self.lost_count += lost_packets;
7563 self.lost_bytes += lost_bytes as u64;
7564 self.acked_bytes += acked_bytes as u64;
7565 self.spurious_lost_count += spurious_losses;
7566 }
7567 },
7568
7569 frame::Frame::ResetStream {
7570 stream_id,
7571 error_code,
7572 final_size,
7573 } => {
7574 if !stream::is_bidi(stream_id) &&
7576 stream::is_local(stream_id, self.is_server)
7577 {
7578 return Err(Error::InvalidStreamState(stream_id));
7579 }
7580
7581 let max_rx_data_left = self.max_rx_data() - self.rx_data;
7582
7583 let stream = match self.get_or_create_stream(stream_id, false) {
7594 Ok(v) => v,
7595
7596 Err(Error::Done) => return Ok(()),
7597
7598 Err(e) => return Err(e),
7599 };
7600
7601 let was_readable = stream.is_readable();
7602 let priority_key = Arc::clone(&stream.priority_key);
7603
7604 let max_off_delta =
7605 stream.recv.reset(error_code, final_size)? as u64;
7606
7607 if max_off_delta > max_rx_data_left {
7608 return Err(Error::FlowControl);
7609 }
7610
7611 if !was_readable && stream.is_readable() {
7612 self.streams.insert_readable(&priority_key);
7613 }
7614
7615 self.rx_data += max_off_delta;
7616
7617 self.reset_stream_remote_count =
7618 self.reset_stream_remote_count.saturating_add(1);
7619 },
7620
7621 frame::Frame::StopSending {
7622 stream_id,
7623 error_code,
7624 } => {
7625 if !stream::is_local(stream_id, self.is_server) &&
7627 !stream::is_bidi(stream_id)
7628 {
7629 return Err(Error::InvalidStreamState(stream_id));
7630 }
7631
7632 let stream = match self.get_or_create_stream(stream_id, false) {
7643 Ok(v) => v,
7644
7645 Err(Error::Done) => return Ok(()),
7646
7647 Err(e) => return Err(e),
7648 };
7649
7650 let was_writable = stream.is_writable();
7651
7652 let priority_key = Arc::clone(&stream.priority_key);
7653
7654 if let Ok((final_size, unsent)) = stream.send.stop(error_code) {
7656 self.tx_data = self.tx_data.saturating_sub(unsent);
7663
7664 self.tx_buffered =
7665 self.tx_buffered.saturating_sub(unsent as usize);
7666
7667 self.streams.insert_reset(stream_id, error_code, final_size);
7668
7669 if !was_writable {
7670 self.streams.insert_writable(&priority_key);
7671 }
7672
7673 self.stopped_stream_remote_count =
7674 self.stopped_stream_remote_count.saturating_add(1);
7675 self.reset_stream_local_count =
7676 self.reset_stream_local_count.saturating_add(1);
7677 }
7678 },
7679
7680 frame::Frame::Crypto { data } => {
7681 if data.max_off() >= MAX_CRYPTO_STREAM_OFFSET {
7682 return Err(Error::CryptoBufferExceeded);
7683 }
7684
7685 self.crypto_ctx[epoch].crypto_stream.recv.write(data)?;
7687
7688 let mut crypto_buf = [0; 512];
7691
7692 let level = crypto::Level::from_epoch(epoch);
7693
7694 let stream = &mut self.crypto_ctx[epoch].crypto_stream;
7695
7696 while let Ok((read, _)) = stream.recv.emit(&mut crypto_buf) {
7697 let recv_buf = &crypto_buf[..read];
7698 self.handshake.provide_data(level, recv_buf)?;
7699 }
7700
7701 self.do_handshake(now)?;
7702 },
7703
7704 frame::Frame::CryptoHeader { .. } => unreachable!(),
7705
7706 frame::Frame::NewToken { .. } =>
7708 if self.is_server {
7709 return Err(Error::InvalidPacket);
7710 },
7711
7712 frame::Frame::Stream { stream_id, data } => {
7713 if !stream::is_bidi(stream_id) &&
7715 stream::is_local(stream_id, self.is_server)
7716 {
7717 return Err(Error::InvalidStreamState(stream_id));
7718 }
7719
7720 let max_rx_data_left = self.max_rx_data() - self.rx_data;
7721
7722 let stream = match self.get_or_create_stream(stream_id, false) {
7733 Ok(v) => v,
7734
7735 Err(Error::Done) => return Ok(()),
7736
7737 Err(e) => return Err(e),
7738 };
7739
7740 let max_off_delta =
7742 data.max_off().saturating_sub(stream.recv.max_off());
7743
7744 if max_off_delta > max_rx_data_left {
7745 return Err(Error::FlowControl);
7746 }
7747
7748 let was_readable = stream.is_readable();
7749 let priority_key = Arc::clone(&stream.priority_key);
7750
7751 let was_draining = stream.recv.is_draining();
7752
7753 stream.recv.write(data)?;
7754
7755 if !was_readable && stream.is_readable() {
7756 self.streams.insert_readable(&priority_key);
7757 }
7758
7759 self.rx_data += max_off_delta;
7760
7761 if was_draining {
7762 self.flow_control.add_consumed(max_off_delta);
7767
7768 if self.should_update_max_data() {
7769 self.almost_full = true;
7770 }
7771 }
7772 },
7773
7774 frame::Frame::StreamHeader { .. } => unreachable!(),
7775
7776 frame::Frame::MaxData { max } => {
7777 self.max_tx_data = cmp::max(self.max_tx_data, max);
7778 },
7779
7780 frame::Frame::MaxStreamData { stream_id, max } => {
7781 if !stream::is_bidi(stream_id) &&
7783 !stream::is_local(stream_id, self.is_server)
7784 {
7785 return Err(Error::InvalidStreamState(stream_id));
7786 }
7787
7788 let stream = match self.get_or_create_stream(stream_id, false) {
7799 Ok(v) => v,
7800
7801 Err(Error::Done) => return Ok(()),
7802
7803 Err(e) => return Err(e),
7804 };
7805
7806 let was_flushable = stream.is_flushable();
7807
7808 stream.send.update_max_data(max);
7809
7810 let writable = stream.is_writable();
7811
7812 let priority_key = Arc::clone(&stream.priority_key);
7813
7814 if stream.is_flushable() && !was_flushable {
7817 let priority_key = Arc::clone(&stream.priority_key);
7818 self.streams.insert_flushable(&priority_key);
7819 }
7820
7821 if writable {
7822 self.streams.insert_writable(&priority_key);
7823 }
7824 },
7825
7826 frame::Frame::MaxStreamsBidi { max } => {
7827 if max > MAX_STREAM_ID {
7828 return Err(Error::InvalidFrame);
7829 }
7830
7831 self.streams.update_peer_max_streams_bidi(max);
7832 },
7833
7834 frame::Frame::MaxStreamsUni { max } => {
7835 if max > MAX_STREAM_ID {
7836 return Err(Error::InvalidFrame);
7837 }
7838
7839 self.streams.update_peer_max_streams_uni(max);
7840 },
7841
7842 frame::Frame::DataBlocked { .. } => (),
7843
7844 frame::Frame::StreamDataBlocked { .. } => (),
7845
7846 frame::Frame::StreamsBlockedBidi { limit } => {
7847 if limit > MAX_STREAM_ID {
7848 return Err(Error::InvalidFrame);
7849 }
7850 },
7851
7852 frame::Frame::StreamsBlockedUni { limit } => {
7853 if limit > MAX_STREAM_ID {
7854 return Err(Error::InvalidFrame);
7855 }
7856 },
7857
7858 frame::Frame::NewConnectionId {
7859 seq_num,
7860 retire_prior_to,
7861 conn_id,
7862 reset_token,
7863 } => {
7864 if self.ids.zero_length_dcid() {
7865 return Err(Error::InvalidState);
7866 }
7867
7868 let mut retired_path_ids = SmallVec::new();
7869
7870 let new_dcid_res = self.ids.new_dcid(
7873 conn_id.into(),
7874 seq_num,
7875 u128::from_be_bytes(reset_token),
7876 retire_prior_to,
7877 &mut retired_path_ids,
7878 );
7879
7880 for (dcid_seq, pid) in retired_path_ids {
7881 let path = self.paths.get_mut(pid)?;
7882
7883 if path.active_dcid_seq != Some(dcid_seq) {
7885 continue;
7886 }
7887
7888 if let Some(new_dcid_seq) =
7889 self.ids.lowest_available_dcid_seq()
7890 {
7891 path.active_dcid_seq = Some(new_dcid_seq);
7892
7893 self.ids.link_dcid_to_path_id(new_dcid_seq, pid)?;
7894
7895 trace!(
7896 "{} path ID {} changed DCID: old seq num {} new seq num {}",
7897 self.trace_id, pid, dcid_seq, new_dcid_seq,
7898 );
7899 } else {
7900 path.active_dcid_seq = None;
7902
7903 trace!(
7904 "{} path ID {} cannot be used; DCID seq num {} has been retired",
7905 self.trace_id, pid, dcid_seq,
7906 );
7907 }
7908 }
7909
7910 new_dcid_res?;
7912 },
7913
7914 frame::Frame::RetireConnectionId { seq_num } => {
7915 if self.ids.zero_length_scid() {
7916 return Err(Error::InvalidState);
7917 }
7918
7919 if let Some(pid) = self.ids.retire_scid(seq_num, &hdr.dcid)? {
7920 let path = self.paths.get_mut(pid)?;
7921
7922 if path.active_scid_seq == Some(seq_num) {
7924 path.active_scid_seq = None;
7928 }
7929 }
7930 },
7931
7932 frame::Frame::PathChallenge { data } => {
7933 self.path_challenge_rx_count += 1;
7934
7935 self.paths
7936 .get_mut(recv_path_id)?
7937 .on_challenge_received(data);
7938 },
7939
7940 frame::Frame::PathResponse { data } => {
7941 self.paths.on_response_received(data)?;
7942 },
7943
7944 frame::Frame::ConnectionClose {
7945 error_code, reason, ..
7946 } => {
7947 self.peer_error = Some(ConnectionError {
7948 is_app: false,
7949 error_code,
7950 reason,
7951 });
7952
7953 let path = self.paths.get_active()?;
7954 self.draining_timer = Some(now + (path.recovery.pto() * 3));
7955 },
7956
7957 frame::Frame::ApplicationClose { error_code, reason } => {
7958 self.peer_error = Some(ConnectionError {
7959 is_app: true,
7960 error_code,
7961 reason,
7962 });
7963
7964 let path = self.paths.get_active()?;
7965 self.draining_timer = Some(now + (path.recovery.pto() * 3));
7966 },
7967
7968 frame::Frame::HandshakeDone => {
7969 if self.is_server {
7970 return Err(Error::InvalidPacket);
7971 }
7972
7973 self.peer_verified_initial_address = true;
7974
7975 self.handshake_confirmed = true;
7976
7977 self.drop_epoch_state(packet::Epoch::Handshake, now);
7979 },
7980
7981 frame::Frame::Datagram { data } => {
7982 if !self.dgram_enabled() {
7987 return Err(Error::InvalidState);
7988 }
7989
7990 if self.dgram_recv_queue.is_full() {
7992 self.dgram_recv_queue.pop();
7993 }
7994
7995 self.dgram_recv_queue.push(data)?;
7996
7997 let _ = self.dgram_recv_count.saturating_add(1);
7998 let _ = self
7999 .paths
8000 .get_mut(recv_path_id)?
8001 .dgram_recv_count
8002 .saturating_add(1);
8003 },
8004
8005 frame::Frame::DatagramHeader { .. } => unreachable!(),
8006 }
8007
8008 Ok(())
8009 }
8010
8011 fn drop_epoch_state(&mut self, epoch: packet::Epoch, now: time::Instant) {
8013 let crypto_ctx = &mut self.crypto_ctx[epoch];
8014 if crypto_ctx.crypto_open.is_none() {
8015 return;
8016 }
8017 crypto_ctx.clear();
8018 self.pkt_num_spaces[epoch].clear();
8019
8020 let handshake_status = self.handshake_status();
8021 for (_, p) in self.paths.iter_mut() {
8022 p.recovery
8023 .on_pkt_num_space_discarded(epoch, handshake_status, now);
8024 }
8025
8026 trace!("{} dropped epoch {} state", self.trace_id, epoch);
8027 }
8028
8029 fn should_update_max_data(&self) -> bool {
8034 self.flow_control.should_update_max_data()
8035 }
8036
8037 fn max_rx_data(&self) -> u64 {
8039 self.flow_control.max_data()
8040 }
8041
8042 fn should_send_handshake_done(&self) -> bool {
8044 self.is_established() && !self.handshake_done_sent && self.is_server
8045 }
8046
8047 fn idle_timeout(&self) -> Option<time::Duration> {
8051 if self.local_transport_params.max_idle_timeout == 0 &&
8055 self.peer_transport_params.max_idle_timeout == 0
8056 {
8057 return None;
8058 }
8059
8060 let idle_timeout = if self.local_transport_params.max_idle_timeout == 0 {
8063 self.peer_transport_params.max_idle_timeout
8064 } else if self.peer_transport_params.max_idle_timeout == 0 {
8065 self.local_transport_params.max_idle_timeout
8066 } else {
8067 cmp::min(
8068 self.local_transport_params.max_idle_timeout,
8069 self.peer_transport_params.max_idle_timeout,
8070 )
8071 };
8072
8073 let path_pto = match self.paths.get_active() {
8074 Ok(p) => p.recovery.pto(),
8075 Err(_) => time::Duration::ZERO,
8076 };
8077
8078 let idle_timeout = time::Duration::from_millis(idle_timeout);
8079 let idle_timeout = cmp::max(idle_timeout, 3 * path_pto);
8080
8081 Some(idle_timeout)
8082 }
8083
8084 fn handshake_status(&self) -> recovery::HandshakeStatus {
8086 recovery::HandshakeStatus {
8087 has_handshake_keys: self.crypto_ctx[packet::Epoch::Handshake]
8088 .has_keys(),
8089
8090 peer_verified_address: self.peer_verified_initial_address,
8091
8092 completed: self.is_established(),
8093 }
8094 }
8095
8096 fn update_tx_cap(&mut self) {
8098 let cwin_available = match self.paths.get_active() {
8099 Ok(p) => p.recovery.cwnd_available() as u64,
8100 Err(_) => 0,
8101 };
8102
8103 let cap =
8104 cmp::min(cwin_available, self.max_tx_data - self.tx_data) as usize;
8105 self.tx_cap = (cap as f64 * self.tx_cap_factor).ceil() as usize;
8106 }
8107
8108 fn delivery_rate_check_if_app_limited(&self) -> bool {
8109 let cwin_available = self
8125 .paths
8126 .iter()
8127 .filter(|&(_, p)| p.active())
8128 .map(|(_, p)| p.recovery.cwnd_available())
8129 .sum();
8130
8131 ((self.tx_buffered + self.dgram_send_queue_byte_size()) < cwin_available) &&
8132 (self.tx_data.saturating_sub(self.last_tx_data)) <
8133 cwin_available as u64 &&
8134 cwin_available > 0
8135 }
8136
8137 fn set_initial_dcid(
8138 &mut self, cid: ConnectionId<'static>, reset_token: Option<u128>,
8139 path_id: usize,
8140 ) -> Result<()> {
8141 self.ids.set_initial_dcid(cid, reset_token, Some(path_id));
8142 self.paths.get_mut(path_id)?.active_dcid_seq = Some(0);
8143
8144 Ok(())
8145 }
8146
8147 fn get_or_create_recv_path_id(
8150 &mut self, recv_pid: Option<usize>, dcid: &ConnectionId, buf_len: usize,
8151 info: &RecvInfo,
8152 ) -> Result<usize> {
8153 let ids = &mut self.ids;
8154
8155 let (in_scid_seq, mut in_scid_pid) =
8156 ids.find_scid_seq(dcid).ok_or(Error::InvalidState)?;
8157
8158 if let Some(recv_pid) = recv_pid {
8159 let recv_path = self.paths.get_mut(recv_pid)?;
8161
8162 let cid_entry =
8163 recv_path.active_scid_seq.and_then(|v| ids.get_scid(v).ok());
8164
8165 if cid_entry.map(|e| &e.cid) != Some(dcid) {
8166 let incoming_cid_entry = ids.get_scid(in_scid_seq)?;
8167
8168 let prev_recv_pid =
8169 incoming_cid_entry.path_id.unwrap_or(recv_pid);
8170
8171 if prev_recv_pid != recv_pid {
8172 trace!(
8173 "{} peer reused CID {:?} from path {} on path {}",
8174 self.trace_id,
8175 dcid,
8176 prev_recv_pid,
8177 recv_pid
8178 );
8179
8180 }
8182
8183 trace!(
8184 "{} path ID {} now see SCID with seq num {}",
8185 self.trace_id,
8186 recv_pid,
8187 in_scid_seq
8188 );
8189
8190 recv_path.active_scid_seq = Some(in_scid_seq);
8191 ids.link_scid_to_path_id(in_scid_seq, recv_pid)?;
8192 }
8193
8194 return Ok(recv_pid);
8195 }
8196
8197 if ids.zero_length_scid() {
8202 in_scid_pid = None;
8203 }
8204
8205 if let Some(in_scid_pid) = in_scid_pid {
8206 let old_path = self.paths.get_mut(in_scid_pid)?;
8210 let old_local_addr = old_path.local_addr();
8211 let old_peer_addr = old_path.peer_addr();
8212
8213 trace!(
8214 "{} reused CID seq {} of ({},{}) (path {}) on ({},{})",
8215 self.trace_id,
8216 in_scid_seq,
8217 old_local_addr,
8218 old_peer_addr,
8219 in_scid_pid,
8220 info.to,
8221 info.from
8222 );
8223
8224 self.paths
8226 .notify_event(path::PathEvent::ReusedSourceConnectionId(
8227 in_scid_seq,
8228 (old_local_addr, old_peer_addr),
8229 (info.to, info.from),
8230 ));
8231 }
8232
8233 let mut path = path::Path::new(
8235 info.to,
8236 info.from,
8237 &self.recovery_config,
8238 self.path_challenge_recv_max_queue_len,
8239 MIN_CLIENT_INITIAL_LEN,
8240 false,
8241 );
8242
8243 path.max_send_bytes = buf_len * self.max_amplification_factor;
8244 path.active_scid_seq = Some(in_scid_seq);
8245
8246 path.request_validation();
8248
8249 let pid = self.paths.insert_path(path, self.is_server)?;
8250
8251 if in_scid_pid.is_none() {
8253 ids.link_scid_to_path_id(in_scid_seq, pid)?;
8254 }
8255
8256 Ok(pid)
8257 }
8258
8259 fn get_send_path_id(
8261 &self, from: Option<SocketAddr>, to: Option<SocketAddr>,
8262 ) -> Result<usize> {
8263 if self.is_established() {
8266 let mut probing = self
8267 .paths
8268 .iter()
8269 .filter(|(_, p)| from.is_none() || Some(p.local_addr()) == from)
8270 .filter(|(_, p)| to.is_none() || Some(p.peer_addr()) == to)
8271 .filter(|(_, p)| p.active_dcid_seq.is_some())
8272 .filter(|(_, p)| p.probing_required())
8273 .map(|(pid, _)| pid);
8274
8275 if let Some(pid) = probing.next() {
8276 return Ok(pid);
8277 }
8278 }
8279
8280 if let Some((pid, p)) = self.paths.get_active_with_pid() {
8281 if from.is_some() && Some(p.local_addr()) != from {
8282 return Err(Error::Done);
8283 }
8284
8285 if to.is_some() && Some(p.peer_addr()) != to {
8286 return Err(Error::Done);
8287 }
8288
8289 return Ok(pid);
8290 };
8291
8292 Err(Error::InvalidState)
8293 }
8294
8295 fn set_active_path(
8297 &mut self, path_id: usize, now: time::Instant,
8298 ) -> Result<()> {
8299 if let Ok(old_active_path) = self.paths.get_active_mut() {
8300 for &e in packet::Epoch::epochs(
8301 packet::Epoch::Initial..=packet::Epoch::Application,
8302 ) {
8303 let (lost_packets, lost_bytes) = old_active_path
8304 .recovery
8305 .on_path_change(e, now, &self.trace_id);
8306
8307 self.lost_count += lost_packets;
8308 self.lost_bytes += lost_bytes as u64;
8309 }
8310 }
8311
8312 self.paths.set_active_path(path_id)
8313 }
8314
8315 fn on_peer_migrated(
8317 &mut self, new_pid: usize, disable_dcid_reuse: bool, now: time::Instant,
8318 ) -> Result<()> {
8319 let active_path_id = self.paths.get_active_path_id()?;
8320
8321 if active_path_id == new_pid {
8322 return Ok(());
8323 }
8324
8325 self.set_active_path(new_pid, now)?;
8326
8327 let no_spare_dcid =
8328 self.paths.get_mut(new_pid)?.active_dcid_seq.is_none();
8329
8330 if no_spare_dcid && !disable_dcid_reuse {
8331 self.paths.get_mut(new_pid)?.active_dcid_seq =
8332 self.paths.get_mut(active_path_id)?.active_dcid_seq;
8333 }
8334
8335 Ok(())
8336 }
8337
8338 fn create_path_on_client(
8340 &mut self, local_addr: SocketAddr, peer_addr: SocketAddr,
8341 ) -> Result<usize> {
8342 if self.is_server {
8343 return Err(Error::InvalidState);
8344 }
8345
8346 if !self.ids.zero_length_scid() && self.ids.available_scids() == 0 {
8349 return Err(Error::OutOfIdentifiers);
8350 }
8351
8352 let dcid_seq = if self.ids.zero_length_dcid() {
8356 0
8357 } else {
8358 self.ids
8359 .lowest_available_dcid_seq()
8360 .ok_or(Error::OutOfIdentifiers)?
8361 };
8362
8363 let mut path = path::Path::new(
8364 local_addr,
8365 peer_addr,
8366 &self.recovery_config,
8367 self.path_challenge_recv_max_queue_len,
8368 MIN_CLIENT_INITIAL_LEN,
8369 false,
8370 );
8371 path.active_dcid_seq = Some(dcid_seq);
8372
8373 let pid = self
8374 .paths
8375 .insert_path(path, false)
8376 .map_err(|_| Error::OutOfIdentifiers)?;
8377 self.ids.link_dcid_to_path_id(dcid_seq, pid)?;
8378
8379 Ok(pid)
8380 }
8381
8382 fn mark_closed(&mut self) {
8384 #[cfg(feature = "qlog")]
8385 {
8386 let cc = match (self.is_established(), self.timed_out, &self.peer_error, &self.local_error) {
8387 (false, _, _, _) => qlog::events::connectivity::ConnectionClosed {
8388 owner: Some(TransportOwner::Local),
8389 connection_code: None,
8390 application_code: None,
8391 internal_code: None,
8392 reason: Some("Failed to establish connection".to_string()),
8393 trigger: Some(qlog::events::connectivity::ConnectionClosedTrigger::HandshakeTimeout)
8394 },
8395
8396 (true, true, _, _) => qlog::events::connectivity::ConnectionClosed {
8397 owner: Some(TransportOwner::Local),
8398 connection_code: None,
8399 application_code: None,
8400 internal_code: None,
8401 reason: Some("Idle timeout".to_string()),
8402 trigger: Some(qlog::events::connectivity::ConnectionClosedTrigger::IdleTimeout)
8403 },
8404
8405 (true, false, Some(peer_error), None) => {
8406 let (connection_code, application_code, trigger) = if peer_error.is_app {
8407 (None, Some(qlog::events::ApplicationErrorCode::Value(peer_error.error_code)), None)
8408 } else {
8409 let trigger = if peer_error.error_code == WireErrorCode::NoError as u64 {
8410 Some(qlog::events::connectivity::ConnectionClosedTrigger::Clean)
8411 } else {
8412 Some(qlog::events::connectivity::ConnectionClosedTrigger::Error)
8413 };
8414
8415 (Some(qlog::events::ConnectionErrorCode::Value(peer_error.error_code)), None, trigger)
8416 };
8417
8418 qlog::events::connectivity::ConnectionClosed {
8419 owner: Some(TransportOwner::Remote),
8420 connection_code,
8421 application_code,
8422 internal_code: None,
8423 reason: Some(String::from_utf8_lossy(&peer_error.reason).to_string()),
8424 trigger,
8425 }
8426 },
8427
8428 (true, false, None, Some(local_error)) => {
8429 let (connection_code, application_code, trigger) = if local_error.is_app {
8430 (None, Some(qlog::events::ApplicationErrorCode::Value(local_error.error_code)), None)
8431 } else {
8432 let trigger = if local_error.error_code == WireErrorCode::NoError as u64 {
8433 Some(qlog::events::connectivity::ConnectionClosedTrigger::Clean)
8434 } else {
8435 Some(qlog::events::connectivity::ConnectionClosedTrigger::Error)
8436 };
8437
8438 (Some(qlog::events::ConnectionErrorCode::Value(local_error.error_code)), None, trigger)
8439 };
8440
8441 qlog::events::connectivity::ConnectionClosed {
8442 owner: Some(TransportOwner::Local),
8443 connection_code,
8444 application_code,
8445 internal_code: None,
8446 reason: Some(String::from_utf8_lossy(&local_error.reason).to_string()),
8447 trigger,
8448 }
8449 },
8450
8451 _ => qlog::events::connectivity::ConnectionClosed {
8452 owner: None,
8453 connection_code: None,
8454 application_code: None,
8455 internal_code: None,
8456 reason: None,
8457 trigger: None,
8458 },
8459 };
8460
8461 qlog_with_type!(QLOG_CONNECTION_CLOSED, self.qlog, q, {
8462 let ev_data = qlog::events::EventData::ConnectionClosed(cc);
8463
8464 q.add_event_data_now(ev_data).ok();
8465 });
8466 self.qlog.streamer = None;
8467 }
8468 self.closed = true;
8469 }
8470}
8471
8472#[cfg(feature = "boringssl-boring-crate")]
8473impl<F: BufFactory> AsMut<boring::ssl::SslRef> for Connection<F> {
8474 fn as_mut(&mut self) -> &mut boring::ssl::SslRef {
8475 self.handshake.ssl_mut()
8476 }
8477}
8478
8479fn drop_pkt_on_err(
8498 e: Error, recv_count: usize, is_server: bool, trace_id: &str,
8499) -> Error {
8500 if is_server && recv_count == 0 {
8504 return e;
8505 }
8506
8507 trace!("{} dropped invalid packet", trace_id);
8508
8509 Error::Done
8512}
8513
8514struct AddrTupleFmt(SocketAddr, SocketAddr);
8515
8516impl std::fmt::Display for AddrTupleFmt {
8517 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
8518 let AddrTupleFmt(src, dst) = &self;
8519
8520 if src.ip().is_unspecified() || dst.ip().is_unspecified() {
8521 return Ok(());
8522 }
8523
8524 f.write_fmt(format_args!("src:{src} dst:{dst}"))
8525 }
8526}
8527
8528#[derive(Clone, Default)]
8534pub struct Stats {
8535 pub recv: usize,
8537
8538 pub sent: usize,
8540
8541 pub lost: usize,
8543
8544 pub spurious_lost: usize,
8546
8547 pub retrans: usize,
8549
8550 pub sent_bytes: u64,
8552
8553 pub recv_bytes: u64,
8555
8556 pub acked_bytes: u64,
8558
8559 pub lost_bytes: u64,
8561
8562 pub stream_retrans_bytes: u64,
8564
8565 pub dgram_recv: usize,
8567
8568 pub dgram_sent: usize,
8570
8571 pub paths_count: usize,
8573
8574 pub reset_stream_count_local: u64,
8576
8577 pub stopped_stream_count_local: u64,
8579
8580 pub reset_stream_count_remote: u64,
8582
8583 pub stopped_stream_count_remote: u64,
8585
8586 pub path_challenge_rx_count: u64,
8588
8589 pub bytes_in_flight_duration: Duration,
8592}
8593
8594impl std::fmt::Debug for Stats {
8595 #[inline]
8596 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
8597 write!(
8598 f,
8599 "recv={} sent={} lost={} retrans={}",
8600 self.recv, self.sent, self.lost, self.retrans,
8601 )?;
8602
8603 write!(
8604 f,
8605 " sent_bytes={} recv_bytes={} lost_bytes={}",
8606 self.sent_bytes, self.recv_bytes, self.lost_bytes,
8607 )?;
8608
8609 Ok(())
8610 }
8611}
8612
8613#[derive(Clone, Debug, PartialEq)]
8618pub struct UnknownTransportParameter<T> {
8619 pub id: u64,
8621
8622 pub value: T,
8624}
8625
8626impl<T> UnknownTransportParameter<T> {
8627 pub fn is_reserved(&self) -> bool {
8632 let n = (self.id - 27) / 31;
8633 self.id == 31 * n + 27
8634 }
8635}
8636
8637#[cfg(feature = "qlog")]
8638impl From<UnknownTransportParameter<Vec<u8>>>
8639 for qlog::events::quic::UnknownTransportParameter
8640{
8641 fn from(value: UnknownTransportParameter<Vec<u8>>) -> Self {
8642 Self {
8643 id: value.id,
8644 value: qlog::HexSlice::maybe_string(Some(value.value.as_slice()))
8645 .unwrap_or_default(),
8646 }
8647 }
8648}
8649
8650impl From<UnknownTransportParameter<&[u8]>>
8651 for UnknownTransportParameter<Vec<u8>>
8652{
8653 fn from(value: UnknownTransportParameter<&[u8]>) -> Self {
8658 Self {
8659 id: value.id,
8660 value: value.value.to_vec(),
8661 }
8662 }
8663}
8664
8665#[derive(Clone, Debug, PartialEq, Default)]
8667pub struct UnknownTransportParameters {
8668 pub capacity: usize,
8670 pub parameters: Vec<UnknownTransportParameter<Vec<u8>>>,
8672}
8673
8674impl UnknownTransportParameters {
8675 pub fn push(&mut self, new: UnknownTransportParameter<&[u8]>) -> Result<()> {
8678 let new_unknown_tp_size = new.value.len() + std::mem::size_of::<u64>();
8679 if new_unknown_tp_size < self.capacity {
8680 self.capacity -= new_unknown_tp_size;
8681 self.parameters.push(new.into());
8682 Ok(())
8683 } else {
8684 Err(BufferTooShortError.into())
8685 }
8686 }
8687}
8688
8689pub struct UnknownTransportParameterIterator<'a> {
8691 index: usize,
8692 parameters: &'a Vec<UnknownTransportParameter<Vec<u8>>>,
8693}
8694
8695impl<'a> IntoIterator for &'a UnknownTransportParameters {
8696 type IntoIter = UnknownTransportParameterIterator<'a>;
8697 type Item = &'a UnknownTransportParameter<Vec<u8>>;
8698
8699 fn into_iter(self) -> Self::IntoIter {
8700 UnknownTransportParameterIterator {
8701 index: 0,
8702 parameters: &self.parameters,
8703 }
8704 }
8705}
8706
8707impl<'a> Iterator for UnknownTransportParameterIterator<'a> {
8708 type Item = &'a UnknownTransportParameter<Vec<u8>>;
8709
8710 fn next(&mut self) -> Option<Self::Item> {
8711 let result = self.parameters.get(self.index);
8712 self.index += 1;
8713 result
8714 }
8715}
8716
8717#[derive(Clone, Debug, PartialEq)]
8719pub struct TransportParams {
8720 pub original_destination_connection_id: Option<ConnectionId<'static>>,
8722 pub max_idle_timeout: u64,
8724 pub stateless_reset_token: Option<u128>,
8726 pub max_udp_payload_size: u64,
8728 pub initial_max_data: u64,
8730 pub initial_max_stream_data_bidi_local: u64,
8732 pub initial_max_stream_data_bidi_remote: u64,
8734 pub initial_max_stream_data_uni: u64,
8736 pub initial_max_streams_bidi: u64,
8738 pub initial_max_streams_uni: u64,
8740 pub ack_delay_exponent: u64,
8742 pub max_ack_delay: u64,
8744 pub disable_active_migration: bool,
8746 pub active_conn_id_limit: u64,
8748 pub initial_source_connection_id: Option<ConnectionId<'static>>,
8751 pub retry_source_connection_id: Option<ConnectionId<'static>>,
8754 pub max_datagram_frame_size: Option<u64>,
8756 pub unknown_params: Option<UnknownTransportParameters>,
8758 }
8760
8761impl Default for TransportParams {
8762 fn default() -> TransportParams {
8763 TransportParams {
8764 original_destination_connection_id: None,
8765 max_idle_timeout: 0,
8766 stateless_reset_token: None,
8767 max_udp_payload_size: 65527,
8768 initial_max_data: 0,
8769 initial_max_stream_data_bidi_local: 0,
8770 initial_max_stream_data_bidi_remote: 0,
8771 initial_max_stream_data_uni: 0,
8772 initial_max_streams_bidi: 0,
8773 initial_max_streams_uni: 0,
8774 ack_delay_exponent: 3,
8775 max_ack_delay: 25,
8776 disable_active_migration: false,
8777 active_conn_id_limit: 2,
8778 initial_source_connection_id: None,
8779 retry_source_connection_id: None,
8780 max_datagram_frame_size: None,
8781 unknown_params: Default::default(),
8782 }
8783 }
8784}
8785
8786impl TransportParams {
8787 fn decode(
8788 buf: &[u8], is_server: bool, unknown_size: Option<usize>,
8789 ) -> Result<TransportParams> {
8790 let mut params = octets::Octets::with_slice(buf);
8791 let mut seen_params = HashSet::new();
8792
8793 let mut tp = TransportParams::default();
8794
8795 if let Some(unknown_transport_param_tracking_size) = unknown_size {
8796 tp.unknown_params = Some(UnknownTransportParameters {
8797 capacity: unknown_transport_param_tracking_size,
8798 parameters: vec![],
8799 });
8800 }
8801
8802 while params.cap() > 0 {
8803 let id = params.get_varint()?;
8804
8805 if seen_params.contains(&id) {
8806 return Err(Error::InvalidTransportParam);
8807 }
8808 seen_params.insert(id);
8809
8810 let mut val = params.get_bytes_with_varint_length()?;
8811
8812 match id {
8813 0x0000 => {
8814 if is_server {
8815 return Err(Error::InvalidTransportParam);
8816 }
8817
8818 tp.original_destination_connection_id =
8819 Some(val.to_vec().into());
8820 },
8821
8822 0x0001 => {
8823 tp.max_idle_timeout = val.get_varint()?;
8824 },
8825
8826 0x0002 => {
8827 if is_server {
8828 return Err(Error::InvalidTransportParam);
8829 }
8830
8831 tp.stateless_reset_token = Some(u128::from_be_bytes(
8832 val.get_bytes(16)?
8833 .to_vec()
8834 .try_into()
8835 .map_err(|_| Error::BufferTooShort)?,
8836 ));
8837 },
8838
8839 0x0003 => {
8840 tp.max_udp_payload_size = val.get_varint()?;
8841
8842 if tp.max_udp_payload_size < 1200 {
8843 return Err(Error::InvalidTransportParam);
8844 }
8845 },
8846
8847 0x0004 => {
8848 tp.initial_max_data = val.get_varint()?;
8849 },
8850
8851 0x0005 => {
8852 tp.initial_max_stream_data_bidi_local = val.get_varint()?;
8853 },
8854
8855 0x0006 => {
8856 tp.initial_max_stream_data_bidi_remote = val.get_varint()?;
8857 },
8858
8859 0x0007 => {
8860 tp.initial_max_stream_data_uni = val.get_varint()?;
8861 },
8862
8863 0x0008 => {
8864 let max = val.get_varint()?;
8865
8866 if max > MAX_STREAM_ID {
8867 return Err(Error::InvalidTransportParam);
8868 }
8869
8870 tp.initial_max_streams_bidi = max;
8871 },
8872
8873 0x0009 => {
8874 let max = val.get_varint()?;
8875
8876 if max > MAX_STREAM_ID {
8877 return Err(Error::InvalidTransportParam);
8878 }
8879
8880 tp.initial_max_streams_uni = max;
8881 },
8882
8883 0x000a => {
8884 let ack_delay_exponent = val.get_varint()?;
8885
8886 if ack_delay_exponent > 20 {
8887 return Err(Error::InvalidTransportParam);
8888 }
8889
8890 tp.ack_delay_exponent = ack_delay_exponent;
8891 },
8892
8893 0x000b => {
8894 let max_ack_delay = val.get_varint()?;
8895
8896 if max_ack_delay >= 2_u64.pow(14) {
8897 return Err(Error::InvalidTransportParam);
8898 }
8899
8900 tp.max_ack_delay = max_ack_delay;
8901 },
8902
8903 0x000c => {
8904 tp.disable_active_migration = true;
8905 },
8906
8907 0x000d => {
8908 if is_server {
8909 return Err(Error::InvalidTransportParam);
8910 }
8911
8912 },
8914
8915 0x000e => {
8916 let limit = val.get_varint()?;
8917
8918 if limit < 2 {
8919 return Err(Error::InvalidTransportParam);
8920 }
8921
8922 tp.active_conn_id_limit = limit;
8923 },
8924
8925 0x000f => {
8926 tp.initial_source_connection_id = Some(val.to_vec().into());
8927 },
8928
8929 0x00010 => {
8930 if is_server {
8931 return Err(Error::InvalidTransportParam);
8932 }
8933
8934 tp.retry_source_connection_id = Some(val.to_vec().into());
8935 },
8936
8937 0x0020 => {
8938 tp.max_datagram_frame_size = Some(val.get_varint()?);
8939 },
8940
8941 unknown_tp_id => {
8943 if let Some(unknown_params) = &mut tp.unknown_params {
8944 let _ = unknown_params.push(UnknownTransportParameter {
8947 id: unknown_tp_id,
8948 value: val.buf(),
8949 });
8950 }
8951 },
8952 }
8953 }
8954
8955 Ok(tp)
8956 }
8957
8958 fn encode_param(
8959 b: &mut octets::OctetsMut, ty: u64, len: usize,
8960 ) -> Result<()> {
8961 b.put_varint(ty)?;
8962 b.put_varint(len as u64)?;
8963
8964 Ok(())
8965 }
8966
8967 fn encode<'a>(
8968 tp: &TransportParams, is_server: bool, out: &'a mut [u8],
8969 ) -> Result<&'a mut [u8]> {
8970 let mut b = octets::OctetsMut::with_slice(out);
8971
8972 if is_server {
8973 if let Some(ref odcid) = tp.original_destination_connection_id {
8974 TransportParams::encode_param(&mut b, 0x0000, odcid.len())?;
8975 b.put_bytes(odcid)?;
8976 }
8977 };
8978
8979 if tp.max_idle_timeout != 0 {
8980 TransportParams::encode_param(
8981 &mut b,
8982 0x0001,
8983 octets::varint_len(tp.max_idle_timeout),
8984 )?;
8985 b.put_varint(tp.max_idle_timeout)?;
8986 }
8987
8988 if is_server {
8989 if let Some(ref token) = tp.stateless_reset_token {
8990 TransportParams::encode_param(&mut b, 0x0002, 16)?;
8991 b.put_bytes(&token.to_be_bytes())?;
8992 }
8993 }
8994
8995 if tp.max_udp_payload_size != 0 {
8996 TransportParams::encode_param(
8997 &mut b,
8998 0x0003,
8999 octets::varint_len(tp.max_udp_payload_size),
9000 )?;
9001 b.put_varint(tp.max_udp_payload_size)?;
9002 }
9003
9004 if tp.initial_max_data != 0 {
9005 TransportParams::encode_param(
9006 &mut b,
9007 0x0004,
9008 octets::varint_len(tp.initial_max_data),
9009 )?;
9010 b.put_varint(tp.initial_max_data)?;
9011 }
9012
9013 if tp.initial_max_stream_data_bidi_local != 0 {
9014 TransportParams::encode_param(
9015 &mut b,
9016 0x0005,
9017 octets::varint_len(tp.initial_max_stream_data_bidi_local),
9018 )?;
9019 b.put_varint(tp.initial_max_stream_data_bidi_local)?;
9020 }
9021
9022 if tp.initial_max_stream_data_bidi_remote != 0 {
9023 TransportParams::encode_param(
9024 &mut b,
9025 0x0006,
9026 octets::varint_len(tp.initial_max_stream_data_bidi_remote),
9027 )?;
9028 b.put_varint(tp.initial_max_stream_data_bidi_remote)?;
9029 }
9030
9031 if tp.initial_max_stream_data_uni != 0 {
9032 TransportParams::encode_param(
9033 &mut b,
9034 0x0007,
9035 octets::varint_len(tp.initial_max_stream_data_uni),
9036 )?;
9037 b.put_varint(tp.initial_max_stream_data_uni)?;
9038 }
9039
9040 if tp.initial_max_streams_bidi != 0 {
9041 TransportParams::encode_param(
9042 &mut b,
9043 0x0008,
9044 octets::varint_len(tp.initial_max_streams_bidi),
9045 )?;
9046 b.put_varint(tp.initial_max_streams_bidi)?;
9047 }
9048
9049 if tp.initial_max_streams_uni != 0 {
9050 TransportParams::encode_param(
9051 &mut b,
9052 0x0009,
9053 octets::varint_len(tp.initial_max_streams_uni),
9054 )?;
9055 b.put_varint(tp.initial_max_streams_uni)?;
9056 }
9057
9058 if tp.ack_delay_exponent != 0 {
9059 TransportParams::encode_param(
9060 &mut b,
9061 0x000a,
9062 octets::varint_len(tp.ack_delay_exponent),
9063 )?;
9064 b.put_varint(tp.ack_delay_exponent)?;
9065 }
9066
9067 if tp.max_ack_delay != 0 {
9068 TransportParams::encode_param(
9069 &mut b,
9070 0x000b,
9071 octets::varint_len(tp.max_ack_delay),
9072 )?;
9073 b.put_varint(tp.max_ack_delay)?;
9074 }
9075
9076 if tp.disable_active_migration {
9077 TransportParams::encode_param(&mut b, 0x000c, 0)?;
9078 }
9079
9080 if tp.active_conn_id_limit != 2 {
9083 TransportParams::encode_param(
9084 &mut b,
9085 0x000e,
9086 octets::varint_len(tp.active_conn_id_limit),
9087 )?;
9088 b.put_varint(tp.active_conn_id_limit)?;
9089 }
9090
9091 if let Some(scid) = &tp.initial_source_connection_id {
9092 TransportParams::encode_param(&mut b, 0x000f, scid.len())?;
9093 b.put_bytes(scid)?;
9094 }
9095
9096 if is_server {
9097 if let Some(scid) = &tp.retry_source_connection_id {
9098 TransportParams::encode_param(&mut b, 0x0010, scid.len())?;
9099 b.put_bytes(scid)?;
9100 }
9101 }
9102
9103 if let Some(max_datagram_frame_size) = tp.max_datagram_frame_size {
9104 TransportParams::encode_param(
9105 &mut b,
9106 0x0020,
9107 octets::varint_len(max_datagram_frame_size),
9108 )?;
9109 b.put_varint(max_datagram_frame_size)?;
9110 }
9111
9112 let out_len = b.off();
9113
9114 Ok(&mut out[..out_len])
9115 }
9116
9117 #[cfg(feature = "qlog")]
9119 pub fn to_qlog(
9120 &self, owner: TransportOwner, cipher: Option<crypto::Algorithm>,
9121 ) -> EventData {
9122 let original_destination_connection_id = qlog::HexSlice::maybe_string(
9123 self.original_destination_connection_id.as_ref(),
9124 );
9125
9126 let stateless_reset_token = qlog::HexSlice::maybe_string(
9127 self.stateless_reset_token.map(|s| s.to_be_bytes()).as_ref(),
9128 );
9129
9130 let tls_cipher: Option<String> = cipher.map(|f| format!("{f:?}"));
9131
9132 EventData::TransportParametersSet(
9133 qlog::events::quic::TransportParametersSet {
9134 owner: Some(owner),
9135 tls_cipher,
9136 original_destination_connection_id,
9137 stateless_reset_token,
9138 disable_active_migration: Some(self.disable_active_migration),
9139 max_idle_timeout: Some(self.max_idle_timeout),
9140 max_udp_payload_size: Some(self.max_udp_payload_size as u32),
9141 ack_delay_exponent: Some(self.ack_delay_exponent as u16),
9142 max_ack_delay: Some(self.max_ack_delay as u16),
9143 active_connection_id_limit: Some(
9144 self.active_conn_id_limit as u32,
9145 ),
9146
9147 initial_max_data: Some(self.initial_max_data),
9148 initial_max_stream_data_bidi_local: Some(
9149 self.initial_max_stream_data_bidi_local,
9150 ),
9151 initial_max_stream_data_bidi_remote: Some(
9152 self.initial_max_stream_data_bidi_remote,
9153 ),
9154 initial_max_stream_data_uni: Some(
9155 self.initial_max_stream_data_uni,
9156 ),
9157 initial_max_streams_bidi: Some(self.initial_max_streams_bidi),
9158 initial_max_streams_uni: Some(self.initial_max_streams_uni),
9159
9160 unknown_parameters: self
9161 .unknown_params
9162 .as_ref()
9163 .map(|unknown_params| {
9164 unknown_params
9165 .into_iter()
9166 .cloned()
9167 .map(
9168 Into::<
9169 qlog::events::quic::UnknownTransportParameter,
9170 >::into,
9171 )
9172 .collect()
9173 })
9174 .unwrap_or_default(),
9175
9176 ..Default::default()
9177 },
9178 )
9179 }
9180}
9181
9182#[doc(hidden)]
9183pub mod testing {
9184 use super::*;
9185 use crate::recovery::Sent;
9186 use smallvec::smallvec;
9187 use std::time::Instant;
9188
9189 pub struct Pipe {
9190 pub client: Connection,
9191 pub server: Connection,
9192 }
9193
9194 impl Pipe {
9195 pub fn new(cc_algorithm_name: &str) -> Result<Pipe> {
9196 let mut config = Config::new(crate::PROTOCOL_VERSION)?;
9197 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
9198 config.load_cert_chain_from_pem_file("examples/cert.crt")?;
9199 config.load_priv_key_from_pem_file("examples/cert.key")?;
9200 config.set_application_protos(&[b"proto1", b"proto2"])?;
9201 config.set_initial_max_data(30);
9202 config.set_initial_max_stream_data_bidi_local(15);
9203 config.set_initial_max_stream_data_bidi_remote(15);
9204 config.set_initial_max_stream_data_uni(10);
9205 config.set_initial_max_streams_bidi(3);
9206 config.set_initial_max_streams_uni(3);
9207 config.set_max_idle_timeout(180_000);
9208 config.verify_peer(false);
9209 config.set_ack_delay_exponent(8);
9210
9211 Pipe::with_config(&mut config)
9212 }
9213
9214 pub fn client_addr() -> SocketAddr {
9215 "127.0.0.1:1234".parse().unwrap()
9216 }
9217
9218 pub fn server_addr() -> SocketAddr {
9219 "127.0.0.1:4321".parse().unwrap()
9220 }
9221
9222 pub fn with_config(config: &mut Config) -> Result<Pipe> {
9223 let mut client_scid = [0; 16];
9224 rand::rand_bytes(&mut client_scid[..]);
9225 let client_scid = ConnectionId::from_ref(&client_scid);
9226 let client_addr = Pipe::client_addr();
9227
9228 let mut server_scid = [0; 16];
9229 rand::rand_bytes(&mut server_scid[..]);
9230 let server_scid = ConnectionId::from_ref(&server_scid);
9231 let server_addr = Pipe::server_addr();
9232
9233 Ok(Pipe {
9234 client: connect(
9235 Some("quic.tech"),
9236 &client_scid,
9237 client_addr,
9238 server_addr,
9239 config,
9240 )?,
9241 server: accept(
9242 &server_scid,
9243 None,
9244 server_addr,
9245 client_addr,
9246 config,
9247 )?,
9248 })
9249 }
9250
9251 pub fn with_config_and_scid_lengths(
9252 config: &mut Config, client_scid_len: usize, server_scid_len: usize,
9253 ) -> Result<Pipe> {
9254 let mut client_scid = vec![0; client_scid_len];
9255 rand::rand_bytes(&mut client_scid[..]);
9256 let client_scid = ConnectionId::from_ref(&client_scid);
9257 let client_addr = Pipe::client_addr();
9258
9259 let mut server_scid = vec![0; server_scid_len];
9260 rand::rand_bytes(&mut server_scid[..]);
9261 let server_scid = ConnectionId::from_ref(&server_scid);
9262 let server_addr = Pipe::server_addr();
9263
9264 Ok(Pipe {
9265 client: connect(
9266 Some("quic.tech"),
9267 &client_scid,
9268 client_addr,
9269 server_addr,
9270 config,
9271 )?,
9272 server: accept(
9273 &server_scid,
9274 None,
9275 server_addr,
9276 client_addr,
9277 config,
9278 )?,
9279 })
9280 }
9281
9282 pub fn with_client_config(client_config: &mut Config) -> Result<Pipe> {
9283 let mut client_scid = [0; 16];
9284 rand::rand_bytes(&mut client_scid[..]);
9285 let client_scid = ConnectionId::from_ref(&client_scid);
9286 let client_addr = Pipe::client_addr();
9287
9288 let mut server_scid = [0; 16];
9289 rand::rand_bytes(&mut server_scid[..]);
9290 let server_scid = ConnectionId::from_ref(&server_scid);
9291 let server_addr = Pipe::server_addr();
9292
9293 let mut config = Config::new(crate::PROTOCOL_VERSION)?;
9294 config.load_cert_chain_from_pem_file("examples/cert.crt")?;
9295 config.load_priv_key_from_pem_file("examples/cert.key")?;
9296 config.set_application_protos(&[b"proto1", b"proto2"])?;
9297 config.set_initial_max_data(30);
9298 config.set_initial_max_stream_data_bidi_local(15);
9299 config.set_initial_max_stream_data_bidi_remote(15);
9300 config.set_initial_max_streams_bidi(3);
9301 config.set_initial_max_streams_uni(3);
9302 config.set_ack_delay_exponent(8);
9303
9304 Ok(Pipe {
9305 client: connect(
9306 Some("quic.tech"),
9307 &client_scid,
9308 client_addr,
9309 server_addr,
9310 client_config,
9311 )?,
9312 server: accept(
9313 &server_scid,
9314 None,
9315 server_addr,
9316 client_addr,
9317 &mut config,
9318 )?,
9319 })
9320 }
9321
9322 pub fn with_server_config(server_config: &mut Config) -> Result<Pipe> {
9323 let mut client_scid = [0; 16];
9324 rand::rand_bytes(&mut client_scid[..]);
9325 let client_scid = ConnectionId::from_ref(&client_scid);
9326 let client_addr = Pipe::client_addr();
9327
9328 let mut server_scid = [0; 16];
9329 rand::rand_bytes(&mut server_scid[..]);
9330 let server_scid = ConnectionId::from_ref(&server_scid);
9331 let server_addr = Pipe::server_addr();
9332
9333 let mut config = Config::new(crate::PROTOCOL_VERSION)?;
9334 config.set_application_protos(&[b"proto1", b"proto2"])?;
9335 config.set_initial_max_data(30);
9336 config.set_initial_max_stream_data_bidi_local(15);
9337 config.set_initial_max_stream_data_bidi_remote(15);
9338 config.set_initial_max_streams_bidi(3);
9339 config.set_initial_max_streams_uni(3);
9340 config.set_ack_delay_exponent(8);
9341
9342 Ok(Pipe {
9343 client: connect(
9344 Some("quic.tech"),
9345 &client_scid,
9346 client_addr,
9347 server_addr,
9348 &mut config,
9349 )?,
9350 server: accept(
9351 &server_scid,
9352 None,
9353 server_addr,
9354 client_addr,
9355 server_config,
9356 )?,
9357 })
9358 }
9359
9360 pub fn with_client_and_server_config(
9361 client_config: &mut Config, server_config: &mut Config,
9362 ) -> Result<Pipe> {
9363 let mut client_scid = [0; 16];
9364 rand::rand_bytes(&mut client_scid[..]);
9365 let client_scid = ConnectionId::from_ref(&client_scid);
9366 let client_addr = Pipe::client_addr();
9367
9368 let mut server_scid = [0; 16];
9369 rand::rand_bytes(&mut server_scid[..]);
9370 let server_scid = ConnectionId::from_ref(&server_scid);
9371 let server_addr = Pipe::server_addr();
9372
9373 Ok(Pipe {
9374 client: connect(
9375 Some("quic.tech"),
9376 &client_scid,
9377 client_addr,
9378 server_addr,
9379 client_config,
9380 )?,
9381 server: accept(
9382 &server_scid,
9383 None,
9384 server_addr,
9385 client_addr,
9386 server_config,
9387 )?,
9388 })
9389 }
9390
9391 pub fn handshake(&mut self) -> Result<()> {
9392 while !self.client.is_established() || !self.server.is_established() {
9393 let flight = emit_flight(&mut self.client)?;
9394 process_flight(&mut self.server, flight)?;
9395
9396 let flight = emit_flight(&mut self.server)?;
9397 process_flight(&mut self.client, flight)?;
9398 }
9399
9400 Ok(())
9401 }
9402
9403 pub fn advance(&mut self) -> Result<()> {
9404 let mut client_done = false;
9405 let mut server_done = false;
9406
9407 while !client_done || !server_done {
9408 match emit_flight(&mut self.client) {
9409 Ok(flight) => process_flight(&mut self.server, flight)?,
9410
9411 Err(Error::Done) => client_done = true,
9412
9413 Err(e) => return Err(e),
9414 };
9415
9416 match emit_flight(&mut self.server) {
9417 Ok(flight) => process_flight(&mut self.client, flight)?,
9418
9419 Err(Error::Done) => server_done = true,
9420
9421 Err(e) => return Err(e),
9422 };
9423 }
9424
9425 Ok(())
9426 }
9427
9428 pub fn client_recv(&mut self, buf: &mut [u8]) -> Result<usize> {
9429 let server_path = &self.server.paths.get_active().unwrap();
9430 let info = RecvInfo {
9431 to: server_path.peer_addr(),
9432 from: server_path.local_addr(),
9433 };
9434
9435 self.client.recv(buf, info)
9436 }
9437
9438 pub fn server_recv(&mut self, buf: &mut [u8]) -> Result<usize> {
9439 let client_path = &self.client.paths.get_active().unwrap();
9440 let info = RecvInfo {
9441 to: client_path.peer_addr(),
9442 from: client_path.local_addr(),
9443 };
9444
9445 self.server.recv(buf, info)
9446 }
9447
9448 pub fn send_pkt_to_server(
9449 &mut self, pkt_type: packet::Type, frames: &[frame::Frame],
9450 buf: &mut [u8],
9451 ) -> Result<usize> {
9452 let written = encode_pkt(&mut self.client, pkt_type, frames, buf)?;
9453 recv_send(&mut self.server, buf, written)
9454 }
9455
9456 pub fn client_update_key(&mut self) -> Result<()> {
9457 let crypto_ctx =
9458 &mut self.client.crypto_ctx[packet::Epoch::Application];
9459
9460 let open_next = crypto_ctx
9461 .crypto_open
9462 .as_ref()
9463 .unwrap()
9464 .derive_next_packet_key()
9465 .unwrap();
9466
9467 let seal_next = crypto_ctx
9468 .crypto_seal
9469 .as_ref()
9470 .unwrap()
9471 .derive_next_packet_key()?;
9472
9473 let open_prev = crypto_ctx.crypto_open.replace(open_next);
9474 crypto_ctx.crypto_seal.replace(seal_next);
9475
9476 crypto_ctx.key_update = Some(packet::KeyUpdate {
9477 crypto_open: open_prev.unwrap(),
9478 pn_on_update: self.client.next_pkt_num,
9479 update_acked: true,
9480 timer: time::Instant::now(),
9481 });
9482
9483 self.client.key_phase = !self.client.key_phase;
9484
9485 Ok(())
9486 }
9487 }
9488
9489 pub fn recv_send<F: BufFactory>(
9490 conn: &mut Connection<F>, buf: &mut [u8], len: usize,
9491 ) -> Result<usize> {
9492 let active_path = conn.paths.get_active()?;
9493 let info = RecvInfo {
9494 to: active_path.local_addr(),
9495 from: active_path.peer_addr(),
9496 };
9497
9498 conn.recv(&mut buf[..len], info)?;
9499
9500 let mut off = 0;
9501
9502 match conn.send(&mut buf[off..]) {
9503 Ok((write, _)) => off += write,
9504
9505 Err(Error::Done) => (),
9506
9507 Err(e) => return Err(e),
9508 }
9509
9510 Ok(off)
9511 }
9512
9513 pub fn process_flight(
9514 conn: &mut Connection, flight: Vec<(Vec<u8>, SendInfo)>,
9515 ) -> Result<()> {
9516 for (mut pkt, si) in flight {
9517 let info = RecvInfo {
9518 to: si.to,
9519 from: si.from,
9520 };
9521
9522 conn.recv(&mut pkt, info)?;
9523 }
9524
9525 Ok(())
9526 }
9527
9528 pub fn emit_flight_with_max_buffer(
9529 conn: &mut Connection, out_size: usize, from: Option<SocketAddr>,
9530 to: Option<SocketAddr>,
9531 ) -> Result<Vec<(Vec<u8>, SendInfo)>> {
9532 let mut flight = Vec::new();
9533
9534 loop {
9535 let mut out = vec![0u8; out_size];
9536
9537 let info = match conn.send_on_path(&mut out, from, to) {
9538 Ok((written, info)) => {
9539 out.truncate(written);
9540 info
9541 },
9542
9543 Err(Error::Done) => break,
9544
9545 Err(e) => return Err(e),
9546 };
9547
9548 flight.push((out, info));
9549 }
9550
9551 if flight.is_empty() {
9552 return Err(Error::Done);
9553 }
9554
9555 Ok(flight)
9556 }
9557
9558 pub fn emit_flight_on_path(
9559 conn: &mut Connection, from: Option<SocketAddr>, to: Option<SocketAddr>,
9560 ) -> Result<Vec<(Vec<u8>, SendInfo)>> {
9561 emit_flight_with_max_buffer(conn, 65535, from, to)
9562 }
9563
9564 pub fn emit_flight(
9565 conn: &mut Connection,
9566 ) -> Result<Vec<(Vec<u8>, SendInfo)>> {
9567 emit_flight_on_path(conn, None, None)
9568 }
9569
9570 pub fn encode_pkt(
9571 conn: &mut Connection, pkt_type: packet::Type, frames: &[frame::Frame],
9572 buf: &mut [u8],
9573 ) -> Result<usize> {
9574 let mut b = octets::OctetsMut::with_slice(buf);
9575
9576 let epoch = pkt_type.to_epoch()?;
9577
9578 let crypto_ctx = &mut conn.crypto_ctx[epoch];
9579
9580 let pn = conn.next_pkt_num;
9581 let pn_len = 4;
9582
9583 let send_path = conn.paths.get_active()?;
9584 let active_dcid_seq = send_path
9585 .active_dcid_seq
9586 .as_ref()
9587 .ok_or(Error::InvalidState)?;
9588 let active_scid_seq = send_path
9589 .active_scid_seq
9590 .as_ref()
9591 .ok_or(Error::InvalidState)?;
9592
9593 let hdr = Header {
9594 ty: pkt_type,
9595 version: conn.version,
9596 dcid: ConnectionId::from_ref(
9597 conn.ids.get_dcid(*active_dcid_seq)?.cid.as_ref(),
9598 ),
9599 scid: ConnectionId::from_ref(
9600 conn.ids.get_scid(*active_scid_seq)?.cid.as_ref(),
9601 ),
9602 pkt_num: pn,
9603 pkt_num_len: pn_len,
9604 token: conn.token.clone(),
9605 versions: None,
9606 key_phase: conn.key_phase,
9607 };
9608
9609 hdr.to_bytes(&mut b)?;
9610
9611 let payload_len = frames.iter().fold(0, |acc, x| acc + x.wire_len());
9612
9613 if pkt_type != packet::Type::Short {
9614 let len =
9615 pn_len + payload_len + crypto_ctx.crypto_overhead().unwrap();
9616 b.put_varint(len as u64)?;
9617 }
9618
9619 b.put_u32(pn as u32)?;
9622
9623 let payload_offset = b.off();
9624
9625 for frame in frames {
9626 frame.to_bytes(&mut b)?;
9627 }
9628
9629 let aead = match crypto_ctx.crypto_seal {
9630 Some(ref v) => v,
9631 None => return Err(Error::InvalidState),
9632 };
9633
9634 let written = packet::encrypt_pkt(
9635 &mut b,
9636 pn,
9637 pn_len,
9638 payload_len,
9639 payload_offset,
9640 None,
9641 aead,
9642 )?;
9643
9644 conn.next_pkt_num += 1;
9645
9646 Ok(written)
9647 }
9648
9649 pub fn decode_pkt(
9650 conn: &mut Connection, buf: &mut [u8],
9651 ) -> Result<Vec<frame::Frame>> {
9652 let mut b = octets::OctetsMut::with_slice(buf);
9653
9654 let mut hdr = Header::from_bytes(&mut b, conn.source_id().len()).unwrap();
9655
9656 let epoch = hdr.ty.to_epoch()?;
9657
9658 let aead = conn.crypto_ctx[epoch].crypto_open.as_ref().unwrap();
9659
9660 let payload_len = b.cap();
9661
9662 packet::decrypt_hdr(&mut b, &mut hdr, aead).unwrap();
9663
9664 let pn = packet::decode_pkt_num(
9665 conn.pkt_num_spaces[epoch].largest_rx_pkt_num,
9666 hdr.pkt_num,
9667 hdr.pkt_num_len,
9668 );
9669
9670 let mut payload =
9671 packet::decrypt_pkt(&mut b, pn, hdr.pkt_num_len, payload_len, aead)
9672 .unwrap();
9673
9674 let mut frames = Vec::new();
9675
9676 while payload.cap() > 0 {
9677 let frame = frame::Frame::from_bytes(&mut payload, hdr.ty)?;
9678 frames.push(frame);
9679 }
9680
9681 Ok(frames)
9682 }
9683
9684 pub fn create_cid_and_reset_token(
9685 cid_len: usize,
9686 ) -> (ConnectionId<'static>, u128) {
9687 let mut cid = vec![0; cid_len];
9688 rand::rand_bytes(&mut cid[..]);
9689 let cid = ConnectionId::from_ref(&cid).into_owned();
9690
9691 let mut reset_token = [0; 16];
9692 rand::rand_bytes(&mut reset_token);
9693 let reset_token = u128::from_be_bytes(reset_token);
9694
9695 (cid, reset_token)
9696 }
9697
9698 pub fn helper_packet_sent(pkt_num: u64, now: Instant, size: usize) -> Sent {
9699 Sent {
9700 pkt_num,
9701 frames: smallvec![],
9702 time_sent: now,
9703 time_acked: None,
9704 time_lost: None,
9705 size,
9706 ack_eliciting: true,
9707 in_flight: true,
9708 delivered: 0,
9709 delivered_time: now,
9710 first_sent_time: now,
9711 is_app_limited: false,
9712 tx_in_flight: 0,
9713 lost: 0,
9714 has_data: false,
9715 pmtud: false,
9716 }
9717 }
9718}
9719
9720#[cfg(test)]
9721mod tests {
9722 use crate::range_buf::RangeBuf;
9723 use rstest::rstest;
9724
9725 use super::*;
9726
9727 #[test]
9728 fn transport_params() {
9729 let tp = TransportParams {
9731 original_destination_connection_id: None,
9732 max_idle_timeout: 30,
9733 stateless_reset_token: Some(u128::from_be_bytes([0xba; 16])),
9734 max_udp_payload_size: 23_421,
9735 initial_max_data: 424_645_563,
9736 initial_max_stream_data_bidi_local: 154_323_123,
9737 initial_max_stream_data_bidi_remote: 6_587_456,
9738 initial_max_stream_data_uni: 2_461_234,
9739 initial_max_streams_bidi: 12_231,
9740 initial_max_streams_uni: 18_473,
9741 ack_delay_exponent: 20,
9742 max_ack_delay: 2_u64.pow(14) - 1,
9743 disable_active_migration: true,
9744 active_conn_id_limit: 8,
9745 initial_source_connection_id: Some(b"woot woot".to_vec().into()),
9746 retry_source_connection_id: Some(b"retry".to_vec().into()),
9747 max_datagram_frame_size: Some(32),
9748 unknown_params: Default::default(),
9749 };
9750
9751 let mut raw_params = [42; 256];
9752 let raw_params =
9753 TransportParams::encode(&tp, true, &mut raw_params).unwrap();
9754 assert_eq!(raw_params.len(), 94);
9755
9756 let new_tp = TransportParams::decode(raw_params, false, None).unwrap();
9757
9758 assert_eq!(new_tp, tp);
9759
9760 let tp = TransportParams {
9762 original_destination_connection_id: None,
9763 max_idle_timeout: 30,
9764 stateless_reset_token: None,
9765 max_udp_payload_size: 23_421,
9766 initial_max_data: 424_645_563,
9767 initial_max_stream_data_bidi_local: 154_323_123,
9768 initial_max_stream_data_bidi_remote: 6_587_456,
9769 initial_max_stream_data_uni: 2_461_234,
9770 initial_max_streams_bidi: 12_231,
9771 initial_max_streams_uni: 18_473,
9772 ack_delay_exponent: 20,
9773 max_ack_delay: 2_u64.pow(14) - 1,
9774 disable_active_migration: true,
9775 active_conn_id_limit: 8,
9776 initial_source_connection_id: Some(b"woot woot".to_vec().into()),
9777 retry_source_connection_id: None,
9778 max_datagram_frame_size: Some(32),
9779 unknown_params: Default::default(),
9780 };
9781
9782 let mut raw_params = [42; 256];
9783 let raw_params =
9784 TransportParams::encode(&tp, false, &mut raw_params).unwrap();
9785 assert_eq!(raw_params.len(), 69);
9786
9787 let new_tp = TransportParams::decode(raw_params, true, None).unwrap();
9788
9789 assert_eq!(new_tp, tp);
9790 }
9791
9792 #[test]
9793 fn transport_params_forbid_duplicates() {
9794 let initial_source_connection_id = b"id";
9796 let initial_source_connection_id_raw = [
9797 15,
9798 initial_source_connection_id.len() as u8,
9799 initial_source_connection_id[0],
9800 initial_source_connection_id[1],
9801 ];
9802
9803 let tp = TransportParams::decode(
9805 initial_source_connection_id_raw.as_slice(),
9806 true,
9807 None,
9808 )
9809 .unwrap();
9810
9811 assert_eq!(
9812 tp.initial_source_connection_id,
9813 Some(initial_source_connection_id.to_vec().into())
9814 );
9815
9816 let mut raw_params = Vec::new();
9818 raw_params.append(&mut initial_source_connection_id_raw.to_vec());
9819 raw_params.append(&mut initial_source_connection_id_raw.to_vec());
9820
9821 assert_eq!(
9823 TransportParams::decode(raw_params.as_slice(), true, None),
9824 Err(Error::InvalidTransportParam)
9825 );
9826 }
9827
9828 #[test]
9829 fn transport_params_unknown_zero_space() {
9830 let mut unknown_params: UnknownTransportParameters =
9831 UnknownTransportParameters {
9832 capacity: 0,
9833 parameters: vec![],
9834 };
9835 let massive_unknown_param = UnknownTransportParameter::<&[u8]> {
9836 id: 5,
9837 value: &[0xau8; 280],
9838 };
9839 assert!(unknown_params.push(massive_unknown_param).is_err());
9840 assert!(unknown_params.capacity == 0);
9841 assert!(unknown_params.parameters.is_empty());
9842 }
9843
9844 #[test]
9845 fn transport_params_unknown_max_space_respected() {
9846 let mut unknown_params: UnknownTransportParameters =
9847 UnknownTransportParameters {
9848 capacity: 256,
9849 parameters: vec![],
9850 };
9851
9852 let massive_unknown_param = UnknownTransportParameter::<&[u8]> {
9853 id: 5,
9854 value: &[0xau8; 280],
9855 };
9856 let big_unknown_param = UnknownTransportParameter::<&[u8]> {
9857 id: 5,
9858 value: &[0xau8; 232],
9859 };
9860 let little_unknown_param = UnknownTransportParameter::<&[u8]> {
9861 id: 6,
9862 value: &[0xau8; 7],
9863 };
9864
9865 assert!(unknown_params.push(massive_unknown_param).is_err());
9866 assert!(unknown_params.capacity == 256);
9867 assert!(unknown_params.parameters.is_empty());
9868
9869 unknown_params.push(big_unknown_param).unwrap();
9870 assert!(unknown_params.capacity == 16);
9871 assert!(unknown_params.parameters.len() == 1);
9872
9873 unknown_params.push(little_unknown_param.clone()).unwrap();
9874 assert!(unknown_params.capacity == 1);
9875 assert!(unknown_params.parameters.len() == 2);
9876
9877 assert!(unknown_params.push(little_unknown_param).is_err());
9878
9879 let mut unknown_params_iter = unknown_params.into_iter();
9880
9881 let unknown_params_first = unknown_params_iter
9882 .next()
9883 .expect("Should have a 0th element.");
9884 assert!(
9885 unknown_params_first.id == 5 &&
9886 unknown_params_first.value == vec![0xau8; 232]
9887 );
9888
9889 let unknown_params_second = unknown_params_iter
9890 .next()
9891 .expect("Should have a 1th element.");
9892 assert!(
9893 unknown_params_second.id == 6 &&
9894 unknown_params_second.value == vec![0xau8; 7]
9895 );
9896 }
9897
9898 #[test]
9899 fn transport_params_unknown_is_reserved() {
9900 let reserved_unknown_param = UnknownTransportParameter::<&[u8]> {
9901 id: 31 * 17 + 27,
9902 value: &[0xau8; 280],
9903 };
9904 let not_reserved_unknown_param = UnknownTransportParameter::<&[u8]> {
9905 id: 32 * 17 + 27,
9906 value: &[0xau8; 280],
9907 };
9908
9909 assert!(reserved_unknown_param.is_reserved());
9910 assert!(!not_reserved_unknown_param.is_reserved());
9911 }
9912 #[test]
9913 fn unknown_version() {
9914 let mut config = Config::new(0xbabababa).unwrap();
9915 config
9916 .set_application_protos(&[b"proto1", b"proto2"])
9917 .unwrap();
9918 config.verify_peer(false);
9919
9920 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
9921 assert_eq!(pipe.handshake(), Err(Error::UnknownVersion));
9922 }
9923
9924 #[test]
9925 fn config_version_reserved() {
9926 Config::new(0xbabababa).unwrap();
9927 Config::new(0x1a2a3a4a).unwrap();
9928 }
9929
9930 #[test]
9931 fn config_version_invalid() {
9932 assert_eq!(
9933 Config::new(0xb1bababa).err().unwrap(),
9934 Error::UnknownVersion
9935 );
9936 }
9937
9938 #[test]
9939 fn version_negotiation() {
9940 let mut buf = [0; 65535];
9941
9942 let mut config = Config::new(0xbabababa).unwrap();
9943 config
9944 .set_application_protos(&[b"proto1", b"proto2"])
9945 .unwrap();
9946 config.verify_peer(false);
9947
9948 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
9949
9950 let (mut len, _) = pipe.client.send(&mut buf).unwrap();
9951
9952 let hdr = packet::Header::from_slice(&mut buf[..len], 0).unwrap();
9953 len = crate::negotiate_version(&hdr.scid, &hdr.dcid, &mut buf).unwrap();
9954
9955 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
9956
9957 assert_eq!(pipe.handshake(), Ok(()));
9958
9959 assert_eq!(pipe.client.version, PROTOCOL_VERSION);
9960 assert_eq!(pipe.server.version, PROTOCOL_VERSION);
9961 }
9962
9963 #[test]
9964 fn verify_custom_root() {
9965 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
9966 config.verify_peer(true);
9967 config
9968 .load_verify_locations_from_file("examples/rootca.crt")
9969 .unwrap();
9970 config
9971 .set_application_protos(&[b"proto1", b"proto2"])
9972 .unwrap();
9973
9974 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
9975 assert_eq!(pipe.handshake(), Ok(()));
9976 }
9977
9978 #[cfg(not(feature = "openssl"))]
9981 #[test]
9982 fn verify_client_invalid() {
9983 let mut server_config = Config::new(crate::PROTOCOL_VERSION).unwrap();
9984 server_config
9985 .load_cert_chain_from_pem_file("examples/cert.crt")
9986 .unwrap();
9987 server_config
9988 .load_priv_key_from_pem_file("examples/cert.key")
9989 .unwrap();
9990 server_config
9991 .set_application_protos(&[b"proto1", b"proto2"])
9992 .unwrap();
9993 server_config.set_initial_max_data(30);
9994 server_config.set_initial_max_stream_data_bidi_local(15);
9995 server_config.set_initial_max_stream_data_bidi_remote(15);
9996 server_config.set_initial_max_streams_bidi(3);
9997
9998 server_config.verify_peer(true);
10001
10002 let mut client_config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10003 client_config
10004 .load_cert_chain_from_pem_file("examples/cert.crt")
10005 .unwrap();
10006 client_config
10007 .load_priv_key_from_pem_file("examples/cert.key")
10008 .unwrap();
10009 client_config
10010 .set_application_protos(&[b"proto1", b"proto2"])
10011 .unwrap();
10012 client_config.set_initial_max_data(30);
10013 client_config.set_initial_max_stream_data_bidi_local(15);
10014 client_config.set_initial_max_stream_data_bidi_remote(15);
10015 client_config.set_initial_max_streams_bidi(3);
10016
10017 client_config
10020 .load_verify_locations_from_file("examples/rootca.crt")
10021 .unwrap();
10022 client_config.verify_peer(true);
10023
10024 let mut pipe = testing::Pipe::with_client_and_server_config(
10025 &mut client_config,
10026 &mut server_config,
10027 )
10028 .unwrap();
10029 assert_eq!(pipe.handshake(), Err(Error::TlsFail));
10030
10031 assert!(pipe.server.peer_cert().is_some());
10033 }
10034
10035 #[test]
10036 fn verify_client_anonymous() {
10037 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10038 config
10039 .load_cert_chain_from_pem_file("examples/cert.crt")
10040 .unwrap();
10041 config
10042 .load_priv_key_from_pem_file("examples/cert.key")
10043 .unwrap();
10044 config
10045 .set_application_protos(&[b"proto1", b"proto2"])
10046 .unwrap();
10047 config.set_initial_max_data(30);
10048 config.set_initial_max_stream_data_bidi_local(15);
10049 config.set_initial_max_stream_data_bidi_remote(15);
10050 config.set_initial_max_streams_bidi(3);
10051
10052 config.verify_peer(true);
10054
10055 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
10056 assert_eq!(pipe.handshake(), Ok(()));
10057
10058 assert!(pipe.server.peer_cert().is_none());
10060 }
10061
10062 #[rstest]
10063 fn missing_initial_source_connection_id(
10064 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10065 ) {
10066 let mut buf = [0; 65535];
10067
10068 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10069
10070 pipe.client
10072 .local_transport_params
10073 .initial_source_connection_id = None;
10074 assert_eq!(pipe.client.encode_transport_params(), Ok(()));
10075
10076 let (len, _) = pipe.client.send(&mut buf).unwrap();
10078
10079 assert_eq!(
10081 pipe.server_recv(&mut buf[..len]),
10082 Err(Error::InvalidTransportParam)
10083 );
10084 }
10085
10086 #[rstest]
10087 fn invalid_initial_source_connection_id(
10088 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10089 ) {
10090 let mut buf = [0; 65535];
10091
10092 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10093
10094 pipe.client
10096 .local_transport_params
10097 .initial_source_connection_id = Some(b"bogus value".to_vec().into());
10098 assert_eq!(pipe.client.encode_transport_params(), Ok(()));
10099
10100 let (len, _) = pipe.client.send(&mut buf).unwrap();
10102
10103 assert_eq!(
10105 pipe.server_recv(&mut buf[..len]),
10106 Err(Error::InvalidTransportParam)
10107 );
10108 }
10109
10110 #[rstest]
10111 fn change_idle_timeout(
10112 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10113 ) {
10114 let mut config = Config::new(0x1).unwrap();
10115 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10116 config
10117 .set_application_protos(&[b"proto1", b"proto2"])
10118 .unwrap();
10119 config.set_max_idle_timeout(999999);
10120 config.verify_peer(false);
10121
10122 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
10123 assert_eq!(pipe.client.local_transport_params.max_idle_timeout, 999999);
10124 assert_eq!(pipe.client.peer_transport_params.max_idle_timeout, 0);
10125 assert_eq!(pipe.server.local_transport_params.max_idle_timeout, 0);
10126 assert_eq!(pipe.server.peer_transport_params.max_idle_timeout, 0);
10127
10128 pipe.client.set_max_idle_timeout(456000).unwrap();
10129 pipe.server.set_max_idle_timeout(234000).unwrap();
10130 assert_eq!(pipe.client.local_transport_params.max_idle_timeout, 456000);
10131 assert_eq!(pipe.client.peer_transport_params.max_idle_timeout, 0);
10132 assert_eq!(pipe.server.local_transport_params.max_idle_timeout, 234000);
10133 assert_eq!(pipe.server.peer_transport_params.max_idle_timeout, 0);
10134
10135 assert_eq!(pipe.handshake(), Ok(()));
10136
10137 assert_eq!(
10138 pipe.client.idle_timeout(),
10139 Some(time::Duration::from_millis(234000))
10140 );
10141 assert_eq!(
10142 pipe.server.idle_timeout(),
10143 Some(time::Duration::from_millis(234000))
10144 );
10145 }
10146
10147 #[rstest]
10148 fn handshake(
10149 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10150 ) {
10151 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10152 assert_eq!(pipe.handshake(), Ok(()));
10153
10154 assert_eq!(
10155 pipe.client.application_proto(),
10156 pipe.server.application_proto()
10157 );
10158
10159 assert_eq!(pipe.server.server_name(), Some("quic.tech"));
10160 }
10161
10162 #[rstest]
10163 fn handshake_done(
10164 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10165 ) {
10166 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10167
10168 pipe.server.handshake.set_options(0x0000_4000);
10171
10172 assert_eq!(pipe.handshake(), Ok(()));
10173
10174 assert!(pipe.server.handshake_done_sent);
10175 }
10176
10177 #[rstest]
10178 fn handshake_confirmation(
10179 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10180 ) {
10181 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10182
10183 let flight = testing::emit_flight(&mut pipe.client).unwrap();
10185 testing::process_flight(&mut pipe.server, flight).unwrap();
10186
10187 let flight = testing::emit_flight(&mut pipe.server).unwrap();
10189
10190 assert!(!pipe.client.is_established());
10191 assert!(!pipe.client.handshake_confirmed);
10192
10193 assert!(!pipe.server.is_established());
10194 assert!(!pipe.server.handshake_confirmed);
10195
10196 testing::process_flight(&mut pipe.client, flight).unwrap();
10197
10198 let flight = testing::emit_flight(&mut pipe.client).unwrap();
10200
10201 assert!(pipe.client.is_established());
10202 assert!(!pipe.client.handshake_confirmed);
10203
10204 assert!(!pipe.server.is_established());
10205 assert!(!pipe.server.handshake_confirmed);
10206
10207 testing::process_flight(&mut pipe.server, flight).unwrap();
10208
10209 let flight = testing::emit_flight(&mut pipe.server).unwrap();
10211
10212 assert!(pipe.client.is_established());
10213 assert!(!pipe.client.handshake_confirmed);
10214
10215 assert!(pipe.server.is_established());
10216 assert!(pipe.server.handshake_confirmed);
10217
10218 testing::process_flight(&mut pipe.client, flight).unwrap();
10219
10220 let flight = testing::emit_flight(&mut pipe.client).unwrap();
10222
10223 assert!(pipe.client.is_established());
10224 assert!(pipe.client.handshake_confirmed);
10225
10226 assert!(pipe.server.is_established());
10227 assert!(pipe.server.handshake_confirmed);
10228
10229 testing::process_flight(&mut pipe.server, flight).unwrap();
10230
10231 assert!(pipe.client.is_established());
10232 assert!(pipe.client.handshake_confirmed);
10233
10234 assert!(pipe.server.is_established());
10235 assert!(pipe.server.handshake_confirmed);
10236 }
10237
10238 #[rstest]
10239 fn handshake_resumption(
10240 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10241 ) {
10242 #[cfg(not(feature = "openssl"))]
10243 const SESSION_TICKET_KEY: [u8; 48] = [0xa; 48];
10244
10245 #[cfg(feature = "openssl")]
10249 const SESSION_TICKET_KEY: [u8; 80] = [0xa; 80];
10250
10251 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10252 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10253
10254 config
10255 .load_cert_chain_from_pem_file("examples/cert.crt")
10256 .unwrap();
10257 config
10258 .load_priv_key_from_pem_file("examples/cert.key")
10259 .unwrap();
10260 config
10261 .set_application_protos(&[b"proto1", b"proto2"])
10262 .unwrap();
10263 config.set_initial_max_data(30);
10264 config.set_initial_max_stream_data_bidi_local(15);
10265 config.set_initial_max_stream_data_bidi_remote(15);
10266 config.set_initial_max_streams_bidi(3);
10267 config.set_ticket_key(&SESSION_TICKET_KEY).unwrap();
10268
10269 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
10271 assert_eq!(pipe.handshake(), Ok(()));
10272
10273 assert!(pipe.client.is_established());
10274 assert!(pipe.server.is_established());
10275
10276 assert!(!pipe.client.is_resumed());
10277 assert!(!pipe.server.is_resumed());
10278
10279 let session = pipe.client.session().unwrap();
10281
10282 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10284 config
10285 .load_cert_chain_from_pem_file("examples/cert.crt")
10286 .unwrap();
10287 config
10288 .load_priv_key_from_pem_file("examples/cert.key")
10289 .unwrap();
10290 config
10291 .set_application_protos(&[b"proto1", b"proto2"])
10292 .unwrap();
10293 config.set_initial_max_data(30);
10294 config.set_initial_max_stream_data_bidi_local(15);
10295 config.set_initial_max_stream_data_bidi_remote(15);
10296 config.set_initial_max_streams_bidi(3);
10297 config.set_ticket_key(&SESSION_TICKET_KEY).unwrap();
10298
10299 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
10300
10301 assert_eq!(pipe.client.set_session(session), Ok(()));
10302 assert_eq!(pipe.handshake(), Ok(()));
10303
10304 assert!(pipe.client.is_established());
10305 assert!(pipe.server.is_established());
10306
10307 assert!(pipe.client.is_resumed());
10308 assert!(pipe.server.is_resumed());
10309 }
10310
10311 #[rstest]
10312 fn handshake_alpn_mismatch(
10313 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10314 ) {
10315 let mut buf = [0; 65535];
10316
10317 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
10318 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10319 config
10320 .set_application_protos(&[b"proto3\x06proto4"])
10321 .unwrap();
10322 config.verify_peer(false);
10323
10324 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
10325 assert_eq!(pipe.handshake(), Err(Error::TlsFail));
10326
10327 assert_eq!(pipe.client.application_proto(), b"");
10328 assert_eq!(pipe.server.application_proto(), b"");
10329
10330 let (len, _) = pipe.server.send(&mut buf).unwrap();
10332 assert_eq!(len, 1200);
10333
10334 assert_eq!(pipe.server.send(&mut buf), Err(Error::Done));
10335 assert_eq!(pipe.server.sent_count, 1);
10336 }
10337
10338 #[cfg(not(feature = "openssl"))] #[rstest]
10340 fn handshake_0rtt(
10341 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10342 ) {
10343 let mut buf = [0; 65535];
10344
10345 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10346 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10347 config
10348 .load_cert_chain_from_pem_file("examples/cert.crt")
10349 .unwrap();
10350 config
10351 .load_priv_key_from_pem_file("examples/cert.key")
10352 .unwrap();
10353 config
10354 .set_application_protos(&[b"proto1", b"proto2"])
10355 .unwrap();
10356 config.set_initial_max_data(30);
10357 config.set_initial_max_stream_data_bidi_local(15);
10358 config.set_initial_max_stream_data_bidi_remote(15);
10359 config.set_initial_max_streams_bidi(3);
10360 config.enable_early_data();
10361 config.verify_peer(false);
10362
10363 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10365 assert_eq!(pipe.handshake(), Ok(()));
10366
10367 let session = pipe.client.session().unwrap();
10369
10370 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10372 assert_eq!(pipe.client.set_session(session), Ok(()));
10373
10374 let (len, _) = pipe.client.send(&mut buf).unwrap();
10376 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
10377
10378 let pkt_type = packet::Type::ZeroRTT;
10380
10381 let frames = [frame::Frame::Stream {
10382 stream_id: 4,
10383 data: <RangeBuf>::from(b"aaaaa", 0, true),
10384 }];
10385
10386 assert_eq!(
10387 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
10388 Ok(1200)
10389 );
10390
10391 assert_eq!(pipe.server.undecryptable_pkts.len(), 0);
10392
10393 let mut r = pipe.server.readable();
10395 assert_eq!(r.next(), Some(4));
10396 assert_eq!(r.next(), None);
10397
10398 let mut b = [0; 15];
10399 assert_eq!(pipe.server.stream_recv(4, &mut b), Ok((5, true)));
10400 assert_eq!(&b[..5], b"aaaaa");
10401 }
10402
10403 #[cfg(not(feature = "openssl"))] #[rstest]
10405 fn handshake_0rtt_reordered(
10406 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10407 ) {
10408 let mut buf = [0; 65535];
10409
10410 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10411 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10412 config
10413 .load_cert_chain_from_pem_file("examples/cert.crt")
10414 .unwrap();
10415 config
10416 .load_priv_key_from_pem_file("examples/cert.key")
10417 .unwrap();
10418 config
10419 .set_application_protos(&[b"proto1", b"proto2"])
10420 .unwrap();
10421 config.set_initial_max_data(30);
10422 config.set_initial_max_stream_data_bidi_local(15);
10423 config.set_initial_max_stream_data_bidi_remote(15);
10424 config.set_initial_max_streams_bidi(3);
10425 config.enable_early_data();
10426 config.verify_peer(false);
10427
10428 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10430 assert_eq!(pipe.handshake(), Ok(()));
10431
10432 let session = pipe.client.session().unwrap();
10434
10435 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10437 assert_eq!(pipe.client.set_session(session), Ok(()));
10438
10439 let (len, _) = pipe.client.send(&mut buf).unwrap();
10441 let mut initial = buf[..len].to_vec();
10442
10443 let pkt_type = packet::Type::ZeroRTT;
10445
10446 let frames = [frame::Frame::Stream {
10447 stream_id: 4,
10448 data: <RangeBuf>::from(b"aaaaa", 0, true),
10449 }];
10450
10451 let len =
10452 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
10453 .unwrap();
10454 let mut zrtt = buf[..len].to_vec();
10455
10456 assert_eq!(pipe.server_recv(&mut zrtt), Ok(zrtt.len()));
10458
10459 assert_eq!(pipe.server.undecryptable_pkts.len(), 1);
10460 assert_eq!(pipe.server.undecryptable_pkts[0].0.len(), zrtt.len());
10461
10462 let mut r = pipe.server.readable();
10463 assert_eq!(r.next(), None);
10464
10465 assert_eq!(pipe.server_recv(&mut initial), Ok(initial.len()));
10467
10468 let mut r = pipe.server.readable();
10470 assert_eq!(r.next(), Some(4));
10471 assert_eq!(r.next(), None);
10472
10473 let mut b = [0; 15];
10474 assert_eq!(pipe.server.stream_recv(4, &mut b), Ok((5, true)));
10475 assert_eq!(&b[..5], b"aaaaa");
10476 }
10477
10478 #[cfg(not(feature = "openssl"))] #[rstest]
10480 fn handshake_0rtt_truncated(
10481 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10482 ) {
10483 let mut buf = [0; 65535];
10484
10485 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10486 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10487 config
10488 .load_cert_chain_from_pem_file("examples/cert.crt")
10489 .unwrap();
10490 config
10491 .load_priv_key_from_pem_file("examples/cert.key")
10492 .unwrap();
10493 config
10494 .set_application_protos(&[b"proto1", b"proto2"])
10495 .unwrap();
10496 config.set_initial_max_data(30);
10497 config.set_initial_max_stream_data_bidi_local(15);
10498 config.set_initial_max_stream_data_bidi_remote(15);
10499 config.set_initial_max_streams_bidi(3);
10500 config.enable_early_data();
10501 config.verify_peer(false);
10502
10503 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10505 assert_eq!(pipe.handshake(), Ok(()));
10506
10507 let session = pipe.client.session().unwrap();
10509
10510 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10512 assert_eq!(pipe.client.set_session(session), Ok(()));
10513
10514 pipe.client.send(&mut buf).unwrap();
10516
10517 let pkt_type = packet::Type::ZeroRTT;
10519
10520 let frames = [frame::Frame::Stream {
10521 stream_id: 4,
10522 data: <RangeBuf>::from(b"aaaaa", 0, true),
10523 }];
10524
10525 let len =
10526 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
10527 .unwrap();
10528
10529 let mut zrtt = buf[..len - 1].to_vec();
10531
10532 assert_eq!(pipe.server_recv(&mut zrtt), Err(Error::InvalidPacket));
10534
10535 assert_eq!(pipe.server.undecryptable_pkts.len(), 0);
10536
10537 assert!(pipe.server.is_closed());
10538 }
10539
10540 #[rstest]
10541 fn crypto_limit(
10542 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10543 ) {
10544 let mut buf = [0; 65535];
10545
10546 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10547 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10548 config
10549 .load_cert_chain_from_pem_file("examples/cert.crt")
10550 .unwrap();
10551 config
10552 .load_priv_key_from_pem_file("examples/cert.key")
10553 .unwrap();
10554 config
10555 .set_application_protos(&[b"proto1", b"proto2"])
10556 .unwrap();
10557 config.set_initial_max_data(30);
10558 config.set_initial_max_stream_data_bidi_local(15);
10559 config.set_initial_max_stream_data_bidi_remote(15);
10560 config.set_initial_max_streams_bidi(3);
10561 config.enable_early_data();
10562 config.verify_peer(false);
10563
10564 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10566 assert_eq!(pipe.handshake(), Ok(()));
10567
10568 let frames = [frame::Frame::Crypto {
10571 data: RangeBuf::from(b"a", MAX_CRYPTO_STREAM_OFFSET, false),
10572 }];
10573
10574 let pkt_type = packet::Type::Short;
10575
10576 let written =
10577 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
10578 .unwrap();
10579
10580 let active_path = pipe.server.paths.get_active().unwrap();
10581 let info = RecvInfo {
10582 to: active_path.local_addr(),
10583 from: active_path.peer_addr(),
10584 };
10585
10586 assert_eq!(
10587 pipe.server.recv(&mut buf[..written], info),
10588 Err(Error::CryptoBufferExceeded)
10589 );
10590
10591 let written = match pipe.server.send(&mut buf) {
10592 Ok((write, _)) => write,
10593
10594 Err(_) => unreachable!(),
10595 };
10596
10597 let frames =
10598 testing::decode_pkt(&mut pipe.client, &mut buf[..written]).unwrap();
10599 let mut iter = frames.iter();
10600
10601 assert_eq!(
10602 iter.next(),
10603 Some(&frame::Frame::ConnectionClose {
10604 error_code: 0x0d,
10605 frame_type: 0,
10606 reason: Vec::new(),
10607 })
10608 );
10609 }
10610
10611 #[rstest]
10612 fn limit_handshake_data(
10613 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10614 ) {
10615 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
10616 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10617 config
10618 .load_cert_chain_from_pem_file("examples/cert-big.crt")
10619 .unwrap();
10620 config
10621 .load_priv_key_from_pem_file("examples/cert.key")
10622 .unwrap();
10623 config
10624 .set_application_protos(&[b"proto1", b"proto2"])
10625 .unwrap();
10626
10627 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
10628
10629 let flight = testing::emit_flight(&mut pipe.client).unwrap();
10630 let client_sent = flight.iter().fold(0, |out, p| out + p.0.len());
10631 testing::process_flight(&mut pipe.server, flight).unwrap();
10632
10633 let flight = testing::emit_flight(&mut pipe.server).unwrap();
10634 let server_sent = flight.iter().fold(0, |out, p| out + p.0.len());
10635
10636 assert_eq!(server_sent, client_sent * MAX_AMPLIFICATION_FACTOR);
10637 }
10638
10639 #[rstest]
10640 fn custom_limit_handshake_data(
10641 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10642 ) {
10643 const CUSTOM_AMPLIFICATION_FACTOR: usize = 2;
10644
10645 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
10646 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10647 config
10648 .load_cert_chain_from_pem_file("examples/cert-big.crt")
10649 .unwrap();
10650 config
10651 .load_priv_key_from_pem_file("examples/cert.key")
10652 .unwrap();
10653 config
10654 .set_application_protos(&[b"proto1", b"proto2"])
10655 .unwrap();
10656 config.set_max_amplification_factor(CUSTOM_AMPLIFICATION_FACTOR);
10657
10658 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
10659
10660 let flight = testing::emit_flight(&mut pipe.client).unwrap();
10661 let client_sent = flight.iter().fold(0, |out, p| out + p.0.len());
10662 testing::process_flight(&mut pipe.server, flight).unwrap();
10663
10664 let flight = testing::emit_flight(&mut pipe.server).unwrap();
10665 let server_sent = flight.iter().fold(0, |out, p| out + p.0.len());
10666
10667 assert_eq!(server_sent, client_sent * CUSTOM_AMPLIFICATION_FACTOR);
10668 }
10669
10670 #[rstest]
10671 fn streamio(
10672 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10673 ) {
10674 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10675 assert_eq!(pipe.handshake(), Ok(()));
10676
10677 assert_eq!(pipe.client.stream_send(4, b"hello, world", true), Ok(12));
10678 assert_eq!(pipe.advance(), Ok(()));
10679
10680 assert!(!pipe.server.stream_finished(4));
10681
10682 let mut r = pipe.server.readable();
10683 assert_eq!(r.next(), Some(4));
10684 assert_eq!(r.next(), None);
10685
10686 let mut b = [0; 15];
10687 assert_eq!(pipe.server.stream_recv(4, &mut b), Ok((12, true)));
10688 assert_eq!(&b[..12], b"hello, world");
10689
10690 assert!(pipe.server.stream_finished(4));
10691 }
10692
10693 #[cfg(not(feature = "openssl"))] #[rstest]
10695 fn zero_rtt(
10696 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10697 ) {
10698 let mut buf = [0; 65535];
10699
10700 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10701 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10702 config
10703 .load_cert_chain_from_pem_file("examples/cert.crt")
10704 .unwrap();
10705 config
10706 .load_priv_key_from_pem_file("examples/cert.key")
10707 .unwrap();
10708 config
10709 .set_application_protos(&[b"proto1", b"proto2"])
10710 .unwrap();
10711 config.set_initial_max_data(30);
10712 config.set_initial_max_stream_data_bidi_local(15);
10713 config.set_initial_max_stream_data_bidi_remote(15);
10714 config.set_initial_max_streams_bidi(3);
10715 config.enable_early_data();
10716 config.verify_peer(false);
10717
10718 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10720 assert_eq!(pipe.handshake(), Ok(()));
10721
10722 let session = pipe.client.session().unwrap();
10724
10725 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10727 assert_eq!(pipe.client.set_session(session), Ok(()));
10728
10729 let (len, _) = pipe.client.send(&mut buf).unwrap();
10731 let mut initial = buf[..len].to_vec();
10732
10733 assert!(pipe.client.is_in_early_data());
10734
10735 assert_eq!(pipe.client.stream_send(4, b"hello, world", true), Ok(12));
10737
10738 let (len, _) = pipe.client.send(&mut buf).unwrap();
10739 let mut zrtt = buf[..len].to_vec();
10740
10741 assert_eq!(pipe.server_recv(&mut initial), Ok(initial.len()));
10743 assert!(pipe.server.is_in_early_data());
10744
10745 assert_eq!(pipe.server_recv(&mut zrtt), Ok(zrtt.len()));
10746
10747 let mut r = pipe.server.readable();
10749 assert_eq!(r.next(), Some(4));
10750 assert_eq!(r.next(), None);
10751
10752 let mut b = [0; 15];
10753 assert_eq!(pipe.server.stream_recv(4, &mut b), Ok((12, true)));
10754 assert_eq!(&b[..12], b"hello, world");
10755 }
10756
10757 #[rstest]
10758 fn stream_send_on_32bit_arch(
10759 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10760 ) {
10761 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
10762 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
10763 config
10764 .load_cert_chain_from_pem_file("examples/cert.crt")
10765 .unwrap();
10766 config
10767 .load_priv_key_from_pem_file("examples/cert.key")
10768 .unwrap();
10769 config
10770 .set_application_protos(&[b"proto1", b"proto2"])
10771 .unwrap();
10772 config.set_initial_max_data(2_u64.pow(32) + 5);
10773 config.set_initial_max_stream_data_bidi_local(15);
10774 config.set_initial_max_stream_data_bidi_remote(15);
10775 config.set_initial_max_stream_data_uni(10);
10776 config.set_initial_max_streams_bidi(3);
10777 config.set_initial_max_streams_uni(0);
10778 config.verify_peer(false);
10779
10780 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
10781 assert_eq!(pipe.handshake(), Ok(()));
10782
10783 assert_eq!(pipe.client.stream_send(4, b"hello, world", true), Ok(12));
10786
10787 assert_eq!(pipe.advance(), Ok(()));
10788
10789 assert!(!pipe.server.stream_finished(4));
10790 }
10791
10792 #[rstest]
10793 fn empty_stream_frame(
10794 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10795 ) {
10796 let mut buf = [0; 65535];
10797
10798 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10799 assert_eq!(pipe.handshake(), Ok(()));
10800
10801 let frames = [frame::Frame::Stream {
10802 stream_id: 4,
10803 data: <RangeBuf>::from(b"aaaaa", 0, false),
10804 }];
10805
10806 let pkt_type = packet::Type::Short;
10807 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(39));
10808
10809 let mut readable = pipe.server.readable();
10810 assert_eq!(readable.next(), Some(4));
10811
10812 assert_eq!(pipe.server.stream_recv(4, &mut buf), Ok((5, false)));
10813
10814 let frames = [frame::Frame::Stream {
10815 stream_id: 4,
10816 data: <RangeBuf>::from(b"", 5, true),
10817 }];
10818
10819 let pkt_type = packet::Type::Short;
10820 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(39));
10821
10822 let mut readable = pipe.server.readable();
10823 assert_eq!(readable.next(), Some(4));
10824
10825 assert_eq!(pipe.server.stream_recv(4, &mut buf), Ok((0, true)));
10826
10827 let frames = [frame::Frame::Stream {
10828 stream_id: 4,
10829 data: <RangeBuf>::from(b"", 15, true),
10830 }];
10831
10832 let pkt_type = packet::Type::Short;
10833 assert_eq!(
10834 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
10835 Err(Error::FinalSize)
10836 );
10837 }
10838
10839 #[rstest]
10840 fn update_key_request(
10841 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10842 ) {
10843 let mut b = [0; 15];
10844
10845 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10846 assert_eq!(pipe.handshake(), Ok(()));
10847 assert_eq!(pipe.advance(), Ok(()));
10848
10849 assert_eq!(pipe.client_update_key(), Ok(()));
10851 assert_eq!(pipe.client.stream_send(4, b"hello", false), Ok(5));
10852 assert_eq!(pipe.advance(), Ok(()));
10853
10854 let mut r = pipe.server.readable();
10856 assert_eq!(r.next(), Some(4));
10857 assert_eq!(r.next(), None);
10858 assert_eq!(pipe.server.stream_recv(4, &mut b), Ok((5, false)));
10859 assert_eq!(&b[..5], b"hello");
10860
10861 assert!(
10863 pipe.server.crypto_ctx[packet::Epoch::Application]
10864 .key_update
10865 .as_ref()
10866 .unwrap()
10867 .update_acked
10868 );
10869
10870 assert_eq!(pipe.server.stream_send(4, b"world", false), Ok(5));
10872 assert_eq!(pipe.advance(), Ok(()));
10873
10874 let mut r = pipe.client.readable();
10876 assert_eq!(r.next(), Some(4));
10877 assert_eq!(r.next(), None);
10878 assert_eq!(pipe.client.stream_recv(4, &mut b), Ok((5, false)));
10879 assert_eq!(&b[..5], b"world");
10880
10881 for _ in 0..10 {
10883 assert_eq!(pipe.server.stream_send(4, b"world", false), Ok(5));
10884 assert_eq!(pipe.advance(), Ok(()));
10885
10886 let mut r = pipe.client.readable();
10887 assert_eq!(r.next(), Some(4));
10888 assert_eq!(r.next(), None);
10889 assert_eq!(pipe.client.stream_recv(4, &mut b), Ok((5, false)));
10890 assert_eq!(&b[..5], b"world");
10891 }
10892 }
10893
10894 #[rstest]
10895 fn update_key_request_twice_error(
10896 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10897 ) {
10898 let mut buf = [0; 65535];
10899
10900 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10901 assert_eq!(pipe.handshake(), Ok(()));
10902 assert_eq!(pipe.advance(), Ok(()));
10903
10904 let frames = [frame::Frame::Stream {
10905 stream_id: 4,
10906 data: <RangeBuf>::from(b"hello", 0, false),
10907 }];
10908
10909 assert_eq!(pipe.client_update_key(), Ok(()));
10911 let written = testing::encode_pkt(
10912 &mut pipe.client,
10913 packet::Type::Short,
10914 &frames,
10915 &mut buf,
10916 )
10917 .unwrap();
10918
10919 assert_eq!(pipe.server_recv(&mut buf[..written]), Ok(written));
10921
10922 assert_eq!(pipe.client_update_key(), Ok(()));
10925 let written = testing::encode_pkt(
10926 &mut pipe.client,
10927 packet::Type::Short,
10928 &frames,
10929 &mut buf,
10930 )
10931 .unwrap();
10932
10933 assert_eq!(pipe.server_recv(&mut buf[..written]), Err(Error::KeyUpdate));
10936 }
10937
10938 #[rstest]
10939 fn max_stream_data_receive_uni(
10942 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10943 ) {
10944 let mut buf = [0; 65535];
10945
10946 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10947 assert_eq!(pipe.handshake(), Ok(()));
10948
10949 assert_eq!(pipe.client.stream_send(2, b"hello", false), Ok(5));
10951 assert_eq!(pipe.advance(), Ok(()));
10952
10953 let frames = [frame::Frame::MaxStreamData {
10955 stream_id: 2,
10956 max: 1024,
10957 }];
10958
10959 let pkt_type = packet::Type::Short;
10960 assert_eq!(
10961 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
10962 Err(Error::InvalidStreamState(2)),
10963 );
10964 }
10965
10966 #[rstest]
10967 fn empty_payload(
10968 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10969 ) {
10970 let mut buf = [0; 65535];
10971
10972 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10973 assert_eq!(pipe.handshake(), Ok(()));
10974
10975 let pkt_type = packet::Type::Short;
10977 assert_eq!(
10978 pipe.send_pkt_to_server(pkt_type, &[], &mut buf),
10979 Err(Error::InvalidPacket)
10980 );
10981 }
10982
10983 #[rstest]
10984 fn min_payload(
10985 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
10986 ) {
10987 let mut buf = [0; 65535];
10988
10989 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
10990
10991 let frames = [frame::Frame::Padding { len: 4 }];
10993
10994 let pkt_type = packet::Type::Initial;
10995 let written =
10996 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
10997 .unwrap();
10998 assert_eq!(pipe.server_recv(&mut buf[..written]), Ok(written));
10999
11000 let initial_path = pipe
11001 .server
11002 .paths
11003 .get_active()
11004 .expect("initial path not found");
11005
11006 assert_eq!(initial_path.max_send_bytes, 195);
11007
11008 pipe.server
11010 .paths
11011 .get_active_mut()
11012 .expect("no active path")
11013 .recovery
11014 .inc_loss_probes(packet::Epoch::Initial);
11015
11016 let initial_path = pipe
11017 .server
11018 .paths
11019 .get_active_mut()
11020 .expect("initial path not found");
11021
11022 initial_path.max_send_bytes = 60;
11024
11025 assert_eq!(pipe.server.send(&mut buf), Err(Error::Done));
11026 }
11027
11028 #[rstest]
11029 fn flow_control_limit(
11030 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11031 ) {
11032 let mut buf = [0; 65535];
11033
11034 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11035 assert_eq!(pipe.handshake(), Ok(()));
11036
11037 let frames = [
11038 frame::Frame::Stream {
11039 stream_id: 0,
11040 data: <RangeBuf>::from(b"aaaaaaaaaaaaaaa", 0, false),
11041 },
11042 frame::Frame::Stream {
11043 stream_id: 4,
11044 data: <RangeBuf>::from(b"aaaaaaaaaaaaaaa", 0, false),
11045 },
11046 frame::Frame::Stream {
11047 stream_id: 8,
11048 data: <RangeBuf>::from(b"a", 0, false),
11049 },
11050 ];
11051
11052 let pkt_type = packet::Type::Short;
11053 assert_eq!(
11054 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11055 Err(Error::FlowControl),
11056 );
11057 }
11058
11059 #[rstest]
11060 fn flow_control_limit_dup(
11061 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11062 ) {
11063 let mut buf = [0; 65535];
11064
11065 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11066 assert_eq!(pipe.handshake(), Ok(()));
11067
11068 let frames = [
11069 frame::Frame::Stream {
11071 stream_id: 0,
11072 data: <RangeBuf>::from(b"aaaaaaaaaaaaaa", 0, false),
11073 },
11074 frame::Frame::Stream {
11076 stream_id: 0,
11077 data: <RangeBuf>::from(b"aaaaaaaaaaaaaaa", 0, false),
11078 },
11079 frame::Frame::Stream {
11080 stream_id: 8,
11081 data: <RangeBuf>::from(b"aaaaaaaaaaaaaaa", 0, false),
11082 },
11083 ];
11084
11085 let pkt_type = packet::Type::Short;
11086 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11087 }
11088
11089 #[rstest]
11090 fn flow_control_update(
11091 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11092 ) {
11093 let mut buf = [0; 65535];
11094
11095 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11096 assert_eq!(pipe.handshake(), Ok(()));
11097
11098 let frames = [
11099 frame::Frame::Stream {
11100 stream_id: 0,
11101 data: <RangeBuf>::from(b"aaaaaaaaaaaaaaa", 0, false),
11102 },
11103 frame::Frame::Stream {
11104 stream_id: 4,
11105 data: <RangeBuf>::from(b"a", 0, false),
11106 },
11107 ];
11108
11109 let pkt_type = packet::Type::Short;
11110
11111 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11112
11113 pipe.server.stream_recv(0, &mut buf).unwrap();
11114 pipe.server.stream_recv(4, &mut buf).unwrap();
11115
11116 let frames = [frame::Frame::Stream {
11117 stream_id: 4,
11118 data: <RangeBuf>::from(b"a", 1, false),
11119 }];
11120
11121 let len = pipe
11122 .send_pkt_to_server(pkt_type, &frames, &mut buf)
11123 .unwrap();
11124
11125 assert!(len > 0);
11126
11127 let frames =
11128 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
11129 let mut iter = frames.iter();
11130
11131 iter.next().unwrap();
11133
11134 assert_eq!(
11135 iter.next(),
11136 Some(&frame::Frame::MaxStreamData {
11137 stream_id: 0,
11138 max: 30
11139 })
11140 );
11141 assert_eq!(iter.next(), Some(&frame::Frame::MaxData { max: 61 }));
11142 }
11143
11144 #[rstest]
11145 fn flow_control_drain(
11148 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11149 ) {
11150 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11151 assert_eq!(pipe.handshake(), Ok(()));
11152
11153 assert_eq!(pipe.client.stream_send(4, b"aaaaa", false), Ok(5));
11155 assert_eq!(pipe.advance(), Ok(()));
11156
11157 let mut r = pipe.server.readable();
11159 assert_eq!(r.next(), Some(4));
11160 assert_eq!(r.next(), None);
11161
11162 assert_eq!(pipe.client.stream_send(4, b"aaaaa", false), Ok(5));
11164 assert_eq!(pipe.client.stream_send(4, b"aaaaa", true), Ok(5));
11165
11166 assert_eq!(pipe.client.stream_send(8, b"aaaaa", false), Ok(5));
11167 assert_eq!(pipe.client.stream_send(8, b"aaaaa", false), Ok(5));
11168 assert_eq!(pipe.client.stream_send(8, b"aaaaa", true), Ok(5));
11169
11170 assert_eq!(pipe.server.stream_shutdown(4, Shutdown::Read, 42), Ok(()));
11172
11173 let mut r = pipe.server.readable();
11174 assert_eq!(r.next(), None);
11175
11176 assert_eq!(pipe.advance(), Ok(()));
11178 }
11179
11180 #[rstest]
11181 fn stream_flow_control_limit_bidi(
11182 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11183 ) {
11184 let mut buf = [0; 65535];
11185
11186 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11187 assert_eq!(pipe.handshake(), Ok(()));
11188
11189 let frames = [frame::Frame::Stream {
11190 stream_id: 4,
11191 data: <RangeBuf>::from(b"aaaaaaaaaaaaaaaa", 0, true),
11192 }];
11193
11194 let pkt_type = packet::Type::Short;
11195 assert_eq!(
11196 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11197 Err(Error::FlowControl),
11198 );
11199 }
11200
11201 #[rstest]
11202 fn stream_flow_control_limit_uni(
11203 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11204 ) {
11205 let mut buf = [0; 65535];
11206
11207 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11208 assert_eq!(pipe.handshake(), Ok(()));
11209
11210 let frames = [frame::Frame::Stream {
11211 stream_id: 2,
11212 data: <RangeBuf>::from(b"aaaaaaaaaaa", 0, true),
11213 }];
11214
11215 let pkt_type = packet::Type::Short;
11216 assert_eq!(
11217 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11218 Err(Error::FlowControl),
11219 );
11220 }
11221
11222 #[rstest]
11223 fn stream_flow_control_update(
11224 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11225 ) {
11226 let mut buf = [0; 65535];
11227
11228 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11229 assert_eq!(pipe.handshake(), Ok(()));
11230
11231 let frames = [frame::Frame::Stream {
11232 stream_id: 4,
11233 data: <RangeBuf>::from(b"aaaaaaaaa", 0, false),
11234 }];
11235
11236 let pkt_type = packet::Type::Short;
11237
11238 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11239
11240 pipe.server.stream_recv(4, &mut buf).unwrap();
11241
11242 let frames = [frame::Frame::Stream {
11243 stream_id: 4,
11244 data: <RangeBuf>::from(b"a", 9, false),
11245 }];
11246
11247 let len = pipe
11248 .send_pkt_to_server(pkt_type, &frames, &mut buf)
11249 .unwrap();
11250
11251 assert!(len > 0);
11252
11253 let frames =
11254 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
11255 let mut iter = frames.iter();
11256
11257 iter.next().unwrap();
11259
11260 assert_eq!(
11261 iter.next(),
11262 Some(&frame::Frame::MaxStreamData {
11263 stream_id: 4,
11264 max: 24,
11265 })
11266 );
11267 }
11268
11269 #[rstest]
11270 fn stream_left_bidi(
11271 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11272 ) {
11273 let mut buf = [0; 65535];
11274
11275 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11276 assert_eq!(pipe.handshake(), Ok(()));
11277
11278 assert_eq!(3, pipe.client.peer_streams_left_bidi());
11279 assert_eq!(3, pipe.server.peer_streams_left_bidi());
11280
11281 pipe.server.stream_send(1, b"a", false).ok();
11282 assert_eq!(2, pipe.server.peer_streams_left_bidi());
11283 pipe.server.stream_send(5, b"a", false).ok();
11284 assert_eq!(1, pipe.server.peer_streams_left_bidi());
11285
11286 pipe.server.stream_send(9, b"a", false).ok();
11287 assert_eq!(0, pipe.server.peer_streams_left_bidi());
11288
11289 let frames = [frame::Frame::MaxStreamsBidi { max: MAX_STREAM_ID }];
11290
11291 let pkt_type = packet::Type::Short;
11292 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11293
11294 assert_eq!(MAX_STREAM_ID - 3, pipe.server.peer_streams_left_bidi());
11295 }
11296
11297 #[rstest]
11298 fn stream_left_uni(
11299 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11300 ) {
11301 let mut buf = [0; 65535];
11302
11303 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11304 assert_eq!(pipe.handshake(), Ok(()));
11305
11306 assert_eq!(3, pipe.client.peer_streams_left_uni());
11307 assert_eq!(3, pipe.server.peer_streams_left_uni());
11308
11309 pipe.server.stream_send(3, b"a", false).ok();
11310 assert_eq!(2, pipe.server.peer_streams_left_uni());
11311 pipe.server.stream_send(7, b"a", false).ok();
11312 assert_eq!(1, pipe.server.peer_streams_left_uni());
11313
11314 pipe.server.stream_send(11, b"a", false).ok();
11315 assert_eq!(0, pipe.server.peer_streams_left_uni());
11316
11317 let frames = [frame::Frame::MaxStreamsUni { max: MAX_STREAM_ID }];
11318
11319 let pkt_type = packet::Type::Short;
11320 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11321
11322 assert_eq!(MAX_STREAM_ID - 3, pipe.server.peer_streams_left_uni());
11323 }
11324
11325 #[rstest]
11326 fn stream_limit_bidi(
11327 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11328 ) {
11329 let mut buf = [0; 65535];
11330
11331 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11332 assert_eq!(pipe.handshake(), Ok(()));
11333
11334 let frames = [
11335 frame::Frame::Stream {
11336 stream_id: 4,
11337 data: <RangeBuf>::from(b"a", 0, false),
11338 },
11339 frame::Frame::Stream {
11340 stream_id: 8,
11341 data: <RangeBuf>::from(b"a", 0, false),
11342 },
11343 frame::Frame::Stream {
11344 stream_id: 12,
11345 data: <RangeBuf>::from(b"a", 0, false),
11346 },
11347 frame::Frame::Stream {
11348 stream_id: 16,
11349 data: <RangeBuf>::from(b"a", 0, false),
11350 },
11351 frame::Frame::Stream {
11352 stream_id: 20,
11353 data: <RangeBuf>::from(b"a", 0, false),
11354 },
11355 frame::Frame::Stream {
11356 stream_id: 24,
11357 data: <RangeBuf>::from(b"a", 0, false),
11358 },
11359 frame::Frame::Stream {
11360 stream_id: 28,
11361 data: <RangeBuf>::from(b"a", 0, false),
11362 },
11363 ];
11364
11365 let pkt_type = packet::Type::Short;
11366 assert_eq!(
11367 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11368 Err(Error::StreamLimit),
11369 );
11370 }
11371
11372 #[rstest]
11373 fn stream_limit_max_bidi(
11374 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11375 ) {
11376 let mut buf = [0; 65535];
11377
11378 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11379 assert_eq!(pipe.handshake(), Ok(()));
11380
11381 let frames = [frame::Frame::MaxStreamsBidi { max: MAX_STREAM_ID }];
11382
11383 let pkt_type = packet::Type::Short;
11384 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11385
11386 let frames = [frame::Frame::MaxStreamsBidi {
11387 max: MAX_STREAM_ID + 1,
11388 }];
11389
11390 let pkt_type = packet::Type::Short;
11391 assert_eq!(
11392 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11393 Err(Error::InvalidFrame),
11394 );
11395 }
11396
11397 #[rstest]
11398 fn stream_limit_uni(
11399 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11400 ) {
11401 let mut buf = [0; 65535];
11402
11403 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11404 assert_eq!(pipe.handshake(), Ok(()));
11405
11406 let frames = [
11407 frame::Frame::Stream {
11408 stream_id: 2,
11409 data: <RangeBuf>::from(b"a", 0, false),
11410 },
11411 frame::Frame::Stream {
11412 stream_id: 6,
11413 data: <RangeBuf>::from(b"a", 0, false),
11414 },
11415 frame::Frame::Stream {
11416 stream_id: 10,
11417 data: <RangeBuf>::from(b"a", 0, false),
11418 },
11419 frame::Frame::Stream {
11420 stream_id: 14,
11421 data: <RangeBuf>::from(b"a", 0, false),
11422 },
11423 frame::Frame::Stream {
11424 stream_id: 18,
11425 data: <RangeBuf>::from(b"a", 0, false),
11426 },
11427 frame::Frame::Stream {
11428 stream_id: 22,
11429 data: <RangeBuf>::from(b"a", 0, false),
11430 },
11431 frame::Frame::Stream {
11432 stream_id: 26,
11433 data: <RangeBuf>::from(b"a", 0, false),
11434 },
11435 ];
11436
11437 let pkt_type = packet::Type::Short;
11438 assert_eq!(
11439 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11440 Err(Error::StreamLimit),
11441 );
11442 }
11443
11444 #[rstest]
11445 fn stream_limit_max_uni(
11446 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11447 ) {
11448 let mut buf = [0; 65535];
11449
11450 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11451 assert_eq!(pipe.handshake(), Ok(()));
11452
11453 let frames = [frame::Frame::MaxStreamsUni { max: MAX_STREAM_ID }];
11454
11455 let pkt_type = packet::Type::Short;
11456 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11457
11458 let frames = [frame::Frame::MaxStreamsUni {
11459 max: MAX_STREAM_ID + 1,
11460 }];
11461
11462 let pkt_type = packet::Type::Short;
11463 assert_eq!(
11464 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11465 Err(Error::InvalidFrame),
11466 );
11467 }
11468
11469 #[rstest]
11470 fn stream_left_reset_bidi(
11471 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11472 ) {
11473 let mut buf = [0; 65535];
11474
11475 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11476 assert_eq!(pipe.handshake(), Ok(()));
11477
11478 assert_eq!(3, pipe.client.peer_streams_left_bidi());
11479 assert_eq!(3, pipe.server.peer_streams_left_bidi());
11480
11481 pipe.client.stream_send(0, b"a", false).ok();
11482 assert_eq!(2, pipe.client.peer_streams_left_bidi());
11483 pipe.client.stream_send(4, b"a", false).ok();
11484 assert_eq!(1, pipe.client.peer_streams_left_bidi());
11485 pipe.client.stream_send(8, b"a", false).ok();
11486 assert_eq!(0, pipe.client.peer_streams_left_bidi());
11487
11488 pipe.client
11490 .stream_shutdown(0, Shutdown::Write, 1001)
11491 .unwrap();
11492 pipe.advance().unwrap();
11493
11494 assert_eq!(0, pipe.client.peer_streams_left_bidi());
11495 let mut r = pipe.server.readable();
11496 assert_eq!(Some(0), r.next());
11497 assert_eq!(Some(4), r.next());
11498 assert_eq!(Some(8), r.next());
11499 assert_eq!(None, r.next());
11500
11501 assert_eq!(
11502 pipe.server.stream_recv(0, &mut buf),
11503 Err(Error::StreamReset(1001))
11504 );
11505
11506 let mut r = pipe.server.readable();
11507 assert_eq!(Some(4), r.next());
11508 assert_eq!(Some(8), r.next());
11509 assert_eq!(None, r.next());
11510
11511 pipe.server
11513 .stream_shutdown(0, Shutdown::Write, 1001)
11514 .unwrap();
11515 pipe.advance().unwrap();
11516
11517 assert_eq!(1, pipe.client.peer_streams_left_bidi());
11518
11519 pipe.client
11521 .stream_shutdown(4, Shutdown::Write, 1001)
11522 .unwrap();
11523 pipe.client
11524 .stream_shutdown(8, Shutdown::Write, 1001)
11525 .unwrap();
11526 pipe.advance().unwrap();
11527
11528 let mut r = pipe.server.readable();
11529 assert_eq!(Some(4), r.next());
11530 assert_eq!(Some(8), r.next());
11531 assert_eq!(None, r.next());
11532
11533 assert_eq!(
11534 pipe.server.stream_recv(4, &mut buf),
11535 Err(Error::StreamReset(1001))
11536 );
11537
11538 assert_eq!(
11539 pipe.server.stream_recv(8, &mut buf),
11540 Err(Error::StreamReset(1001))
11541 );
11542
11543 let mut r = pipe.server.readable();
11544 assert_eq!(None, r.next());
11545
11546 pipe.server
11547 .stream_shutdown(4, Shutdown::Write, 1001)
11548 .unwrap();
11549 pipe.server
11550 .stream_shutdown(8, Shutdown::Write, 1001)
11551 .unwrap();
11552 pipe.advance().unwrap();
11553
11554 assert_eq!(3, pipe.client.peer_streams_left_bidi());
11555 }
11556
11557 #[rstest]
11558 fn stream_reset_counts(
11559 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11560 ) {
11561 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11562 assert_eq!(pipe.handshake(), Ok(()));
11563
11564 pipe.client.stream_send(0, b"a", false).ok();
11565 pipe.client.stream_send(2, b"a", false).ok();
11566 pipe.client.stream_send(4, b"a", false).ok();
11567 pipe.client.stream_send(8, b"a", false).ok();
11568 pipe.advance().unwrap();
11569
11570 let stats = pipe.client.stats();
11571 assert_eq!(stats.reset_stream_count_local, 0);
11572
11573 pipe.client
11575 .stream_shutdown(0, Shutdown::Write, 1001)
11576 .unwrap();
11577 pipe.advance().unwrap();
11578
11579 let stats = pipe.client.stats();
11580 assert_eq!(stats.reset_stream_count_local, 1);
11581 assert_eq!(stats.reset_stream_count_remote, 0);
11582 let stats = pipe.server.stats();
11583 assert_eq!(stats.reset_stream_count_local, 0);
11584 assert_eq!(stats.reset_stream_count_remote, 1);
11585
11586 pipe.server
11588 .stream_shutdown(0, Shutdown::Write, 1001)
11589 .unwrap();
11590 pipe.advance().unwrap();
11591
11592 let stats = pipe.client.stats();
11593 assert_eq!(stats.reset_stream_count_local, 1);
11594 assert_eq!(stats.reset_stream_count_remote, 1);
11595 let stats = pipe.server.stats();
11596 assert_eq!(stats.reset_stream_count_local, 1);
11597 assert_eq!(stats.reset_stream_count_remote, 1);
11598
11599 pipe.client
11601 .stream_shutdown(2, Shutdown::Write, 1001)
11602 .unwrap();
11603 pipe.client
11604 .stream_shutdown(4, Shutdown::Write, 1001)
11605 .unwrap();
11606 pipe.client
11607 .stream_shutdown(8, Shutdown::Write, 1001)
11608 .unwrap();
11609 pipe.advance().unwrap();
11610
11611 pipe.server
11612 .stream_shutdown(4, Shutdown::Write, 1001)
11613 .unwrap();
11614 pipe.server
11615 .stream_shutdown(8, Shutdown::Write, 1001)
11616 .unwrap();
11617 pipe.advance().unwrap();
11618
11619 let stats = pipe.client.stats();
11620 assert_eq!(stats.reset_stream_count_local, 4);
11621 assert_eq!(stats.reset_stream_count_remote, 3);
11622 let stats = pipe.server.stats();
11623 assert_eq!(stats.reset_stream_count_local, 3);
11624 assert_eq!(stats.reset_stream_count_remote, 4);
11625 }
11626
11627 #[rstest]
11628 fn stream_stop_counts(
11629 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11630 ) {
11631 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11632 assert_eq!(pipe.handshake(), Ok(()));
11633
11634 pipe.client.stream_send(0, b"a", false).ok();
11635 pipe.client.stream_send(2, b"a", false).ok();
11636 pipe.client.stream_send(4, b"a", false).ok();
11637 pipe.client.stream_send(8, b"a", false).ok();
11638 pipe.advance().unwrap();
11639
11640 let stats = pipe.client.stats();
11641 assert_eq!(stats.reset_stream_count_local, 0);
11642
11643 pipe.server
11645 .stream_shutdown(0, Shutdown::Read, 1001)
11646 .unwrap();
11647 pipe.advance().unwrap();
11648
11649 let stats = pipe.client.stats();
11650 assert_eq!(stats.stopped_stream_count_local, 0);
11651 assert_eq!(stats.stopped_stream_count_remote, 1);
11652 assert_eq!(stats.reset_stream_count_local, 1);
11653 assert_eq!(stats.reset_stream_count_remote, 0);
11654
11655 let stats = pipe.server.stats();
11656 assert_eq!(stats.stopped_stream_count_local, 1);
11657 assert_eq!(stats.stopped_stream_count_remote, 0);
11658 assert_eq!(stats.reset_stream_count_local, 0);
11659 assert_eq!(stats.reset_stream_count_remote, 1);
11660
11661 pipe.server
11663 .stream_shutdown(2, Shutdown::Read, 1001)
11664 .unwrap();
11665 pipe.server
11666 .stream_shutdown(4, Shutdown::Read, 1001)
11667 .unwrap();
11668 pipe.server
11669 .stream_shutdown(8, Shutdown::Read, 1001)
11670 .unwrap();
11671 pipe.advance().unwrap();
11672
11673 let stats = pipe.client.stats();
11674 assert_eq!(stats.stopped_stream_count_local, 0);
11675 assert_eq!(stats.stopped_stream_count_remote, 4);
11676 assert_eq!(stats.reset_stream_count_local, 4);
11677 assert_eq!(stats.reset_stream_count_remote, 0);
11678
11679 let stats = pipe.server.stats();
11680 assert_eq!(stats.stopped_stream_count_local, 4);
11681 assert_eq!(stats.stopped_stream_count_remote, 0);
11682 assert_eq!(stats.reset_stream_count_local, 0);
11683 assert_eq!(stats.reset_stream_count_remote, 4);
11684 }
11685
11686 #[rstest]
11687 fn streams_blocked_max_bidi(
11688 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11689 ) {
11690 let mut buf = [0; 65535];
11691
11692 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11693 assert_eq!(pipe.handshake(), Ok(()));
11694
11695 let frames = [frame::Frame::StreamsBlockedBidi {
11696 limit: MAX_STREAM_ID,
11697 }];
11698
11699 let pkt_type = packet::Type::Short;
11700 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11701
11702 let frames = [frame::Frame::StreamsBlockedBidi {
11703 limit: MAX_STREAM_ID + 1,
11704 }];
11705
11706 let pkt_type = packet::Type::Short;
11707 assert_eq!(
11708 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11709 Err(Error::InvalidFrame),
11710 );
11711 }
11712
11713 #[rstest]
11714 fn streams_blocked_max_uni(
11715 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11716 ) {
11717 let mut buf = [0; 65535];
11718
11719 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11720 assert_eq!(pipe.handshake(), Ok(()));
11721
11722 let frames = [frame::Frame::StreamsBlockedUni {
11723 limit: MAX_STREAM_ID,
11724 }];
11725
11726 let pkt_type = packet::Type::Short;
11727 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11728
11729 let frames = [frame::Frame::StreamsBlockedUni {
11730 limit: MAX_STREAM_ID + 1,
11731 }];
11732
11733 let pkt_type = packet::Type::Short;
11734 assert_eq!(
11735 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11736 Err(Error::InvalidFrame),
11737 );
11738 }
11739
11740 #[rstest]
11741 fn stream_data_overlap(
11742 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11743 ) {
11744 let mut buf = [0; 65535];
11745
11746 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11747 assert_eq!(pipe.handshake(), Ok(()));
11748
11749 let frames = [
11750 frame::Frame::Stream {
11751 stream_id: 0,
11752 data: <RangeBuf>::from(b"aaaaa", 0, false),
11753 },
11754 frame::Frame::Stream {
11755 stream_id: 0,
11756 data: <RangeBuf>::from(b"bbbbb", 3, false),
11757 },
11758 frame::Frame::Stream {
11759 stream_id: 0,
11760 data: <RangeBuf>::from(b"ccccc", 6, false),
11761 },
11762 ];
11763
11764 let pkt_type = packet::Type::Short;
11765 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11766
11767 let mut b = [0; 15];
11768 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((11, false)));
11769 assert_eq!(&b[..11], b"aaaaabbbccc");
11770 }
11771
11772 #[rstest]
11773 fn stream_data_overlap_with_reordering(
11774 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11775 ) {
11776 let mut buf = [0; 65535];
11777
11778 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11779 assert_eq!(pipe.handshake(), Ok(()));
11780
11781 let frames = [
11782 frame::Frame::Stream {
11783 stream_id: 0,
11784 data: <RangeBuf>::from(b"aaaaa", 0, false),
11785 },
11786 frame::Frame::Stream {
11787 stream_id: 0,
11788 data: <RangeBuf>::from(b"ccccc", 6, false),
11789 },
11790 frame::Frame::Stream {
11791 stream_id: 0,
11792 data: <RangeBuf>::from(b"bbbbb", 3, false),
11793 },
11794 ];
11795
11796 let pkt_type = packet::Type::Short;
11797 assert!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf).is_ok());
11798
11799 let mut b = [0; 15];
11800 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((11, false)));
11801 assert_eq!(&b[..11], b"aaaaabccccc");
11802 }
11803
11804 #[rstest]
11805 fn reset_stream_data_recvd(
11808 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11809 ) {
11810 let mut b = [0; 15];
11811 let mut buf = [0; 65535];
11812
11813 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11814 assert_eq!(pipe.handshake(), Ok(()));
11815
11816 assert_eq!(pipe.client.stream_send(0, b"hello", false), Ok(5));
11818 assert_eq!(pipe.advance(), Ok(()));
11819
11820 let mut r = pipe.server.readable();
11822 assert_eq!(r.next(), Some(0));
11823 assert_eq!(r.next(), None);
11824
11825 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((5, false)));
11826 assert!(!pipe.server.stream_finished(0));
11827
11828 let mut r = pipe.server.readable();
11829 assert_eq!(r.next(), None);
11830
11831 assert_eq!(pipe.server.stream_send(0, b"", true), Ok(0));
11832 assert_eq!(pipe.advance(), Ok(()));
11833
11834 let mut r = pipe.client.readable();
11835 assert_eq!(r.next(), Some(0));
11836 assert_eq!(r.next(), None);
11837
11838 assert_eq!(pipe.client.stream_recv(0, &mut b), Ok((0, true)));
11839 assert!(pipe.client.stream_finished(0));
11840
11841 let frames = [frame::Frame::ResetStream {
11843 stream_id: 0,
11844 error_code: 42,
11845 final_size: 5,
11846 }];
11847
11848 let pkt_type = packet::Type::Short;
11849 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(39));
11850
11851 let mut r = pipe.server.readable();
11853 assert_eq!(r.next(), Some(0));
11854 assert_eq!(r.next(), None);
11855
11856 assert_eq!(
11857 pipe.server.stream_recv(0, &mut b),
11858 Err(Error::StreamReset(42))
11859 );
11860
11861 assert!(pipe.server.stream_finished(0));
11862
11863 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf)
11865 .unwrap();
11866
11867 let mut r = pipe.server.readable();
11868 assert_eq!(r.next(), None);
11869 }
11870
11871 #[rstest]
11872 fn reset_stream_data_not_recvd(
11875 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11876 ) {
11877 let mut b = [0; 15];
11878 let mut buf = [0; 65535];
11879
11880 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11881 assert_eq!(pipe.handshake(), Ok(()));
11882
11883 assert_eq!(pipe.client.stream_send(0, b"h", false), Ok(1));
11885 assert_eq!(pipe.advance(), Ok(()));
11886
11887 let mut r = pipe.server.readable();
11889 assert_eq!(r.next(), Some(0));
11890 assert_eq!(r.next(), None);
11891
11892 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((1, false)));
11893 assert!(!pipe.server.stream_finished(0));
11894
11895 let mut r = pipe.server.readable();
11896 assert_eq!(r.next(), None);
11897
11898 assert_eq!(pipe.server.stream_send(0, b"", true), Ok(0));
11899 assert_eq!(pipe.advance(), Ok(()));
11900
11901 let mut r = pipe.client.readable();
11902 assert_eq!(r.next(), Some(0));
11903 assert_eq!(r.next(), None);
11904
11905 assert_eq!(pipe.client.stream_recv(0, &mut b), Ok((0, true)));
11906 assert!(pipe.client.stream_finished(0));
11907
11908 let frames = [frame::Frame::ResetStream {
11910 stream_id: 0,
11911 error_code: 42,
11912 final_size: 5,
11913 }];
11914
11915 let pkt_type = packet::Type::Short;
11916 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(39));
11917
11918 let mut r = pipe.server.readable();
11920 assert_eq!(r.next(), Some(0));
11921 assert_eq!(r.next(), None);
11922
11923 assert_eq!(
11924 pipe.server.stream_recv(0, &mut b),
11925 Err(Error::StreamReset(42))
11926 );
11927
11928 assert!(pipe.server.stream_finished(0));
11929
11930 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(39));
11932
11933 let mut r = pipe.server.readable();
11934 assert_eq!(r.next(), None);
11935 }
11936
11937 #[rstest]
11938 fn reset_stream_flow_control(
11941 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11942 ) {
11943 let mut buf = [0; 65535];
11944
11945 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11946 assert_eq!(pipe.handshake(), Ok(()));
11947
11948 let frames = [
11949 frame::Frame::Stream {
11950 stream_id: 0,
11951 data: <RangeBuf>::from(b"aaaaaaaaaaaaaaa", 0, false),
11952 },
11953 frame::Frame::Stream {
11954 stream_id: 4,
11955 data: <RangeBuf>::from(b"a", 0, false),
11956 },
11957 frame::Frame::ResetStream {
11958 stream_id: 4,
11959 error_code: 0,
11960 final_size: 15,
11961 },
11962 frame::Frame::Stream {
11963 stream_id: 8,
11964 data: <RangeBuf>::from(b"a", 0, false),
11965 },
11966 ];
11967
11968 let pkt_type = packet::Type::Short;
11969 assert_eq!(
11970 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
11971 Err(Error::FlowControl),
11972 );
11973 }
11974
11975 #[rstest]
11976 fn reset_stream_flow_control_stream(
11979 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
11980 ) {
11981 let mut buf = [0; 65535];
11982
11983 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
11984 assert_eq!(pipe.handshake(), Ok(()));
11985
11986 let frames = [
11987 frame::Frame::Stream {
11988 stream_id: 4,
11989 data: <RangeBuf>::from(b"a", 0, false),
11990 },
11991 frame::Frame::ResetStream {
11992 stream_id: 4,
11993 error_code: 0,
11994 final_size: 16, },
11996 ];
11997
11998 let pkt_type = packet::Type::Short;
11999 assert_eq!(
12000 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf),
12001 Err(Error::FlowControl),
12002 );
12003 }
12004
12005 #[rstest]
12006 fn path_challenge(
12007 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12008 ) {
12009 let mut buf = [0; 65535];
12010
12011 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12012 assert_eq!(pipe.handshake(), Ok(()));
12013
12014 let frames = [frame::Frame::PathChallenge { data: [0xba; 8] }];
12015
12016 let pkt_type = packet::Type::Short;
12017
12018 let len = pipe
12019 .send_pkt_to_server(pkt_type, &frames, &mut buf)
12020 .unwrap();
12021
12022 assert!(len > 0);
12023
12024 let frames =
12025 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
12026 let mut iter = frames.iter();
12027
12028 iter.next().unwrap();
12030
12031 assert_eq!(
12032 iter.next(),
12033 Some(&frame::Frame::PathResponse { data: [0xba; 8] })
12034 );
12035 }
12036
12037 #[cfg(not(feature = "openssl"))] #[rstest]
12039 fn early_1rtt_packet(
12042 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12043 ) {
12044 let mut buf = [0; 65535];
12045
12046 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12047
12048 let flight = testing::emit_flight(&mut pipe.client).unwrap();
12050 testing::process_flight(&mut pipe.server, flight).unwrap();
12051
12052 let flight = testing::emit_flight(&mut pipe.server).unwrap();
12054 testing::process_flight(&mut pipe.client, flight).unwrap();
12055
12056 let flight = testing::emit_flight(&mut pipe.client).unwrap();
12058
12059 let delayed = flight;
12062
12063 testing::emit_flight(&mut pipe.server).ok();
12064
12065 assert!(pipe.client.is_established());
12066
12067 let frames = [frame::Frame::Stream {
12069 stream_id: 0,
12070 data: <RangeBuf>::from(b"hello, world", 0, true),
12071 }];
12072
12073 let pkt_type = packet::Type::Short;
12074 let written =
12075 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
12076 .unwrap();
12077
12078 assert_eq!(pipe.server_recv(&mut buf[..written]), Ok(written));
12079
12080 let frames = [frame::Frame::Stream {
12082 stream_id: 4,
12083 data: <RangeBuf>::from(b"hello, world", 0, true),
12084 }];
12085
12086 let written =
12087 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
12088 .unwrap();
12089
12090 assert_eq!(pipe.server_recv(&mut buf[..written]), Ok(written));
12091
12092 assert!(!pipe.server.is_established());
12093
12094 assert_eq!(
12099 pipe.server.pkt_num_spaces[packet::Epoch::Application]
12100 .largest_rx_pkt_num,
12101 0
12102 );
12103
12104 testing::process_flight(&mut pipe.server, delayed).unwrap();
12106
12107 assert!(pipe.server.is_established());
12108
12109 assert_eq!(
12110 pipe.server.pkt_num_spaces[packet::Epoch::Application]
12111 .largest_rx_pkt_num,
12112 0
12113 );
12114 }
12115
12116 #[rstest]
12117 fn stop_sending(
12118 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12119 ) {
12120 let mut b = [0; 15];
12121
12122 let mut buf = [0; 65535];
12123
12124 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12125 assert_eq!(pipe.handshake(), Ok(()));
12126
12127 assert_eq!(pipe.client.stream_send(0, b"hello", true), Ok(5));
12129 assert_eq!(pipe.advance(), Ok(()));
12130
12131 let mut r = pipe.server.readable();
12133 assert_eq!(r.next(), Some(0));
12134 assert_eq!(r.next(), None);
12135
12136 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((5, true)));
12137 assert!(pipe.server.stream_finished(0));
12138
12139 let mut r = pipe.server.readable();
12140 assert_eq!(r.next(), None);
12141
12142 let mut r = pipe.server.writable();
12144 assert_eq!(r.next(), Some(0));
12145 assert_eq!(r.next(), None);
12146
12147 while pipe.server.stream_send(0, b"world", false) != Err(Error::Done) {
12148 assert_eq!(pipe.advance(), Ok(()));
12149 }
12150
12151 let mut r = pipe.server.writable();
12152 assert_eq!(r.next(), None);
12153
12154 let frames = [frame::Frame::StopSending {
12156 stream_id: 0,
12157 error_code: 42,
12158 }];
12159
12160 let pkt_type = packet::Type::Short;
12161 let len = pipe
12162 .send_pkt_to_server(pkt_type, &frames, &mut buf)
12163 .unwrap();
12164
12165 let frames =
12167 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
12168
12169 let mut iter = frames.iter();
12170
12171 iter.next();
12173
12174 assert_eq!(
12175 iter.next(),
12176 Some(&frame::Frame::ResetStream {
12177 stream_id: 0,
12178 error_code: 42,
12179 final_size: 15,
12180 })
12181 );
12182
12183 let mut r = pipe.server.writable();
12185 assert_eq!(r.next(), Some(0));
12186 assert_eq!(r.next(), None);
12187
12188 assert_eq!(
12189 pipe.server.stream_send(0, b"world", true),
12190 Err(Error::StreamStopped(42)),
12191 );
12192
12193 assert_eq!(pipe.server.streams.len(), 1);
12194
12195 let mut ranges = ranges::RangeSet::default();
12197 ranges.insert(pipe.server.next_pkt_num - 5..pipe.server.next_pkt_num);
12198
12199 let frames = [frame::Frame::ACK {
12200 ack_delay: 15,
12201 ranges,
12202 ecn_counts: None,
12203 }];
12204
12205 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(0));
12206
12207 assert_eq!(pipe.server.streams.len(), 0);
12209
12210 let frames = [frame::Frame::StopSending {
12212 stream_id: 0,
12213 error_code: 42,
12214 }];
12215
12216 let len = pipe
12217 .send_pkt_to_server(pkt_type, &frames, &mut buf)
12218 .unwrap();
12219
12220 let frames =
12221 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
12222
12223 assert_eq!(frames.len(), 1);
12224
12225 match frames.first() {
12226 Some(frame::Frame::ACK { .. }) => (),
12227
12228 f => panic!("expected ACK frame, got {:?}", f),
12229 };
12230
12231 let mut r = pipe.server.writable();
12232 assert_eq!(r.next(), None);
12233 }
12234
12235 #[rstest]
12236 fn stop_sending_fin(
12237 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12238 ) {
12239 let mut b = [0; 15];
12240
12241 let mut buf = [0; 65535];
12242
12243 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12244 assert_eq!(pipe.handshake(), Ok(()));
12245
12246 assert_eq!(pipe.client.stream_send(4, b"hello", true), Ok(5));
12248 assert_eq!(pipe.advance(), Ok(()));
12249
12250 let mut r = pipe.server.readable();
12252 assert_eq!(r.next(), Some(4));
12253 assert_eq!(r.next(), None);
12254
12255 assert_eq!(pipe.server.stream_recv(4, &mut b), Ok((5, true)));
12256 assert!(pipe.server.stream_finished(4));
12257
12258 let mut r = pipe.server.readable();
12259 assert_eq!(r.next(), None);
12260
12261 let mut r = pipe.server.writable();
12263 assert_eq!(r.next(), Some(4));
12264 assert_eq!(r.next(), None);
12265
12266 assert_eq!(pipe.server.stream_send(4, b"world", false), Ok(5));
12267 assert_eq!(pipe.advance(), Ok(()));
12268
12269 assert_eq!(pipe.server.stream_send(4, b"world", true), Ok(5));
12271
12272 let frames = [frame::Frame::StopSending {
12274 stream_id: 4,
12275 error_code: 42,
12276 }];
12277
12278 let pkt_type = packet::Type::Short;
12279 let len = pipe
12280 .send_pkt_to_server(pkt_type, &frames, &mut buf)
12281 .unwrap();
12282
12283 let frames =
12285 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
12286
12287 let mut iter = frames.iter();
12288
12289 iter.next();
12291
12292 assert_eq!(
12293 iter.next(),
12294 Some(&frame::Frame::ResetStream {
12295 stream_id: 4,
12296 error_code: 42,
12297 final_size: 5,
12298 })
12299 );
12300
12301 assert_eq!(iter.next(), None);
12303 }
12304
12305 #[rstest]
12306 fn stop_sending_unsent_tx_cap(
12308 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12309 ) {
12310 let mut buf = [0; 65535];
12311
12312 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
12313 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
12314 config
12315 .load_cert_chain_from_pem_file("examples/cert.crt")
12316 .unwrap();
12317 config
12318 .load_priv_key_from_pem_file("examples/cert.key")
12319 .unwrap();
12320 config
12321 .set_application_protos(&[b"proto1", b"proto2"])
12322 .unwrap();
12323 config.set_initial_max_data(15);
12324 config.set_initial_max_stream_data_bidi_local(30);
12325 config.set_initial_max_stream_data_bidi_remote(30);
12326 config.set_initial_max_stream_data_uni(30);
12327 config.set_initial_max_streams_bidi(3);
12328 config.set_initial_max_streams_uni(0);
12329 config.verify_peer(false);
12330
12331 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
12332 assert_eq!(pipe.handshake(), Ok(()));
12333
12334 assert_eq!(pipe.client.stream_send(4, b"hello", true), Ok(5));
12336 assert_eq!(pipe.advance(), Ok(()));
12337
12338 let mut r = pipe.server.readable();
12339 assert_eq!(r.next(), Some(4));
12340 assert_eq!(r.next(), None);
12341
12342 let mut b = [0; 15];
12343 assert_eq!(pipe.server.stream_recv(4, &mut b), Ok((5, true)));
12344
12345 assert_eq!(pipe.server.stream_send(4, b"hello", false), Ok(5));
12347 assert_eq!(pipe.advance(), Ok(()));
12348
12349 assert_eq!(pipe.server.stream_send(4, b"hello", false), Ok(5));
12351 assert_eq!(pipe.server.stream_send(4, b"hello", false), Ok(5));
12352 assert_eq!(
12353 pipe.server.stream_send(4, b"hello", false),
12354 Err(Error::Done)
12355 );
12356
12357 let frames = [frame::Frame::StopSending {
12359 stream_id: 4,
12360 error_code: 42,
12361 }];
12362
12363 let pkt_type = packet::Type::Short;
12364 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf)
12365 .unwrap();
12366
12367 assert_eq!(pipe.client.stream_send(8, b"hello", true), Ok(5));
12369 assert_eq!(pipe.advance(), Ok(()));
12370
12371 assert_eq!(pipe.server.stream_send(8, b"hello", false), Ok(5));
12372 assert_eq!(pipe.server.stream_send(8, b"hello", false), Ok(5));
12373 assert_eq!(
12374 pipe.server.stream_send(8, b"hello", false),
12375 Err(Error::Done)
12376 );
12377 assert_eq!(pipe.advance(), Ok(()));
12378 }
12379
12380 #[rstest]
12381 fn stream_shutdown_read(
12382 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12383 ) {
12384 let mut buf = [0; 65535];
12385
12386 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12387 assert_eq!(pipe.handshake(), Ok(()));
12388
12389 assert_eq!(pipe.client.stream_send(4, b"hello, world", false), Ok(12));
12391 assert_eq!(pipe.advance(), Ok(()));
12392
12393 let mut r = pipe.server.readable();
12394 assert_eq!(r.next(), Some(4));
12395 assert_eq!(r.next(), None);
12396
12397 assert_eq!(pipe.client.streams.len(), 1);
12398 assert_eq!(pipe.server.streams.len(), 1);
12399
12400 assert_eq!(pipe.server.stream_shutdown(4, Shutdown::Read, 42), Ok(()));
12402
12403 let mut r = pipe.server.readable();
12404 assert_eq!(r.next(), None);
12405
12406 let (len, _) = pipe.server.send(&mut buf).unwrap();
12407
12408 let mut dummy = buf[..len].to_vec();
12409
12410 let frames =
12411 testing::decode_pkt(&mut pipe.client, &mut dummy[..len]).unwrap();
12412 let mut iter = frames.iter();
12413
12414 assert_eq!(
12415 iter.next(),
12416 Some(&frame::Frame::StopSending {
12417 stream_id: 4,
12418 error_code: 42,
12419 })
12420 );
12421
12422 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
12423
12424 assert_eq!(pipe.advance(), Ok(()));
12425
12426 let mut r = pipe.client.writable();
12428 assert_eq!(r.next(), Some(4));
12429 assert_eq!(r.next(), None);
12430
12431 assert_eq!(
12432 pipe.client.stream_send(4, b"bye", false),
12433 Err(Error::StreamStopped(42))
12434 );
12435
12436 assert_eq!(pipe.server.stream_send(4, b"hello, world", true), Ok(12));
12439 assert_eq!(pipe.advance(), Ok(()));
12440
12441 let mut r = pipe.client.readable();
12443 assert_eq!(r.next(), Some(4));
12444 assert_eq!(r.next(), None);
12445
12446 assert_eq!(pipe.client.stream_recv(4, &mut buf), Ok((12, true)));
12447
12448 assert_eq!(pipe.client.streams.len(), 0);
12450 assert_eq!(pipe.server.streams.len(), 0);
12451
12452 assert_eq!(
12453 pipe.server.stream_shutdown(4, Shutdown::Read, 0),
12454 Err(Error::Done)
12455 );
12456 }
12457
12458 #[rstest]
12459 fn stream_shutdown_read_after_fin(
12460 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12461 ) {
12462 let mut buf = [0; 65535];
12463
12464 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12465 assert_eq!(pipe.handshake(), Ok(()));
12466
12467 assert_eq!(pipe.client.stream_send(4, b"hello, world", true), Ok(12));
12469 assert_eq!(pipe.advance(), Ok(()));
12470
12471 let mut r = pipe.server.readable();
12472 assert_eq!(r.next(), Some(4));
12473 assert_eq!(r.next(), None);
12474
12475 assert_eq!(pipe.client.streams.len(), 1);
12476 assert_eq!(pipe.server.streams.len(), 1);
12477
12478 assert_eq!(pipe.server.stream_shutdown(4, Shutdown::Read, 42), Ok(()));
12480
12481 let mut r = pipe.server.readable();
12482 assert_eq!(r.next(), None);
12483
12484 assert_eq!(pipe.server.send(&mut buf), Err(Error::Done));
12486
12487 assert_eq!(pipe.advance(), Ok(()));
12488
12489 assert_eq!(pipe.server.stream_send(4, b"hello, world", true), Ok(12));
12492 assert_eq!(pipe.advance(), Ok(()));
12493
12494 let mut r = pipe.client.readable();
12496 assert_eq!(r.next(), Some(4));
12497 assert_eq!(r.next(), None);
12498
12499 assert_eq!(pipe.client.stream_recv(4, &mut buf), Ok((12, true)));
12500
12501 assert_eq!(pipe.client.streams.len(), 0);
12503 assert_eq!(pipe.server.streams.len(), 0);
12504
12505 assert_eq!(
12506 pipe.server.stream_shutdown(4, Shutdown::Read, 0),
12507 Err(Error::Done)
12508 );
12509 }
12510
12511 #[rstest]
12512 fn stream_shutdown_read_update_max_data(
12513 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12514 ) {
12515 let mut buf = [0; 65535];
12516
12517 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
12518 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
12519 config
12520 .load_cert_chain_from_pem_file("examples/cert.crt")
12521 .unwrap();
12522 config
12523 .load_priv_key_from_pem_file("examples/cert.key")
12524 .unwrap();
12525 config
12526 .set_application_protos(&[b"proto1", b"proto2"])
12527 .unwrap();
12528 config.set_initial_max_data(30);
12529 config.set_initial_max_stream_data_bidi_local(10000);
12530 config.set_initial_max_stream_data_bidi_remote(10000);
12531 config.set_initial_max_streams_bidi(10);
12532 config.verify_peer(false);
12533
12534 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
12535 assert_eq!(pipe.handshake(), Ok(()));
12536
12537 assert_eq!(pipe.client.stream_send(0, b"a", false), Ok(1));
12538 assert_eq!(pipe.advance(), Ok(()));
12539
12540 assert_eq!(pipe.server.stream_recv(0, &mut buf), Ok((1, false)));
12541 assert_eq!(pipe.server.stream_shutdown(0, Shutdown::Read, 123), Ok(()));
12542
12543 assert_eq!(pipe.server.rx_data, 1);
12544 assert_eq!(pipe.client.tx_data, 1);
12545 assert_eq!(pipe.client.max_tx_data, 30);
12546
12547 assert_eq!(
12548 pipe.client
12549 .stream_send(0, &buf[..pipe.client.tx_cap], false),
12550 Ok(29)
12551 );
12552 assert_eq!(pipe.advance(), Ok(()));
12553
12554 assert!(!pipe.server.stream_readable(0)); assert_eq!(pipe.client.tx_data, 30);
12559 assert_eq!(pipe.server.rx_data, 30);
12560 assert_eq!(pipe.client.tx_cap, 45);
12561 }
12562
12563 #[rstest]
12564 fn stream_shutdown_uni(
12565 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12566 ) {
12567 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12568 assert_eq!(pipe.handshake(), Ok(()));
12569
12570 assert_eq!(pipe.client.stream_send(2, b"hello, world", false), Ok(10));
12572 assert_eq!(pipe.server.stream_send(3, b"hello, world", false), Ok(10));
12573 assert_eq!(pipe.advance(), Ok(()));
12574
12575 assert_eq!(pipe.client.stream_shutdown(2, Shutdown::Write, 42), Ok(()));
12577 assert_eq!(
12578 pipe.client.stream_shutdown(2, Shutdown::Read, 42),
12579 Err(Error::InvalidStreamState(2))
12580 );
12581
12582 assert_eq!(
12583 pipe.client.stream_shutdown(3, Shutdown::Write, 42),
12584 Err(Error::InvalidStreamState(3))
12585 );
12586 assert_eq!(pipe.client.stream_shutdown(3, Shutdown::Read, 42), Ok(()));
12587 }
12588
12589 #[rstest]
12590 fn stream_shutdown_write(
12591 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12592 ) {
12593 let mut buf = [0; 65535];
12594
12595 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12596 assert_eq!(pipe.handshake(), Ok(()));
12597
12598 assert_eq!(pipe.client.stream_send(4, b"hello, world", false), Ok(12));
12600 assert_eq!(pipe.advance(), Ok(()));
12601
12602 let mut r = pipe.server.readable();
12603 assert_eq!(r.next(), Some(4));
12604 assert_eq!(r.next(), None);
12605
12606 let mut r = pipe.server.writable();
12607 assert_eq!(r.next(), Some(4));
12608 assert_eq!(r.next(), None);
12609
12610 assert_eq!(pipe.client.streams.len(), 1);
12611 assert_eq!(pipe.server.streams.len(), 1);
12612
12613 assert_eq!(pipe.server.stream_send(4, b"goodbye, world", false), Ok(14));
12615 assert_eq!(pipe.advance(), Ok(()));
12616
12617 assert_eq!(pipe.server.stream_shutdown(4, Shutdown::Write, 42), Ok(()));
12619
12620 let mut r = pipe.server.writable();
12621 assert_eq!(r.next(), None);
12622
12623 let (len, _) = pipe.server.send(&mut buf).unwrap();
12624
12625 let mut dummy = buf[..len].to_vec();
12626
12627 let frames =
12628 testing::decode_pkt(&mut pipe.client, &mut dummy[..len]).unwrap();
12629 let mut iter = frames.iter();
12630
12631 assert_eq!(
12632 iter.next(),
12633 Some(&frame::Frame::ResetStream {
12634 stream_id: 4,
12635 error_code: 42,
12636 final_size: 14,
12637 })
12638 );
12639
12640 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
12641
12642 assert_eq!(pipe.advance(), Ok(()));
12643
12644 assert_eq!(
12646 pipe.server.stream_send(4, b"bye", false),
12647 Err(Error::FinalSize)
12648 );
12649
12650 assert_eq!(pipe.client.stream_send(4, b"bye", true), Ok(3));
12652 assert_eq!(pipe.advance(), Ok(()));
12653
12654 let mut r = pipe.server.readable();
12656 assert_eq!(r.next(), Some(4));
12657 assert_eq!(r.next(), None);
12658
12659 assert_eq!(pipe.server.stream_recv(4, &mut buf), Ok((15, true)));
12660
12661 let mut r = pipe.client.readable();
12663 assert_eq!(r.next(), Some(4));
12664 assert_eq!(r.next(), None);
12665
12666 assert_eq!(
12667 pipe.client.stream_recv(4, &mut buf),
12668 Err(Error::StreamReset(42))
12669 );
12670
12671 assert_eq!(pipe.client.streams.len(), 0);
12673 assert_eq!(pipe.server.streams.len(), 0);
12674
12675 assert_eq!(
12676 pipe.server.stream_shutdown(4, Shutdown::Write, 0),
12677 Err(Error::Done)
12678 );
12679 }
12680
12681 #[rstest]
12682 fn stream_shutdown_write_unsent_tx_cap(
12684 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12685 ) {
12686 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
12687 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
12688 config
12689 .load_cert_chain_from_pem_file("examples/cert.crt")
12690 .unwrap();
12691 config
12692 .load_priv_key_from_pem_file("examples/cert.key")
12693 .unwrap();
12694 config
12695 .set_application_protos(&[b"proto1", b"proto2"])
12696 .unwrap();
12697 config.set_initial_max_data(15);
12698 config.set_initial_max_stream_data_bidi_local(30);
12699 config.set_initial_max_stream_data_bidi_remote(30);
12700 config.set_initial_max_stream_data_uni(30);
12701 config.set_initial_max_streams_bidi(3);
12702 config.set_initial_max_streams_uni(0);
12703 config.verify_peer(false);
12704
12705 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
12706 assert_eq!(pipe.handshake(), Ok(()));
12707
12708 assert_eq!(pipe.client.stream_send(4, b"hello", true), Ok(5));
12710 assert_eq!(pipe.advance(), Ok(()));
12711
12712 let mut r = pipe.server.readable();
12713 assert_eq!(r.next(), Some(4));
12714 assert_eq!(r.next(), None);
12715
12716 let mut b = [0; 15];
12717 assert_eq!(pipe.server.stream_recv(4, &mut b), Ok((5, true)));
12718
12719 assert_eq!(pipe.server.stream_send(4, b"hello", false), Ok(5));
12721 assert_eq!(pipe.advance(), Ok(()));
12722
12723 assert_eq!(pipe.server.stream_send(4, b"hello", false), Ok(5));
12725 assert_eq!(pipe.server.stream_send(4, b"hello", false), Ok(5));
12726 assert_eq!(
12727 pipe.server.stream_send(4, b"hello", false),
12728 Err(Error::Done)
12729 );
12730
12731 assert!(!pipe.client.should_update_max_data());
12733
12734 assert_eq!(pipe.server.stream_shutdown(4, Shutdown::Write, 42), Ok(()));
12736 assert_eq!(pipe.advance(), Ok(()));
12737
12738 assert_eq!(pipe.client.stream_send(8, b"hello", true), Ok(5));
12740 assert_eq!(pipe.advance(), Ok(()));
12741
12742 assert_eq!(pipe.server.stream_send(8, b"hello", false), Ok(5));
12743 assert_eq!(pipe.server.stream_send(8, b"hello", false), Ok(5));
12744 assert_eq!(
12745 pipe.server.stream_send(8, b"hello", false),
12746 Err(Error::Done)
12747 );
12748 assert_eq!(pipe.advance(), Ok(()));
12749 }
12750
12751 #[rstest]
12752 fn stream_round_robin(
12755 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12756 ) {
12757 let mut buf = [0; 65535];
12758
12759 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12760 assert_eq!(pipe.handshake(), Ok(()));
12761
12762 assert_eq!(pipe.client.stream_send(8, b"aaaaa", false), Ok(5));
12763 assert_eq!(pipe.client.stream_send(0, b"aaaaa", false), Ok(5));
12764 assert_eq!(pipe.client.stream_send(4, b"aaaaa", false), Ok(5));
12765
12766 let (len, _) = pipe.client.send(&mut buf).unwrap();
12767
12768 let frames =
12769 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
12770
12771 let mut iter = frames.iter();
12772
12773 iter.next();
12775
12776 assert_eq!(
12777 iter.next(),
12778 Some(&frame::Frame::Stream {
12779 stream_id: 8,
12780 data: <RangeBuf>::from(b"aaaaa", 0, false),
12781 })
12782 );
12783
12784 let (len, _) = pipe.client.send(&mut buf).unwrap();
12785
12786 let frames =
12787 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
12788
12789 assert_eq!(
12790 frames.first(),
12791 Some(&frame::Frame::Stream {
12792 stream_id: 0,
12793 data: <RangeBuf>::from(b"aaaaa", 0, false),
12794 })
12795 );
12796
12797 let (len, _) = pipe.client.send(&mut buf).unwrap();
12798
12799 let frames =
12800 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
12801
12802 assert_eq!(
12803 frames.first(),
12804 Some(&frame::Frame::Stream {
12805 stream_id: 4,
12806 data: <RangeBuf>::from(b"aaaaa", 0, false),
12807 })
12808 );
12809 }
12810
12811 #[rstest]
12812 fn stream_readable(
12814 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12815 ) {
12816 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12817 assert_eq!(pipe.handshake(), Ok(()));
12818
12819 let mut r = pipe.client.readable();
12821 assert_eq!(r.next(), None);
12822
12823 assert_eq!(pipe.client.stream_send(0, b"aaaaa", false), Ok(5));
12824
12825 let mut r = pipe.client.readable();
12826 assert_eq!(r.next(), None);
12827
12828 let mut r = pipe.server.readable();
12829 assert_eq!(r.next(), None);
12830
12831 assert_eq!(pipe.advance(), Ok(()));
12832
12833 let mut r = pipe.server.readable();
12835 assert_eq!(r.next(), Some(0));
12836 assert_eq!(r.next(), None);
12837
12838 assert_eq!(
12839 pipe.server.stream_send(0, b"aaaaaaaaaaaaaaa", false),
12840 Ok(15)
12841 );
12842 assert_eq!(pipe.advance(), Ok(()));
12843
12844 let mut r = pipe.client.readable();
12845 assert_eq!(r.next(), Some(0));
12846 assert_eq!(r.next(), None);
12847
12848 let mut b = [0; 15];
12850 pipe.client.stream_recv(0, &mut b).unwrap();
12851 assert_eq!(pipe.advance(), Ok(()));
12852
12853 let mut r = pipe.client.readable();
12854 assert_eq!(r.next(), None);
12855
12856 let mut r = pipe.server.readable();
12858 assert_eq!(r.next(), Some(0));
12859 assert_eq!(r.next(), None);
12860
12861 assert_eq!(pipe.server.stream_shutdown(0, Shutdown::Read, 0), Ok(()));
12862
12863 let mut r = pipe.server.readable();
12864 assert_eq!(r.next(), None);
12865
12866 assert_eq!(pipe.client.stream_send(4, b"aaaaa", false), Ok(5));
12868 assert_eq!(pipe.advance(), Ok(()));
12869
12870 assert_eq!(pipe.client.stream_send(8, b"aaaaa", false), Ok(5));
12871 assert_eq!(pipe.advance(), Ok(()));
12872
12873 let mut r = pipe.server.readable();
12874 assert_eq!(r.len(), 2);
12875
12876 assert!(r.next().is_some());
12877 assert!(r.next().is_some());
12878 assert!(r.next().is_none());
12879
12880 assert_eq!(r.len(), 0);
12881 }
12882
12883 #[rstest]
12884 fn stream_writable(
12886 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12887 ) {
12888 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
12889 assert_eq!(pipe.handshake(), Ok(()));
12890
12891 let mut w = pipe.client.writable();
12893 assert_eq!(w.next(), None);
12894
12895 assert_eq!(pipe.client.stream_send(0, b"aaaaa", false), Ok(5));
12896
12897 let mut w = pipe.client.writable();
12899 assert_eq!(w.next(), Some(0));
12900 assert_eq!(w.next(), None);
12901
12902 assert_eq!(pipe.advance(), Ok(()));
12903
12904 let mut w = pipe.server.writable();
12906 assert_eq!(w.next(), Some(0));
12907 assert_eq!(w.next(), None);
12908
12909 assert_eq!(
12910 pipe.server.stream_send(0, b"aaaaaaaaaaaaaaa", false),
12911 Ok(15)
12912 );
12913
12914 let mut w = pipe.server.writable();
12916 assert_eq!(w.next(), None);
12917
12918 assert_eq!(pipe.advance(), Ok(()));
12919
12920 let mut b = [0; 15];
12922 pipe.client.stream_recv(0, &mut b).unwrap();
12923 assert_eq!(pipe.advance(), Ok(()));
12924
12925 let mut w = pipe.server.writable();
12927 assert_eq!(w.next(), Some(0));
12928 assert_eq!(w.next(), None);
12929
12930 assert_eq!(pipe.server.stream_shutdown(0, Shutdown::Write, 0), Ok(()));
12932
12933 let mut w = pipe.server.writable();
12934 assert_eq!(w.next(), None);
12935
12936 assert_eq!(pipe.client.stream_send(4, b"aaaaa", false), Ok(5));
12938 assert_eq!(pipe.advance(), Ok(()));
12939
12940 assert_eq!(pipe.client.stream_send(8, b"aaaaa", false), Ok(5));
12941 assert_eq!(pipe.advance(), Ok(()));
12942
12943 let mut w = pipe.server.writable();
12944 assert_eq!(w.len(), 2);
12945
12946 assert!(w.next().is_some());
12947 assert!(w.next().is_some());
12948 assert!(w.next().is_none());
12949
12950 assert_eq!(w.len(), 0);
12951
12952 assert_eq!(pipe.server.stream_send(8, b"aaaaa", true), Ok(5));
12954
12955 let mut w = pipe.server.writable();
12956 assert_eq!(w.next(), Some(4));
12957 assert_eq!(w.next(), None);
12958 }
12959
12960 #[rstest]
12961 fn stream_writable_blocked(
12962 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
12963 ) {
12964 let mut config = crate::Config::new(crate::PROTOCOL_VERSION).unwrap();
12965 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
12966 config
12967 .load_cert_chain_from_pem_file("examples/cert.crt")
12968 .unwrap();
12969 config
12970 .load_priv_key_from_pem_file("examples/cert.key")
12971 .unwrap();
12972 config.set_application_protos(&[b"h3"]).unwrap();
12973 config.set_initial_max_data(70);
12974 config.set_initial_max_stream_data_bidi_local(150000);
12975 config.set_initial_max_stream_data_bidi_remote(150000);
12976 config.set_initial_max_stream_data_uni(150000);
12977 config.set_initial_max_streams_bidi(100);
12978 config.set_initial_max_streams_uni(5);
12979 config.verify_peer(false);
12980
12981 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
12982 assert_eq!(pipe.handshake(), Ok(()));
12983
12984 let send_buf = [0; 35];
12986 assert_eq!(pipe.client.stream_send(0, &send_buf, false), Ok(35));
12987
12988 assert_eq!(pipe.client.stream_writable_next(), Some(0));
12990 assert_eq!(pipe.client.stream_writable_next(), None);
12991
12992 let send_buf = [0; 36];
12995 assert_eq!(pipe.client.stream_send(0, &send_buf, false), Ok(35));
12996
12997 assert_eq!(pipe.client.stream_writable_next(), None);
12998
12999 assert_eq!(pipe.client.tx_cap, 0);
13000
13001 assert_eq!(pipe.advance(), Ok(()));
13002
13003 let mut b = [0; 70];
13004 pipe.server.stream_recv(0, &mut b).unwrap();
13005
13006 assert_eq!(pipe.advance(), Ok(()));
13007
13008 assert_ne!(pipe.client.tx_cap, 0);
13011
13012 assert_eq!(pipe.client.stream_writable_next(), Some(0));
13013 assert_eq!(pipe.client.stream_writable_next(), None);
13014 }
13015
13016 #[rstest]
13017 fn flow_control_limit_send(
13020 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13021 ) {
13022 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13023 assert_eq!(pipe.handshake(), Ok(()));
13024
13025 assert_eq!(
13026 pipe.client.stream_send(0, b"aaaaaaaaaaaaaaa", false),
13027 Ok(15)
13028 );
13029 assert_eq!(pipe.advance(), Ok(()));
13030 assert_eq!(
13031 pipe.client.stream_send(4, b"aaaaaaaaaaaaaaa", false),
13032 Ok(15)
13033 );
13034 assert_eq!(pipe.advance(), Ok(()));
13035 assert_eq!(pipe.client.stream_send(8, b"a", false), Err(Error::Done));
13036 assert_eq!(pipe.advance(), Ok(()));
13037
13038 let mut r = pipe.server.readable();
13039 assert!(r.next().is_some());
13040 assert!(r.next().is_some());
13041 assert!(r.next().is_none());
13042 }
13043
13044 #[rstest]
13045 fn invalid_initial_server(
13048 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13049 ) {
13050 let mut buf = [0; 65535];
13051 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13052
13053 let frames = [frame::Frame::Padding { len: 10 }];
13054
13055 let written = testing::encode_pkt(
13056 &mut pipe.client,
13057 packet::Type::Initial,
13058 &frames,
13059 &mut buf,
13060 )
13061 .unwrap();
13062
13063 buf[written - 1] = !buf[written - 1];
13067
13068 assert_eq!(pipe.server.timeout(), None);
13069
13070 assert_eq!(
13071 pipe.server_recv(&mut buf[..written]),
13072 Err(Error::CryptoFail)
13073 );
13074
13075 assert!(pipe.server.is_closed());
13076 }
13077
13078 #[rstest]
13079 fn invalid_initial_client(
13082 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13083 ) {
13084 let mut buf = [0; 65535];
13085 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13086
13087 let (len, _) = pipe.client.send(&mut buf).unwrap();
13089
13090 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(1200));
13092
13093 let frames = [frame::Frame::Padding { len: 10 }];
13094
13095 let written = testing::encode_pkt(
13096 &mut pipe.server,
13097 packet::Type::Initial,
13098 &frames,
13099 &mut buf,
13100 )
13101 .unwrap();
13102
13103 buf[written - 1] = !buf[written - 1];
13107
13108 assert_eq!(pipe.client_recv(&mut buf[..written]), Ok(71));
13110
13111 assert!(!pipe.client.is_closed());
13113
13114 assert!(pipe.client.idle_timer.is_some());
13116 }
13117
13118 #[rstest]
13119 fn invalid_initial_payload(
13122 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13123 ) {
13124 let mut buf = [0; 65535];
13125 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13126
13127 let mut b = octets::OctetsMut::with_slice(&mut buf);
13128
13129 let epoch = packet::Type::Initial.to_epoch().unwrap();
13130
13131 let pn = 0;
13132 let pn_len = packet::pkt_num_len(pn, 0);
13133
13134 let dcid = pipe.client.destination_id();
13135 let scid = pipe.client.source_id();
13136
13137 let hdr = Header {
13138 ty: packet::Type::Initial,
13139 version: pipe.client.version,
13140 dcid: ConnectionId::from_ref(&dcid),
13141 scid: ConnectionId::from_ref(&scid),
13142 pkt_num: 0,
13143 pkt_num_len: pn_len,
13144 token: pipe.client.token.clone(),
13145 versions: None,
13146 key_phase: false,
13147 };
13148
13149 hdr.to_bytes(&mut b).unwrap();
13150
13151 let payload_len = 4096;
13153
13154 let len = pn_len + payload_len;
13155 b.put_varint(len as u64).unwrap();
13156
13157 packet::encode_pkt_num(pn, pn_len, &mut b).unwrap();
13158
13159 let payload_offset = b.off();
13160
13161 let frames = [frame::Frame::Padding { len: 10 }];
13162
13163 for frame in &frames {
13164 frame.to_bytes(&mut b).unwrap();
13165 }
13166
13167 let crypto_ctx = &mut pipe.client.crypto_ctx[epoch];
13168
13169 let payload_len = frames.iter().fold(0, |acc, x| acc + x.wire_len());
13171
13172 let aead = crypto_ctx.crypto_seal.as_ref().unwrap();
13173
13174 let written = packet::encrypt_pkt(
13175 &mut b,
13176 pn,
13177 pn_len,
13178 payload_len,
13179 payload_offset,
13180 None,
13181 aead,
13182 )
13183 .unwrap();
13184
13185 assert_eq!(pipe.server.timeout(), None);
13186
13187 assert_eq!(
13188 pipe.server_recv(&mut buf[..written]),
13189 Err(Error::InvalidPacket)
13190 );
13191
13192 assert!(pipe.server.is_closed());
13193 }
13194
13195 #[rstest]
13196 fn invalid_packet(
13198 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13199 ) {
13200 let mut buf = [0; 65535];
13201
13202 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13203 assert_eq!(pipe.handshake(), Ok(()));
13204
13205 let frames = [frame::Frame::Padding { len: 10 }];
13206
13207 let written = testing::encode_pkt(
13208 &mut pipe.client,
13209 packet::Type::Short,
13210 &frames,
13211 &mut buf,
13212 )
13213 .unwrap();
13214
13215 buf[written - 1] = !buf[written - 1];
13219
13220 assert_eq!(pipe.server_recv(&mut buf[..written]), Ok(written));
13221
13222 buf[0] = 255;
13224
13225 assert_eq!(pipe.server_recv(&mut buf[..written]), Ok(written));
13226 }
13227
13228 #[rstest]
13229 fn recv_empty_buffer(
13230 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13231 ) {
13232 let mut buf = [0; 65535];
13233
13234 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13235 assert_eq!(pipe.handshake(), Ok(()));
13236
13237 assert_eq!(pipe.server_recv(&mut buf[..0]), Err(Error::BufferTooShort));
13238 }
13239
13240 #[rstest]
13241 fn stop_sending_before_flushed_packets(
13242 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13243 ) {
13244 let mut b = [0; 15];
13245
13246 let mut buf = [0; 65535];
13247
13248 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13249 assert_eq!(pipe.handshake(), Ok(()));
13250
13251 assert_eq!(pipe.client.stream_send(0, b"hello", true), Ok(5));
13253 assert_eq!(pipe.advance(), Ok(()));
13254
13255 let mut r = pipe.server.readable();
13257 assert_eq!(r.next(), Some(0));
13258 assert_eq!(r.next(), None);
13259
13260 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((5, true)));
13261 assert!(pipe.server.stream_finished(0));
13262
13263 let mut r = pipe.server.readable();
13264 assert_eq!(r.next(), None);
13265
13266 let mut r = pipe.server.writable();
13268 assert_eq!(r.next(), Some(0));
13269 assert_eq!(r.next(), None);
13270
13271 while pipe.server.stream_send(0, b"world", false) != Err(Error::Done) {}
13272
13273 let mut r = pipe.server.writable();
13274 assert_eq!(r.next(), None);
13275
13276 let frames = [frame::Frame::StopSending {
13278 stream_id: 0,
13279 error_code: 42,
13280 }];
13281
13282 let pkt_type = packet::Type::Short;
13283 let len = pipe
13284 .send_pkt_to_server(pkt_type, &frames, &mut buf)
13285 .unwrap();
13286
13287 let frames =
13289 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
13290
13291 let mut iter = frames.iter();
13292
13293 iter.next();
13295
13296 assert_eq!(
13297 iter.next(),
13298 Some(&frame::Frame::ResetStream {
13299 stream_id: 0,
13300 error_code: 42,
13301 final_size: 0,
13302 })
13303 );
13304
13305 let mut r = pipe.server.writable();
13307 assert_eq!(r.next(), Some(0));
13308 assert_eq!(r.next(), None);
13309
13310 assert_eq!(
13311 pipe.server.stream_send(0, b"world", true),
13312 Err(Error::StreamStopped(42)),
13313 );
13314
13315 assert_eq!(pipe.server.streams.len(), 1);
13316
13317 let mut ranges = ranges::RangeSet::default();
13319 ranges.insert(0..6);
13320
13321 let frames = [frame::Frame::ACK {
13322 ack_delay: 15,
13323 ranges,
13324 ecn_counts: None,
13325 }];
13326
13327 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(0));
13328
13329 assert_eq!(pipe.server.streams.len(), 0);
13331 }
13332
13333 #[rstest]
13334 fn reset_before_flushed_packets(
13335 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13336 ) {
13337 let mut b = [0; 15];
13338
13339 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
13340 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
13341 config
13342 .load_cert_chain_from_pem_file("examples/cert.crt")
13343 .unwrap();
13344 config
13345 .load_priv_key_from_pem_file("examples/cert.key")
13346 .unwrap();
13347 config
13348 .set_application_protos(&[b"proto1", b"proto2"])
13349 .unwrap();
13350 config.set_initial_max_data(30);
13351 config.set_initial_max_stream_data_bidi_local(5);
13352 config.set_initial_max_stream_data_bidi_remote(15);
13353 config.set_initial_max_streams_bidi(3);
13354 config.verify_peer(false);
13355
13356 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
13357 assert_eq!(pipe.handshake(), Ok(()));
13358
13359 assert_eq!(pipe.client.stream_send(0, b"hello", true), Ok(5));
13361 assert_eq!(pipe.advance(), Ok(()));
13362
13363 let mut r = pipe.server.readable();
13365 assert_eq!(r.next(), Some(0));
13366 assert_eq!(r.next(), None);
13367
13368 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((5, true)));
13369 assert!(pipe.server.stream_finished(0));
13370
13371 let mut r = pipe.server.readable();
13372 assert_eq!(r.next(), None);
13373
13374 let mut r = pipe.server.writable();
13376 assert_eq!(r.next(), Some(0));
13377 assert_eq!(r.next(), None);
13378
13379 assert_eq!(pipe.server.stream_send(0, b"helloworld", false), Ok(5));
13380 assert_eq!(pipe.advance(), Ok(()));
13381
13382 assert_eq!(pipe.client.stream_recv(0, &mut b), Ok((5, false)));
13384 assert_eq!(pipe.advance(), Ok(()));
13385
13386 assert_eq!(pipe.server.stream_send(0, b"world", false), Ok(5));
13389 pipe.server.stream_shutdown(0, Shutdown::Write, 42).unwrap();
13390 assert_eq!(pipe.advance(), Ok(()));
13391
13392 assert_eq!(pipe.server.streams.len(), 0);
13394 }
13395
13396 #[rstest]
13397 fn stream_limit_update_bidi(
13399 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13400 ) {
13401 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
13402 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
13403 config
13404 .load_cert_chain_from_pem_file("examples/cert.crt")
13405 .unwrap();
13406 config
13407 .load_priv_key_from_pem_file("examples/cert.key")
13408 .unwrap();
13409 config
13410 .set_application_protos(&[b"proto1", b"proto2"])
13411 .unwrap();
13412 config.set_initial_max_data(30);
13413 config.set_initial_max_stream_data_bidi_local(15);
13414 config.set_initial_max_stream_data_bidi_remote(15);
13415 config.set_initial_max_stream_data_uni(10);
13416 config.set_initial_max_streams_bidi(3);
13417 config.set_initial_max_streams_uni(0);
13418 config.verify_peer(false);
13419
13420 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
13421 assert_eq!(pipe.handshake(), Ok(()));
13422
13423 assert_eq!(pipe.client.stream_send(0, b"a", false), Ok(1));
13425 assert_eq!(pipe.advance(), Ok(()));
13426
13427 assert_eq!(pipe.client.stream_send(4, b"a", false), Ok(1));
13428 assert_eq!(pipe.advance(), Ok(()));
13429
13430 assert_eq!(pipe.client.stream_send(4, b"b", true), Ok(1));
13431 assert_eq!(pipe.advance(), Ok(()));
13432
13433 assert_eq!(pipe.client.stream_send(0, b"b", true), Ok(1));
13434 assert_eq!(pipe.advance(), Ok(()));
13435
13436 let mut b = [0; 15];
13438 pipe.server.stream_recv(0, &mut b).unwrap();
13439 pipe.server.stream_recv(4, &mut b).unwrap();
13440 assert_eq!(pipe.advance(), Ok(()));
13441
13442 assert_eq!(pipe.server.stream_send(0, b"a", false), Ok(1));
13444 assert_eq!(pipe.advance(), Ok(()));
13445
13446 assert_eq!(pipe.server.stream_send(4, b"a", false), Ok(1));
13447 assert_eq!(pipe.advance(), Ok(()));
13448
13449 assert_eq!(pipe.server.stream_send(4, b"b", true), Ok(1));
13450 assert_eq!(pipe.advance(), Ok(()));
13451
13452 assert_eq!(pipe.server.stream_send(0, b"b", true), Ok(1));
13453
13454 assert_eq!(pipe.advance(), Ok(()));
13456
13457 assert_eq!(pipe.client.stream_send(8, b"a", false), Ok(1));
13459 assert_eq!(pipe.advance(), Ok(()));
13460
13461 assert_eq!(pipe.client.stream_send(12, b"a", false), Ok(1));
13462 assert_eq!(pipe.advance(), Ok(()));
13463
13464 assert_eq!(pipe.client.stream_send(16, b"a", false), Ok(1));
13465 assert_eq!(pipe.advance(), Ok(()));
13466
13467 assert_eq!(
13468 pipe.client.stream_send(20, b"a", false),
13469 Err(Error::StreamLimit)
13470 );
13471
13472 assert_eq!(pipe.server.readable().len(), 3);
13473 }
13474
13475 #[rstest]
13476 fn stream_limit_update_uni(
13478 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13479 ) {
13480 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
13481 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
13482 config
13483 .load_cert_chain_from_pem_file("examples/cert.crt")
13484 .unwrap();
13485 config
13486 .load_priv_key_from_pem_file("examples/cert.key")
13487 .unwrap();
13488 config
13489 .set_application_protos(&[b"proto1", b"proto2"])
13490 .unwrap();
13491 config.set_initial_max_data(30);
13492 config.set_initial_max_stream_data_bidi_local(15);
13493 config.set_initial_max_stream_data_bidi_remote(15);
13494 config.set_initial_max_stream_data_uni(10);
13495 config.set_initial_max_streams_bidi(0);
13496 config.set_initial_max_streams_uni(3);
13497 config.verify_peer(false);
13498
13499 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
13500 assert_eq!(pipe.handshake(), Ok(()));
13501
13502 assert_eq!(pipe.client.stream_send(2, b"a", false), Ok(1));
13504 assert_eq!(pipe.advance(), Ok(()));
13505
13506 assert_eq!(pipe.client.stream_send(6, b"a", false), Ok(1));
13507 assert_eq!(pipe.advance(), Ok(()));
13508
13509 assert_eq!(pipe.client.stream_send(6, b"b", true), Ok(1));
13510 assert_eq!(pipe.advance(), Ok(()));
13511
13512 assert_eq!(pipe.client.stream_send(2, b"b", true), Ok(1));
13513 assert_eq!(pipe.advance(), Ok(()));
13514
13515 let mut b = [0; 15];
13517 pipe.server.stream_recv(2, &mut b).unwrap();
13518 pipe.server.stream_recv(6, &mut b).unwrap();
13519
13520 assert_eq!(pipe.advance(), Ok(()));
13522
13523 assert_eq!(pipe.client.stream_send(10, b"a", false), Ok(1));
13525 assert_eq!(pipe.advance(), Ok(()));
13526
13527 assert_eq!(pipe.client.stream_send(14, b"a", false), Ok(1));
13528 assert_eq!(pipe.advance(), Ok(()));
13529
13530 assert_eq!(pipe.client.stream_send(18, b"a", false), Ok(1));
13531 assert_eq!(pipe.advance(), Ok(()));
13532
13533 assert_eq!(
13534 pipe.client.stream_send(22, b"a", false),
13535 Err(Error::StreamLimit)
13536 );
13537
13538 assert_eq!(pipe.server.readable().len(), 3);
13539 }
13540
13541 #[rstest]
13542 fn stream_zero_length_fin(
13546 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13547 ) {
13548 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13549 assert_eq!(pipe.handshake(), Ok(()));
13550
13551 assert_eq!(
13552 pipe.client.stream_send(0, b"aaaaaaaaaaaaaaa", false),
13553 Ok(15)
13554 );
13555 assert_eq!(pipe.advance(), Ok(()));
13556
13557 let mut r = pipe.server.readable();
13558 assert_eq!(r.next(), Some(0));
13559 assert!(r.next().is_none());
13560
13561 let mut b = [0; 15];
13562 pipe.server.stream_recv(0, &mut b).unwrap();
13563 assert_eq!(pipe.advance(), Ok(()));
13564
13565 assert_eq!(pipe.client.stream_send(0, b"", true), Ok(0));
13567 assert_eq!(pipe.advance(), Ok(()));
13568
13569 let mut r = pipe.server.readable();
13571 assert_eq!(r.next(), Some(0));
13572 assert!(r.next().is_none());
13573
13574 let mut b = [0; 15];
13575 pipe.server.stream_recv(0, &mut b).unwrap();
13576 assert_eq!(pipe.advance(), Ok(()));
13577
13578 assert_eq!(pipe.client.stream_send(0, b"", true), Ok(0));
13580 assert_eq!(pipe.advance(), Ok(()));
13581
13582 let mut r = pipe.server.readable();
13585 assert_eq!(r.next(), None);
13586 }
13587
13588 #[rstest]
13589 fn stream_zero_length_fin_deferred_collection(
13593 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13594 ) {
13595 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13596 assert_eq!(pipe.handshake(), Ok(()));
13597
13598 assert_eq!(
13599 pipe.client.stream_send(0, b"aaaaaaaaaaaaaaa", false),
13600 Ok(15)
13601 );
13602 assert_eq!(pipe.advance(), Ok(()));
13603
13604 let mut r = pipe.server.readable();
13605 assert_eq!(r.next(), Some(0));
13606 assert!(r.next().is_none());
13607
13608 let mut b = [0; 15];
13609 pipe.server.stream_recv(0, &mut b).unwrap();
13610 assert_eq!(pipe.advance(), Ok(()));
13611
13612 assert_eq!(pipe.client.stream_send(0, b"", true), Ok(0));
13614 assert_eq!(pipe.advance(), Ok(()));
13615
13616 assert_eq!(pipe.server.stream_send(0, b"", true), Ok(0));
13618 assert_eq!(pipe.advance(), Ok(()));
13619
13620 let mut r = pipe.server.readable();
13622 assert_eq!(r.next(), Some(0));
13623 assert!(r.next().is_none());
13624
13625 let mut b = [0; 15];
13626 pipe.server.stream_recv(0, &mut b).unwrap();
13627 assert_eq!(pipe.advance(), Ok(()));
13628
13629 assert_eq!(pipe.client.stream_send(0, b"", true), Ok(0));
13631 assert_eq!(pipe.advance(), Ok(()));
13632
13633 let mut r = pipe.server.readable();
13636 assert_eq!(r.next(), None);
13637
13638 let mut r = pipe.client.readable();
13640 assert_eq!(r.next(), Some(0));
13641
13642 pipe.client.stream_recv(0, &mut b).unwrap();
13643 assert_eq!(pipe.advance(), Ok(()));
13644
13645 let mut r = pipe.client.readable();
13647 assert_eq!(r.next(), None);
13648 }
13649
13650 #[rstest]
13651 fn stream_zero_length_non_fin(
13654 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13655 ) {
13656 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13657 assert_eq!(pipe.handshake(), Ok(()));
13658
13659 assert_eq!(pipe.client.stream_send(0, b"", false), Ok(0));
13660
13661 assert_eq!(pipe.client.streams.len(), 1);
13663 assert_eq!(pipe.advance(), Ok(()));
13664
13665 let mut r = pipe.server.readable();
13668 assert!(r.next().is_none());
13669 }
13670
13671 #[rstest]
13672 fn collect_streams(
13674 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13675 ) {
13676 let mut buf = [0; 65535];
13677
13678 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13679 assert_eq!(pipe.handshake(), Ok(()));
13680
13681 assert_eq!(pipe.client.streams.len(), 0);
13682 assert_eq!(pipe.server.streams.len(), 0);
13683
13684 assert_eq!(pipe.client.stream_send(0, b"aaaaa", true), Ok(5));
13685 assert_eq!(pipe.advance(), Ok(()));
13686
13687 assert!(!pipe.client.stream_finished(0));
13688 assert!(!pipe.server.stream_finished(0));
13689
13690 assert_eq!(pipe.client.streams.len(), 1);
13691 assert_eq!(pipe.server.streams.len(), 1);
13692
13693 let mut b = [0; 5];
13694 pipe.server.stream_recv(0, &mut b).unwrap();
13695 assert_eq!(pipe.advance(), Ok(()));
13696
13697 assert_eq!(pipe.server.stream_send(0, b"aaaaa", true), Ok(5));
13698 assert_eq!(pipe.advance(), Ok(()));
13699
13700 assert!(!pipe.client.stream_finished(0));
13701 assert!(pipe.server.stream_finished(0));
13702
13703 assert_eq!(pipe.client.streams.len(), 1);
13704 assert_eq!(pipe.server.streams.len(), 0);
13705
13706 let mut b = [0; 5];
13707 pipe.client.stream_recv(0, &mut b).unwrap();
13708 assert_eq!(pipe.advance(), Ok(()));
13709
13710 assert_eq!(pipe.client.streams.len(), 0);
13711 assert_eq!(pipe.server.streams.len(), 0);
13712
13713 assert!(pipe.client.stream_finished(0));
13714 assert!(pipe.server.stream_finished(0));
13715
13716 assert_eq!(pipe.client.stream_send(0, b"", true), Err(Error::Done));
13717
13718 let frames = [frame::Frame::Stream {
13719 stream_id: 0,
13720 data: <RangeBuf>::from(b"aa", 0, false),
13721 }];
13722
13723 let pkt_type = packet::Type::Short;
13724 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(39));
13725 }
13726
13727 #[test]
13728 fn config_set_cc_algorithm_name() {
13729 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
13730
13731 assert_eq!(config.set_cc_algorithm_name("reno"), Ok(()));
13732
13733 assert_eq!(
13735 config.set_cc_algorithm_name("???"),
13736 Err(Error::CongestionControl)
13737 );
13738 }
13739
13740 #[rstest]
13741 fn peer_cert(
13742 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13743 ) {
13744 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
13745 assert_eq!(pipe.handshake(), Ok(()));
13746
13747 match pipe.client.peer_cert() {
13748 Some(c) => assert_eq!(c.len(), 753),
13749
13750 None => panic!("missing server certificate"),
13751 }
13752 }
13753
13754 #[rstest]
13755 fn peer_cert_chain(
13756 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13757 ) {
13758 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
13759 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
13760 config
13761 .load_cert_chain_from_pem_file("examples/cert-big.crt")
13762 .unwrap();
13763 config
13764 .load_priv_key_from_pem_file("examples/cert.key")
13765 .unwrap();
13766 config
13767 .set_application_protos(&[b"proto1", b"proto2"])
13768 .unwrap();
13769
13770 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
13771 assert_eq!(pipe.handshake(), Ok(()));
13772
13773 match pipe.client.peer_cert_chain() {
13774 Some(c) => assert_eq!(c.len(), 5),
13775
13776 None => panic!("missing server certificate chain"),
13777 }
13778 }
13779
13780 #[rstest]
13781 fn retry(
13782 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13783 ) {
13784 let mut buf = [0; 65535];
13785
13786 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
13787 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
13788 config
13789 .load_cert_chain_from_pem_file("examples/cert.crt")
13790 .unwrap();
13791 config
13792 .load_priv_key_from_pem_file("examples/cert.key")
13793 .unwrap();
13794 config
13795 .set_application_protos(&[b"proto1", b"proto2"])
13796 .unwrap();
13797
13798 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
13799
13800 let (mut len, _) = pipe.client.send(&mut buf).unwrap();
13802
13803 let hdr = Header::from_slice(&mut buf[..len], MAX_CONN_ID_LEN).unwrap();
13805
13806 let odcid = hdr.dcid.clone();
13807
13808 let mut scid = [0; MAX_CONN_ID_LEN];
13809 rand::rand_bytes(&mut scid[..]);
13810 let scid = ConnectionId::from_ref(&scid);
13811
13812 let token = b"quiche test retry token";
13813
13814 len = packet::retry(
13815 &hdr.scid,
13816 &hdr.dcid,
13817 &scid,
13818 token,
13819 hdr.version,
13820 &mut buf,
13821 )
13822 .unwrap();
13823
13824 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
13826
13827 let (len, send_info) = pipe.client.send(&mut buf).unwrap();
13828
13829 let hdr = Header::from_slice(&mut buf[..len], MAX_CONN_ID_LEN).unwrap();
13830 assert_eq!(&hdr.token.unwrap(), token);
13831
13832 pipe.server = accept(
13834 &scid,
13835 Some(&odcid),
13836 testing::Pipe::server_addr(),
13837 send_info.from,
13838 &mut config,
13839 )
13840 .unwrap();
13841 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
13842
13843 assert_eq!(pipe.advance(), Ok(()));
13844
13845 assert!(pipe.client.is_established());
13846 assert!(pipe.server.is_established());
13847 }
13848
13849 #[rstest]
13850 fn retry_with_pto(
13851 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13852 ) {
13853 let mut buf = [0; 65535];
13854
13855 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
13856 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
13857 config
13858 .load_cert_chain_from_pem_file("examples/cert.crt")
13859 .unwrap();
13860 config
13861 .load_priv_key_from_pem_file("examples/cert.key")
13862 .unwrap();
13863 config
13864 .set_application_protos(&[b"proto1", b"proto2"])
13865 .unwrap();
13866
13867 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
13868
13869 let (mut len, _) = pipe.client.send(&mut buf).unwrap();
13871
13872 let hdr = Header::from_slice(&mut buf[..len], MAX_CONN_ID_LEN).unwrap();
13874
13875 let odcid = hdr.dcid.clone();
13876
13877 let mut scid = [0; MAX_CONN_ID_LEN];
13878 rand::rand_bytes(&mut scid[..]);
13879 let scid = ConnectionId::from_ref(&scid);
13880
13881 let token = b"quiche test retry token";
13882
13883 len = packet::retry(
13884 &hdr.scid,
13885 &hdr.dcid,
13886 &scid,
13887 token,
13888 hdr.version,
13889 &mut buf,
13890 )
13891 .unwrap();
13892
13893 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
13895
13896 let (len, send_info) = pipe.client.send(&mut buf).unwrap();
13897
13898 let hdr = Header::from_slice(&mut buf[..len], MAX_CONN_ID_LEN).unwrap();
13899 assert_eq!(&hdr.token.unwrap(), token);
13900
13901 pipe.server = accept(
13903 &scid,
13904 Some(&odcid),
13905 testing::Pipe::server_addr(),
13906 send_info.from,
13907 &mut config,
13908 )
13909 .unwrap();
13910 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
13911
13912 let timer = pipe.client.timeout().unwrap();
13914 std::thread::sleep(timer + time::Duration::from_millis(1));
13915 pipe.client.on_timeout();
13916
13917 assert_eq!(pipe.advance(), Ok(()));
13918
13919 assert!(pipe.client.is_established());
13920 assert!(pipe.server.is_established());
13921 }
13922
13923 #[rstest]
13924 fn missing_retry_source_connection_id(
13925 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13926 ) {
13927 let mut buf = [0; 65535];
13928
13929 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
13930 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
13931 config
13932 .load_cert_chain_from_pem_file("examples/cert.crt")
13933 .unwrap();
13934 config
13935 .load_priv_key_from_pem_file("examples/cert.key")
13936 .unwrap();
13937 config
13938 .set_application_protos(&[b"proto1", b"proto2"])
13939 .unwrap();
13940
13941 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
13942
13943 let (mut len, _) = pipe.client.send(&mut buf).unwrap();
13945
13946 let hdr = Header::from_slice(&mut buf[..len], MAX_CONN_ID_LEN).unwrap();
13948
13949 let mut scid = [0; MAX_CONN_ID_LEN];
13950 rand::rand_bytes(&mut scid[..]);
13951 let scid = ConnectionId::from_ref(&scid);
13952
13953 let token = b"quiche test retry token";
13954
13955 len = packet::retry(
13956 &hdr.scid,
13957 &hdr.dcid,
13958 &scid,
13959 token,
13960 hdr.version,
13961 &mut buf,
13962 )
13963 .unwrap();
13964
13965 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
13967
13968 let (len, _) = pipe.client.send(&mut buf).unwrap();
13969
13970 let from = "127.0.0.1:1234".parse().unwrap();
13973 pipe.server =
13974 accept(&scid, None, testing::Pipe::server_addr(), from, &mut config)
13975 .unwrap();
13976 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
13977
13978 let flight = testing::emit_flight(&mut pipe.server).unwrap();
13979
13980 assert_eq!(
13981 testing::process_flight(&mut pipe.client, flight),
13982 Err(Error::InvalidTransportParam)
13983 );
13984 }
13985
13986 #[rstest]
13987 fn invalid_retry_source_connection_id(
13988 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
13989 ) {
13990 let mut buf = [0; 65535];
13991
13992 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
13993 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
13994 config
13995 .load_cert_chain_from_pem_file("examples/cert.crt")
13996 .unwrap();
13997 config
13998 .load_priv_key_from_pem_file("examples/cert.key")
13999 .unwrap();
14000 config
14001 .set_application_protos(&[b"proto1", b"proto2"])
14002 .unwrap();
14003
14004 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
14005
14006 let (mut len, _) = pipe.client.send(&mut buf).unwrap();
14008
14009 let hdr = Header::from_slice(&mut buf[..len], MAX_CONN_ID_LEN).unwrap();
14011
14012 let mut scid = [0; MAX_CONN_ID_LEN];
14013 rand::rand_bytes(&mut scid[..]);
14014 let scid = ConnectionId::from_ref(&scid);
14015
14016 let token = b"quiche test retry token";
14017
14018 len = packet::retry(
14019 &hdr.scid,
14020 &hdr.dcid,
14021 &scid,
14022 token,
14023 hdr.version,
14024 &mut buf,
14025 )
14026 .unwrap();
14027
14028 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
14030
14031 let (len, _) = pipe.client.send(&mut buf).unwrap();
14032
14033 let from = "127.0.0.1:1234".parse().unwrap();
14036 let odcid = ConnectionId::from_ref(b"bogus value");
14037 pipe.server = accept(
14038 &scid,
14039 Some(&odcid),
14040 testing::Pipe::server_addr(),
14041 from,
14042 &mut config,
14043 )
14044 .unwrap();
14045 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
14046
14047 let flight = testing::emit_flight(&mut pipe.server).unwrap();
14048
14049 assert_eq!(
14050 testing::process_flight(&mut pipe.client, flight),
14051 Err(Error::InvalidTransportParam)
14052 );
14053 }
14054
14055 #[rstest]
14056 fn zero_length_new_token(
14058 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14059 ) {
14060 let mut buf = [0; 65535];
14061
14062 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
14063 assert_eq!(pipe.handshake(), Ok(()));
14064
14065 let frames = vec![frame::Frame::NewToken { token: vec![] }];
14066
14067 let pkt_type = packet::Type::Short;
14068
14069 let written =
14070 testing::encode_pkt(&mut pipe.server, pkt_type, &frames, &mut buf)
14071 .unwrap();
14072
14073 assert_eq!(
14074 pipe.client_recv(&mut buf[..written]),
14075 Err(Error::InvalidFrame)
14076 );
14077 }
14078
14079 #[rstest]
14080 fn client_sent_new_token(
14082 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14083 ) {
14084 let mut buf = [0; 65535];
14085
14086 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
14087 assert_eq!(pipe.handshake(), Ok(()));
14088
14089 let frames = vec![frame::Frame::NewToken {
14090 token: vec![1, 2, 3],
14091 }];
14092
14093 let pkt_type = packet::Type::Short;
14094
14095 let written =
14096 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
14097 .unwrap();
14098
14099 assert_eq!(
14100 pipe.server_recv(&mut buf[..written]),
14101 Err(Error::InvalidPacket)
14102 );
14103 }
14104
14105 fn check_send(_: &mut impl Send) {}
14106
14107 #[rstest]
14108 fn config_must_be_send(
14109 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14110 ) {
14111 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
14112 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14113 check_send(&mut config);
14114 }
14115
14116 #[rstest]
14117 fn connection_must_be_send(
14118 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14119 ) {
14120 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
14121 check_send(&mut pipe.client);
14122 }
14123
14124 fn check_sync(_: &mut impl Sync) {}
14125
14126 #[rstest]
14127 fn config_must_be_sync(
14128 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14129 ) {
14130 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
14131 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14132 check_sync(&mut config);
14133 }
14134
14135 #[rstest]
14136 fn connection_must_be_sync(
14137 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14138 ) {
14139 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
14140 check_sync(&mut pipe.client);
14141 }
14142
14143 #[rstest]
14144 fn data_blocked(
14145 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14146 ) {
14147 let mut buf = [0; 65535];
14148
14149 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
14150 assert_eq!(pipe.handshake(), Ok(()));
14151
14152 assert_eq!(pipe.client.stream_send(0, b"aaaaaaaaaa", false), Ok(10));
14153 assert_eq!(pipe.client.blocked_limit, None);
14154 assert_eq!(pipe.advance(), Ok(()));
14155
14156 assert_eq!(pipe.client.stream_send(4, b"aaaaaaaaaa", false), Ok(10));
14157 assert_eq!(pipe.client.blocked_limit, None);
14158 assert_eq!(pipe.advance(), Ok(()));
14159
14160 assert_eq!(pipe.client.stream_send(8, b"aaaaaaaaaaa", false), Ok(10));
14161 assert_eq!(pipe.client.blocked_limit, Some(30));
14162
14163 let (len, _) = pipe.client.send(&mut buf).unwrap();
14164 assert_eq!(pipe.client.blocked_limit, None);
14165
14166 let frames =
14167 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
14168
14169 let mut iter = frames.iter();
14170
14171 assert_eq!(iter.next(), Some(&frame::Frame::DataBlocked { limit: 30 }));
14172
14173 assert_eq!(
14174 iter.next(),
14175 Some(&frame::Frame::Stream {
14176 stream_id: 8,
14177 data: <RangeBuf>::from(b"aaaaaaaaaa", 0, false),
14178 })
14179 );
14180
14181 assert_eq!(iter.next(), None);
14182 }
14183
14184 #[rstest]
14185 fn stream_data_blocked(
14186 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14187 ) {
14188 let mut buf = [0; 65535];
14189
14190 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
14191 assert_eq!(pipe.handshake(), Ok(()));
14192
14193 assert_eq!(pipe.client.stream_send(0, b"aaaaa", false), Ok(5));
14194 assert_eq!(pipe.client.streams.blocked().len(), 0);
14195
14196 assert_eq!(pipe.client.stream_send(0, b"aaaaa", false), Ok(5));
14197 assert_eq!(pipe.client.streams.blocked().len(), 0);
14198
14199 assert_eq!(pipe.client.stream_send(0, b"aaaaaa", false), Ok(5));
14200 assert_eq!(pipe.client.streams.blocked().len(), 1);
14201
14202 let (len, _) = pipe.client.send(&mut buf).unwrap();
14203 assert_eq!(pipe.client.streams.blocked().len(), 0);
14204
14205 let frames =
14206 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
14207
14208 let mut iter = frames.iter();
14209
14210 iter.next();
14212
14213 assert_eq!(
14214 iter.next(),
14215 Some(&frame::Frame::StreamDataBlocked {
14216 stream_id: 0,
14217 limit: 15,
14218 })
14219 );
14220
14221 assert_eq!(
14222 iter.next(),
14223 Some(&frame::Frame::Stream {
14224 stream_id: 0,
14225 data: <RangeBuf>::from(b"aaaaaaaaaaaaaaa", 0, false),
14226 })
14227 );
14228
14229 assert_eq!(iter.next(), None);
14230
14231 assert_eq!(pipe.client.stream_send(4, b"a", false), Ok(1));
14234
14235 let (len, _) = pipe.client.send(&mut buf).unwrap();
14236 assert_eq!(pipe.client.streams.blocked().len(), 0);
14237
14238 let frames =
14239 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
14240
14241 let mut iter = frames.iter();
14242
14243 assert_eq!(
14244 iter.next(),
14245 Some(&frame::Frame::Stream {
14246 stream_id: 4,
14247 data: <RangeBuf>::from(b"a", 0, false),
14248 })
14249 );
14250
14251 assert_eq!(iter.next(), None);
14252
14253 assert_eq!(
14256 pipe.client.stream_send(0, b"aaaaaa", false),
14257 Err(Error::Done)
14258 );
14259 assert_eq!(pipe.client.streams.blocked().len(), 0);
14260 assert_eq!(pipe.client.send(&mut buf), Err(Error::Done));
14261 }
14262
14263 #[rstest]
14264 fn stream_data_blocked_unblocked_flow_control(
14265 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14266 ) {
14267 let mut buf = [0; 65535];
14268 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
14269 assert_eq!(pipe.handshake(), Ok(()));
14270
14271 assert_eq!(
14272 pipe.client.stream_send(0, b"aaaaaaaaaaaaaaah", false),
14273 Ok(15)
14274 );
14275 assert_eq!(pipe.client.streams.blocked().len(), 1);
14276 assert_eq!(pipe.advance(), Ok(()));
14277 assert_eq!(pipe.client.streams.blocked().len(), 0);
14278
14279 assert_eq!(pipe.client.stream_send(0, b"h", false), Err(Error::Done));
14282 assert_eq!(pipe.client.streams.blocked().len(), 0);
14283
14284 assert_eq!(pipe.client.stream_send(0, b"h", false), Err(Error::Done));
14287 assert_eq!(pipe.client.send(&mut buf), Err(Error::Done));
14288
14289 assert_eq!(pipe.client.stream_send(0, b"h", false), Err(Error::Done));
14290 assert_eq!(pipe.client.send(&mut buf), Err(Error::Done));
14291
14292 assert_eq!(pipe.client.stream_send(0, b"h", false), Err(Error::Done));
14293 assert_eq!(pipe.client.send(&mut buf), Err(Error::Done));
14294
14295 let mut r = pipe.server.readable();
14297 assert_eq!(r.next(), Some(0));
14298 assert_eq!(r.next(), None);
14299
14300 let mut b = [0; 10];
14301 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((10, false)));
14302 assert_eq!(&b[..10], b"aaaaaaaaaa");
14303 assert_eq!(pipe.advance(), Ok(()));
14304
14305 assert_eq!(pipe.client.stream_send(0, b"hhhhhhhhhh!", false), Ok(10));
14306 assert_eq!(pipe.client.streams.blocked().len(), 1);
14307
14308 let (len, _) = pipe.client.send(&mut buf).unwrap();
14309 assert_eq!(pipe.client.streams.blocked().len(), 0);
14310
14311 let frames =
14312 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
14313
14314 let mut iter = frames.iter();
14315
14316 assert_eq!(
14317 iter.next(),
14318 Some(&frame::Frame::StreamDataBlocked {
14319 stream_id: 0,
14320 limit: 25,
14321 })
14322 );
14323
14324 assert_eq!(pipe.client.stream_send(0, b"!", false), Err(Error::Done));
14327 assert_eq!(pipe.client.streams.blocked().len(), 0);
14328 assert_eq!(pipe.client.send(&mut buf), Err(Error::Done));
14329 }
14330
14331 #[rstest]
14332 fn app_limited_true(
14333 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14334 ) {
14335 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
14336 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14337 config
14338 .set_application_protos(&[b"proto1", b"proto2"])
14339 .unwrap();
14340 config.set_initial_max_data(50000);
14341 config.set_initial_max_stream_data_bidi_local(50000);
14342 config.set_initial_max_stream_data_bidi_remote(50000);
14343 config.set_max_recv_udp_payload_size(1200);
14344 config.verify_peer(false);
14345
14346 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
14347 assert_eq!(pipe.handshake(), Ok(()));
14348
14349 assert_eq!(pipe.client.stream_send(0, b"a", true), Ok(1));
14351 assert_eq!(pipe.advance(), Ok(()));
14352
14353 let mut b = [0; 15];
14355 pipe.server.stream_recv(0, &mut b).unwrap();
14356 assert_eq!(pipe.advance(), Ok(()));
14357
14358 let send_buf = [0; 10000];
14360 assert_eq!(pipe.server.stream_send(0, &send_buf, false), Ok(10000));
14361 assert_eq!(pipe.advance(), Ok(()));
14362
14363 assert!(pipe
14365 .server
14366 .paths
14367 .get_active()
14368 .expect("no active")
14369 .recovery
14370 .app_limited());
14371 }
14372
14373 #[rstest]
14374 fn app_limited_false(
14375 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14376 ) {
14377 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
14378 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14379 config
14380 .set_application_protos(&[b"proto1", b"proto2"])
14381 .unwrap();
14382 config.set_initial_max_data(50000);
14383 config.set_initial_max_stream_data_bidi_local(50000);
14384 config.set_initial_max_stream_data_bidi_remote(50000);
14385 config.set_max_recv_udp_payload_size(1200);
14386 config.verify_peer(false);
14387
14388 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
14389 assert_eq!(pipe.handshake(), Ok(()));
14390
14391 assert_eq!(pipe.client.stream_send(0, b"a", true), Ok(1));
14393 assert_eq!(pipe.advance(), Ok(()));
14394
14395 let mut b = [0; 15];
14397 pipe.server.stream_recv(0, &mut b).unwrap();
14398 assert_eq!(pipe.advance(), Ok(()));
14399
14400 let send_buf1 = [0; 20000];
14402 assert_eq!(pipe.server.stream_send(0, &send_buf1, false), Ok(12000));
14403
14404 testing::emit_flight(&mut pipe.server).ok();
14405
14406 assert!(!pipe
14409 .server
14410 .paths
14411 .get_active()
14412 .expect("no active")
14413 .recovery
14414 .app_limited());
14415 }
14416
14417 #[test]
14418 fn tx_cap_factor() {
14419 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
14420 config
14421 .set_application_protos(&[b"proto1", b"proto2"])
14422 .unwrap();
14423 config
14424 .load_cert_chain_from_pem_file("examples/cert.crt")
14425 .unwrap();
14426 config
14427 .load_priv_key_from_pem_file("examples/cert.key")
14428 .unwrap();
14429 config.set_initial_max_data(50000);
14430 config.set_initial_max_stream_data_bidi_local(12000);
14431 config.set_initial_max_stream_data_bidi_remote(12000);
14432 config.set_initial_max_streams_bidi(3);
14433 config.set_initial_max_streams_uni(3);
14434 config.set_max_recv_udp_payload_size(1200);
14435 config.verify_peer(false);
14436
14437 config.set_send_capacity_factor(2.0);
14438
14439 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
14440 assert_eq!(pipe.handshake(), Ok(()));
14441
14442 assert_eq!(pipe.client.stream_send(0, b"a", true), Ok(1));
14444 assert_eq!(pipe.client.stream_send(4, b"a", true), Ok(1));
14445 assert_eq!(pipe.advance(), Ok(()));
14446
14447 let mut b = [0; 50000];
14448
14449 pipe.server.stream_recv(0, &mut b).unwrap();
14451 assert_eq!(pipe.advance(), Ok(()));
14452
14453 let send_buf = [0; 50000];
14455 assert_eq!(pipe.server.stream_send(0, &send_buf, false), Ok(12000));
14456 assert_eq!(pipe.server.stream_send(4, &send_buf, false), Ok(12000));
14457 assert_eq!(pipe.advance(), Ok(()));
14458
14459 let mut r = pipe.client.readable();
14460 assert_eq!(r.next(), Some(0));
14461 assert_eq!(pipe.client.stream_recv(0, &mut b), Ok((12000, false)));
14462
14463 assert_eq!(r.next(), Some(4));
14464 assert_eq!(pipe.client.stream_recv(4, &mut b), Ok((12000, false)));
14465
14466 assert_eq!(r.next(), None);
14467 }
14468
14469 #[rstest]
14470 fn sends_ack_only_pkt_when_full_cwnd_and_ack_elicited(
14471 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14472 ) {
14473 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
14474 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14475 config
14476 .load_cert_chain_from_pem_file("examples/cert.crt")
14477 .unwrap();
14478 config
14479 .load_priv_key_from_pem_file("examples/cert.key")
14480 .unwrap();
14481 config
14482 .set_application_protos(&[b"proto1", b"proto2"])
14483 .unwrap();
14484 config.set_initial_max_data(50000);
14485 config.set_initial_max_stream_data_bidi_local(50000);
14486 config.set_initial_max_stream_data_bidi_remote(50000);
14487 config.set_initial_max_streams_bidi(3);
14488 config.set_initial_max_streams_uni(3);
14489 config.set_max_recv_udp_payload_size(1200);
14490 config.verify_peer(false);
14491
14492 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
14493 assert_eq!(pipe.handshake(), Ok(()));
14494
14495 let send_buf1 = [0; 20000];
14498 assert_eq!(
14499 pipe.client.stream_send(0, &send_buf1, false),
14500 if cc_algorithm_name == "cubic" {
14501 Ok(12000)
14502 } else {
14503 if cfg!(feature = "openssl") {
14504 Ok(12345)
14505 } else {
14506 Ok(12299)
14507 }
14508 }
14509 );
14510
14511 testing::emit_flight(&mut pipe.client).ok();
14512
14513 assert_eq!(
14515 pipe.server.stream_send(1, &send_buf1[..500], false),
14516 Ok(500)
14517 );
14518
14519 testing::process_flight(
14520 &mut pipe.client,
14521 testing::emit_flight(&mut pipe.server).unwrap(),
14522 )
14523 .unwrap();
14524
14525 let mut buf = [0; 2000];
14526
14527 let ret = pipe.client.send(&mut buf);
14528
14529 assert_eq!(pipe.client.tx_cap, 0);
14530
14531 assert!(matches!(ret, Ok((_, _))), "the client should at least send one packet to acknowledge the newly received data");
14532
14533 let (sent, _) = ret.unwrap();
14534
14535 assert_ne!(sent, 0, "the client should at least send a pure ACK packet");
14536
14537 let frames =
14538 testing::decode_pkt(&mut pipe.server, &mut buf[..sent]).unwrap();
14539 assert_eq!(1, frames.len());
14540 assert!(
14541 matches!(frames[0], frame::Frame::ACK { .. }),
14542 "the packet sent by the client must be an ACK only packet"
14543 );
14544 }
14545
14546 #[rstest]
14549 fn sends_ack_only_pkt_when_full_cwnd_and_ack_elicited_despite_max_unacknowledging(
14550 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14551 ) {
14552 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
14553 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14554 config
14555 .load_cert_chain_from_pem_file("examples/cert.crt")
14556 .unwrap();
14557 config
14558 .load_priv_key_from_pem_file("examples/cert.key")
14559 .unwrap();
14560 config
14561 .set_application_protos(&[b"proto1", b"proto2"])
14562 .unwrap();
14563 config.set_initial_max_data(50000);
14564 config.set_initial_max_stream_data_bidi_local(50000);
14565 config.set_initial_max_stream_data_bidi_remote(50000);
14566 config.set_initial_max_streams_bidi(3);
14567 config.set_initial_max_streams_uni(3);
14568 config.set_max_recv_udp_payload_size(1200);
14569 config.verify_peer(false);
14570
14571 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
14572 assert_eq!(pipe.handshake(), Ok(()));
14573
14574 let send_buf1 = [0; 20000];
14577 assert_eq!(
14578 pipe.client.stream_send(0, &send_buf1, false),
14579 if cc_algorithm_name == "cubic" {
14580 Ok(12000)
14581 } else {
14582 if cfg!(feature = "openssl") {
14583 Ok(12345)
14584 } else {
14585 Ok(12299)
14586 }
14587 }
14588 );
14589
14590 testing::emit_flight(&mut pipe.client).ok();
14591
14592 let mut buf = [0; 2000];
14594 for _ in 0..recovery::MAX_OUTSTANDING_NON_ACK_ELICITING {
14595 let written = testing::encode_pkt(
14596 &mut pipe.server,
14597 packet::Type::Short,
14598 &[frame::Frame::Ping { mtu_probe: None }],
14599 &mut buf,
14600 )
14601 .unwrap();
14602
14603 pipe.client_recv(&mut buf[..written])
14604 .expect("client recv ping");
14605
14606 let ret = pipe.client.send(&mut buf);
14608
14609 assert!(matches!(ret, Ok((_, _))), "the client should at least send one packet to acknowledge the newly received data");
14610
14611 let (sent, _) = ret.unwrap();
14612
14613 assert_ne!(
14614 sent, 0,
14615 "the client should at least send a pure ACK packet"
14616 );
14617
14618 let frames =
14619 testing::decode_pkt(&mut pipe.server, &mut buf[..sent]).unwrap();
14620
14621 assert_eq!(1, frames.len());
14622
14623 assert!(
14624 matches!(frames[0], frame::Frame::ACK { .. }),
14625 "the packet sent by the client must be an ACK only packet"
14626 );
14627 }
14628
14629 assert_eq!(
14632 pipe.client.send(&mut buf),
14633 Err(Error::Done),
14634 "nothing for client to send after ACK-only packet"
14635 );
14636 }
14637
14638 #[rstest]
14639 fn app_limited_false_no_frame(
14640 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14641 ) {
14642 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
14643 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14644 config
14645 .set_application_protos(&[b"proto1", b"proto2"])
14646 .unwrap();
14647 config.set_initial_max_data(50000);
14648 config.set_initial_max_stream_data_bidi_local(50000);
14649 config.set_initial_max_stream_data_bidi_remote(50000);
14650 config.set_max_recv_udp_payload_size(1405);
14651 config.verify_peer(false);
14652
14653 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
14654 assert_eq!(pipe.handshake(), Ok(()));
14655
14656 assert_eq!(pipe.client.stream_send(0, b"a", true), Ok(1));
14658 assert_eq!(pipe.advance(), Ok(()));
14659
14660 let mut b = [0; 15];
14662 pipe.server.stream_recv(0, &mut b).unwrap();
14663 assert_eq!(pipe.advance(), Ok(()));
14664
14665 let send_buf1 = [0; 20000];
14667 assert_eq!(pipe.server.stream_send(0, &send_buf1, false), Ok(12000));
14668
14669 testing::emit_flight(&mut pipe.server).ok();
14670
14671 assert!(!pipe
14674 .server
14675 .paths
14676 .get_active()
14677 .expect("no active")
14678 .recovery
14679 .app_limited());
14680 }
14681
14682 #[rstest]
14683 fn app_limited_false_no_header(
14684 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14685 ) {
14686 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
14687 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14688 config
14689 .set_application_protos(&[b"proto1", b"proto2"])
14690 .unwrap();
14691 config.set_initial_max_data(50000);
14692 config.set_initial_max_stream_data_bidi_local(50000);
14693 config.set_initial_max_stream_data_bidi_remote(50000);
14694 config.set_max_recv_udp_payload_size(1406);
14695 config.verify_peer(false);
14696
14697 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
14698 assert_eq!(pipe.handshake(), Ok(()));
14699
14700 assert_eq!(pipe.client.stream_send(0, b"a", true), Ok(1));
14702 assert_eq!(pipe.advance(), Ok(()));
14703
14704 let mut b = [0; 15];
14706 pipe.server.stream_recv(0, &mut b).unwrap();
14707 assert_eq!(pipe.advance(), Ok(()));
14708
14709 let send_buf1 = [0; 20000];
14711 assert_eq!(pipe.server.stream_send(0, &send_buf1, false), Ok(12000));
14712
14713 testing::emit_flight(&mut pipe.server).ok();
14714
14715 assert!(!pipe
14718 .server
14719 .paths
14720 .get_active()
14721 .expect("no active")
14722 .recovery
14723 .app_limited());
14724 }
14725
14726 #[rstest]
14727 fn app_limited_not_changed_on_no_new_frames(
14728 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14729 ) {
14730 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
14731 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14732 config
14733 .set_application_protos(&[b"proto1", b"proto2"])
14734 .unwrap();
14735 config.set_initial_max_data(50000);
14736 config.set_initial_max_stream_data_bidi_local(50000);
14737 config.set_initial_max_stream_data_bidi_remote(50000);
14738 config.set_max_recv_udp_payload_size(1200);
14739 config.verify_peer(false);
14740
14741 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
14742 assert_eq!(pipe.handshake(), Ok(()));
14743
14744 assert_eq!(pipe.client.stream_send(0, b"a", true), Ok(1));
14746 assert_eq!(pipe.advance(), Ok(()));
14747
14748 let mut b = [0; 15];
14750 pipe.server.stream_recv(0, &mut b).unwrap();
14751 assert_eq!(pipe.advance(), Ok(()));
14752
14753 assert!(pipe
14756 .client
14757 .paths
14758 .get_active()
14759 .expect("no active")
14760 .recovery
14761 .app_limited());
14762
14763 assert_eq!(testing::emit_flight(&mut pipe.client), Err(Error::Done));
14765
14766 assert!(pipe
14768 .client
14769 .paths
14770 .get_active()
14771 .expect("no active")
14772 .recovery
14773 .app_limited());
14774 }
14775
14776 #[rstest]
14777 fn limit_ack_ranges(
14778 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14779 ) {
14780 let mut buf = [0; 65535];
14781
14782 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
14783 assert_eq!(pipe.handshake(), Ok(()));
14784
14785 let epoch = packet::Epoch::Application;
14786
14787 assert_eq!(pipe.server.pkt_num_spaces[epoch].recv_pkt_need_ack.len(), 0);
14788
14789 let frames = [
14790 frame::Frame::Ping { mtu_probe: None },
14791 frame::Frame::Padding { len: 3 },
14792 ];
14793
14794 let pkt_type = packet::Type::Short;
14795
14796 let mut last_packet_sent = 0;
14797
14798 for _ in 0..512 {
14799 let recv_count = pipe.server.recv_count;
14800
14801 last_packet_sent = pipe.client.next_pkt_num;
14802
14803 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf)
14804 .unwrap();
14805
14806 assert_eq!(pipe.server.recv_count, recv_count + 1);
14807
14808 pipe.client.next_pkt_num += 1;
14810 }
14811
14812 assert_eq!(
14813 pipe.server.pkt_num_spaces[epoch].recv_pkt_need_ack.len(),
14814 MAX_ACK_RANGES
14815 );
14816
14817 assert_eq!(
14818 pipe.server.pkt_num_spaces[epoch].recv_pkt_need_ack.first(),
14819 Some(last_packet_sent - ((MAX_ACK_RANGES as u64) - 1) * 2)
14820 );
14821
14822 assert_eq!(
14823 pipe.server.pkt_num_spaces[epoch].recv_pkt_need_ack.last(),
14824 Some(last_packet_sent)
14825 );
14826 }
14827
14828 #[rstest]
14829 fn stream_priority(
14831 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
14832 ) {
14833 const MAX_TEST_PACKET_SIZE: usize = 540;
14835
14836 let mut buf = [0; 65535];
14837
14838 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
14839 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
14840 config
14841 .load_cert_chain_from_pem_file("examples/cert.crt")
14842 .unwrap();
14843 config
14844 .load_priv_key_from_pem_file("examples/cert.key")
14845 .unwrap();
14846 config
14847 .set_application_protos(&[b"proto1", b"proto2"])
14848 .unwrap();
14849 config.set_initial_max_data(1_000_000);
14850 config.set_initial_max_stream_data_bidi_local(1_000_000);
14851 config.set_initial_max_stream_data_bidi_remote(1_000_000);
14852 config.set_initial_max_stream_data_uni(0);
14853 config.set_initial_max_streams_bidi(100);
14854 config.set_initial_max_streams_uni(0);
14855 config.verify_peer(false);
14856
14857 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
14858 assert_eq!(pipe.handshake(), Ok(()));
14859
14860 assert_eq!(pipe.client.stream_send(0, b"a", false), Ok(1));
14861 assert_eq!(pipe.advance(), Ok(()));
14862
14863 assert_eq!(pipe.client.stream_send(4, b"a", false), Ok(1));
14864 assert_eq!(pipe.advance(), Ok(()));
14865
14866 assert_eq!(pipe.client.stream_send(8, b"a", false), Ok(1));
14867 assert_eq!(pipe.advance(), Ok(()));
14868
14869 assert_eq!(pipe.client.stream_send(12, b"a", false), Ok(1));
14870 assert_eq!(pipe.advance(), Ok(()));
14871
14872 assert_eq!(pipe.client.stream_send(16, b"a", false), Ok(1));
14873 assert_eq!(pipe.advance(), Ok(()));
14874
14875 assert_eq!(pipe.client.stream_send(20, b"a", false), Ok(1));
14876 assert_eq!(pipe.advance(), Ok(()));
14877
14878 let mut b = [0; 1];
14879
14880 let out = [b'b'; 500];
14881
14882 pipe.server.stream_recv(0, &mut b).unwrap();
14889 assert_eq!(pipe.server.stream_priority(0, 255, true), Ok(()));
14890 pipe.server.stream_send(0, &out, false).unwrap();
14891 pipe.server.stream_send(0, &out, false).unwrap();
14892 pipe.server.stream_send(0, &out, false).unwrap();
14893
14894 pipe.server.stream_recv(12, &mut b).unwrap();
14895 assert_eq!(pipe.server.stream_priority(12, 42, true), Ok(()));
14896 pipe.server.stream_send(12, &out, false).unwrap();
14897 pipe.server.stream_send(12, &out, false).unwrap();
14898 pipe.server.stream_send(12, &out, false).unwrap();
14899
14900 pipe.server.stream_recv(16, &mut b).unwrap();
14901 assert_eq!(pipe.server.stream_priority(16, 10, false), Ok(()));
14902 pipe.server.stream_send(16, &out, false).unwrap();
14903 pipe.server.stream_send(16, &out, false).unwrap();
14904 pipe.server.stream_send(16, &out, false).unwrap();
14905
14906 pipe.server.stream_recv(4, &mut b).unwrap();
14907 assert_eq!(pipe.server.stream_priority(4, 42, true), Ok(()));
14908 pipe.server.stream_send(4, &out, false).unwrap();
14909 pipe.server.stream_send(4, &out, false).unwrap();
14910 pipe.server.stream_send(4, &out, false).unwrap();
14911
14912 pipe.server.stream_recv(8, &mut b).unwrap();
14913 assert_eq!(pipe.server.stream_priority(8, 10, false), Ok(()));
14914 pipe.server.stream_send(8, &out, false).unwrap();
14915 pipe.server.stream_send(8, &out, false).unwrap();
14916 pipe.server.stream_send(8, &out, false).unwrap();
14917
14918 pipe.server.stream_recv(20, &mut b).unwrap();
14919 assert_eq!(pipe.server.stream_priority(20, 42, false), Ok(()));
14920 pipe.server.stream_send(20, &out, false).unwrap();
14921 pipe.server.stream_send(20, &out, false).unwrap();
14922 pipe.server.stream_send(20, &out, false).unwrap();
14923
14924 let mut off = 0;
14926
14927 for _ in 1..=3 {
14928 let (len, _) =
14929 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
14930
14931 let frames =
14932 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
14933 let stream = frames.first().unwrap();
14934
14935 assert_eq!(stream, &frame::Frame::Stream {
14936 stream_id: 8,
14937 data: <RangeBuf>::from(&out, off, false),
14938 });
14939
14940 off = match stream {
14941 frame::Frame::Stream { data, .. } => data.max_off(),
14942
14943 _ => unreachable!(),
14944 };
14945 }
14946
14947 let mut off = 0;
14949
14950 for _ in 1..=3 {
14951 let (len, _) =
14952 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
14953
14954 let frames =
14955 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
14956 let stream = frames.first().unwrap();
14957
14958 assert_eq!(stream, &frame::Frame::Stream {
14959 stream_id: 16,
14960 data: <RangeBuf>::from(&out, off, false),
14961 });
14962
14963 off = match stream {
14964 frame::Frame::Stream { data, .. } => data.max_off(),
14965
14966 _ => unreachable!(),
14967 };
14968 }
14969
14970 let mut off = 0;
14972
14973 for _ in 1..=3 {
14974 let (len, _) =
14975 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
14976
14977 let frames =
14978 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
14979 let stream = frames.first().unwrap();
14980
14981 assert_eq!(stream, &frame::Frame::Stream {
14982 stream_id: 20,
14983 data: <RangeBuf>::from(&out, off, false),
14984 });
14985
14986 off = match stream {
14987 frame::Frame::Stream { data, .. } => data.max_off(),
14988
14989 _ => unreachable!(),
14990 };
14991 }
14992
14993 let mut off = 0;
14995
14996 for _ in 1..=3 {
14997 let (len, _) =
14998 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
14999
15000 let frames =
15001 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15002
15003 assert_eq!(
15004 frames.first(),
15005 Some(&frame::Frame::Stream {
15006 stream_id: 12,
15007 data: <RangeBuf>::from(&out, off, false),
15008 })
15009 );
15010
15011 let (len, _) =
15012 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
15013
15014 let frames =
15015 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15016
15017 let stream = frames.first().unwrap();
15018
15019 assert_eq!(stream, &frame::Frame::Stream {
15020 stream_id: 4,
15021 data: <RangeBuf>::from(&out, off, false),
15022 });
15023
15024 off = match stream {
15025 frame::Frame::Stream { data, .. } => data.max_off(),
15026
15027 _ => unreachable!(),
15028 };
15029 }
15030
15031 let mut off = 0;
15033
15034 for _ in 1..=3 {
15035 let (len, _) =
15036 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
15037
15038 let frames =
15039 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15040 let stream = frames.first().unwrap();
15041
15042 assert_eq!(stream, &frame::Frame::Stream {
15043 stream_id: 0,
15044 data: <RangeBuf>::from(&out, off, false),
15045 });
15046
15047 off = match stream {
15048 frame::Frame::Stream { data, .. } => data.max_off(),
15049
15050 _ => unreachable!(),
15051 };
15052 }
15053
15054 assert_eq!(pipe.server.send(&mut buf), Err(Error::Done));
15055 }
15056
15057 #[rstest]
15058 fn stream_reprioritize(
15060 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15061 ) {
15062 let mut buf = [0; 65535];
15063
15064 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15065 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15066 config
15067 .load_cert_chain_from_pem_file("examples/cert.crt")
15068 .unwrap();
15069 config
15070 .load_priv_key_from_pem_file("examples/cert.key")
15071 .unwrap();
15072 config
15073 .set_application_protos(&[b"proto1", b"proto2"])
15074 .unwrap();
15075 config.set_initial_max_data(30);
15076 config.set_initial_max_stream_data_bidi_local(15);
15077 config.set_initial_max_stream_data_bidi_remote(15);
15078 config.set_initial_max_stream_data_uni(0);
15079 config.set_initial_max_streams_bidi(5);
15080 config.set_initial_max_streams_uni(0);
15081 config.verify_peer(false);
15082
15083 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
15084 assert_eq!(pipe.handshake(), Ok(()));
15085
15086 assert_eq!(pipe.client.stream_send(0, b"a", false), Ok(1));
15087 assert_eq!(pipe.advance(), Ok(()));
15088
15089 assert_eq!(pipe.client.stream_send(4, b"a", false), Ok(1));
15090 assert_eq!(pipe.advance(), Ok(()));
15091
15092 assert_eq!(pipe.client.stream_send(8, b"a", false), Ok(1));
15093 assert_eq!(pipe.advance(), Ok(()));
15094
15095 assert_eq!(pipe.client.stream_send(12, b"a", false), Ok(1));
15096 assert_eq!(pipe.advance(), Ok(()));
15097
15098 let mut b = [0; 1];
15099
15100 pipe.server.stream_recv(0, &mut b).unwrap();
15101 assert_eq!(pipe.server.stream_priority(0, 255, true), Ok(()));
15102 pipe.server.stream_send(0, b"b", false).unwrap();
15103
15104 pipe.server.stream_recv(12, &mut b).unwrap();
15105 assert_eq!(pipe.server.stream_priority(12, 42, true), Ok(()));
15106 pipe.server.stream_send(12, b"b", false).unwrap();
15107
15108 pipe.server.stream_recv(8, &mut b).unwrap();
15109 assert_eq!(pipe.server.stream_priority(8, 10, true), Ok(()));
15110 pipe.server.stream_send(8, b"b", false).unwrap();
15111
15112 pipe.server.stream_recv(4, &mut b).unwrap();
15113 assert_eq!(pipe.server.stream_priority(4, 42, true), Ok(()));
15114 pipe.server.stream_send(4, b"b", false).unwrap();
15115
15116 assert_eq!(pipe.server.stream_priority(0, 20, true), Ok(()));
15118
15119 let (len, _) = pipe.server.send(&mut buf).unwrap();
15121
15122 let frames =
15123 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15124
15125 assert_eq!(
15126 frames.first(),
15127 Some(&frame::Frame::Stream {
15128 stream_id: 8,
15129 data: <RangeBuf>::from(b"b", 0, false),
15130 })
15131 );
15132
15133 let (len, _) = pipe.server.send(&mut buf).unwrap();
15135
15136 let frames =
15137 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15138
15139 assert_eq!(
15140 frames.first(),
15141 Some(&frame::Frame::Stream {
15142 stream_id: 0,
15143 data: <RangeBuf>::from(b"b", 0, false),
15144 })
15145 );
15146
15147 let (len, _) = pipe.server.send(&mut buf).unwrap();
15149
15150 let frames =
15151 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15152
15153 assert_eq!(
15154 frames.first(),
15155 Some(&frame::Frame::Stream {
15156 stream_id: 12,
15157 data: <RangeBuf>::from(b"b", 0, false),
15158 })
15159 );
15160
15161 let (len, _) = pipe.server.send(&mut buf).unwrap();
15162
15163 let frames =
15164 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15165
15166 assert_eq!(
15167 frames.first(),
15168 Some(&frame::Frame::Stream {
15169 stream_id: 4,
15170 data: <RangeBuf>::from(b"b", 0, false),
15171 })
15172 );
15173
15174 assert_eq!(pipe.server.send(&mut buf), Err(Error::Done));
15175 }
15176
15177 #[rstest]
15178 fn stream_datagram_priority(
15180 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15181 ) {
15182 const MAX_TEST_PACKET_SIZE: usize = 540;
15184
15185 let mut buf = [0; 65535];
15186
15187 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15188 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15189 config
15190 .load_cert_chain_from_pem_file("examples/cert.crt")
15191 .unwrap();
15192 config
15193 .load_priv_key_from_pem_file("examples/cert.key")
15194 .unwrap();
15195 config
15196 .set_application_protos(&[b"proto1", b"proto2"])
15197 .unwrap();
15198 config.set_initial_max_data(1_000_000);
15199 config.set_initial_max_stream_data_bidi_local(1_000_000);
15200 config.set_initial_max_stream_data_bidi_remote(1_000_000);
15201 config.set_initial_max_stream_data_uni(0);
15202 config.set_initial_max_streams_bidi(100);
15203 config.set_initial_max_streams_uni(0);
15204 config.enable_dgram(true, 10, 10);
15205 config.verify_peer(false);
15206
15207 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
15208 assert_eq!(pipe.handshake(), Ok(()));
15209
15210 assert_eq!(pipe.client.stream_send(0, b"a", false), Ok(1));
15211 assert_eq!(pipe.advance(), Ok(()));
15212
15213 assert_eq!(pipe.client.stream_send(4, b"a", false), Ok(1));
15214 assert_eq!(pipe.advance(), Ok(()));
15215
15216 let mut b = [0; 1];
15217
15218 let out = [b'b'; 500];
15219
15220 pipe.server.stream_recv(0, &mut b).unwrap();
15227 assert_eq!(pipe.server.stream_priority(0, 255, true), Ok(()));
15228 pipe.server.stream_send(0, &out, false).unwrap();
15229 pipe.server.stream_send(0, &out, false).unwrap();
15230 pipe.server.stream_send(0, &out, false).unwrap();
15231
15232 assert_eq!(pipe.server.stream_priority(4, 255, true), Ok(()));
15233 pipe.server.stream_send(4, &out, false).unwrap();
15234 pipe.server.stream_send(4, &out, false).unwrap();
15235 pipe.server.stream_send(4, &out, false).unwrap();
15236
15237 for _ in 1..=6 {
15238 assert_eq!(pipe.server.dgram_send(&out), Ok(()));
15239 }
15240
15241 let mut off_0 = 0;
15242 let mut off_4 = 0;
15243
15244 for _ in 1..=3 {
15245 let (len, _) =
15247 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
15248
15249 let frames =
15250 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15251 let mut frame_iter = frames.iter();
15252
15253 assert_eq!(frame_iter.next().unwrap(), &frame::Frame::Datagram {
15254 data: out.into()
15255 });
15256 assert_eq!(frame_iter.next(), None);
15257
15258 let (len, _) =
15260 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
15261
15262 let frames =
15263 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15264 let mut frame_iter = frames.iter();
15265 let stream = frame_iter.next().unwrap();
15266
15267 assert_eq!(stream, &frame::Frame::Stream {
15268 stream_id: 0,
15269 data: <RangeBuf>::from(&out, off_0, false),
15270 });
15271
15272 off_0 = match stream {
15273 frame::Frame::Stream { data, .. } => data.max_off(),
15274
15275 _ => unreachable!(),
15276 };
15277 assert_eq!(frame_iter.next(), None);
15278
15279 let (len, _) =
15281 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
15282
15283 let frames =
15284 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15285 let mut frame_iter = frames.iter();
15286
15287 assert_eq!(frame_iter.next().unwrap(), &frame::Frame::Datagram {
15288 data: out.into()
15289 });
15290 assert_eq!(frame_iter.next(), None);
15291
15292 let (len, _) =
15294 pipe.server.send(&mut buf[..MAX_TEST_PACKET_SIZE]).unwrap();
15295
15296 let frames =
15297 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
15298 let mut frame_iter = frames.iter();
15299 let stream = frame_iter.next().unwrap();
15300
15301 assert_eq!(stream, &frame::Frame::Stream {
15302 stream_id: 4,
15303 data: <RangeBuf>::from(&out, off_4, false),
15304 });
15305
15306 off_4 = match stream {
15307 frame::Frame::Stream { data, .. } => data.max_off(),
15308
15309 _ => unreachable!(),
15310 };
15311 assert_eq!(frame_iter.next(), None);
15312 }
15313 }
15314
15315 #[rstest]
15316 fn early_retransmit(
15318 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15319 ) {
15320 let mut buf = [0; 65535];
15321
15322 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
15323 assert_eq!(pipe.handshake(), Ok(()));
15324
15325 assert_eq!(pipe.client.stream_send(0, b"a", false), Ok(1));
15327 assert_eq!(pipe.advance(), Ok(()));
15328
15329 assert_eq!(pipe.client.stream_send(4, b"b", false), Ok(1));
15331 assert!(pipe.client.send(&mut buf).is_ok());
15332
15333 let timer = pipe.client.timeout().unwrap();
15335 std::thread::sleep(timer + time::Duration::from_millis(1));
15336
15337 pipe.client.on_timeout();
15338
15339 let epoch = packet::Epoch::Application;
15340 assert_eq!(
15341 pipe.client
15342 .paths
15343 .get_active()
15344 .expect("no active")
15345 .recovery
15346 .loss_probes(epoch),
15347 1,
15348 );
15349
15350 let (len, _) = pipe.client.send(&mut buf).unwrap();
15352 assert_eq!(
15353 pipe.client
15354 .paths
15355 .get_active()
15356 .expect("no active")
15357 .recovery
15358 .loss_probes(epoch),
15359 0,
15360 );
15361
15362 let frames =
15363 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
15364
15365 let mut iter = frames.iter();
15366
15367 iter.next();
15369
15370 assert_eq!(
15371 iter.next(),
15372 Some(&frame::Frame::Stream {
15373 stream_id: 4,
15374 data: <RangeBuf>::from(b"b", 0, false),
15375 })
15376 );
15377 assert_eq!(pipe.client.stats().retrans, 1);
15378 }
15379
15380 #[rstest]
15381 fn dont_coalesce_probes(
15383 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15384 ) {
15385 let mut buf = [0; 65535];
15386
15387 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
15388
15389 let (len, _) = pipe.client.send(&mut buf).unwrap();
15391 assert_eq!(len, 1200);
15392
15393 let timer = pipe.client.timeout().unwrap();
15395 std::thread::sleep(timer + time::Duration::from_millis(1));
15396
15397 pipe.client.on_timeout();
15398
15399 let epoch = packet::Epoch::Initial;
15400 assert_eq!(
15401 pipe.client
15402 .paths
15403 .get_active()
15404 .expect("no active")
15405 .recovery
15406 .loss_probes(epoch),
15407 1,
15408 );
15409
15410 let (len, _) = pipe.client.send(&mut buf).unwrap();
15412 assert_eq!(len, 1200);
15413 assert_eq!(
15414 pipe.client
15415 .paths
15416 .get_active()
15417 .expect("no active")
15418 .recovery
15419 .loss_probes(epoch),
15420 0,
15421 );
15422
15423 let timer = pipe.client.timeout().unwrap();
15425 std::thread::sleep(timer + time::Duration::from_millis(1));
15426
15427 pipe.client.on_timeout();
15428
15429 assert_eq!(
15430 pipe.client
15431 .paths
15432 .get_active()
15433 .expect("no active")
15434 .recovery
15435 .loss_probes(epoch),
15436 2,
15437 );
15438
15439 let (len, _) = pipe.client.send(&mut buf).unwrap();
15441 assert_eq!(len, 1200);
15442 assert_eq!(
15443 pipe.client
15444 .paths
15445 .get_active()
15446 .expect("no active")
15447 .recovery
15448 .loss_probes(epoch),
15449 1,
15450 );
15451
15452 let (len, _) = pipe.client.send(&mut buf).unwrap();
15454 assert_eq!(len, 1200);
15455 assert_eq!(
15456 pipe.client
15457 .paths
15458 .get_active()
15459 .expect("no active")
15460 .recovery
15461 .loss_probes(epoch),
15462 0,
15463 );
15464 }
15465
15466 #[rstest]
15467 fn coalesce_padding_short(
15468 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15469 ) {
15470 let mut buf = [0; 65535];
15471
15472 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
15473
15474 let (len, _) = pipe.client.send(&mut buf).unwrap();
15476 assert_eq!(len, MIN_CLIENT_INITIAL_LEN);
15477 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
15478
15479 let (len, _) = pipe.server.send(&mut buf).unwrap();
15481 assert_eq!(len, MIN_CLIENT_INITIAL_LEN);
15482 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
15483
15484 let (len, _) = pipe.server.send(&mut buf).unwrap();
15485 assert_eq!(pipe.client_recv(&mut buf[..len]), Ok(len));
15486
15487 assert!(pipe.client.is_established());
15489 assert_eq!(pipe.client.stream_send(4, b"hello", true), Ok(5));
15490
15491 let (len, _) = pipe.client.send(&mut buf).unwrap();
15493 assert_eq!(len, MIN_CLIENT_INITIAL_LEN);
15494 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
15495
15496 assert_eq!(pipe.client.sent_count, pipe.server.recv_count);
15498 assert_eq!(pipe.server.sent_count, pipe.client.recv_count);
15499 }
15500
15501 #[rstest]
15502 fn handshake_anti_deadlock(
15504 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15505 ) {
15506 let mut buf = [0; 65535];
15507
15508 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
15509 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15510 config
15511 .load_cert_chain_from_pem_file("examples/cert-big.crt")
15512 .unwrap();
15513 config
15514 .load_priv_key_from_pem_file("examples/cert.key")
15515 .unwrap();
15516 config
15517 .set_application_protos(&[b"proto1", b"proto2"])
15518 .unwrap();
15519
15520 let mut pipe = testing::Pipe::with_server_config(&mut config).unwrap();
15521
15522 assert!(!pipe.client.handshake_status().has_handshake_keys);
15523 assert!(!pipe.client.handshake_status().peer_verified_address);
15524 assert!(!pipe.server.handshake_status().has_handshake_keys);
15525 assert!(pipe.server.handshake_status().peer_verified_address);
15526
15527 let (len, _) = pipe.client.send(&mut buf).unwrap();
15529 assert_eq!(len, 1200);
15530
15531 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
15534 let flight = testing::emit_flight(&mut pipe.server).unwrap();
15535
15536 assert!(!pipe.client.handshake_status().has_handshake_keys);
15537 assert!(!pipe.client.handshake_status().peer_verified_address);
15538 assert!(pipe.server.handshake_status().has_handshake_keys);
15539 assert!(pipe.server.handshake_status().peer_verified_address);
15540
15541 testing::process_flight(&mut pipe.client, flight).unwrap();
15544 testing::emit_flight(&mut pipe.client).unwrap();
15545
15546 assert!(pipe.client.handshake_status().has_handshake_keys);
15547 assert!(!pipe.client.handshake_status().peer_verified_address);
15548 assert!(pipe.server.handshake_status().has_handshake_keys);
15549 assert!(pipe.server.handshake_status().peer_verified_address);
15550
15551 assert!(pipe.client.timeout().is_some());
15553 }
15554
15555 #[rstest]
15556 fn handshake_packet_type_corruption(
15559 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15560 ) {
15561 let mut buf = [0; 65535];
15562
15563 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
15564
15565 let (len, _) = pipe.client.send(&mut buf).unwrap();
15567 assert_eq!(len, 1200);
15568
15569 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
15571
15572 let flight = testing::emit_flight(&mut pipe.server).unwrap();
15573 testing::process_flight(&mut pipe.client, flight).unwrap();
15574
15575 let active_pid =
15577 pipe.client.paths.get_active_path_id().expect("no active");
15578 let (ty, len) = pipe
15579 .client
15580 .send_single(&mut buf, active_pid, false, time::Instant::now())
15581 .unwrap();
15582 assert_eq!(ty, Type::Initial);
15583
15584 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
15585
15586 let (ty, len) = pipe
15588 .client
15589 .send_single(&mut buf, active_pid, false, time::Instant::now())
15590 .unwrap();
15591 assert_eq!(ty, Type::Handshake);
15592
15593 buf[0] &= !(0x20);
15595
15596 let hdr = Header::from_slice(&mut buf[..len], 0).unwrap();
15597 assert_eq!(hdr.ty, Type::Initial);
15598
15599 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
15601 }
15602
15603 #[rstest]
15604 fn dgram_send_fails_invalidstate(
15605 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15606 ) {
15607 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
15608 assert_eq!(pipe.handshake(), Ok(()));
15609
15610 assert_eq!(
15611 pipe.client.dgram_send(b"hello, world"),
15612 Err(Error::InvalidState)
15613 );
15614 }
15615
15616 #[rstest]
15617 fn dgram_send_app_limited(
15618 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15619 ) {
15620 let mut buf = [0; 65535];
15621 let send_buf = [0xcf; 1000];
15622
15623 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15624 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15625 config
15626 .load_cert_chain_from_pem_file("examples/cert.crt")
15627 .unwrap();
15628 config
15629 .load_priv_key_from_pem_file("examples/cert.key")
15630 .unwrap();
15631 config
15632 .set_application_protos(&[b"proto1", b"proto2"])
15633 .unwrap();
15634 config.set_initial_max_data(30);
15635 config.set_initial_max_stream_data_bidi_local(15);
15636 config.set_initial_max_stream_data_bidi_remote(15);
15637 config.set_initial_max_stream_data_uni(10);
15638 config.set_initial_max_streams_bidi(3);
15639 config.set_initial_max_streams_uni(3);
15640 config.enable_dgram(true, 1000, 1000);
15641 config.set_max_recv_udp_payload_size(1200);
15642 config.verify_peer(false);
15643
15644 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
15645 assert_eq!(pipe.handshake(), Ok(()));
15646
15647 for _ in 0..1000 {
15648 assert_eq!(pipe.client.dgram_send(&send_buf), Ok(()));
15649 }
15650
15651 assert_eq!(
15652 !pipe
15653 .client
15654 .paths
15655 .get_active()
15656 .expect("no active")
15657 .recovery
15658 .app_limited(),
15659 cc_algorithm_name != "bbr2_gcongestion"
15662 );
15663 assert_eq!(pipe.client.dgram_send_queue.byte_size(), 1_000_000);
15664
15665 let (len, _) = pipe.client.send(&mut buf).unwrap();
15666
15667 assert_ne!(pipe.client.dgram_send_queue.byte_size(), 0);
15668 assert_ne!(pipe.client.dgram_send_queue.byte_size(), 1_000_000);
15669 assert_eq!(
15670 !pipe
15671 .client
15672 .paths
15673 .get_active()
15674 .expect("no active")
15675 .recovery
15676 .app_limited(),
15677 cc_algorithm_name != "bbr2_gcongestion"
15678 );
15679
15680 assert_eq!(pipe.server_recv(&mut buf[..len]), Ok(len));
15681
15682 let flight = testing::emit_flight(&mut pipe.client).unwrap();
15683 testing::process_flight(&mut pipe.server, flight).unwrap();
15684
15685 let flight = testing::emit_flight(&mut pipe.server).unwrap();
15686 testing::process_flight(&mut pipe.client, flight).unwrap();
15687
15688 assert_ne!(pipe.client.dgram_send_queue.byte_size(), 0);
15689 assert_ne!(pipe.client.dgram_send_queue.byte_size(), 1_000_000);
15690
15691 assert_eq!(
15692 !pipe
15693 .client
15694 .paths
15695 .get_active()
15696 .expect("no active")
15697 .recovery
15698 .app_limited(),
15699 cc_algorithm_name != "bbr2_gcongestion"
15700 );
15701 }
15702
15703 #[rstest]
15704 fn dgram_single_datagram(
15705 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15706 ) {
15707 let mut buf = [0; 65535];
15708
15709 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15710 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15711 config
15712 .load_cert_chain_from_pem_file("examples/cert.crt")
15713 .unwrap();
15714 config
15715 .load_priv_key_from_pem_file("examples/cert.key")
15716 .unwrap();
15717 config
15718 .set_application_protos(&[b"proto1", b"proto2"])
15719 .unwrap();
15720 config.set_initial_max_data(30);
15721 config.set_initial_max_stream_data_bidi_local(15);
15722 config.set_initial_max_stream_data_bidi_remote(15);
15723 config.set_initial_max_stream_data_uni(10);
15724 config.set_initial_max_streams_bidi(3);
15725 config.set_initial_max_streams_uni(3);
15726 config.enable_dgram(true, 10, 10);
15727 config.verify_peer(false);
15728
15729 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
15730 assert_eq!(pipe.handshake(), Ok(()));
15731
15732 assert_eq!(pipe.client.dgram_send(b"hello, world"), Ok(()));
15733
15734 assert_eq!(pipe.advance(), Ok(()));
15735
15736 let result1 = pipe.server.dgram_recv(&mut buf);
15737 assert_eq!(result1, Ok(12));
15738
15739 let result2 = pipe.server.dgram_recv(&mut buf);
15740 assert_eq!(result2, Err(Error::Done));
15741 }
15742
15743 #[rstest]
15744 fn dgram_multiple_datagrams(
15745 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15746 ) {
15747 let mut buf = [0; 65535];
15748
15749 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15750 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15751 config
15752 .load_cert_chain_from_pem_file("examples/cert.crt")
15753 .unwrap();
15754 config
15755 .load_priv_key_from_pem_file("examples/cert.key")
15756 .unwrap();
15757 config
15758 .set_application_protos(&[b"proto1", b"proto2"])
15759 .unwrap();
15760 config.set_initial_max_data(30);
15761 config.set_initial_max_stream_data_bidi_local(15);
15762 config.set_initial_max_stream_data_bidi_remote(15);
15763 config.set_initial_max_stream_data_uni(10);
15764 config.set_initial_max_streams_bidi(3);
15765 config.set_initial_max_streams_uni(3);
15766 config.enable_dgram(true, 2, 3);
15767 config.verify_peer(false);
15768
15769 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
15770 assert_eq!(pipe.handshake(), Ok(()));
15771
15772 assert_eq!(pipe.client.dgram_send_queue_len(), 0);
15773 assert_eq!(pipe.client.dgram_send_queue_byte_size(), 0);
15774
15775 assert_eq!(pipe.client.dgram_send(b"hello, world"), Ok(()));
15776 assert_eq!(pipe.client.dgram_send(b"ciao, mondo"), Ok(()));
15777 assert_eq!(pipe.client.dgram_send(b"hola, mundo"), Ok(()));
15778 assert!(pipe.client.is_dgram_send_queue_full());
15779
15780 assert_eq!(pipe.client.dgram_send_queue_byte_size(), 34);
15781
15782 pipe.client
15783 .dgram_purge_outgoing(|d: &[u8]| -> bool { d[0] == b'c' });
15784
15785 assert_eq!(pipe.client.dgram_send_queue_len(), 2);
15786 assert_eq!(pipe.client.dgram_send_queue_byte_size(), 23);
15787 assert!(!pipe.client.is_dgram_send_queue_full());
15788
15789 assert_eq!(pipe.server.dgram_recv_queue_len(), 0);
15791
15792 assert_eq!(pipe.advance(), Ok(()));
15793
15794 assert_eq!(pipe.client.dgram_send_queue_len(), 0);
15796 assert_eq!(pipe.client.dgram_send_queue_byte_size(), 0);
15797
15798 assert_eq!(pipe.server.dgram_recv_queue_len(), 2);
15799 assert_eq!(pipe.server.dgram_recv_queue_byte_size(), 23);
15800 assert!(pipe.server.is_dgram_recv_queue_full());
15801
15802 let result1 = pipe.server.dgram_recv(&mut buf);
15803 assert_eq!(result1, Ok(12));
15804 assert_eq!(buf[0], b'h');
15805 assert_eq!(buf[1], b'e');
15806 assert!(!pipe.server.is_dgram_recv_queue_full());
15807
15808 let result2 = pipe.server.dgram_recv(&mut buf);
15809 assert_eq!(result2, Ok(11));
15810 assert_eq!(buf[0], b'h');
15811 assert_eq!(buf[1], b'o');
15812
15813 let result3 = pipe.server.dgram_recv(&mut buf);
15814 assert_eq!(result3, Err(Error::Done));
15815
15816 assert_eq!(pipe.server.dgram_recv_queue_len(), 0);
15817 assert_eq!(pipe.server.dgram_recv_queue_byte_size(), 0);
15818 }
15819
15820 #[rstest]
15821 fn dgram_send_queue_overflow(
15822 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15823 ) {
15824 let mut buf = [0; 65535];
15825
15826 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15827 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15828 config
15829 .load_cert_chain_from_pem_file("examples/cert.crt")
15830 .unwrap();
15831 config
15832 .load_priv_key_from_pem_file("examples/cert.key")
15833 .unwrap();
15834 config
15835 .set_application_protos(&[b"proto1", b"proto2"])
15836 .unwrap();
15837 config.set_initial_max_data(30);
15838 config.set_initial_max_stream_data_bidi_local(15);
15839 config.set_initial_max_stream_data_bidi_remote(15);
15840 config.set_initial_max_stream_data_uni(10);
15841 config.set_initial_max_streams_bidi(3);
15842 config.set_initial_max_streams_uni(3);
15843 config.enable_dgram(true, 10, 2);
15844 config.verify_peer(false);
15845
15846 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
15847 assert_eq!(pipe.handshake(), Ok(()));
15848
15849 assert_eq!(pipe.client.dgram_send(b"hello, world"), Ok(()));
15850 assert_eq!(pipe.client.dgram_send(b"ciao, mondo"), Ok(()));
15851 assert_eq!(pipe.client.dgram_send(b"hola, mundo"), Err(Error::Done));
15852
15853 assert_eq!(pipe.advance(), Ok(()));
15854
15855 let result1 = pipe.server.dgram_recv(&mut buf);
15856 assert_eq!(result1, Ok(12));
15857 assert_eq!(buf[0], b'h');
15858 assert_eq!(buf[1], b'e');
15859
15860 let result2 = pipe.server.dgram_recv(&mut buf);
15861 assert_eq!(result2, Ok(11));
15862 assert_eq!(buf[0], b'c');
15863 assert_eq!(buf[1], b'i');
15864
15865 let result3 = pipe.server.dgram_recv(&mut buf);
15866 assert_eq!(result3, Err(Error::Done));
15867 }
15868
15869 #[rstest]
15870 fn dgram_recv_queue_overflow(
15871 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15872 ) {
15873 let mut buf = [0; 65535];
15874
15875 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15876 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15877 config
15878 .load_cert_chain_from_pem_file("examples/cert.crt")
15879 .unwrap();
15880 config
15881 .load_priv_key_from_pem_file("examples/cert.key")
15882 .unwrap();
15883 config
15884 .set_application_protos(&[b"proto1", b"proto2"])
15885 .unwrap();
15886 config.set_initial_max_data(30);
15887 config.set_initial_max_stream_data_bidi_local(15);
15888 config.set_initial_max_stream_data_bidi_remote(15);
15889 config.set_initial_max_stream_data_uni(10);
15890 config.set_initial_max_streams_bidi(3);
15891 config.set_initial_max_streams_uni(3);
15892 config.enable_dgram(true, 2, 10);
15893 config.set_max_recv_udp_payload_size(1200);
15894 config.verify_peer(false);
15895
15896 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
15897 assert_eq!(pipe.handshake(), Ok(()));
15898
15899 assert_eq!(pipe.client.dgram_send(b"hello, world"), Ok(()));
15900 assert_eq!(pipe.client.dgram_send(b"ciao, mondo"), Ok(()));
15901 assert_eq!(pipe.client.dgram_send(b"hola, mundo"), Ok(()));
15902
15903 assert_eq!(pipe.advance(), Ok(()));
15904
15905 let result1 = pipe.server.dgram_recv(&mut buf);
15906 assert_eq!(result1, Ok(11));
15907 assert_eq!(buf[0], b'c');
15908 assert_eq!(buf[1], b'i');
15909
15910 let result2 = pipe.server.dgram_recv(&mut buf);
15911 assert_eq!(result2, Ok(11));
15912 assert_eq!(buf[0], b'h');
15913 assert_eq!(buf[1], b'o');
15914
15915 let result3 = pipe.server.dgram_recv(&mut buf);
15916 assert_eq!(result3, Err(Error::Done));
15917 }
15918
15919 #[rstest]
15920 fn dgram_send_max_size(
15921 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15922 ) {
15923 let mut buf = [0; MAX_DGRAM_FRAME_SIZE as usize];
15924
15925 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15926 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15927 config
15928 .load_cert_chain_from_pem_file("examples/cert.crt")
15929 .unwrap();
15930 config
15931 .load_priv_key_from_pem_file("examples/cert.key")
15932 .unwrap();
15933 config
15934 .set_application_protos(&[b"proto1", b"proto2"])
15935 .unwrap();
15936 config.set_initial_max_data(30);
15937 config.set_initial_max_stream_data_bidi_local(15);
15938 config.set_initial_max_stream_data_bidi_remote(15);
15939 config.set_initial_max_stream_data_uni(10);
15940 config.set_initial_max_streams_bidi(3);
15941 config.set_initial_max_streams_uni(3);
15942 config.enable_dgram(true, 10, 10);
15943 config.set_max_recv_udp_payload_size(1452);
15944 config.verify_peer(false);
15945
15946 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
15947
15948 assert_eq!(pipe.client.dgram_max_writable_len(), None);
15950
15951 assert_eq!(pipe.handshake(), Ok(()));
15952
15953 let max_dgram_size = pipe.client.dgram_max_writable_len().unwrap();
15954
15955 assert_eq!(max_dgram_size, 1160);
15958
15959 let dgram_packet: Vec<u8> = vec![42; max_dgram_size];
15960
15961 assert_eq!(pipe.client.dgram_send(&dgram_packet), Ok(()));
15962
15963 assert_eq!(pipe.advance(), Ok(()));
15964
15965 let result1 = pipe.server.dgram_recv(&mut buf);
15966 assert_eq!(result1, Ok(max_dgram_size));
15967
15968 let result2 = pipe.server.dgram_recv(&mut buf);
15969 assert_eq!(result2, Err(Error::Done));
15970 }
15971
15972 #[rstest]
15973 fn is_readable(
15975 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
15976 ) {
15977 let mut buf = [0; 65535];
15978
15979 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
15980 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
15981 config
15982 .load_cert_chain_from_pem_file("examples/cert.crt")
15983 .unwrap();
15984 config
15985 .load_priv_key_from_pem_file("examples/cert.key")
15986 .unwrap();
15987 config
15988 .set_application_protos(&[b"proto1", b"proto2"])
15989 .unwrap();
15990 config.set_initial_max_data(30);
15991 config.set_initial_max_stream_data_bidi_local(15);
15992 config.set_initial_max_stream_data_bidi_remote(15);
15993 config.set_initial_max_stream_data_uni(10);
15994 config.set_initial_max_streams_bidi(3);
15995 config.set_initial_max_streams_uni(3);
15996 config.enable_dgram(true, 10, 10);
15997 config.set_max_recv_udp_payload_size(1452);
15998 config.verify_peer(false);
15999
16000 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
16001 assert_eq!(pipe.handshake(), Ok(()));
16002
16003 assert!(!pipe.client.is_readable());
16005 assert!(!pipe.server.is_readable());
16006
16007 assert_eq!(pipe.client.stream_send(4, b"aaaaa", false), Ok(5));
16008 assert_eq!(pipe.advance(), Ok(()));
16009
16010 assert!(!pipe.client.is_readable());
16012 assert!(pipe.server.is_readable());
16013
16014 assert_eq!(
16015 pipe.server.stream_send(4, b"aaaaaaaaaaaaaaa", false),
16016 Ok(15)
16017 );
16018 assert_eq!(pipe.advance(), Ok(()));
16019
16020 assert!(pipe.client.is_readable());
16022 assert!(pipe.server.is_readable());
16023
16024 let mut b = [0; 15];
16026 pipe.client.stream_recv(4, &mut b).unwrap();
16027 assert_eq!(pipe.advance(), Ok(()));
16028
16029 assert!(!pipe.client.is_readable());
16030 assert!(pipe.server.is_readable());
16031
16032 assert_eq!(pipe.server.stream_shutdown(4, Shutdown::Read, 0), Ok(()));
16034 assert!(!pipe.server.is_readable());
16035
16036 assert_eq!(pipe.client.dgram_send(b"dddddddddddddd"), Ok(()));
16038 assert_eq!(pipe.advance(), Ok(()));
16039
16040 assert!(!pipe.client.is_readable());
16041 assert!(pipe.server.is_readable());
16042
16043 assert_eq!(pipe.server.dgram_send(b"dddddddddddddd"), Ok(()));
16045 assert_eq!(pipe.advance(), Ok(()));
16046
16047 assert!(pipe.client.is_readable());
16048 assert!(pipe.server.is_readable());
16049
16050 let r = pipe.server.dgram_recv(&mut buf);
16052 assert_eq!(r, Ok(14));
16053 assert!(!pipe.server.is_readable());
16054
16055 let r = pipe.client.dgram_recv(&mut buf);
16056 assert_eq!(r, Ok(14));
16057 assert!(!pipe.client.is_readable());
16058 }
16059
16060 #[rstest]
16061 fn close(
16062 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16063 ) {
16064 let mut buf = [0; 65535];
16065
16066 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16067 assert_eq!(pipe.handshake(), Ok(()));
16068
16069 assert_eq!(pipe.client.close(false, 0x1234, b"hello?"), Ok(()));
16070
16071 assert_eq!(
16072 pipe.client.close(false, 0x4321, b"hello?"),
16073 Err(Error::Done)
16074 );
16075
16076 let (len, _) = pipe.client.send(&mut buf).unwrap();
16077
16078 let frames =
16079 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
16080
16081 assert_eq!(
16082 frames.first(),
16083 Some(&frame::Frame::ConnectionClose {
16084 error_code: 0x1234,
16085 frame_type: 0,
16086 reason: b"hello?".to_vec(),
16087 })
16088 );
16089 }
16090
16091 #[rstest]
16092 fn app_close_by_client(
16093 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16094 ) {
16095 let mut buf = [0; 65535];
16096
16097 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16098 assert_eq!(pipe.handshake(), Ok(()));
16099
16100 assert_eq!(pipe.client.close(true, 0x1234, b"hello!"), Ok(()));
16101
16102 assert_eq!(pipe.client.close(true, 0x4321, b"hello!"), Err(Error::Done));
16103
16104 let (len, _) = pipe.client.send(&mut buf).unwrap();
16105
16106 let frames =
16107 testing::decode_pkt(&mut pipe.server, &mut buf[..len]).unwrap();
16108
16109 assert_eq!(
16110 frames.first(),
16111 Some(&frame::Frame::ApplicationClose {
16112 error_code: 0x1234,
16113 reason: b"hello!".to_vec(),
16114 })
16115 );
16116 }
16117
16118 #[cfg(not(feature = "openssl"))]
16121 #[rstest]
16122 fn app_close_by_server_during_handshake_private_key_failure(
16123 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16124 ) {
16125 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16126 pipe.server.handshake.set_failing_private_key_method();
16127
16128 let flight = testing::emit_flight(&mut pipe.client).unwrap();
16130 assert_eq!(
16131 testing::process_flight(&mut pipe.server, flight),
16132 Err(Error::TlsFail)
16133 );
16134
16135 let flight = testing::emit_flight(&mut pipe.server).unwrap();
16136
16137 assert!(!pipe.server.is_established());
16139 assert!(!pipe.client.is_established());
16140
16141 assert_eq!(
16143 pipe.server.close(true, 123, b"fail whale"),
16144 Err(Error::Done)
16145 );
16146
16147 testing::process_flight(&mut pipe.client, flight).unwrap();
16148
16149 assert_eq!(
16151 pipe.client.close(true, 123, b"fail whale"),
16152 Err(Error::Done)
16153 );
16154
16155 assert!(!pipe.server.is_established());
16158 assert!(!pipe.client.is_established());
16159
16160 assert_eq!(pipe.advance(), Ok(()));
16161
16162 assert_eq!(
16163 pipe.server.local_error(),
16164 Some(&ConnectionError {
16165 is_app: false,
16166 error_code: 0x01,
16167 reason: vec![],
16168 })
16169 );
16170 assert_eq!(
16171 pipe.client.peer_error(),
16172 Some(&ConnectionError {
16173 is_app: false,
16174 error_code: 0x01,
16175 reason: vec![],
16176 })
16177 );
16178 }
16179
16180 #[rstest]
16181 fn app_close_by_server_during_handshake_not_established(
16182 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16183 ) {
16184 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16185
16186 let flight = testing::emit_flight(&mut pipe.client).unwrap();
16188 testing::process_flight(&mut pipe.server, flight).unwrap();
16189
16190 let flight = testing::emit_flight(&mut pipe.server).unwrap();
16191
16192 assert!(!pipe.client.is_established() && !pipe.server.is_established());
16194
16195 pipe.server.close(true, 123, b"fail whale").unwrap();
16197
16198 testing::process_flight(&mut pipe.client, flight).unwrap();
16199
16200 assert!(pipe.client.is_established());
16202
16203 pipe.client.stream_send(0, b"badauthtoken", true).unwrap();
16205
16206 let flight = testing::emit_flight(&mut pipe.client).unwrap();
16207 testing::process_flight(&mut pipe.server, flight).unwrap();
16208
16209 assert!(!pipe.server.is_established());
16211
16212 assert_eq!(pipe.advance(), Ok(()));
16213
16214 assert_eq!(
16215 pipe.server.local_error(),
16216 Some(&ConnectionError {
16217 is_app: false,
16218 error_code: 0x0c,
16219 reason: vec![],
16220 })
16221 );
16222 assert_eq!(
16223 pipe.client.peer_error(),
16224 Some(&ConnectionError {
16225 is_app: false,
16226 error_code: 0x0c,
16227 reason: vec![],
16228 })
16229 );
16230 }
16231
16232 #[rstest]
16233 fn app_close_by_server_during_handshake_established(
16234 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16235 ) {
16236 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16237
16238 let flight = testing::emit_flight(&mut pipe.client).unwrap();
16240 testing::process_flight(&mut pipe.server, flight).unwrap();
16241
16242 let flight = testing::emit_flight(&mut pipe.server).unwrap();
16243
16244 assert!(!pipe.client.is_established() && !pipe.server.is_established());
16246
16247 testing::process_flight(&mut pipe.client, flight).unwrap();
16248
16249 assert!(pipe.client.is_established());
16251
16252 pipe.client.stream_send(0, b"badauthtoken", true).unwrap();
16254
16255 let flight = testing::emit_flight(&mut pipe.client).unwrap();
16256 testing::process_flight(&mut pipe.server, flight).unwrap();
16257
16258 assert!(pipe.server.is_established());
16261
16262 pipe.server
16264 .close(true, 123, b"Invalid authentication")
16265 .unwrap();
16266
16267 assert_eq!(pipe.advance(), Ok(()));
16269
16270 assert_eq!(
16271 pipe.server.local_error(),
16272 Some(&ConnectionError {
16273 is_app: true,
16274 error_code: 123,
16275 reason: b"Invalid authentication".to_vec()
16276 })
16277 );
16278 assert_eq!(
16279 pipe.client.peer_error(),
16280 Some(&ConnectionError {
16281 is_app: true,
16282 error_code: 123,
16283 reason: b"Invalid authentication".to_vec()
16284 })
16285 );
16286 }
16287
16288 #[rstest]
16289 fn transport_close_by_client_during_handshake_established(
16290 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16291 ) {
16292 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16293
16294 let flight = testing::emit_flight(&mut pipe.client).unwrap();
16296 testing::process_flight(&mut pipe.server, flight).unwrap();
16297
16298 let flight = testing::emit_flight(&mut pipe.server).unwrap();
16299
16300 assert!(!pipe.client.is_established() && !pipe.server.is_established());
16302
16303 testing::process_flight(&mut pipe.client, flight).unwrap();
16304
16305 assert!(pipe.client.is_established());
16307
16308 pipe.client.close(false, 123, b"connection close").unwrap();
16310
16311 let flight = testing::emit_flight(&mut pipe.client).unwrap();
16312 testing::process_flight(&mut pipe.server, flight).unwrap();
16313
16314 assert_eq!(
16315 pipe.server.peer_error(),
16316 Some(&ConnectionError {
16317 is_app: false,
16318 error_code: 123,
16319 reason: b"connection close".to_vec()
16320 })
16321 );
16322 assert_eq!(
16323 pipe.client.local_error(),
16324 Some(&ConnectionError {
16325 is_app: false,
16326 error_code: 123,
16327 reason: b"connection close".to_vec()
16328 })
16329 );
16330 }
16331
16332 #[rstest]
16333 fn peer_error(
16334 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16335 ) {
16336 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16337 assert_eq!(pipe.handshake(), Ok(()));
16338
16339 assert_eq!(pipe.server.close(false, 0x1234, b"hello?"), Ok(()));
16340 assert_eq!(pipe.advance(), Ok(()));
16341
16342 assert_eq!(
16343 pipe.client.peer_error(),
16344 Some(&ConnectionError {
16345 is_app: false,
16346 error_code: 0x1234u64,
16347 reason: b"hello?".to_vec()
16348 })
16349 );
16350 }
16351
16352 #[rstest]
16353 fn app_peer_error(
16354 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16355 ) {
16356 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16357 assert_eq!(pipe.handshake(), Ok(()));
16358
16359 assert_eq!(pipe.server.close(true, 0x1234, b"hello!"), Ok(()));
16360 assert_eq!(pipe.advance(), Ok(()));
16361
16362 assert_eq!(
16363 pipe.client.peer_error(),
16364 Some(&ConnectionError {
16365 is_app: true,
16366 error_code: 0x1234u64,
16367 reason: b"hello!".to_vec()
16368 })
16369 );
16370 }
16371
16372 #[rstest]
16373 fn local_error(
16374 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16375 ) {
16376 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
16377 assert_eq!(pipe.handshake(), Ok(()));
16378
16379 assert_eq!(pipe.server.local_error(), None);
16380
16381 assert_eq!(pipe.server.close(true, 0x1234, b"hello!"), Ok(()));
16382
16383 assert_eq!(
16384 pipe.server.local_error(),
16385 Some(&ConnectionError {
16386 is_app: true,
16387 error_code: 0x1234u64,
16388 reason: b"hello!".to_vec()
16389 })
16390 );
16391 }
16392
16393 #[rstest]
16394 fn update_max_datagram_size(
16395 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16396 ) {
16397 let mut client_scid = [0; 16];
16398 rand::rand_bytes(&mut client_scid[..]);
16399 let client_scid = ConnectionId::from_ref(&client_scid);
16400 let client_addr = "127.0.0.1:1234".parse().unwrap();
16401
16402 let mut server_scid = [0; 16];
16403 rand::rand_bytes(&mut server_scid[..]);
16404 let server_scid = ConnectionId::from_ref(&server_scid);
16405 let server_addr = "127.0.0.1:4321".parse().unwrap();
16406
16407 let mut client_config = Config::new(crate::PROTOCOL_VERSION).unwrap();
16408 assert_eq!(
16409 client_config.set_cc_algorithm_name(cc_algorithm_name),
16410 Ok(())
16411 );
16412 client_config
16413 .set_application_protos(&[b"proto1", b"proto2"])
16414 .unwrap();
16415 client_config.set_max_recv_udp_payload_size(1200);
16416
16417 let mut server_config = Config::new(crate::PROTOCOL_VERSION).unwrap();
16418 assert_eq!(
16419 server_config.set_cc_algorithm_name(cc_algorithm_name),
16420 Ok(())
16421 );
16422 server_config
16423 .load_cert_chain_from_pem_file("examples/cert.crt")
16424 .unwrap();
16425 server_config
16426 .load_priv_key_from_pem_file("examples/cert.key")
16427 .unwrap();
16428 server_config
16429 .set_application_protos(&[b"proto1", b"proto2"])
16430 .unwrap();
16431 server_config.verify_peer(false);
16432 server_config
16433 .set_application_protos(&[b"proto1", b"proto2"])
16434 .unwrap();
16435 server_config.set_max_send_udp_payload_size(1500);
16437
16438 let mut pipe = testing::Pipe {
16439 client: connect(
16440 Some("quic.tech"),
16441 &client_scid,
16442 client_addr,
16443 server_addr,
16444 &mut client_config,
16445 )
16446 .unwrap(),
16447 server: accept(
16448 &server_scid,
16449 None,
16450 server_addr,
16451 client_addr,
16452 &mut server_config,
16453 )
16454 .unwrap(),
16455 };
16456
16457 assert_eq!(
16459 pipe.server
16460 .paths
16461 .get_active()
16462 .expect("no active")
16463 .recovery
16464 .max_datagram_size(),
16465 1500,
16466 );
16467
16468 assert_eq!(pipe.handshake(), Ok(()));
16469
16470 assert_eq!(
16473 pipe.server
16474 .paths
16475 .get_active()
16476 .expect("no active")
16477 .recovery
16478 .max_datagram_size(),
16479 1200,
16480 );
16481 assert_eq!(
16482 pipe.server
16483 .paths
16484 .get_active()
16485 .expect("no active")
16486 .recovery
16487 .cwnd(),
16488 if cc_algorithm_name == "cubic" {
16489 12000
16490 } else {
16491 if cfg!(feature = "openssl") {
16492 13437
16493 } else {
16494 13421
16495 }
16496 },
16497 );
16498 }
16499
16500 #[rstest]
16501 fn send_capacity(
16504 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16505 ) {
16506 let mut buf = [0; 65535];
16507
16508 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
16509 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
16510 config
16511 .load_cert_chain_from_pem_file("examples/cert.crt")
16512 .unwrap();
16513 config
16514 .load_priv_key_from_pem_file("examples/cert.key")
16515 .unwrap();
16516 config
16517 .set_application_protos(&[b"proto1", b"proto2"])
16518 .unwrap();
16519 config.set_initial_max_data(100000);
16520 config.set_initial_max_stream_data_bidi_local(10000);
16521 config.set_initial_max_stream_data_bidi_remote(10000);
16522 config.set_initial_max_streams_bidi(10);
16523 config.verify_peer(false);
16524
16525 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
16526 assert_eq!(pipe.handshake(), Ok(()));
16527
16528 assert_eq!(pipe.client.stream_send(0, b"hello!", true), Ok(6));
16529 assert_eq!(pipe.advance(), Ok(()));
16530
16531 assert_eq!(pipe.client.stream_send(4, b"hello!", true), Ok(6));
16532 assert_eq!(pipe.advance(), Ok(()));
16533
16534 assert_eq!(pipe.client.stream_send(8, b"hello!", true), Ok(6));
16535 assert_eq!(pipe.advance(), Ok(()));
16536
16537 assert_eq!(pipe.client.stream_send(12, b"hello!", true), Ok(6));
16538 assert_eq!(pipe.advance(), Ok(()));
16539
16540 let mut r = pipe.server.readable().collect::<Vec<u64>>();
16541 assert_eq!(r.len(), 4);
16542
16543 r.sort();
16544
16545 assert_eq!(r, [0, 4, 8, 12]);
16546
16547 assert_eq!(pipe.server.stream_recv(0, &mut buf), Ok((6, true)));
16548 assert_eq!(pipe.server.stream_recv(4, &mut buf), Ok((6, true)));
16549 assert_eq!(pipe.server.stream_recv(8, &mut buf), Ok((6, true)));
16550 assert_eq!(pipe.server.stream_recv(12, &mut buf), Ok((6, true)));
16551
16552 assert_eq!(
16553 pipe.server.tx_cap,
16554 if cc_algorithm_name == "cubic" {
16555 12000
16556 } else {
16557 if cfg!(feature = "openssl") {
16558 13959
16559 } else {
16560 13873
16561 }
16562 }
16563 );
16564
16565 assert_eq!(pipe.server.stream_send(0, &buf[..5000], false), Ok(5000));
16566 assert_eq!(pipe.server.stream_send(4, &buf[..5000], false), Ok(5000));
16567 assert_eq!(
16568 pipe.server.stream_send(8, &buf[..5000], false),
16569 if cc_algorithm_name == "cubic" {
16570 Ok(2000)
16571 } else {
16572 if cfg!(feature = "openssl") {
16573 Ok(3959)
16574 } else {
16575 Ok(3873)
16576 }
16577 }
16578 );
16579
16580 assert_eq!(
16582 pipe.server.stream_send(12, &buf[..5000], false),
16583 Err(Error::Done)
16584 );
16585 assert_eq!(pipe.server.tx_cap, 0);
16586
16587 assert_eq!(pipe.advance(), Ok(()));
16588 }
16589
16590 #[cfg(feature = "boringssl-boring-crate")]
16591 #[rstest]
16592 fn user_provided_boring_ctx(
16593 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16594 ) -> Result<()> {
16595 let mut server_tls_ctx_builder =
16597 boring::ssl::SslContextBuilder::new(boring::ssl::SslMethod::tls())
16598 .unwrap();
16599 server_tls_ctx_builder
16600 .set_certificate_chain_file("examples/cert.crt")
16601 .unwrap();
16602 server_tls_ctx_builder
16603 .set_private_key_file(
16604 "examples/cert.key",
16605 boring::ssl::SslFiletype::PEM,
16606 )
16607 .unwrap();
16608
16609 let mut server_config = Config::with_boring_ssl_ctx_builder(
16610 crate::PROTOCOL_VERSION,
16611 server_tls_ctx_builder,
16612 )?;
16613 let mut client_config = Config::new(crate::PROTOCOL_VERSION)?;
16614 assert_eq!(
16615 client_config.set_cc_algorithm_name(cc_algorithm_name),
16616 Ok(())
16617 );
16618 client_config.load_cert_chain_from_pem_file("examples/cert.crt")?;
16619 client_config.load_priv_key_from_pem_file("examples/cert.key")?;
16620
16621 for config in [&mut client_config, &mut server_config] {
16622 config.set_application_protos(&[b"proto1", b"proto2"])?;
16623 config.set_initial_max_data(30);
16624 config.set_initial_max_stream_data_bidi_local(15);
16625 config.set_initial_max_stream_data_bidi_remote(15);
16626 config.set_initial_max_stream_data_uni(10);
16627 config.set_initial_max_streams_bidi(3);
16628 config.set_initial_max_streams_uni(3);
16629 config.set_max_idle_timeout(180_000);
16630 config.verify_peer(false);
16631 config.set_ack_delay_exponent(8);
16632 }
16633
16634 let mut pipe = testing::Pipe::with_client_and_server_config(
16635 &mut client_config,
16636 &mut server_config,
16637 )?;
16638
16639 assert_eq!(pipe.handshake(), Ok(()));
16640
16641 Ok(())
16642 }
16643
16644 #[cfg(feature = "boringssl-boring-crate")]
16645 #[rstest]
16646 fn in_handshake_config(
16647 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16648 ) -> Result<()> {
16649 let mut buf = [0; 65535];
16650
16651 const CUSTOM_INITIAL_CONGESTION_WINDOW_PACKETS: usize = 30;
16652 const CUSTOM_INITIAL_MAX_STREAMS_BIDI: u64 = 30;
16653 const CUSTOM_MAX_IDLE_TIMEOUT: Duration = Duration::from_secs(3);
16654
16655 let mut server_tls_ctx_builder =
16658 boring::ssl::SslContextBuilder::new(boring::ssl::SslMethod::tls())
16659 .unwrap();
16660 server_tls_ctx_builder
16661 .set_certificate_chain_file("examples/cert.crt")
16662 .unwrap();
16663 server_tls_ctx_builder
16664 .set_private_key_file(
16665 "examples/cert.key",
16666 boring::ssl::SslFiletype::PEM,
16667 )
16668 .unwrap();
16669 server_tls_ctx_builder.set_select_certificate_callback(|mut hello| {
16670 <Connection>::set_initial_congestion_window_packets_in_handshake(
16671 hello.ssl_mut(),
16672 CUSTOM_INITIAL_CONGESTION_WINDOW_PACKETS,
16673 )
16674 .unwrap();
16675
16676 <Connection>::set_max_idle_timeout_in_handshake(
16677 hello.ssl_mut(),
16678 CUSTOM_MAX_IDLE_TIMEOUT.as_millis() as u64,
16679 )
16680 .unwrap();
16681
16682 <Connection>::set_initial_max_streams_bidi_in_handshake(
16683 hello.ssl_mut(),
16684 CUSTOM_INITIAL_MAX_STREAMS_BIDI,
16685 )
16686 .unwrap();
16687
16688 Ok(())
16689 });
16690
16691 let mut server_config = Config::with_boring_ssl_ctx_builder(
16692 crate::PROTOCOL_VERSION,
16693 server_tls_ctx_builder,
16694 )?;
16695 assert_eq!(
16696 server_config.set_cc_algorithm_name(cc_algorithm_name),
16697 Ok(())
16698 );
16699
16700 let mut client_config = Config::new(crate::PROTOCOL_VERSION)?;
16701 client_config.load_cert_chain_from_pem_file("examples/cert.crt")?;
16702 client_config.load_priv_key_from_pem_file("examples/cert.key")?;
16703
16704 for config in [&mut client_config, &mut server_config] {
16705 config.set_application_protos(&[b"proto1", b"proto2"])?;
16706 config.set_initial_max_data(1000000);
16707 config.set_initial_max_stream_data_bidi_local(15);
16708 config.set_initial_max_stream_data_bidi_remote(15);
16709 config.set_initial_max_stream_data_uni(10);
16710 config.set_initial_max_streams_bidi(3);
16711 config.set_initial_max_streams_uni(3);
16712 config.set_max_idle_timeout(180_000);
16713 config.verify_peer(false);
16714 config.set_ack_delay_exponent(8);
16715 }
16716
16717 let mut pipe = testing::Pipe::with_client_and_server_config(
16718 &mut client_config,
16719 &mut server_config,
16720 )?;
16721
16722 let (len, _) = pipe.client.send(&mut buf).unwrap();
16724
16725 assert_eq!(pipe.server.tx_cap, 0);
16726
16727 pipe.server_recv(&mut buf[..len]).unwrap();
16729
16730 assert_eq!(
16731 pipe.server.tx_cap,
16732 CUSTOM_INITIAL_CONGESTION_WINDOW_PACKETS * 1200
16733 );
16734
16735 assert_eq!(pipe.server.idle_timeout(), Some(CUSTOM_MAX_IDLE_TIMEOUT));
16736
16737 let (len, _) = pipe.server.send(&mut buf).unwrap();
16739 pipe.client_recv(&mut buf[..len]).unwrap();
16740
16741 assert_eq!(pipe.client.idle_timeout(), Some(CUSTOM_MAX_IDLE_TIMEOUT));
16743
16744 assert_eq!(
16745 pipe.client.peer_streams_left_bidi(),
16746 CUSTOM_INITIAL_MAX_STREAMS_BIDI
16747 );
16748
16749 assert_eq!(pipe.handshake(), Ok(()));
16750
16751 Ok(())
16752 }
16753
16754 #[rstest]
16755 fn initial_cwnd(
16756 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16757 ) -> Result<()> {
16758 const CUSTOM_INITIAL_CONGESTION_WINDOW_PACKETS: usize = 30;
16759
16760 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
16761 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
16762 config.set_initial_congestion_window_packets(
16763 CUSTOM_INITIAL_CONGESTION_WINDOW_PACKETS,
16764 );
16765 config.load_cert_chain_from_pem_file("examples/cert.crt")?;
16767 config.load_priv_key_from_pem_file("examples/cert.key")?;
16768 config.set_application_protos(&[b"proto1", b"proto2"])?;
16769 config.set_initial_max_data(1000000);
16770 config.set_initial_max_stream_data_bidi_local(15);
16771 config.set_initial_max_stream_data_bidi_remote(15);
16772 config.set_initial_max_stream_data_uni(10);
16773 config.set_initial_max_streams_bidi(3);
16774 config.set_initial_max_streams_uni(3);
16775 config.set_max_idle_timeout(180_000);
16776 config.verify_peer(false);
16777 config.set_ack_delay_exponent(8);
16778
16779 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
16780 assert_eq!(pipe.handshake(), Ok(()));
16781
16782 if cc_algorithm_name == "cubic" {
16783 assert_eq!(
16784 pipe.server.tx_cap,
16785 CUSTOM_INITIAL_CONGESTION_WINDOW_PACKETS * 1200
16786 );
16787 } else {
16788 let expected = CUSTOM_INITIAL_CONGESTION_WINDOW_PACKETS * 1200 +
16791 if cfg!(feature = "openssl") {
16792 1463
16793 } else {
16794 1447
16795 };
16796
16797 assert!(
16798 pipe.server.tx_cap >= expected,
16799 "{} vs {}",
16800 pipe.server.tx_cap,
16801 expected
16802 );
16803 assert!(
16804 pipe.server.tx_cap <= expected + 1,
16805 "{} vs {}",
16806 pipe.server.tx_cap,
16807 expected + 1
16808 );
16809 }
16810
16811 Ok(())
16812 }
16813
16814 #[rstest]
16815 fn last_tx_data_larger_than_tx_data(
16817 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16818 ) {
16819 let mut config = Config::new(PROTOCOL_VERSION).unwrap();
16820 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
16821 config
16822 .set_application_protos(&[b"proto1", b"proto2"])
16823 .unwrap();
16824 config.set_initial_max_data(12000);
16825 config.set_initial_max_stream_data_bidi_local(20000);
16826 config.set_initial_max_stream_data_bidi_remote(20000);
16827 config.set_max_recv_udp_payload_size(1200);
16828 config.verify_peer(false);
16829
16830 let mut pipe = testing::Pipe::with_client_config(&mut config).unwrap();
16831 assert_eq!(pipe.handshake(), Ok(()));
16832
16833 assert_eq!(pipe.client.stream_send(4, b"a", true), Ok(1));
16835 assert_eq!(pipe.client.stream_send(8, b"b", true), Ok(1));
16836 assert_eq!(pipe.advance(), Ok(()));
16837
16838 let mut b = [0; 15];
16840 pipe.server.stream_recv(4, &mut b).unwrap();
16841
16842 let buf = [0; 10000];
16844 assert_eq!(pipe.server.stream_send(4, &buf, false), Ok(10000));
16845
16846 testing::emit_flight(&mut pipe.server).unwrap();
16847
16848 let mut buf = [0; 1200];
16850 assert_eq!(pipe.server.stream_send(4, &buf, false), Ok(1200));
16851 assert_eq!(pipe.server.stream_send(8, &buf, false), Ok(800));
16852 assert_eq!(pipe.server.stream_send(4, &buf, false), Err(Error::Done));
16853
16854 let timer = pipe.server.timeout().unwrap();
16856 std::thread::sleep(timer + time::Duration::from_millis(1));
16857
16858 pipe.server.on_timeout();
16859
16860 let (len, _) = pipe.server.send(&mut buf).unwrap();
16863 assert_eq!(len, 1200);
16864
16865 let frames = [frame::Frame::StopSending {
16869 stream_id: 4,
16870 error_code: 42,
16871 }];
16872
16873 let pkt_type = packet::Type::Short;
16874 pipe.send_pkt_to_server(pkt_type, &frames, &mut buf)
16875 .unwrap();
16876 }
16877
16878 #[rstest]
16881 fn send_connection_ids(
16882 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16883 ) {
16884 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
16885 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
16886 config
16887 .load_cert_chain_from_pem_file("examples/cert.crt")
16888 .unwrap();
16889 config
16890 .load_priv_key_from_pem_file("examples/cert.key")
16891 .unwrap();
16892 config
16893 .set_application_protos(&[b"proto1", b"proto2"])
16894 .unwrap();
16895 config.verify_peer(false);
16896 config.set_active_connection_id_limit(3);
16897
16898 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
16899 assert_eq!(pipe.handshake(), Ok(()));
16900
16901 assert_eq!(pipe.client.path_event_next(), None);
16903 assert_eq!(pipe.server.path_event_next(), None);
16904 assert_eq!(pipe.client.scids_left(), 2);
16905
16906 let (scid, reset_token) = testing::create_cid_and_reset_token(16);
16907 assert_eq!(pipe.client.new_scid(&scid, reset_token, false), Ok(1));
16908
16909 assert_eq!(pipe.advance(), Ok(()));
16911
16912 assert_eq!(pipe.server.available_dcids(), 1);
16914 assert_eq!(pipe.server.path_event_next(), None);
16915 assert_eq!(pipe.client.path_event_next(), None);
16916 assert_eq!(pipe.client.scids_left(), 1);
16917
16918 let (scid, reset_token) = testing::create_cid_and_reset_token(16);
16920 assert_eq!(pipe.client.new_scid(&scid, reset_token, false), Ok(2));
16921
16922 assert_eq!(pipe.advance(), Ok(()));
16924
16925 assert_eq!(pipe.server.available_dcids(), 2);
16927 assert_eq!(pipe.server.path_event_next(), None);
16928 assert_eq!(pipe.client.path_event_next(), None);
16929 assert_eq!(pipe.client.scids_left(), 0);
16930
16931 let (scid, reset_token) = testing::create_cid_and_reset_token(16);
16934 assert_eq!(
16935 pipe.client.new_scid(&scid, reset_token, false),
16936 Err(Error::IdLimit),
16937 );
16938 }
16939
16940 #[rstest]
16941 fn connection_id_zero(
16943 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
16944 ) {
16945 let mut buf = [0; 65535];
16946
16947 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
16948 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
16949 config
16950 .load_cert_chain_from_pem_file("examples/cert.crt")
16951 .unwrap();
16952 config
16953 .load_priv_key_from_pem_file("examples/cert.key")
16954 .unwrap();
16955 config
16956 .set_application_protos(&[b"proto1", b"proto2"])
16957 .unwrap();
16958 config.verify_peer(false);
16959 config.set_active_connection_id_limit(2);
16960
16961 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
16962 assert_eq!(pipe.handshake(), Ok(()));
16963
16964 let mut frames = Vec::new();
16965
16966 let (scid, reset_token) = testing::create_cid_and_reset_token(0);
16968
16969 frames.push(frame::Frame::NewConnectionId {
16970 seq_num: 1,
16971 retire_prior_to: 0,
16972 conn_id: scid.to_vec(),
16973 reset_token: reset_token.to_be_bytes(),
16974 });
16975
16976 let pkt_type = packet::Type::Short;
16977
16978 let written =
16979 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
16980 .unwrap();
16981
16982 let active_path = pipe.server.paths.get_active().unwrap();
16983 let info = RecvInfo {
16984 to: active_path.local_addr(),
16985 from: active_path.peer_addr(),
16986 };
16987
16988 assert_eq!(
16989 pipe.server.recv(&mut buf[..written], info),
16990 Err(Error::InvalidFrame)
16991 );
16992
16993 let written = match pipe.server.send(&mut buf) {
16994 Ok((write, _)) => write,
16995
16996 Err(_) => unreachable!(),
16997 };
16998
16999 let frames =
17000 testing::decode_pkt(&mut pipe.client, &mut buf[..written]).unwrap();
17001 let mut iter = frames.iter();
17002
17003 assert_eq!(
17004 iter.next(),
17005 Some(&frame::Frame::ConnectionClose {
17006 error_code: 0x7,
17007 frame_type: 0,
17008 reason: Vec::new(),
17009 })
17010 );
17011 }
17012
17013 #[rstest]
17014 fn connection_id_invalid_max_len(
17016 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17017 ) {
17018 let mut buf = [0; 65535];
17019
17020 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17021 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17022 config
17023 .load_cert_chain_from_pem_file("examples/cert.crt")
17024 .unwrap();
17025 config
17026 .load_priv_key_from_pem_file("examples/cert.key")
17027 .unwrap();
17028 config
17029 .set_application_protos(&[b"proto1", b"proto2"])
17030 .unwrap();
17031 config.verify_peer(false);
17032 config.set_active_connection_id_limit(2);
17033
17034 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
17035 assert_eq!(pipe.handshake(), Ok(()));
17036
17037 let mut frames = Vec::new();
17038
17039 let (scid, reset_token) =
17041 testing::create_cid_and_reset_token(MAX_CONN_ID_LEN + 1);
17042
17043 frames.push(frame::Frame::NewConnectionId {
17044 seq_num: 1,
17045 retire_prior_to: 0,
17046 conn_id: scid.to_vec(),
17047 reset_token: reset_token.to_be_bytes(),
17048 });
17049
17050 let pkt_type = packet::Type::Short;
17051
17052 let written =
17053 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
17054 .unwrap();
17055
17056 let active_path = pipe.server.paths.get_active().unwrap();
17057 let info = RecvInfo {
17058 to: active_path.local_addr(),
17059 from: active_path.peer_addr(),
17060 };
17061
17062 assert_eq!(
17063 pipe.server.recv(&mut buf[..written], info),
17064 Err(Error::InvalidFrame)
17065 );
17066
17067 let written = match pipe.server.send(&mut buf) {
17068 Ok((write, _)) => write,
17069
17070 Err(_) => unreachable!(),
17071 };
17072
17073 let frames =
17074 testing::decode_pkt(&mut pipe.client, &mut buf[..written]).unwrap();
17075 let mut iter = frames.iter();
17076
17077 assert_eq!(
17078 iter.next(),
17079 Some(&frame::Frame::ConnectionClose {
17080 error_code: 0x7,
17081 frame_type: 0,
17082 reason: Vec::new(),
17083 })
17084 );
17085 }
17086
17087 #[rstest]
17088 fn connection_id_handling(
17091 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17092 ) {
17093 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17094 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17095 config
17096 .load_cert_chain_from_pem_file("examples/cert.crt")
17097 .unwrap();
17098 config
17099 .load_priv_key_from_pem_file("examples/cert.key")
17100 .unwrap();
17101 config
17102 .set_application_protos(&[b"proto1", b"proto2"])
17103 .unwrap();
17104 config.verify_peer(false);
17105 config.set_active_connection_id_limit(2);
17106
17107 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
17108 assert_eq!(pipe.handshake(), Ok(()));
17109
17110 assert_eq!(pipe.client.path_event_next(), None);
17112 assert_eq!(pipe.server.path_event_next(), None);
17113 assert_eq!(pipe.client.scids_left(), 1);
17114
17115 let scid = pipe.client.source_id().into_owned();
17116
17117 let (scid_1, reset_token_1) = testing::create_cid_and_reset_token(16);
17118 assert_eq!(pipe.client.new_scid(&scid_1, reset_token_1, false), Ok(1));
17119
17120 assert_eq!(pipe.advance(), Ok(()));
17122
17123 assert_eq!(pipe.server.available_dcids(), 1);
17125 assert_eq!(pipe.server.path_event_next(), None);
17126 assert_eq!(pipe.client.path_event_next(), None);
17127 assert_eq!(pipe.client.scids_left(), 0);
17128
17129 let (scid_2, reset_token_2) = testing::create_cid_and_reset_token(16);
17135 assert_eq!(pipe.client.new_scid(&scid_2, reset_token_2, true), Ok(2));
17136
17137 assert_eq!(pipe.advance(), Ok(()));
17139
17140 assert_eq!(pipe.server.available_dcids(), 1);
17142 assert_eq!(pipe.server.path_event_next(), None);
17143
17144 assert_eq!(pipe.client.retired_scid_next(), Some(scid));
17146 assert_eq!(pipe.client.retired_scid_next(), None);
17147
17148 assert_eq!(pipe.client.path_event_next(), None);
17149 assert_eq!(pipe.client.scids_left(), 0);
17150
17151 assert_eq!(pipe.server.destination_id(), scid_1);
17154
17155 assert_eq!(pipe.server.retire_dcid(0), Err(Error::InvalidState));
17158 assert_eq!(pipe.server.retire_dcid(3), Err(Error::InvalidState));
17159
17160 assert_eq!(pipe.server.retire_dcid(1), Ok(()));
17162
17163 assert_eq!(pipe.advance(), Ok(()));
17165
17166 assert_eq!(pipe.server.path_event_next(), None);
17167 assert_eq!(pipe.client.retired_scid_next(), Some(scid_1));
17168 assert_eq!(pipe.client.retired_scid_next(), None);
17169
17170 assert_eq!(pipe.server.destination_id(), scid_2);
17171 assert_eq!(pipe.server.available_dcids(), 0);
17172
17173 assert_eq!(pipe.server.retire_dcid(2), Err(Error::OutOfIdentifiers));
17175 }
17176
17177 #[rstest]
17178 fn lost_connection_id_frames(
17179 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17180 ) {
17181 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17182 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17183 config
17184 .load_cert_chain_from_pem_file("examples/cert.crt")
17185 .unwrap();
17186 config
17187 .load_priv_key_from_pem_file("examples/cert.key")
17188 .unwrap();
17189 config
17190 .set_application_protos(&[b"proto1", b"proto2"])
17191 .unwrap();
17192 config.verify_peer(false);
17193 config.set_active_connection_id_limit(2);
17194
17195 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
17196 assert_eq!(pipe.handshake(), Ok(()));
17197
17198 let scid = pipe.client.source_id().into_owned();
17199
17200 let (scid_1, reset_token_1) = testing::create_cid_and_reset_token(16);
17201 assert_eq!(pipe.client.new_scid(&scid_1, reset_token_1, false), Ok(1));
17202
17203 testing::emit_flight(&mut pipe.client).unwrap();
17205
17206 let timer = pipe.client.timeout().unwrap();
17208 std::thread::sleep(timer + time::Duration::from_millis(1));
17209
17210 pipe.client.on_timeout();
17211
17212 assert_eq!(pipe.advance(), Ok(()));
17214
17215 assert_eq!(pipe.server.available_dcids(), 1);
17217
17218 assert_eq!(pipe.server.retire_dcid(0), Ok(()));
17220
17221 testing::emit_flight(&mut pipe.server).unwrap();
17223
17224 let timer = pipe.server.timeout().unwrap();
17226 std::thread::sleep(timer + time::Duration::from_millis(1));
17227
17228 pipe.server.on_timeout();
17229
17230 assert_eq!(pipe.advance(), Ok(()));
17232
17233 assert_eq!(pipe.client.retired_scid_next(), Some(scid));
17234 assert_eq!(pipe.client.retired_scid_next(), None);
17235 }
17236
17237 #[rstest]
17238 fn sending_duplicate_scids(
17239 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17240 ) {
17241 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17242 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17243 config
17244 .load_cert_chain_from_pem_file("examples/cert.crt")
17245 .unwrap();
17246 config
17247 .load_priv_key_from_pem_file("examples/cert.key")
17248 .unwrap();
17249 config
17250 .set_application_protos(&[b"proto1", b"proto2"])
17251 .unwrap();
17252 config.verify_peer(false);
17253 config.set_active_connection_id_limit(3);
17254
17255 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
17256 assert_eq!(pipe.handshake(), Ok(()));
17257
17258 let (scid_1, reset_token_1) = testing::create_cid_and_reset_token(16);
17259 assert_eq!(pipe.client.new_scid(&scid_1, reset_token_1, false), Ok(1));
17260 assert_eq!(pipe.advance(), Ok(()));
17261
17262 let reset_token_2 = reset_token_1.wrapping_add(1);
17265 assert_eq!(
17266 pipe.client.new_scid(&scid_1, reset_token_2, false),
17267 Err(Error::InvalidState),
17268 );
17269
17270 assert_eq!(pipe.client.new_scid(&scid_1, reset_token_1, false), Ok(1));
17273 assert!(!pipe.client.ids.has_new_scids());
17274
17275 assert_eq!(pipe.server.retire_dcid(1), Ok(()));
17277 assert_eq!(pipe.advance(), Ok(()));
17278
17279 assert_eq!(pipe.client.new_scid(&scid_1, reset_token_1, false), Ok(2));
17282 }
17283
17284 #[rstest]
17285 fn connection_id_retire_limit(
17287 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17288 ) {
17289 let mut buf = [0; 65535];
17290
17291 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17292 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17293 config
17294 .load_cert_chain_from_pem_file("examples/cert.crt")
17295 .unwrap();
17296 config
17297 .load_priv_key_from_pem_file("examples/cert.key")
17298 .unwrap();
17299 config
17300 .set_application_protos(&[b"proto1", b"proto2"])
17301 .unwrap();
17302 config.verify_peer(false);
17303 config.set_active_connection_id_limit(2);
17304
17305 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
17306 assert_eq!(pipe.handshake(), Ok(()));
17307
17308 assert_eq!(pipe.client.path_event_next(), None);
17310 assert_eq!(pipe.server.path_event_next(), None);
17311 assert_eq!(pipe.client.scids_left(), 1);
17312
17313 let (scid_1, reset_token_1) = testing::create_cid_and_reset_token(16);
17314 assert_eq!(pipe.client.new_scid(&scid_1, reset_token_1, false), Ok(1));
17315
17316 assert_eq!(pipe.advance(), Ok(()));
17318
17319 assert_eq!(pipe.server.available_dcids(), 1);
17321 assert_eq!(pipe.server.path_event_next(), None);
17322 assert_eq!(pipe.client.path_event_next(), None);
17323 assert_eq!(pipe.client.scids_left(), 0);
17324
17325 let mut frames = Vec::new();
17326
17327 for i in 2..=7 {
17329 let (scid, reset_token) = testing::create_cid_and_reset_token(16);
17330
17331 frames.push(frame::Frame::NewConnectionId {
17332 seq_num: i,
17333 retire_prior_to: i,
17334 conn_id: scid.to_vec(),
17335 reset_token: reset_token.to_be_bytes(),
17336 });
17337 }
17338
17339 let pkt_type = packet::Type::Short;
17340
17341 let written =
17342 testing::encode_pkt(&mut pipe.client, pkt_type, &frames, &mut buf)
17343 .unwrap();
17344
17345 let active_path = pipe.server.paths.get_active().unwrap();
17346 let info = RecvInfo {
17347 to: active_path.local_addr(),
17348 from: active_path.peer_addr(),
17349 };
17350
17351 assert_eq!(
17352 pipe.server.recv(&mut buf[..written], info),
17353 Err(Error::IdLimit)
17354 );
17355
17356 let written = match pipe.server.send(&mut buf) {
17357 Ok((write, _)) => write,
17358
17359 Err(_) => unreachable!(),
17360 };
17361
17362 let frames =
17363 testing::decode_pkt(&mut pipe.client, &mut buf[..written]).unwrap();
17364 let mut iter = frames.iter();
17365
17366 assert_eq!(
17367 iter.next(),
17368 Some(&frame::Frame::ConnectionClose {
17369 error_code: 0x9,
17370 frame_type: 0,
17371 reason: Vec::new(),
17372 })
17373 );
17374 }
17375
17376 fn pipe_with_exchanged_cids(
17378 config: &mut Config, client_scid_len: usize, server_scid_len: usize,
17379 additional_cids: usize,
17380 ) -> testing::Pipe {
17381 let mut pipe = testing::Pipe::with_config_and_scid_lengths(
17382 config,
17383 client_scid_len,
17384 server_scid_len,
17385 )
17386 .unwrap();
17387 assert_eq!(pipe.handshake(), Ok(()));
17388
17389 let mut c_cids = Vec::new();
17390 let mut c_reset_tokens = Vec::new();
17391 let mut s_cids = Vec::new();
17392 let mut s_reset_tokens = Vec::new();
17393
17394 for i in 0..additional_cids {
17395 if client_scid_len > 0 {
17396 let (c_cid, c_reset_token) =
17397 testing::create_cid_and_reset_token(client_scid_len);
17398 c_cids.push(c_cid);
17399 c_reset_tokens.push(c_reset_token);
17400
17401 assert_eq!(
17402 pipe.client.new_scid(&c_cids[i], c_reset_tokens[i], true),
17403 Ok(i as u64 + 1)
17404 );
17405 }
17406
17407 if server_scid_len > 0 {
17408 let (s_cid, s_reset_token) =
17409 testing::create_cid_and_reset_token(server_scid_len);
17410 s_cids.push(s_cid);
17411 s_reset_tokens.push(s_reset_token);
17412 assert_eq!(
17413 pipe.server.new_scid(&s_cids[i], s_reset_tokens[i], true),
17414 Ok(i as u64 + 1)
17415 );
17416 }
17417 }
17418
17419 assert_eq!(pipe.advance(), Ok(()));
17421
17422 if client_scid_len > 0 {
17423 assert_eq!(pipe.server.available_dcids(), additional_cids);
17424 }
17425
17426 if server_scid_len > 0 {
17427 assert_eq!(pipe.client.available_dcids(), additional_cids);
17428 }
17429
17430 assert_eq!(pipe.server.path_event_next(), None);
17431 assert_eq!(pipe.client.path_event_next(), None);
17432
17433 pipe
17434 }
17435
17436 #[rstest]
17437 fn path_validation(
17438 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17439 ) {
17440 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17441 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17442 config
17443 .load_cert_chain_from_pem_file("examples/cert.crt")
17444 .unwrap();
17445 config
17446 .load_priv_key_from_pem_file("examples/cert.key")
17447 .unwrap();
17448 config
17449 .set_application_protos(&[b"proto1", b"proto2"])
17450 .unwrap();
17451 config.verify_peer(false);
17452 config.set_active_connection_id_limit(2);
17453
17454 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
17455 assert_eq!(pipe.handshake(), Ok(()));
17456
17457 let server_addr = testing::Pipe::server_addr();
17458 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
17459
17460 assert_eq!(
17462 pipe.client.probe_path(client_addr_2, server_addr),
17463 Err(Error::OutOfIdentifiers)
17464 );
17465
17466 let (c_cid, c_reset_token) = testing::create_cid_and_reset_token(16);
17467
17468 assert_eq!(pipe.client.new_scid(&c_cid, c_reset_token, true), Ok(1));
17469
17470 let (s_cid, s_reset_token) = testing::create_cid_and_reset_token(16);
17471 assert_eq!(pipe.server.new_scid(&s_cid, s_reset_token, true), Ok(1));
17472
17473 assert_eq!(
17475 pipe.client.probe_path(client_addr_2, server_addr),
17476 Err(Error::OutOfIdentifiers)
17477 );
17478
17479 assert_eq!(pipe.advance(), Ok(()));
17481
17482 assert_eq!(pipe.server.available_dcids(), 1);
17483 assert_eq!(pipe.server.path_event_next(), None);
17484 assert_eq!(pipe.client.available_dcids(), 1);
17485 assert_eq!(pipe.client.path_event_next(), None);
17486
17487 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
17489
17490 assert_eq!(
17492 pipe.server.probe_path(server_addr, client_addr_2),
17493 Err(Error::InvalidState),
17494 );
17495
17496 assert_eq!(pipe.advance(), Ok(()));
17497
17498 assert_eq!(
17500 pipe.client.path_event_next(),
17501 Some(PathEvent::Validated(client_addr_2, server_addr)),
17502 );
17503 assert_eq!(pipe.client.path_event_next(), None);
17504
17505 assert_eq!(
17507 pipe.server.path_event_next(),
17508 Some(PathEvent::New(server_addr, client_addr_2)),
17509 );
17510 assert_eq!(
17511 pipe.server.path_event_next(),
17512 Some(PathEvent::Validated(server_addr, client_addr_2)),
17513 );
17514 assert_eq!(pipe.server.path_event_next(), None);
17515
17516 assert_eq!(pipe.server.probe_path(server_addr, client_addr_2), Ok(1));
17518
17519 assert_eq!(pipe.client.path_event_next(), None);
17521 assert_eq!(pipe.server.path_event_next(), None);
17522 }
17523
17524 #[rstest]
17525 fn losing_probing_packets(
17526 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17527 ) {
17528 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17529 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17530 config
17531 .load_cert_chain_from_pem_file("examples/cert.crt")
17532 .unwrap();
17533 config
17534 .load_priv_key_from_pem_file("examples/cert.key")
17535 .unwrap();
17536 config
17537 .set_application_protos(&[b"proto1", b"proto2"])
17538 .unwrap();
17539 config.verify_peer(false);
17540 config.set_active_connection_id_limit(2);
17541
17542 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 1);
17543
17544 let server_addr = testing::Pipe::server_addr();
17545 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
17546 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
17547
17548 testing::emit_flight(&mut pipe.client).unwrap();
17550
17551 let probed_pid = pipe
17554 .client
17555 .paths
17556 .path_id_from_addrs(&(client_addr_2, server_addr))
17557 .unwrap();
17558 let probe_instant = pipe
17559 .client
17560 .paths
17561 .get(probed_pid)
17562 .unwrap()
17563 .recovery
17564 .loss_detection_timer()
17565 .unwrap();
17566 let timer = probe_instant.duration_since(time::Instant::now());
17567 std::thread::sleep(timer + time::Duration::from_millis(1));
17568
17569 pipe.client.on_timeout();
17570
17571 assert_eq!(pipe.advance(), Ok(()));
17572
17573 assert_eq!(
17575 pipe.client.path_event_next(),
17576 Some(PathEvent::Validated(client_addr_2, server_addr))
17577 );
17578 assert_eq!(pipe.client.path_event_next(), None);
17579
17580 assert_eq!(
17581 pipe.server.path_event_next(),
17582 Some(PathEvent::New(server_addr, client_addr_2))
17583 );
17584 assert_eq!(
17586 pipe.server.path_event_next(),
17587 Some(PathEvent::Validated(server_addr, client_addr_2))
17588 );
17589 assert_eq!(pipe.server.path_event_next(), None);
17590 }
17591
17592 #[rstest]
17593 fn failed_path_validation(
17594 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17595 ) {
17596 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17597 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17598 config
17599 .load_cert_chain_from_pem_file("examples/cert.crt")
17600 .unwrap();
17601 config
17602 .load_priv_key_from_pem_file("examples/cert.key")
17603 .unwrap();
17604 config
17605 .set_application_protos(&[b"proto1", b"proto2"])
17606 .unwrap();
17607 config.verify_peer(false);
17608 config.set_active_connection_id_limit(2);
17609
17610 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 1);
17611
17612 let server_addr = testing::Pipe::server_addr();
17613 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
17614 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
17615
17616 for _ in 0..MAX_PROBING_TIMEOUTS {
17617 testing::emit_flight(&mut pipe.client).unwrap();
17619
17620 let probed_pid = pipe
17623 .client
17624 .paths
17625 .path_id_from_addrs(&(client_addr_2, server_addr))
17626 .unwrap();
17627 let probe_instant = pipe
17628 .client
17629 .paths
17630 .get(probed_pid)
17631 .unwrap()
17632 .recovery
17633 .loss_detection_timer()
17634 .unwrap();
17635 let timer = probe_instant.duration_since(time::Instant::now());
17636 std::thread::sleep(timer + time::Duration::from_millis(1));
17637
17638 pipe.client.on_timeout();
17639 }
17640
17641 assert_eq!(
17642 pipe.client.path_event_next(),
17643 Some(PathEvent::FailedValidation(client_addr_2, server_addr)),
17644 );
17645 }
17646
17647 #[rstest]
17648 fn client_discard_unknown_address(
17649 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17650 ) {
17651 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17652 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17653 config
17654 .load_cert_chain_from_pem_file("examples/cert.crt")
17655 .unwrap();
17656 config
17657 .load_priv_key_from_pem_file("examples/cert.key")
17658 .unwrap();
17659 config
17660 .set_application_protos(&[b"proto1", b"proto2"])
17661 .unwrap();
17662 config.verify_peer(false);
17663 config.set_initial_max_data(30);
17664 config.set_initial_max_stream_data_uni(10);
17665 config.set_initial_max_streams_uni(3);
17666
17667 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
17668 assert_eq!(pipe.handshake(), Ok(()));
17669
17670 assert_eq!(pipe.server.stream_send(3, b"a", true), Ok(1));
17672
17673 let mut flight =
17674 testing::emit_flight(&mut pipe.server).expect("no packet");
17675 flight
17677 .iter_mut()
17678 .for_each(|(_, si)| si.from = "127.0.0.1:9292".parse().unwrap());
17679 assert_eq!(testing::process_flight(&mut pipe.client, flight), Ok(()));
17680 assert_eq!(pipe.client.paths.len(), 1);
17681 }
17682
17683 #[rstest]
17684 fn path_validation_limited_mtu(
17685 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17686 ) {
17687 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17688 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17689 config
17690 .load_cert_chain_from_pem_file("examples/cert.crt")
17691 .unwrap();
17692 config
17693 .load_priv_key_from_pem_file("examples/cert.key")
17694 .unwrap();
17695 config
17696 .set_application_protos(&[b"proto1", b"proto2"])
17697 .unwrap();
17698 config.verify_peer(false);
17699 config.set_active_connection_id_limit(2);
17700
17701 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 1);
17702
17703 let server_addr = testing::Pipe::server_addr();
17704 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
17705 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
17706 testing::process_flight(
17708 &mut pipe.server,
17709 testing::emit_flight_with_max_buffer(
17710 &mut pipe.client,
17711 1199,
17712 None,
17713 None,
17714 )
17715 .expect("no packet"),
17716 )
17717 .expect("error when processing client packets");
17718 testing::process_flight(
17719 &mut pipe.client,
17720 testing::emit_flight(&mut pipe.server).expect("no packet"),
17721 )
17722 .expect("error when processing client packets");
17723 let probed_pid = pipe
17724 .client
17725 .paths
17726 .path_id_from_addrs(&(client_addr_2, server_addr))
17727 .unwrap();
17728 assert!(!pipe.client.paths.get(probed_pid).unwrap().validated(),);
17729 assert_eq!(pipe.client.path_event_next(), None);
17730 assert_eq!(pipe.advance(), Ok(()));
17732 assert!(pipe.client.paths.get(probed_pid).unwrap().validated());
17733 assert_eq!(
17734 pipe.client.path_event_next(),
17735 Some(PathEvent::Validated(client_addr_2, server_addr))
17736 );
17737 }
17738
17739 #[rstest]
17740 fn path_probing_dos(
17741 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17742 ) {
17743 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17744 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17745 config
17746 .load_cert_chain_from_pem_file("examples/cert.crt")
17747 .unwrap();
17748 config
17749 .load_priv_key_from_pem_file("examples/cert.key")
17750 .unwrap();
17751 config
17752 .set_application_protos(&[b"proto1", b"proto2"])
17753 .unwrap();
17754 config.verify_peer(false);
17755 config.set_active_connection_id_limit(2);
17756
17757 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 1);
17758
17759 let server_addr = testing::Pipe::server_addr();
17760 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
17761 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
17762
17763 assert_eq!(pipe.advance(), Ok(()));
17764
17765 assert_eq!(
17767 pipe.client.path_event_next(),
17768 Some(PathEvent::Validated(client_addr_2, server_addr))
17769 );
17770 assert_eq!(pipe.client.path_event_next(), None);
17771
17772 assert_eq!(
17774 pipe.server.path_event_next(),
17775 Some(PathEvent::New(server_addr, client_addr_2))
17776 );
17777 assert_eq!(
17778 pipe.server.path_event_next(),
17779 Some(PathEvent::Validated(server_addr, client_addr_2))
17780 );
17781 assert_eq!(pipe.server.path_event_next(), None);
17782
17783 assert_eq!(pipe.server.paths.len(), 2);
17784
17785 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
17788 let client_addr_3 = "127.0.0.1:9012".parse().unwrap();
17789 let mut flight =
17790 testing::emit_flight(&mut pipe.client).expect("no generated packet");
17791 flight
17792 .iter_mut()
17793 .for_each(|(_, si)| si.from = client_addr_3);
17794 testing::process_flight(&mut pipe.server, flight)
17795 .expect("failed to process");
17796 assert_eq!(pipe.server.paths.len(), 2);
17797 assert_eq!(
17798 pipe.server.path_event_next(),
17799 Some(PathEvent::ReusedSourceConnectionId(
17800 1,
17801 (server_addr, client_addr_2),
17802 (server_addr, client_addr_3)
17803 ))
17804 );
17805 assert_eq!(pipe.server.path_event_next(), None);
17806 }
17807
17808 #[rstest]
17809 fn retiring_active_path_dcid(
17810 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17811 ) {
17812 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17813 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17814 config
17815 .load_cert_chain_from_pem_file("examples/cert.crt")
17816 .unwrap();
17817 config
17818 .load_priv_key_from_pem_file("examples/cert.key")
17819 .unwrap();
17820 config
17821 .set_application_protos(&[b"proto1", b"proto2"])
17822 .unwrap();
17823 config.verify_peer(false);
17824 config.set_active_connection_id_limit(2);
17825
17826 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 1);
17827 let server_addr = testing::Pipe::server_addr();
17828 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
17829 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
17830
17831 assert_eq!(pipe.client.retire_dcid(0), Err(Error::OutOfIdentifiers));
17832 }
17833
17834 #[rstest]
17835 fn send_on_path_test(
17836 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
17837 ) {
17838 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
17839 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
17840 config
17841 .load_cert_chain_from_pem_file("examples/cert.crt")
17842 .unwrap();
17843 config
17844 .load_priv_key_from_pem_file("examples/cert.key")
17845 .unwrap();
17846 config
17847 .set_application_protos(&[b"proto1", b"proto2"])
17848 .unwrap();
17849 config.verify_peer(false);
17850 config.set_initial_max_data(100000);
17851 config.set_initial_max_stream_data_bidi_local(100000);
17852 config.set_initial_max_stream_data_bidi_remote(100000);
17853 config.set_initial_max_streams_bidi(2);
17854 config.set_active_connection_id_limit(4);
17855
17856 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 3);
17857
17858 let server_addr = testing::Pipe::server_addr();
17859 let client_addr = testing::Pipe::client_addr();
17860 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
17861 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
17862
17863 let mut buf = [0; 65535];
17864 assert_eq!(
17866 pipe.client.send_on_path(
17867 &mut buf,
17868 Some(client_addr),
17869 Some(server_addr)
17870 ),
17871 Err(Error::Done)
17872 );
17873
17874 let (sent, si) = pipe
17876 .client
17877 .send_on_path(&mut buf, Some(client_addr_2), Some(server_addr))
17878 .expect("No error");
17879 assert_eq!(sent, MIN_CLIENT_INITIAL_LEN);
17880 assert_eq!(si.from, client_addr_2);
17881 assert_eq!(si.to, server_addr);
17882
17883 let ri = RecvInfo {
17884 to: si.to,
17885 from: si.from,
17886 };
17887 assert_eq!(pipe.server.recv(&mut buf[..sent], ri), Ok(sent));
17888
17889 let stats = pipe.server.stats();
17890 assert_eq!(stats.path_challenge_rx_count, 1);
17891
17892 let client_addr_3 = "127.0.0.1:9012".parse().unwrap();
17894 let server_addr_2 = "127.0.0.1:9876".parse().unwrap();
17895 assert_eq!(
17896 pipe.client.send_on_path(
17897 &mut buf,
17898 Some(client_addr_3),
17899 Some(server_addr)
17900 ),
17901 Err(Error::InvalidState)
17902 );
17903 assert_eq!(
17904 pipe.client.send_on_path(
17905 &mut buf,
17906 Some(client_addr),
17907 Some(server_addr_2)
17908 ),
17909 Err(Error::InvalidState)
17910 );
17911
17912 assert_eq!(pipe.client.probe_path(client_addr, server_addr_2), Ok(2));
17914 assert_eq!(pipe.client.probe_path(client_addr_3, server_addr), Ok(3));
17915 assert_eq!(pipe.client.stream_send(0, &buf[..1201], true), Ok(1201));
17917
17918 let (sent, si) = pipe
17920 .client
17921 .send_on_path(&mut buf, Some(client_addr), None)
17922 .expect("No error");
17923 assert_eq!(sent, MIN_CLIENT_INITIAL_LEN);
17924 assert_eq!(si.from, client_addr);
17925 assert_eq!(si.to, server_addr_2);
17926
17927 let ri = RecvInfo {
17928 to: si.to,
17929 from: si.from,
17930 };
17931 assert_eq!(pipe.server.recv(&mut buf[..sent], ri), Ok(sent));
17932
17933 let stats = pipe.server.stats();
17934 assert_eq!(stats.path_challenge_rx_count, 2);
17935
17936 let (sent, si) = pipe
17938 .client
17939 .send_on_path(&mut buf, Some(client_addr), None)
17940 .expect("No error");
17941 assert_eq!(si.from, client_addr);
17942 assert_eq!(si.to, server_addr);
17943
17944 let ri = RecvInfo {
17945 to: si.to,
17946 from: si.from,
17947 };
17948 assert_eq!(pipe.server.recv(&mut buf[..sent], ri), Ok(sent));
17949
17950 let stats = pipe.server.stats();
17951 assert_eq!(stats.path_challenge_rx_count, 2);
17952
17953 let (sent, si) = pipe
17955 .client
17956 .send_on_path(&mut buf, None, Some(server_addr))
17957 .expect("No error");
17958 assert_eq!(sent, MIN_CLIENT_INITIAL_LEN);
17959 assert_eq!(si.from, client_addr_3);
17960 assert_eq!(si.to, server_addr);
17961
17962 let ri = RecvInfo {
17963 to: si.to,
17964 from: si.from,
17965 };
17966 assert_eq!(pipe.server.recv(&mut buf[..sent], ri), Ok(sent));
17967
17968 let stats = pipe.server.stats();
17969 assert_eq!(stats.path_challenge_rx_count, 3);
17970
17971 let (sent, si) = pipe
17973 .client
17974 .send_on_path(&mut buf, None, Some(server_addr))
17975 .expect("No error");
17976 assert_eq!(si.from, client_addr);
17977 assert_eq!(si.to, server_addr);
17978
17979 let ri = RecvInfo {
17980 to: si.to,
17981 from: si.from,
17982 };
17983 assert_eq!(pipe.server.recv(&mut buf[..sent], ri), Ok(sent));
17984
17985 assert_eq!(
17987 pipe.client.send_on_path(&mut buf, Some(client_addr), None),
17988 Err(Error::Done)
17989 );
17990 assert_eq!(
17991 pipe.client.send_on_path(&mut buf, None, Some(server_addr)),
17992 Err(Error::Done)
17993 );
17994
17995 assert_eq!(pipe.advance(), Ok(()));
17996
17997 let mut v1 = pipe.client.paths_iter(client_addr).collect::<Vec<_>>();
17998 let mut v2 = vec![server_addr, server_addr_2];
17999
18000 v1.sort();
18001 v2.sort();
18002
18003 assert_eq!(v1, v2);
18004
18005 let mut v1 = pipe.client.paths_iter(client_addr_2).collect::<Vec<_>>();
18006 let mut v2 = vec![server_addr];
18007
18008 v1.sort();
18009 v2.sort();
18010
18011 assert_eq!(v1, v2);
18012
18013 let mut v1 = pipe.client.paths_iter(client_addr_3).collect::<Vec<_>>();
18014 let mut v2 = vec![server_addr];
18015
18016 v1.sort();
18017 v2.sort();
18018
18019 assert_eq!(v1, v2);
18020
18021 let stats = pipe.server.stats();
18022 assert_eq!(stats.path_challenge_rx_count, 3);
18023 }
18024
18025 #[rstest]
18026 fn connection_migration(
18027 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18028 ) {
18029 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
18030 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
18031 config
18032 .load_cert_chain_from_pem_file("examples/cert.crt")
18033 .unwrap();
18034 config
18035 .load_priv_key_from_pem_file("examples/cert.key")
18036 .unwrap();
18037 config
18038 .set_application_protos(&[b"proto1", b"proto2"])
18039 .unwrap();
18040 config.verify_peer(false);
18041 config.set_active_connection_id_limit(3);
18042 config.set_initial_max_data(30);
18043 config.set_initial_max_stream_data_bidi_local(15);
18044 config.set_initial_max_stream_data_bidi_remote(15);
18045 config.set_initial_max_stream_data_uni(10);
18046 config.set_initial_max_streams_bidi(3);
18047
18048 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 2);
18049
18050 let server_addr = testing::Pipe::server_addr();
18051 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
18052 let client_addr_3 = "127.0.0.1:9012".parse().unwrap();
18053 let client_addr_4 = "127.0.0.1:8908".parse().unwrap();
18054
18055 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
18058 assert_eq!(pipe.advance(), Ok(()));
18059 assert_eq!(
18060 pipe.client.path_event_next(),
18061 Some(PathEvent::Validated(client_addr_2, server_addr))
18062 );
18063 assert_eq!(pipe.client.path_event_next(), None);
18064 assert_eq!(
18065 pipe.server.path_event_next(),
18066 Some(PathEvent::New(server_addr, client_addr_2))
18067 );
18068 assert_eq!(
18069 pipe.server.path_event_next(),
18070 Some(PathEvent::Validated(server_addr, client_addr_2))
18071 );
18072 assert_eq!(
18073 pipe.client.is_path_validated(client_addr_2, server_addr),
18074 Ok(true)
18075 );
18076 assert_eq!(
18077 pipe.server.is_path_validated(server_addr, client_addr_2),
18078 Ok(true)
18079 );
18080 assert_eq!(
18082 pipe.server.migrate(server_addr, client_addr_2),
18083 Err(Error::InvalidState)
18084 );
18085 assert_eq!(pipe.client.migrate(client_addr_2, server_addr), Ok(1));
18086 assert_eq!(pipe.client.stream_send(0, b"data", true), Ok(4));
18087 assert_eq!(pipe.advance(), Ok(()));
18088 assert_eq!(
18089 pipe.client
18090 .paths
18091 .get_active()
18092 .expect("no active")
18093 .local_addr(),
18094 client_addr_2
18095 );
18096 assert_eq!(
18097 pipe.client
18098 .paths
18099 .get_active()
18100 .expect("no active")
18101 .peer_addr(),
18102 server_addr
18103 );
18104 assert_eq!(
18105 pipe.server.path_event_next(),
18106 Some(PathEvent::PeerMigrated(server_addr, client_addr_2))
18107 );
18108 assert_eq!(pipe.server.path_event_next(), None);
18109 assert_eq!(
18110 pipe.server
18111 .paths
18112 .get_active()
18113 .expect("no active")
18114 .local_addr(),
18115 server_addr
18116 );
18117 assert_eq!(
18118 pipe.server
18119 .paths
18120 .get_active()
18121 .expect("no active")
18122 .peer_addr(),
18123 client_addr_2
18124 );
18125
18126 assert_eq!(pipe.client.migrate(client_addr_3, server_addr), Ok(2));
18129 assert_eq!(pipe.client.stream_send(4, b"data", true), Ok(4));
18130 assert_eq!(pipe.advance(), Ok(()));
18131 assert_eq!(
18132 pipe.client
18133 .paths
18134 .get_active()
18135 .expect("no active")
18136 .local_addr(),
18137 client_addr_3
18138 );
18139 assert_eq!(
18140 pipe.client
18141 .paths
18142 .get_active()
18143 .expect("no active")
18144 .peer_addr(),
18145 server_addr
18146 );
18147 assert_eq!(
18148 pipe.server.path_event_next(),
18149 Some(PathEvent::New(server_addr, client_addr_3))
18150 );
18151 assert_eq!(
18152 pipe.server.path_event_next(),
18153 Some(PathEvent::Validated(server_addr, client_addr_3))
18154 );
18155 assert_eq!(
18156 pipe.server.path_event_next(),
18157 Some(PathEvent::PeerMigrated(server_addr, client_addr_3))
18158 );
18159 assert_eq!(pipe.server.path_event_next(), None);
18160 assert_eq!(
18161 pipe.server
18162 .paths
18163 .get_active()
18164 .expect("no active")
18165 .local_addr(),
18166 server_addr
18167 );
18168 assert_eq!(
18169 pipe.server
18170 .paths
18171 .get_active()
18172 .expect("no active")
18173 .peer_addr(),
18174 client_addr_3
18175 );
18176
18177 assert_eq!(pipe.client.migrate(client_addr_3, server_addr), Ok(2));
18180 assert_eq!(pipe.client.stream_send(8, b"data", true), Ok(4));
18181 assert_eq!(pipe.advance(), Ok(()));
18182 assert_eq!(pipe.client.path_event_next(), None);
18183 assert_eq!(
18184 pipe.client
18185 .paths
18186 .get_active()
18187 .expect("no active")
18188 .local_addr(),
18189 client_addr_3
18190 );
18191 assert_eq!(
18192 pipe.client
18193 .paths
18194 .get_active()
18195 .expect("no active")
18196 .peer_addr(),
18197 server_addr
18198 );
18199 assert_eq!(pipe.server.path_event_next(), None);
18200 assert_eq!(
18201 pipe.server
18202 .paths
18203 .get_active()
18204 .expect("no active")
18205 .local_addr(),
18206 server_addr
18207 );
18208 assert_eq!(
18209 pipe.server
18210 .paths
18211 .get_active()
18212 .expect("no active")
18213 .peer_addr(),
18214 client_addr_3
18215 );
18216
18217 assert_eq!(
18220 pipe.client.migrate(client_addr_4, server_addr),
18221 Err(Error::OutOfIdentifiers)
18222 );
18223 assert_eq!(
18224 pipe.client
18225 .paths
18226 .get_active()
18227 .expect("no active")
18228 .local_addr(),
18229 client_addr_3
18230 );
18231 assert_eq!(
18232 pipe.client
18233 .paths
18234 .get_active()
18235 .expect("no active")
18236 .peer_addr(),
18237 server_addr
18238 );
18239 }
18240
18241 #[rstest]
18242 fn connection_migration_zero_length_cid(
18243 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18244 ) {
18245 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
18246 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
18247 config
18248 .load_cert_chain_from_pem_file("examples/cert.crt")
18249 .unwrap();
18250 config
18251 .load_priv_key_from_pem_file("examples/cert.key")
18252 .unwrap();
18253 config
18254 .set_application_protos(&[b"proto1", b"proto2"])
18255 .unwrap();
18256 config.verify_peer(false);
18257 config.set_active_connection_id_limit(2);
18258 config.set_initial_max_data(30);
18259 config.set_initial_max_stream_data_bidi_local(15);
18260 config.set_initial_max_stream_data_bidi_remote(15);
18261 config.set_initial_max_stream_data_uni(10);
18262 config.set_initial_max_streams_bidi(3);
18263
18264 let mut pipe = pipe_with_exchanged_cids(&mut config, 0, 16, 1);
18265
18266 let server_addr = testing::Pipe::server_addr();
18267 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
18268
18269 assert_eq!(pipe.client.migrate(client_addr_2, server_addr), Ok(1));
18272 assert_eq!(pipe.client.stream_send(4, b"data", true), Ok(4));
18273 assert_eq!(pipe.advance(), Ok(()));
18274 assert_eq!(
18275 pipe.client
18276 .paths
18277 .get_active()
18278 .expect("no active")
18279 .local_addr(),
18280 client_addr_2
18281 );
18282 assert_eq!(
18283 pipe.client
18284 .paths
18285 .get_active()
18286 .expect("no active")
18287 .peer_addr(),
18288 server_addr
18289 );
18290 assert_eq!(
18291 pipe.server.path_event_next(),
18292 Some(PathEvent::New(server_addr, client_addr_2))
18293 );
18294 assert_eq!(
18295 pipe.server.path_event_next(),
18296 Some(PathEvent::Validated(server_addr, client_addr_2))
18297 );
18298 assert_eq!(
18299 pipe.server.path_event_next(),
18300 Some(PathEvent::PeerMigrated(server_addr, client_addr_2))
18301 );
18302 assert_eq!(pipe.server.path_event_next(), None);
18303 assert_eq!(
18304 pipe.server
18305 .paths
18306 .get_active()
18307 .expect("no active")
18308 .local_addr(),
18309 server_addr
18310 );
18311 assert_eq!(
18312 pipe.server
18313 .paths
18314 .get_active()
18315 .expect("no active")
18316 .peer_addr(),
18317 client_addr_2
18318 );
18319 }
18320
18321 #[rstest]
18322 fn connection_migration_reordered_non_probing(
18323 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18324 ) {
18325 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
18326 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
18327 config
18328 .load_cert_chain_from_pem_file("examples/cert.crt")
18329 .unwrap();
18330 config
18331 .load_priv_key_from_pem_file("examples/cert.key")
18332 .unwrap();
18333 config
18334 .set_application_protos(&[b"proto1", b"proto2"])
18335 .unwrap();
18336 config.verify_peer(false);
18337 config.set_active_connection_id_limit(2);
18338 config.set_initial_max_data(30);
18339 config.set_initial_max_stream_data_bidi_local(15);
18340 config.set_initial_max_stream_data_bidi_remote(15);
18341 config.set_initial_max_stream_data_uni(10);
18342 config.set_initial_max_streams_bidi(3);
18343
18344 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 1);
18345
18346 let client_addr = testing::Pipe::client_addr();
18347 let server_addr = testing::Pipe::server_addr();
18348 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
18349
18350 assert_eq!(pipe.client.probe_path(client_addr_2, server_addr), Ok(1));
18351 assert_eq!(pipe.advance(), Ok(()));
18352 assert_eq!(
18353 pipe.client.path_event_next(),
18354 Some(PathEvent::Validated(client_addr_2, server_addr))
18355 );
18356 assert_eq!(pipe.client.path_event_next(), None);
18357 assert_eq!(
18358 pipe.server.path_event_next(),
18359 Some(PathEvent::New(server_addr, client_addr_2))
18360 );
18361 assert_eq!(
18362 pipe.server.path_event_next(),
18363 Some(PathEvent::Validated(server_addr, client_addr_2))
18364 );
18365 assert_eq!(pipe.server.path_event_next(), None);
18366
18367 assert_eq!(pipe.client.stream_send(0, b"data", true), Ok(4));
18369 let mut first = testing::emit_flight(&mut pipe.client).unwrap();
18370 first.iter_mut().for_each(|(_, si)| si.from = client_addr_2);
18371 assert_eq!(pipe.client.stream_send(4, b"data", true), Ok(4));
18373 let second = testing::emit_flight(&mut pipe.client).unwrap();
18374 assert_eq!(testing::process_flight(&mut pipe.server, second), Ok(()));
18376 assert_eq!(testing::process_flight(&mut pipe.server, first), Ok(()));
18377
18378 assert_eq!(pipe.server.path_event_next(), None);
18381 assert_eq!(
18382 pipe.server
18383 .paths
18384 .get_active()
18385 .expect("no active")
18386 .peer_addr(),
18387 client_addr
18388 );
18389 }
18390
18391 #[rstest]
18392 fn resilience_against_migration_attack(
18393 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18394 ) {
18395 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
18396 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
18397 config
18398 .load_cert_chain_from_pem_file("examples/cert.crt")
18399 .unwrap();
18400 config
18401 .load_priv_key_from_pem_file("examples/cert.key")
18402 .unwrap();
18403 config
18404 .set_application_protos(&[b"proto1", b"proto2"])
18405 .unwrap();
18406 config.verify_peer(false);
18407 config.set_active_connection_id_limit(3);
18408 config.set_initial_max_data(100000);
18409 config.set_initial_max_stream_data_bidi_local(100000);
18410 config.set_initial_max_stream_data_bidi_remote(100000);
18411 config.set_initial_max_streams_bidi(2);
18412
18413 let mut pipe = pipe_with_exchanged_cids(&mut config, 16, 16, 1);
18414
18415 let client_addr = testing::Pipe::client_addr();
18416 let server_addr = testing::Pipe::server_addr();
18417 let spoofed_client_addr = "127.0.0.1:6666".parse().unwrap();
18418
18419 const DATA_BYTES: usize = 24000;
18420 let buf = [42; DATA_BYTES];
18421 let mut recv_buf = [0; DATA_BYTES];
18422 let send1_bytes = pipe.server.stream_send(1, &buf, true).unwrap();
18423 assert_eq!(send1_bytes, match cc_algorithm_name {
18424 #[cfg(feature = "openssl")]
18425 "bbr2" => 14041,
18426 #[cfg(not(feature = "openssl"))]
18427 "bbr2" => 13955,
18428 #[cfg(feature = "openssl")]
18429 "bbr2_gcongestion" => 13966,
18430 #[cfg(not(feature = "openssl"))]
18431 "bbr2_gcongestion" => 13880,
18432 _ => 12000,
18433 });
18434 assert_eq!(
18435 testing::process_flight(
18436 &mut pipe.client,
18437 testing::emit_flight(&mut pipe.server).unwrap()
18438 ),
18439 Ok(())
18440 );
18441 let (rcv_data_1, _) = pipe.client.stream_recv(1, &mut recv_buf).unwrap();
18442
18443 let mut faked_addr_flight =
18445 testing::emit_flight(&mut pipe.client).unwrap();
18446 faked_addr_flight
18447 .iter_mut()
18448 .for_each(|(_, si)| si.from = spoofed_client_addr);
18449 assert_eq!(
18450 testing::process_flight(&mut pipe.server, faked_addr_flight),
18451 Ok(())
18452 );
18453 assert_eq!(
18454 pipe.server.stream_send(1, &buf[send1_bytes..], true),
18455 Ok(24000 - send1_bytes)
18456 );
18457 assert_eq!(
18458 pipe.server.path_event_next(),
18459 Some(PathEvent::ReusedSourceConnectionId(
18460 0,
18461 (server_addr, client_addr),
18462 (server_addr, spoofed_client_addr)
18463 ))
18464 );
18465 assert_eq!(
18466 pipe.server.path_event_next(),
18467 Some(PathEvent::New(server_addr, spoofed_client_addr))
18468 );
18469
18470 assert_eq!(
18471 pipe.server.is_path_validated(server_addr, client_addr),
18472 Ok(true)
18473 );
18474 assert_eq!(
18475 pipe.server
18476 .is_path_validated(server_addr, spoofed_client_addr),
18477 Ok(false)
18478 );
18479
18480 testing::emit_flight(&mut pipe.server).unwrap();
18482
18483 let probed_pid = pipe
18486 .server
18487 .paths
18488 .path_id_from_addrs(&(server_addr, spoofed_client_addr))
18489 .unwrap();
18490 let probe_instant = pipe
18491 .server
18492 .paths
18493 .get(probed_pid)
18494 .unwrap()
18495 .recovery
18496 .loss_detection_timer()
18497 .unwrap();
18498 let timer = probe_instant.duration_since(time::Instant::now());
18499 std::thread::sleep(timer + time::Duration::from_millis(1));
18500
18501 pipe.server.on_timeout();
18502
18503 assert_eq!(
18506 pipe.server.path_event_next(),
18507 Some(PathEvent::FailedValidation(
18508 server_addr,
18509 spoofed_client_addr
18510 ))
18511 );
18512
18513 assert_eq!(
18514 pipe.server.is_path_validated(server_addr, client_addr),
18515 Ok(true)
18516 );
18517 assert_eq!(
18518 pipe.server
18519 .is_path_validated(server_addr, spoofed_client_addr),
18520 Ok(false)
18521 );
18522
18523 let server_active_path = pipe.server.paths.get_active().unwrap();
18524 assert_eq!(server_active_path.local_addr(), server_addr);
18525 assert_eq!(server_active_path.peer_addr(), client_addr);
18526 assert_eq!(pipe.advance(), Ok(()));
18527 let (rcv_data_2, fin) =
18528 pipe.client.stream_recv(1, &mut recv_buf).unwrap();
18529 assert!(fin);
18530 assert_eq!(rcv_data_1 + rcv_data_2, DATA_BYTES);
18531 }
18532
18533 #[rstest]
18534 fn consecutive_non_ack_eliciting(
18535 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18536 ) {
18537 let mut buf = [0; 65535];
18538
18539 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
18540 assert_eq!(pipe.handshake(), Ok(()));
18541
18542 let frames = [frame::Frame::Ping { mtu_probe: None }];
18545 let pkt_type = packet::Type::Short;
18546 for _ in 0..24 {
18547 let len = pipe
18548 .send_pkt_to_server(pkt_type, &frames, &mut buf)
18549 .unwrap();
18550 assert!(len > 0);
18551
18552 let frames =
18553 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
18554 assert!(
18555 frames
18556 .iter()
18557 .all(|frame| matches!(frame, frame::Frame::ACK { .. })),
18558 "ACK only"
18559 );
18560 }
18561
18562 let len = pipe
18564 .send_pkt_to_server(pkt_type, &frames, &mut buf)
18565 .unwrap();
18566 assert!(len > 0);
18567
18568 let frames =
18569 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
18570 assert!(
18571 frames
18572 .iter()
18573 .any(|frame| matches!(frame, frame::Frame::Ping {
18574 mtu_probe: None
18575 })),
18576 "found a PING"
18577 );
18578 }
18579
18580 #[rstest]
18581 fn send_ack_eliciting_causes_ping(
18582 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18583 ) {
18584 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
18586 assert_eq!(pipe.handshake(), Ok(()));
18587
18588 pipe.server.send_ack_eliciting().unwrap();
18590
18591 let mut buf = [0; 1500];
18593 let (len, _) = pipe.server.send(&mut buf).unwrap();
18594
18595 let frames =
18596 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
18597 let mut iter = frames.iter();
18598
18599 assert_eq!(iter.next(), Some(&frame::Frame::Ping { mtu_probe: None }));
18600 }
18601
18602 #[rstest]
18603 fn send_ack_eliciting_no_ping(
18604 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18605 ) {
18606 let mut pipe = testing::Pipe::new(cc_algorithm_name).unwrap();
18608 assert_eq!(pipe.handshake(), Ok(()));
18609
18610 pipe.server.send_ack_eliciting().unwrap();
18612
18613 assert_eq!(pipe.server.stream_send(1, b"a", false), Ok(1));
18616
18617 let mut buf = [0; 1500];
18619 let (len, _) = pipe.server.send(&mut buf).unwrap();
18620
18621 let frames =
18622 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
18623 let mut iter = frames.iter();
18624
18625 assert!(matches!(
18626 iter.next(),
18627 Some(&frame::Frame::Stream {
18628 stream_id: 1,
18629 data: _
18630 })
18631 ));
18632 assert!(iter.next().is_none());
18633 }
18634
18635 #[rstest]
18638 fn stop_sending_stream_send_after_reset_stream_ack(
18639 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18640 ) {
18641 let mut b = [0; 15];
18642
18643 let mut buf = [0; 65535];
18644
18645 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
18646 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
18647 config
18648 .load_cert_chain_from_pem_file("examples/cert.crt")
18649 .unwrap();
18650 config
18651 .load_priv_key_from_pem_file("examples/cert.key")
18652 .unwrap();
18653 config
18654 .set_application_protos(&[b"proto1", b"proto2"])
18655 .unwrap();
18656 config.set_initial_max_data(999999999);
18657 config.set_initial_max_stream_data_bidi_local(30);
18658 config.set_initial_max_stream_data_bidi_remote(30);
18659 config.set_initial_max_stream_data_uni(30);
18660 config.set_initial_max_streams_bidi(1000);
18661 config.set_initial_max_streams_uni(0);
18662 config.verify_peer(false);
18663
18664 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
18665 assert_eq!(pipe.handshake(), Ok(()));
18666
18667 assert_eq!(pipe.server.streams.len(), 0);
18668 assert_eq!(pipe.server.readable().len(), 0);
18669 assert_eq!(pipe.server.writable().len(), 0);
18670
18671 assert_eq!(pipe.client.stream_send(0, b"hello", true), Ok(5));
18673 assert_eq!(pipe.client.stream_send(4, b"hello", true), Ok(5));
18674 assert_eq!(pipe.client.stream_send(8, b"hello", true), Ok(5));
18675 assert_eq!(pipe.client.stream_send(12, b"hello", true), Ok(5));
18676 assert_eq!(pipe.client.stream_send(16, b"hello", true), Ok(5));
18677 assert_eq!(pipe.client.stream_send(20, b"hello", true), Ok(5));
18678 assert_eq!(pipe.client.stream_send(24, b"hello", true), Ok(5));
18679 assert_eq!(pipe.client.stream_send(28, b"hello", true), Ok(5));
18680 assert_eq!(pipe.client.stream_send(32, b"hello", true), Ok(5));
18681 assert_eq!(pipe.client.stream_send(36, b"hello", true), Ok(5));
18682 assert_eq!(pipe.advance(), Ok(()));
18683
18684 let mut r = pipe.server.readable();
18686 assert_eq!(r.len(), 10);
18687 assert_eq!(r.next(), Some(0));
18688 assert_eq!(r.next(), Some(4));
18689 assert_eq!(r.next(), Some(8));
18690 assert_eq!(r.next(), Some(12));
18691 assert_eq!(r.next(), Some(16));
18692 assert_eq!(r.next(), Some(20));
18693 assert_eq!(r.next(), Some(24));
18694 assert_eq!(r.next(), Some(28));
18695 assert_eq!(r.next(), Some(32));
18696 assert_eq!(r.next(), Some(36));
18697
18698 assert_eq!(r.next(), None);
18699
18700 let mut w = pipe.server.writable();
18701 assert_eq!(w.len(), 10);
18702 assert_eq!(w.next(), Some(0));
18703 assert_eq!(w.next(), Some(4));
18704 assert_eq!(w.next(), Some(8));
18705 assert_eq!(w.next(), Some(12));
18706 assert_eq!(w.next(), Some(16));
18707 assert_eq!(w.next(), Some(20));
18708 assert_eq!(w.next(), Some(24));
18709 assert_eq!(w.next(), Some(28));
18710 assert_eq!(w.next(), Some(32));
18711 assert_eq!(w.next(), Some(36));
18712 assert_eq!(w.next(), None);
18713
18714 assert_eq!(pipe.server.stream_recv(0, &mut b), Ok((5, true)));
18716 assert!(pipe.server.stream_finished(0));
18717
18718 assert_eq!(pipe.server.readable().len(), 9);
18719 assert_eq!(pipe.server.writable().len(), 10);
18720
18721 assert_eq!(pipe.server.stream_writable(0, 0), Ok(true));
18722
18723 while pipe.server.stream_send(0, b"world", false) != Err(Error::Done) {
18725 assert_eq!(pipe.advance(), Ok(()));
18726 }
18727
18728 assert_eq!(pipe.server.writable().len(), 9);
18729 assert_eq!(pipe.server.stream_writable(0, 0), Ok(true));
18730
18731 let frames = [frame::Frame::StopSending {
18733 stream_id: 0,
18734 error_code: 42,
18735 }];
18736
18737 let pkt_type = packet::Type::Short;
18738 let len = pipe
18739 .send_pkt_to_server(pkt_type, &frames, &mut buf)
18740 .unwrap();
18741
18742 let frames =
18744 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
18745
18746 let mut iter = frames.iter();
18747
18748 iter.next();
18750
18751 assert_eq!(
18752 iter.next(),
18753 Some(&frame::Frame::ResetStream {
18754 stream_id: 0,
18755 error_code: 42,
18756 final_size: 30,
18757 })
18758 );
18759
18760 let mut w = pipe.server.writable();
18763 assert_eq!(w.len(), 10);
18764
18765 assert!(w.any(|s| s == 0));
18766 assert_eq!(
18767 pipe.server.stream_writable(0, 1),
18768 Err(Error::StreamStopped(42))
18769 );
18770
18771 assert_eq!(pipe.server.writable().len(), 10);
18772 assert_eq!(pipe.server.streams.len(), 10);
18773
18774 let mut ranges = ranges::RangeSet::default();
18776 ranges.insert(0..12);
18777
18778 let frames = [frame::Frame::ACK {
18779 ack_delay: 15,
18780 ranges,
18781 ecn_counts: None,
18782 }];
18783
18784 assert_eq!(pipe.send_pkt_to_server(pkt_type, &frames, &mut buf), Ok(0));
18785
18786 assert_eq!(pipe.server.streams.len(), 9);
18788
18789 let frames = [frame::Frame::StopSending {
18791 stream_id: 0,
18792 error_code: 42,
18793 }];
18794
18795 let len = pipe
18796 .send_pkt_to_server(pkt_type, &frames, &mut buf)
18797 .unwrap();
18798
18799 let frames =
18800 testing::decode_pkt(&mut pipe.client, &mut buf[..len]).unwrap();
18801
18802 assert_eq!(frames.len(), 1);
18803
18804 match frames.first() {
18805 Some(frame::Frame::ACK { .. }) => (),
18806
18807 f => panic!("expected ACK frame, got {:?}", f),
18808 };
18809
18810 assert_eq!(pipe.server.streams.len(), 9);
18811
18812 let mut w = pipe.server.writable();
18814 assert_eq!(w.len(), 9);
18815 assert!(!w.any(|s| s == 0));
18816
18817 assert_eq!(pipe.server.stream_send(0, b"world", true), Err(Error::Done),);
18820
18821 let mut w = pipe.server.writable();
18823 assert_eq!(w.len(), 9);
18824 assert!(!w.any(|s| s == 0));
18825 }
18826
18827 #[rstest]
18828 fn challenge_no_cids(
18829 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18830 ) {
18831 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
18832 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
18833 config
18834 .load_cert_chain_from_pem_file("examples/cert.crt")
18835 .unwrap();
18836 config
18837 .load_priv_key_from_pem_file("examples/cert.key")
18838 .unwrap();
18839 config
18840 .set_application_protos(&[b"proto1", b"proto2"])
18841 .unwrap();
18842 config.verify_peer(false);
18843 config.set_active_connection_id_limit(4);
18844 config.set_initial_max_data(30);
18845 config.set_initial_max_stream_data_bidi_local(15);
18846 config.set_initial_max_stream_data_bidi_remote(15);
18847 config.set_initial_max_stream_data_uni(10);
18848 config.set_initial_max_streams_bidi(3);
18849
18850 let mut pipe =
18851 testing::Pipe::with_config_and_scid_lengths(&mut config, 16, 16)
18852 .unwrap();
18853 assert_eq!(pipe.handshake(), Ok(()));
18854
18855 let mut server_cids = Vec::new();
18857 for _ in 0..2 {
18858 let (cid, reset_token) = testing::create_cid_and_reset_token(16);
18859 pipe.server
18860 .new_scid(&cid, reset_token, true)
18861 .expect("server issue cid");
18862 server_cids.push(cid);
18863 }
18864 assert_eq!(pipe.advance(), Ok(()));
18865
18866 let server_addr = testing::Pipe::server_addr();
18867 let client_addr_2 = "127.0.0.1:5678".parse().unwrap();
18868
18869 let frames = [frame::Frame::PathChallenge {
18871 data: [0, 1, 2, 3, 4, 5, 6, 7],
18872 }];
18873 let mut pkt_buf = [0u8; 1500];
18874 let mut b = octets::OctetsMut::with_slice(&mut pkt_buf);
18875 let epoch = packet::Type::Short.to_epoch().unwrap();
18876 let crypto_ctx = &mut pipe.client.crypto_ctx[epoch];
18877 let pn = pipe.client.next_pkt_num;
18878 let pn_len = 4;
18879
18880 let hdr = Header {
18881 ty: packet::Type::Short,
18882 version: pipe.client.version,
18883 dcid: server_cids[0].clone(),
18884 scid: ConnectionId::from_ref(&[5, 4, 3, 2, 1]),
18885 pkt_num: 0,
18886 pkt_num_len: pn_len,
18887 token: pipe.client.token.clone(),
18888 versions: None,
18889 key_phase: pipe.client.key_phase,
18890 };
18891 hdr.to_bytes(&mut b).expect("encode header");
18892 let payload_len = frames.iter().fold(0, |acc, x| acc + x.wire_len());
18893 b.put_u32(pn as u32).expect("put pn");
18894
18895 let payload_offset = b.off();
18896
18897 for frame in frames {
18898 frame.to_bytes(&mut b).expect("encode frames");
18899 }
18900
18901 let aead = crypto_ctx.crypto_seal.as_ref().expect("crypto seal");
18902
18903 let written = packet::encrypt_pkt(
18904 &mut b,
18905 pn,
18906 pn_len,
18907 payload_len,
18908 payload_offset,
18909 None,
18910 aead,
18911 )
18912 .expect("packet encrypt");
18913 pipe.client.next_pkt_num += 1;
18914
18915 pipe.server
18916 .recv(&mut pkt_buf[..written], RecvInfo {
18917 to: server_addr,
18918 from: client_addr_2,
18919 })
18920 .expect("server receive path challenge");
18921
18922 assert!(!pipe
18924 .server
18925 .paths_iter(server_addr)
18926 .any(|path| path == client_addr_2));
18927 }
18928
18929 #[rstest]
18930 fn successful_probe_pmtud(
18931 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18932 ) {
18933 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
18934 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
18935 config
18936 .load_cert_chain_from_pem_file("examples/cert.crt")
18937 .unwrap();
18938 config
18939 .load_priv_key_from_pem_file("examples/cert.key")
18940 .unwrap();
18941 config
18942 .set_application_protos(&[b"proto1", b"proto2"])
18943 .unwrap();
18944 config.verify_peer(false);
18945 config.set_initial_max_data(100000);
18946 config.set_initial_max_stream_data_bidi_local(100000);
18947 config.set_initial_max_stream_data_bidi_remote(100000);
18948 config.set_initial_max_streams_bidi(2);
18949 config.set_active_connection_id_limit(4);
18950 config.set_max_send_udp_payload_size(1350);
18951 config.set_max_recv_udp_payload_size(1350);
18952 config.discover_pmtu(true);
18953
18954 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
18956 assert_eq!(pipe.handshake(), Ok(()));
18957
18958 let server_addr = testing::Pipe::server_addr();
18959 let client_addr = testing::Pipe::client_addr();
18960 let pid_1 = pipe
18961 .server
18962 .paths
18963 .path_id_from_addrs(&(server_addr, client_addr))
18964 .expect("no such path");
18965
18966 let pmtu_param = &mut pipe.server.paths.get_mut(pid_1).unwrap().pmtud;
18968 assert!(pmtu_param.get_probe_status());
18969 assert_eq!(pmtu_param.get_probe_size(), 1350);
18970 assert_eq!(pipe.advance(), Ok(()));
18971
18972 for (_, p) in pipe.server.paths.iter_mut() {
18973 assert_eq!(p.pmtud.get_current(), 1350);
18974 assert!(!p.pmtud.get_probe_status());
18975 }
18976 }
18977
18978 #[rstest]
18979 fn pmtud_probe_loss(
18980 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
18981 ) {
18982 let mut config = Config::new(crate::PROTOCOL_VERSION).unwrap();
18983 assert_eq!(config.set_cc_algorithm_name(cc_algorithm_name), Ok(()));
18984 config
18985 .load_cert_chain_from_pem_file("examples/cert.crt")
18986 .unwrap();
18987 config
18988 .load_priv_key_from_pem_file("examples/cert.key")
18989 .unwrap();
18990 config
18991 .set_application_protos(&[b"proto1", b"proto2"])
18992 .unwrap();
18993 config.verify_peer(false);
18994 config.set_initial_max_data(100000);
18995 config.set_initial_max_stream_data_bidi_local(100000);
18996 config.set_initial_max_stream_data_bidi_remote(100000);
18997 config.set_initial_max_streams_bidi(2);
18998 config.set_active_connection_id_limit(4);
18999 config.set_max_send_udp_payload_size(1350);
19000 config.set_max_recv_udp_payload_size(1250);
19001 config.discover_pmtu(true);
19002
19003 let mut pipe = testing::Pipe::with_config(&mut config).unwrap();
19005 assert_eq!(pipe.handshake(), Ok(()));
19006
19007 let server_addr = testing::Pipe::server_addr();
19008 let client_addr = testing::Pipe::client_addr();
19009 let pid_1 = pipe
19010 .server
19011 .paths
19012 .path_id_from_addrs(&(server_addr, client_addr))
19013 .expect("no such path");
19014
19015 let pmtu_param = &mut pipe.server.paths.get_mut(pid_1).unwrap().pmtud;
19017 assert!(pmtu_param.get_probe_status());
19018 assert_eq!(pmtu_param.get_probe_size(), 1350);
19019 std::thread::sleep(
19020 pipe.server.paths.get_mut(pid_1).unwrap().recovery.rtt() +
19021 time::Duration::from_millis(1),
19022 );
19023
19024 let active_server_path = pipe.server.paths.get_active_mut().unwrap();
19025 let pmtu_param = &mut active_server_path.pmtud;
19026
19027 assert_eq!(pmtu_param.get_current(), 1200);
19029
19030 assert!(pmtu_param.get_probe_status());
19032 }
19033
19034 #[cfg(feature = "boringssl-boring-crate")]
19035 #[rstest]
19036 fn enable_pmtud_mid_handshake(
19037 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
19038 ) {
19039 let mut server_tls_ctx_builder =
19042 boring::ssl::SslContextBuilder::new(boring::ssl::SslMethod::tls())
19043 .unwrap();
19044 server_tls_ctx_builder
19045 .set_certificate_chain_file("examples/cert.crt")
19046 .unwrap();
19047 server_tls_ctx_builder
19048 .set_private_key_file(
19049 "examples/cert.key",
19050 boring::ssl::SslFiletype::PEM,
19051 )
19052 .unwrap();
19053 server_tls_ctx_builder.set_select_certificate_callback(|mut hello| {
19054 <Connection>::set_discover_pmtu_in_handshake(hello.ssl_mut(), true)
19055 .unwrap();
19056
19057 Ok(())
19058 });
19059
19060 let mut server_config = Config::with_boring_ssl_ctx_builder(
19061 crate::PROTOCOL_VERSION,
19062 server_tls_ctx_builder,
19063 )
19064 .unwrap();
19065 assert_eq!(
19066 server_config.set_cc_algorithm_name(cc_algorithm_name),
19067 Ok(())
19068 );
19069
19070 let mut client_config = Config::new(crate::PROTOCOL_VERSION).unwrap();
19071 client_config
19072 .load_cert_chain_from_pem_file("examples/cert.crt")
19073 .unwrap();
19074 client_config
19075 .load_priv_key_from_pem_file("examples/cert.key")
19076 .unwrap();
19077
19078 for config in [&mut client_config, &mut server_config] {
19079 config
19080 .set_application_protos(&[b"proto1", b"proto2"])
19081 .unwrap();
19082 config.set_initial_max_data(1000000);
19083 config.set_initial_max_stream_data_bidi_local(15);
19084 config.set_initial_max_stream_data_bidi_remote(15);
19085 config.set_initial_max_stream_data_uni(10);
19086 config.set_initial_max_streams_bidi(3);
19087 config.set_initial_max_streams_uni(3);
19088 config.set_max_idle_timeout(180_000);
19089 config.verify_peer(false);
19090 config.set_ack_delay_exponent(8);
19091 config.set_max_send_udp_payload_size(1350);
19092 }
19093
19094 let mut pipe = testing::Pipe::with_client_and_server_config(
19095 &mut client_config,
19096 &mut server_config,
19097 )
19098 .unwrap();
19099
19100 let pmtud_enabled = pipe
19101 .server
19102 .paths
19103 .get_active_mut()
19104 .unwrap()
19105 .pmtud
19106 .is_enabled();
19107 assert_eq!(pmtud_enabled, false);
19108
19109 assert_eq!(pipe.handshake(), Ok(()));
19110
19111 let pmtud_enabled = pipe
19112 .server
19113 .paths
19114 .get_active_mut()
19115 .unwrap()
19116 .pmtud
19117 .is_enabled();
19118 assert_eq!(pmtud_enabled, true);
19119
19120 let current_path_size = pipe
19121 .server
19122 .paths
19123 .get_active_mut()
19124 .unwrap()
19125 .pmtud
19126 .get_current();
19127 assert_eq!(current_path_size, 1200);
19128
19129 assert_eq!(pipe.advance(), Ok(()));
19130
19131 let new_path_size = pipe
19132 .server
19133 .paths
19134 .get_active_mut()
19135 .unwrap()
19136 .pmtud
19137 .get_current();
19138 assert_eq!(new_path_size, 1350);
19139 }
19140
19141 #[cfg(feature = "boringssl-boring-crate")]
19142 #[rstest]
19143 fn disable_pmtud_mid_handshake(
19144 #[values("cubic", "bbr2", "bbr2_gcongestion")] cc_algorithm_name: &str,
19145 ) {
19146 let mut server_tls_ctx_builder =
19149 boring::ssl::SslContextBuilder::new(boring::ssl::SslMethod::tls())
19150 .unwrap();
19151 server_tls_ctx_builder
19152 .set_certificate_chain_file("examples/cert.crt")
19153 .unwrap();
19154 server_tls_ctx_builder
19155 .set_private_key_file(
19156 "examples/cert.key",
19157 boring::ssl::SslFiletype::PEM,
19158 )
19159 .unwrap();
19160 server_tls_ctx_builder.set_select_certificate_callback(|mut hello| {
19161 <Connection>::set_discover_pmtu_in_handshake(hello.ssl_mut(), false)
19162 .unwrap();
19163
19164 Ok(())
19165 });
19166
19167 let mut server_config = Config::with_boring_ssl_ctx_builder(
19168 crate::PROTOCOL_VERSION,
19169 server_tls_ctx_builder,
19170 )
19171 .unwrap();
19172 assert_eq!(
19173 server_config.set_cc_algorithm_name(cc_algorithm_name),
19174 Ok(())
19175 );
19176
19177 let mut client_config = Config::new(crate::PROTOCOL_VERSION).unwrap();
19178 client_config
19179 .load_cert_chain_from_pem_file("examples/cert.crt")
19180 .unwrap();
19181 client_config
19182 .load_priv_key_from_pem_file("examples/cert.key")
19183 .unwrap();
19184
19185 for config in [&mut client_config, &mut server_config] {
19186 config
19187 .set_application_protos(&[b"proto1", b"proto2"])
19188 .unwrap();
19189 config.set_initial_max_data(1000000);
19190 config.set_initial_max_stream_data_bidi_local(15);
19191 config.set_initial_max_stream_data_bidi_remote(15);
19192 config.set_initial_max_stream_data_uni(10);
19193 config.set_initial_max_streams_bidi(3);
19194 config.set_initial_max_streams_uni(3);
19195 config.set_max_idle_timeout(180_000);
19196 config.verify_peer(false);
19197 config.set_ack_delay_exponent(8);
19198 config.set_max_send_udp_payload_size(1350);
19199 config.discover_pmtu(true);
19200 }
19201
19202 let mut pipe = testing::Pipe::with_client_and_server_config(
19203 &mut client_config,
19204 &mut server_config,
19205 )
19206 .unwrap();
19207
19208 let pmtud_enabled = pipe
19209 .server
19210 .paths
19211 .get_active_mut()
19212 .unwrap()
19213 .pmtud
19214 .is_enabled();
19215 assert_eq!(pmtud_enabled, true);
19216
19217 assert_eq!(pipe.handshake(), Ok(()));
19218
19219 let pmtud_enabled = pipe
19220 .server
19221 .paths
19222 .get_active_mut()
19223 .unwrap()
19224 .pmtud
19225 .is_enabled();
19226 assert_eq!(pmtud_enabled, false);
19227
19228 let current_path_size = pipe
19229 .server
19230 .paths
19231 .get_active_mut()
19232 .unwrap()
19233 .pmtud
19234 .get_current();
19235 assert_eq!(current_path_size, 1200);
19236
19237 assert_eq!(pipe.advance(), Ok(()));
19238
19239 let new_path_size = pipe
19240 .server
19241 .paths
19242 .get_active_mut()
19243 .unwrap()
19244 .pmtud
19245 .get_current();
19246 assert_eq!(new_path_size, 1200);
19247 }
19248}
19249
19250pub use crate::packet::ConnectionId;
19251pub use crate::packet::Header;
19252pub use crate::packet::Type;
19253
19254pub use crate::path::PathEvent;
19255pub use crate::path::PathStats;
19256pub use crate::path::SocketAddrIter;
19257
19258pub use crate::recovery::BbrBwLoReductionStrategy;
19259pub use crate::recovery::BbrParams;
19260pub use crate::recovery::CongestionControlAlgorithm;
19261use crate::recovery::RecoveryOps;
19262pub use crate::recovery::StartupExit;
19263pub use crate::recovery::StartupExitReason;
19264
19265pub use crate::stream::StreamIter;
19266
19267pub use crate::range_buf::BufFactory;
19268pub use crate::range_buf::BufSplit;
19269
19270mod cid;
19271mod crypto;
19272mod dgram;
19273#[cfg(feature = "ffi")]
19274mod ffi;
19275mod flowcontrol;
19276mod frame;
19277pub mod h3;
19278mod minmax;
19279mod packet;
19280mod path;
19281mod pmtud;
19282mod rand;
19283mod range_buf;
19284mod ranges;
19285mod recovery;
19286mod stream;
19287mod tls;