gfe-relnote: In QUIC, add largest_packets_peer_knows_is_acked_ and largest_sent_packets_ which are necessary to sent_packet_manager and unacked_packet_map, respectively, for multiple packet number support. Not used yet. Not protected. PiperOrigin-RevId: 239787104 Change-Id: I9955881f09eb4b70a740a913fcd4ad7bc8fe863d
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc index b1ba487..72c5c0f 100644 --- a/quic/core/quic_sent_packet_manager.cc +++ b/quic/core/quic_sent_packet_manager.cc
@@ -1147,6 +1147,11 @@ << acked_packet.packet_number; last_ack_frame_.packets.Add(acked_packet.packet_number); largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked); + if (supports_multiple_packet_number_spaces()) { + largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace( + info->encryption_level)] + .UpdateMax(info->largest_acked); + } // If data is associated with the most recent transmission of this // packet, then inform the caller. if (info->in_flight) { @@ -1196,5 +1201,30 @@ rtt_stats_.set_initial_rtt(std::max(min_rtt, std::min(max_rtt, rtt))); } +void QuicSentPacketManager::EnableMultiplePacketNumberSpacesSupport() { + unacked_packets_.EnableMultiplePacketNumberSpacesSupport(); +} + +QuicPacketNumber QuicSentPacketManager::GetLargestAckedPacket( + EncryptionLevel decrypted_packet_level) const { + DCHECK(supports_multiple_packet_number_spaces()); + return unacked_packets_.GetLargestAckedOfPacketNumberSpace( + QuicUtils::GetPacketNumberSpace(decrypted_packet_level)); +} + +QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket( + EncryptionLevel decrypted_packet_level) const { + DCHECK(supports_multiple_packet_number_spaces()); + return unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + decrypted_packet_level); +} + +QuicPacketNumber QuicSentPacketManager::GetLargestPacketPeerKnowsIsAcked( + EncryptionLevel decrypted_packet_level) const { + DCHECK(supports_multiple_packet_number_spaces()); + return largest_packets_peer_knows_is_acked_[QuicUtils::GetPacketNumberSpace( + decrypted_packet_level)]; +} + #undef ENDPOINT // undef for jumbo builds } // namespace quic
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h index 3d75e45..592fb1a 100644 --- a/quic/core/quic_sent_packet_manager.h +++ b/quic/core/quic_sent_packet_manager.h
@@ -272,6 +272,8 @@ unacked_packets_.SetSessionDecideWhatToWrite(session_decides_what_to_write); } + void EnableMultiplePacketNumberSpacesSupport(); + void SetDebugDelegate(DebugDelegate* debug_delegate); void SetPacingAlarmGranularity(QuicTime::Delta alarm_granularity) { @@ -282,10 +284,19 @@ return unacked_packets_.largest_acked(); } + QuicPacketNumber GetLargestAckedPacket( + EncryptionLevel decrypted_packet_level) const; + QuicPacketNumber GetLargestSentPacket() const { return unacked_packets_.largest_sent_packet(); } + QuicPacketNumber GetLargestSentPacket( + EncryptionLevel decrypted_packet_level) const; + + QuicPacketNumber GetLargestPacketPeerKnowsIsAcked( + EncryptionLevel decrypted_packet_level) const; + void SetNetworkChangeVisitor(NetworkChangeVisitor* visitor) { DCHECK(!network_change_visitor_); DCHECK(visitor); @@ -352,6 +363,10 @@ bool tolerate_reneging() const { return tolerate_reneging_; } + bool supports_multiple_packet_number_spaces() const { + return unacked_packets_.supports_multiple_packet_number_spaces(); + } + private: friend class test::QuicConnectionPeer; friend class test::QuicSentPacketManagerPeer; @@ -567,6 +582,11 @@ // The largest acked value that was sent in an ack, which has then been acked. QuicPacketNumber largest_packet_peer_knows_is_acked_; + // The largest acked value that was sent in an ack, which has then been acked + // for per packet number space. Only used when connection supports multiple + // packet number spaces. + QuicPacketNumber + largest_packets_peer_knows_is_acked_[NUM_PACKET_NUMBER_SPACES]; // The maximum amount of time to wait before sending an acknowledgement. // The recovery code assumes the delayed ack time is the same on both sides.
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc index 024b4c7..4624a8a 100644 --- a/quic/core/quic_sent_packet_manager_test.cc +++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -264,10 +264,16 @@ } void SendDataPacket(uint64_t packet_number) { + SendDataPacket(packet_number, ENCRYPTION_INITIAL); + } + + void SendDataPacket(uint64_t packet_number, + EncryptionLevel encryption_level) { EXPECT_CALL(*send_algorithm_, OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number), _, _)); SerializedPacket packet(CreateDataPacket(packet_number)); + packet.encryption_level = encryption_level; manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); } @@ -2465,6 +2471,111 @@ EXPECT_EQ(QuicPacketNumber(16), manager_.GetLargestObserved()); } +TEST_P(QuicSentPacketManagerTest, MultiplePacketNumberSpaces) { + if (!GetQuicReloadableFlag(quic_use_uber_loss_algorithm)) { + return; + } + manager_.EnableMultiplePacketNumberSpacesSupport(); + EXPECT_FALSE( + manager_.GetLargestSentPacket(ENCRYPTION_INITIAL).IsInitialized()); + EXPECT_FALSE( + manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL).IsInitialized()); + // Send packet 1. + SendDataPacket(1, ENCRYPTION_INITIAL); + EXPECT_EQ(QuicPacketNumber(1), + manager_.GetLargestSentPacket(ENCRYPTION_INITIAL)); + EXPECT_FALSE( + manager_.GetLargestSentPacket(ENCRYPTION_HANDSHAKE).IsInitialized()); + // Ack packet 1. + ExpectAck(1); + manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); + EXPECT_EQ(QuicPacketNumber(1), + manager_.GetLargestAckedPacket(ENCRYPTION_INITIAL)); + EXPECT_FALSE( + manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE).IsInitialized()); + // Send packets 2 and 3. + SendDataPacket(2, ENCRYPTION_HANDSHAKE); + SendDataPacket(3, ENCRYPTION_HANDSHAKE); + EXPECT_EQ(QuicPacketNumber(1), + manager_.GetLargestSentPacket(ENCRYPTION_INITIAL)); + EXPECT_EQ(QuicPacketNumber(3), + manager_.GetLargestSentPacket(ENCRYPTION_HANDSHAKE)); + EXPECT_FALSE( + manager_.GetLargestSentPacket(ENCRYPTION_ZERO_RTT).IsInitialized()); + // Ack packet 2. + ExpectAck(2); + manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3)); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); + EXPECT_EQ(QuicPacketNumber(2), + manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE)); + EXPECT_FALSE( + manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized()); + // Ack packet 3. + ExpectAck(3); + manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(4)); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); + EXPECT_EQ(QuicPacketNumber(3), + manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE)); + EXPECT_FALSE( + manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT).IsInitialized()); + // Send packets 4 and 5. + SendDataPacket(4, ENCRYPTION_ZERO_RTT); + SendDataPacket(5, ENCRYPTION_ZERO_RTT); + EXPECT_EQ(QuicPacketNumber(1), + manager_.GetLargestSentPacket(ENCRYPTION_INITIAL)); + EXPECT_EQ(QuicPacketNumber(3), + manager_.GetLargestSentPacket(ENCRYPTION_HANDSHAKE)); + EXPECT_EQ(QuicPacketNumber(5), + manager_.GetLargestSentPacket(ENCRYPTION_ZERO_RTT)); + EXPECT_EQ(QuicPacketNumber(5), + manager_.GetLargestSentPacket(ENCRYPTION_FORWARD_SECURE)); + // Ack packet 5. + ExpectAck(5); + manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(6)); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); + EXPECT_EQ(QuicPacketNumber(3), + manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE)); + EXPECT_EQ(QuicPacketNumber(5), + manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT)); + EXPECT_EQ(QuicPacketNumber(5), + manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)); + + // Send packets 6 - 8. + SendDataPacket(6, ENCRYPTION_FORWARD_SECURE); + SendDataPacket(7, ENCRYPTION_FORWARD_SECURE); + SendDataPacket(8, ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(QuicPacketNumber(1), + manager_.GetLargestSentPacket(ENCRYPTION_INITIAL)); + EXPECT_EQ(QuicPacketNumber(3), + manager_.GetLargestSentPacket(ENCRYPTION_HANDSHAKE)); + EXPECT_EQ(QuicPacketNumber(8), + manager_.GetLargestSentPacket(ENCRYPTION_ZERO_RTT)); + EXPECT_EQ(QuicPacketNumber(8), + manager_.GetLargestSentPacket(ENCRYPTION_FORWARD_SECURE)); + // Ack all packets. + uint64_t acked[] = {4, 6, 7, 8}; + ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0); + manager_.OnAckFrameStart(QuicPacketNumber(8), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(9)); + EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now())); + EXPECT_EQ(QuicPacketNumber(3), + manager_.GetLargestAckedPacket(ENCRYPTION_HANDSHAKE)); + EXPECT_EQ(QuicPacketNumber(8), + manager_.GetLargestAckedPacket(ENCRYPTION_ZERO_RTT)); + EXPECT_EQ(QuicPacketNumber(8), + manager_.GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)); +} + } // namespace } // namespace test } // namespace quic
diff --git a/quic/core/quic_unacked_packet_map.cc b/quic/core/quic_unacked_packet_map.cc index 0f5fa49..5a9bd24 100644 --- a/quic/core/quic_unacked_packet_map.cc +++ b/quic/core/quic_unacked_packet_map.cc
@@ -33,7 +33,8 @@ session_notifier_(nullptr), session_decides_what_to_write_(false), use_uber_loss_algorithm_( - GetQuicReloadableFlag(quic_use_uber_loss_algorithm)) { + GetQuicReloadableFlag(quic_use_uber_loss_algorithm)), + supports_multiple_packet_number_spaces_(false) { if (use_uber_loss_algorithm_) { QUIC_RELOADABLE_FLAG_COUNT(quic_use_uber_loss_algorithm); } @@ -75,6 +76,10 @@ } largest_sent_packet_ = packet_number; + if (supports_multiple_packet_number_spaces_) { + largest_sent_packets_[GetPacketNumberSpace(packet->encryption_level)] = + packet_number; + } if (set_in_flight) { bytes_in_flight_ += bytes_sent; info.in_flight = true; @@ -501,6 +506,9 @@ PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace( EncryptionLevel encryption_level) const { DCHECK(use_uber_loss_algorithm_); + if (supports_multiple_packet_number_spaces_) { + return QuicUtils::GetPacketNumberSpace(encryption_level); + } if (perspective_ == Perspective::IS_CLIENT) { return encryption_level == ENCRYPTION_INITIAL ? HANDSHAKE_DATA : APPLICATION_DATA; @@ -539,4 +547,24 @@ session_decides_what_to_write_ = session_decides_what_to_write; } +void QuicUnackedPacketMap::EnableMultiplePacketNumberSpacesSupport() { + if (supports_multiple_packet_number_spaces_) { + QUIC_BUG << "Multiple packet number spaces has already been enabled"; + return; + } + if (largest_sent_packet_.IsInitialized()) { + QUIC_BUG << "Try to enable multiple packet number spaces support after any " + "packet has been sent."; + return; + } + + supports_multiple_packet_number_spaces_ = true; +} + +QuicPacketNumber QuicUnackedPacketMap::GetLargestSentPacketOfPacketNumberSpace( + EncryptionLevel encryption_level) const { + DCHECK(supports_multiple_packet_number_spaces_); + return largest_sent_packets_[GetPacketNumberSpace(encryption_level)]; +} + } // namespace quic
diff --git a/quic/core/quic_unacked_packet_map.h b/quic/core/quic_unacked_packet_map.h index 9245589..1d4f00c 100644 --- a/quic/core/quic_unacked_packet_map.h +++ b/quic/core/quic_unacked_packet_map.h
@@ -204,11 +204,17 @@ QuicPacketNumber GetLargestSentRetransmittableOfPacketNumberSpace( PacketNumberSpace packet_number_space) const; + // Returns largest sent packet number of |encryption_level|. + QuicPacketNumber GetLargestSentPacketOfPacketNumberSpace( + EncryptionLevel encryption_level) const; + // Called to start/stop letting session decide what to write. void SetSessionDecideWhatToWrite(bool session_decides_what_to_write); void SetSessionNotifier(SessionNotifierInterface* session_notifier); + void EnableMultiplePacketNumberSpacesSupport(); + bool session_decides_what_to_write() const { return session_decides_what_to_write_; } @@ -217,6 +223,10 @@ Perspective perspective() const { return perspective_; } + bool supports_multiple_packet_number_spaces() const { + return supports_multiple_packet_number_spaces_; + } + private: friend class test::QuicUnackedPacketMapPeer; @@ -249,6 +259,8 @@ const Perspective perspective_; QuicPacketNumber largest_sent_packet_; + // Only used when supports_multiple_packet_number_spaces_ is true. + QuicPacketNumber largest_sent_packets_[NUM_PACKET_NUMBER_SPACES]; // The largest sent packet we expect to receive an ack for. // TODO(fayang): Remove largest_sent_retransmittable_packet_ when deprecating // quic_use_uber_loss_algorithm. @@ -296,6 +308,9 @@ // Latched value of quic_use_uber_loss_algorithm. const bool use_uber_loss_algorithm_; + + // If true, supports multiple packet number spaces. + bool supports_multiple_packet_number_spaces_; }; } // namespace quic
diff --git a/quic/core/quic_unacked_packet_map_test.cc b/quic/core/quic_unacked_packet_map_test.cc index cf725fa..331a0e8 100644 --- a/quic/core/quic_unacked_packet_map_test.cc +++ b/quic/core/quic_unacked_packet_map_test.cc
@@ -674,6 +674,85 @@ unacked_packets_.NotifyAggregatedStreamFrameAcked(QuicTime::Delta::Zero()); } +TEST_P(QuicUnackedPacketMapTest, LargestSentPacketMultiplePacketNumberSpaces) { + if (!GetQuicReloadableFlag(quic_use_uber_loss_algorithm)) { + return; + } + unacked_packets_.EnableMultiplePacketNumberSpacesSupport(); + EXPECT_FALSE(unacked_packets_ + .GetLargestSentPacketOfPacketNumberSpace(ENCRYPTION_INITIAL) + .IsInitialized()); + // Send packet 1. + SerializedPacket packet1(CreateRetransmittablePacket(1)); + packet1.encryption_level = ENCRYPTION_INITIAL; + unacked_packets_.AddSentPacket(&packet1, QuicPacketNumber(), + NOT_RETRANSMISSION, now_, true); + EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.largest_sent_packet()); + EXPECT_EQ(QuicPacketNumber(1), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_INITIAL)); + EXPECT_FALSE( + unacked_packets_ + .GetLargestSentPacketOfPacketNumberSpace(ENCRYPTION_HANDSHAKE) + .IsInitialized()); + // Send packet 2. + SerializedPacket packet2(CreateRetransmittablePacket(2)); + packet2.encryption_level = ENCRYPTION_HANDSHAKE; + unacked_packets_.AddSentPacket(&packet2, QuicPacketNumber(), + NOT_RETRANSMISSION, now_, true); + EXPECT_EQ(QuicPacketNumber(2u), unacked_packets_.largest_sent_packet()); + EXPECT_EQ(QuicPacketNumber(1), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_INITIAL)); + EXPECT_EQ(QuicPacketNumber(2), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_HANDSHAKE)); + EXPECT_FALSE(unacked_packets_ + .GetLargestSentPacketOfPacketNumberSpace(ENCRYPTION_ZERO_RTT) + .IsInitialized()); + // Send packet 3. + SerializedPacket packet3(CreateRetransmittablePacket(3)); + packet3.encryption_level = ENCRYPTION_ZERO_RTT; + unacked_packets_.AddSentPacket(&packet3, QuicPacketNumber(), + NOT_RETRANSMISSION, now_, true); + EXPECT_EQ(QuicPacketNumber(3u), unacked_packets_.largest_sent_packet()); + EXPECT_EQ(QuicPacketNumber(1), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_INITIAL)); + EXPECT_EQ(QuicPacketNumber(2), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_HANDSHAKE)); + EXPECT_EQ(QuicPacketNumber(3), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_ZERO_RTT)); + // Verify forward secure belongs to the same packet number space as encryption + // zero rtt. + EXPECT_EQ(QuicPacketNumber(3), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_FORWARD_SECURE)); + + // Send packet 4. + SerializedPacket packet4(CreateRetransmittablePacket(4)); + packet4.encryption_level = ENCRYPTION_FORWARD_SECURE; + unacked_packets_.AddSentPacket(&packet4, QuicPacketNumber(), + NOT_RETRANSMISSION, now_, true); + EXPECT_EQ(QuicPacketNumber(4u), unacked_packets_.largest_sent_packet()); + EXPECT_EQ(QuicPacketNumber(1), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_INITIAL)); + EXPECT_EQ(QuicPacketNumber(2), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_HANDSHAKE)); + EXPECT_EQ(QuicPacketNumber(4), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_ZERO_RTT)); + // Verify forward secure belongs to the same packet number space as encryption + // zero rtt. + EXPECT_EQ(QuicPacketNumber(4), + unacked_packets_.GetLargestSentPacketOfPacketNumberSpace( + ENCRYPTION_FORWARD_SECURE)); +} + } // namespace } // namespace test } // namespace quic