#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
#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)
*/
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;
}
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;
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)) {
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)
{
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;
}
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,