From 098914d0b768c090d443a46b66e4875969bee1e6 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Tue, 25 Jul 2023 11:32:25 +0100 Subject: [PATCH] QUIC CHANNEL: Apply flow control to CRYPTO streams Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/21547) --- ssl/quic/quic_channel.c | 15 ++++++++++++++- ssl/quic/quic_channel_local.h | 2 +- ssl/quic/quic_rx_depack.c | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index bdf6376e2b..c7fbb9f4a1 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -176,6 +176,12 @@ static int ch_init(QUIC_CHANNEL *ch) get_time, ch)) goto err; + for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) + if (!ossl_quic_rxfc_init_standalone(&ch->crypto_rxfc[pn_space], + INIT_CRYPTO_BUF_LEN, + get_time, ch)) + goto err; + if (!ossl_quic_rxfc_init_standalone(&ch->max_streams_bidi_rxfc, DEFAULT_INIT_CONN_MAX_STREAMS, get_time, ch)) @@ -855,11 +861,18 @@ static int ch_on_crypto_release_record(size_t bytes_read, void *arg) { QUIC_CHANNEL *ch = arg; QUIC_RSTREAM *rstream; + OSSL_RTT_INFO rtt_info; + uint32_t rx_pn_space = ossl_quic_enc_level_to_pn_space(ch->rx_enc_level); - rstream = ch->crypto_recv[ossl_quic_enc_level_to_pn_space(ch->rx_enc_level)]; + rstream = ch->crypto_recv[rx_pn_space]; if (rstream == NULL) return 0; + ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ch), &rtt_info); + if (!ossl_quic_rxfc_on_retire(&ch->crypto_rxfc[rx_pn_space], bytes_read, + rtt_info.smoothed_rtt)) + return 0; + return ossl_quic_rstream_release_record(rstream, bytes_read); } diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h index 11e43ffdcf..ba129d9db3 100644 --- a/ssl/quic/quic_channel_local.h +++ b/ssl/quic/quic_channel_local.h @@ -74,7 +74,7 @@ struct quic_channel_st { * MAX_STREAMS signalling. */ QUIC_TXFC conn_txfc; - QUIC_RXFC conn_rxfc; + QUIC_RXFC conn_rxfc, crypto_rxfc[QUIC_PN_SPACE_NUM]; QUIC_RXFC max_streams_bidi_rxfc, max_streams_uni_rxfc; QUIC_STREAM_MAP qsm; OSSL_STATM statm; diff --git a/ssl/quic/quic_rx_depack.c b/ssl/quic/quic_rx_depack.c index d58efb2af3..d1e166e062 100644 --- a/ssl/quic/quic_rx_depack.c +++ b/ssl/quic/quic_rx_depack.c @@ -257,6 +257,7 @@ static int depack_do_frame_crypto(PACKET *pkt, QUIC_CHANNEL *ch, { OSSL_QUIC_FRAME_CRYPTO f; QUIC_RSTREAM *rstream; + QUIC_RXFC *rxfc; *datalen = 0; @@ -277,6 +278,24 @@ static int depack_do_frame_crypto(PACKET *pkt, QUIC_CHANNEL *ch, */ return 0; + rxfc = &ch->crypto_rxfc[ackm_data->pkt_space]; + + if (!ossl_quic_rxfc_on_rx_stream_frame(rxfc, f.offset + f.len, + /*is_fin=*/0)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "internal error (crypto RXFC)"); + return 0; + } + + if (ossl_quic_rxfc_get_error(rxfc, 0) != QUIC_ERR_NO_ERROR) { + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_CRYPTO_BUFFER_EXCEEDED, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "exceeded maximum crypto buffer"); + return 0; + } + if (!ossl_quic_rstream_queue_data(rstream, parent_pkt, f.offset, f.data, f.len, 0)) return 0; -- 2.39.2