gfe-relnote: In IETF QUIC draft 25+, default to 1 packet per PTO, skip a packet number and 1st PTO to be std::max(1.5 * srtt, srtt + 4 * rttvar + ack_delay). Protected by existing gfe2_reloadable_flag_quic_enable_version_draft_25_v3. PiperOrigin-RevId: 300377945 Change-Id: I029b1709a852542124d8068bc4f7003f674c625a
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index 0940048..007856b 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -3693,13 +3693,18 @@ // Fire the RTO and verify that the RST_STREAM is resent, the stream data // is sent. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(2)); + const size_t num_retransmissions = + connection_.SupportsMultiplePacketNumberSpaces() ? 1 : 2; + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .Times(AtLeast(num_retransmissions)); clock_.AdvanceTime(DefaultRetransmissionTime()); connection_.GetRetransmissionAlarm()->Fire(); size_t padding_frame_count = writer_->padding_frames().size(); EXPECT_EQ(padding_frame_count + 1u, writer_->frame_count()); - ASSERT_EQ(1u, writer_->rst_stream_frames().size()); - EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id); + if (num_retransmissions == 2) { + ASSERT_EQ(1u, writer_->rst_stream_frames().size()); + EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id); + } } TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) { @@ -3916,7 +3921,10 @@ writer_->SetWritable(); connection_.OnCanWrite(); EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet()); - EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 2)); + const uint64_t retransmission = + connection_.SupportsMultiplePacketNumberSpaces() ? 3 : 2; + EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, + retransmission)); } TEST_P(QuicConnectionTest, AlarmsWhenWriteBlocked) { @@ -4155,9 +4163,11 @@ // Simulate the retransmission alarm firing and sending a tlp, // so send algorithm's OnRetransmissionTimeout is not called. clock_.AdvanceTime(retransmission_time - clock_.Now()); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _)); + const QuicPacketNumber retransmission( + connection_.SupportsMultiplePacketNumberSpaces() ? 3 : 2); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, retransmission, _, _)); connection_.GetRetransmissionAlarm()->Fire(); - EXPECT_EQ(QuicPacketNumber(2u), writer_->header().packet_number); + EXPECT_EQ(retransmission, writer_->header().packet_number); // We do not raise the high water mark yet. EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked); } @@ -9714,6 +9724,7 @@ if (!connection_.version().SupportsAntiAmplificationLimit()) { return; } + SetQuicReloadableFlag(quic_send_ping_when_pto_skips_packet_number, true); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet()); @@ -9735,7 +9746,7 @@ EXPECT_EQ(0u, connection_.GetStats().crypto_retransmit_count); // PTO fires, verify a PING packet gets sent because there is no data to send. - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _)); EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() { SendPing(); })); connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(1u, connection_.GetStats().pto_count); @@ -9977,7 +9988,7 @@ // Retransmit handshake data. clock_.AdvanceTime(retransmission_time - clock_.Now()); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(3), _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _)); connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet()); @@ -9990,7 +10001,7 @@ // Retransmit handshake data again. clock_.AdvanceTime(retransmission_time - clock_.Now()); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(5), _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(7), _, _)); connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet()); @@ -10001,7 +10012,7 @@ // Retransmit application data. clock_.AdvanceTime(retransmission_time - clock_.Now()); - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(6), _, _)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(9), _, _)); connection_.GetRetransmissionAlarm()->Fire(); EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet()); }
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc index bad8aa6..09f92e1 100644 --- a/quic/core/quic_sent_packet_manager.cc +++ b/quic/core/quic_sent_packet_manager.cc
@@ -892,6 +892,12 @@ void QuicSentPacketManager::EnableIetfPtoAndLossDetection() { pto_enabled_ = true; handshake_mode_disabled_ = true; + // Default to 1 packet per PTO and skip a packet number. Arm the 1st PTO with + // max of earliest in flight sent time + PTO delay and 1.5 * srtt from + // last in flight packet. + max_probe_packets_per_pto_ = 1; + skip_packet_number_for_pto_ = true; + first_pto_srtt_multiplier_ = 1.5; } void QuicSentPacketManager::StartExponentialBackoffAfterNthPto(