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 to report a proper closure. This is the case for QCS instances flagged with QC_SF_UNKNOWN_PL_LENGTH. Shut is performed with an empty FIN emission instead of a RESET_STREAM. This has been implemented since the following patch : 24962dd1784dd22babc8da09a5fc8769617f89e3 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 at least 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 no 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. (cherry picked from commit 68c8c910238f0b759d75b4da2128370abf184cd1) Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
This commit is contained in:
parent
7e69007d4a
commit
260fa5648e
@ -3192,8 +3192,12 @@ static void qmux_strm_shut(struct stconn *sc, unsigned int mode, struct se_abort
|
||||
if (!qcs_is_close_local(qcs) &&
|
||||
!(qcs->flags & (QC_SF_FIN_STREAM|QC_SF_TO_RESET))) {
|
||||
|
||||
if (qcs->flags & QC_SF_UNKNOWN_PL_LENGTH) {
|
||||
/* Close stream with a FIN STREAM frame. */
|
||||
/* Close stream with FIN if length unknown and some data are
|
||||
* ready to be/already transmitted.
|
||||
* TODO select closure method on app proto layer
|
||||
*/
|
||||
if (qcs->flags & QC_SF_UNKNOWN_PL_LENGTH &&
|
||||
qcs->tx.fc.off_soft) {
|
||||
if (!(qcc->flags & (QC_CF_ERR_CONN|QC_CF_ERRL))) {
|
||||
TRACE_STATE("set FIN STREAM",
|
||||
QMUX_EV_STRM_SHUT, qcc->conn, qcs);
|
||||
@ -3296,7 +3300,7 @@ static const struct mux_ops qmux_ops = {
|
||||
.subscribe = qmux_strm_subscribe,
|
||||
.unsubscribe = qmux_strm_unsubscribe,
|
||||
.wake = qmux_wake,
|
||||
.shut = qmux_strm_shut,
|
||||
.shut = qmux_strm_shut,
|
||||
.ctl = qmux_ctl,
|
||||
.sctl = qmux_sctl,
|
||||
.show_sd = qmux_strm_show_sd,
|
||||
|
Loading…
x
Reference in New Issue
Block a user