Project

General

Profile

Actions

Feature #9228

open
SJ CT

QUIC: support concurrent handshakes within the same UDP flow

Feature #9228: QUIC: support concurrent handshakes within the same UDP flow

Added by Shaoqi Jiang 7 days ago. Updated 3 days ago.

Status:
Triaged
Priority:
Normal
Target version:
Effort:
Difficulty:
Label:
Protocol, Rust

Description

quic: support concurrent handshakes within the same UDP flow

Background

This is a follow-up to Redmine #8776 and Suricata PR #16209, as requested during the code review.

PR #16209 addresses sequential reuse of the same UDP five-tuple by allowing a valid new QUIC Client Initial to replace the previous handshake state after successful decryption and parsing.

However, the current implementation maintains only one active QUIC handshake context per Suricata UDP flow. It does not support multiple independent QUIC handshakes that are active concurrently and whose packets are interleaved within the same flow.

The reviewer suggested tracking this broader functionality in a separate ticket so that PR #16209 can remain focused on sequential connection reuse.

Current Limitation

The current `QuicState` maintains a single set of connection-specific parsing state, including Initial keys, CRYPTO reassembly buffers, ClientHello processing flags, and Retry state.

When a new Client Initial is accepted, PR #16209 resets the existing handshake state.

This approach is appropriate for sequential reuse, but it cannot preserve multiple unfinished handshakes simultaneously.

For example, two independent QUIC connections may share the same UDP five-tuple while using different connection IDs and cryptographic state. If their Initial packets and CRYPTO fragments are interleaved, replacing the active handshake context may discard information needed to complete the earlier handshake.

Consequently, ClientHello reconstruction, SNI extraction, or signature matching for one of the connections may be incomplete or missed.

Proposed Reproduction Scenario

A dedicated concurrent-handshake regression test should be added.

1. Establish two independent QUIC handshakes, A and B, using the same source/destination IP addresses and UDP ports, but distinct connection IDs and cryptographic state.

2. Split the ClientHello CRYPTO data for both handshakes across multiple Initial packets.

3. Interleave the packets, for example:
- A: Initial containing the first ClientHello fragment
- B: Initial containing the first ClientHello fragment
- A: Initial containing the remaining ClientHello fragment
- B: Initial containing the remaining ClientHello fragment

4. Use different SNI values for the two connections and configure corresponding detection rules.

5. Verify that Suricata can reconstruct and inspect both ClientHellos independently.

This scenario is a proposed regression test, not a claim that a separate concurrent-handshake PCAP has already been reproduced and validated.

Expected Behavior

Suricata should be able to track multiple concurrent QUIC handshakes within a single UDP five-tuple, subject to appropriate resource limits.

Each independent QUIC connection should retain its own handshake state and CRYPTO reassembly context.

When a ClientHello is successfully reconstructed, its SNI should be exposed to the detection engine and corresponding signature matching should work.

Processing packets from one connection must not discard or corrupt the unfinished handshake state of another connection.

Proposed Implementation Scope

The follow-up implementation would likely require:

- Maintaining independent QUIC handshake contexts, including Initial keys, CRYPTO reassembly buffers, ClientHello state, and Retry state.
- Associating incoming packets with the correct handshake context using QUIC connection IDs, including appropriate handling of connection ID changes and zero-length IDs.
- Preserving existing handshake contexts when additional valid Client Initial packets are observed.
- Reviewing transaction handling so that multiple ClientHellos can be exposed to the detection engine independently.
- Reviewing flow-level encryption handling, inspection stopping conditions, and bypass behavior to avoid suppressing other active handshakes.
- Defining bounded resource usage, context expiration, and cleanup behavior.
- Adding Suricata-Verify tests for interleaved handshakes, including multiple concurrent connections, fragmented CRYPTO data, retransmissions, and invalid or unrelated Initial packets.

The final context-management design and resource limits should be determined during implementation and review.

Relationship to Existing Work

This ticket is intentionally separate from the sequential five-tuple reuse fix in PR #16209.

PR #16209 should remain focused on its existing scope. This follow-up tracks the broader refactoring needed for concurrent QUIC handshakes.

References:

- Original Redmine issue: https://redmine.openinfosecfoundation.org/issues/8776
- Current fix: https://github.com/OISF/suricata/pull/16209
- Review discussion: https://github.com/OISF/suricata/pull/16209#discussion_r4208598543
- Existing sequential-reuse test: https://github.com/OISF/suricata-verify/pull/3324

The existing Suricata-Verify test covers sequential reuse and does not establish concurrent-handshake support.


Related issues 1 (1 open — 0 closed)

Related to Suricata - Bug #8776: quic: SNI detection evasion when a new connection reuses an existing UDP five-tupleIn ReviewActions
Actions

Also available in: PDF Atom