In quic, do not truncate ack if there is ack queued in the creator. protected by gfe2_reloadable_flag_quic_donot_change_queued_ack.

PiperOrigin-RevId: 310024106
Change-Id: I9209e467a76e8a05d8f4aef0271cb67729ca3b86
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index fa4b3d8..7ec7955 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -3788,12 +3788,17 @@
 void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
                                               bool acked_new_packet) {
   if (no_stop_waiting_frames_) {
-    uber_received_packet_manager_.DontWaitForPacketsBefore(
-        last_decrypted_packet_level_,
-        SupportsMultiplePacketNumberSpaces()
-            ? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
-                  last_decrypted_packet_level_)
-            : sent_packet_manager_.largest_packet_peer_knows_is_acked());
+    if (GetQuicReloadableFlag(quic_donot_change_queued_ack) &&
+        packet_creator_.has_ack()) {
+      QUIC_RELOADABLE_FLAG_COUNT(quic_donot_change_queued_ack);
+    } else {
+      uber_received_packet_manager_.DontWaitForPacketsBefore(
+          last_decrypted_packet_level_,
+          SupportsMultiplePacketNumberSpaces()
+              ? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
+                    last_decrypted_packet_level_)
+              : sent_packet_manager_.largest_packet_peer_knows_is_acked());
+    }
   }
   // Always reset the retransmission alarm when an ack comes in, since we now
   // have a better estimate of the current rtt than when it was set.
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 613358a..6f803c3 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -10495,6 +10495,48 @@
   EXPECT_EQ(1u, writer_->ping_frames().size());
 }
 
+// Regression test for b/155757133
+TEST_P(QuicConnectionTest, DonotChangeQueuedAcks) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  const size_t kMinRttMs = 40;
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_->GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kMinRttMs),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+
+  ProcessPacket(2);
+  ProcessPacket(3);
+  ProcessPacket(4);
+  // Process a packet containing stream frame followed by ACK of packets 1.
+  QuicFrames frames;
+  frames.push_back(QuicFrame(QuicStreamFrame(
+      QuicUtils::GetFirstBidirectionalStreamId(
+          connection_.version().transport_version, Perspective::IS_CLIENT),
+      false, 0u, quiche::QuicheStringPiece())));
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  frames.push_back(QuicFrame(&ack_frame));
+  // Receiving stream frame causes something to send.
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).WillOnce(Invoke([this]() {
+    connection_.SendControlFrame(QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
+    // Verify now the queued ACK contains packet number 2.
+    EXPECT_TRUE(QuicPacketCreatorPeer::QueuedFrames(
+                    QuicConnectionPeer::GetPacketCreator(&connection_))[0]
+                    .ack_frame->packets.Contains(QuicPacketNumber(2)));
+  }));
+  ProcessFramesPacketAtLevel(9, frames, ENCRYPTION_FORWARD_SECURE);
+  if (GetQuicReloadableFlag(quic_donot_change_queued_ack)) {
+    EXPECT_TRUE(writer_->ack_frames()[0].packets.Contains(QuicPacketNumber(2)));
+  } else {
+    // ACK frame changes mid packet serialiation!
+    EXPECT_FALSE(
+        writer_->ack_frames()[0].packets.Contains(QuicPacketNumber(2)));
+  }
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic
diff --git a/quic/test_tools/quic_packet_creator_peer.cc b/quic/test_tools/quic_packet_creator_peer.cc
index 8224012..1b5eb53 100644
--- a/quic/test_tools/quic_packet_creator_peer.cc
+++ b/quic/test_tools/quic_packet_creator_peer.cc
@@ -149,5 +149,10 @@
   return creator->retry_token_;
 }
 
+// static
+QuicFrames& QuicPacketCreatorPeer::QueuedFrames(QuicPacketCreator* creator) {
+  return creator->queued_frames_;
+}
+
 }  // namespace test
 }  // namespace quic
diff --git a/quic/test_tools/quic_packet_creator_peer.h b/quic/test_tools/quic_packet_creator_peer.h
index bdadc2b..60eb811 100644
--- a/quic/test_tools/quic_packet_creator_peer.h
+++ b/quic/test_tools/quic_packet_creator_peer.h
@@ -59,6 +59,7 @@
   static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator);
   static QuicFramer* framer(QuicPacketCreator* creator);
   static std::string GetRetryToken(QuicPacketCreator* creator);
+  static QuicFrames& QueuedFrames(QuicPacketCreator* creator);
 };
 
 }  // namespace test