From: Amaury Denoyelle Date: Fri, 20 May 2022 13:04:38 +0000 (+0200) Subject: MINOR: quic/mux-quic: define CONNECTION_CLOSE send API X-Git-Tag: v2.6-dev11~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9fab9fd7e580b897cdac023dd95c30f088b2694d;p=thirdparty%2Fhaproxy.git MINOR: quic/mux-quic: define CONNECTION_CLOSE send API 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. --- diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index 12b66eb237..b2d0aad039 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -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; diff --git a/include/haproxy/xprt_quic.h b/include/haproxy/xprt_quic.h index 9602b3a824..ac6a8e269a 100644 --- a/include/haproxy/xprt_quic.h +++ b/include/haproxy/xprt_quic.h @@ -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); diff --git a/src/mux_quic.c b/src/mux_quic.c index 5205f0a184..0e3e2c2e51 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -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 . 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 and 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; diff --git a/src/xprt_quic.c b/src/xprt_quic.c index f3bdddc565..b2b1f60827 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -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 . All send/receive + * activity for 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 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); }