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