From 68ed191f6b6541631dd8e298017e83b9b16d5413 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Fri, 3 Nov 2023 15:13:51 +0000 Subject: QUIC TXP: Handle padding correctly for ACK_ONLY archetype Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22615) (cherry picked from commit e1c15a8abeb87a387cc7c64a424ca5f282b00632) --- ssl/quic/quic_txp.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c index f607d6964b..e13501f1e9 100644 --- a/ssl/quic/quic_txp.c +++ b/ssl/quic/quic_txp.c @@ -828,35 +828,51 @@ int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp, if (need_padding) { size_t total_dgram_size = 0; const size_t min_dpl = QUIC_MIN_INITIAL_DGRAM_LEN; - uint32_t first_el = QUIC_ENC_LEVEL_NUM; + uint32_t pad_el = QUIC_ENC_LEVEL_NUM; for (enc_level = QUIC_ENC_LEVEL_INITIAL; enc_level < QUIC_ENC_LEVEL_NUM; ++enc_level) if (pkt[enc_level].h_valid && pkt[enc_level].h.bytes_appended > 0) { - if (first_el == QUIC_ENC_LEVEL_NUM) - first_el = enc_level; + if (pad_el == QUIC_ENC_LEVEL_NUM + /* + * We might not be able to add padding, for example if we + * are using the ACK_ONLY archetype. + */ + && pkt[enc_level].geom.adata.allow_padding + && !pkt[enc_level].h.done_implicit) + pad_el = enc_level; txp_pkt_postgen_update_pkt_overhead(&pkt[enc_level], txp); total_dgram_size += pkt[enc_level].geom.pkt_overhead + pkt[enc_level].h.bytes_appended; } - if (first_el != QUIC_ENC_LEVEL_NUM - && total_dgram_size < min_dpl) { + if (pad_el != QUIC_ENC_LEVEL_NUM && total_dgram_size < min_dpl) { size_t deficit = min_dpl - total_dgram_size; - if (!ossl_assert(!pkt[first_el].h.done_implicit)) + if (!txp_pkt_append_padding(&pkt[pad_el], txp, deficit)) goto out; - if (!txp_pkt_append_padding(&pkt[first_el], txp, deficit)) - goto out; + total_dgram_size += deficit; /* * Padding frames make a packet ineligible for being a non-inflight * packet. */ - pkt[first_el].tpkt->ackm_pkt.is_inflight = 1; + pkt[pad_el].tpkt->ackm_pkt.is_inflight = 1; + } + + /* + * If we have failed to make a datagram of adequate size, for example + * because we have a padding requirement but are using the ACK_ONLY + * archetype (because we are CC limited), which precludes us from + * sending padding, give up on generating the datagram - there is + * nothing we can do. + */ + if (total_dgram_size < min_dpl) { + res = 1; + goto out; } } @@ -875,11 +891,17 @@ int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp, rc = txp_pkt_commit(txp, &pkt[enc_level], archetype, &txpim_pkt_reffed); - if (rc) + if (rc) { status->sent_ack_eliciting = status->sent_ack_eliciting || pkt[enc_level].tpkt->ackm_pkt.is_ack_eliciting; + if (enc_level == QUIC_ENC_LEVEL_HANDSHAKE) + status->sent_handshake + = (pkt[enc_level].h_valid + && pkt[enc_level].h.bytes_appended > 0); + } + if (txpim_pkt_reffed) pkt[enc_level].tpkt = NULL; /* don't free */ @@ -889,10 +911,6 @@ int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp, ++pkts_done; } - status->sent_handshake - = (pkt[QUIC_ENC_LEVEL_HANDSHAKE].h_valid - && pkt[QUIC_ENC_LEVEL_HANDSHAKE].h.bytes_appended > 0); - /* Flush & Cleanup */ res = 1; out: -- cgit v1.2.3