mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 07:07:04 +02:00
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 :
24962dd178
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.
This commit is contained in:
parent
1cae481c4c
commit
adf76aa501
@ -3359,8 +3359,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);
|
||||
@ -3485,7 +3489,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…
Reference in New Issue
Block a user