]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux-quic: report CO_FL_ERROR on send
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 6 Apr 2022 14:13:09 +0000 (16:13 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 7 Apr 2022 08:35:34 +0000 (10:35 +0200)
Mark the connection with CO_FL_ERROR on qc_send() if the socket Tx is
closed. This flag is used by the upper layer to order a close on the
MUX. This requires to check CO_FL_ERROR in qcc_is_dead() to process to
immediate MUX free when set.

The qc_wake() callback has been completed. Most notably, it now calls
qc_send() to report a possible CO_FL_ERROR. This is useful because
qc_wake() is called by the quic-conn on imminent closing.

Note that for the moment the error flag can never be set because the
quic-conn does not report when the Tx socket is closed. This will be
implemented in a following patch.

src/mux_quic.c

index 34c0236cd5733c6744bebc958622d15a0479d235..243fb09b2d744ba2f886a16a877560fbb8b687dd 100644 (file)
@@ -466,7 +466,7 @@ static inline int qcc_is_dead(const struct qcc *qcc)
            qcc->app_ops->is_active(qcc, qcc->ctx))
                return 0;
 
-       if (!qcc->task)
+       if ((qcc->conn->flags & CO_FL_ERROR) || !qcc->task)
                return 1;
 
        return 0;
@@ -791,6 +791,12 @@ static int qc_send(struct qcc *qcc)
 
        TRACE_ENTER(QMUX_EV_QCC_SEND);
 
+       if (qcc->conn->flags & CO_FL_SOCK_WR_SH) {
+               qcc->conn->flags |= CO_FL_ERROR;
+               TRACE_DEVEL("leaving on error", QMUX_EV_QCC_SEND, qcc->conn);
+               return 0;
+       }
+
        if (qc_is_max_streams_needed(qcc))
                qc_send_max_streams(qcc);
 
@@ -1200,14 +1206,30 @@ static int qc_unsubscribe(struct conn_stream *cs, int event_type, struct wait_ev
 static int qc_wake(struct connection *conn)
 {
        struct qcc *qcc = conn->ctx;
+       struct proxy *prx = conn->qc->li->bind_conf->frontend;
+
+       TRACE_ENTER(QMUX_EV_QCC_WAKE, conn);
 
        /* Check if a soft-stop is in progress.
         * Release idling front connection if this is the case.
+        *
+        * TODO this is revelant for frontend connections only.
         */
-       if (unlikely(conn->qc->li->bind_conf->frontend->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
-               qc_release(qcc);
-       }
+       if (unlikely(prx->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))
+               goto release;
+
+       qc_send(qcc);
+
+       if (qcc_is_dead(qcc))
+               goto release;
+
+       TRACE_LEAVE(QMUX_EV_QCC_WAKE, conn);
+
+       return 0;
 
+ release:
+       qc_release(qcc);
+       TRACE_DEVEL("leaving after releasing the connection", QMUX_EV_QCC_WAKE);
        return 1;
 }