gfe-relnote: Notify SendAlgorithm on neutered packets in QUIC. Protected by (enabling blocked) --gfe2_reloadable_flag_quic_avoid_overestimate_bandwidth_with_aggregation.

This is split from cl/279746200 for easier review. I'll unblock this flag in that cl.

PiperOrigin-RevId: 296301871
Change-Id: I499357505e3b817a82b6f4f2172f7b890b684b32
diff --git a/quic/core/congestion_control/bandwidth_sampler.cc b/quic/core/congestion_control/bandwidth_sampler.cc
index 6ecd886..6272664 100644
--- a/quic/core/congestion_control/bandwidth_sampler.cc
+++ b/quic/core/congestion_control/bandwidth_sampler.cc
@@ -73,6 +73,7 @@
     : total_bytes_sent_(0),
       total_bytes_acked_(0),
       total_bytes_lost_(0),
+      total_bytes_neutered_(0),
       total_bytes_sent_at_last_acked_packet_(0),
       last_acked_packet_sent_time_(QuicTime::Zero()),
       last_acked_packet_ack_time_(QuicTime::Zero()),
@@ -147,6 +148,14 @@
                            "in it.";
 }
 
+void BandwidthSampler::OnPacketNeutered(QuicPacketNumber packet_number) {
+  connection_state_map_.Remove(
+      packet_number, [&](const ConnectionStateOnSentPacket& sent_packet) {
+        QUIC_CODE_COUNT(quic_bandwidth_sampler_packet_neutered);
+        total_bytes_neutered_ += sent_packet.size;
+      });
+}
+
 BandwidthSamplerInterface::CongestionEventSample
 BandwidthSampler::OnCongestionEvent(QuicTime ack_time,
                                     const AckedPacketVector& acked_packets,
@@ -390,6 +399,10 @@
   return total_bytes_lost_;
 }
 
+QuicByteCount BandwidthSampler::total_bytes_neutered() const {
+  return total_bytes_neutered_;
+}
+
 bool BandwidthSampler::is_app_limited() const {
   return is_app_limited_;
 }
diff --git a/quic/core/congestion_control/bandwidth_sampler.h b/quic/core/congestion_control/bandwidth_sampler.h
index df63fa5..90b20fc 100644
--- a/quic/core/congestion_control/bandwidth_sampler.h
+++ b/quic/core/congestion_control/bandwidth_sampler.h
@@ -149,6 +149,8 @@
       QuicByteCount bytes_in_flight,
       HasRetransmittableData has_retransmittable_data) = 0;
 
+  virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
+
   // Notifies the sampler that the |packet_number| is acknowledged. Returns a
   // bandwidth sample. If no bandwidth sample is available,
   // QuicBandwidth::Zero() is returned.
@@ -206,10 +208,11 @@
   // Remove all the packets lower than the specified packet number.
   virtual void RemoveObsoletePackets(QuicPacketNumber least_unacked) = 0;
 
-  // Total number of bytes sent/acked/lost in the connection.
+  // Total number of bytes sent/acked/lost/neutered in the connection.
   virtual QuicByteCount total_bytes_sent() const = 0;
   virtual QuicByteCount total_bytes_acked() const = 0;
   virtual QuicByteCount total_bytes_lost() const = 0;
+  virtual QuicByteCount total_bytes_neutered() const = 0;
 
   // Application-limited information exported for debugging.
   virtual bool is_app_limited() const = 0;
@@ -308,6 +311,7 @@
                     QuicByteCount bytes,
                     QuicByteCount bytes_in_flight,
                     HasRetransmittableData has_retransmittable_data) override;
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
   BandwidthSample OnPacketAcknowledged(QuicTime ack_time,
                                        QuicPacketNumber packet_number) override;
   CongestionEventSample OnCongestionEvent(
@@ -329,6 +333,7 @@
   QuicByteCount total_bytes_sent() const override;
   QuicByteCount total_bytes_acked() const override;
   QuicByteCount total_bytes_lost() const override;
+  QuicByteCount total_bytes_neutered() const override;
 
   bool is_app_limited() const override;
 
@@ -432,6 +437,9 @@
   // The total number of congestion controlled bytes which were lost.
   QuicByteCount total_bytes_lost_;
 
+  // The total number of congestion controlled bytes which have been neutered.
+  QuicByteCount total_bytes_neutered_;
+
   // The value of |total_bytes_sent_| at the time the last acknowledged packet
   // was sent. Valid only when |last_acked_packet_sent_time_| is valid.
   QuicByteCount total_bytes_sent_at_last_acked_packet_;
diff --git a/quic/core/congestion_control/bandwidth_sampler_test.cc b/quic/core/congestion_control/bandwidth_sampler_test.cc
index 9a3c456..13fa1c0 100644
--- a/quic/core/congestion_control/bandwidth_sampler_test.cc
+++ b/quic/core/congestion_control/bandwidth_sampler_test.cc
@@ -566,16 +566,39 @@
   EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
 }
 
+TEST_F(BandwidthSamplerTest, NeuterPacket) {
+  SendPacket(1);
+  EXPECT_EQ(0u, sampler_.total_bytes_neutered());
+
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  sampler_.OnPacketNeutered(QuicPacketNumber(1));
+  EXPECT_LT(0u, sampler_.total_bytes_neutered());
+  EXPECT_EQ(0u, sampler_.total_bytes_acked());
+
+  // If packet 1 is acked it should not produce a bandwidth sample.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
+  BandwidthSampler::CongestionEventSample sample = sampler_.OnCongestionEvent(
+      clock_.Now(),
+      {AckedPacket(QuicPacketNumber(1), kRegularPacketSize, clock_.Now())}, {},
+      max_bandwidth_, est_bandwidth_upper_bound_, round_trip_count_);
+  EXPECT_EQ(0u, sampler_.total_bytes_acked());
+  EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
+  EXPECT_FALSE(sample.sample_is_app_limited);
+  EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
+  EXPECT_EQ(0u, sample.sample_max_inflight);
+  EXPECT_EQ(0u, sample.extra_acked);
+}
+
 TEST_F(BandwidthSamplerTest, CongestionEventSampleDefaultValues) {
   // Make sure a default constructed CongestionEventSample has the correct
   // initial values for BandwidthSampler::OnCongestionEvent() to work.
   BandwidthSampler::CongestionEventSample sample;
 
-  DCHECK_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
-  DCHECK(!sample.sample_is_app_limited);
-  DCHECK_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
-  DCHECK_EQ(0u, sample.sample_max_inflight);
-  DCHECK_EQ(0u, sample.extra_acked);
+  EXPECT_EQ(QuicBandwidth::Zero(), sample.sample_max_bandwidth);
+  EXPECT_FALSE(sample.sample_is_app_limited);
+  EXPECT_EQ(QuicTime::Delta::Infinite(), sample.sample_rtt);
+  EXPECT_EQ(0u, sample.sample_max_inflight);
+  EXPECT_EQ(0u, sample.extra_acked);
 }
 
 // 1) Send 2 packets, 2) Ack both in 1 event, 3) Repeat.
diff --git a/quic/core/congestion_control/bbr2_misc.h b/quic/core/congestion_control/bbr2_misc.h
index 1d6fb35..2226566 100644
--- a/quic/core/congestion_control/bbr2_misc.h
+++ b/quic/core/congestion_control/bbr2_misc.h
@@ -359,6 +359,10 @@
     return bandwidth_sampler_.max_ack_height();
   }
 
+  void OnPacketNeutered(QuicPacketNumber packet_number) {
+    bandwidth_sampler_.OnPacketNeutered(packet_number);
+  }
+
   uint64_t num_ack_aggregation_epochs() const {
     return bandwidth_sampler_.num_ack_aggregation_epochs();
   }
diff --git a/quic/core/congestion_control/bbr2_sender.cc b/quic/core/congestion_control/bbr2_sender.cc
index d795ad1..108cb34 100644
--- a/quic/core/congestion_control/bbr2_sender.cc
+++ b/quic/core/congestion_control/bbr2_sender.cc
@@ -284,6 +284,10 @@
                       is_retransmittable);
 }
 
+void Bbr2Sender::OnPacketNeutered(QuicPacketNumber packet_number) {
+  model_.OnPacketNeutered(packet_number);
+}
+
 bool Bbr2Sender::CanSend(QuicByteCount bytes_in_flight) {
   const bool result = bytes_in_flight < GetCongestionWindow();
   return result;
diff --git a/quic/core/congestion_control/bbr2_sender.h b/quic/core/congestion_control/bbr2_sender.h
index 2bba285..64b6fcb 100644
--- a/quic/core/congestion_control/bbr2_sender.h
+++ b/quic/core/congestion_control/bbr2_sender.h
@@ -64,6 +64,8 @@
                     QuicByteCount bytes,
                     HasRetransmittableData is_retransmittable) override;
 
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
+
   void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
 
   void OnConnectionMigration() override {}
diff --git a/quic/core/congestion_control/bbr_sender.cc b/quic/core/congestion_control/bbr_sender.cc
index 3fd6139..da723c4 100644
--- a/quic/core/congestion_control/bbr_sender.cc
+++ b/quic/core/congestion_control/bbr_sender.cc
@@ -181,6 +181,10 @@
                         is_retransmittable);
 }
 
+void BbrSender::OnPacketNeutered(QuicPacketNumber packet_number) {
+  sampler_.OnPacketNeutered(packet_number);
+}
+
 bool BbrSender::CanSend(QuicByteCount bytes_in_flight) {
   return bytes_in_flight < GetCongestionWindow();
 }
diff --git a/quic/core/congestion_control/bbr_sender.h b/quic/core/congestion_control/bbr_sender.h
index 87d3272..a58b8d5 100644
--- a/quic/core/congestion_control/bbr_sender.h
+++ b/quic/core/congestion_control/bbr_sender.h
@@ -118,6 +118,7 @@
                     QuicPacketNumber packet_number,
                     QuicByteCount bytes,
                     HasRetransmittableData is_retransmittable) override;
+  void OnPacketNeutered(QuicPacketNumber packet_number) override;
   void OnRetransmissionTimeout(bool /*packets_retransmitted*/) override {}
   void OnConnectionMigration() override {}
   bool CanSend(QuicByteCount bytes_in_flight) override;
diff --git a/quic/core/congestion_control/send_algorithm_interface.h b/quic/core/congestion_control/send_algorithm_interface.h
index a049e67..b242951 100644
--- a/quic/core/congestion_control/send_algorithm_interface.h
+++ b/quic/core/congestion_control/send_algorithm_interface.h
@@ -110,6 +110,9 @@
                             QuicByteCount bytes,
                             HasRetransmittableData is_retransmittable) = 0;
 
+  // Inform that |packet_number| has been neutered.
+  virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
+
   // Called when the retransmission timeout fires.  Neither OnPacketAbandoned
   // nor OnPacketLost will be called for these packets.
   virtual void OnRetransmissionTimeout(bool packets_retransmitted) = 0;
diff --git a/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index 9144b8a..7a36f76 100644
--- a/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -61,6 +61,7 @@
                     QuicPacketNumber packet_number,
                     QuicByteCount bytes,
                     HasRetransmittableData is_retransmittable) override;
+  void OnPacketNeutered(QuicPacketNumber /*packet_number*/) override {}
   void OnRetransmissionTimeout(bool packets_retransmitted) override;
   bool CanSend(QuicByteCount bytes_in_flight) override;
   QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override;