diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index abf00bfc3..1670262a1 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -188,6 +188,7 @@ struct qcc_app_ops { size_t (*snd_buf)(struct stconn *sc, struct buffer *buf, size_t count, int flags); void (*detach)(struct qcs *qcs); int (*finalize)(void *ctx); + void (*shutdown)(void *ctx); /* Close a connection. */ void (*release)(void *ctx); void (*inc_err_cnt)(void *ctx, int err_code); }; diff --git a/src/h3.c b/src/h3.c index 6c6764851..8d13f5d09 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1203,7 +1203,8 @@ static int h3_init(struct qcc *qcc) return 0; } -static void h3_release(void *ctx) +/* Send a HTTP/3 GOAWAY followed by a CONNECTION_CLOSE_APP. */ +static void h3_shutdown(void *ctx) { struct h3c *h3c = ctx; @@ -1223,7 +1224,11 @@ static void h3_release(void *ctx) * the connection. */ qcc_emit_cc_app(h3c->qcc, H3_NO_ERROR, 0); +} +static void h3_release(void *ctx) +{ + struct h3c *h3c = ctx; pool_free(pool_head_h3c, h3c); } @@ -1266,6 +1271,7 @@ const struct qcc_app_ops h3_ops = { .snd_buf = h3_snd_buf, .detach = h3_detach, .finalize = h3_finalize, - .release = h3_release, + .shutdown = h3_shutdown, .inc_err_cnt = h3_stats_inc_err_cnt, + .release = h3_release, }; diff --git a/src/mux_quic.c b/src/mux_quic.c index bf91750c5..08db5387e 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -1796,11 +1796,11 @@ static void qc_release(struct qcc *qcc) TRACE_ENTER(QMUX_EV_QCC_END, conn); - if (qcc->app_ops && qcc->app_ops->release) { + if (qcc->app_ops && qcc->app_ops->shutdown) { /* Application protocol with dedicated connection closing * procedure. */ - qcc->app_ops->release(qcc->ctx); + qcc->app_ops->shutdown(qcc->ctx); /* useful if application protocol should emit some closing * frames. For example HTTP/3 GOAWAY frame. @@ -1810,7 +1810,6 @@ static void qc_release(struct qcc *qcc) else { qcc_emit_cc_app(qcc, QC_ERR_NO_ERROR, 0); } - TRACE_PROTO("application layer released", QMUX_EV_QCC_END, conn); if (qcc->task) { task_destroy(qcc->task); @@ -1839,6 +1838,10 @@ static void qc_release(struct qcc *qcc) pool_free(pool_head_quic_frame, frm); } + if (qcc->app_ops && qcc->app_ops->release) + qcc->app_ops->release(qcc->ctx); + TRACE_PROTO("application layer released", QMUX_EV_QCC_END, conn); + pool_free(pool_head_qcc, qcc); if (conn) {