MINOR: quic: define a generic QUIC error type
Define a new structure quic_err to abstract a QUIC error type. This allows to easily differentiate a transport and an application error code. This simplifies error transmission from QUIC MUX and H3 layers. This new type is defined in quic_frame module. It is used to replace <err_code> field in <quic_conn>. QUIC_FL_CONN_APP_ALERT flag is removed as it is now useless. Utility functions are defined to be able to quickly instantiate transport, tls and application errors.
This commit is contained in:
parent
41cd879383
commit
57e6db7021
@ -273,5 +273,33 @@ struct quic_frame {
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
|
||||
/* QUIC error codes */
|
||||
struct quic_err {
|
||||
uint64_t code; /* error code */
|
||||
int app; /* set for Application error code */
|
||||
};
|
||||
|
||||
/* Transport level error codes. */
|
||||
#define QC_ERR_NO_ERROR 0x00
|
||||
#define QC_ERR_INTERNAL_ERROR 0x01
|
||||
#define QC_ERR_CONNECTION_REFUSED 0x02
|
||||
#define QC_ERR_FLOW_CONTROL_ERROR 0x03
|
||||
#define QC_ERR_STREAM_LIMIT_ERROR 0x04
|
||||
#define QC_ERR_STREAM_STATE_ERROR 0x05
|
||||
#define QC_ERR_FINAL_SIZE_ERROR 0x06
|
||||
#define QC_ERR_FRAME_ENCODING_ERROR 0x07
|
||||
#define QC_ERR_TRANSPORT_PARAMETER_ERROR 0x08
|
||||
#define QC_ERR_CONNECTION_ID_LIMIT_ERROR 0x09
|
||||
#define QC_ERR_PROTOCOL_VIOLATION 0x0a
|
||||
#define QC_ERR_INVALID_TOKEN 0x0b
|
||||
#define QC_ERR_APPLICATION_ERROR 0x0c
|
||||
#define QC_ERR_CRYPTO_BUFFER_EXCEEDED 0x0d
|
||||
#define QC_ERR_KEY_UPDATE_ERROR 0x0e
|
||||
#define QC_ERR_AEAD_LIMIT_REACHED 0x0f
|
||||
#define QC_ERR_NO_VIABLE_PATH 0x10
|
||||
/* 256 TLS reserved errors 0x100-0x1ff. */
|
||||
#define QC_ERR_CRYPTO_ERROR 0x100
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _TYPES_QUIC_FRAME_H */
|
||||
|
@ -160,5 +160,21 @@ static inline size_t qc_frm_len(struct quic_frame *frm)
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline struct quic_err quic_err_transport(uint64_t code)
|
||||
{
|
||||
return (struct quic_err){ .code = code, .app = 0 };
|
||||
}
|
||||
|
||||
static inline struct quic_err quic_err_tls(uint64_t tls_alert)
|
||||
{
|
||||
const uint64_t code = QC_ERR_CRYPTO_ERROR|tls_alert;
|
||||
return (struct quic_err){ .code = code, .app = 0 };
|
||||
}
|
||||
|
||||
static inline struct quic_err quic_err_app(uint64_t code)
|
||||
{
|
||||
return (struct quic_err){ .code = code, .app = 1 };
|
||||
}
|
||||
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _HAPROXY_QUIC_FRAME_H */
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include <haproxy/mux_quic-t.h>
|
||||
#include <haproxy/quic_cc-t.h>
|
||||
#include <haproxy/quic_frame-t.h>
|
||||
#include <haproxy/quic_loss-t.h>
|
||||
#include <haproxy/quic_stats-t.h>
|
||||
#include <haproxy/quic_tls-t.h>
|
||||
@ -164,29 +165,6 @@ enum quic_pkt_type {
|
||||
|
||||
#define QUIC_PACKET_KEY_PHASE_BIT 0x04 /* (protected) */
|
||||
|
||||
/*
|
||||
* Transport level error codes.
|
||||
*/
|
||||
#define QC_ERR_NO_ERROR 0x00
|
||||
#define QC_ERR_INTERNAL_ERROR 0x01
|
||||
#define QC_ERR_CONNECTION_REFUSED 0x02
|
||||
#define QC_ERR_FLOW_CONTROL_ERROR 0x03
|
||||
#define QC_ERR_STREAM_LIMIT_ERROR 0x04
|
||||
#define QC_ERR_STREAM_STATE_ERROR 0x05
|
||||
#define QC_ERR_FINAL_SIZE_ERROR 0x06
|
||||
#define QC_ERR_FRAME_ENCODING_ERROR 0x07
|
||||
#define QC_ERR_TRANSPORT_PARAMETER_ERROR 0x08
|
||||
#define QC_ERR_CONNECTION_ID_LIMIT_ERROR 0x09
|
||||
#define QC_ERR_PROTOCOL_VIOLATION 0x0a
|
||||
#define QC_ERR_INVALID_TOKEN 0x0b
|
||||
#define QC_ERR_APPLICATION_ERROR 0x0c
|
||||
#define QC_ERR_CRYPTO_BUFFER_EXCEEDED 0x0d
|
||||
#define QC_ERR_KEY_UPDATE_ERROR 0x0e
|
||||
#define QC_ERR_AEAD_LIMIT_REACHED 0x0f
|
||||
#define QC_ERR_NO_VIABLE_PATH 0x10
|
||||
/* 256 TLS reserved errors 0x100-0x1ff. */
|
||||
#define QC_ERR_CRYPTO_ERROR 0x100
|
||||
|
||||
/* The maximum number of QUIC packets stored by the fd I/O handler by QUIC
|
||||
* connection. Must be a power of two.
|
||||
*/
|
||||
@ -619,7 +597,7 @@ enum qc_mux_state {
|
||||
#define QUIC_FL_CONN_RETRANS_NEEDED (1U << 7)
|
||||
#define QUIC_FL_CONN_RETRANS_OLD_DATA (1U << 8)
|
||||
#define QUIC_FL_CONN_TLS_ALERT (1U << 9)
|
||||
#define QUIC_FL_CONN_APP_ALERT (1U << 10) /* A connection error of type CONNECTION_CLOSE_APP must be emitted. */
|
||||
/* gap here */
|
||||
#define QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED (1U << 11) /* The half-open connection counter was decremented */
|
||||
#define QUIC_FL_CONN_NOTIFY_CLOSE (1U << 27) /* MUX notified about quic-conn imminent closure (idle-timeout or CONNECTION_CLOSE emission/reception) */
|
||||
#define QUIC_FL_CONN_EXP_TIMER (1U << 28) /* timer has expired, quic-conn can be freed */
|
||||
@ -637,7 +615,7 @@ struct quic_conn {
|
||||
int tid;
|
||||
int state;
|
||||
enum qc_mux_state mux_state; /* status of the connection/mux layer */
|
||||
uint64_t err_code;
|
||||
struct quic_err err;
|
||||
unsigned char enc_params[QUIC_TP_MAX_ENCLEN]; /* encoded QUIC transport parameters */
|
||||
size_t enc_params_len;
|
||||
|
||||
|
@ -767,7 +767,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, int app);
|
||||
void quic_set_connection_close(struct quic_conn *qc, const struct quic_err 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);
|
||||
|
@ -107,7 +107,7 @@ INITCALL1(STG_REGISTER, trace_register_source, TRACE_SOURCE);
|
||||
*/
|
||||
static void qcc_emit_cc(struct qcc *qcc, int err)
|
||||
{
|
||||
quic_set_connection_close(qcc->conn->handle.qc, err, 0);
|
||||
quic_set_connection_close(qcc->conn->handle.qc, quic_err_transport(err));
|
||||
qcc->flags |= QC_CF_CC_EMIT;
|
||||
tasklet_wakeup(qcc->wait_event.tasklet);
|
||||
}
|
||||
@ -671,7 +671,7 @@ static int qcc_decode_qcs(struct qcc *qcc, struct qcs *qcs)
|
||||
*/
|
||||
void qcc_emit_cc_app(struct qcc *qcc, int err)
|
||||
{
|
||||
quic_set_connection_close(qcc->conn->handle.qc, err, 1);
|
||||
quic_set_connection_close(qcc->conn->handle.qc, quic_err_app(err));
|
||||
qcc->flags |= QC_CF_CC_EMIT;
|
||||
tasklet_wakeup(qcc->wait_event.tasklet);
|
||||
}
|
||||
|
@ -438,8 +438,8 @@ static void quic_trace(enum trace_level level, uint64_t mask, const struct trace
|
||||
quic_enc_level_char(ssl_to_quic_enc_level(level)));
|
||||
}
|
||||
|
||||
if (qc->err_code)
|
||||
chunk_appendf(&trace_buf, " err_code=0x%llx", (ull)qc->err_code);
|
||||
if (qc->err.code)
|
||||
chunk_appendf(&trace_buf, " err_code=0x%llx", (ull)qc->err.code);
|
||||
}
|
||||
|
||||
if (mask & (QUIC_EV_CONN_PRSFRM|QUIC_EV_CONN_BFRM)) {
|
||||
@ -1057,16 +1057,14 @@ static int quic_crypto_data_cpy(struct quic_enc_level *qel,
|
||||
/* 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, int app)
|
||||
void quic_set_connection_close(struct quic_conn *qc, const struct quic_err err)
|
||||
{
|
||||
if (qc->flags & QUIC_FL_CONN_IMMEDIATE_CLOSE)
|
||||
return;
|
||||
|
||||
qc->err_code = err;
|
||||
qc->flags |= QUIC_FL_CONN_IMMEDIATE_CLOSE;
|
||||
|
||||
if (app)
|
||||
qc->flags |= QUIC_FL_CONN_APP_ALERT;
|
||||
qc->err.code = err.code;
|
||||
qc->err.app = err.app;
|
||||
}
|
||||
|
||||
/* Set <alert> TLS alert as QUIC CRYPTO_ERROR error */
|
||||
@ -1076,7 +1074,7 @@ void quic_set_tls_alert(struct quic_conn *qc, int alert)
|
||||
qc->flags |= QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED;
|
||||
HA_ATOMIC_DEC(&qc->prx_counters->half_open_conn);
|
||||
}
|
||||
quic_set_connection_close(qc, QC_ERR_CRYPTO_ERROR | alert, 0);
|
||||
quic_set_connection_close(qc, quic_err_tls(alert));
|
||||
qc->flags |= QUIC_FL_CONN_TLS_ALERT;
|
||||
TRACE_PROTO("Alert set", QUIC_EV_CONN_SSLDATA, qc);
|
||||
}
|
||||
@ -4319,6 +4317,7 @@ static struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
qc->dcid.len = dcid->len;
|
||||
}
|
||||
qc->mux_state = QC_MUX_NULL;
|
||||
qc->err = quic_err_transport(QC_ERR_NO_ERROR);
|
||||
|
||||
icid = new_quic_cid(&qc->cids, qc, 0);
|
||||
if (!icid) {
|
||||
@ -6141,10 +6140,10 @@ static int qc_do_build_pkt(unsigned char *pos, const unsigned char *end,
|
||||
len += QUIC_TLS_TAG_LEN;
|
||||
/* CONNECTION_CLOSE frame */
|
||||
if (cc) {
|
||||
cc_frm.type = qc->flags & QUIC_FL_CONN_APP_ALERT ?
|
||||
cc_frm.type = qc->err.app ?
|
||||
QUIC_FT_CONNECTION_CLOSE_APP : QUIC_FT_CONNECTION_CLOSE;
|
||||
|
||||
cc_frm.connection_close.error_code = qc->err_code;
|
||||
cc_frm.connection_close.error_code = qc->err.code;
|
||||
len += qc_frm_len(&cc_frm);
|
||||
}
|
||||
add_ping_frm = 0;
|
||||
@ -6441,8 +6440,7 @@ static int qc_xprt_start(struct connection *conn, void *ctx)
|
||||
if (qcc_install_app_ops(qc->qcc, qc->app_ops)) {
|
||||
TRACE_PROTO("Cannot install app layer", QUIC_EV_CONN_LPKT, qc);
|
||||
/* prepare a CONNECTION_CLOSE frame */
|
||||
qc->err_code = QC_ERR_APPLICATION_ERROR;
|
||||
qc->flags |= QUIC_FL_CONN_IMMEDIATE_CLOSE;
|
||||
quic_set_connection_close(qc, quic_err_transport(QC_ERR_APPLICATION_ERROR));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user