summaryrefslogtreecommitdiffstats
path: root/ssl/quic/quic_txp.c
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2023-07-03 15:45:25 +0100
committerPauli <pauli@openssl.org>2023-07-19 13:03:11 +1000
commit178c104de68ebf981ae1813a3e0548bbb1051a75 (patch)
tree2dde9156a3da5d39e5de3ff1610504dd48af610b /ssl/quic/quic_txp.c
parent427a02ad0a71a50c9be125d860a84d4e07d09f1e (diff)
QUIC TXP: Handle non-inflight-eligible packets correctly
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21349)
Diffstat (limited to 'ssl/quic/quic_txp.c')
-rw-r--r--ssl/quic/quic_txp.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c
index 959186d4a6..f22f2cb5dd 100644
--- a/ssl/quic/quic_txp.c
+++ b/ssl/quic/quic_txp.c
@@ -1274,7 +1274,8 @@ static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp,
QUIC_TXPIM_PKT *tpkt,
uint32_t pn_space,
struct archetype_data *a,
- int chosen_for_conn_close)
+ int chosen_for_conn_close,
+ int *can_be_non_inflight)
{
const OSSL_QUIC_FRAME_ACK *ack;
OSSL_QUIC_FRAME_ACK ack2;
@@ -1350,6 +1351,8 @@ static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp,
if (ossl_quic_wire_encode_frame_conn_close(wpkt, pf)) {
if (!tx_helper_commit(h))
return 0;
+
+ *can_be_non_inflight = 0;
} else {
tx_helper_rollback(h);
}
@@ -2026,6 +2029,15 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level);
struct tx_helper h;
int have_helper = 0, have_ack_eliciting = 0, done_pre_token = 0;
+ /*
+ * Cleared if we encode any non-ACK-eliciting frame type which rules out the
+ * packet being a non-inflight frame. This means any non-ACK ACK-eliciting
+ * frame, even PADDING frames. ACK eliciting frames always cause a packet to
+ * become ineligible for non-inflight treatment so it is not necessary to
+ * clear this in cases where have_ack_eliciting is set, as it is ignored in
+ * that case.
+ */
+ int can_be_non_inflight = 1;
int require_ack_eliciting = 0;
QUIC_CFQ_ITEM *cfq_item;
QUIC_TXPIM_PKT *tpkt = NULL;
@@ -2205,7 +2217,8 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
*/
if (!done_pre_token)
if (txp_generate_pre_token(txp, &h, tpkt, pn_space, &a,
- chosen_for_conn_close))
+ chosen_for_conn_close,
+ &can_be_non_inflight))
done_pre_token = 1;
break;
@@ -2239,7 +2252,8 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
*/
if (!done_pre_token)
if (txp_generate_pre_token(txp, &h, tpkt, pn_space, &a,
- chosen_for_conn_close))
+ chosen_for_conn_close,
+ &can_be_non_inflight))
done_pre_token = 1;
/* CRYPTO Frames */
@@ -2285,18 +2299,23 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
if (!ossl_quic_wire_encode_padding(wpkt, min_ppl - h.bytes_appended)
|| !tx_helper_commit(&h))
goto fatal_err;
+
+ can_be_non_inflight = 0;
}
/*
* Dispatch
* ========
*/
+ if (have_ack_eliciting)
+ can_be_non_inflight = 0;
+
/* ACKM Data */
tpkt->ackm_pkt.num_bytes = h.bytes_appended + pkt_overhead;
tpkt->ackm_pkt.pkt_num = txp->next_pn[pn_space];
/* largest_acked is set in txp_generate_pre_token */
tpkt->ackm_pkt.pkt_space = pn_space;
- tpkt->ackm_pkt.is_inflight = 1;
+ tpkt->ackm_pkt.is_inflight = !can_be_non_inflight;
tpkt->ackm_pkt.is_ack_eliciting = have_ack_eliciting;
tpkt->ackm_pkt.is_pto_probe = 0;
tpkt->ackm_pkt.is_mtu_probe = 0;