gfe-relnote: In QUIC, deprecate queued_control_frames_ from QuicPacketGenerator. Protected by gfe2_reloadable_flag_quic_deprecate_queued_control_frames.

Change void AddControlFrame(const QuicFrame& frame) to bool ConsumeRetransmittableControlFrame(const QuicFrame& frame).

PiperOrigin-RevId: 246495306
Change-Id: I48a645ea0ef88636afb725abf88da5a4f3125a07
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index aa7b55a..cf36197 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1785,13 +1785,19 @@
 }
 
 bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
-  if (!CanWrite(HAS_RETRANSMITTABLE_DATA) && frame.type != PING_FRAME) {
+  if (!packet_generator_.deprecate_queued_control_frames() &&
+      !CanWrite(HAS_RETRANSMITTABLE_DATA) && frame.type != PING_FRAME) {
     QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame;
     // Do not check congestion window for ping.
     return false;
   }
   ScopedPacketFlusher flusher(this, SEND_ACK_IF_PENDING);
-  packet_generator_.AddControlFrame(frame);
+  const bool consumed =
+      packet_generator_.ConsumeRetransmittableControlFrame(frame);
+  if (packet_generator_.deprecate_queued_control_frames() && !consumed) {
+    QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame;
+    return false;
+  }
   if (frame.type == PING_FRAME) {
     // Flush PING frame immediately.
     packet_generator_.FlushAllQueuedFrames();
@@ -3054,7 +3060,7 @@
   if (transport_version() == QUIC_VERSION_99) {
     frame->close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
   }
-  packet_generator_.AddControlFrame(QuicFrame(frame));
+  packet_generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
   packet_generator_.FlushAllQueuedFrames();
 }
 
diff --git a/quic/core/quic_packet_generator.cc b/quic/core/quic_packet_generator.cc
index d3d950c..7e98274 100644
--- a/quic/core/quic_packet_generator.cc
+++ b/quic/core/quic_packet_generator.cc
@@ -30,7 +30,10 @@
       random_generator_(random_generator),
       fully_pad_crypto_handshake_packets_(true),
       deprecate_ack_bundling_mode_(
-          GetQuicReloadableFlag(quic_deprecate_ack_bundling_mode)) {}
+          GetQuicReloadableFlag(quic_deprecate_ack_bundling_mode)),
+      deprecate_queued_control_frames_(
+          deprecate_ack_bundling_mode_ &&
+          GetQuicReloadableFlag(quic_deprecate_queued_control_frames)) {}
 
 QuicPacketGenerator::~QuicPacketGenerator() {
   DeleteFrames(&queued_control_frames_);
@@ -53,14 +56,37 @@
   SendQueuedFrames(/*flush=*/false);
 }
 
-void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) {
+bool QuicPacketGenerator::ConsumeRetransmittableControlFrame(
+    const QuicFrame& frame) {
   QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
       << "Adding a control frame with no control frame id: " << frame;
+  DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
   if (deprecate_ack_bundling_mode_) {
     MaybeBundleAckOpportunistically();
   }
+  if (deprecate_queued_control_frames_) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_deprecate_queued_control_frames);
+    if (packet_creator_.HasPendingFrames()) {
+      if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) {
+        // There is pending frames and current frame fits.
+        return true;
+      }
+    }
+    DCHECK(!packet_creator_.HasPendingFrames());
+    if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
+        !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
+                                         NOT_HANDSHAKE)) {
+      // Do not check congestion window for ping or connection close frames.
+      return false;
+    }
+    const bool success =
+        packet_creator_.AddSavedFrame(frame, next_transmission_type_);
+    DCHECK(success);
+    return success;
+  }
   queued_control_frames_.push_back(frame);
   SendQueuedFrames(/*flush=*/false);
+  return true;
 }
 
 size_t QuicPacketGenerator::ConsumeCryptoData(EncryptionLevel level,
diff --git a/quic/core/quic_packet_generator.h b/quic/core/quic_packet_generator.h
index dc191a0..047295d 100644
--- a/quic/core/quic_packet_generator.h
+++ b/quic/core/quic_packet_generator.h
@@ -92,7 +92,9 @@
   // CreateAckFrame() when the packet is serialized.
   void SetShouldSendAck(bool also_send_stop_waiting);
 
-  void AddControlFrame(const QuicFrame& frame);
+  // Consumes retransmittable control |frame|. Returns true if the frame is
+  // successfully consumed. Returns false otherwise.
+  bool ConsumeRetransmittableControlFrame(const QuicFrame& frame);
 
   // Given some data, may consume part or all of it and pass it to the
   // packet creator to be serialized into packets. If not in batch
@@ -251,6 +253,10 @@
     return deprecate_ack_bundling_mode_;
   }
 
+  bool deprecate_queued_control_frames() const {
+    return deprecate_queued_control_frames_;
+  }
+
  private:
   friend class test::QuicPacketGeneratorPeer;
 
@@ -281,6 +287,8 @@
   DelegateInterface* delegate_;
 
   QuicPacketCreator packet_creator_;
+  // TODO(fayang): remove this when deprecating
+  // quic_deprecate_queued_control_frames.
   QuicFrames queued_control_frames_;
 
   // Transmission type of the next serialized packet.
@@ -309,6 +317,9 @@
 
   // Latched value of quic_deprecate_ack_bundling_mode.
   const bool deprecate_ack_bundling_mode_;
+
+  // Latched value of quic_deprecate_queued_control_frames.
+  const bool deprecate_queued_control_frames_;
 };
 
 }  // namespace quic
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc
index bd867b8..dfd9ae2 100644
--- a/quic/core/quic_packet_generator_test.cc
+++ b/quic/core/quic_packet_generator_test.cc
@@ -118,7 +118,8 @@
         delegate_(static_cast<MockDelegate*>(delegate)),
         producer_(producer) {}
 
-  void AddControlFrame(const QuicFrame& frame, bool bundle_ack) {
+  bool ConsumeRetransmittableControlFrame(const QuicFrame& frame,
+                                          bool bundle_ack) {
     if (GetQuicReloadableFlag(quic_deprecate_ack_bundling_mode) &&
         !QuicPacketGeneratorPeer::GetPacketCreator(this)->has_ack()) {
       QuicFrames frames;
@@ -131,7 +132,7 @@
             .WillOnce(Return(frames));
       }
     }
-    QuicPacketGenerator::AddControlFrame(frame);
+    return QuicPacketGenerator::ConsumeRetransmittableControlFrame(frame);
   }
 
   QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
@@ -414,26 +415,45 @@
 TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
   delegate_.SetCanNotWrite();
 
-  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()),
-                             /*bundle_ack=*/false);
-  EXPECT_TRUE(generator_.HasQueuedFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool consumed =
+      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                    /*bundle_ack=*/false);
+  if (generator_.deprecate_queued_control_frames()) {
+    EXPECT_FALSE(consumed);
+    EXPECT_FALSE(generator_.HasQueuedFrames());
+    EXPECT_FALSE(generator_.HasRetransmittableFrames());
+    delete rst_frame;
+  } else {
+    EXPECT_TRUE(generator_.HasQueuedFrames());
+    EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  }
 }
 
 TEST_F(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) {
   delegate_.SetCanWriteOnlyNonRetransmittable();
 
-  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()),
-                             /*bundle_ack=*/false);
-  EXPECT_TRUE(generator_.HasQueuedFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool consumed =
+      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                    /*bundle_ack=*/false);
+  if (generator_.deprecate_queued_control_frames()) {
+    EXPECT_FALSE(consumed);
+    EXPECT_FALSE(generator_.HasQueuedFrames());
+    EXPECT_FALSE(generator_.HasRetransmittableFrames());
+    delete rst_frame;
+  } else {
+    EXPECT_TRUE(generator_.HasQueuedFrames());
+    EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  }
 }
 
 TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
   delegate_.SetCanWriteAnything();
 
-  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()),
-                             /*bundle_ack=*/false);
+  generator_.ConsumeRetransmittableControlFrame(
+      QuicFrame(CreateRstStreamFrame()),
+      /*bundle_ack=*/false);
   EXPECT_TRUE(generator_.HasQueuedFrames());
   EXPECT_TRUE(generator_.HasRetransmittableFrames());
 }
@@ -441,8 +461,17 @@
 TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritableBatchThenFlush) {
   delegate_.SetCanNotWrite();
 
-  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()),
-                             /*bundle_ack=*/false);
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool consumed =
+      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                    /*bundle_ack=*/false);
+  if (generator_.deprecate_queued_control_frames()) {
+    EXPECT_FALSE(consumed);
+    EXPECT_FALSE(generator_.HasQueuedFrames());
+    EXPECT_FALSE(generator_.HasRetransmittableFrames());
+    delete rst_frame;
+    return;
+  }
   EXPECT_TRUE(generator_.HasQueuedFrames());
   EXPECT_TRUE(generator_.HasRetransmittableFrames());
   generator_.Flush();
@@ -467,8 +496,9 @@
   EXPECT_CALL(delegate_, OnSerializedPacket(_))
       .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
 
-  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()),
-                             /*bundle_ack=*/false);
+  generator_.ConsumeRetransmittableControlFrame(
+      QuicFrame(CreateRstStreamFrame()),
+      /*bundle_ack=*/false);
   generator_.Flush();
   EXPECT_FALSE(generator_.HasQueuedFrames());
   EXPECT_FALSE(generator_.HasRetransmittableFrames());
@@ -778,10 +808,18 @@
   if (!GetQuicReloadableFlag(quic_deprecate_ack_bundling_mode)) {
     generator_.SetShouldSendAck(false);
   }
-  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()),
-                             /*bundle_ack=*/true);
-  EXPECT_TRUE(generator_.HasQueuedFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool success =
+      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                    /*bundle_ack=*/true);
+  if (generator_.deprecate_queued_control_frames()) {
+    EXPECT_FALSE(success);
+    EXPECT_FALSE(generator_.HasQueuedFrames());
+    EXPECT_FALSE(generator_.HasRetransmittableFrames());
+  } else {
+    EXPECT_TRUE(generator_.HasQueuedFrames());
+    EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  }
 
   delegate_.SetCanWriteAnything();
 
@@ -789,11 +827,20 @@
     EXPECT_CALL(delegate_, GetUpdatedAckFrame())
         .WillOnce(Return(QuicFrame(&ack_frame_)));
   }
+  if (generator_.deprecate_queued_control_frames()) {
+    generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                  /*bundle_ack=*/false);
+  }
 
   // Create a 10000 byte IOVector.
   CreateData(10000);
   EXPECT_CALL(delegate_, OnSerializedPacket(_))
       .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
+  if (generator_.deprecate_queued_control_frames()) {
+    generator_.ConsumeRetransmittableControlFrame(
+        QuicFrame(CreateRstStreamFrame()),
+        /*bundle_ack=*/true);
+  }
   QuicConsumedData consumed = generator_.ConsumeData(
       QuicUtils::GetHeadersStreamId(framer_.transport_version()), &iov_, 1u,
       iov_.iov_len, 0, FIN);
@@ -863,10 +910,18 @@
   if (!GetQuicReloadableFlag(quic_deprecate_ack_bundling_mode)) {
     generator_.SetShouldSendAck(false);
   }
-  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()),
-                             /*bundle_ack=*/true);
-  EXPECT_TRUE(generator_.HasQueuedFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool consumed =
+      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                    /*bundle_ack=*/true);
+  if (generator_.deprecate_queued_control_frames()) {
+    EXPECT_FALSE(consumed);
+    EXPECT_FALSE(generator_.HasQueuedFrames());
+    EXPECT_FALSE(generator_.HasRetransmittableFrames());
+  } else {
+    EXPECT_TRUE(generator_.HasQueuedFrames());
+    EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  }
   EXPECT_FALSE(generator_.HasPendingStreamFramesOfStream(3));
 
   delegate_.SetCanWriteAnything();
@@ -877,13 +932,18 @@
     EXPECT_CALL(delegate_, GetUpdatedAckFrame())
         .WillOnce(Return(QuicFrame(&ack_frame_)));
   }
-
+  if (generator_.deprecate_queued_control_frames()) {
+    EXPECT_TRUE(
+        generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                      /*bundle_ack=*/false));
+  }
   // Send some data and a control frame
   MakeIOVector("quux", &iov_);
   generator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, NO_FIN);
   if (framer_.transport_version() != QUIC_VERSION_99) {
-    generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()),
-                               /*bundle_ack=*/false);
+    generator_.ConsumeRetransmittableControlFrame(
+        QuicFrame(CreateGoAwayFrame()),
+        /*bundle_ack=*/false);
   }
   EXPECT_TRUE(generator_.HasPendingStreamFramesOfStream(3));
 
@@ -918,10 +978,18 @@
   if (!GetQuicReloadableFlag(quic_deprecate_ack_bundling_mode)) {
     generator_.SetShouldSendAck(false);
   }
-  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()),
-                             /*bundle_ack=*/true);
-  EXPECT_TRUE(generator_.HasQueuedFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
+  const bool success =
+      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                    /*bundle_ack=*/true);
+  if (generator_.deprecate_queued_control_frames()) {
+    EXPECT_FALSE(success);
+    EXPECT_FALSE(generator_.HasQueuedFrames());
+    EXPECT_FALSE(generator_.HasRetransmittableFrames());
+  } else {
+    EXPECT_TRUE(generator_.HasQueuedFrames());
+    EXPECT_TRUE(generator_.HasRetransmittableFrames());
+  }
 
   delegate_.SetCanWriteAnything();
 
@@ -940,7 +1008,11 @@
     EXPECT_CALL(delegate_, OnSerializedPacket(_))
         .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
   }
-
+  if (generator_.deprecate_queued_control_frames()) {
+    EXPECT_TRUE(
+        generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
+                                                      /*bundle_ack=*/false));
+  }
   // Send enough data to exceed one packet
   size_t data_len = kDefaultMaxPacketSize + 100;
   CreateData(data_len);
@@ -949,8 +1021,9 @@
   EXPECT_EQ(data_len, consumed.bytes_consumed);
   EXPECT_TRUE(consumed.fin_consumed);
   if (framer_.transport_version() != QUIC_VERSION_99) {
-    generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()),
-                               /*bundle_ack=*/false);
+    generator_.ConsumeRetransmittableControlFrame(
+        QuicFrame(CreateGoAwayFrame()),
+        /*bundle_ack=*/false);
   }
 
   generator_.Flush();
@@ -1355,7 +1428,8 @@
   if (framer_.transport_version() == QUIC_VERSION_99) {
     frame->close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
   }
-  generator_.AddControlFrame(QuicFrame(frame), /*bundle_ack=*/false);
+  generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame),
+                                                /*bundle_ack=*/false);
   EXPECT_TRUE(generator_.HasQueuedFrames());
   EXPECT_TRUE(generator_.HasRetransmittableFrames());
 }