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