diff options
author | Hugo Landau <hlandau@openssl.org> | 2022-12-16 13:26:33 +0000 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2023-01-13 13:20:22 +0000 |
commit | 05f97354bb6fe29731a8a25a475a115a2c44720a (patch) | |
tree | 9095f77a8b05923f2503813ae41fb515ee78bc11 /ssl | |
parent | c41c7ee976aad76f63ce42c1ea883e4d075e2f0e (diff) |
QUIC TXP: Fix bug in send stream handling, cleanup
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19703)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/quic/quic_sstream.c | 13 | ||||
-rw-r--r-- | ssl/quic/quic_txp.c | 19 |
2 files changed, 27 insertions, 5 deletions
diff --git a/ssl/quic/quic_sstream.c b/ssl/quic/quic_sstream.c index 47d7ab1d21..a5c4b92823 100644 --- a/ssl/quic/quic_sstream.c +++ b/ssl/quic/quic_sstream.c @@ -280,6 +280,10 @@ int ossl_quic_sstream_get_stream_frame(QUIC_SSTREAM *qss, range = ossl_list_uint_set_next(range); if (range == NULL) { + if (i < skip) + /* Don't return FIN for infinitely increasing skip */ + return 0; + /* No new bytes to send, but we might have a FIN */ if (!qss->have_final_size || qss->sent_final_size) return 0; @@ -333,6 +337,15 @@ int ossl_quic_sstream_get_stream_frame(QUIC_SSTREAM *qss, return 1; } +int ossl_quic_sstream_has_pending(QUIC_SSTREAM *qss) +{ + OSSL_QUIC_FRAME_STREAM shdr; + OSSL_QTX_IOVEC iov[2]; + size_t num_iov = OSSL_NELEM(iov); + + return ossl_quic_sstream_get_stream_frame(qss, 0, &shdr, iov, &num_iov); +} + uint64_t ossl_quic_sstream_get_cur_size(QUIC_SSTREAM *qss) { return qss->ring_buf.head_offset; diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c index 6ebe2283ad..9c8fd9b547 100644 --- a/ssl/quic/quic_txp.c +++ b/ssl/quic/quic_txp.c @@ -1409,6 +1409,7 @@ static int txp_generate_stream_frames(OSSL_QUIC_TX_PACKETISER *txp, size_t i, j, space_left; int needs_padding_if_implicit, can_fill_payload, use_explicit_len; int could_have_following_chunk; + uint64_t orig_len; uint64_t hdr_len_implicit, payload_len_implicit; uint64_t hdr_len_explicit, payload_len_explicit; uint64_t fc_swm, fc_new_hwm; @@ -1459,6 +1460,7 @@ static int txp_generate_stream_frames(OSSL_QUIC_TX_PACKETISER *txp, goto err; shdr = &chunks[i % 2].shdr; + orig_len = shdr->len; if (i > 0) /* Load next chunk for lookahead. */ if (!txp_plan_stream_chunk(txp, h, sstream, stream_txfc, i + 1, @@ -1577,6 +1579,16 @@ static int txp_generate_stream_frames(OSSL_QUIC_TX_PACKETISER *txp, chunk.has_reset_stream = 0; if (!ossl_quic_txpim_pkt_append_chunk(tpkt, &chunk)) goto err; /* alloc error */ + + if (shdr->len < orig_len) { + /* + * If we did not serialize all of this chunk we definitely do not + * want to try the next chunk (and we must not mark the stream + * as drained). + */ + rc = 1; + goto err; + } } err: @@ -2093,11 +2105,8 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp, */ ossl_quic_stream_map_update_state(txp->args.qsm, stream); - if (!stream->want_max_stream_data - && !stream->want_stop_sending - && !stream->want_reset_stream - && (stream->txp_drained || stream->txp_blocked)) - assert(!stream->active); + if (stream->txp_drained) + assert(!ossl_quic_sstream_has_pending(stream->sstream)); } /* We have now sent the packet, so update state accordingly. */ |