gfe-relnote: (n/a) Add 2 connection options for BBRv2 to disable 1) adding ack height in queueing threshold, and 2) avoiding unnecessary PROBE_RTTs. Not protected, just more switches for already existing behaviors.

PiperOrigin-RevId: 301176881
Change-Id: Idb6108aec370ea3aa7c8db5fafe2f3e57b507e8d
diff --git a/quic/core/congestion_control/bbr2_misc.h b/quic/core/congestion_control/bbr2_misc.h
index d98bb1a..b8ba702 100644
--- a/quic/core/congestion_control/bbr2_misc.h
+++ b/quic/core/congestion_control/bbr2_misc.h
@@ -161,6 +161,22 @@
   float beta = 0.3;
 
   Limits<QuicByteCount> cwnd_limits;
+
+  /*
+   * Experimental flags from QuicConfig.
+   */
+
+  // Indicates app-limited calls should be ignored as long as there's
+  // enough data inflight to see more bandwidth when necessary.
+  bool flexible_app_limited = false;
+
+  // Can be disabled by connection option 'B2NA'.
+  bool add_ack_height_to_queueing_threshold =
+      GetQuicReloadableFlag(quic_bbr2_add_ack_height_to_queueing_threshold);
+
+  // Can be disabled by connection option 'B2RP'.
+  bool avoid_unnecessary_probe_rtt =
+      GetQuicReloadableFlag(quic_bbr2_avoid_unnecessary_probe_rtt);
 };
 
 class QUIC_EXPORT_PRIVATE RoundTripCounter {
diff --git a/quic/core/congestion_control/bbr2_probe_bw.cc b/quic/core/congestion_control/bbr2_probe_bw.cc
index 1002983..1a7a719 100644
--- a/quic/core/congestion_control/bbr2_probe_bw.cc
+++ b/quic/core/congestion_control/bbr2_probe_bw.cc
@@ -393,7 +393,7 @@
   } else if (cycle_.rounds_in_phase > 0) {
     const QuicByteCount bdp = model_->BDP(model_->MaxBandwidth());
     QuicByteCount queuing_threshold_extra_bytes = 2 * kDefaultTCPMSS;
-    if (add_ack_height_to_queueing_threshold_) {
+    if (Params().add_ack_height_to_queueing_threshold) {
       QUIC_RELOADABLE_FLAG_COUNT(
           quic_bbr2_add_ack_height_to_queueing_threshold);
       queuing_threshold_extra_bytes += model_->MaxAckHeight();
diff --git a/quic/core/congestion_control/bbr2_probe_bw.h b/quic/core/congestion_control/bbr2_probe_bw.h
index e42ab30..5c0224f 100644
--- a/quic/core/congestion_control/bbr2_probe_bw.h
+++ b/quic/core/congestion_control/bbr2_probe_bw.h
@@ -126,9 +126,6 @@
 
   bool last_cycle_probed_too_high_;
   bool last_cycle_stopped_risky_probe_;
-
-  const bool add_ack_height_to_queueing_threshold_ =
-      GetQuicReloadableFlag(quic_bbr2_add_ack_height_to_queueing_threshold);
 };
 
 QUIC_EXPORT_PRIVATE std::ostream& operator<<(
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc
index 5b6f6e8..c975aec 100644
--- a/quic/core/congestion_control/bbr2_sender.cc
+++ b/quic/core/congestion_control/bbr2_sender.cc
@@ -81,7 +81,6 @@
       drain_(this, &model_),
       probe_bw_(this, &model_),
       probe_rtt_(this, &model_),
-      flexible_app_limited_(false),
       last_sample_is_app_limited_(false) {
   QUIC_DVLOG(2) << this << " Initializing Bbr2Sender. mode:" << mode_
                 << ", PacingRate:" << pacing_rate_ << ", Cwnd:" << cwnd_
@@ -92,7 +91,7 @@
 void Bbr2Sender::SetFromConfig(const QuicConfig& config,
                                Perspective perspective) {
   if (config.HasClientRequestedIndependentOption(kBBR9, perspective)) {
-    flexible_app_limited_ = true;
+    params_.flexible_app_limited = true;
   }
   if (GetQuicReloadableFlag(
           quic_avoid_overestimate_bandwidth_with_aggregation) &&
@@ -101,6 +100,12 @@
         quic_avoid_overestimate_bandwidth_with_aggregation, 4, 4);
     model_.EnableOverestimateAvoidance();
   }
+  if (config.HasClientRequestedIndependentOption(kB2NA, perspective)) {
+    params_.add_ack_height_to_queueing_threshold = false;
+  }
+  if (config.HasClientRequestedIndependentOption(kB2RP, perspective)) {
+    params_.avoid_unnecessary_probe_rtt = false;
+  }
 }
 
 Limits<QuicByteCount> Bbr2Sender::GetCwndLimitsByMode() const {
@@ -120,7 +125,7 @@
 }
 
 const Limits<QuicByteCount>& Bbr2Sender::cwnd_limits() const {
-  return params_.cwnd_limits;
+  return params().cwnd_limits;
 }
 
 void Bbr2Sender::AdjustNetworkParameters(const NetworkParams& params) {
@@ -197,7 +202,8 @@
   model_.OnCongestionEventFinish(unacked_packets_->GetLeastUnacked(),
                                  congestion_event);
   last_sample_is_app_limited_ = congestion_event.last_sample_is_app_limited;
-  if (avoid_unnecessary_probe_rtt_ && congestion_event.bytes_in_flight == 0) {
+  if (congestion_event.bytes_in_flight == 0 &&
+      params().avoid_unnecessary_probe_rtt) {
     QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_avoid_unnecessary_probe_rtt, 2, 2);
     OnEnterQuiescence(event_time);
   }
@@ -292,7 +298,7 @@
                 << ", total_acked:" << model_.total_bytes_acked()
                 << ", total_lost:" << model_.total_bytes_lost() << "  @ "
                 << sent_time;
-  if (avoid_unnecessary_probe_rtt_ && bytes_in_flight == 0) {
+  if (bytes_in_flight == 0 && params().avoid_unnecessary_probe_rtt) {
     QUIC_RELOADABLE_FLAG_COUNT_N(quic_bbr2_avoid_unnecessary_probe_rtt, 1, 2);
     OnExitQuiescence(sent_time);
   }
@@ -322,7 +328,7 @@
   if (bytes_in_flight >= GetCongestionWindow()) {
     return;
   }
-  if (flexible_app_limited_ && IsPipeSufficientlyFull()) {
+  if (params().flexible_app_limited && IsPipeSufficientlyFull()) {
     return;
   }
 
@@ -367,12 +373,12 @@
   // TODO(b/77975811): If the pipe is highly under-utilized, consider not
   // sending a probing transmission, because the extra bandwidth is not needed.
   // If flexible_app_limited is enabled, check if the pipe is sufficiently full.
-  if (flexible_app_limited_) {
+  if (params().flexible_app_limited) {
     const bool is_pipe_sufficiently_full = IsPipeSufficientlyFull();
     QUIC_DVLOG(3) << this << " CWND: " << GetCongestionWindow()
                   << ", inflight: " << unacked_packets_->bytes_in_flight()
                   << ", pacing_rate: " << PacingRate(0)
-                  << ", flexible_app_limited_: true, ShouldSendProbingPacket: "
+                  << ", flexible_app_limited: true, ShouldSendProbingPacket: "
                   << !is_pipe_sufficiently_full;
     return !is_pipe_sufficiently_full;
   } else {
diff --git a/quic/core/congestion_control/bbr2_sender.h b/quic/core/congestion_control/bbr2_sender.h
index e63b2bd..f865e27 100644
--- a/quic/core/congestion_control/bbr2_sender.h
+++ b/quic/core/congestion_control/bbr2_sender.h
@@ -162,6 +162,8 @@
   // Cwnd limits imposed by caller.
   const Limits<QuicByteCount>& cwnd_limits() const;
 
+  const Bbr2Params& params() const { return params_; }
+
   Bbr2Mode mode_;
 
   const RttStats* const rtt_stats_;
@@ -169,7 +171,9 @@
   QuicRandom* random_;
   QuicConnectionStats* connection_stats_;
 
-  const Bbr2Params params_;
+  // Don't use it directly outside of SetFromConfig. Instead, use params() to
+  // get read-only access.
+  Bbr2Params params_;
 
   Bbr2NetworkModel model_;
 
@@ -186,16 +190,9 @@
   Bbr2ProbeBwMode probe_bw_;
   Bbr2ProbeRttMode probe_rtt_;
 
-  // Indicates app-limited calls should be ignored as long as there's
-  // enough data inflight to see more bandwidth when necessary.
-  bool flexible_app_limited_;
-
   // Debug only.
   bool last_sample_is_app_limited_;
 
-  const bool avoid_unnecessary_probe_rtt_ =
-      GetQuicReloadableFlag(quic_bbr2_avoid_unnecessary_probe_rtt);
-
   friend class Bbr2StartupMode;
   friend class Bbr2DrainMode;
   friend class Bbr2ProbeBwMode;
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h
index 7f8d959..b9ddae9 100644
--- a/quic/core/crypto/crypto_protocol.h
+++ b/quic/core/crypto/crypto_protocol.h
@@ -121,6 +121,10 @@
 const QuicTag kIW20 = TAG('I', 'W', '2', '0');   // Force ICWND to 20
 const QuicTag kIW50 = TAG('I', 'W', '5', '0');   // Force ICWND to 50
 const QuicTag kB2ON = TAG('B', '2', 'O', 'N');   // Enable BBRv2
+const QuicTag kB2NA = TAG('B', '2', 'N', 'A');   // For BBRv2, do not add ack
+                                                 // height to queueing threshold
+const QuicTag kB2RP = TAG('B', '2', 'R', 'P');   // For BBRv2, run PROBE_RTT on
+                                                 // the regular schedule
 const QuicTag kBSAO = TAG('B', 'S', 'A', 'O');   // Avoid Overestimation in
                                                  // Bandwidth Sampler with ack
                                                  // aggregation