]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-quic: define a QCC application state member
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 18 Feb 2025 10:42:59 +0000 (11:42 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 19 Feb 2025 09:59:53 +0000 (10:59 +0100)
Introduce a new QCC field to track the current application layer state.
For the moment, only INIT and SHUT state are defined. This allows to
replace the older flag QC_CF_APP_SHUT.

This commit does not bring major changes. It is only necessary to permit
future evolutions on QUIC MUX. The only noticeable change is that QMUX
traces can now display this new field.

include/haproxy/mux_quic-t.h
src/mux_quic.c
src/qmux_trace.c

index 5b6df8b1e455ac6dffafedfa8d9602981ae0ec8f..e9e3bf5e72cb53fb09d266343f75820f98ce9c3d 100644 (file)
@@ -32,11 +32,17 @@ enum qcs_type {
        QCS_MAX_TYPES
 };
 
+enum qcc_app_st {
+       QCC_APP_ST_INIT,
+       QCC_APP_ST_SHUT,
+} __attribute__((packed));
+
 struct qcc {
        struct connection *conn;
        uint64_t nb_sc; /* number of attached stream connectors */
        uint64_t nb_hreq; /* number of in-progress http requests */
        uint32_t flags; /* QC_CF_* */
+       enum qcc_app_st app_st; /* application layer state */
        int glitches;   /* total number of glitches on this connection */
 
        /* flow-control fields set by us enforced on our side. */
@@ -221,7 +227,7 @@ struct qcc_app_ops {
 #define QC_CF_ERRL_DONE 0x00000002 /* local error properly handled, connection can be released */
 /* unused 0x00000004 */
 #define QC_CF_CONN_FULL 0x00000008 /* no stream buffers available on connection */
-#define QC_CF_APP_SHUT  0x00000010 /* Application layer shutdown done. */
+/* unused 0x00000010 */
 #define QC_CF_ERR_CONN  0x00000020 /* fatal error reported by transport layer */
 #define QC_CF_WAIT_HS   0x00000040 /* MUX init before QUIC handshake completed (0-RTT) */
 
@@ -238,9 +244,8 @@ static forceinline char *qcc_show_flags(char *buf, size_t len, const char *delim
        _(QC_CF_ERRL,
        _(QC_CF_ERRL_DONE,
        _(QC_CF_CONN_FULL,
-       _(QC_CF_APP_SHUT,
        _(QC_CF_ERR_CONN,
-       _(QC_CF_WAIT_HS))))));
+       _(QC_CF_WAIT_HS)))));
        /* epilogue */
        _(~0U);
        return buf;
index 3bf9577ce1495ca9a022782bc5f508e66530c36a..50f2665333fdcea5d131722d9d77737a863be002 100644 (file)
@@ -309,7 +309,7 @@ static void qcc_refresh_timeout(struct qcc *qcc)
         * processed if shutdown already one or connection is idle.
         */
        if (!conn_is_back(qcc->conn)) {
-               if (qcc->nb_hreq && !(qcc->flags & QC_CF_APP_SHUT)) {
+               if (qcc->nb_hreq && qcc->app_st < QCC_APP_ST_SHUT) {
                        TRACE_DEVEL("one or more requests still in progress", QMUX_EV_QCC_WAKE, qcc->conn);
                        qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout);
                        task_queue(qcc->task);
@@ -317,7 +317,7 @@ static void qcc_refresh_timeout(struct qcc *qcc)
                }
 
                if ((!LIST_ISEMPTY(&qcc->opening_list) || unlikely(!qcc->largest_bidi_r)) &&
-                   !(qcc->flags & QC_CF_APP_SHUT)) {
+                   qcc->app_st < QCC_APP_ST_SHUT) {
                        int timeout = px->timeout.httpreq;
                        struct qcs *qcs = NULL;
                        int base_time;
@@ -333,7 +333,7 @@ static void qcc_refresh_timeout(struct qcc *qcc)
                        qcc->task->expire = tick_add_ifset(base_time, timeout);
                }
                else {
-                       if (qcc->flags & QC_CF_APP_SHUT) {
+                       if (qcc->app_st >= QCC_APP_ST_SHUT) {
                                TRACE_DEVEL("connection in closing", QMUX_EV_QCC_WAKE, qcc->conn);
                                qcc->task->expire = tick_add_ifset(now_ms,
                                                                   qcc->shut_timeout);
@@ -2704,7 +2704,7 @@ static void qcc_purge_streams(struct qcc *qcc)
 
 /* Execute application layer shutdown. If this operation is not defined, a
  * CONNECTION_CLOSE will be prepared as a fallback. This function is protected
- * against multiple invocation with the flag QC_CF_APP_SHUT.
+ * against multiple invocation thanks to <qcc> application state context.
  */
 static void qcc_shutdown(struct qcc *qcc)
 {
@@ -2715,7 +2715,7 @@ static void qcc_shutdown(struct qcc *qcc)
                goto out;
        }
 
-       if (qcc->flags & QC_CF_APP_SHUT)
+       if (qcc->app_st >= QCC_APP_ST_SHUT)
                goto out;
 
        TRACE_STATE("perform graceful shutdown", QMUX_EV_QCC_END, qcc->conn);
@@ -2738,7 +2738,7 @@ static void qcc_shutdown(struct qcc *qcc)
                qcc->conn->handle.qc->err = qcc->err;
 
  out:
-       qcc->flags |= QC_CF_APP_SHUT;
+       qcc->app_st = QCC_APP_ST_SHUT;
        TRACE_LEAVE(QMUX_EV_QCC_END, qcc->conn);
 }
 
@@ -3042,6 +3042,7 @@ static int qmux_init(struct connection *conn, struct proxy *prx,
        conn->ctx = qcc;
        qcc->nb_hreq = qcc->nb_sc = 0;
        qcc->flags = 0;
+       qcc->app_st = QCC_APP_ST_INIT;
        qcc->glitches = 0;
        qcc->err = quic_err_transport(QC_ERR_NO_ERROR);
 
index f75e702ccba1baa8337c31a976a659b6f8a42266..3788e3d91032c32081bdd36783a027d7eacdc413 100644 (file)
@@ -130,6 +130,15 @@ static void qmux_trace_fill_ctx(struct trace_ctx *ctx, const struct trace_source
 /* register qmux traces */
 INITCALL1(STG_REGISTER, trace_register_source, TRACE_SOURCE);
 
+static char *qcc_app_st_to_str(const enum qcc_app_st st)
+{
+       switch (st) {
+       case QCC_APP_ST_INIT: return "INIT";
+       case QCC_APP_ST_SHUT: return "SHUT";
+       default:              return "";
+       }
+}
+
 void qmux_dump_qcc_info(struct buffer *msg, const struct qcc *qcc)
 {
        const struct quic_conn *qc = qcc->conn->handle.qc;
@@ -137,7 +146,9 @@ void qmux_dump_qcc_info(struct buffer *msg, const struct qcc *qcc)
        chunk_appendf(msg, " qcc=%p(F)", qcc);
        if (qcc->conn->handle.qc)
                chunk_appendf(msg, " qc=%p", qcc->conn->handle.qc);
-       chunk_appendf(msg, " .sc=%llu .hreq=%llu .flg=0x%04x", (ullong)qcc->nb_sc, (ullong)qcc->nb_hreq, qcc->flags);
+       chunk_appendf(msg, " .st=%s .sc=%llu .hreq=%llu .flg=0x%04x",
+                     qcc_app_st_to_str(qcc->app_st), (ullong)qcc->nb_sc,
+                     (ullong)qcc->nb_hreq, qcc->flags);
 
        chunk_appendf(msg, " .tx=%llu %llu/%llu bwnd=%llu/%llu",
                      (ullong)qcc->tx.fc.off_soft, (ullong)qcc->tx.fc.off_real, (ullong)qcc->tx.fc.limit,