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.
This commit is contained in:
Amaury Denoyelle 2022-05-20 15:04:38 +02:00
parent dfd1301035
commit 9fab9fd7e5
4 changed files with 28 additions and 5 deletions

View 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;

View 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);

View 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;

View 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);
}