goto out;
}
- if (qc->flags & QUIC_FL_CONN_TO_KILL) {
- TRACE_DEVEL("connection to be killed", QUIC_EV_CONN_PHPKTS, qc);
- goto out;
- }
-
if ((qc->flags & QUIC_FL_CONN_DRAINING) &&
!(qc->flags & QUIC_FL_CONN_IMMEDIATE_CLOSE))
goto out;
qc_release_pktns_frms(qc, qc->hel->pktns);
}
- /* Release 0RTT packets still waiting for HP removal. These
+ /* Note: if no token for address validation was received
+ * for a 0RTT connection, some 0RTT packet could still be
+ * waiting for HP removal AFTER the successful handshake completion.
+ * Indeed a successful handshake completion implicitely valids
+ * the peer address. In this case, one wants to process
+ * these ORTT packets AFTER the succesful handshake completion.
+ *
+ * On the contrary, when a token for address validation was received,
+ * release 0RTT packets still waiting for HP removal. These
* packets are considered unneeded after handshake completion.
* They will be freed later from Rx buf via quic_rx_pkts_del().
*/
- if (qc->eel && !LIST_ISEMPTY(&qc->eel->rx.pqpkts)) {
+ if (qc->eel && !LIST_ISEMPTY(&qc->eel->rx.pqpkts) &&
+ !(qc->flags & QUIC_FL_CONN_NO_TOKEN_RCVD)) {
struct quic_rx_packet *pqpkt, *pkttmp;
list_for_each_entry_safe(pqpkt, pkttmp, &qc->eel->rx.pqpkts, list) {
LIST_DEL_INIT(&pqpkt->list);
quic_nictx_free(qc);
}
- if (qc->flags & QUIC_FL_CONN_SEND_RETRY) {
- struct quic_counters *prx_counters;
- struct proxy *prx = qc->li->bind_conf->frontend;
- struct quic_rx_packet pkt = {
- .scid = qc->dcid,
- .dcid = qc->odcid,
- };
-
- prx_counters = EXTRA_COUNTERS_GET(prx->extra_counters_fe, &quic_stats_module);
- if (send_retry(qc->li->rx.fd, &qc->peer_addr, &pkt, qc->original_version)) {
- TRACE_ERROR("Error during Retry generation",
- QUIC_EV_CONN_LPKT, NULL, NULL, NULL, qc->original_version);
- }
- else
- HA_ATOMIC_INC(&prx_counters->retry_sent);
- }
-
- if ((qc->flags & (QUIC_FL_CONN_CLOSING|QUIC_FL_CONN_TO_KILL)) &&
- qc->mux_state != QC_MUX_READY) {
+ if ((qc->flags & QUIC_FL_CONN_CLOSING) && qc->mux_state != QC_MUX_READY) {
quic_conn_release(qc);
qc = NULL;
}
}
/* Enqueue this connection asap if we could derive O-RTT secrets as
- * listener. Note that a listener derives only RX secrets for this
- * level.
+ * listener and if a token was received. Note that a listener derives only RX
+ * secrets for this level.
*/
if (qc_is_listener(qc) && level == ssl_encryption_early_data) {
- TRACE_DEVEL("pushing connection into accept queue", QUIC_EV_CONN_RWSEC, qc);
- quic_accept_push_qc(qc);
+ if (qc->flags & QUIC_FL_CONN_NO_TOKEN_RCVD) {
+ /* Leave a chance to the address validation to be completed by the
+ * handshake without starting the mux: one does not want to process
+ * the 0RTT data in this case.
+ */
+ TRACE_PROTO("0RTT session without token", QUIC_EV_CONN_RWSEC, qc);
+ }
+ else {
+ TRACE_DEVEL("pushing connection into accept queue", QUIC_EV_CONN_RWSEC, qc);
+ quic_accept_push_qc(qc);
+ }
}
write:
TRACE_PROTO("ha_quic_add_handshake_data() called", QUIC_EV_CONN_IO_CB, qc, NULL, NULL, ssl);
-#ifdef HAVE_SSL_0RTT_QUIC
- /* Detect asap if some 0-RTT data were accepted for this connection.
- * If this is the case and no token was provided, interrupt the useless
- * secrets derivations. A Retry packet must be sent, and this connection
- * must be killed.
- * Note that QUIC_FL_CONN_NO_TOKEN_RCVD is possibly set only for when 0-RTT is
- * enabled for the connection.
- */
- if ((qc->flags & QUIC_FL_CONN_NO_TOKEN_RCVD) && qc_ssl_eary_data_accepted(ssl)) {
- TRACE_PROTO("connection to be killed", QUIC_EV_CONN_ADDDATA, qc);
- qc->flags |= QUIC_FL_CONN_TO_KILL|QUIC_FL_CONN_SEND_RETRY;
- goto leave;
- }
-#endif
-
if (qc->flags & QUIC_FL_CONN_TO_KILL) {
TRACE_PROTO("connection to be killed", QUIC_EV_CONN_ADDDATA, qc);
goto out;