use crate::{
frame::ack_elicitation::AckElicitation, inet::ExplicitCongestionNotification, path,
time::Timestamp, transmission,
};
#[cfg(feature = "alloc")]
pub type SentPackets<PacketInfo> = crate::packet::number::Map<SentPacketInfo<PacketInfo>>;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct SentPacketInfo<PacketInfo> {
pub congestion_controlled: bool,
pub sent_bytes: u16,
pub time_sent: Timestamp,
pub ack_elicitation: AckElicitation,
pub path_id: path::Id,
pub ecn: ExplicitCongestionNotification,
pub transmission_mode: transmission::Mode,
pub cc_packet_info: PacketInfo,
}
impl<PacketInfo> SentPacketInfo<PacketInfo> {
pub fn new(
congestion_controlled: bool,
sent_bytes: usize,
time_sent: Timestamp,
ack_elicitation: AckElicitation,
path_id: path::Id,
ecn: ExplicitCongestionNotification,
transmission_mode: transmission::Mode,
cc_packet_info: PacketInfo,
) -> Self {
debug_assert_eq!(
sent_bytes > 0,
congestion_controlled,
"sent bytes should be zero for packets that are not congestion controlled"
);
SentPacketInfo {
congestion_controlled,
sent_bytes: sent_bytes
.try_into()
.expect("sent_bytes exceeds max UDP payload size"),
time_sent,
ack_elicitation,
path_id,
ecn,
transmission_mode,
cc_packet_info,
}
}
}
#[cfg(test)]
mod test {
use crate::{
frame::ack_elicitation::AckElicitation,
inet::ExplicitCongestionNotification,
path,
recovery::SentPacketInfo,
time::{Clock, NoopClock},
transmission,
};
#[test]
#[should_panic]
fn too_large_packet() {
SentPacketInfo::new(
true,
u16::MAX as usize + 1,
NoopClock.get_time(),
AckElicitation::Eliciting,
unsafe { path::Id::new(0) },
ExplicitCongestionNotification::default(),
transmission::Mode::Normal,
(),
);
}
#[test]
#[cfg_attr(miri, ignore)] fn sent_packet_info_size_test() {
insta::assert_debug_snapshot!(
stringify!(sent_packet_info_size_test),
core::mem::size_of::<SentPacketInfo<()>>()
);
assert_eq!(
core::mem::size_of::<Option<SentPacketInfo<()>>>(),
core::mem::size_of::<SentPacketInfo<()>>()
);
}
}