gfe-relnote: In QUIC, populate nonretransmittable_frames in SerializedPacket. Protected by gfe2_reloadable_flag_quic_populate_nonretransmittable_frames.

PiperOrigin-RevId: 275833395
Change-Id: I96d8663e89354a777cabb9e636eede9e61002d26
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index ee2dc02..f2e9789 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -94,11 +94,16 @@
       flusher_attached_(false),
       fully_pad_crypto_handshake_packets_(true),
       combine_generator_and_creator_(
-          GetQuicReloadableFlag(quic_combine_generator_and_creator)) {
+          GetQuicReloadableFlag(quic_combine_generator_and_creator)),
+      populate_nonretransmittable_frames_(
+          GetQuicReloadableFlag(quic_populate_nonretransmittable_frames)) {
   SetMaxPacketLength(kDefaultMaxPacketSize);
   if (combine_generator_and_creator_) {
     QUIC_RELOADABLE_FLAG_COUNT(quic_combine_generator_and_creator);
   }
+  if (populate_nonretransmittable_frames_) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_populate_nonretransmittable_frames);
+  }
 }
 
 QuicPacketCreator::~QuicPacketCreator() {
@@ -445,6 +450,7 @@
   packet_.encrypted_buffer = nullptr;
   packet_.encrypted_length = 0;
   DCHECK(packet_.retransmittable_frames.empty());
+  DCHECK(packet_.nonretransmittable_frames.empty());
   packet_.largest_acked.Clear();
   needs_full_padding_ = false;
 }
@@ -1399,6 +1405,10 @@
       packet_.has_crypto_handshake = IS_HANDSHAKE;
     }
   } else {
+    if (populate_nonretransmittable_frames_ &&
+        !QuicUtils::IsRetransmittableFrame(frame.type)) {
+      packet_.nonretransmittable_frames.push_back(frame);
+    }
     queued_frames_.push_back(frame);
   }
 
diff --git a/quic/core/quic_packet_creator.h b/quic/core/quic_packet_creator.h
index 9b4b665..50bd7f8 100644
--- a/quic/core/quic_packet_creator.h
+++ b/quic/core/quic_packet_creator.h
@@ -582,6 +582,9 @@
 
   // Latched value of quic_combine_generator_and_creator.
   const bool combine_generator_and_creator_;
+
+  // Latched value of quic_populate_nonretransmittable_frames.
+  const bool populate_nonretransmittable_frames_;
 };
 
 }  // namespace quic
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
index b9779cc..2d0d5b3 100644
--- a/quic/core/quic_packet_creator_test.cc
+++ b/quic/core/quic_packet_creator_test.cc
@@ -2426,6 +2426,27 @@
   ProcessPacket(serialized_packet_);
 }
 
+TEST_P(QuicPacketCreatorTest, SaveNonRetransmittableFrames) {
+  if (!GetQuicReloadableFlag(quic_populate_nonretransmittable_frames)) {
+    return;
+  }
+  QuicAckFrame ack_frame(InitAckFrame(1));
+  frames_.push_back(QuicFrame(&ack_frame));
+  frames_.push_back(QuicFrame(QuicPaddingFrame(-1)));
+  SerializedPacket serialized = SerializeAllFrames(frames_);
+  ASSERT_EQ(2u, serialized.nonretransmittable_frames.size());
+  EXPECT_EQ(ACK_FRAME, serialized.nonretransmittable_frames[0].type);
+  EXPECT_EQ(PADDING_FRAME, serialized.nonretransmittable_frames[1].type);
+  frames_.clear();
+
+  // Serialize another packet with the same frames.
+  SerializedPacket packet = QuicPacketCreatorPeer::SerializeAllFrames(
+      &creator_, serialized.nonretransmittable_frames, buffer_,
+      kMaxOutgoingPacketSize);
+  // Verify the packet length of both packets are equal.
+  EXPECT_EQ(serialized.encrypted_length, packet.encrypted_length);
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic
diff --git a/quic/core/quic_packets.cc b/quic/core/quic_packets.cc
index dfe80cf..216a37b 100644
--- a/quic/core/quic_packets.cc
+++ b/quic/core/quic_packets.cc
@@ -477,6 +477,7 @@
       original_packet_number(other.original_packet_number),
       largest_acked(other.largest_acked) {
   retransmittable_frames.swap(other.retransmittable_frames);
+  nonretransmittable_frames.swap(other.nonretransmittable_frames);
 }
 
 SerializedPacket::~SerializedPacket() {}
@@ -485,6 +486,14 @@
   if (!serialized_packet->retransmittable_frames.empty()) {
     DeleteFrames(&serialized_packet->retransmittable_frames);
   }
+  for (auto& frame : serialized_packet->nonretransmittable_frames) {
+    if (frame.type == ACK_FRAME) {
+      // Ack frame is owned by received_packet_manager.
+      continue;
+    }
+    DeleteFrame(&frame);
+  }
+  serialized_packet->nonretransmittable_frames.clear();
   serialized_packet->encrypted_buffer = nullptr;
   serialized_packet->encrypted_length = 0;
   serialized_packet->largest_acked.Clear();
diff --git a/quic/core/quic_packets.h b/quic/core/quic_packets.h
index 82647c6..fcb2e56 100644
--- a/quic/core/quic_packets.h
+++ b/quic/core/quic_packets.h
@@ -370,6 +370,7 @@
   const char* encrypted_buffer;
   QuicPacketLength encrypted_length;
   QuicFrames retransmittable_frames;
+  QuicFrames nonretransmittable_frames;
   IsHandshake has_crypto_handshake;
   // -1: full padding to the end of a max-sized packet
   //  0: no padding