diff options
author | Matt Caswell <matt@openssl.org> | 2023-11-13 14:16:57 +0000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2023-11-15 09:08:16 +0100 |
commit | e57bf6b3bfa2f0b18e5cad7fd3c5fdd7c51516b9 (patch) | |
tree | 3fec6376b029555c4a2b3affde7ac70b1d09709f /ssl | |
parent | f5a63bf1c02cf0605ce3f5614cd016c3750766d3 (diff) |
Keep track of connection credit as we add stream data
If a single packet contains data from multiple streams we need to keep track
of the cummulative connection level credit consumed across all of the
streams. Once the connection level credit has been consumed we must stop
adding stream data.
Fixes #22706
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22718)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/quic/quic_fc.c | 14 | ||||
-rw-r--r-- | ssl/quic/quic_stream_map.c | 2 | ||||
-rw-r--r-- | ssl/quic/quic_txp.c | 18 |
3 files changed, 20 insertions, 14 deletions
diff --git a/ssl/quic/quic_fc.c b/ssl/quic/quic_fc.c index 1a9c5890f8..750e896306 100644 --- a/ssl/quic/quic_fc.c +++ b/ssl/quic/quic_fc.c @@ -46,21 +46,21 @@ int ossl_quic_txfc_bump_cwm(QUIC_TXFC *txfc, uint64_t cwm) return 1; } -uint64_t ossl_quic_txfc_get_credit_local(QUIC_TXFC *txfc) +uint64_t ossl_quic_txfc_get_credit_local(QUIC_TXFC *txfc, uint64_t consumed) { - assert(txfc->swm <= txfc->cwm); - return txfc->cwm - txfc->swm; + assert((txfc->swm + consumed) <= txfc->cwm); + return txfc->cwm - (consumed + txfc->swm); } -uint64_t ossl_quic_txfc_get_credit(QUIC_TXFC *txfc) +uint64_t ossl_quic_txfc_get_credit(QUIC_TXFC *txfc, uint64_t consumed) { uint64_t r, conn_r; - r = ossl_quic_txfc_get_credit_local(txfc); + r = ossl_quic_txfc_get_credit_local(txfc, 0); if (txfc->parent != NULL) { assert(txfc->parent->parent == NULL); - conn_r = ossl_quic_txfc_get_credit_local(txfc->parent); + conn_r = ossl_quic_txfc_get_credit_local(txfc->parent, consumed); if (conn_r < r) r = conn_r; } @@ -71,7 +71,7 @@ uint64_t ossl_quic_txfc_get_credit(QUIC_TXFC *txfc) int ossl_quic_txfc_consume_credit_local(QUIC_TXFC *txfc, uint64_t num_bytes) { int ok = 1; - uint64_t credit = ossl_quic_txfc_get_credit_local(txfc); + uint64_t credit = ossl_quic_txfc_get_credit_local(txfc, 0); if (num_bytes > credit) { ok = 0; diff --git a/ssl/quic/quic_stream_map.c b/ssl/quic/quic_stream_map.c index 0f41b03da5..f8278c9913 100644 --- a/ssl/quic/quic_stream_map.c +++ b/ssl/quic/quic_stream_map.c @@ -269,7 +269,7 @@ static int stream_has_data_to_send(QUIC_STREAM *s) &num_iov)) return 0; - fc_credit = ossl_quic_txfc_get_credit(&s->txfc); + fc_credit = ossl_quic_txfc_get_credit(&s->txfc, 0); fc_swm = ossl_quic_txfc_get_swm(&s->txfc); fc_limit = fc_swm + fc_credit; diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c index 5500c9b3f6..f26f1e81a1 100644 --- a/ssl/quic/quic_txp.c +++ b/ssl/quic/quic_txp.c @@ -2111,7 +2111,8 @@ static int txp_plan_stream_chunk(OSSL_QUIC_TX_PACKETISER *txp, QUIC_SSTREAM *sstream, QUIC_TXFC *stream_txfc, size_t skip, - struct chunk_info *chunk) + struct chunk_info *chunk, + uint64_t consumed) { uint64_t fc_credit, fc_swm, fc_limit; @@ -2130,7 +2131,7 @@ static int txp_plan_stream_chunk(OSSL_QUIC_TX_PACKETISER *txp, chunk->orig_len = chunk->shdr.len; /* Clamp according to connection and stream-level TXFC. */ - fc_credit = ossl_quic_txfc_get_credit(stream_txfc); + fc_credit = ossl_quic_txfc_get_credit(stream_txfc, consumed); fc_swm = ossl_quic_txfc_get_swm(stream_txfc); fc_limit = fc_swm + fc_credit; @@ -2166,7 +2167,8 @@ static int txp_generate_stream_frames(OSSL_QUIC_TX_PACKETISER *txp, QUIC_STREAM *next_stream, int *have_ack_eliciting, int *packet_full, - uint64_t *new_credit_consumed) + uint64_t *new_credit_consumed, + uint64_t conn_consumed) { int rc = 0; struct chunk_info chunks[2] = {0}; @@ -2194,7 +2196,8 @@ static int txp_generate_stream_frames(OSSL_QUIC_TX_PACKETISER *txp, * determining when we can use an implicit length in a STREAM frame. */ for (i = 0; i < 2; ++i) { - if (!txp_plan_stream_chunk(txp, h, sstream, stream_txfc, i, &chunks[i])) + if (!txp_plan_stream_chunk(txp, h, sstream, stream_txfc, i, &chunks[i], + conn_consumed)) goto err; if (i == 0 && !chunks[i].valid) { @@ -2232,7 +2235,7 @@ static int txp_generate_stream_frames(OSSL_QUIC_TX_PACKETISER *txp, if (i > 0) /* Load next chunk for lookahead. */ if (!txp_plan_stream_chunk(txp, h, sstream, stream_txfc, i + 1, - &chunks[(i + 1) % 2])) + &chunks[(i + 1) % 2], conn_consumed)) goto err; /* @@ -2382,6 +2385,7 @@ static int txp_generate_stream_related(OSSL_QUIC_TX_PACKETISER *txp, uint64_t cwm; QUIC_STREAM *stream, *snext; struct tx_helper *h = &pkt->h; + uint64_t conn_consumed = 0; for (ossl_quic_stream_iter_init(&it, txp->args.qsm, 1); it.stream != NULL;) { @@ -2517,11 +2521,13 @@ static int txp_generate_stream_related(OSSL_QUIC_TX_PACKETISER *txp, snext, have_ack_eliciting, &packet_full, - &stream->txp_txfc_new_credit_consumed)) { + &stream->txp_txfc_new_credit_consumed, + conn_consumed)) { /* Fatal error (allocation, etc.) */ txp_enlink_tmp(tmp_head, stream); return 0; } + conn_consumed += stream->txp_txfc_new_credit_consumed; if (packet_full) { txp_enlink_tmp(tmp_head, stream); |