gfe-relnote: In QUIC, add a connection option to set max cwnd to 100 when adjusting network parameters. Protected by existing gfe2_reloadable_flag_quic_use_ip_bandwidth_module.

PiperOrigin-RevId: 294291230
Change-Id: Iff1fe789bb6938a0068853114c01ee9bae8993d1
diff --git a/quic/core/congestion_control/bbr_sender.cc b/quic/core/congestion_control/bbr_sender.cc
index 5a6de91..3fd6139 100644
--- a/quic/core/congestion_control/bbr_sender.cc
+++ b/quic/core/congestion_control/bbr_sender.cc
@@ -130,6 +130,8 @@
       network_parameters_adjusted_(false),
       bytes_lost_with_network_parameters_adjusted_(0),
       bytes_lost_multiplier_with_network_parameters_adjusted_(2),
+      max_congestion_window_with_network_parameters_adjusted_(
+          kMaxInitialCongestionWindow * kDefaultTCPMSS),
       loss_based_startup_exit_(
           GetQuicReloadableFlag(quic_bbr_loss_based_startup_exit) &&
           sampler_.one_bw_sample_per_ack_event()) {
@@ -320,6 +322,10 @@
   if (config.HasClientRequestedIndependentOption(kMIN1, perspective)) {
     min_congestion_window_ = kMaxSegmentSize;
   }
+  if (config.HasClientRequestedIndependentOption(kICW1, perspective)) {
+    max_congestion_window_with_network_parameters_adjusted_ =
+        100 * kDefaultTCPMSS;
+  }
 }
 
 void BbrSender::AdjustNetworkParameters(const NetworkParams& params) {
@@ -342,7 +348,7 @@
     }
     const QuicByteCount new_cwnd = std::max(
         kMinInitialCongestionWindow * kDefaultTCPMSS,
-        std::min(kMaxInitialCongestionWindow * kDefaultTCPMSS,
+        std::min(max_congestion_window_with_network_parameters_adjusted_,
                  bandwidth * (params.quic_bbr_donot_inject_bandwidth
                                   ? GetMinRtt()
                                   : rtt_stats_->SmoothedOrInitialRtt())));
diff --git a/quic/core/congestion_control/bbr_sender.h b/quic/core/congestion_control/bbr_sender.h
index 4e348f3..87d3272 100644
--- a/quic/core/congestion_control/bbr_sender.h
+++ b/quic/core/congestion_control/bbr_sender.h
@@ -402,6 +402,9 @@
   // bytes_lost_multiplier_with_network_parameters_adjusted_ > IW.
   uint8_t bytes_lost_multiplier_with_network_parameters_adjusted_;
 
+  // Max congestion window when adjusting network parameters.
+  QuicByteCount max_congestion_window_with_network_parameters_adjusted_;
+
   // Latched value of --quic_bbr_loss_based_startup_exit &&
   // sampler_.one_bw_sample_per_ack_event().
   const bool loss_based_startup_exit_;
diff --git a/quic/core/congestion_control/bbr_sender_test.cc b/quic/core/congestion_control/bbr_sender_test.cc
index fac4a34..096b7fa 100644
--- a/quic/core/congestion_control/bbr_sender_test.cc
+++ b/quic/core/congestion_control/bbr_sender_test.cc
@@ -1445,5 +1445,48 @@
   }
 }
 
+TEST_F(BbrSenderTest, 200InitialCongestionWindowWithNetworkParameterAdjusted) {
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  // Verify cwnd is capped at 200.
+  EXPECT_EQ(200 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
+}
+
+TEST_F(BbrSenderTest, 100InitialCongestionWindowWithNetworkParameterAdjusted) {
+  SetConnectionOption(kICW1);
+  CreateDefaultSetup();
+
+  bbr_sender_.AddBytesToTransfer(1 * 1024 * 1024);
+  // Wait until an ACK comes back.
+  const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
+      timeout);
+  ASSERT_TRUE(simulator_result);
+
+  // Bootstrap cwnd by a overly large bandwidth sample.
+  bbr_sender_.connection()->AdjustNetworkParameters(
+      SendAlgorithmInterface::NetworkParams(1024 * kTestLinkBandwidth,
+                                            QuicTime::Delta::Zero(), false));
+  // Verify cwnd is capped at 100.
+  EXPECT_EQ(100 * kDefaultTCPMSS,
+            sender_->ExportDebugState().congestion_window);
+  EXPECT_GT(1024 * kTestLinkBandwidth, sender_->PacingRate(0));
+}
+
 }  // namespace test
 }  // namespace quic
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h
index 766fa0b..54a91e2 100644
--- a/quic/core/crypto/crypto_protocol.h
+++ b/quic/core/crypto/crypto_protocol.h
@@ -245,6 +245,8 @@
 const QuicTag kBWM4 = TAG('B', 'W', 'M', '4');  // Consider overshooting if
                                                 // bytes lost after bandwidth
                                                 // resumption * 4 > IW.
+const QuicTag kICW1 = TAG('I', 'C', 'W', '1');  // Max initial congestion window
+                                                // 100.
 
 // Enable path MTU discovery experiment.
 const QuicTag kMTUH = TAG('M', 'T', 'U', 'H');  // High-target MTU discovery.