From 5bd9ddd86e714705840215b8d2bbb0aedc598e96 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Tue, 18 Apr 2023 19:30:55 +0100 Subject: QUIC FC: Modify RXFC to support use for enforcing MAX_STREAMS Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/20765) --- include/internal/quic_fc.h | 13 ++++++++++++- ssl/quic/quic_fc.c | 22 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/internal/quic_fc.h b/include/internal/quic_fc.h index b07326ddf4..78398c7242 100644 --- a/include/internal/quic_fc.h +++ b/include/internal/quic_fc.h @@ -137,7 +137,7 @@ struct quic_rxfc_st { OSSL_TIME (*now)(void *arg); void *now_arg; QUIC_RXFC *parent; - unsigned char error_code, has_cwm_changed, is_fin; + unsigned char error_code, has_cwm_changed, is_fin, stream_count_mode; }; /* @@ -147,6 +147,9 @@ struct quic_rxfc_st { * and absolute maximum window sizes, respectively. Window size values are * expressed in bytes and determine how much credit the RXFC extends to the peer * to transmit more data at a time. + * + * If stream_count_mode is 1, this RXFC is for use tracking maximum stream count + * enforcement. In this case conn_rxfc must be NULL. */ int ossl_quic_rxfc_init(QUIC_RXFC *rxfc, QUIC_RXFC *conn_rxfc, uint64_t initial_window_size, @@ -154,6 +157,14 @@ int ossl_quic_rxfc_init(QUIC_RXFC *rxfc, QUIC_RXFC *conn_rxfc, OSSL_TIME (*now)(void *arg), void *now_arg); +/* + * Initialises an RX flow controller for stream count enforcement. + */ +int ossl_quic_rxfc_init_for_stream_count(QUIC_RXFC *rxfc, + uint64_t initial_window_size, + OSSL_TIME (*now)(void *arg), + void *now_arg); + /* * Gets the parent (i.e., connection-level) RXFC. Returns NULL if called on a * connection-level RXFC. diff --git a/ssl/quic/quic_fc.c b/ssl/quic/quic_fc.c index 40bdd9909f..b016c02151 100644 --- a/ssl/quic/quic_fc.c +++ b/ssl/quic/quic_fc.c @@ -146,6 +146,21 @@ int ossl_quic_rxfc_init(QUIC_RXFC *rxfc, QUIC_RXFC *conn_rxfc, rxfc->now = now; rxfc->now_arg = now_arg; rxfc->is_fin = 0; + rxfc->stream_count_mode = 0; + return 1; +} + +int ossl_quic_rxfc_init_for_stream_count(QUIC_RXFC *rxfc, + uint64_t initial_window_size, + OSSL_TIME (*now)(void *arg), + void *now_arg) +{ + if (!ossl_quic_rxfc_init(rxfc, NULL, + initial_window_size, initial_window_size, + now, now_arg)) + return 0; + + rxfc->stream_count_mode = 1; return 1; } @@ -185,7 +200,7 @@ int ossl_quic_rxfc_on_rx_stream_frame(QUIC_RXFC *rxfc, uint64_t end, int is_fin) { uint64_t delta; - if (rxfc->parent == NULL) + if (!rxfc->stream_count_mode && rxfc->parent == NULL) return 0; if (rxfc->is_fin && ((is_fin && rxfc->hwm != end) || end > rxfc->hwm)) { @@ -201,8 +216,9 @@ int ossl_quic_rxfc_on_rx_stream_frame(QUIC_RXFC *rxfc, uint64_t end, int is_fin) delta = end - rxfc->hwm; rxfc->hwm = end; - on_rx_controlled_bytes(rxfc, delta); /* result ignored */ - on_rx_controlled_bytes(rxfc->parent, delta); /* result ignored */ + on_rx_controlled_bytes(rxfc, delta); /* result ignored */ + if (rxfc->parent != NULL) + on_rx_controlled_bytes(rxfc->parent, delta); /* result ignored */ } else if (end < rxfc->hwm && is_fin) { rxfc->error_code = QUIC_ERR_FINAL_SIZE_ERROR; return 1; /* not a caller error */ -- cgit v1.2.1