mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MINOR: mux-quic: do not reuse connection if app already shut
QUIC connection graceful closure is performed in two steps. First, the application layer is closed. In the context of HTTP/3, this is done with a GOAWAY frame emission, which forbids opening of new streams. Then the whole connection is terminated via CONNECTION_CLOSE which is the final emitted frame. This commit ensures that when app layer is shut for a backend connection, this connection is removed from either idle or avail server tree. The objective is to prevent stream layer to try to reuse a connection if no new stream can be attached on it. New BUG_ON checks are inserted in qmux_strm_attach() and h3_attach() to ensure that this assertion is always true.
This commit is contained in:
parent
3217835b1d
commit
00d668549e
3
src/h3.c
3
src/h3.c
@ -3005,6 +3005,9 @@ static int h3_attach(struct qcs *qcs, void *conn_ctx)
|
||||
*/
|
||||
if (h3c->flags & H3_CF_GOAWAY_SENT && qcs->id >= h3c->id_goaway &&
|
||||
quic_stream_is_bidi(qcs->id)) {
|
||||
/* Local stack should not attached stream on a closed connection. */
|
||||
BUG_ON(quic_stream_is_local(qcs->qcc, qcs->id));
|
||||
|
||||
TRACE_STATE("close stream outside of goaway range", H3_EV_H3S_NEW, qcs->qcc->conn, qcs);
|
||||
qcc_abort_stream_read(qcs);
|
||||
qcc_reset_stream(qcs, H3_ERR_REQUEST_REJECTED);
|
||||
|
@ -3195,6 +3195,10 @@ static void qcc_shutdown(struct qcc *qcc)
|
||||
if (!(qcc->conn->handle.qc->flags & QUIC_FL_CONN_IMMEDIATE_CLOSE))
|
||||
qcc->conn->handle.qc->err = qcc->err;
|
||||
|
||||
/* A connection is not reusable if app layer is closed. */
|
||||
if (qcc->flags & QC_CF_IS_BACK)
|
||||
conn_delete_from_tree(qcc->conn);
|
||||
|
||||
out:
|
||||
qcc->app_st = QCC_APP_ST_SHUT;
|
||||
TRACE_LEAVE(QMUX_EV_QCC_END, qcc->conn);
|
||||
@ -3719,6 +3723,9 @@ static int qmux_strm_attach(struct connection *conn, struct sedesc *sd, struct s
|
||||
*/
|
||||
BUG_ON(!qcc_fctl_avail_streams(qcc, 1));
|
||||
|
||||
/* Connnection should not be reused if already on error/closed. */
|
||||
BUG_ON(qcc->flags & QC_CF_ERRL || qcc->app_st >= QCC_APP_ST_SHUT);
|
||||
|
||||
qcs = qcc_init_stream_local(qcc, 1);
|
||||
if (!qcs) {
|
||||
TRACE_DEVEL("leaving on error", QMUX_EV_QCS_NEW, qcc->conn);
|
||||
@ -3771,7 +3778,8 @@ static void qmux_strm_detach(struct sedesc *sd)
|
||||
qcs_destroy(qcs);
|
||||
|
||||
/* Backend connection can be reused unless it is already on error/closed. */
|
||||
if (qcc->flags & QC_CF_IS_BACK && !qcc_is_dead(qcc)) {
|
||||
if ((qcc->flags & QC_CF_IS_BACK) && !qcc_is_dead(qcc) &&
|
||||
qcc->app_st == QCC_APP_ST_INIT) {
|
||||
if (!(conn->flags & CO_FL_PRIVATE)) {
|
||||
if (!qcc->nb_sc) {
|
||||
TRACE_DEVEL("prepare for idle connection reuse", QMUX_EV_STRM_END, conn);
|
||||
|
Loading…
Reference in New Issue
Block a user