]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-quic: define qc_shutdown()
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 24 Jan 2023 17:18:23 +0000 (18:18 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 20 Feb 2023 10:18:58 +0000 (11:18 +0100)
Factorize shutdown operation in a dedicated function qc_shutdown(). This
will allow to call it from multiple places. A new flag QC_CF_APP_SHUT is
also defined to ensure it will only be executed once even if called
multiple times per connection.

This commit will be useful to properly support haproxy soft stop.
This should be backported up to 2.7.

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

index 2141506feb07e8a0e9937741bb1cd1297eafec51..2c66f85f58f7d6b620e76d766a502679b469b7ef 100644 (file)
@@ -30,6 +30,7 @@ enum qcs_type {
 #define QC_CF_CC_EMIT   0x00000001 /* A CONNECTION_CLOSE is set by the MUX */
 #define QC_CF_BLK_MFCTL 0x00000002 /* sending blocked due to connection flow-control */
 #define QC_CF_CONN_FULL 0x00000004 /* no stream buffers available on connection */
+#define QC_CF_APP_SHUT  0x00000008 /* Application layer shutdown done. */
 
 struct qcc {
        struct connection *conn;
index 8577debd3f96a5c8942944f6c6cac001e5239a31..125d2984e53178aac3e2f64bca364eb2ef184725 100644 (file)
@@ -1926,31 +1926,42 @@ static int qc_purge_streams(struct qcc *qcc)
        return release;
 }
 
-/* release function. This one should be called to free all resources allocated
- * to the mux.
+/* 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.
  */
-static void qc_release(struct qcc *qcc)
+static void qc_shutdown(struct qcc *qcc)
 {
-       struct connection *conn = qcc->conn;
-       struct eb64_node *node;
+       TRACE_ENTER(QMUX_EV_QCC_END, qcc->conn);
 
-       TRACE_ENTER(QMUX_EV_QCC_END, conn);
+       if (qcc->flags & QC_CF_APP_SHUT)
+               goto out;
 
        if (qcc->app_ops && qcc->app_ops->shutdown) {
-               /* Application protocol with dedicated connection closing
-                * procedure.
-                */
                qcc->app_ops->shutdown(qcc->ctx);
-
-               /* useful if application protocol should emit some closing
-                * frames. For example HTTP/3 GOAWAY frame.
-                */
                qc_send(qcc);
        }
        else {
                qcc_emit_cc_app(qcc, QC_ERR_NO_ERROR, 0);
        }
 
+ out:
+       qcc->flags |= QC_CF_APP_SHUT;
+       TRACE_LEAVE(QMUX_EV_QCC_END, qcc->conn);
+}
+
+/* release function. This one should be called to free all resources allocated
+ * to the mux.
+ */
+static void qc_release(struct qcc *qcc)
+{
+       struct connection *conn = qcc->conn;
+       struct eb64_node *node;
+
+       TRACE_ENTER(QMUX_EV_QCC_END, conn);
+
+       qc_shutdown(qcc);
+
        if (qcc->task) {
                task_destroy(qcc->task);
                qcc->task = NULL;