]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic/mux-quic: define CONNECTION_CLOSE send API
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 20 May 2022 13:04:38 +0000 (15:04 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 20 May 2022 15:26:56 +0000 (17:26 +0200)
Define an API to easily set a CONNECTION_CLOSE. This will mainly be
useful for the MUX when an error is detected which require to close the
whole connection.

On the MUX side, a new flag is added when a CONNECTION_CLOSE has been
prepared. This will disable add future send operations.

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

index 12b66eb237e6301d866bb958ef0ddc2650dd660d..b2d0aad039e36bc82f577f4488a5f2be7e73e7be 100644 (file)
@@ -26,8 +26,9 @@ enum qcs_type {
        QCS_MAX_TYPES
 };
 
-#define QC_CF_BLK_MFCTL 0x00000001 /* sending blocked due to connection flow-control */
-#define QC_CF_CONN_FULL 0x00000002 /* no stream buffers available on connection */
+#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 */
 
 struct qcc {
        struct connection *conn;
index 9602b3a8241633607dd5378c0e71298b7cec6512..ac6a8e269aa0dce1dff3121750793a5c4dd00f04 100644 (file)
@@ -1255,6 +1255,7 @@ static inline void qc_list_all_rx_pkts(struct quic_conn *qc)
 
 void chunk_frm_appendf(struct buffer *buf, const struct quic_frame *frm);
 
+void quic_set_connection_close(struct quic_conn *qc, int err);
 void quic_set_tls_alert(struct quic_conn *qc, int alert);
 int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alpn_len);
 struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state);
index 5205f0a18460f7880f5ee898584f07819175fc1e..0e3e2c2e5149d6e36227c1b393391460eff7398a 100644 (file)
@@ -102,6 +102,16 @@ struct trace_source trace_qmux = {
 #define TRACE_SOURCE    &trace_qmux
 INITCALL1(STG_REGISTER, trace_register_source, TRACE_SOURCE);
 
+/* Emit a CONNECTION_CLOSE with error <err>. This will interrupt all future
+ * send operations.
+ */
+static void qcc_emit_cc(struct qcc *qcc, int err)
+{
+       quic_set_connection_close(qcc->conn->handle.qc, err);
+       qcc->flags |= QC_CF_CC_EMIT;
+       tasklet_wakeup(qcc->wait_event.tasklet);
+}
+
 /* Allocate a new QUIC streams with id <id> and type <type>. */
 struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type)
 {
@@ -1009,7 +1019,7 @@ static int qc_send(struct qcc *qcc)
 
        TRACE_ENTER(QMUX_EV_QCC_SEND);
 
-       if (qcc->conn->flags & CO_FL_SOCK_WR_SH) {
+       if (qcc->conn->flags & CO_FL_SOCK_WR_SH || qcc->flags & QC_CF_CC_EMIT) {
                qcc->conn->flags |= CO_FL_ERROR;
                TRACE_DEVEL("leaving on error", QMUX_EV_QCC_SEND, qcc->conn);
                return 0;
index f3bdddc565129fd2d2156288b3da74116b019ff6..b2b1f60827041d464d52e365152f239142820d81 100644 (file)
@@ -1107,13 +1107,24 @@ static int quic_crypto_data_cpy(struct quic_enc_level *qel,
        return len == 0;
 }
 
+/* Prepare the emission of CONNECTION_CLOSE with error <err>. All send/receive
+ * activity for <qc> will be interrupted.
+ */
+void quic_set_connection_close(struct quic_conn *qc, int err)
+{
+       if (qc->flags & QUIC_FL_CONN_IMMEDIATE_CLOSE)
+               return;
+
+       qc->err_code = err;
+       qc->flags |= QUIC_FL_CONN_IMMEDIATE_CLOSE;
+}
 
 /* Set <alert> TLS alert as QUIC CRYPTO_ERROR error */
 void quic_set_tls_alert(struct quic_conn *qc, int alert)
 {
        HA_ATOMIC_DEC(&qc->prx_counters->conn_opening);
-       qc->err_code = QC_ERR_CRYPTO_ERROR | alert;
-       qc->flags |= QUIC_FL_CONN_IMMEDIATE_CLOSE | QUIC_FL_CONN_TLS_ALERT;
+       quic_set_connection_close(qc, QC_ERR_CRYPTO_ERROR | alert);
+       qc->flags |= QUIC_FL_CONN_TLS_ALERT;
        TRACE_PROTO("Alert set", QUIC_EV_CONN_SSLDATA, qc);
 }