BUG/MINOR: quic: repeat packet parsing to deal with fragmented CRYPTO
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 4 Nov 2024 16:28:02 +0000 (17:28 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 8 Nov 2024 14:54:11 +0000 (15:54 +0100)
commitf3bddfa8eb033243b0d65c74bffd9b0f0e3256c6
tree6d7e0a15b325432b82b533dab6b93370594e0c39
parent19c4b37c9fa38d4ec8675b5533efa65b0ec4247c
BUG/MINOR: quic: repeat packet parsing to deal with fragmented CRYPTO

A ClientHello may be splitted accross several different CRYPTO frames,
then mixed in a single QUIC packet. This is used notably by clients such
as chrome to render the first Initial packet opaque to middleboxes.

Each packet frame is handled sequentially. Out-of-order CRYPTO frames
are buffered in a ncbuf, until gaps are filled and data is transferred
to the SSL stack. If CRYPTO frames are heavily splitted with small
fragments, buffering may fail as ncbuf does not support small gaps. This
causes the whole packet to be rejected and unacknowledged. It could be
solved if the client reemits its ClientHello after remixing its CRYPTO
frames.

This patch is written to improve CRYPTO frame parsing. Each CRYPTO
frames which cannot be buffered due to ncbuf limitation are now stored
in a temporary list. Packet parsing is completed until all frames have
been handled. If temporary list is not empty, reparsing is done on the
stored frames. With the newly buffered CRYPTO frames, ncbuf insert
operation may this time succeeds if the frame now covers a whole gap.
Reparsing will loop until either no progress can be made or it has been
done at least 3 times, to prevent CPU utilization.

This patch should fix github issue #2776.

This should be backported up to 2.6, after a period of observation. Note
that it relies on the following refactor patches :
  MINOR: quic: extend return value of CRYPTO parsing
  MINOR: quic: use dynamically allocated frame on parsing
  MINOR: quic: simplify qc_parse_pkt_frms() return path

(cherry picked from commit 1767196d5b2d8d1e557f7b3911a940000166ecda)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
include/haproxy/quic_rx-t.h
src/quic_rx.c