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(&params);
+
+  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.