QUIC TXP: Handle padding correctly for ACK_ONLY archetype

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22615)
This commit is contained in:
Hugo Landau 2023-11-03 15:13:51 +00:00
parent 3bef14c536
commit e1c15a8abe

View File

@ -828,35 +828,51 @@ int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp,
if (need_padding) { if (need_padding) {
size_t total_dgram_size = 0; size_t total_dgram_size = 0;
const size_t min_dpl = QUIC_MIN_INITIAL_DGRAM_LEN; 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; for (enc_level = QUIC_ENC_LEVEL_INITIAL;
enc_level < QUIC_ENC_LEVEL_NUM; enc_level < QUIC_ENC_LEVEL_NUM;
++enc_level) ++enc_level)
if (pkt[enc_level].h_valid && pkt[enc_level].h.bytes_appended > 0) { if (pkt[enc_level].h_valid && pkt[enc_level].h.bytes_appended > 0) {
if (first_el == QUIC_ENC_LEVEL_NUM) if (pad_el == QUIC_ENC_LEVEL_NUM
first_el = enc_level; /*
* 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); txp_pkt_postgen_update_pkt_overhead(&pkt[enc_level], txp);
total_dgram_size += pkt[enc_level].geom.pkt_overhead total_dgram_size += pkt[enc_level].geom.pkt_overhead
+ pkt[enc_level].h.bytes_appended; + pkt[enc_level].h.bytes_appended;
} }
if (first_el != QUIC_ENC_LEVEL_NUM if (pad_el != QUIC_ENC_LEVEL_NUM && total_dgram_size < min_dpl) {
&& total_dgram_size < min_dpl) {
size_t deficit = min_dpl - total_dgram_size; 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; goto out;
if (!txp_pkt_append_padding(&pkt[first_el], txp, deficit)) total_dgram_size += deficit;
goto out;
/* /*
* Padding frames make a packet ineligible for being a non-inflight * Padding frames make a packet ineligible for being a non-inflight
* packet. * 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, rc = txp_pkt_commit(txp, &pkt[enc_level], archetype,
&txpim_pkt_reffed); &txpim_pkt_reffed);
if (rc) if (rc) {
status->sent_ack_eliciting status->sent_ack_eliciting
= status->sent_ack_eliciting = status->sent_ack_eliciting
|| pkt[enc_level].tpkt->ackm_pkt.is_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) if (txpim_pkt_reffed)
pkt[enc_level].tpkt = NULL; /* don't free */ 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; ++pkts_done;
} }
status->sent_handshake
= (pkt[QUIC_ENC_LEVEL_HANDSHAKE].h_valid
&& pkt[QUIC_ENC_LEVEL_HANDSHAKE].h.bytes_appended > 0);
/* Flush & Cleanup */ /* Flush & Cleanup */
res = 1; res = 1;
out: out: