Add ECN support to SendAlgorithmInterface.

PiperOrigin-RevId: 518275643
diff --git a/quiche/quic/core/congestion_control/bbr2_sender.cc b/quiche/quic/core/congestion_control/bbr2_sender.cc
index 4df888b..6f884d8 100644
--- a/quiche/quic/core/congestion_control/bbr2_sender.cc
+++ b/quiche/quic/core/congestion_control/bbr2_sender.cc
@@ -277,7 +277,9 @@
                                    QuicByteCount prior_in_flight,
                                    QuicTime event_time,
                                    const AckedPacketVector& acked_packets,
-                                   const LostPacketVector& lost_packets) {
+                                   const LostPacketVector& lost_packets,
+                                   QuicPacketCount /*num_ect*/,
+                                   QuicPacketCount /*num_ce*/) {
   QUIC_DVLOG(3) << this
                 << " OnCongestionEvent. prior_in_flight:" << prior_in_flight
                 << " prior_cwnd:" << cwnd_ << "  @ " << event_time;
diff --git a/quiche/quic/core/congestion_control/bbr2_sender.h b/quiche/quic/core/congestion_control/bbr2_sender.h
index 7f47a4e..171028a 100644
--- a/quiche/quic/core/congestion_control/bbr2_sender.h
+++ b/quiche/quic/core/congestion_control/bbr2_sender.h
@@ -55,7 +55,9 @@
   void OnCongestionEvent(bool rtt_updated, QuicByteCount prior_in_flight,
                          QuicTime event_time,
                          const AckedPacketVector& acked_packets,
-                         const LostPacketVector& lost_packets) override;
+                         const LostPacketVector& lost_packets,
+                         QuicPacketCount num_ect,
+                         QuicPacketCount num_ce) override;
 
   void OnPacketSent(QuicTime sent_time, QuicByteCount bytes_in_flight,
                     QuicPacketNumber packet_number, QuicByteCount bytes,
@@ -92,6 +94,9 @@
   void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
 
   void PopulateConnectionStats(QuicConnectionStats* stats) const override;
+
+  bool SupportsECT0() const override { return false; }
+  bool SupportsECT1() const override { return false; }
   // End implementation of SendAlgorithmInterface.
 
   const Bbr2Params& Params() const { return params_; }
diff --git a/quiche/quic/core/congestion_control/bbr2_simulator_test.cc b/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
index f08805f..d65adfe 100644
--- a/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
+++ b/quiche/quic/core/congestion_control/bbr2_simulator_test.cc
@@ -1771,7 +1771,7 @@
   auto next_packet_number = sender_unacked_map()->largest_sent_packet() + 1;
   sender_->OnCongestionEvent(
       /*rtt_updated=*/true, sender_unacked_map()->bytes_in_flight(), now,
-      acked_packets, {});
+      acked_packets, {}, 0, 0);
   ASSERT_EQ(CyclePhase::PROBE_REFILL,
             sender_->ExportDebugState().probe_bw.phase);
 
@@ -1781,7 +1781,8 @@
   now = now + params.RTT();
   sender_->OnCongestionEvent(
       /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
-      {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)}, {});
+      {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)}, {}, 0,
+      0);
   ASSERT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
 
   // Send 2 packets and lose the first one(50% loss) to exit PROBE_UP.
@@ -1794,7 +1795,7 @@
   sender_->OnCongestionEvent(
       /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
       {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)},
-      {LostPacket(next_packet_number - 2, kDefaultMaxPacketSize)});
+      {LostPacket(next_packet_number - 2, kDefaultMaxPacketSize)}, 0, 0);
 
   QuicByteCount inflight_hi = sender_->ExportDebugState().inflight_hi;
   EXPECT_LT(2 * kDefaultMaxPacketSize, inflight_hi);
@@ -1832,7 +1833,7 @@
 
   QuicTime now = simulator_.GetClock()->Now() + params.RTT() * 0.25;
   sender_->OnCongestionEvent(false, sender_unacked_map()->bytes_in_flight(),
-                             now, {}, lost_packets);
+                             now, {}, lost_packets, 0, 0);
 
   // Bandwidth estimate should not change for the loss only event.
   EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
@@ -1960,7 +1961,7 @@
       AckedPacket(QuicPacketNumber(2), /*bytes_acked=*/0, QuicTime::Zero()),
   };
   now = now + QuicTime::Delta::FromMilliseconds(2000);
-  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {}, 0, 0);
 
   // Send 30-41.
   while (next_packet_number < QuicPacketNumber(42)) {
@@ -1975,7 +1976,7 @@
       AckedPacket(QuicPacketNumber(3), /*bytes_acked=*/0, QuicTime::Zero()),
   };
   now = now + QuicTime::Delta::FromMilliseconds(2000);
-  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {}, 0, 0);
 
   // Send 42.
   now = now + QuicTime::Delta::FromMilliseconds(10);
@@ -1991,7 +1992,7 @@
       AckedPacket(QuicPacketNumber(7), /*bytes_acked=*/1350, QuicTime::Zero()),
   };
   now = now + QuicTime::Delta::FromMilliseconds(2000);
-  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {});
+  sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {}, 0, 0);
   EXPECT_FALSE(sender_->BandwidthEstimate().IsZero());
 }
 
diff --git a/quiche/quic/core/congestion_control/bbr_sender.cc b/quiche/quic/core/congestion_control/bbr_sender.cc
index 7abba24..322e7aa 100644
--- a/quiche/quic/core/congestion_control/bbr_sender.cc
+++ b/quiche/quic/core/congestion_control/bbr_sender.cc
@@ -327,7 +327,9 @@
                                   QuicByteCount prior_in_flight,
                                   QuicTime event_time,
                                   const AckedPacketVector& acked_packets,
-                                  const LostPacketVector& lost_packets) {
+                                  const LostPacketVector& lost_packets,
+                                  QuicPacketCount /*num_ect*/,
+                                  QuicPacketCount /*num_ce*/) {
   const QuicByteCount total_bytes_acked_before = sampler_.total_bytes_acked();
   const QuicByteCount total_bytes_lost_before = sampler_.total_bytes_lost();
 
diff --git a/quiche/quic/core/congestion_control/bbr_sender.h b/quiche/quic/core/congestion_control/bbr_sender.h
index 5f711fd..1504004 100644
--- a/quiche/quic/core/congestion_control/bbr_sender.h
+++ b/quiche/quic/core/congestion_control/bbr_sender.h
@@ -111,7 +111,9 @@
   void OnCongestionEvent(bool rtt_updated, QuicByteCount prior_in_flight,
                          QuicTime event_time,
                          const AckedPacketVector& acked_packets,
-                         const LostPacketVector& lost_packets) override;
+                         const LostPacketVector& lost_packets,
+                         QuicPacketCount num_ect,
+                         QuicPacketCount num_ce) override;
   void OnPacketSent(QuicTime sent_time, QuicByteCount bytes_in_flight,
                     QuicPacketNumber packet_number, QuicByteCount bytes,
                     HasRetransmittableData is_retransmittable) override;
@@ -130,6 +132,8 @@
   std::string GetDebugState() const override;
   void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
   void PopulateConnectionStats(QuicConnectionStats* stats) const override;
+  bool SupportsECT0() const override { return false; }
+  bool SupportsECT1() const override { return false; }
   // End implementation of SendAlgorithmInterface.
 
   // Gets the number of RTTs BBR remains in STARTUP phase.
diff --git a/quiche/quic/core/congestion_control/bbr_sender_test.cc b/quiche/quic/core/congestion_control/bbr_sender_test.cc
index fdd401b..696e364 100644
--- a/quiche/quic/core/congestion_control/bbr_sender_test.cc
+++ b/quiche/quic/core/congestion_control/bbr_sender_test.cc
@@ -402,7 +402,7 @@
   LostPacketVector lost_packets;
   lost_packets.emplace_back(least_inflight, least_inflight_packet_size);
   sender_->OnCongestionEvent(false, prior_inflight, clock_->Now(), {},
-                             lost_packets);
+                             lost_packets, 0, 0);
   EXPECT_EQ(sender_->ExportDebugState().recovery_window,
             prior_inflight - least_inflight_packet_size);
   EXPECT_LT(sender_->ExportDebugState().recovery_window, prior_recovery_window);
@@ -1300,7 +1300,7 @@
 
   QuicTime now = simulator_.GetClock()->Now() + kTestRtt * 0.25;
   sender_->OnCongestionEvent(false, unacked_packets->bytes_in_flight(), now, {},
-                             lost_packets);
+                             lost_packets, 0, 0);
 
   // Bandwidth estimate should not change for the loss only event.
   EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
diff --git a/quiche/quic/core/congestion_control/pacing_sender.cc b/quiche/quic/core/congestion_control/pacing_sender.cc
index 46ba8a1..b4b6105 100644
--- a/quiche/quic/core/congestion_control/pacing_sender.cc
+++ b/quiche/quic/core/congestion_control/pacing_sender.cc
@@ -39,14 +39,16 @@
                                      QuicByteCount bytes_in_flight,
                                      QuicTime event_time,
                                      const AckedPacketVector& acked_packets,
-                                     const LostPacketVector& lost_packets) {
+                                     const LostPacketVector& lost_packets,
+                                     QuicPacketCount num_ect,
+                                     QuicPacketCount num_ce) {
   QUICHE_DCHECK(sender_ != nullptr);
   if (!lost_packets.empty()) {
     // Clear any burst tokens when entering recovery.
     burst_tokens_ = 0;
   }
   sender_->OnCongestionEvent(rtt_updated, bytes_in_flight, event_time,
-                             acked_packets, lost_packets);
+                             acked_packets, lost_packets, num_ect, num_ce);
 }
 
 void PacingSender::OnPacketSent(
diff --git a/quiche/quic/core/congestion_control/pacing_sender.h b/quiche/quic/core/congestion_control/pacing_sender.h
index 94cbfaa..0e3de00 100644
--- a/quiche/quic/core/congestion_control/pacing_sender.h
+++ b/quiche/quic/core/congestion_control/pacing_sender.h
@@ -53,7 +53,8 @@
   void OnCongestionEvent(bool rtt_updated, QuicByteCount bytes_in_flight,
                          QuicTime event_time,
                          const AckedPacketVector& acked_packets,
-                         const LostPacketVector& lost_packets);
+                         const LostPacketVector& lost_packets,
+                         QuicPacketCount num_ect, QuicPacketCount num_ce);
 
   void OnPacketSent(QuicTime sent_time, QuicByteCount bytes_in_flight,
                     QuicPacketNumber packet_number, QuicByteCount bytes,
diff --git a/quiche/quic/core/congestion_control/pacing_sender_test.cc b/quiche/quic/core/congestion_control/pacing_sender_test.cc
index 7206b4c..108b12e 100644
--- a/quiche/quic/core/congestion_control/pacing_sender_test.cc
+++ b/quiche/quic/core/congestion_control/pacing_sender_test.cc
@@ -60,13 +60,13 @@
     EXPECT_CALL(*mock_sender_, BandwidthEstimate())
         .WillRepeatedly(Return(bandwidth));
     if (burst_size == 0) {
-      EXPECT_CALL(*mock_sender_, OnCongestionEvent(_, _, _, _, _));
+      EXPECT_CALL(*mock_sender_, OnCongestionEvent(_, _, _, _, _, _, _));
       LostPacketVector lost_packets;
       lost_packets.push_back(
           LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
       AckedPacketVector empty;
       pacing_sender_->OnCongestionEvent(true, 1234, clock_.Now(), empty,
-                                        lost_packets);
+                                        lost_packets, 0, 0);
     } else if (burst_size != kInitialBurstPackets) {
       QUIC_LOG(FATAL) << "Unsupported burst_size " << burst_size
                       << " specificied, only 0 and " << kInitialBurstPackets
@@ -126,11 +126,11 @@
 
   void UpdateRtt() {
     EXPECT_CALL(*mock_sender_,
-                OnCongestionEvent(true, kBytesInFlight, _, _, _));
+                OnCongestionEvent(true, kBytesInFlight, _, _, _, _, _));
     AckedPacketVector empty_acked;
     LostPacketVector empty_lost;
     pacing_sender_->OnCongestionEvent(true, kBytesInFlight, clock_.Now(),
-                                      empty_acked, empty_lost);
+                                      empty_acked, empty_lost, 0, 0);
   }
 
   void OnApplicationLimited() { pacing_sender_->OnApplicationLimited(); }
@@ -340,9 +340,9 @@
       LostPacket(QuicPacketNumber(1), kMaxOutgoingPacketSize));
   AckedPacketVector empty_acked;
   EXPECT_CALL(*mock_sender_, OnCongestionEvent(true, kMaxOutgoingPacketSize, _,
-                                               testing::IsEmpty(), _));
+                                               testing::IsEmpty(), _, _, _));
   pacing_sender_->OnCongestionEvent(true, kMaxOutgoingPacketSize, clock_.Now(),
-                                    empty_acked, lost_packets);
+                                    empty_acked, lost_packets, 0, 0);
   // One packet is sent immediately, because of 1ms pacing granularity.
   CheckPacketIsSentImmediately();
   // Ensure packets are immediately paced.
diff --git a/quiche/quic/core/congestion_control/send_algorithm_interface.h b/quiche/quic/core/congestion_control/send_algorithm_interface.h
index db14a1e..e5e8d58 100644
--- a/quiche/quic/core/congestion_control/send_algorithm_interface.h
+++ b/quiche/quic/core/congestion_control/send_algorithm_interface.h
@@ -79,11 +79,18 @@
   // latest_rtt sample has been taken, |prior_in_flight| the bytes in flight
   // prior to the congestion event.  |acked_packets| and |lost_packets| are any
   // packets considered acked or lost as a result of the congestion event.
+  // |num_ect| and |num_ce| indicate the number of newly acknowledged packets
+  // for which the receiver reported the Explicit Congestion Notification (ECN)
+  // bits were set to ECT(1) or CE, respectively. A sender will not use ECT(0).
+  // If QUIC determines the peer's feedback is invalid, it will send zero in
+  // these fields.
   virtual void OnCongestionEvent(bool rtt_updated,
                                  QuicByteCount prior_in_flight,
                                  QuicTime event_time,
                                  const AckedPacketVector& acked_packets,
-                                 const LostPacketVector& lost_packets) = 0;
+                                 const LostPacketVector& lost_packets,
+                                 QuicPacketCount num_ect,
+                                 QuicPacketCount num_ce) = 0;
 
   // Inform that we sent |bytes| to the wire, and if the packet is
   // retransmittable.  |bytes_in_flight| is the number of bytes in flight before
@@ -160,6 +167,11 @@
 
   // Called before connection close to collect stats.
   virtual void PopulateConnectionStats(QuicConnectionStats* stats) const = 0;
+
+  // Returns true if the algorithm will respond to Congestion Experienced (CE)
+  // indications in accordance with RFC3168 [ECT(0)] or RFC9331 [ECT(1)].
+  virtual bool SupportsECT0() const = 0;
+  virtual bool SupportsECT1() const = 0;
 };
 
 }  // namespace quic
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
index bc61d87..610bce7 100644
--- a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -91,7 +91,8 @@
 void TcpCubicSenderBytes::OnCongestionEvent(
     bool rtt_updated, QuicByteCount prior_in_flight, QuicTime event_time,
     const AckedPacketVector& acked_packets,
-    const LostPacketVector& lost_packets) {
+    const LostPacketVector& lost_packets, QuicPacketCount /*num_ect*/,
+    QuicPacketCount /*num_ce*/) {
   if (rtt_updated && InSlowStart() &&
       hybrid_slow_start_.ShouldExitSlowStart(
           rtt_stats_->latest_rtt(), rtt_stats_->min_rtt(),
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index 2531e5a..184357d 100644
--- a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -54,7 +54,9 @@
   void OnCongestionEvent(bool rtt_updated, QuicByteCount prior_in_flight,
                          QuicTime event_time,
                          const AckedPacketVector& acked_packets,
-                         const LostPacketVector& lost_packets) override;
+                         const LostPacketVector& lost_packets,
+                         QuicPacketCount num_ect,
+                         QuicPacketCount num_ce) override;
   void OnPacketSent(QuicTime sent_time, QuicByteCount bytes_in_flight,
                     QuicPacketNumber packet_number, QuicByteCount bytes,
                     HasRetransmittableData is_retransmittable) override;
@@ -72,6 +74,8 @@
   std::string GetDebugState() const override;
   void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
   void PopulateConnectionStats(QuicConnectionStats* /*stats*/) const override {}
+  bool SupportsECT0() const override { return false; }
+  bool SupportsECT1() const override { return false; }
   // End implementation of SendAlgorithmInterface.
 
   QuicByteCount min_congestion_window() const { return min_congestion_window_; }
diff --git a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
index 3ac1ba2..919233a 100644
--- a/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
+++ b/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -89,7 +89,7 @@
                       QuicTime::Zero()));
     }
     sender_->OnCongestionEvent(true, bytes_in_flight_, clock_.Now(),
-                               acked_packets, lost_packets);
+                               acked_packets, lost_packets, 0, 0);
     bytes_in_flight_ -= n * kDefaultTCPMSS;
     clock_.AdvanceTime(one_ms_);
   }
@@ -105,7 +105,7 @@
           LostPacket(QuicPacketNumber(acked_packet_number_), packet_length));
     }
     sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
-                               acked_packets, lost_packets);
+                               acked_packets, lost_packets, 0, 0);
     bytes_in_flight_ -= n * packet_length;
   }
 
@@ -116,7 +116,7 @@
     lost_packets.push_back(
         LostPacket(QuicPacketNumber(packet_number), kDefaultTCPMSS));
     sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
-                               acked_packets, lost_packets);
+                               acked_packets, lost_packets, 0, 0);
     bytes_in_flight_ -= kDefaultTCPMSS;
   }
 
@@ -793,7 +793,7 @@
     acked_packets.push_back(
         AckedPacket(QuicPacketNumber(i), 1350, QuicTime::Zero()));
     sender->OnCongestionEvent(true, sender->GetCongestionWindow(), clock_.Now(),
-                              acked_packets, missing_packets);
+                              acked_packets, missing_packets, 0, 0);
   }
   EXPECT_EQ(max_congestion_window,
             sender->GetCongestionWindow() / kDefaultTCPMSS);
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index d3ff120..27cf706 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -1551,7 +1551,7 @@
 
     connection_.SendCryptoStreamData();
     EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
     QuicAckFrame frame = InitAckFrame(1);
     // Received ACK for packet 1.
     ProcessFramePacketAtLevel(1, QuicFrame(&frame), ENCRYPTION_INITIAL);
@@ -1953,7 +1953,7 @@
   // Receiving an ACK to the packet sent after changing peer address doesn't
   // finish migration validation.
   QuicAckFrame ack_frame = InitAckFrame(2);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
                                   kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
   EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
@@ -2130,7 +2130,7 @@
     // we need to make sure a new migration does not start after the previous
     // one is completed.
     QuicAckFrame ack_frame = InitAckFrame(1);
-    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
     ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
                                     kNewPeerAddress, ENCRYPTION_FORWARD_SECURE);
     EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
@@ -2225,7 +2225,7 @@
   const QuicSocketAddress kPeerAddress3 =
       QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/56789);
   auto ack_frame = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
   ProcessFramesPacketWithAddresses({QuicFrame(&ack_frame)}, kSelfAddress,
                                    kPeerAddress3, ENCRYPTION_FORWARD_SECURE);
@@ -3129,7 +3129,7 @@
 
   connection_.SendCryptoStreamData();
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame = InitAckFrame(1);
   // Received ACK for packet 1.
   ProcessFramePacketAtLevel(1, QuicFrame(&frame), ENCRYPTION_INITIAL);
@@ -3413,7 +3413,7 @@
   // awaiting' is 4.  The connection should then realize 1 will not be
   // retransmitted, and will remove it from the missing list.
   QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   ProcessAckPacket(6, &frame);
 
   // Force an ack to be sent.
@@ -3467,7 +3467,7 @@
 
   QuicAckFrame ack1 = InitAckFrame(1);
   QuicAckFrame ack2 = InitAckFrame(2);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   if (connection_.SupportsMultiplePacketNumberSpaces()) {
     EXPECT_CALL(visitor_, OnOneRttPacketAcknowledged()).Times(1);
   }
@@ -3498,7 +3498,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
                       Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicPacketNumber retransmission;
   // Packet 1 is short header for IETF QUIC because the encryption level
   // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
@@ -3513,7 +3513,7 @@
   ProcessAckPacket(&frame);
 
   QuicAckFrame frame2 = ConstructAckFrame(retransmission, original);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
   ProcessAckPacket(&frame2);
 
@@ -3760,7 +3760,7 @@
   SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
   SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);
   SendStreamDataToPeer(1, "eep", 6, NO_FIN, nullptr);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
 
   // Start out saying the largest observed is 2.
   QuicAckFrame frame1 = InitAckFrame(1);
@@ -3824,7 +3824,7 @@
     EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
   }
 
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
 
   // Peer acks up to packet 3.
   QuicAckFrame frame = InitAckFrame(3);
@@ -3840,7 +3840,7 @@
     EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
   }
 
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
 
   // Peer acks up to packet 4, the last packet.
   QuicAckFrame frame2 = InitAckFrame(6);
@@ -4281,7 +4281,7 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   // Don't lose a packet on an ack, and nothing is retransmitted.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame ack_one = InitAckFrame(1);
   ProcessAckPacket(&ack_one);
 
@@ -4293,7 +4293,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
                       Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   EXPECT_FALSE(QuicPacketCreatorPeer::SendVersionInPacket(creator_));
   ProcessAckPacket(&nack_two);
@@ -4353,7 +4353,7 @@
   QuicAckFrame nack_two = ConstructAckFrame(last_packet, last_packet - 1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   ProcessAckPacket(&nack_two);
 }
@@ -4376,7 +4376,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
                       Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(1));
   ProcessAckPacket(&nack_two);
 }
@@ -4416,7 +4416,7 @@
   QuicAckFrame nack_stream_data =
       ConstructAckFrame(rst_packet, last_data_packet);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   ProcessAckPacket(&nack_stream_data);
 
@@ -4455,7 +4455,7 @@
   QuicAckFrame ack = ConstructAckFrame(last_packet, last_packet - 1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   ProcessAckPacket(&ack);
 
@@ -4488,7 +4488,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
                       Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   ProcessAckPacket(&ack);
 
@@ -4528,7 +4528,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
                       Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
       .Times(1);
   ProcessAckPacket(&nack_two);
@@ -4536,7 +4536,7 @@
 
   // Now, ack the previous transmission.
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _, _, _));
   QuicAckFrame ack_all = InitAckFrame(3);
   ProcessAckPacket(&ack_all);
 
@@ -4566,7 +4566,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
                       Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   // Packet 1 is short header for IETF QUIC because the encryption level
   // switched to ENCRYPTION_FORWARD_SECURE in SendStreamDataToPeer.
   EXPECT_CALL(*send_algorithm_,
@@ -4626,7 +4626,7 @@
   // Ack the sent packet before the callback returns, which happens in
   // rare circumstances with write blocked sockets.
   QuicAckFrame ack = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&ack);
 
   writer_->SetWritable();
@@ -4689,7 +4689,7 @@
 
   // Process an ACK, make sure the connection calls visitor_->OnWriteBlocked().
   QuicAckFrame ack1 = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
   ProcessAckPacket(1, &ack1);
 }
@@ -4753,7 +4753,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
                       Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   ProcessAckPacket(&nack);
 }
@@ -4781,12 +4781,12 @@
   EXPECT_EQ(QuicPacketNumber(6u), last_packet);
 
   // Client will ack packets 1, 2, [!3], 4, 5.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame1 = ConstructAckFrame(5, 3);
   ProcessAckPacket(&frame1);
 
   // Now the client implicitly acks 3, and explicitly acks 6.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame2 = InitAckFrame(6);
   ProcessAckPacket(&frame2);
 }
@@ -4803,7 +4803,7 @@
   // From now on, we send acks, so the send algorithm won't mark them pending.
   SendAckPacketToPeer();  // Packet 2
 
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame = InitAckFrame(1);
   ProcessAckPacket(&frame);
 
@@ -4812,7 +4812,7 @@
 
   EXPECT_EQ(QuicPacketNumber(2u), stop_waiting()->least_unacked);
 
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   frame = InitAckFrame(2);
   ProcessAckPacket(&frame);
   EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
@@ -4832,7 +4832,7 @@
   }
 
   // Ack the ack, which updates the rtt and raises the least unacked.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   frame = InitAckFrame(3);
   ProcessAckPacket(&frame);
 
@@ -4851,7 +4851,7 @@
   SendStreamDataToPeer(1, "bar", 6, NO_FIN, nullptr);  // Packet 6
   SendStreamDataToPeer(1, "bar", 9, NO_FIN, nullptr);  // Packet 7
 
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   frame = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
                         {QuicPacketNumber(7), QuicPacketNumber(8)}});
   ProcessAckPacket(&frame);
@@ -5184,7 +5184,7 @@
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(3));
   QuicAckFrame frame = InitAckFrame(1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&frame);
 
   EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
@@ -5232,7 +5232,7 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   QuicAckFrame frame = InitAckFrame(1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
   // The ping timer is set slightly less than 15 seconds in the future, because
@@ -5285,7 +5285,7 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   QuicAckFrame frame = InitAckFrame(1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
   // The ping timer is set slightly less than 10 seconds in the future, because
@@ -5338,7 +5338,7 @@
 
   // Acknowledge all packets so far.
   QuicAckFrame probe_ack = InitAckFrame(3);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&probe_ack);
   EXPECT_EQ(new_mtu, connection_.max_packet_length());
 
@@ -5415,7 +5415,7 @@
 
   // Acknowledge all packets sent so far.
   QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _))
       .Times(AnyNumber());
   ProcessAckPacket(&probe_ack);
   EXPECT_EQ(probe_size, connection_.max_packet_length());
@@ -5513,7 +5513,7 @@
 
   // Acknowledge all packets sent so far.
   QuicAckFrame probe_ack = InitAckFrame(probe_packet_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _))
       .Times(AnyNumber());
   ProcessAckPacket(&probe_ack);
   EXPECT_EQ(probe_size, connection_.max_packet_length());
@@ -5608,7 +5608,7 @@
       packets_between_probes_base * (1 << (kMtuDiscoveryAttempts + 1));
   std::vector<QuicPacketNumber> mtu_discovery_packets;
   // Called on many acks.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _))
       .Times(AnyNumber());
   for (QuicPacketCount i = 0; i < number_of_packets; i++) {
     SendStreamDataToPeer(3, "!", i, NO_FIN, nullptr);
@@ -5698,7 +5698,7 @@
 
   // Acknowledge all packets sent so far.
   QuicAckFrame first_ack = InitAckFrame(probe_packet_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _))
       .Times(AnyNumber());
   ProcessAckPacket(&first_ack);
   EXPECT_EQ(probe_size, connection_.max_packet_length());
@@ -5809,7 +5809,7 @@
 
   // Acknowledge all packets sent so far.
   QuicAckFrame probe_ack = InitAckFrame(probe_sequence_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _))
       .Times(AnyNumber());
   ProcessAckPacket(&probe_ack);
   EXPECT_EQ(probe_size, connection_.max_packet_length());
@@ -5890,7 +5890,7 @@
   // Acknowledge all packets sent so far, except for the lost probe.
   QuicAckFrame probe_ack =
       ConstructAckFrame(creator_->packet_number(), probe_number);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&probe_ack);
   EXPECT_EQ(initial_mtu, connection_.max_packet_length());
 
@@ -6147,7 +6147,7 @@
   // When we receive a packet, the timeout will change to 5ms +
   // kInitialIdleTimeoutSecs.
   QuicAckFrame ack = InitAckFrame(2);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&ack);
 
   // The original alarm will fire.  We should not time out because we had a
@@ -6203,7 +6203,7 @@
   // When we receive a packet, the timeout will change to 5ms +
   // kInitialIdleTimeoutSecs.
   QuicAckFrame ack = InitAckFrame(2);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&ack);
 
   // The original alarm will fire.  We should not time out because we had a
@@ -6787,7 +6787,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(DoAll(SetArgPointee<5>(lost_packets),
                       Return(LossDetectionInterface::DetectionStats())));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&ack);
   size_t padding_frame_count = writer_->padding_frames().size();
   EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count());
@@ -6798,7 +6798,7 @@
   // and see if there is more data to send.
   ack = ConstructAckFrame(3, 1);
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(&ack);
 
   // Check that no packet is sent and the ack alarm isn't set.
@@ -7347,7 +7347,7 @@
   // Process an ack and the send alarm will be set to the new 5ms delay.
   QuicAckFrame ack = InitAckFrame(1);
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
   ProcessAckPacket(&ack);
   size_t padding_frame_count = writer_->padding_frames().size();
@@ -7501,7 +7501,7 @@
     if (i == 0) {
       EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
     }
-    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
     QuicAckFrame frame = InitAckFrame(
         {{QuicPacketNumber(1u + 2u * i), QuicPacketNumber(2u + 2u * i)}});
     ProcessAckPacket(&frame);
@@ -7517,7 +7517,7 @@
       // retransmittable packets on the wire, this should cancel the path
       // degrading detection.
       clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-      EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+      EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
       frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
       ProcessAckPacket(&frame);
       EXPECT_FALSE(connection_.PathDegradingDetectionInProgress());
@@ -7576,7 +7576,7 @@
   // Now receive an ACK of the packet.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
@@ -7630,7 +7630,7 @@
 
   // Now receive an ACK of the packet.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(2, &frame);
@@ -7666,7 +7666,7 @@
   connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
   // Receive an ACK after 1-RTT.
   clock_.AdvanceTime(kTestRtt);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
@@ -7711,7 +7711,7 @@
   connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
   // Receive an ACK after 1-RTT.
   clock_.AdvanceTime(kTestRtt);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
@@ -7760,7 +7760,7 @@
   connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
   // Receive an ACK after 1-RTT.
   clock_.AdvanceTime(kTestRtt);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
@@ -7820,7 +7820,7 @@
   // degrading detection's deadline since forward progress has been made.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
   ProcessAckPacket(&frame);
@@ -7906,7 +7906,7 @@
   // degrading alarm's deadline since forward progress has been made.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
   ProcessAckPacket(&frame);
@@ -7937,7 +7937,7 @@
   // Now receive an ACK of the second packet. This should unmark the path as
   // degrading. And will set a timer to detect new path degrading.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(visitor_, OnForwardProgressMadeAfterPathDegrading()).Times(1);
   frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   ProcessAckPacket(&frame);
@@ -7963,7 +7963,7 @@
 
   // Ack data.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
   ProcessAckPacket(&frame);
@@ -8320,7 +8320,7 @@
   // retransmittable-on-wire alarm since packet 2 is still on the wire.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
@@ -8337,7 +8337,7 @@
   // retransmittable-on-wire alarm now that no retransmittable packets are on
   // the wire.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
@@ -8403,7 +8403,7 @@
   // the wire.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame =
       InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
@@ -8422,7 +8422,7 @@
   // retransmittable-on-wire alarm now that no retransmittable packets are on
   // the wire.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
@@ -8472,7 +8472,7 @@
             connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
 
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _))
       .Times(AnyNumber());
 
   // Verify that the first few consecutive retransmittable on wire pings are
@@ -8553,7 +8553,7 @@
   EXPECT_CALL(visitor_, ShouldKeepConnectionAlive())
       .WillRepeatedly(Return(true));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _))
       .Times(AnyNumber());
 
   const char data[] = "data";
@@ -8685,7 +8685,7 @@
             connection_.GetPingAlarm()->deadline() - clock_.ApproximateNow());
 
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _))
       .Times(AnyNumber());
 
   // Verify that the first few consecutive retransmittable on wire pings are
@@ -8746,7 +8746,7 @@
   connection_.SendStreamDataWithString(5, "foo", 0, FIN);
   // This causes connection to be closed because packet 1 has not been sent yet.
   QuicAckFrame frame = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   ProcessAckPacket(1, &frame);
   EXPECT_EQ(0, connection_close_frame_count_);
 }
@@ -9214,7 +9214,7 @@
   connection_.SendCryptoStreamData();
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   QuicAckFrame frame1 = InitAckFrame(1);
   // Received ACK for packet 1.
@@ -9231,7 +9231,7 @@
                                          12, FIN);
   // Received ACK for packets 2, 4, 5.
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   QuicAckFrame frame2 =
       InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
@@ -9251,7 +9251,7 @@
   connection_.SendCryptoStreamData();
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   QuicAckFrame frame1 = InitAckFrame(1);
   // Received ACK for packet 1.
@@ -9904,7 +9904,7 @@
   EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
 
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   QuicAckFrame frame1 = InitAckFrame(1);
   // Received ACK for packet 1.
@@ -10830,7 +10830,7 @@
   rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
                        QuicTime::Delta::Zero(), QuicTime::Zero());
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   // Discard INITIAL key.
   connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
@@ -11231,7 +11231,7 @@
   QuicFrames frames;
   auto ack_frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   frames.push_back(QuicFrame(&ack_frame));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   ProcessFramesPacketAtLevel(30, frames, ENCRYPTION_HANDSHAKE);
   // Discard INITIAL key.
   connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
@@ -11297,7 +11297,7 @@
   QuicFrames frames;
   auto ack_frame = InitAckFrame({{QuicPacketNumber(4), QuicPacketNumber(5)}});
   frames.push_back(QuicFrame(&ack_frame));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
       .Times(AnyNumber());
   ProcessFramesPacketAtLevel(1001, frames, ENCRYPTION_INITIAL);
   EXPECT_EQ(kTestRTT, rtt_stats->latest_rtt());
@@ -11557,7 +11557,7 @@
       GetNthClientInitiatedStreamId(0, connection_.transport_version()), true,
       0u, absl::string_view())));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
   ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_FORWARD_SECURE);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
@@ -11599,7 +11599,8 @@
   }
   ASSERT_TRUE(connection_.BlackholeDetectionInProgress());
 
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(3);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
+      .Times(3);
 
   // ACK packet 5 and 1 and 2 are detected lost.
   QuicAckFrame frame =
@@ -11680,7 +11681,7 @@
   // Received an ACK 100ms later.
   clock_.AdvanceTime(timeout - QuicTime::Delta::FromMilliseconds(100));
   QuicAckFrame ack = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   ProcessAckPacket(1, &ack);
   // Verify idle timeout gets extended.
   EXPECT_EQ(clock_.Now() + timeout, connection_.GetTimeoutAlarm()->deadline());
@@ -12513,7 +12514,7 @@
 
   QuicAckFrame frame1 = InitAckFrame(1);
   // Received ACK for packet 1.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
   EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
 
@@ -12544,7 +12545,7 @@
   connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
   connection_.SendStreamDataWithString(4, "bar", 0, NO_FIN);
   // Received ACK for packet 1, HANDSHAKE packet and 1-RTT ACK.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
       .Times(AnyNumber());
   QuicFrames frames1;
   QuicAckFrame ack_frame1 = InitAckFrame(1);
@@ -12630,7 +12631,7 @@
 
   EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
   // Receive ack for packet 1.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame1 = InitAckFrame(1);
   ProcessAckPacket(&frame1);
 
@@ -12678,7 +12679,7 @@
   EXPECT_EQ(QuicPacketNumber(2u), last_packet);
   EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
   // Receive ack for packet 2.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame2 = InitAckFrame(2);
   ProcessAckPacket(&frame2);
   EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
@@ -12722,7 +12723,7 @@
   EXPECT_TRUE(connection_.HaveSentPacketsInCurrentKeyPhaseButNoneAcked());
 
   // Receive ack for packet 3.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame3 = InitAckFrame(3);
   ProcessAckPacket(&frame3);
   EXPECT_TRUE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet());
@@ -12828,7 +12829,7 @@
       peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote);
     }
     // Receive ack for packet.
-    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
     QuicAckFrame frame1 = InitAckFrame(packet_num);
     ProcessAckPacket(&frame1);
   }
@@ -13086,7 +13087,7 @@
   SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
   EXPECT_EQ(QuicPacketNumber(1u), last_packet);
   // Receive ack for packet 1.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame1 = InitAckFrame(1);
   ProcessAckPacket(&frame1);
   // Key update should now be allowed, initiate it.
@@ -13115,7 +13116,7 @@
   SendStreamDataToPeer(2, "bar", 0, NO_FIN, &last_packet);
   EXPECT_EQ(QuicPacketNumber(2u), last_packet);
   // Receive ack for packet 2.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _, _, _));
   QuicAckFrame frame2 = InitAckFrame(2);
   ProcessAckPacket(&frame2);
 
@@ -13144,7 +13145,7 @@
   }
   SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
   set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
       .Times(AnyNumber());
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
 
@@ -13185,7 +13186,7 @@
   }
   SetQuicReloadableFlag(quic_can_send_ack_frequency, true);
   set_perspective(Perspective::IS_SERVER);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
       .Times(AnyNumber());
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
 
@@ -14028,7 +14029,8 @@
               OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
   EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
 
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
+      .Times(0);
   ProcessFramePacketWithAddresses(QuicFrame(&frame), kSelfAddress,
                                   kNewPeerAddress, ENCRYPTION_INITIAL);
   EXPECT_FALSE(connection_.connected());
@@ -15395,7 +15397,7 @@
   // CHLO gets acknowledged after 10ms.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
   QuicAckFrame frame1 = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
   // Verify PTO is still armed since address validation is not finished yet.
   ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
@@ -15434,7 +15436,7 @@
   // CHLO gets acknowledged after 10ms.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
   QuicAckFrame frame1 = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
   // Verify PTO is still armed since address validation is not finished yet.
   ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
@@ -15508,7 +15510,7 @@
   // CHLO gets acknowledged after 10ms.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
   QuicAckFrame frame1 = InitAckFrame(1);
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   ProcessFramePacketAtLevel(1, QuicFrame(&frame1), ENCRYPTION_INITIAL);
   // Verify PTO is still armed since address validation is not finished yet.
   ASSERT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
@@ -15546,7 +15548,7 @@
   EXPECT_CALL(visitor_, OnBlockedFrame(_));
   EXPECT_CALL(visitor_, OnHandshakeDoneReceived());
   EXPECT_CALL(visitor_, OnStreamFrame(_));
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   EXPECT_CALL(visitor_, OnMaxStreamsFrame(_));
   EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_));
   EXPECT_CALL(visitor_, OnStopSendingFrame(_));
@@ -15922,7 +15924,7 @@
       std::make_unique<StrictTaggingDecrypter>(ENCRYPTION_FORWARD_SECURE));
   ASSERT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
 
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _));
   connection_.GetProcessUndecryptablePacketsAlarm()->Fire();
   // Verify RTT sample does not include queueing delay.
   EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
@@ -16218,7 +16220,7 @@
   }
 
   // Received ACKs for both INITIAL and HANDSHAKE packets.
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
       .Times(AnyNumber());
   QuicFrames frames1;
   QuicAckFrame ack_frame1 = InitAckFrame(1);
diff --git a/quiche/quic/core/quic_sent_packet_manager.cc b/quiche/quic/core/quic_sent_packet_manager.cc
index 88039a5..d458452 100644
--- a/quiche/quic/core/quic_sent_packet_manager.cc
+++ b/quiche/quic/core/quic_sent_packet_manager.cc
@@ -362,10 +362,10 @@
       stats_->overshooting_detected_with_network_parameters_adjusted;
   if (using_pacing_) {
     pacing_sender_.OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
-                                     packets_acked_, packets_lost_);
+                                     packets_acked_, packets_lost_, 0, 0);
   } else {
     send_algorithm_->OnCongestionEvent(rtt_updated, prior_in_flight, event_time,
-                                       packets_acked_, packets_lost_);
+                                       packets_acked_, packets_lost_, 0, 0);
   }
   if (debug_delegate_ != nullptr && !overshooting_detected &&
       stats_->overshooting_detected_with_network_parameters_adjusted) {
diff --git a/quiche/quic/core/quic_sent_packet_manager_test.cc b/quiche/quic/core/quic_sent_packet_manager_test.cc
index 4bc98d5..01c8b0b 100644
--- a/quiche/quic/core/quic_sent_packet_manager_test.cc
+++ b/quiche/quic/core/quic_sent_packet_manager_test.cc
@@ -157,13 +157,13 @@
         // Ensure the AckedPacketVector argument contains largest_observed.
         OnCongestionEvent(true, _, _,
                           Pointwise(PacketNumberEq(), {largest_observed}),
-                          IsEmpty()));
+                          IsEmpty(), _, _));
     EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
   }
 
   void ExpectUpdatedRtt(uint64_t /*largest_observed*/) {
     EXPECT_CALL(*send_algorithm_,
-                OnCongestionEvent(true, _, _, IsEmpty(), IsEmpty()));
+                OnCongestionEvent(true, _, _, IsEmpty(), IsEmpty(), _, _));
     EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
   }
 
@@ -173,7 +173,7 @@
         *send_algorithm_,
         OnCongestionEvent(rtt_updated, _, _,
                           Pointwise(PacketNumberEq(), {largest_observed}),
-                          Pointwise(PacketNumberEq(), {lost_packet})));
+                          Pointwise(PacketNumberEq(), {lost_packet}), _, _));
     EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
   }
 
@@ -190,9 +190,9 @@
       lost_vector.push_back(QuicPacketNumber(packets_lost[i]));
     }
     EXPECT_CALL(*send_algorithm_,
-                OnCongestionEvent(rtt_updated, _, _,
-                                  Pointwise(PacketNumberEq(), ack_vector),
-                                  Pointwise(PacketNumberEq(), lost_vector)));
+                OnCongestionEvent(
+                    rtt_updated, _, _, Pointwise(PacketNumberEq(), ack_vector),
+                    Pointwise(PacketNumberEq(), lost_vector), _, _));
     EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
         .Times(AnyNumber());
   }
@@ -1379,8 +1379,9 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
   // Receiving an ACK for packet1 20s later shouldn't update the RTT, and
   // shouldn't be treated as spurious retransmission.
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/false, kDefaultLength, _, _, _))
+  EXPECT_CALL(
+      *send_algorithm_,
+      OnCongestionEvent(/*rtt_updated=*/false, kDefaultLength, _, _, _, _, _))
       .WillOnce(testing::WithArg<3>(
           Invoke([](const AckedPacketVector& acked_packets) {
             EXPECT_EQ(1u, acked_packets.size());
@@ -1404,8 +1405,9 @@
                            clock_.Now());
   manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
   EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _))
+  EXPECT_CALL(
+      *send_algorithm_,
+      OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _, _, _))
       .WillOnce(testing::WithArg<3>(
           Invoke([](const AckedPacketVector& acked_packets) {
             EXPECT_EQ(1u, acked_packets.size());
@@ -1432,7 +1434,7 @@
       })));
   EXPECT_CALL(notifier_, OnFrameLost(_));
   EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(false, kDefaultLength, _, _, _));
+              OnCongestionEvent(false, kDefaultLength, _, _, _, _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
   manager_.OnRetransmissionTimeout();
   EXPECT_EQ(0u, BytesInFlight());
@@ -1463,7 +1465,7 @@
   EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
   EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
   EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
+              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _, _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
   EXPECT_EQ(PACKETS_NEWLY_ACKED,
             manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(3),
@@ -1482,7 +1484,7 @@
       })));
   EXPECT_CALL(notifier_, OnFrameLost(_));
   EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(false, kDefaultLength, _, _, _));
+              OnCongestionEvent(false, kDefaultLength, _, _, _, _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
   manager_.OnRetransmissionTimeout();
   EXPECT_EQ(0u, BytesInFlight());
@@ -1499,8 +1501,9 @@
   manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
   EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
   EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _));
+  EXPECT_CALL(
+      *send_algorithm_,
+      OnCongestionEvent(/*rtt_updated=*/true, kDefaultLength, _, _, _, _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
   EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
   EXPECT_EQ(PACKETS_NEWLY_ACKED,
@@ -1534,7 +1537,7 @@
   EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
   EXPECT_CALL(*loss_algorithm, SpuriousLossDetected(_, _, _, _, _)).Times(0u);
   EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _));
+              OnCongestionEvent(/*rtt_updated=*/false, 0, _, _, _, _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
   EXPECT_CALL(notifier_, OnFrameAcked(_, _, _));
   EXPECT_EQ(PACKETS_NEWLY_ACKED,
@@ -2735,9 +2738,10 @@
   manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
                         NO_RETRANSMITTABLE_DATA, false);
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_CALL(*send_algorithm_,
-              OnCongestionEvent(/*rtt_updated=*/false, _, _,
-                                Pointwise(PacketNumberEq(), {1}), IsEmpty()));
+  EXPECT_CALL(
+      *send_algorithm_,
+      OnCongestionEvent(/*rtt_updated=*/false, _, _,
+                        Pointwise(PacketNumberEq(), {1}), IsEmpty(), _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
 
   // Get ACK for the packet.
@@ -2768,7 +2772,7 @@
 TEST_F(QuicSentPacketManagerTest,
        PeerMaxAckDelayUpdatedFromAckFrequencyFrameOneAtATime) {
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
       .Times(AnyNumber());
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
       .Times(AnyNumber());
@@ -2812,7 +2816,7 @@
 TEST_F(QuicSentPacketManagerTest,
        PeerMaxAckDelayUpdatedFromInOrderAckFrequencyFrames) {
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
       .Times(AnyNumber());
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
       .Times(AnyNumber());
@@ -2864,7 +2868,7 @@
 TEST_F(QuicSentPacketManagerTest,
        PeerMaxAckDelayUpdatedFromOutOfOrderAckedAckFrequencyFrames) {
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
       .Times(AnyNumber());
   EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
       .Times(AnyNumber());
diff --git a/quiche/quic/test_tools/quic_test_utils.h b/quiche/quic/test_tools/quic_test_utils.h
index f33fe49..061fe0f 100644
--- a/quiche/quic/test_tools/quic_test_utils.h
+++ b/quiche/quic/test_tools/quic_test_utils.h
@@ -1220,7 +1220,8 @@
   MOCK_METHOD(void, OnCongestionEvent,
               (bool rtt_updated, QuicByteCount bytes_in_flight,
                QuicTime event_time, const AckedPacketVector& acked_packets,
-               const LostPacketVector& lost_packets),
+               const LostPacketVector& lost_packets, QuicPacketCount num_ect,
+               QuicPacketCount num_ce),
               (override));
   MOCK_METHOD(void, OnPacketSent,
               (QuicTime, QuicByteCount, QuicPacketNumber, QuicByteCount,
@@ -1246,6 +1247,8 @@
   MOCK_METHOD(void, OnApplicationLimited, (QuicByteCount), (override));
   MOCK_METHOD(void, PopulateConnectionStats, (QuicConnectionStats*),
               (const, override));
+  MOCK_METHOD(bool, SupportsECT0, (), (const, override));
+  MOCK_METHOD(bool, SupportsECT1, (), (const, override));
 };
 
 class MockLossAlgorithm : public LossDetectionInterface {