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;
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);
#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)
{
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;
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);
}