From: Amaury Denoyelle Date: Wed, 6 Apr 2022 14:13:09 +0000 (+0200) Subject: MEDIUM: mux-quic: report CO_FL_ERROR on send X-Git-Tag: v2.6-dev5~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d97fc804f94ad47f8487259cfee17d547825e579;p=thirdparty%2Fhaproxy.git MEDIUM: mux-quic: report CO_FL_ERROR on send 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. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 34c0236cd5..243fb09b2d 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -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; }