From f7e80a4c29381a04f4aa8f8d64f8f0c867ea53d5 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Wed, 9 Feb 2022 17:50:13 -0800 Subject: [PATCH] Limit volume of CIDs retired at peer's request --- quinn-proto/src/cid_queue.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/quinn-proto/src/cid_queue.rs b/quinn-proto/src/cid_queue.rs index a9869d561..d3fac19e4 100644 --- a/quinn-proto/src/cid_queue.rs +++ b/quinn-proto/src/cid_queue.rs @@ -80,8 +80,14 @@ impl CidQueue { self.cursor = (self.cursor + i) % Self::LEN; let orig_offset = self.offset; self.offset = cid.retire_prior_to + i as u64; + // We don't immediately retire CIDs in the range (orig_offset + + // Self::LEN)..self.offset. These are CIDs that we haven't yet received from a + // NEW_CONNECTION_ID frame, since having previously received them would violate the + // connection ID limit we specified based on Self::LEN. If we do receive a such a frame + // in the future, e.g. due to reordering, we'll retire it then. This ensures we can't be + // made to buffer an arbitrarily large number of RETIRE_CONNECTION_ID frames. Ok(Some(( - orig_offset..self.offset, + orig_offset..self.offset.min(orig_offset + Self::LEN as u64), token.expect("non-initial CID missing reset token"), ))) } @@ -240,7 +246,7 @@ mod tests { q.insert(cid(2, 0)).unwrap(); assert_eq!( q.insert(cid(1_000_000, 1_000_000)).unwrap().unwrap().0, - 0..1_000_000, + 0..CidQueue::LEN as u64, ); assert_eq!(q.active_seq(), 1_000_000); }