Skip to content

Commit adf76aa

Browse files
committed
BUG/MINOR: mux-quic: do not close STREAM with empty FIN if no data sent
A stream may be shut without any HTX EOM reported. This is the case for QCS instances flagged with QC_SF_UNKNOWN_PL_LENGTH. In this case, shut is conducted with an empty FIN emission instead of a RESET_STREAM. This has been implemented since the following patch : 24962dd BUG/MEDIUM: mux-quic: do not emit RESET_STREAM for unknown length However, in case of HTTP/3, an empty FIN should only be done after a full message is emitted, which requires a HEADERS frame. If an empty FIN is emitted without it, client may interpret this as invalid and close the connection. To prevent this, fallback to a RESET_STREAM emission if not data were emitted on the stream. This was reproduced using ngtcp2-client with 10% loss (-r 0.1) on a remote host, with httpterm request "/?s=100k&C=1&b=0&P=400". An error ERR_H3_FRAME_UNEXPECTED is returned by ngtcp2-client when the bug occurs. Note that this change is incomplete. The message validity depends solely on the application protocol in use. As such, a new app_ops callback should be implemented to ensure the stream is closed accordingly. However, this first patch ensures that at least HTTP/3 case is valid while keeping a minimal backport process. This should be backported up to 2.8.
1 parent 1cae481 commit adf76aa

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

src/mux_quic.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3359,8 +3359,12 @@ static void qmux_strm_shut(struct stconn *sc, unsigned int mode, struct se_abort
33593359
if (!qcs_is_close_local(qcs) &&
33603360
!(qcs->flags & (QC_SF_FIN_STREAM|QC_SF_TO_RESET))) {
33613361

3362-
if (qcs->flags & QC_SF_UNKNOWN_PL_LENGTH) {
3363-
/* Close stream with a FIN STREAM frame. */
3362+
/* Close stream with FIN if length unknown and some data are
3363+
* ready to be/already transmitted.
3364+
* TODO select closure method on app proto layer
3365+
*/
3366+
if (qcs->flags & QC_SF_UNKNOWN_PL_LENGTH &&
3367+
qcs->tx.fc.off_soft) {
33643368
if (!(qcc->flags & (QC_CF_ERR_CONN|QC_CF_ERRL))) {
33653369
TRACE_STATE("set FIN STREAM",
33663370
QMUX_EV_STRM_SHUT, qcc->conn, qcs);
@@ -3485,7 +3489,7 @@ static const struct mux_ops qmux_ops = {
34853489
.subscribe = qmux_strm_subscribe,
34863490
.unsubscribe = qmux_strm_unsubscribe,
34873491
.wake = qmux_wake,
3488-
.shut = qmux_strm_shut,
3492+
.shut = qmux_strm_shut,
34893493
.ctl = qmux_ctl,
34903494
.sctl = qmux_sctl,
34913495
.show_sd = qmux_strm_show_sd,

0 commit comments

Comments
 (0)