Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions quiche/src/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,15 @@ pub fn pkt_num_len(pn: u64, largest_acked: u64) -> usize {
let num_unacked: u64 = pn.saturating_sub(largest_acked) + 1;
// computes ceil of num_unacked.log2() + 1
let min_bits = u64::BITS - num_unacked.leading_zeros() + 1;
// get the num len in bytes
min_bits.div_ceil(8) as usize
// get the num len in bytes; floor at 2 to avoid the 1-byte
// truncation ambiguity that breaks AEAD decryption when the
// receiver sees more than 128 packets reordered (the entire
// valid range of a 1-byte truncation collapses, so the decoder
// cannot recover the full packet number unambiguously). The
// reference Go implementation, quic-go, refuses 1-byte truncation
// for the same reason — see PacketNumberLengthForHeader in
// quic-go/internal/protocol/packet_number.go.
(min_bits.div_ceil(8) as usize).max(2)
}

pub fn decrypt_hdr(
Expand Down Expand Up @@ -1356,8 +1363,11 @@ mod tests {

#[test]
fn pkt_num_encode_decode() {
// pkt_num_len floors at 2: the function never emits a 1-byte
// truncated packet number, so the smallest unacked-distance
// encoding still uses 2 bytes.
let num_len = pkt_num_len(0, 0);
assert_eq!(num_len, 1);
assert_eq!(num_len, 2);
let pn = decode_pkt_num(0xa82f30ea, 0x9b32, 2);
assert_eq!(pn, 0xa82f9b32);
let mut d = [0; 10];
Expand All @@ -1380,19 +1390,14 @@ mod tests {
let hdr_num = u64::from(b.get_u24().unwrap());
let pn = decode_pkt_num(0xace9fa, hdr_num, num_len);
assert_eq!(pn, 0xace9fe);
// roundtrip
// roundtrip — every result is at least 2 bytes
let base = 0xdeadbeef;
for i in 1..255 {
let pn = base + i;
let num_len = pkt_num_len(pn, base);
if num_len == 1 {
let decoded = decode_pkt_num(base, pn & 0xff, num_len);
assert_eq!(decoded, pn);
} else {
assert_eq!(num_len, 2);
let decoded = decode_pkt_num(base, pn & 0xffff, num_len);
assert_eq!(decoded, pn);
}
assert_eq!(num_len, 2);
let decoded = decode_pkt_num(base, pn & 0xffff, num_len);
assert_eq!(decoded, pn);
}
}

Expand Down
Loading