From 541d87eb8dbc997388db8e20253cec3aad044e77 Mon Sep 17 00:00:00 2001 From: obchain Date: Thu, 28 May 2026 11:29:53 +0530 Subject: [PATCH] perf(dpi/quic): drop redundant `dcid.clone()` in long-header parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `parse_long_header_packet_with_length` was allocating the DCID bytes twice per packet: let dcid = payload[offset..offset + dcid_len].to_vec(); quic_info.connection_id = dcid.clone(); ... extract_tls_from_long_header_packet(packet_data, &mut quic_info, &dcid, ...); The intermediate `dcid` Vec only existed to feed `extract_tls_*` a `&[u8]`, and `extract_tls_*` already accepts a borrowed slice — there's no reason to materialize a second owned copy when the bytes are sitting right there inside `payload`. Capture the DCID byte-range, assign `quic_info.connection_id` directly from `payload[dcid_range]`, and reborrow the same slice for the `extract_tls_*` call. The borrow checker is fine with this since `payload: &[u8]` and the `&mut QuicInfo` reference disjoint memory. The short-header path had the same shape and got fixed in #317. The long-header path was missed; this brings the two paths into parity. No behavior change — the 11 QUIC DPI unit tests plus the full lib sweep (371 passed) keep their existing assertions. Closes #342 --- crates/rustnet-core/src/network/dpi/quic.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/crates/rustnet-core/src/network/dpi/quic.rs b/crates/rustnet-core/src/network/dpi/quic.rs index ba86417e..042b29ee 100644 --- a/crates/rustnet-core/src/network/dpi/quic.rs +++ b/crates/rustnet-core/src/network/dpi/quic.rs @@ -367,8 +367,12 @@ fn parse_long_header_packet_with_length(payload: &[u8]) -> (Option, us ); return (None, 0); } - let dcid = payload[offset..offset + dcid_len].to_vec(); - quic_info.connection_id = dcid.clone(); + // Remember the DCID byte-range so we can reborrow `payload` later instead + // of allocating a separate owned copy. The short-header path got the same + // fix in #317; the long-header path kept doing `to_vec().clone()` which + // allocated the DCID twice per packet. + let dcid_range = offset..offset + dcid_len; + quic_info.connection_id = payload[dcid_range.clone()].to_vec(); quic_info.connection_id_hex = None; offset += dcid_len; @@ -438,8 +442,15 @@ fn parse_long_header_packet_with_length(payload: &[u8]) -> (Option, us payload // Use what we have if packet extends beyond datagram }; - // Extract TLS info from this packet - extract_tls_from_long_header_packet(packet_data, &mut quic_info, &dcid, version, packet_type); + // Extract TLS info from this packet. The DCID lives inside `payload`, so + // pass a borrowed slice instead of cloning the owned `connection_id` Vec. + extract_tls_from_long_header_packet( + packet_data, + &mut quic_info, + &payload[dcid_range], + version, + packet_type, + ); (Some(quic_info), total_packet_size.min(payload.len())) }