Allow creation of HTTP/3 static stream after MAX_STREAM frame is received. outgoing_max_streams_ is not incremented after MAX_STREAM frame to reflect the intention that after max stream settings, outgoing_max_streams_ becomes the real max stream count, including static streams. gfe-relnote: v99 only, not protected. PiperOrigin-RevId: 263140936 Change-Id: I187fcaf6874f1e8386edb497ba92b7a7b563bfea
diff --git a/quic/core/quic_stream_id_manager.cc b/quic/core/quic_stream_id_manager.cc index f384776..8865a1d 100644 --- a/quic/core/quic_stream_id_manager.cc +++ b/quic/core/quic_stream_id_manager.cc
@@ -276,10 +276,6 @@ return true; } - QUIC_BUG_IF(!using_default_max_streams_) - << "Attempted to allocate static stream (id " << stream_id - << ") after receiving a MAX_STREAMS frame"; - // If we have reached the limit on stream creation, do not create // the static stream; return false. if (outgoing_max_streams_ >= @@ -291,7 +287,9 @@ // outgoing_max_streams_ was inialized to a "maximum request/response" count // and only becomes a maximum stream count when we receive the first // MAX_STREAMS. - outgoing_max_streams_++; + if (using_default_max_streams_) { + outgoing_max_streams_++; + } outgoing_static_stream_count_++; return true; }
diff --git a/quic/core/quic_stream_id_manager_test.cc b/quic/core/quic_stream_id_manager_test.cc index 30ff954..bd41e45 100644 --- a/quic/core/quic_stream_id_manager_test.cc +++ b/quic/core/quic_stream_id_manager_test.cc
@@ -867,6 +867,30 @@ EXPECT_EQ(max_stream_count, stream_id_manager_->outgoing_max_streams()); } +// Check that static streams can be created before and after MAX_STREAM frame is +// received. +TEST_P(QuicStreamIdManagerTestServer, RegisterStaticStreams) { + EXPECT_EQ(0u, stream_id_manager_->outgoing_static_stream_count()); + QuicStreamCount previous_max = stream_id_manager_->outgoing_max_streams(); + stream_id_manager_->RegisterStaticStream( + stream_id_manager_->GetNextOutgoingStreamId(), + /*stream_already_counted = */ false); + EXPECT_EQ(1u, stream_id_manager_->outgoing_static_stream_count()); + EXPECT_EQ(previous_max + 1, stream_id_manager_->outgoing_max_streams()); + + QuicMaxStreamsFrame frame; + frame.unidirectional = IsUnidi(); + frame.stream_count = 20; + EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame)); + EXPECT_EQ(20u, stream_id_manager_->outgoing_max_streams()); + + stream_id_manager_->RegisterStaticStream( + stream_id_manager_->GetNextOutgoingStreamId(), + /*stream_already_counted = */ false); + EXPECT_EQ(2u, stream_id_manager_->outgoing_static_stream_count()); + EXPECT_EQ(20u, stream_id_manager_->outgoing_max_streams()); +} + } // namespace } // namespace test } // namespace quic