mod sliding_window;
pub use sliding_window::{SlidingWindow, SlidingWindowError};
mod protected_packet_number;
pub use protected_packet_number::ProtectedPacketNumber;
use crate::varint::VarInt;
mod packet_number;
pub use packet_number::PacketNumber;
mod truncated_packet_number;
pub use truncated_packet_number::TruncatedPacketNumber;
mod packet_number_space;
pub use packet_number_space::PacketNumberSpace;
pub(crate) const PACKET_NUMBER_LEN_MASK: u8 = 0b11;
mod packet_number_len;
pub use packet_number_len::PacketNumberLen;
mod packet_number_range;
pub use packet_number_range::PacketNumberRange;
#[cfg(feature = "alloc")]
pub mod map;
#[cfg(feature = "alloc")]
pub use map::Map;
#[cfg(test)]
mod tests;
fn derive_truncation_range(
largest_acknowledged_packet_number: PacketNumber,
packet_number: PacketNumber,
) -> Option<PacketNumberLen> {
let space = packet_number.space();
space.assert_eq(largest_acknowledged_packet_number.space());
packet_number
.as_u64()
.checked_sub(largest_acknowledged_packet_number.as_u64())
.and_then(|value| value.checked_mul(2))
.and_then(|value| VarInt::new(value).ok())
.and_then(|value| PacketNumberLen::from_varint(value, space))
}
#[test]
fn packet_number_len_example_test() {
let largest_acknowledged_packet_number =
PacketNumberSpace::default().new_packet_number(VarInt::from_u32(0x00ab_e8bc));
assert_eq!(
PacketNumberSpace::default()
.new_packet_number(VarInt::from_u32(0x00ac_5c02))
.truncate(largest_acknowledged_packet_number)
.unwrap()
.bitsize(),
16,
);
assert_eq!(
PacketNumberSpace::default()
.new_packet_number(VarInt::from_u32(0x00ac_e8fe))
.truncate(largest_acknowledged_packet_number)
.unwrap()
.bitsize(),
24,
);
}
#[test]
fn packet_decoding_example_test() {
let space = PacketNumberSpace::default();
let largest_packet_number = space.new_packet_number(VarInt::from_u32(0xa82f_30ea));
let truncated_packet_number = TruncatedPacketNumber::new(0x9b32u16, space);
let expected = space.new_packet_number(VarInt::from_u32(0xa82f_9b32));
let actual = decode_packet_number(largest_packet_number, truncated_packet_number);
assert_eq!(actual, expected);
assert_eq!(
expected.truncate(largest_packet_number).unwrap(),
truncated_packet_number
);
}
#[inline(never)] fn decode_packet_number(
largest_pn: PacketNumber,
truncated_pn: TruncatedPacketNumber,
) -> PacketNumber {
let space = largest_pn.space();
space.assert_eq(truncated_pn.space());
let pn_nbits = truncated_pn.bitsize();
let expected_pn = largest_pn.as_u64() + 1;
let pn_win = 1 << pn_nbits;
let pn_hwin = pn_win / 2;
let pn_mask = pn_win - 1;
let mut candidate_pn = (expected_pn & !pn_mask) | truncated_pn.into_u64();
let a = expected_pn
.checked_sub(pn_hwin)
.filter(|v| candidate_pn <= *v)
.is_some();
let b = (1u64 << 62)
.checked_sub(pn_win)
.filter(|v| candidate_pn < *v)
.is_some();
let c = expected_pn
.checked_add(pn_hwin)
.filter(|v| candidate_pn > *v)
.is_some();
let d = candidate_pn >= pn_win;
let ab = a && b;
let cd = !ab && c && d;
core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
if ab {
candidate_pn += pn_win;
}
if cd {
candidate_pn -= pn_win
}
let candidate_pn = VarInt::new(candidate_pn).unwrap_or(VarInt::MAX);
PacketNumber::from_varint(candidate_pn, space)
}