From: Hugo Landau Date: Tue, 18 Apr 2023 18:30:54 +0000 (+0100) Subject: QUIC CHANNEL: Handle any number of streams X-Git-Tag: openssl-3.2.0-alpha1~872 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=26ad16ea84c58d91375491c0872e43dc27915b4a QUIC CHANNEL: Handle any number of streams Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/20765) --- diff --git a/include/internal/quic_stream_map.h b/include/internal/quic_stream_map.h index b4e0993eb5..f9a04723c1 100644 --- a/include/internal/quic_stream_map.h +++ b/include/internal/quic_stream_map.h @@ -166,6 +166,16 @@ void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP *qsm); #define QUIC_STREAM_DIR_UNI 2 #define QUIC_STREAM_DIR_MASK 2 +static ossl_inline ossl_unused int ossl_quic_stream_is_server_init(QUIC_STREAM *s) +{ + return (s->type & QUIC_STREAM_INITIATOR_MASK) == QUIC_STREAM_INITIATOR_SERVER; +} + +static ossl_inline ossl_unused int ossl_quic_stream_is_bidi(QUIC_STREAM *s) +{ + return (s->type & QUIC_STREAM_DIR_MASK) == QUIC_STREAM_DIR_BIDI; +} + /* * Allocate a new stream. type is a combination of one QUIC_STREAM_INITIATOR_* * value and one QUIC_STREAM_DIR_* value. Note that clients can e.g. allocate diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 79e015d123..7ef66b234d 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -714,6 +714,31 @@ static int ch_on_handshake_alert(void *arg, unsigned char alert_code) #define TP_REASON_REQUIRED(x) \ x " was not sent but is required" +static void txfc_bump_cwm_bidi(QUIC_STREAM *s, void *arg) +{ + if (!ossl_quic_stream_is_bidi(s) + || ossl_quic_stream_is_server_init(s)) + return; + + ossl_quic_txfc_bump_cwm(&s->txfc, *(uint64_t *)arg); +} + +static void txfc_bump_cwm_uni(QUIC_STREAM *s, void *arg) +{ + if (ossl_quic_stream_is_bidi(s) + || ossl_quic_stream_is_server_init(s)) + return; + + ossl_quic_txfc_bump_cwm(&s->txfc, *(uint64_t *)arg); +} + +static void do_update(QUIC_STREAM *s, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + ossl_quic_stream_map_update_state(&ch->qsm, s); +} + static int ch_on_transport_params(const unsigned char *params, size_t params_len, void *arg) @@ -881,8 +906,8 @@ static int ch_on_transport_params(const unsigned char *params, */ ch->rx_init_max_stream_data_bidi_local = v; - /* Apply to stream 0. */ - ossl_quic_txfc_bump_cwm(&ch->stream0->txfc, v); + /* Apply to all existing streams. */ + ossl_quic_stream_map_visit(&ch->qsm, txfc_bump_cwm_bidi, &v); got_initial_max_stream_data_bidi_remote = 1; break; @@ -899,6 +924,9 @@ static int ch_on_transport_params(const unsigned char *params, } ch->rx_init_max_stream_data_uni_remote = v; + + /* Apply to all existing streams. */ + ossl_quic_stream_map_visit(&ch->qsm, txfc_bump_cwm_uni, &v); got_initial_max_stream_data_uni = 1; break; @@ -1093,8 +1121,11 @@ static int ch_on_transport_params(const unsigned char *params, if (got_initial_max_data || got_initial_max_stream_data_bidi_remote || got_initial_max_streams_bidi || got_initial_max_streams_uni) - /* If FC credit was bumped, we may now be able to send. */ - ossl_quic_stream_map_update_state(&ch->qsm, ch->stream0); + /* + * If FC credit was bumped, we may now be able to send. Update all + * streams. + */ + ossl_quic_stream_map_visit(&ch->qsm, do_update, ch); /* If we are a server, we now generate our own transport parameters. */ if (ch->is_server && !ch_generate_transport_params(ch)) { diff --git a/ssl/quic/quic_rx_depack.c b/ssl/quic/quic_rx_depack.c index 7af86c8841..ea54bc3c08 100644 --- a/ssl/quic/quic_rx_depack.c +++ b/ssl/quic/quic_rx_depack.c @@ -308,6 +308,33 @@ static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch, return 1; } +static void update_streams(QUIC_STREAM *s, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + ossl_quic_stream_map_update_state(&ch->qsm, s); +} + +static void update_streams_bidi(QUIC_STREAM *s, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + if (!ossl_quic_stream_is_bidi(s)) + return; + + ossl_quic_stream_map_update_state(&ch->qsm, s); +} + +static void update_streams_uni(QUIC_STREAM *s, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + if (ossl_quic_stream_is_bidi(s)) + return; + + ossl_quic_stream_map_update_state(&ch->qsm, s); +} + static int depack_do_frame_max_data(PACKET *pkt, QUIC_CHANNEL *ch, OSSL_ACKM_RX_PKT *ackm_data) { @@ -325,7 +352,7 @@ static int depack_do_frame_max_data(PACKET *pkt, QUIC_CHANNEL *ch, ackm_data->is_ack_eliciting = 1; ossl_quic_txfc_bump_cwm(&ch->conn_txfc, max_data); - ossl_quic_stream_map_update_state(&ch->qsm, ch->stream0); + ossl_quic_stream_map_visit(&ch->qsm, update_streams, ch); return 1; } @@ -404,17 +431,15 @@ static int depack_do_frame_max_streams(PACKET *pkt, if (max_streams > ch->max_local_streams_bidi) ch->max_local_streams_bidi = max_streams; - /* Stream may now be able to send */ - ossl_quic_stream_map_update_state(&ch->qsm, - ch->stream0); + /* Some streams may now be able to send. */ + ossl_quic_stream_map_visit(&ch->qsm, update_streams_bidi, ch); break; case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: if (max_streams > ch->max_local_streams_uni) ch->max_local_streams_uni = max_streams; - /* Stream may now be able to send */ - ossl_quic_stream_map_update_state(&ch->qsm, - ch->stream0); + /* Some streams may now be able to send. */ + ossl_quic_stream_map_visit(&ch->qsm, update_streams_uni, ch); break; default: ossl_quic_channel_raise_protocol_error(ch,