gfe-relnote: Honor IETF QUIC initial flow control limits when using TLS. Protected by disabled --gfe2_reloadable_flag_quic_supports_tls_handshake PiperOrigin-RevId: 268605601 Change-Id: If7e0d3e59a30197d4bc9c681b988bd7251074395
diff --git a/quic/core/http/quic_headers_stream_test.cc b/quic/core/http/quic_headers_stream_test.cc index b5385b7..2f2db8d 100644 --- a/quic/core/http/quic_headers_stream_test.cc +++ b/quic/core/http/quic_headers_stream_test.cc
@@ -321,6 +321,7 @@ } void CheckHeaders() { + ASSERT_TRUE(headers_handler_); EXPECT_EQ(headers_, headers_handler_->decoded_block()); headers_handler_.reset(); }
diff --git a/quic/core/quic_config.cc b/quic/core/quic_config.cc index 425dbdf..6400b0e 100644 --- a/quic/core/quic_config.cc +++ b/quic/core/quic_config.cc
@@ -407,6 +407,11 @@ max_incoming_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED), bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL), initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL), + initial_max_stream_data_bytes_incoming_bidirectional_(0, + PRESENCE_OPTIONAL), + initial_max_stream_data_bytes_outgoing_bidirectional_(0, + PRESENCE_OPTIONAL), + initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL), initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL), initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL), connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL), @@ -633,6 +638,87 @@ return initial_stream_flow_control_window_bytes_.GetReceivedValue(); } +void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend( + uint32_t window_bytes) { + if (window_bytes < kMinimumFlowControlSendWindow) { + QUIC_BUG << "Initial stream flow control receive window (" << window_bytes + << ") cannot be set lower than minimum (" + << kMinimumFlowControlSendWindow << ")."; + window_bytes = kMinimumFlowControlSendWindow; + } + initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue( + window_bytes); +} + +uint32_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() + const { + return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue(); +} + +bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() + const { + return initial_max_stream_data_bytes_incoming_bidirectional_ + .HasReceivedValue(); +} + +uint32_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional() + const { + return initial_max_stream_data_bytes_incoming_bidirectional_ + .GetReceivedValue(); +} + +void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend( + uint32_t window_bytes) { + if (window_bytes < kMinimumFlowControlSendWindow) { + QUIC_BUG << "Initial stream flow control receive window (" << window_bytes + << ") cannot be set lower than minimum (" + << kMinimumFlowControlSendWindow << ")."; + window_bytes = kMinimumFlowControlSendWindow; + } + initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue( + window_bytes); +} + +uint32_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() + const { + return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue(); +} + +bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() + const { + return initial_max_stream_data_bytes_outgoing_bidirectional_ + .HasReceivedValue(); +} + +uint32_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() + const { + return initial_max_stream_data_bytes_outgoing_bidirectional_ + .GetReceivedValue(); +} + +void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend( + uint32_t window_bytes) { + if (window_bytes < kMinimumFlowControlSendWindow) { + QUIC_BUG << "Initial stream flow control receive window (" << window_bytes + << ") cannot be set lower than minimum (" + << kMinimumFlowControlSendWindow << ")."; + window_bytes = kMinimumFlowControlSendWindow; + } + initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes); +} + +uint32_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const { + return initial_max_stream_data_bytes_unidirectional_.GetSendValue(); +} + +bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const { + return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue(); +} + +uint32_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const { + return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue(); +} + void QuicConfig::SetInitialSessionFlowControlWindowToSend( uint32_t window_bytes) { if (window_bytes < kMinimumFlowControlSendWindow) { @@ -725,6 +811,12 @@ max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets; SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow); + SetInitialMaxStreamDataBytesIncomingBidirectionalToSend( + kMinimumFlowControlSendWindow); + SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend( + kMinimumFlowControlSendWindow); + SetInitialMaxStreamDataBytesUnidirectionalToSend( + kMinimumFlowControlSendWindow); SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow); SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs); SetSupportMaxHeaderListSize(); @@ -848,11 +940,11 @@ params->initial_max_data.set_value( initial_session_flow_control_window_bytes_.GetSendValue()); params->initial_max_stream_data_bidi_local.set_value( - initial_stream_flow_control_window_bytes_.GetSendValue()); + initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue()); params->initial_max_stream_data_bidi_remote.set_value( - initial_stream_flow_control_window_bytes_.GetSendValue()); + initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue()); params->initial_max_stream_data_uni.set_value( - initial_stream_flow_control_window_bytes_.GetSendValue()); + initial_max_stream_data_bytes_unidirectional_.GetSendValue()); params->initial_max_streams_bidi.set_value( max_incoming_bidirectional_streams_.GetSendValue()); params->initial_max_streams_uni.set_value( @@ -940,9 +1032,16 @@ std::min<uint64_t>(params.initial_max_streams_uni.value(), std::numeric_limits<uint32_t>::max())); - initial_stream_flow_control_window_bytes_.SetReceivedValue( + initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue( std::min<uint64_t>(params.initial_max_stream_data_bidi_local.value(), std::numeric_limits<uint32_t>::max())); + initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue( + std::min<uint64_t>(params.initial_max_stream_data_bidi_remote.value(), + std::numeric_limits<uint32_t>::max())); + initial_max_stream_data_bytes_unidirectional_.SetReceivedValue( + std::min<uint64_t>(params.initial_max_stream_data_uni.value(), + std::numeric_limits<uint32_t>::max())); + if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) { QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 4, 4); max_ack_delay_ms_.SetReceivedValue(std::min<uint32_t>(
diff --git a/quic/core/quic_config.h b/quic/core/quic_config.h index b4a4ca9..b9ebcc1 100644 --- a/quic/core/quic_config.h +++ b/quic/core/quic_config.h
@@ -377,13 +377,33 @@ // Sets an initial stream flow control window size to transmit to the peer. void SetInitialStreamFlowControlWindowToSend(uint32_t window_bytes); - uint32_t GetInitialStreamFlowControlWindowToSend() const; - bool HasReceivedInitialStreamFlowControlWindowBytes() const; - uint32_t ReceivedInitialStreamFlowControlWindowBytes() const; + // Specifies the initial flow control window (max stream data) for + // incoming bidirectional streams. + void SetInitialMaxStreamDataBytesIncomingBidirectionalToSend( + uint32_t window_bytes); + uint32_t GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const; + bool HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() const; + uint32_t ReceivedInitialMaxStreamDataBytesIncomingBidirectional() const; + + // Specifies the initial flow control window (max stream data) for + // outgoing bidirectional streams. + void SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend( + uint32_t window_bytes); + uint32_t GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const; + bool HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const; + uint32_t ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const; + + // Specifies the initial flow control window (max stream data) for + // uidirectional streams. + void SetInitialMaxStreamDataBytesUnidirectionalToSend(uint32_t window_bytes); + uint32_t GetInitialMaxStreamDataBytesUnidirectionalToSend() const; + bool HasReceivedInitialMaxStreamDataBytesUnidirectional() const; + uint32_t ReceivedInitialMaxStreamDataBytesUnidirectional() const; + // Sets an initial session flow control window size to transmit to the peer. void SetInitialSessionFlowControlWindowToSend(uint32_t window_bytes); @@ -491,8 +511,17 @@ // Initial round trip time estimate in microseconds. QuicFixedUint32 initial_round_trip_time_us_; - // Initial stream flow control receive window in bytes. + // Initial IETF QUIC stream flow control receive windows in bytes. + // Incoming bidirectional streams. + QuicFixedUint32 initial_max_stream_data_bytes_incoming_bidirectional_; + // Outgoing bidirectional streams. + QuicFixedUint32 initial_max_stream_data_bytes_outgoing_bidirectional_; + // Unidirectional streams. + QuicFixedUint32 initial_max_stream_data_bytes_unidirectional_; + + // Initial Google QUIC stream flow control receive window in bytes. QuicFixedUint32 initial_stream_flow_control_window_bytes_; + // Initial session flow control receive window in bytes. QuicFixedUint32 initial_session_flow_control_window_bytes_;
diff --git a/quic/core/quic_config_test.cc b/quic/core/quic_config_test.cc index 5e3bb65..fe04008 100644 --- a/quic/core/quic_config_test.cc +++ b/quic/core/quic_config_test.cc
@@ -31,6 +31,23 @@ QuicConfigTest, ::testing::ValuesIn(AllSupportedTransportVersions())); +TEST_P(QuicConfigTest, SetDefaults) { + EXPECT_EQ(kMinimumFlowControlSendWindow, + config_.GetInitialStreamFlowControlWindowToSend()); + EXPECT_EQ(kMinimumFlowControlSendWindow, + config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()); + EXPECT_EQ(kMinimumFlowControlSendWindow, + config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()); + EXPECT_EQ(kMinimumFlowControlSendWindow, + config_.GetInitialMaxStreamDataBytesUnidirectionalToSend()); + EXPECT_FALSE(config_.HasReceivedInitialStreamFlowControlWindowBytes()); + EXPECT_FALSE( + config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()); + EXPECT_FALSE( + config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()); + EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()); +} + TEST_P(QuicConfigTest, ToHandshakeMessage) { config_.SetInitialStreamFlowControlWindowToSend( kInitialStreamFlowControlWindowForTest); @@ -108,6 +125,13 @@ } else { EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs()); } + + // IETF QUIC stream limits should not be received in QUIC crypto messages. + EXPECT_FALSE( + config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()); + EXPECT_FALSE( + config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()); + EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()); } TEST_P(QuicConfigTest, ProcessServerHello) { @@ -155,6 +179,13 @@ } else { EXPECT_FALSE(config_.HasReceivedMaxAckDelayMs()); } + + // IETF QUIC stream limits should not be received in QUIC crypto messages. + EXPECT_FALSE( + config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()); + EXPECT_FALSE( + config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()); + EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()); } TEST_P(QuicConfigTest, MissingOptionalValuesInCHLO) { @@ -322,6 +353,54 @@ config_.IdleNetworkTimeout()); } +TEST_P(QuicConfigTest, FillTransportParams) { + config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend( + 2 * kMinimumFlowControlSendWindow); + config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend( + 3 * kMinimumFlowControlSendWindow); + config_.SetInitialMaxStreamDataBytesUnidirectionalToSend( + 4 * kMinimumFlowControlSendWindow); + + TransportParameters params; + config_.FillTransportParameters(¶ms); + + EXPECT_EQ(2 * kMinimumFlowControlSendWindow, + params.initial_max_stream_data_bidi_local.value()); + EXPECT_EQ(3 * kMinimumFlowControlSendWindow, + params.initial_max_stream_data_bidi_remote.value()); + EXPECT_EQ(4 * kMinimumFlowControlSendWindow, + params.initial_max_stream_data_uni.value()); +} + +TEST_P(QuicConfigTest, ProcessTransportParametersServer) { + TransportParameters params; + + params.initial_max_stream_data_bidi_local.set_value( + 2 * kMinimumFlowControlSendWindow); + params.initial_max_stream_data_bidi_remote.set_value( + 3 * kMinimumFlowControlSendWindow); + params.initial_max_stream_data_uni.set_value(4 * + kMinimumFlowControlSendWindow); + + std::string error_details; + EXPECT_EQ(QUIC_NO_ERROR, + config_.ProcessTransportParameters(params, SERVER, &error_details)); + + ASSERT_TRUE( + config_.HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()); + EXPECT_EQ(2 * kMinimumFlowControlSendWindow, + config_.ReceivedInitialMaxStreamDataBytesIncomingBidirectional()); + + ASSERT_TRUE( + config_.HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()); + EXPECT_EQ(3 * kMinimumFlowControlSendWindow, + config_.ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()); + + ASSERT_TRUE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional()); + EXPECT_EQ(4 * kMinimumFlowControlSendWindow, + config_.ReceivedInitialMaxStreamDataBytesUnidirectional()); +} + } // namespace } // namespace test } // namespace quic
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc index 91ba580..43b8db8 100644 --- a/quic/core/quic_stream.cc +++ b/quic/core/quic_stream.cc
@@ -24,13 +24,68 @@ namespace { -size_t GetInitialStreamFlowControlWindowToSend(QuicSession* session) { - return session->config()->GetInitialStreamFlowControlWindowToSend(); +size_t GetInitialStreamFlowControlWindowToSend(QuicSession* session, + QuicStreamId stream_id) { + ParsedQuicVersion version = session->connection()->version(); + if (version.handshake_protocol != PROTOCOL_TLS1_3) { + return session->config()->GetInitialStreamFlowControlWindowToSend(); + } + + // Unidirectional streams (v99 only). + if (VersionHasIetfQuicFrames(version.transport_version) && + !QuicUtils::IsBidirectionalStreamId(stream_id)) { + return session->config() + ->GetInitialMaxStreamDataBytesUnidirectionalToSend(); + } + + if (session->perspective() == Perspective::IS_SERVER && + QuicUtils::IsServerInitiatedStreamId(version.transport_version, + stream_id)) { + return session->config() + ->GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(); + } + + return session->config() + ->GetInitialMaxStreamDataBytesIncomingBidirectionalToSend(); } -size_t GetReceivedFlowControlWindow(QuicSession* session) { - if (session->config()->HasReceivedInitialStreamFlowControlWindowBytes()) { - return session->config()->ReceivedInitialStreamFlowControlWindowBytes(); +size_t GetReceivedFlowControlWindow(QuicSession* session, + QuicStreamId stream_id) { + ParsedQuicVersion version = session->connection()->version(); + if (version.handshake_protocol != PROTOCOL_TLS1_3) { + if (session->config()->HasReceivedInitialStreamFlowControlWindowBytes()) { + return session->config()->ReceivedInitialStreamFlowControlWindowBytes(); + } + + return kDefaultFlowControlSendWindow; + } + + // Unidirectional streams (v99 only). + if (VersionHasIetfQuicFrames(version.transport_version) && + !QuicUtils::IsBidirectionalStreamId(stream_id)) { + if (session->config() + ->HasReceivedInitialMaxStreamDataBytesUnidirectional()) { + return session->config() + ->ReceivedInitialMaxStreamDataBytesUnidirectional(); + } + return kDefaultFlowControlSendWindow; + } + + if (session->perspective() == Perspective::IS_SERVER && + QuicUtils::IsServerInitiatedStreamId(version.transport_version, + stream_id)) { + if (session->config() + ->HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()) { + return session->config() + ->ReceivedInitialMaxStreamDataBytesIncomingBidirectional(); + } + return kDefaultFlowControlSendWindow; + } + + if (session->config() + ->HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()) { + return session->config() + ->ReceivedInitialMaxStreamDataBytesOutgoingBidirectional(); } return kDefaultFlowControlSendWindow; @@ -50,8 +105,8 @@ flow_controller_(session, id, /*is_connection_flow_controller*/ false, - GetReceivedFlowControlWindow(session), - GetInitialStreamFlowControlWindowToSend(session), + GetReceivedFlowControlWindow(session, id), + GetInitialStreamFlowControlWindowToSend(session, id), kStreamReceiveWindowLimit, session_->flow_controller()->auto_tune_receive_window(), session_->flow_controller()), @@ -206,8 +261,8 @@ return QuicFlowController( session, id, /*is_connection_flow_controller*/ false, - GetReceivedFlowControlWindow(session), - GetInitialStreamFlowControlWindowToSend(session), + GetReceivedFlowControlWindow(session, id), + GetInitialStreamFlowControlWindowToSend(session, id), kStreamReceiveWindowLimit, session->flow_controller()->auto_tune_receive_window(), session->flow_controller());
diff --git a/quic/test_tools/quic_config_peer.cc b/quic/test_tools/quic_config_peer.cc index f9ce04f..6278817 100644 --- a/quic/test_tools/quic_config_peer.cc +++ b/quic/test_tools/quic_config_peer.cc
@@ -18,6 +18,30 @@ } // static +void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional( + QuicConfig* config, + uint32_t window_bytes) { + config->initial_max_stream_data_bytes_incoming_bidirectional_ + .SetReceivedValue(window_bytes); +} + +// static +void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional( + QuicConfig* config, + uint32_t window_bytes) { + config->initial_max_stream_data_bytes_outgoing_bidirectional_ + .SetReceivedValue(window_bytes); +} + +// static +void QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional( + QuicConfig* config, + uint32_t window_bytes) { + config->initial_max_stream_data_bytes_unidirectional_.SetReceivedValue( + window_bytes); +} + +// static void QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow( QuicConfig* config, uint32_t window_bytes) {
diff --git a/quic/test_tools/quic_config_peer.h b/quic/test_tools/quic_config_peer.h index 7faee7e..e68d87d 100644 --- a/quic/test_tools/quic_config_peer.h +++ b/quic/test_tools/quic_config_peer.h
@@ -22,6 +22,18 @@ static void SetReceivedInitialStreamFlowControlWindow(QuicConfig* config, uint32_t window_bytes); + static void SetReceivedInitialMaxStreamDataBytesIncomingBidirectional( + QuicConfig* config, + uint32_t window_bytes); + + static void SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional( + QuicConfig* config, + uint32_t window_bytes); + + static void SetReceivedInitialMaxStreamDataBytesUnidirectional( + QuicConfig* config, + uint32_t window_bytes); + static void SetReceivedInitialSessionFlowControlWindow(QuicConfig* config, uint32_t window_bytes);
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc index 9afbf98..7a43deb 100644 --- a/quic/test_tools/quic_test_utils.cc +++ b/quic/test_tools/quic_test_utils.cc
@@ -1058,6 +1058,12 @@ QuicConfig DefaultQuicConfig() { QuicConfig config; + config.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend( + kInitialStreamFlowControlWindowForTest); + config.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend( + kInitialStreamFlowControlWindowForTest); + config.SetInitialMaxStreamDataBytesUnidirectionalToSend( + kInitialStreamFlowControlWindowForTest); config.SetInitialStreamFlowControlWindowToSend( kInitialStreamFlowControlWindowForTest); config.SetInitialSessionFlowControlWindowToSend(
diff --git a/quic/tools/quic_simple_server_session_test.cc b/quic/tools/quic_simple_server_session_test.cc index 378edec..1116cc9 100644 --- a/quic/tools/quic_simple_server_session_test.cc +++ b/quic/tools/quic_simple_server_session_test.cc
@@ -200,6 +200,12 @@ config_.SetInitialStreamFlowControlWindowToSend( kInitialStreamFlowControlWindowForTest); + config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend( + kInitialStreamFlowControlWindowForTest); + config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend( + kInitialStreamFlowControlWindowForTest); + config_.SetInitialMaxStreamDataBytesUnidirectionalToSend( + kInitialStreamFlowControlWindowForTest); config_.SetInitialSessionFlowControlWindowToSend( kInitialSessionFlowControlWindowForTest); if (VersionUsesQpack(GetParam().transport_version)) { @@ -555,8 +561,19 @@ QuicSimpleServerSessionServerPushTest() { // Reset stream level flow control window to be 32KB. - QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow( - &config_, kStreamFlowControlWindowSize); + if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) { + if (VersionHasIetfQuicFrames(GetParam().transport_version)) { + QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional( + &config_, kStreamFlowControlWindowSize); + } else { + QuicConfigPeer:: + SetReceivedInitialMaxStreamDataBytesIncomingBidirectional( + &config_, kStreamFlowControlWindowSize); + } + } else { + QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow( + &config_, kStreamFlowControlWindowSize); + } // Reset connection level flow control window to be 1.5 MB which is large // enough that it won't block any stream to write before stream level flow // control blocks it.