#![allow(clippy::items_after_statements)]
#![allow(clippy::too_many_lines)]
use std::time::{Duration, Instant};
use super::*;
use super::ack::{self, AckAction, AckState};
use super::frame;
use super::session::ReplayWindow;
use super::stream_id::Dir;
use super::streams::StreamRef;
use super::testfix::*;
use super::timers::TimerKind;
use crate::constants::{
FRAME_ACK, FRAME_PADDING, FRAME_PING, INITIAL_WINDOW, MAX_ACK_DELAY, MAX_ACK_RANGES,
MAX_PLAINTEXT, PROTOCOL_VIOLATION, REPLAY_WINDOW,
};
#[derive(Debug, Clone, PartialEq, Eq)]
struct AckFields {
largest: u64,
ack_delay: u64,
first_range: u64,
ranges: Vec<(u64, u64)>,
}
impl AckFields {
fn blocks(&self) -> Vec<std::ops::RangeInclusive<u64>> {
let mut out = Vec::with_capacity(1 + self.ranges.len());
let mut smallest = self
.largest
.checked_sub(self.first_range)
.expect("§12.1: the first block must not descend below counter zero");
out.push(smallest..=self.largest);
for (gap, range) in &self.ranges {
let block_largest = smallest
.checked_sub(*gap)
.and_then(|v| v.checked_sub(2))
.expect("§12.1: a block must not descend below counter zero");
smallest = block_largest
.checked_sub(*range)
.expect("§12.1: a block must not descend below counter zero");
out.push(smallest..=block_largest);
}
out
}
fn counters(&self) -> Vec<u64> {
let mut out = Vec::new();
for b in self.blocks() {
assert!(
b.end() - b.start() < 4096,
"this helper is for small spans only"
);
out.extend(b.rev());
}
out
}
}
fn split_ack(pt: &[u8]) -> (Option<AckFields>, Vec<u8>) {
if pt.first() != Some(&(FRAME_ACK as u8)) {
return (None, pt.to_vec());
}
let mut at = 0usize;
let ty = take_varint(pt, &mut at);
assert_eq!(ty, FRAME_ACK);
let largest = take_varint(pt, &mut at);
let ack_delay = take_varint(pt, &mut at);
let range_count = take_varint(pt, &mut at);
let first_range = take_varint(pt, &mut at);
let mut ranges = Vec::with_capacity(range_count as usize);
for _ in 0..range_count {
let gap = take_varint(pt, &mut at);
let range = take_varint(pt, &mut at);
ranges.push((gap, range));
}
(
Some(AckFields {
largest,
ack_delay,
first_range,
ranges,
}),
pt[at..].to_vec(),
)
}
type Packet = (Option<AckFields>, Vec<Wire>);
fn packets(s: &mut Solo, d: &Drained) -> Vec<Packet> {
d.transmits()
.iter()
.map(|t| {
let pt = s.peer.open_dgram(&t.data);
let (ack, rest) = split_ack(&pt);
(ack, parse_frames(&rest))
})
.collect()
}
fn acks(s: &mut Solo, d: &Drained) -> Vec<AckFields> {
packets(s, d).into_iter().filter_map(|(a, _)| a).collect()
}
fn ping() -> Vec<u8> {
let mut f = Vec::new();
put(&mut f, FRAME_PING);
f
}
fn padding(n: usize) -> Vec<u8> {
let mut f = Vec::new();
for _ in 0..n {
put(&mut f, FRAME_PADDING);
}
f
}
fn ack_frame(largest: u64, ack_delay: u64, first_range: u64, pairs: &[(u64, u64)]) -> Vec<u8> {
let mut f = Vec::new();
put(&mut f, FRAME_ACK);
put(&mut f, largest);
put(&mut f, ack_delay);
put(&mut f, pairs.len() as u64);
put(&mut f, first_range);
for (gap, range) in pairs {
put(&mut f, *gap);
put(&mut f, *range);
}
f
}
fn counter_of(dgram: &[u8]) -> u64 {
u64::from_le_bytes(dgram[6..14].try_into().expect("§3.4 data header"))
}
fn seal_at(peer: &mut RawPeer, counter: u64, pt: &[u8]) -> Vec<u8> {
for _ in 0..4096 {
let d = peer.seal(pt);
let c = counter_of(&d);
assert!(c <= counter, "§7.1: the counter only goes forward");
if c == counter {
return d;
}
}
panic!("seal_at({counter}) never reached its counter");
}
fn feed(s: &mut Solo, now: Instant, dgram: &[u8]) -> Drained {
s.conn.handle_datagram(now, a_addr(), dgram);
drain(&mut s.conn)
}
fn drain_boundary(s: &mut Solo, now: Instant) -> Drained {
s.conn.handle_timeout(now);
drain(&mut s.conn)
}
fn window_of(counters: &[u64]) -> ReplayWindow {
let mut w = ReplayWindow::new();
for c in counters {
assert!(w.check_and_mark(*c), "the fixture must mark {c} fresh");
}
w
}
fn derived(w: &ReplayWindow, delay_us: u64, room: usize) -> Option<AckFields> {
let a = ack::derive(w, delay_us, room)?;
let mut bytes = Vec::new();
frame::Frame::Ack(a).encode(&mut bytes);
let (fields, rest) = split_ack(&bytes);
assert!(rest.is_empty(), "the ACK must encode to exactly its bytes");
fields
}
fn derived_len(w: &ReplayWindow, delay_us: u64, room: usize) -> usize {
let a = ack::derive(w, delay_us, room).expect("an ACK was expected here");
frame::Frame::Ack(a).encoded_len()
}
mod range_semantics {
use super::*;
#[test]
fn pairs_encode_the_spec_arithmetic_not_the_missing_counter_count() {
let w = window_of(&[100, 99, 98, 95, 94, 88, 87, 86]);
let a = derived(&w, 0, MAX_PLAINTEXT).expect("the window has a greatest");
assert_eq!(a.largest, 100, "§12.1: the first block's top");
assert_eq!(a.first_range, 2, "§12.1: 100 − 98");
assert_eq!(
a.ranges,
vec![(1, 1), (4, 2)],
"§12.1: block_largest = prev_smallest − gap − 2"
);
assert_eq!(
a.blocks(),
vec![98..=100, 94..=95, 86..=88],
"and they decode back to the window's ranges"
);
}
#[test]
fn derived_ranges_equal_the_windows_ranges_when_nothing_truncates() {
let w = window_of(&[40, 39, 33, 32, 31, 20, 7, 6, 5, 4, 0]);
let a = derived(&w, 0, MAX_PLAINTEXT).expect("the window has a greatest");
let want: Vec<_> = w.ranges_desc().collect();
assert_eq!(a.blocks(), want, "§12.2: derived from the window, verbatim");
assert_eq!(
a.counters(),
vec![40, 39, 33, 32, 31, 20, 7, 6, 5, 4, 0],
"and the flattened counters are exactly what was marked"
);
}
#[test]
fn one_counter_is_one_block_and_no_pairs() {
let a = derived(&window_of(&[0]), 0, MAX_PLAINTEXT).expect("greatest is 0");
assert_eq!(a.largest, 0);
assert_eq!(a.first_range, 0);
assert!(a.ranges.is_empty(), "§12.1: no subsequent blocks exist");
assert_eq!(a.blocks(), vec![0..=0]);
}
#[test]
fn a_block_reaching_counter_zero_is_legal_and_one_below_is_structural() {
let t = t0();
let mut s = Solo::installed_at(t);
let mut pt = ack_frame(5, 0, 5, &[]);
pt.extend_from_slice(&stream_frame(Solo::peer_uni(0), 0, b"legal", false));
let d = s.deliver(t, &pt);
assert_alive(&d);
assert_eq!(
d.count_events(|e| matches!(e, ConnEvent::StreamOpened { .. })),
1,
"§12.1: a block reaching exactly zero is not a failure, so the \
packet's other frames apply"
);
let mut s = Solo::installed_at(t);
let mut pt = ack_frame(5, 0, 6, &[]);
pt.extend_from_slice(&stream_frame(Solo::peer_uni(0), 0, b"illegal", false));
let d = s.deliver(t, &pt);
let frames = s.drain_frames(&d);
assert_violation(&d, &frames, PROTOCOL_VIOLATION);
assert_eq!(
d.count_events(|e| matches!(e, ConnEvent::StreamOpened { .. })),
0,
"§8.2: nothing from the packet is applied"
);
}
#[test]
fn a_pair_descending_to_exactly_zero_is_legal_and_one_below_is_structural() {
let t = t0();
let mut s = Solo::installed_at(t);
let mut pt = ack_frame(5, 0, 0, &[(3, 0)]);
pt.extend_from_slice(&stream_frame(Solo::peer_uni(0), 0, b"legal", false));
let d = s.deliver(t, &pt);
assert_alive(&d);
assert_eq!(
d.count_events(|e| matches!(e, ConnEvent::StreamOpened { .. })),
1
);
let mut s = Solo::installed_at(t);
let mut pt = ack_frame(5, 0, 0, &[(4, 0)]);
pt.extend_from_slice(&stream_frame(Solo::peer_uni(0), 0, b"illegal", false));
let d = s.deliver(t, &pt);
let frames = s.drain_frames(&d);
assert_violation(&d, &frames, PROTOCOL_VIOLATION);
assert_eq!(
d.count_events(|e| matches!(e, ConnEvent::StreamOpened { .. })),
0
);
}
#[test]
fn ack_delay_is_carried_as_raw_microseconds() {
let a = derived(&window_of(&[9]), 12_345, MAX_PLAINTEXT).expect("greatest is 9");
assert_eq!(a.ack_delay, 12_345, "§12.1: raw µs, no exponent scaling");
}
}
mod derivation {
use super::*;
#[test]
fn an_empty_window_derives_no_ack() {
assert!(ack::derive(&ReplayWindow::new(), 0, MAX_PLAINTEXT).is_none());
}
#[test]
fn the_alternating_worst_case_truncates_at_sixty_four_pairs_newest_first() {
let counters: Vec<u64> = (0..REPLAY_WINDOW as u64).step_by(2).collect();
let w = window_of(&counters);
let greatest = w.greatest().expect("something was marked");
assert_eq!(greatest, REPLAY_WINDOW as u64 - 2);
let available: Vec<_> = w.ranges_desc().collect();
assert!(
available.len() > MAX_ACK_RANGES + 1,
"the fixture must offer more blocks than the cap admits, or the \
cap is not exercised: {} available",
available.len()
);
let a = derived(&w, 0, MAX_PLAINTEXT).expect("the window has a greatest");
assert_eq!(
a.ranges.len(),
MAX_ACK_RANGES,
"§12.2: the cap is on the (gap, range) pairs"
);
assert_eq!(
a.blocks().len(),
MAX_ACK_RANGES + 1,
"§12.2: at most 65 blocks including the first"
);
assert_eq!(
a.largest, greatest,
"§12.2: newest-first — the greatest survives truncation"
);
assert_eq!(
a.blocks(),
available[..=MAX_ACK_RANGES].to_vec(),
"§12.2: the surviving blocks are the newest ones, in order"
);
}
#[test]
fn a_small_window_is_not_padded_to_the_cap() {
let w = window_of(&[10, 8, 6]);
let a = derived(&w, 0, MAX_PLAINTEXT).expect("greatest is 10");
assert_eq!(a.ranges.len(), 2, "three blocks means two pairs");
assert_eq!(a.blocks(), vec![10..=10, 8..=8, 6..=6]);
}
#[test]
fn room_truncates_from_the_old_end_and_the_result_always_fits() {
let counters: Vec<u64> = (0..REPLAY_WINDOW as u64).step_by(2).collect();
let w = window_of(&counters);
let greatest = w.greatest().expect("something was marked");
let full_len = derived_len(&w, 0, MAX_PLAINTEXT);
let full = derived(&w, 0, MAX_PLAINTEXT).expect("greatest exists");
assert_eq!(
derived(&w, 0, full_len),
Some(full.clone()),
"§12.2: at exactly its own length, capacity does not bind"
);
let tight = derived(&w, 0, full_len - 1).expect("the first block still fits");
assert!(
tight.ranges.len() < full.ranges.len(),
"§12.2: one byte less must cost at least one pair"
);
assert!(
derived_len(&w, 0, full_len - 1) < full_len,
"§2.1: the returned frame always encodes to <= room bytes"
);
assert_eq!(
tight.largest, greatest,
"§12.2: capacity truncation is newest-first too"
);
}
#[test]
fn no_ack_is_derived_when_even_the_first_block_does_not_fit() {
let w = window_of(&[1000, 999, 990, 980]);
let single = window_of(&[1000, 999]);
let first_only_len = derived_len(&single, 0, MAX_PLAINTEXT);
assert!(
derived(&w, 0, first_only_len).is_some(),
"§2.1: room for the first block is room for an ACK"
);
assert!(
ack::derive(&w, 0, first_only_len - 1).is_none(),
"§2.1: if even the first block does not fit, this returns None"
);
assert!(
ack::derive(&w, 0, 0).is_none(),
"and zero room is the degenerate case of the same rule"
);
}
#[test]
fn the_reported_delay_is_not_capped_at_max_ack_delay() {
let over = u64::try_from(MAX_ACK_DELAY.as_micros()).expect("25 ms fits") + 15_000;
let a = derived(&window_of(&[3]), over, MAX_PLAINTEXT).expect("greatest is 3");
assert_eq!(
a.ack_delay, over,
"§12.3: the cap is the estimator's, applied on receipt (§13.1)"
);
}
#[test]
fn the_derivation_never_reaches_past_the_windows_edge() {
let mut w = ReplayWindow::new();
assert!(w.check_and_mark(0));
let far = REPLAY_WINDOW as u64 + 1;
assert!(w.check_and_mark(far), "far ahead is always fresh");
assert!(
!w.would_accept(0),
"§7.2: 0 is now {} behind and outside the window",
far
);
let a = derived(&w, 0, MAX_PLAINTEXT).expect("greatest is far");
assert_eq!(a.largest, far);
assert!(
!a.counters().contains(&0),
"§12.2: the window is the single record, and it has forgotten 0"
);
assert_eq!(a.blocks(), vec![far..=far]);
}
}
mod ack_delay {
use super::*;
#[test]
fn the_delay_is_the_measured_microseconds_since_the_largest_arrived() {
let t = t0();
let mut a = AckState::new();
assert_eq!(a.on_recv(t, 0, None, true, true), AckAction::Now);
assert_eq!(a.ack_delay_us(t + Duration::from_micros(7_300)), 7_300);
}
#[test]
fn the_delay_tracks_the_newest_packet_not_the_first_of_the_batch() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 5, None, true, true);
a.on_recv(t + Duration::from_millis(10), 6, Some(5), true, true);
assert_eq!(
a.ack_delay_us(t + Duration::from_millis(15)),
5_000,
"§12.3: from the arrival of the packet bearing `largest`"
);
}
#[test]
fn a_gap_filling_arrival_does_not_move_the_delay_anchor() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 9, None, true, true);
a.on_recv(t + Duration::from_millis(10), 7, Some(9), true, true);
assert_eq!(
a.ack_delay_us(t + Duration::from_millis(15)),
15_000,
"§12.3: 7 is not the window's greatest, so it is not the anchor"
);
}
#[test]
fn a_keepalive_bearing_the_largest_yields_zero_and_a_frame_does_not() {
let t = t0();
let later = t + Duration::from_millis(9);
let mut quiet = AckState::new();
quiet.on_recv(t, 4, None, false, false);
assert_eq!(
quiet.ack_delay_us(later),
0,
"§12.3: the largest was a keepalive"
);
let mut seen = AckState::new();
seen.on_recv(t, 4, None, false, true);
assert_eq!(
seen.ack_delay_us(later),
9_000,
"§12.3: a frame-bearing largest reports the real delay"
);
}
#[test]
fn the_frame_seen_flag_follows_the_greatest_rather_than_latching() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 1, None, true, true);
a.on_recv(t + Duration::from_millis(2), 2, Some(1), false, false);
assert_eq!(
a.ack_delay_us(t + Duration::from_millis(6)),
0,
"§12.3: the greatest is now a keepalive's counter"
);
a.on_recv(t + Duration::from_millis(8), 3, Some(2), true, true);
assert_eq!(
a.ack_delay_us(t + Duration::from_millis(11)),
3_000,
"§12.3: the newest frame-bearing greatest is the anchor again"
);
}
#[test]
fn the_delay_is_zero_before_anything_has_been_received() {
assert_eq!(AckState::new().ack_delay_us(t0()), 0);
}
#[test]
fn a_backwards_instant_saturates_rather_than_panicking() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t + Duration::from_secs(10), 0, None, true, true);
assert_eq!(a.ack_delay_us(t), 0);
}
}
mod policy {
use super::*;
#[test]
fn the_first_ack_eliciting_packet_of_a_session_is_acked_immediately() {
let t = t0();
let mut a = AckState::new();
assert_eq!(a.on_recv(t, 0, None, true, true), AckAction::Now);
assert!(a.is_owed());
}
#[test]
fn an_ack_is_owed_after_every_second_ack_eliciting_packet() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 0, None, true, true);
a.on_ack_packed();
assert!(!a.is_owed(), "packing clears the debt");
let first = a.on_recv(t, 1, Some(0), true, true);
assert_eq!(
first,
AckAction::Arm(t + MAX_ACK_DELAY),
"§12.4: the 1st unacknowledged ack-eliciting packet arms"
);
assert!(!a.is_ready(), "§12.4: one is not two — nothing is due yet");
let second = a.on_recv(t, 2, Some(1), true, true);
assert_eq!(
second,
AckAction::Arm(t),
"§12.4 (ruling 271): the 2nd arms at `now` itself, already due"
);
assert!(a.is_ready(), "…and the ACK rides the next packet built");
assert!(
!a.is_owed(),
"ruling 271: …but it is not, by itself, a reason to build one"
);
}
#[test]
fn the_delay_timer_is_armed_at_exactly_twenty_five_milliseconds() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 0, None, true, true);
a.on_ack_packed();
let later = t + Duration::from_millis(400);
assert_eq!(
a.on_recv(later, 1, Some(0), true, true),
AckAction::Arm(later + Duration::from_millis(25)),
"§12.4: MAX_ACK_DELAY is 25 ms, measured from this packet"
);
}
#[test]
fn out_of_order_arrival_forces_an_immediate_ack_and_in_order_does_not() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 5, None, true, true);
a.on_ack_packed();
assert_eq!(
a.on_recv(t, 7, Some(5), true, true),
AckAction::Now,
"§12.4: it opens a gap"
);
let mut a = AckState::new();
a.on_recv(t, 7, None, true, true);
a.on_ack_packed();
assert_eq!(
a.on_recv(t, 6, Some(7), true, true),
AckAction::Now,
"§12.4: it fills a gap"
);
let mut a = AckState::new();
a.on_recv(t, 100, None, true, true);
a.on_ack_packed();
assert_eq!(
a.on_recv(t, 40, Some(100), true, true),
AckAction::Now,
"§12.4: it sits inside a gap"
);
let mut a = AckState::new();
a.on_recv(t, 5, None, true, true);
a.on_ack_packed();
assert_eq!(
a.on_recv(t, 6, Some(5), true, true),
AckAction::Arm(t + MAX_ACK_DELAY),
"§12.4: exactly one greater is in order, so the 1st only arms"
);
}
#[test]
fn a_non_eliciting_out_of_order_packet_owes_nothing() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 5, None, true, true);
a.on_ack_packed();
assert_eq!(
a.on_recv(t, 9, Some(5), false, true),
AckAction::None,
"§12.4: the immediate rule names an ack-eliciting packet"
);
assert!(!a.is_owed());
assert_eq!(
a.on_recv(t, 10, Some(9), true, true),
AckAction::Arm(t + MAX_ACK_DELAY),
"§2.1: a non-eliciting packet does not advance `since_ack`"
);
}
#[test]
fn non_eliciting_packets_never_reach_the_every_second_trigger() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 0, None, true, true);
a.on_ack_packed();
for c in 1..=6u64 {
assert_eq!(
a.on_recv(t, c, Some(c - 1), false, true),
AckAction::None,
"counter {c}: §12.4 counts ack-eliciting packets"
);
assert!(!a.is_owed(), "counter {c}");
}
}
#[test]
fn the_delay_timer_firing_makes_the_ack_owed() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 0, None, true, true);
a.on_ack_packed();
a.on_recv(t, 1, Some(0), true, true);
assert!(!a.is_owed());
a.on_delay_expired();
assert!(a.is_owed(), "§12.4: whichever comes first");
}
#[test]
fn packing_an_ack_resets_the_every_second_counter_not_only_the_debt() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 0, None, true, true);
a.on_ack_packed();
a.on_recv(t, 1, Some(0), true, true); assert_eq!(a.on_recv(t, 2, Some(1), true, true), AckAction::Arm(t)); a.on_ack_packed();
assert!(!a.is_owed());
assert!(
!a.is_ready(),
"ruling 271: packing clears `pending` too, not only `owed`"
);
assert_eq!(
a.on_recv(t, 3, Some(2), true, true),
AckAction::Arm(t + MAX_ACK_DELAY),
"§12.4: after packing, this is the 1st unacknowledged again"
);
}
#[test]
fn an_unpacked_debt_survives_further_arrivals() {
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 0, None, true, true);
a.on_ack_packed();
a.on_recv(t, 1, Some(0), true, true);
a.on_recv(t, 2, Some(1), true, true);
assert!(a.is_ready(), "§12.4: the 2nd leaves an ACK due");
assert!(!a.is_owed(), "ruling 271: due, and it builds no packet");
for c in 3..=5u64 {
a.on_recv(t, c, Some(c - 1), true, true);
assert!(a.is_ready(), "counter {c}: the debt is not paid by arrival");
}
}
#[test]
fn the_coalesce_valve_discharges_the_debt_mid_drain() {
const VALVE: u64 = 32;
let t = t0();
let mut a = AckState::new();
a.on_recv(t, 0, None, true, true);
a.on_ack_packed();
assert_eq!(
a.on_recv(t, 1, Some(0), true, true),
AckAction::Arm(t + MAX_ACK_DELAY),
"the 1st since the pack arms long, valve or no valve"
);
for c in 2..VALVE {
assert_eq!(
a.on_recv(t, c, Some(c - 1), true, true),
AckAction::Arm(t),
"counter {c}: under the valve the burst folds — it does not flush"
);
assert!(!a.is_owed(), "counter {c}: due is not owed");
}
assert_eq!(
a.on_recv(t, VALVE, Some(VALVE - 1), true, true),
AckAction::Now,
"§12.4 (ruling 271): the {VALVE}th discharges mid-drain"
);
assert!(
a.is_owed(),
"…and it builds a packet rather than riding one"
);
a.on_ack_packed();
assert_eq!(
a.on_recv(t, VALVE + 1, Some(VALVE), true, true),
AckAction::Arm(t + MAX_ACK_DELAY),
"the valve resets the every-2nd counter, not only the debt"
);
}
}
mod policy_on_the_wire {
use super::*;
#[test]
fn one_packet_arms_the_timer_and_the_second_makes_it_due_now() {
let t = t0();
let mut s = Solo::installed_at(t);
let d = s.deliver(t, &ping());
assert_eq!(acks(&mut s, &d).len(), 1, "§12.4: the first is immediate");
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
None,
"§12.4: packing the ACK disarms the timer"
);
let t1 = t + Duration::from_millis(100);
let d = s.deliver(t1, &ping());
assert!(
d.transmits().is_empty(),
"§12.4: one ack-eliciting packet is not two"
);
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t1 + MAX_ACK_DELAY),
"§12.4: armed at MAX_ACK_DELAY on the first unacknowledged packet"
);
let d = s.deliver(t1, &ping());
assert!(
d.transmits().is_empty(),
"§12.4 (ruling 271): the 2nd arms, it does not emit"
);
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t1),
"§12.4 (ruling 271): re-armed at `now` itself — already due"
);
let d = drain_boundary(&mut s, t1);
let got = acks(&mut s, &d);
assert_eq!(got.len(), 1, "§12.4: one ACK for the whole batch");
assert_eq!(got[0].largest, 2, "it acknowledges the newest counter");
assert_eq!(got[0].counters(), vec![2, 1, 0], "and everything received");
assert_eq!(s.conn.timer(TimerKind::AckDelay), None);
}
#[test]
fn the_delayed_ack_fires_at_twenty_five_milliseconds_and_not_before() {
let t = t0();
let mut s = Solo::installed_at(t);
let d = s.deliver(t, &ping());
assert_eq!(acks(&mut s, &d).len(), 1);
let t1 = t + Duration::from_millis(100);
let d = s.deliver(t1, &ping());
assert!(d.transmits().is_empty());
s.conn.handle_timeout(t1 + Duration::from_millis(24));
let early = drain(&mut s.conn);
assert!(
early.transmits().is_empty(),
"§12.4: MAX_ACK_DELAY is 25 ms, and 24 is not 25"
);
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t1 + MAX_ACK_DELAY),
"and the timer is still armed"
);
s.conn.handle_timeout(t1 + MAX_ACK_DELAY);
let due = drain(&mut s.conn);
let got = acks(&mut s, &due);
assert_eq!(got.len(), 1, "§12.4: the AckDelay timer fires");
assert_eq!(got[0].largest, 1);
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
None,
"§12.4: and the debt is paid, so the timer is disarmed"
);
}
#[test]
fn a_repeated_timeout_at_the_same_instant_emits_no_second_ack() {
let t = t0();
let mut s = Solo::installed_at(t);
let d = s.deliver(t, &ping());
assert_eq!(acks(&mut s, &d).len(), 1);
let t1 = t + Duration::from_millis(100);
s.deliver(t1, &ping());
let due = t1 + MAX_ACK_DELAY;
s.conn.handle_timeout(due);
let first = drain(&mut s.conn);
assert_eq!(acks(&mut s, &first).len(), 1);
s.conn.handle_timeout(due);
let again = drain(&mut s.conn);
assert!(
again.transmits().is_empty(),
"§16.5: a repeated call at one instant finds an empty due set"
);
}
#[test]
fn a_gap_in_the_counter_space_is_acked_in_the_same_drain() {
let t = t0();
let mut s = Solo::installed_at(t);
let d = s.deliver(t, &ping());
assert_eq!(acks(&mut s, &d).len(), 1, "counter 0, immediate");
let dgram = seal_at(&mut s.peer, 3, &ping());
let d = feed(&mut s, t, &dgram);
let got = acks(&mut s, &d);
assert_eq!(
got.len(),
1,
"§12.4: out-of-order arrival is ACKed immediately, as the 1st"
);
assert_eq!(got[0].largest, 3);
assert_eq!(
got[0].blocks(),
vec![3..=3, 0..=0],
"§12.1: the gap at 1..=2 is reported as a gap"
);
}
#[test]
fn a_replayed_packet_does_not_advance_the_every_second_counter() {
let t = t0();
let mut s = Solo::installed_at(t);
let d = s.deliver(t, &ping());
assert_eq!(acks(&mut s, &d).len(), 1, "counter 0, immediate");
let dgram = s.peer.seal(&ping());
let d = feed(&mut s, t, &dgram);
assert!(d.transmits().is_empty(), "counter 1 is the 1st: armed only");
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t + MAX_ACK_DELAY),
"…and the 1st arms at MAX_ACK_DELAY, not at `now`"
);
let d = feed(&mut s, t, &dgram);
assert!(
d.transmits().is_empty(),
"§7.2: the replay is dropped after decryption, without delivery, \
so it is not the 2nd anything"
);
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t + MAX_ACK_DELAY),
"and the armed deadline is untouched — a build that counted the \
replay would have moved it to `now`"
);
assert!(
drain_boundary(&mut s, t).transmits().is_empty(),
"…so the drain boundary has nothing to flush: the replay bought \
the attacker no ACK at all"
);
let d = s.deliver(t, &ping());
assert!(
d.transmits().is_empty(),
"the 2nd arms rather than emitting"
);
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t),
"§12.4: the 2nd *fresh* ack-eliciting packet makes the ACK due"
);
let d = drain_boundary(&mut s, t);
assert_eq!(
acks(&mut s, &d).len(),
1,
"…and one ACK leaves at the drain boundary"
);
}
#[test]
fn a_pure_ack_packet_is_quiet_unelicited_and_untracked() {
let t = t0();
let mut s = Solo::installed_at(t);
let installed_last_send = s.conn.liveness().expect("installed").last_send();
assert_eq!(installed_last_send, t);
let later = t + Duration::from_millis(5);
let d = s.deliver(later, &ping());
let decoded = packets(&mut s, &d);
assert_eq!(decoded.len(), 1, "one packet out");
let (ack, rest) = &decoded[0];
assert!(ack.is_some(), "§12.4: a standalone ACK packet");
assert!(
rest.is_empty(),
"§12.4: a pure ACK carries nothing else — got {rest:?}"
);
let live = s.conn.liveness().expect("still installed");
assert_eq!(
live.last_send(),
installed_last_send,
"§12.4/§7.4: pure ACKs are sealed `seal_quiet`, so the marking \
clock does not move"
);
assert!(
!live.is_armed(),
"§12.4: a pure ACK is not ack-eliciting, so it does not arm \
§7.4's death deadline"
);
assert_eq!(
s.conn.bytes_in_flight(),
0,
"§12.4: pure ACKs are never tracked for loss"
);
}
#[test]
fn a_hundred_pure_acks_leave_nothing_in_flight() {
let t = t0();
let mut s = Solo::installed_at(t);
for _ in 0..100 {
s.deliver(t, &ping());
}
assert_eq!(
s.conn.bytes_in_flight(),
0,
"§12.4: never tracked for loss, and they bypass the window"
);
}
#[test]
fn an_owed_ack_rides_a_pending_data_packet_rather_than_going_alone() {
let t = t0();
let mut s = Solo::installed_at(t);
let r: StreamRef = s.conn.open(Dir::Uni).expect("the first uni stream fits");
const BYTES: usize = 20_000;
const _: () = assert!(BYTES as u64 > INITIAL_WINDOW);
const _: () = assert!((BYTES as u64) < crate::constants::INITIAL_MAX_STREAM_DATA);
write_all(&mut s.conn, t, r, &ramp(0, BYTES));
let d = drain(&mut s.conn);
let sent: Vec<u64> = d.transmits().iter().map(|x| counter_of(&x.data)).collect();
assert!(!sent.is_empty(), "some data must have gone out");
let flight = s.conn.bytes_in_flight();
assert!(
flight > 0 && flight <= INITIAL_WINDOW,
"§14.5: the initial window bounds the first flight, got {flight}"
);
let largest = *sent.last().expect("non-empty");
let mut pt = ack_frame(largest, 0, largest - sent[0], &[]);
pt.extend_from_slice(&ping());
let d = s.deliver(t, &pt);
let decoded = packets(&mut s, &d);
let carrying: Vec<&Packet> = decoded.iter().filter(|(a, _)| a.is_some()).collect();
assert_eq!(
carrying.len(),
1,
"§12.4: one owed ACK, so exactly one ACK on the wire"
);
assert!(
carrying[0]
.1
.iter()
.any(|f| matches!(f, Wire::Stream { .. })),
"§12.4: the owed ACK rides the next outgoing packet — it did \
not, and went alone: {decoded:?}"
);
}
}
mod processing {
use super::*;
fn write_and_collect(s: &mut Solo, now: Instant, bytes: usize) -> (StreamRef, Vec<u64>) {
let r: StreamRef = s.conn.open(Dir::Uni).expect("the first uni stream fits");
write_all(&mut s.conn, now, r, &ramp(0, bytes));
let d = drain(&mut s.conn);
let counters = d
.transmits()
.iter()
.map(|x| counter_of(&x.data))
.collect::<Vec<_>>();
assert!(!counters.is_empty(), "the write must have sealed something");
(r, counters)
}
#[test]
fn an_ack_above_the_highest_sealed_counter_is_ignored_whole() {
let t = t0();
let mut s = Solo::installed_at(t);
let (_r, _sent) = write_and_collect(&mut s, t, 4096);
let flight_before = s.conn.bytes_in_flight();
assert!(flight_before > 0);
let highest = s.conn.next_counter().expect("installed") - 1;
let forged = 1_000_000;
assert!(forged > highest, "the point of the test");
let mut pt = ack_frame(forged, 0, forged, &[]);
pt.extend_from_slice(&stream_frame(Solo::peer_uni(0), 0, b"hello", true));
let d = s.deliver(t, &pt);
assert_alive(&d);
assert_eq!(
s.conn.bytes_in_flight(),
flight_before,
"§12.5: ignored whole — the frame applies as a no-op"
);
assert_eq!(
d.count_events(|e| matches!(e, ConnEvent::StreamOpened { .. })),
1,
"§12.5: the packet's other frames still apply (§8.2's split)"
);
let claimed = accept_all(&mut s.conn, Dir::Uni);
assert_eq!(claimed.len(), 1);
let (got, eos) = read_available(&mut s.conn, t, claimed[0].1);
assert_eq!(got, b"hello".to_vec());
assert!(eos, "the FIN applied too");
}
#[test]
fn largest_equal_to_the_highest_sealed_counter_is_processed() {
let t = t0();
let mut s = Solo::installed_at(t);
let (_r, sent) = write_and_collect(&mut s, t, 4096);
let highest = s.conn.next_counter().expect("installed") - 1;
assert_eq!(
highest,
*sent.last().expect("non-empty"),
"the last data packet is the highest sealed"
);
assert!(s.conn.bytes_in_flight() > 0);
s.deliver(t, &ack_frame(highest, 0, highest - sent[0], &[]));
assert_eq!(
s.conn.bytes_in_flight(),
0,
"§12.5: `exceeds` excludes equality, so this ACK applies"
);
let mut s = Solo::installed_at(t);
let (_r, sent) = write_and_collect(&mut s, t, 4096);
let highest = s.conn.next_counter().expect("installed") - 1;
let flight = s.conn.bytes_in_flight();
let d = s.deliver(t, &ack_frame(highest + 1, 0, highest + 1 - sent[0], &[]));
assert_alive(&d);
assert_eq!(
s.conn.bytes_in_flight(),
flight,
"§12.5: one above the highest sealed is ignored whole"
);
}
#[test]
fn a_duplicate_acknowledgment_changes_nothing() {
let t = t0();
let mut s = Solo::installed_at(t);
let (_r, sent) = write_and_collect(&mut s, t, 4096);
assert!(s.conn.bytes_in_flight() > 0);
let largest = *sent.last().expect("non-empty");
let pt = ack_frame(largest, 0, largest - sent[0], &[]);
s.deliver(t, &pt);
assert_eq!(s.conn.bytes_in_flight(), 0, "the flight is acknowledged");
for round in 0..3 {
let d = s.deliver(t, &pt);
assert_alive(&d);
assert_eq!(
s.conn.bytes_in_flight(),
0,
"§12.5: duplicate acknowledgment is a no-op (round {round})"
);
}
}
#[test]
fn sixty_four_ranges_apply_and_sixty_five_take_the_whole_packet_down() {
let t = t0();
let pairs = vec![(0u64, 0u64); MAX_ACK_RANGES + 1];
let mut s = Solo::installed_at(t);
let mut pt = ack_frame(1_000_000, 0, 0, &pairs[..MAX_ACK_RANGES]);
pt.extend_from_slice(&stream_frame(Solo::peer_uni(0), 0, b"sixty-four", false));
let d = s.deliver(t, &pt);
assert_alive(&d);
assert_eq!(
d.count_events(|e| matches!(e, ConnEvent::StreamOpened { .. })),
1,
"§12.2: 64 pairs is the cap, not one past it"
);
let mut s = Solo::installed_at(t);
let mut pt = ack_frame(1_000_000, 0, 0, &pairs);
pt.extend_from_slice(&stream_frame(Solo::peer_uni(0), 0, b"sixty-five", false));
let d = s.deliver(t, &pt);
let frames = s.drain_frames(&d);
assert_violation(&d, &frames, PROTOCOL_VIOLATION);
assert_eq!(
d.count_events(|e| matches!(e, ConnEvent::StreamOpened { .. })),
0,
"§8.2: nothing from the packet is applied — no ACK scheduling, \
no state"
);
}
#[test]
fn a_full_sixty_four_pair_ack_acknowledges_only_what_is_in_flight() {
let t = t0();
let mut s = Solo::installed_at(t);
for _ in 0..400 {
s.deliver(t, &ping());
drain_boundary(&mut s, t);
}
let floor = s.conn.next_counter().expect("installed");
assert!(
floor > 2 * MAX_ACK_RANGES as u64 + 2,
"the counter space must be deep enough for 64 descending pairs, \
got {floor}"
);
assert_eq!(s.conn.bytes_in_flight(), 0, "pure ACKs are not tracked");
let (_r, sent) = write_and_collect(&mut s, t, 4096);
let flight = s.conn.bytes_in_flight();
assert!(flight > 0);
let largest = *sent.last().expect("non-empty");
let first_range = largest - sent[0];
let pairs = vec![(0u64, 0u64); MAX_ACK_RANGES];
let pt = ack_frame(largest, 0, first_range, &pairs);
let d = s.deliver(t, &pt);
assert_alive(&d);
assert_eq!(
s.conn.bytes_in_flight(),
0,
"§12.5: the first block retires the flight"
);
}
#[test]
fn an_ack_naming_only_untracked_counters_retires_nothing() {
let t = t0();
let mut s = Solo::installed_at(t);
for _ in 0..10 {
s.deliver(t, &ping());
}
let untracked_top = s.conn.next_counter().expect("installed") - 1;
let (_r, _sent) = write_and_collect(&mut s, t, 4096);
let flight = s.conn.bytes_in_flight();
assert!(flight > 0);
let d = s.deliver(t, &ack_frame(untracked_top, 0, untracked_top, &[]));
assert_alive(&d);
assert_eq!(
s.conn.bytes_in_flight(),
flight,
"§12.5: intersected with the in-flight set, which holds none of \
these counters"
);
}
#[test]
fn a_received_ack_elicits_no_ack_in_reply() {
let t = t0();
let mut s = Solo::installed_at(t);
let (_r, sent) = write_and_collect(&mut s, t, 4096);
let largest = *sent.last().expect("non-empty");
for round in 0..4 {
let d = s.deliver(t, &ack_frame(largest, 0, largest - sent[0], &[]));
assert!(
acks(&mut s, &d).is_empty(),
"§8.3/§12.4: an ACK is not ack-eliciting (round {round})"
);
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
None,
"and it arms nothing (round {round})"
);
}
}
#[test]
fn a_padding_only_packet_elicits_no_ack() {
let t = t0();
let mut s = Solo::installed_at(t);
let d = s.deliver(t, &padding(8));
assert!(
d.transmits().is_empty(),
"§8.3: PADDING is not ack-eliciting, first packet or not"
);
assert_eq!(s.conn.timer(TimerKind::AckDelay), None);
let d = s.deliver(t, &ping());
assert!(d.transmits().is_empty(), "§8.3: nothing is owed yet");
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t + MAX_ACK_DELAY),
"§2.1: a non-eliciting packet does not advance `since_ack`, so \
this is the 1st — armed at MAX_ACK_DELAY, not due at `now`"
);
s.deliver(t, &ping());
let d = drain_boundary(&mut s, t);
let got = acks(&mut s, &d);
assert_eq!(got.len(), 1);
assert_eq!(
got[0].counters(),
vec![2, 1, 0],
"§12.2: the window records every authenticated fresh counter, \
ack-eliciting or not"
);
}
#[test]
fn a_keepalive_elicits_no_ack_but_is_still_acknowledged() {
let t = t0();
let mut s = Solo::installed_at(t);
let d = s.deliver(t, &[]);
assert!(
d.transmits().is_empty(),
"§3.4/§12.4: a keepalive carries no ack-eliciting frame"
);
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
None,
"§12.4: a keepalive arms no timer either"
);
let d = s.deliver(t, &ping());
assert!(d.transmits().is_empty());
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t + MAX_ACK_DELAY),
"§12.4: the keepalive did not advance `since_ack`, so this is \
the 1st"
);
s.deliver(t, &ping());
assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t),
"§12.4 (ruling 271): …and this is the 2nd"
);
let d = drain_boundary(&mut s, t);
let got = acks(&mut s, &d);
assert_eq!(got.len(), 1);
assert_eq!(
got[0].counters(),
vec![2, 1, 0],
"§7.2: the keepalive's counter was authenticated and marked"
);
}
#[test]
fn the_wire_delay_is_zero_when_a_keepalive_holds_the_greatest() {
let t = t0();
let gap = Duration::from_millis(7);
let mut s = Solo::installed_at(t);
s.deliver(t, &ping()); s.deliver(t, &ping()); s.deliver(t + gap, &ping()); assert_eq!(
s.conn.timer(TimerKind::AckDelay),
Some(t + gap),
"§12.4 (ruling 271): the 2nd re-arms at this packet's `now`, \
which is earlier than the 1st's `t + 25 ms`"
);
let d = drain_boundary(&mut s, t + gap);
let got = acks(&mut s, &d);
assert_eq!(got.len(), 1);
assert_eq!(got[0].largest, 2);
assert_eq!(
got[0].ack_delay, 0,
"§12.3: measured from the arrival of the packet bearing \
`largest`, which is this very packet"
);
let mut s = Solo::installed_at(t);
s.deliver(t, &ping()); s.deliver(t, &ping()); s.conn.handle_timeout(t + MAX_ACK_DELAY);
let d = drain(&mut s.conn);
let got = acks(&mut s, &d);
assert_eq!(got.len(), 1);
assert_eq!(
got[0].ack_delay,
u64::try_from(MAX_ACK_DELAY.as_micros()).expect("25 ms fits"),
"§12.3: the full delayed-ACK interval, in raw µs"
);
let mut s = Solo::installed_at(t);
s.deliver(t, &ping()); s.deliver(t, &ping()); s.deliver(t, &[]); s.conn.handle_timeout(t + MAX_ACK_DELAY);
let d = drain(&mut s.conn);
let got = acks(&mut s, &d);
assert_eq!(got.len(), 1);
assert_eq!(got[0].largest, 2, "the keepalive's counter is the largest");
assert_eq!(
got[0].ack_delay, 0,
"§12.3: the window's largest was not frame-seen"
);
}
}
mod two_cores {
use super::*;
#[test]
fn two_cores_acknowledge_each_others_data_and_the_flight_empties() {
let t = t0();
let mut p = Pair::installed_at(t);
let r = p.a.open(Dir::Uni).expect("the first uni stream fits");
write_all(&mut p.a, t, r, &ramp(0, 4096));
let _ = p.drain_a();
assert!(
p.a.bytes_in_flight() > 0,
"§13.5/§14.5: the data is tracked while in flight"
);
let _ = p.pump(t);
let _ = p.pump(t + MAX_ACK_DELAY);
assert_eq!(
p.a.bytes_in_flight(),
0,
"§12.5: B's ACKs retired A's whole flight"
);
assert_eq!(
p.b.bytes_in_flight(),
0,
"and B's own ACKs were never tracked (§12.4)"
);
}
}