Fix auto-setting IETF stream flow control limits

The code would set the IETF limits in the old setter in the hopes of having them used when they weren't individually set. But since they were set in the constructor that didn't work. The new code checks the old value from the getter, which gets us the requested behavior of using the old setter value in the absence of other information.

gfe-relnote: fix IETF flow control, protected by disabled TLS flag
PiperOrigin-RevId: 274898114
Change-Id: I77ddd45b00715a15cc301c4f48833a28184b8685
diff --git a/quic/core/quic_config.cc b/quic/core/quic_config.cc
index ccf64cf..a3840ec 100644
--- a/quic/core/quic_config.cc
+++ b/quic/core/quic_config.cc
@@ -518,15 +518,15 @@
   max_incoming_bidirectional_streams_.SetSendValue(max_streams);
 }
 
-uint32_t QuicConfig::GetMaxIncomingBidirectionalStreamsToSend() {
+uint32_t QuicConfig::GetMaxIncomingBidirectionalStreamsToSend() const {
   return max_incoming_bidirectional_streams_.GetSendValue();
 }
 
-bool QuicConfig::HasReceivedMaxIncomingBidirectionalStreams() {
+bool QuicConfig::HasReceivedMaxIncomingBidirectionalStreams() const {
   return max_incoming_bidirectional_streams_.HasReceivedValue();
 }
 
-uint32_t QuicConfig::ReceivedMaxIncomingBidirectionalStreams() {
+uint32_t QuicConfig::ReceivedMaxIncomingBidirectionalStreams() const {
   return max_incoming_bidirectional_streams_.GetReceivedValue();
 }
 
@@ -535,15 +535,15 @@
   max_incoming_unidirectional_streams_.SetSendValue(max_streams);
 }
 
-uint32_t QuicConfig::GetMaxIncomingUnidirectionalStreamsToSend() {
+uint32_t QuicConfig::GetMaxIncomingUnidirectionalStreamsToSend() const {
   return max_incoming_unidirectional_streams_.GetSendValue();
 }
 
-bool QuicConfig::HasReceivedMaxIncomingUnidirectionalStreams() {
+bool QuicConfig::HasReceivedMaxIncomingUnidirectionalStreams() const {
   return max_incoming_unidirectional_streams_.HasReceivedValue();
 }
 
-uint32_t QuicConfig::ReceivedMaxIncomingUnidirectionalStreams() {
+uint32_t QuicConfig::ReceivedMaxIncomingUnidirectionalStreams() const {
   return max_incoming_unidirectional_streams_.GetReceivedValue();
 }
 
@@ -567,7 +567,7 @@
   ack_delay_exponent_.SetSendValue(exponent);
 }
 
-uint32_t QuicConfig::GetAckDelayExponentToSend() {
+uint32_t QuicConfig::GetAckDelayExponentToSend() const {
   return ack_delay_exponent_.GetSendValue();
 }
 
@@ -624,19 +624,6 @@
     window_bytes = kMinimumFlowControlSendWindow;
   }
   initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
-
-  // If the IETF flow control configs have not been set yet, set them.
-  if (!initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
-    initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
-        window_bytes);
-  }
-  if (!initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
-    initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
-        window_bytes);
-  }
-  if (!initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
-    initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
-  }
 }
 
 uint32_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
@@ -659,7 +646,10 @@
 
 uint32_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
     const {
-  return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
+  if (initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
 }
 
 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
@@ -682,7 +672,10 @@
 
 uint32_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
     const {
-  return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
+  if (initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
 }
 
 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
@@ -703,7 +696,10 @@
 }
 
 uint32_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
-  return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
+  if (initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
+    return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
+  }
+  return initial_stream_flow_control_window_bytes_.GetSendValue();
 }
 
 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
@@ -806,12 +802,6 @@
   max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
 
   SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
-  SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
-      kMinimumFlowControlSendWindow);
-  SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
-      kMinimumFlowControlSendWindow);
-  SetInitialMaxStreamDataBytesUnidirectionalToSend(
-      kMinimumFlowControlSendWindow);
   SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
   SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
   SetSupportMaxHeaderListSize();
@@ -933,7 +923,7 @@
 
   params->max_packet_size.set_value(kMaxIncomingPacketSize);
   params->initial_max_data.set_value(
-      initial_session_flow_control_window_bytes_.GetSendValue());
+      GetInitialSessionFlowControlWindowToSend());
   // The max stream data bidirectional transport parameters can be either local
   // or remote. A stream is local iff it is initiated by the endpoint that sent
   // the transport parameter (see the Transport Parameter Definitions section of
@@ -941,20 +931,20 @@
   // parameters, so a local stream is one we initiated, which means an outgoing
   // stream.
   params->initial_max_stream_data_bidi_local.set_value(
-      initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue());
+      GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
   params->initial_max_stream_data_bidi_remote.set_value(
-      initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue());
+      GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
   params->initial_max_stream_data_uni.set_value(
-      initial_max_stream_data_bytes_unidirectional_.GetSendValue());
+      GetInitialMaxStreamDataBytesUnidirectionalToSend());
   params->initial_max_streams_bidi.set_value(
-      max_incoming_bidirectional_streams_.GetSendValue());
+      GetMaxIncomingBidirectionalStreamsToSend());
   params->initial_max_streams_uni.set_value(
-      max_incoming_unidirectional_streams_.GetSendValue());
+      GetMaxIncomingUnidirectionalStreamsToSend());
   if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
     QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 3, 4);
     params->max_ack_delay.set_value(kDefaultDelayedAckTimeMs);
   }
-  params->ack_delay_exponent.set_value(ack_delay_exponent_.GetSendValue());
+  params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
   params->disable_migration =
       connection_migration_disabled_.HasSendValue() &&
       connection_migration_disabled_.GetSendValue() != 0;
diff --git a/quic/core/quic_config.h b/quic/core/quic_config.h
index b2316bb..ecece2a 100644
--- a/quic/core/quic_config.h
+++ b/quic/core/quic_config.h
@@ -316,14 +316,14 @@
   // dynamic stream count (which are bidirectional streams).
   // TODO(b/142351095) rename these to improve clarity.
   void SetMaxIncomingBidirectionalStreamsToSend(uint32_t max_streams);
-  uint32_t GetMaxIncomingBidirectionalStreamsToSend();
-  bool HasReceivedMaxIncomingBidirectionalStreams();
-  uint32_t ReceivedMaxIncomingBidirectionalStreams();
+  uint32_t GetMaxIncomingBidirectionalStreamsToSend() const;
+  bool HasReceivedMaxIncomingBidirectionalStreams() const;
+  uint32_t ReceivedMaxIncomingBidirectionalStreams() const;
 
   void SetMaxIncomingUnidirectionalStreamsToSend(uint32_t max_streams);
-  uint32_t GetMaxIncomingUnidirectionalStreamsToSend();
-  bool HasReceivedMaxIncomingUnidirectionalStreams();
-  uint32_t ReceivedMaxIncomingUnidirectionalStreams();
+  uint32_t GetMaxIncomingUnidirectionalStreamsToSend() const;
+  bool HasReceivedMaxIncomingUnidirectionalStreams() const;
+  uint32_t ReceivedMaxIncomingUnidirectionalStreams() const;
 
   void set_max_time_before_crypto_handshake(
       QuicTime::Delta max_time_before_crypto_handshake) {
@@ -377,8 +377,6 @@
   uint32_t GetInitialRoundTripTimeUsToSend() const;
 
   // Sets an initial stream flow control window size to transmit to the peer.
-  // This sets the Google QUIC flow control window size, and additionally,
-  // if they are not yet set, sets the three IETF stream max data limits.
   void SetInitialStreamFlowControlWindowToSend(uint32_t window_bytes);
   uint32_t GetInitialStreamFlowControlWindowToSend() const;
   bool HasReceivedInitialStreamFlowControlWindowBytes() const;
@@ -386,7 +384,8 @@
 
   // Specifies the initial flow control window (max stream data) for
   // incoming bidirectional streams. Incoming means streams initiated by our
-  // peer.
+  // peer. If not set, GetInitialMaxStreamDataBytesIncomingBidirectionalToSend
+  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
   void SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
       uint32_t window_bytes);
   uint32_t GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const;
@@ -395,6 +394,8 @@
 
   // Specifies the initial flow control window (max stream data) for
   // outgoing bidirectional streams. Outgoing means streams initiated by us.
+  // If not set, GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend
+  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
   void SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
       uint32_t window_bytes);
   uint32_t GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const;
@@ -402,7 +403,9 @@
   uint32_t ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
 
   // Specifies the initial flow control window (max stream data) for
-  // uidirectional streams.
+  // unidirectional streams. If not set,
+  // GetInitialMaxStreamDataBytesUnidirectionalToSend returns the value passed
+  // to SetInitialStreamFlowControlWindowToSend.
   void SetInitialMaxStreamDataBytesUnidirectionalToSend(uint32_t window_bytes);
   uint32_t GetInitialMaxStreamDataBytesUnidirectionalToSend() const;
   bool HasReceivedInitialMaxStreamDataBytesUnidirectional() const;
@@ -449,7 +452,7 @@
   uint32_t ReceivedMaxAckDelayMs() const;
 
   void SetAckDelayExponentToSend(uint32_t exponent);
-  uint32_t GetAckDelayExponentToSend();
+  uint32_t GetAckDelayExponentToSend() const;
   bool HasReceivedAckDelayExponent() const;
   uint32_t ReceivedAckDelayExponent() const;
 
diff --git a/quic/core/quic_config_test.cc b/quic/core/quic_config_test.cc
index 070e809..e0eb304 100644
--- a/quic/core/quic_config_test.cc
+++ b/quic/core/quic_config_test.cc
@@ -49,6 +49,36 @@
   EXPECT_FALSE(config_.HasReceivedInitialMaxStreamDataBytesUnidirectional());
 }
 
+TEST_P(QuicConfigTest, AutoSetIetfFlowControl) {
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  static const uint32_t kTestWindowSize = 1234567;
+  config_.SetInitialStreamFlowControlWindowToSend(kTestWindowSize);
+  EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+  static const uint32_t kTestWindowSizeTwo = 2345678;
+  config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
+      kTestWindowSizeTwo);
+  EXPECT_EQ(kTestWindowSize, config_.GetInitialStreamFlowControlWindowToSend());
+  EXPECT_EQ(kTestWindowSizeTwo,
+            config_.GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
+  EXPECT_EQ(kTestWindowSize,
+            config_.GetInitialMaxStreamDataBytesUnidirectionalToSend());
+}
+
 TEST_P(QuicConfigTest, ToHandshakeMessage) {
   config_.SetInitialStreamFlowControlWindowToSend(
       kInitialStreamFlowControlWindowForTest);