BUG/MINOR: mux-quic: properly init STREAM frame as not duplicated

STREAM frame retransmission has been recently fixed. A new boolean field
<dup> was created for quic_stream frame type. It is set for duplicated
STREAM frame to ensure extra checks on the underlying buffer are
conducted before sending the frame. All of this has been implemented by
this commit :
  315a4f6ae5
  BUG/MEDIUM: quic: do not crash when handling STREAM on released MUX

However, the above commit is incomplete. In the MUX code, when a new
STREAM frame is created, <dup> is left uninitialized. In most cases this
is harmless as it will only add extra unneeded checks before sending the
frame. So this is mainly a performance issue.

There is however one case where this bug will lead to a crash : when the
response consists only of an empty STREAM frame. In this case, the empty
frame will be silently removed as it is incorrectly assimilated to an
already acked frame range in qc_build_frms(). This can trigger a
BUG_ON() on the MUX code as a qcs instance is still in the send list
after qc_send_frames() invocation.

Note that this is extremely rare to have only an empty STREAM frame. It
was reproduced with HTTP/0.9 where no HTTP status line exists on an
empty body. I do not know if this is possible on HTTP/3 as a status line
should be present each time in a HEADERS frame.

Properly initialize <dup> field to 0 on each STREAM frames generated by
the QUIC MUX to fix this issue.

This crash may be linked to github issue #2049.

This should be backported up to 2.6.
This commit is contained in:
Amaury Denoyelle 2023-03-07 18:07:08 +01:00
parent 737d10fac1
commit ebfafc212a

View File

@ -1473,6 +1473,7 @@ static int qcs_build_stream_frm(struct qcs *qcs, struct buffer *out, char fin,
frm->stream.buf = out;
frm->stream.data = (unsigned char *)b_peek(out, head);
frm->stream.offset.key = 0;
frm->stream.dup = 0;
/* FIN is positioned only when the buffer has been totally emptied. */
if (fin)