mirror of
https://github.com/haproxy/haproxy.git
synced 2026-07-16 12:23:15 -04:00
BUG/MINOR: quic: ignore STREAM after MUX closure on BE side
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
FreeBSD / clang (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
FreeBSD / clang (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
For frontend connections, quic_conn layer is able to reject any new streams opened after MUX closure. This is necessary as the peer may not have been notified yet of the closure. This operation is unnecessary on backend side. This is due to the fact that only HTTP protocols are currently supported on top of QUIC, with requests initiated by the client. For requests started before the MUX closure, either they are already completed or closed early with a STOP_SENDING emitted during stream shut. Prior to this patch, spurrious RESET_STREAM could have been emitted on backend connections after MUX closure as quic_conn stream_max_bidi was not correctly set. Now reject is only performed for frontend connections so this should not occured anymore. This should be backported up to 3.3.
This commit is contained in:
parent
bf76275fff
commit
73a4f6bea7
2 changed files with 17 additions and 5 deletions
|
|
@ -3643,8 +3643,10 @@ static void qcc_release(struct qcc *qcc)
|
|||
}
|
||||
|
||||
/* register streams IDs so that quic-conn layer can ignore already closed streams. */
|
||||
qc->rx.stream_max_uni = qcc->largest_uni_r;
|
||||
qc->rx.stream_max_bidi = qcc->largest_bidi_r;
|
||||
if (!conn_is_back(conn)) {
|
||||
qc->rx.stream_max_uni = qcc->largest_uni_r;
|
||||
qc->rx.stream_max_bidi = qcc->largest_bidi_r;
|
||||
}
|
||||
}
|
||||
|
||||
tasklet_free(qcc->wait_event.tasklet);
|
||||
|
|
@ -3667,7 +3669,7 @@ static void qcc_release(struct qcc *qcc)
|
|||
if (qcc->app_ops) {
|
||||
if (qcc->app_ops->release)
|
||||
qcc->app_ops->release(qcc->ctx);
|
||||
if (conn && conn_is_quic(conn) && conn->handle.qc)
|
||||
if (conn && !conn_is_back(conn) && conn_is_quic(conn) && conn->handle.qc)
|
||||
conn->handle.qc->strm_reject = qcc->app_ops->strm_reject;
|
||||
}
|
||||
TRACE_PROTO("application layer released", QMUX_EV_QCC_END, conn);
|
||||
|
|
|
|||
|
|
@ -975,11 +975,21 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
|
|||
{
|
||||
struct qf_stream *strm_frm = &frm->stream;
|
||||
const char fin = frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT;
|
||||
const uint64_t max = quic_stream_is_uni(strm_frm->id) ?
|
||||
qc->rx.stream_max_uni : qc->rx.stream_max_bidi;
|
||||
uint64_t max;
|
||||
|
||||
/* The upper layer may not be allocated. */
|
||||
if (!qc_is_conn_ready(qc)) {
|
||||
if (qc_is_back(qc)) {
|
||||
/* Drain STREAM frames on the backend side. MUX should
|
||||
* have emitted STOP_SENDING on shut for incomplete streams,
|
||||
* so the peer should soon stop emission.
|
||||
*/
|
||||
TRACE_DATA("Ignore stream on backend", QUIC_EV_CONN_PRSHPKT, qc);
|
||||
break;
|
||||
}
|
||||
|
||||
max = quic_stream_is_uni(strm_frm->id) ?
|
||||
qc->rx.stream_max_uni : qc->rx.stream_max_bidi;
|
||||
if (strm_frm->id < max) {
|
||||
TRACE_DATA("Already closed stream", QUIC_EV_CONN_PRSHPKT, qc);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue