From 05bf4a8dece772495c815866d395ea2ac103d9cd Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 21 Feb 2025 10:38:06 +0100 Subject: [PATCH] quic: discard late retry packets Ticket: 7556 See RFC 9000 section 17.2.5.2 : After the client has received and processed an Initial or Retry packet from the server, it MUST discard any subsequent Retry packets that it receives. (cherry picked from commit 726de5520f77e778cd2511bf262611079ae2528d) --- rust/src/quic/quic.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/rust/src/quic/quic.rs b/rust/src/quic/quic.rs index e937196f78..2d0e9da95d 100644 --- a/rust/src/quic/quic.rs +++ b/rust/src/quic/quic.rs @@ -115,6 +115,7 @@ pub struct QuicState { crypto_fraglen_ts: u32, hello_tc: bool, hello_ts: bool, + has_retried: bool, transactions: VecDeque, } @@ -130,6 +131,7 @@ impl Default for QuicState { crypto_fraglen_ts: 0, hello_tc: false, hello_ts: false, + has_retried: false, transactions: VecDeque::new(), } } @@ -334,10 +336,17 @@ impl QuicState { // unprotect/decrypt packet if self.keys.is_none() && header.ty == QuicType::Initial { self.keys = quic_keys_initial(u32::from(header.version), &header.dcid); - } else if !to_server && self.keys.is_some() && header.ty == QuicType::Retry { + } else if !to_server + && self.keys.is_some() + && header.ty == QuicType::Retry + && !self.has_retried + { // a retry packet discards the current keys, client will resend an initial packet with new keys self.hello_ts = false; self.keys = None; + // RFC 9000 17.2.5.2 After the client has received and processed an Initial or Retry packet + // from the server, it MUST discard any subsequent Retry packets that it receives. + self.has_retried = true; } // header.length was checked against rest.len() during parsing let (mut framebuf, next_buf) = rest.split_at(header.length.into()); -- 2.47.2