MINOR: quic: Prepare Handshake packets asap after completed handshake
Switch back to QUIC_HS_ST_SERVER_HANDSHAKE state after a completed handshake
if acks must be send.
Also ensure we build post handshake frames only one time without using prev_st
variable and ensure we discard the Handshake packet number space only one time.
diff --git a/include/haproxy/xprt_quic-t.h b/include/haproxy/xprt_quic-t.h
index 550a017..8005b9b 100644
--- a/include/haproxy/xprt_quic-t.h
+++ b/include/haproxy/xprt_quic-t.h
@@ -616,6 +616,7 @@
/* Flags at connection level */
#define QUIC_FL_CONN_ANTI_AMPLIFICATION_REACHED (1U << 0)
+#define QUIC_FL_POST_HANDSHAKE_FRAMES_BUILT (1U << 1)
#define QUIC_FL_CONN_IMMEDIATE_CLOSE (1U << 31)
struct quic_conn {
/* The quic_conn instance is refcounted as it can be used by threads
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index 6e6be11..0ceb98a 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -2721,6 +2721,7 @@
quic_connection_id_to_frm_cpy(frm, cid);
MT_LIST_APPEND(&qel->pktns->tx.frms, &frm->mt_list);
}
+ HA_ATOMIC_OR(&qc->flags, QUIC_FL_POST_HANDSHAKE_FRAMES_BUILT);
return 1;
@@ -3090,7 +3091,7 @@
struct quic_enc_level *qel, *next_qel;
struct quic_tls_ctx *tls_ctx;
struct qring *qr; // Tx ring
- int prev_st, st, force_ack, zero_rtt;
+ int st, force_ack, zero_rtt;
ctx = context;
qc = ctx->qc;
@@ -3125,7 +3126,6 @@
(tls_ctx->rx.flags & QUIC_FL_TLS_SECRETS_SET))
qc_rm_hp_pkts(qc, qel);
- prev_st = HA_ATOMIC_LOAD(&qc->state);
force_ack = qel == &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL] ||
qel == &qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE];
if (!qc_treat_rx_pkts(qel, next_qel, ctx, force_ack))
@@ -3139,19 +3139,26 @@
}
st = HA_ATOMIC_LOAD(&qc->state);
- if (st >= QUIC_HS_ST_COMPLETE &&
- (prev_st == QUIC_HS_ST_SERVER_INITIAL || prev_st == QUIC_HS_ST_SERVER_HANDSHAKE)) {
- /* Discard the Handshake keys. */
- quic_tls_discard_keys(&qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE]);
- TRACE_PROTO("discarding Handshake pktns", QUIC_EV_CONN_PHPKTS, qc);
- quic_pktns_discard(qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].pktns, qc);
- qc_set_timer(qc);
- if (!quic_build_post_handshake_frames(qc))
+ if (st >= QUIC_HS_ST_COMPLETE) {
+ if (!(HA_ATOMIC_LOAD(&qc->flags) & QUIC_FL_POST_HANDSHAKE_FRAMES_BUILT) &&
+ !quic_build_post_handshake_frames(qc))
goto err;
+ if (!(qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].tls_ctx.rx.flags &
+ QUIC_FL_TLS_SECRETS_DCD)) {
+ /* Discard the Handshake keys. */
+ quic_tls_discard_keys(&qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE]);
+ TRACE_PROTO("discarding Handshake pktns", QUIC_EV_CONN_PHPKTS, qc);
+ quic_pktns_discard(qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].pktns, qc);
+ qc_set_timer(qc);
+ qc_el_rx_pkts_del(&qc->els[QUIC_TLS_ENC_LEVEL_INITIAL]);
+ qc_el_rx_pkts_del(&qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE]);
+ }
+
- qc_el_rx_pkts_del(&qc->els[QUIC_TLS_ENC_LEVEL_INITIAL]);
- qc_el_rx_pkts_del(&qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE]);
- goto start;
+ if (qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].pktns->flags & QUIC_FL_PKTNS_ACK_REQUIRED) {
+ /* There may be remaining handshake to build (acks) */
+ st = QUIC_HS_ST_SERVER_HANDSHAKE;
+ }
}
if (!qr)