long long retry_sent; /* total number of Retry sent */
long long retry_validated; /* total number of validated Retry tokens */
long long retry_error; /* total number of Retry token errors */
- long long half_open_conn; /* total number of half open connections */
+ long long half_open_conn; /* current number of connections waiting for address validation */
long long hdshk_fail; /* total number of handshake failures */
long long stateless_reset_sent; /* total number of handshake failures */
/* Special events of interest */
{
TRACE_ENTER(QUIC_EV_CONN_SSLALERT, qc);
- if (!(qc->flags & QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED)) {
- qc->flags |= QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED;
- TRACE_DEVEL("dec half open counter", QUIC_EV_CONN_SSLALERT, qc);
- HA_ATOMIC_DEC(&qc->prx_counters->half_open_conn);
- }
quic_set_connection_close(qc, quic_err_tls(alert));
qc->flags |= QUIC_FL_CONN_TLS_ALERT;
TRACE_STATE("Alert set", QUIC_EV_CONN_SSLALERT, qc);
QUIC_EV_CONN_INIT, qc);
qc->flags |= QUIC_FL_CONN_PEER_VALIDATED_ADDR;
}
+ else {
+ HA_ATOMIC_INC(&qc->prx_counters->half_open_conn);
+ }
TRACE_LEAVE(QUIC_EV_CONN_INIT, qc);
quic_conn_prx_cntrs_update(qc);
pool_free(pool_head_quic_conn_rxbuf, qc->rx.buf.area);
qc->rx.buf.area = NULL;
+
+ /* Connection released before peer address validated. */
+ if (unlikely(!(qc->flags & QUIC_FL_CONN_PEER_VALIDATED_ADDR))) {
+ BUG_ON(!qc->prx_counters->half_open_conn);
+ HA_ATOMIC_DEC(&qc->prx_counters->half_open_conn);
+ }
+
pool_free(pool_head_quic_conn, qc);
qc = NULL;
struct task *qc_idle_timer_task(struct task *t, void *ctx, unsigned int state)
{
struct quic_conn *qc = ctx;
- struct quic_counters *prx_counters = qc->prx_counters;
- unsigned int qc_flags = qc->flags;
TRACE_ENTER(QUIC_EV_CONN_IDLE_TIMER, qc);
* least clean some parts of it such as the tasklet.
*/
- if (!(qc_flags & QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED)) {
- qc_flags |= QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED;
- TRACE_DEVEL("dec half open counter", QUIC_EV_CONN_IDLE_TIMER, qc);
- HA_ATOMIC_DEC(&prx_counters->half_open_conn);
- }
-
requeue:
TRACE_LEAVE(QUIC_EV_CONN_IDLE_TIMER, qc);
return t;
/* Increment the error counters */
qc_cc_err_count_inc(qc, &frm);
if (!(qc->flags & QUIC_FL_CONN_DRAINING)) {
- if (!(qc->flags & QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED)) {
- qc->flags |= QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED;
- HA_ATOMIC_DEC(&qc->prx_counters->half_open_conn);
- }
TRACE_STATE("Entering draining state", QUIC_EV_CONN_PRSHPKT, qc);
/* RFC 9000 10.2. Immediate Close:
* The closing and draining connection states exist to ensure
* Handshake keys confirms that the peer successfully processed an
* Initial packet.
*/
- if (qel == qc->hel) {
+ if (qel == qc->hel &&
+ !(qc->flags & QUIC_FL_CONN_PEER_VALIDATED_ADDR)) {
TRACE_STATE("validate peer address on handshake packet",
QUIC_EV_CONN_RXPKT, qc, pkt);
qc->flags |= QUIC_FL_CONN_PEER_VALIDATED_ADDR;
+ BUG_ON(!qc->prx_counters->half_open_conn);
+ HA_ATOMIC_DEC(&qc->prx_counters->half_open_conn);
}
/* Update the list of ranges to acknowledge. */
if (*new_tid != -1)
goto out;
-
- HA_ATOMIC_INC(&prx_counters->half_open_conn);
}
}
else if (!qc) {
goto out;
}
- /* TODO: Should close the connection asap */
- if (!(qc->flags & QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED)) {
- qc->flags |= QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED;
- HA_ATOMIC_DEC(&qc->prx_counters->half_open_conn);
- HA_ATOMIC_INC(&qc->prx_counters->hdshk_fail);
- }
TRACE_ERROR("SSL handshake error", QUIC_EV_CONN_IO_CB, qc, &state, &ssl_err);
+ HA_ATOMIC_INC(&qc->prx_counters->hdshk_fail);
qc_ssl_dump_errors(ctx->conn);
ERR_clear_error();
goto leave;
goto leave;
}
- if (!(qc->flags & QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED)) {
- TRACE_DEVEL("dec half open counter", QUIC_EV_CONN_IO_CB, qc, &state);
- qc->flags |= QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED;
- HA_ATOMIC_DEC(&qc->prx_counters->half_open_conn);
- }
/* I/O callback switch */
qc->wait_event.tasklet->process = quic_conn_app_io_cb;
if (qc_is_listener(ctx->qc)) {