gfe-relnote: In QUIC, Enable multiple packet number support in uber_received_packet_manager. Not used yet, not protected.
PiperOrigin-RevId: 239821420
Change-Id: Iae12d214d8ecf65dfe4918f12e528ea1001ce5f2
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index f213d35..2c7df67 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -357,6 +357,7 @@
GetQuicReloadableFlag(quic_validate_packet_number_post_decryption)),
use_uber_received_packet_manager_(
received_packet_manager_.decide_when_to_send_acks() &&
+ validate_packet_number_post_decryption_ &&
GetQuicReloadableFlag(quic_use_uber_received_packet_manager)) {
if (ack_mode_ == ACK_DECIMATION) {
QUIC_RELOADABLE_FLAG_COUNT(quic_enable_ack_decimation);
@@ -825,7 +826,7 @@
const bool is_awaiting =
use_uber_received_packet_manager_
? uber_received_packet_manager_.IsAwaitingPacket(
- header.packet_number)
+ last_decrypted_packet_level_, header.packet_number)
: received_packet_manager_.IsAwaitingPacket(header.packet_number);
if (!is_awaiting) {
if (framer_.IsIetfStatelessResetPacket(header)) {
@@ -959,7 +960,8 @@
// frames, since the processing may result in sending a bundled ack.
if (use_uber_received_packet_manager_) {
uber_received_packet_manager_.RecordPacketReceived(
- last_header_, time_of_last_received_packet_);
+ last_decrypted_packet_level_, last_header_,
+ time_of_last_received_packet_);
} else {
received_packet_manager_.RecordPacketReceived(
last_header_, time_of_last_received_packet_);
@@ -1167,7 +1169,8 @@
largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
if (use_uber_received_packet_manager_) {
- uber_received_packet_manager_.DontWaitForPacketsBefore(frame.least_unacked);
+ uber_received_packet_manager_.DontWaitForPacketsBefore(
+ last_decrypted_packet_level_, frame.least_unacked);
} else {
received_packet_manager_.DontWaitForPacketsBefore(frame.least_unacked);
}
@@ -1490,9 +1493,9 @@
if (received_packet_manager_.decide_when_to_send_acks()) {
if (use_uber_received_packet_manager_) {
uber_received_packet_manager_.MaybeUpdateAckTimeout(
- should_last_packet_instigate_acks_, last_header_.packet_number,
- time_of_last_received_packet_, clock_->ApproximateNow(),
- sent_packet_manager_.GetRttStats(),
+ should_last_packet_instigate_acks_, last_decrypted_packet_level_,
+ last_header_.packet_number, time_of_last_received_packet_,
+ clock_->ApproximateNow(), sent_packet_manager_.GetRttStats(),
sent_packet_manager_.delayed_ack_time());
} else {
received_packet_manager_.MaybeUpdateAckTimeout(
@@ -1656,6 +1659,7 @@
const QuicFrame QuicConnection::GetUpdatedAckFrame() {
if (use_uber_received_packet_manager_) {
return uber_received_packet_manager_.GetUpdatedAckFrame(
+ QuicUtils::GetPacketNumberSpace(encryption_level_),
clock_->ApproximateNow());
}
return received_packet_manager_.GetUpdatedAckFrame(clock_->ApproximateNow());
@@ -1961,7 +1965,8 @@
if (received_packet_manager_.decide_when_to_send_acks()) {
const QuicTime ack_timeout =
use_uber_received_packet_manager_
- ? uber_received_packet_manager_.GetAckTimeout()
+ ? uber_received_packet_manager_.GetAckTimeout(
+ QuicUtils::GetPacketNumberSpace(encryption_level_))
: received_packet_manager_.ack_timeout();
if (ack_timeout.IsInitialized() &&
ack_timeout <= clock_->ApproximateNow()) {
@@ -2088,7 +2093,8 @@
if (validate_packet_number_post_decryption_) {
const bool is_awaiting =
use_uber_received_packet_manager_
- ? uber_received_packet_manager_.IsAwaitingPacket(packet_number)
+ ? uber_received_packet_manager_.IsAwaitingPacket(
+ last_decrypted_packet_level_, packet_number)
: received_packet_manager_.IsAwaitingPacket(packet_number);
if (!is_awaiting) {
QUIC_DLOG(INFO) << ENDPOINT << "Packet " << packet_number
@@ -2273,7 +2279,9 @@
if (received_packet_manager_.decide_when_to_send_acks()) {
if (use_uber_received_packet_manager_) {
has_pending_ack =
- uber_received_packet_manager_.GetAckTimeout().IsInitialized();
+ uber_received_packet_manager_
+ .GetAckTimeout(QuicUtils::GetPacketNumberSpace(encryption_level_))
+ .IsInitialized();
} else {
has_pending_ack = received_packet_manager_.ack_timeout().IsInitialized();
}
@@ -3271,7 +3279,9 @@
if (connection_->received_packet_manager_.decide_when_to_send_acks()) {
const QuicTime ack_timeout =
connection_->use_uber_received_packet_manager_
- ? connection_->uber_received_packet_manager_.GetAckTimeout()
+ ? connection_->uber_received_packet_manager_.GetAckTimeout(
+ QuicUtils::GetPacketNumberSpace(
+ connection_->encryption_level_))
: connection_->received_packet_manager_.ack_timeout();
if (ack_timeout.IsInitialized()) {
if (ack_timeout <= connection_->clock_->ApproximateNow() &&
@@ -3597,7 +3607,7 @@
bool QuicConnection::ack_frame_updated() const {
if (use_uber_received_packet_manager_) {
- return uber_received_packet_manager_.AckFrameUpdated();
+ return uber_received_packet_manager_.IsAckFrameUpdated();
}
return received_packet_manager_.ack_frame_updated();
}
@@ -3746,6 +3756,7 @@
if (no_stop_waiting_frames_) {
if (use_uber_received_packet_manager_) {
uber_received_packet_manager_.DontWaitForPacketsBefore(
+ last_decrypted_packet_level_,
sent_packet_manager_.largest_packet_peer_knows_is_acked());
} else {
received_packet_manager_.DontWaitForPacketsBefore(
@@ -3818,7 +3829,7 @@
num_packets_received_since_last_ack_sent_ = 0;
if (received_packet_manager_.decide_when_to_send_acks()) {
if (use_uber_received_packet_manager_) {
- uber_received_packet_manager_.ResetAckStates();
+ uber_received_packet_manager_.ResetAckStates(encryption_level_);
} else {
received_packet_manager_.ResetAckStates();
}
@@ -3905,7 +3916,8 @@
QuicPacketNumber QuicConnection::GetLargestReceivedPacket() const {
if (use_uber_received_packet_manager_) {
- return uber_received_packet_manager_.GetLargestObserved();
+ return uber_received_packet_manager_.GetLargestObserved(
+ last_decrypted_packet_level_);
}
return received_packet_manager_.GetLargestObserved();
}
diff --git a/quic/core/quic_received_packet_manager.cc b/quic/core/quic_received_packet_manager.cc
index 82984eb..528b866 100644
--- a/quic/core/quic_received_packet_manager.cc
+++ b/quic/core/quic_received_packet_manager.cc
@@ -39,6 +39,9 @@
const float kShortAckDecimationDelay = 0.125;
} // namespace
+QuicReceivedPacketManager::QuicReceivedPacketManager()
+ : QuicReceivedPacketManager(nullptr) {}
+
QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
: ack_frame_updated_(false),
max_ack_ranges_(0),
diff --git a/quic/core/quic_received_packet_manager.h b/quic/core/quic_received_packet_manager.h
index 8eb8cac..7c9bd7f 100644
--- a/quic/core/quic_received_packet_manager.h
+++ b/quic/core/quic_received_packet_manager.h
@@ -25,6 +25,7 @@
// Records all received packets by a connection.
class QUIC_EXPORT_PRIVATE QuicReceivedPacketManager {
public:
+ QuicReceivedPacketManager();
explicit QuicReceivedPacketManager(QuicConnectionStats* stats);
QuicReceivedPacketManager(const QuicReceivedPacketManager&) = delete;
QuicReceivedPacketManager& operator=(const QuicReceivedPacketManager&) =
@@ -91,6 +92,8 @@
// least one packet has been received.
QuicPacketNumber PeerFirstSendingPacketNumber() const;
+ void set_connection_stats(QuicConnectionStats* stats) { stats_ = stats; }
+
// For logging purposes.
const QuicAckFrame& ack_frame() const { return ack_frame_; }
diff --git a/quic/core/quic_utils.cc b/quic/core/quic_utils.cc
index 63b9b85..56cfe87 100644
--- a/quic/core/quic_utils.cc
+++ b/quic/core/quic_utils.cc
@@ -549,5 +549,21 @@
}
}
+// static
+EncryptionLevel QuicUtils::GetEncryptionLevel(
+ PacketNumberSpace packet_number_space) {
+ switch (packet_number_space) {
+ case INITIAL_DATA:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE_DATA:
+ return ENCRYPTION_HANDSHAKE;
+ case APPLICATION_DATA:
+ return ENCRYPTION_FORWARD_SECURE;
+ default:
+ DCHECK(false);
+ return NUM_ENCRYPTION_LEVELS;
+ }
+}
+
#undef RETURN_STRING_LITERAL // undef for jumbo builds
} // namespace quic
diff --git a/quic/core/quic_utils.h b/quic/core/quic_utils.h
index 515056c..340f474 100644
--- a/quic/core/quic_utils.h
+++ b/quic/core/quic_utils.h
@@ -183,6 +183,10 @@
// Determines packet number space from |encryption_level|.
static PacketNumberSpace GetPacketNumberSpace(
EncryptionLevel encryption_level);
+
+ // Determines encryption level to send packets in |packet_number_space|.
+ static EncryptionLevel GetEncryptionLevel(
+ PacketNumberSpace packet_number_space);
};
} // namespace quic
diff --git a/quic/core/uber_received_packet_manager.cc b/quic/core/uber_received_packet_manager.cc
index b730474..00c430e 100644
--- a/quic/core/uber_received_packet_manager.cc
+++ b/quic/core/uber_received_packet_manager.cc
@@ -4,105 +4,214 @@
#include "net/third_party/quiche/src/quic/core/uber_received_packet_manager.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+
namespace quic {
UberReceivedPacketManager::UberReceivedPacketManager(QuicConnectionStats* stats)
- : received_packet_manager_(stats) {}
+ : supports_multiple_packet_number_spaces_(false) {
+ for (auto& received_packet_manager : received_packet_managers_) {
+ received_packet_manager.set_connection_stats(stats);
+ }
+}
UberReceivedPacketManager::~UberReceivedPacketManager() {}
void UberReceivedPacketManager::SetFromConfig(const QuicConfig& config,
Perspective perspective) {
- received_packet_manager_.SetFromConfig(config, perspective);
+ for (auto& received_packet_manager : received_packet_managers_) {
+ received_packet_manager.SetFromConfig(config, perspective);
+ }
}
bool UberReceivedPacketManager::IsAwaitingPacket(
+ EncryptionLevel decrypted_packet_level,
QuicPacketNumber packet_number) const {
- return received_packet_manager_.IsAwaitingPacket(packet_number);
+ if (!supports_multiple_packet_number_spaces_) {
+ return received_packet_managers_[0].IsAwaitingPacket(packet_number);
+ }
+ return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+ decrypted_packet_level)]
+ .IsAwaitingPacket(packet_number);
}
const QuicFrame UberReceivedPacketManager::GetUpdatedAckFrame(
+ PacketNumberSpace packet_number_space,
QuicTime approximate_now) {
- return received_packet_manager_.GetUpdatedAckFrame(approximate_now);
+ if (!supports_multiple_packet_number_spaces_) {
+ return received_packet_managers_[0].GetUpdatedAckFrame(approximate_now);
+ }
+ return received_packet_managers_[packet_number_space].GetUpdatedAckFrame(
+ approximate_now);
}
void UberReceivedPacketManager::RecordPacketReceived(
+ EncryptionLevel decrypted_packet_level,
const QuicPacketHeader& header,
QuicTime receipt_time) {
- received_packet_manager_.RecordPacketReceived(header, receipt_time);
+ if (!supports_multiple_packet_number_spaces_) {
+ received_packet_managers_[0].RecordPacketReceived(header, receipt_time);
+ return;
+ }
+ received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+ decrypted_packet_level)]
+ .RecordPacketReceived(header, receipt_time);
}
void UberReceivedPacketManager::DontWaitForPacketsBefore(
+ EncryptionLevel decrypted_packet_level,
QuicPacketNumber least_unacked) {
- received_packet_manager_.DontWaitForPacketsBefore(least_unacked);
+ if (!supports_multiple_packet_number_spaces_) {
+ received_packet_managers_[0].DontWaitForPacketsBefore(least_unacked);
+ return;
+ }
+ received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+ decrypted_packet_level)]
+ .DontWaitForPacketsBefore(least_unacked);
}
void UberReceivedPacketManager::MaybeUpdateAckTimeout(
bool should_last_packet_instigate_acks,
+ EncryptionLevel decrypted_packet_level,
QuicPacketNumber last_received_packet_number,
QuicTime time_of_last_received_packet,
QuicTime now,
const RttStats* rtt_stats,
QuicTime::Delta delayed_ack_time) {
- received_packet_manager_.MaybeUpdateAckTimeout(
- should_last_packet_instigate_acks, last_received_packet_number,
- time_of_last_received_packet, now, rtt_stats, delayed_ack_time);
+ if (!supports_multiple_packet_number_spaces_) {
+ received_packet_managers_[0].MaybeUpdateAckTimeout(
+ should_last_packet_instigate_acks, last_received_packet_number,
+ time_of_last_received_packet, now, rtt_stats, delayed_ack_time);
+ return;
+ }
+ received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+ decrypted_packet_level)]
+ .MaybeUpdateAckTimeout(
+ should_last_packet_instigate_acks, last_received_packet_number,
+ time_of_last_received_packet, now, rtt_stats, delayed_ack_time);
}
-void UberReceivedPacketManager::ResetAckStates() {
- received_packet_manager_.ResetAckStates();
+void UberReceivedPacketManager::ResetAckStates(
+ EncryptionLevel encryption_level) {
+ if (!supports_multiple_packet_number_spaces_) {
+ received_packet_managers_[0].ResetAckStates();
+ return;
+ }
+ received_packet_managers_[QuicUtils::GetPacketNumberSpace(encryption_level)]
+ .ResetAckStates();
}
-bool UberReceivedPacketManager::AckFrameUpdated() const {
- return received_packet_manager_.ack_frame_updated();
+void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport() {
+ if (supports_multiple_packet_number_spaces_) {
+ QUIC_BUG << "Multiple packet number spaces has already been enabled";
+ return;
+ }
+ if (received_packet_managers_[0].GetLargestObserved().IsInitialized()) {
+ QUIC_BUG << "Try to enable multiple packet number spaces support after any "
+ "packet has been received.";
+ return;
+ }
+
+ supports_multiple_packet_number_spaces_ = true;
}
-QuicPacketNumber UberReceivedPacketManager::GetLargestObserved() const {
- return received_packet_manager_.GetLargestObserved();
+bool UberReceivedPacketManager::IsAckFrameUpdated() const {
+ if (!supports_multiple_packet_number_spaces_) {
+ return received_packet_managers_[0].ack_frame_updated();
+ }
+ for (const auto& received_packet_manager : received_packet_managers_) {
+ if (received_packet_manager.ack_frame_updated()) {
+ return true;
+ }
+ }
+ return false;
}
-QuicTime UberReceivedPacketManager::GetAckTimeout() const {
- return received_packet_manager_.ack_timeout();
+QuicPacketNumber UberReceivedPacketManager::GetLargestObserved(
+ EncryptionLevel decrypted_packet_level) const {
+ if (!supports_multiple_packet_number_spaces_) {
+ return received_packet_managers_[0].GetLargestObserved();
+ }
+ return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
+ decrypted_packet_level)]
+ .GetLargestObserved();
+}
+
+QuicTime UberReceivedPacketManager::GetAckTimeout(
+ PacketNumberSpace packet_number_space) const {
+ if (!supports_multiple_packet_number_spaces_) {
+ return received_packet_managers_[0].ack_timeout();
+ }
+ return received_packet_managers_[packet_number_space].ack_timeout();
+}
+
+QuicTime UberReceivedPacketManager::GetEarliestAckTimeout() const {
+ DCHECK(supports_multiple_packet_number_spaces_);
+ QuicTime ack_timeout = QuicTime::Zero();
+ // Returns the earliest non-zero ack timeout.
+ for (const auto& received_packet_manager : received_packet_managers_) {
+ const QuicTime timeout = received_packet_manager.ack_timeout();
+ if (!ack_timeout.IsInitialized()) {
+ ack_timeout = timeout;
+ continue;
+ }
+ if (timeout.IsInitialized()) {
+ ack_timeout = std::min(ack_timeout, timeout);
+ }
+ }
+ return ack_timeout;
}
QuicPacketNumber UberReceivedPacketManager::PeerFirstSendingPacketNumber()
const {
- return received_packet_manager_.PeerFirstSendingPacketNumber();
+ DCHECK(!supports_multiple_packet_number_spaces_);
+ return received_packet_managers_[0].PeerFirstSendingPacketNumber();
}
QuicPacketNumber UberReceivedPacketManager::peer_least_packet_awaiting_ack()
const {
- return received_packet_manager_.peer_least_packet_awaiting_ack();
+ DCHECK(!supports_multiple_packet_number_spaces_);
+ return received_packet_managers_[0].peer_least_packet_awaiting_ack();
}
size_t UberReceivedPacketManager::min_received_before_ack_decimation() const {
- return received_packet_manager_.min_received_before_ack_decimation();
+ return received_packet_managers_[0].min_received_before_ack_decimation();
}
void UberReceivedPacketManager::set_min_received_before_ack_decimation(
size_t new_value) {
- received_packet_manager_.set_min_received_before_ack_decimation(new_value);
+ for (auto& received_packet_manager : received_packet_managers_) {
+ received_packet_manager.set_min_received_before_ack_decimation(new_value);
+ }
}
size_t UberReceivedPacketManager::ack_frequency_before_ack_decimation() const {
- return received_packet_manager_.ack_frequency_before_ack_decimation();
+ return received_packet_managers_[0].ack_frequency_before_ack_decimation();
}
void UberReceivedPacketManager::set_ack_frequency_before_ack_decimation(
size_t new_value) {
- received_packet_manager_.set_ack_frequency_before_ack_decimation(new_value);
+ for (auto& received_packet_manager : received_packet_managers_) {
+ received_packet_manager.set_ack_frequency_before_ack_decimation(new_value);
+ }
}
const QuicAckFrame& UberReceivedPacketManager::ack_frame() const {
- return received_packet_manager_.ack_frame();
+ DCHECK(!supports_multiple_packet_number_spaces_);
+ return received_packet_managers_[0].ack_frame();
}
void UberReceivedPacketManager::set_max_ack_ranges(size_t max_ack_ranges) {
- received_packet_manager_.set_max_ack_ranges(max_ack_ranges);
+ for (auto& received_packet_manager : received_packet_managers_) {
+ received_packet_manager.set_max_ack_ranges(max_ack_ranges);
+ }
}
void UberReceivedPacketManager::set_save_timestamps(bool save_timestamps) {
- received_packet_manager_.set_save_timestamps(save_timestamps);
+ for (auto& received_packet_manager : received_packet_managers_) {
+ received_packet_manager.set_save_timestamps(save_timestamps);
+ }
}
} // namespace quic
diff --git a/quic/core/uber_received_packet_manager.h b/quic/core/uber_received_packet_manager.h
index 367a7c0..62348b9 100644
--- a/quic/core/uber_received_packet_manager.h
+++ b/quic/core/uber_received_packet_manager.h
@@ -9,7 +9,9 @@
namespace quic {
-// This class simply wraps a single received packet manager.
+// This class comprises multiple received packet managers, one per packet number
+// space. Please note, if multiple packet number spaces is not supported, only
+// one received packet manager will be used.
class QUIC_EXPORT_PRIVATE UberReceivedPacketManager {
public:
explicit UberReceivedPacketManager(QuicConnectionStats* stats);
@@ -21,23 +23,28 @@
void SetFromConfig(const QuicConfig& config, Perspective perspective);
// Checks if we are still waiting for the packet with |packet_number|.
- bool IsAwaitingPacket(QuicPacketNumber packet_number) const;
+ bool IsAwaitingPacket(EncryptionLevel decrypted_packet_level,
+ QuicPacketNumber packet_number) const;
// Called after a packet has been successfully decrypted and its header has
// been parsed.
- void RecordPacketReceived(const QuicPacketHeader& header,
+ void RecordPacketReceived(EncryptionLevel decrypted_packet_level,
+ const QuicPacketHeader& header,
QuicTime receipt_time);
// Retrieves a frame containing a QuicAckFrame. The ack frame must be
// serialized before another packet is received, or it will change.
- const QuicFrame GetUpdatedAckFrame(QuicTime approximate_now);
+ const QuicFrame GetUpdatedAckFrame(PacketNumberSpace packet_number_space,
+ QuicTime approximate_now);
// Stop ACKing packets before |least_unacked|.
- void DontWaitForPacketsBefore(QuicPacketNumber least_unacked);
+ void DontWaitForPacketsBefore(EncryptionLevel decrypted_packet_level,
+ QuicPacketNumber least_unacked);
// Called after header of last received packet has been successfully processed
// to update ACK timeout.
void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+ EncryptionLevel decrypted_packet_level,
QuicPacketNumber last_received_packet_number,
QuicTime time_of_last_received_packet,
QuicTime now,
@@ -45,17 +52,24 @@
QuicTime::Delta delayed_ack_time);
// Resets ACK related states, called after an ACK is successfully sent.
- void ResetAckStates();
+ void ResetAckStates(EncryptionLevel encryption_level);
+
+ // Called to enable multiple packet number support.
+ void EnableMultiplePacketNumberSpacesSupport();
// Returns true if ACK frame has been updated since GetUpdatedAckFrame was
// last called.
- bool AckFrameUpdated() const;
+ bool IsAckFrameUpdated() const;
// Returns the largest received packet number.
- QuicPacketNumber GetLargestObserved() const;
+ QuicPacketNumber GetLargestObserved(
+ EncryptionLevel decrypted_packet_level) const;
- // Returns current ACK timeout.
- QuicTime GetAckTimeout() const;
+ // Returns ACK timeout of |packet_number_space|.
+ QuicTime GetAckTimeout(PacketNumberSpace packet_number_space) const;
+
+ // Get the earliest ack_timeout of all packet number spaces.
+ QuicTime GetEarliestAckTimeout() const;
// Returns peer first sending packet number to our best knowledge.
QuicPacketNumber PeerFirstSendingPacketNumber() const;
@@ -68,6 +82,10 @@
size_t ack_frequency_before_ack_decimation() const;
void set_ack_frequency_before_ack_decimation(size_t new_value);
+ bool supports_multiple_packet_number_spaces() const {
+ return supports_multiple_packet_number_spaces_;
+ }
+
// For logging purposes.
const QuicAckFrame& ack_frame() const;
@@ -79,7 +97,12 @@
friend class test::QuicConnectionPeer;
friend class test::UberReceivedPacketManagerPeer;
- QuicReceivedPacketManager received_packet_manager_;
+ // One received packet manager per packet number space. If
+ // supports_multiple_packet_number_spaces_ is false, only the first (0 index)
+ // received_packet_manager is used.
+ QuicReceivedPacketManager received_packet_managers_[NUM_PACKET_NUMBER_SPACES];
+
+ bool supports_multiple_packet_number_spaces_;
};
} // namespace quic
diff --git a/quic/core/uber_received_packet_manager_test.cc b/quic/core/uber_received_packet_manager_test.cc
index 4ffb03c..b717178 100644
--- a/quic/core/uber_received_packet_manager_test.cc
+++ b/quic/core/uber_received_packet_manager_test.cc
@@ -7,6 +7,7 @@
#include "net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h"
#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
#include "net/third_party/quiche/src/quic/core/quic_connection_stats.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
@@ -17,19 +18,24 @@
class UberReceivedPacketManagerPeer {
public:
static void SetAckMode(UberReceivedPacketManager* manager, AckMode ack_mode) {
- manager->received_packet_manager_.ack_mode_ = ack_mode;
+ for (auto& received_packet_manager : manager->received_packet_managers_) {
+ received_packet_manager.ack_mode_ = ack_mode;
+ }
}
static void SetFastAckAfterQuiescence(UberReceivedPacketManager* manager,
bool fast_ack_after_quiescence) {
- manager->received_packet_manager_.fast_ack_after_quiescence_ =
- fast_ack_after_quiescence;
+ for (auto& received_packet_manager : manager->received_packet_managers_) {
+ received_packet_manager.fast_ack_after_quiescence_ =
+ fast_ack_after_quiescence;
+ }
}
static void SetAckDecimationDelay(UberReceivedPacketManager* manager,
float ack_decimation_delay) {
- manager->received_packet_manager_.ack_decimation_delay_ =
- ack_decimation_delay;
+ for (auto& received_packet_manager : manager->received_packet_managers_) {
+ received_packet_manager.ack_decimation_delay_ = ack_decimation_delay;
+ }
}
};
@@ -52,31 +58,73 @@
}
void RecordPacketReceipt(uint64_t packet_number) {
- RecordPacketReceipt(packet_number, QuicTime::Zero());
+ RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number);
}
void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
- QuicPacketHeader header;
- header.packet_number = QuicPacketNumber(packet_number);
- manager_->RecordPacketReceived(header, receipt_time);
+ RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, packet_number, receipt_time);
}
- bool HasPendingAck() { return manager_->GetAckTimeout().IsInitialized(); }
+ void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
+ uint64_t packet_number) {
+ RecordPacketReceipt(decrypted_packet_level, packet_number,
+ QuicTime::Zero());
+ }
+
+ void RecordPacketReceipt(EncryptionLevel decrypted_packet_level,
+ uint64_t packet_number,
+ QuicTime receipt_time) {
+ QuicPacketHeader header;
+ header.packet_number = QuicPacketNumber(packet_number);
+ manager_->RecordPacketReceived(decrypted_packet_level, header,
+ receipt_time);
+ }
+
+ bool HasPendingAck() {
+ if (!manager_->supports_multiple_packet_number_spaces()) {
+ return manager_->GetAckTimeout(APPLICATION_DATA).IsInitialized();
+ }
+ return manager_->GetEarliestAckTimeout().IsInitialized();
+ }
void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
uint64_t last_received_packet_number) {
+ MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
+ ENCRYPTION_FORWARD_SECURE,
+ last_received_packet_number);
+ }
+
+ void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks,
+ EncryptionLevel decrypted_packet_level,
+ uint64_t last_received_packet_number) {
manager_->MaybeUpdateAckTimeout(
- should_last_packet_instigate_acks,
+ should_last_packet_instigate_acks, decrypted_packet_level,
QuicPacketNumber(last_received_packet_number), clock_.ApproximateNow(),
clock_.ApproximateNow(), &rtt_stats_, kDelayedAckTime);
}
void CheckAckTimeout(QuicTime time) {
- DCHECK(HasPendingAck() && manager_->GetAckTimeout() == time);
- if (time <= clock_.ApproximateNow()) {
- // ACK timeout expires, send an ACK.
- manager_->ResetAckStates();
- DCHECK(!HasPendingAck());
+ DCHECK(HasPendingAck());
+ if (!manager_->supports_multiple_packet_number_spaces()) {
+ DCHECK(manager_->GetAckTimeout(APPLICATION_DATA) == time);
+ if (time <= clock_.ApproximateNow()) {
+ // ACK timeout expires, send an ACK.
+ manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+ DCHECK(!HasPendingAck());
+ }
+ return;
+ }
+ DCHECK(manager_->GetEarliestAckTimeout() == time);
+ // Send all expired ACKs.
+ for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
+ const QuicTime ack_timeout =
+ manager_->GetAckTimeout(static_cast<PacketNumberSpace>(i));
+ if (!ack_timeout.IsInitialized() ||
+ ack_timeout > clock_.ApproximateNow()) {
+ continue;
+ }
+ manager_->ResetAckStates(
+ QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
}
}
@@ -87,38 +135,39 @@
};
TEST_F(UberReceivedPacketManagerTest, DontWaitForPacketsBefore) {
- QuicPacketHeader header;
- header.packet_number = QuicPacketNumber(2u);
- manager_->RecordPacketReceived(header, QuicTime::Zero());
- header.packet_number = QuicPacketNumber(7u);
- manager_->RecordPacketReceived(header, QuicTime::Zero());
- EXPECT_TRUE(manager_->IsAwaitingPacket(QuicPacketNumber(3u)));
- EXPECT_TRUE(manager_->IsAwaitingPacket(QuicPacketNumber(6u)));
- manager_->DontWaitForPacketsBefore(QuicPacketNumber(4));
- EXPECT_FALSE(manager_->IsAwaitingPacket(QuicPacketNumber(3u)));
- EXPECT_TRUE(manager_->IsAwaitingPacket(QuicPacketNumber(6u)));
+ RecordPacketReceipt(2);
+ RecordPacketReceipt(7);
+ EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(3u)));
+ EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(6u)));
+ manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(4));
+ EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(3u)));
+ EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(6u)));
}
TEST_F(UberReceivedPacketManagerTest, GetUpdatedAckFrame) {
- QuicPacketHeader header;
- header.packet_number = QuicPacketNumber(2u);
QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
- EXPECT_FALSE(manager_->AckFrameUpdated());
- manager_->RecordPacketReceived(header, two_ms);
- EXPECT_TRUE(manager_->AckFrameUpdated());
+ EXPECT_FALSE(manager_->IsAckFrameUpdated());
+ RecordPacketReceipt(2, two_ms);
+ EXPECT_TRUE(manager_->IsAckFrameUpdated());
- QuicFrame ack = manager_->GetUpdatedAckFrame(QuicTime::Zero());
- manager_->ResetAckStates();
- EXPECT_FALSE(manager_->AckFrameUpdated());
+ QuicFrame ack =
+ manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
+ manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+ EXPECT_FALSE(manager_->IsAckFrameUpdated());
// When UpdateReceivedPacketInfo with a time earlier than the time of the
// largest observed packet, make sure that the delta is 0, not negative.
EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
- ack = manager_->GetUpdatedAckFrame(four_ms);
- manager_->ResetAckStates();
- EXPECT_FALSE(manager_->AckFrameUpdated());
+ ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, four_ms);
+ manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+ EXPECT_FALSE(manager_->IsAckFrameUpdated());
// When UpdateReceivedPacketInfo after not having received a new packet,
// the delta should still be accurate.
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
@@ -126,25 +175,22 @@
// And received packet times won't have change.
EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
- header.packet_number = QuicPacketNumber(999u);
- manager_->RecordPacketReceived(header, two_ms);
- header.packet_number = QuicPacketNumber(4u);
- manager_->RecordPacketReceived(header, two_ms);
- header.packet_number = QuicPacketNumber(1000u);
- manager_->RecordPacketReceived(header, two_ms);
- EXPECT_TRUE(manager_->AckFrameUpdated());
- ack = manager_->GetUpdatedAckFrame(two_ms);
- manager_->ResetAckStates();
- EXPECT_FALSE(manager_->AckFrameUpdated());
+ RecordPacketReceipt(999, two_ms);
+ RecordPacketReceipt(4, two_ms);
+ RecordPacketReceipt(1000, two_ms);
+ EXPECT_TRUE(manager_->IsAckFrameUpdated());
+ ack = manager_->GetUpdatedAckFrame(APPLICATION_DATA, two_ms);
+ manager_->ResetAckStates(ENCRYPTION_FORWARD_SECURE);
+ EXPECT_FALSE(manager_->IsAckFrameUpdated());
// UpdateReceivedPacketInfo should discard any times which can't be
// expressed on the wire.
EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
}
TEST_F(UberReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
- EXPECT_FALSE(manager_->AckFrameUpdated());
+ EXPECT_FALSE(manager_->IsAckFrameUpdated());
RecordPacketReceipt(1);
- EXPECT_TRUE(manager_->AckFrameUpdated());
+ EXPECT_TRUE(manager_->IsAckFrameUpdated());
RecordPacketReceipt(6);
RecordPacketReceipt(2,
QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
@@ -156,11 +202,11 @@
TEST_F(UberReceivedPacketManagerTest, LimitAckRanges) {
manager_->set_max_ack_ranges(10);
- EXPECT_FALSE(manager_->AckFrameUpdated());
+ EXPECT_FALSE(manager_->IsAckFrameUpdated());
for (int i = 0; i < 100; ++i) {
RecordPacketReceipt(1 + 2 * i);
- EXPECT_TRUE(manager_->AckFrameUpdated());
- manager_->GetUpdatedAckFrame(QuicTime::Zero());
+ EXPECT_TRUE(manager_->IsAckFrameUpdated());
+ manager_->GetUpdatedAckFrame(APPLICATION_DATA, QuicTime::Zero());
EXPECT_GE(10u, manager_->ack_frame().packets.NumIntervals());
EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
manager_->ack_frame().packets.Max());
@@ -177,9 +223,9 @@
}
TEST_F(UberReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
- EXPECT_FALSE(manager_->AckFrameUpdated());
+ EXPECT_FALSE(manager_->IsAckFrameUpdated());
RecordPacketReceipt(1, QuicTime::Zero());
- EXPECT_TRUE(manager_->AckFrameUpdated());
+ EXPECT_TRUE(manager_->IsAckFrameUpdated());
EXPECT_EQ(1u, manager_->ack_frame().received_packet_times.size());
RecordPacketReceipt(2,
QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
@@ -685,6 +731,69 @@
CheckAckTimeout(clock_.ApproximateNow());
}
+TEST_F(UberReceivedPacketManagerTest,
+ DontWaitForPacketsBeforeMultiplePacketNumberSpaces) {
+ manager_->EnableMultiplePacketNumberSpacesSupport();
+ EXPECT_FALSE(
+ manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE).IsInitialized());
+ EXPECT_FALSE(
+ manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE).IsInitialized());
+ RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 2);
+ RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 4);
+ RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
+ RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 7);
+ EXPECT_EQ(QuicPacketNumber(4),
+ manager_->GetLargestObserved(ENCRYPTION_HANDSHAKE));
+ EXPECT_EQ(QuicPacketNumber(7),
+ manager_->GetLargestObserved(ENCRYPTION_FORWARD_SECURE));
+
+ EXPECT_TRUE(
+ manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
+ EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(3)));
+ EXPECT_TRUE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(4)));
+
+ manager_->DontWaitForPacketsBefore(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(5));
+ EXPECT_TRUE(
+ manager_->IsAwaitingPacket(ENCRYPTION_HANDSHAKE, QuicPacketNumber(3)));
+ EXPECT_FALSE(manager_->IsAwaitingPacket(ENCRYPTION_FORWARD_SECURE,
+ QuicPacketNumber(4)));
+}
+
+TEST_F(UberReceivedPacketManagerTest, AckSendingDifferentPacketNumberSpaces) {
+ manager_->EnableMultiplePacketNumberSpacesSupport();
+ SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
+ EXPECT_FALSE(HasPendingAck());
+ EXPECT_FALSE(manager_->IsAckFrameUpdated());
+
+ RecordPacketReceipt(ENCRYPTION_HANDSHAKE, 3);
+ EXPECT_TRUE(manager_->IsAckFrameUpdated());
+ MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_HANDSHAKE, 3);
+ EXPECT_TRUE(HasPendingAck());
+ // Delayed ack is scheduled.
+ CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+ RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 3);
+ MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 3);
+ EXPECT_TRUE(HasPendingAck());
+ // Delayed ack is scheduled.
+ CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+ RecordPacketReceipt(ENCRYPTION_FORWARD_SECURE, 2);
+ MaybeUpdateAckTimeout(kInstigateAck, ENCRYPTION_FORWARD_SECURE, 2);
+ // Application data ACK should be sent immediately.
+ CheckAckTimeout(clock_.ApproximateNow());
+ // Delayed ACK of handshake data is pending.
+ CheckAckTimeout(clock_.ApproximateNow() + kDelayedAckTime);
+
+ // Send delayed handshake data ACK.
+ clock_.AdvanceTime(kDelayedAckTime);
+ CheckAckTimeout(clock_.ApproximateNow());
+ EXPECT_FALSE(HasPendingAck());
+}
+
} // namespace
} // namespace test
} // namespace quic