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
diff --git a/quic/test_tools/quic_connection_peer.cc b/quic/test_tools/quic_connection_peer.cc index 22d2880..4e344a8 100644 --- a/quic/test_tools/quic_connection_peer.cc +++ b/quic/test_tools/quic_connection_peer.cc
@@ -40,7 +40,9 @@ const bool ack_frame_updated = connection->ack_frame_updated(); const QuicFrame ack_frame = connection->GetUpdatedAckFrame(); if (connection->use_uber_received_packet_manager_) { - connection->uber_received_packet_manager_.received_packet_manager_ + DCHECK(!connection->uber_received_packet_manager_ + .supports_multiple_packet_number_spaces()); + connection->uber_received_packet_manager_.received_packet_managers_[0] .ack_frame_updated_ = ack_frame_updated; } else { connection->received_packet_manager_.ack_frame_updated_ = ack_frame_updated; @@ -265,8 +267,11 @@ AckMode ack_mode) { if (connection->received_packet_manager_.decide_when_to_send_acks()) { if (connection->use_uber_received_packet_manager_) { - connection->uber_received_packet_manager_.received_packet_manager_ - .ack_mode_ = ack_mode; + for (auto& received_packet_manager : + connection->uber_received_packet_manager_ + .received_packet_managers_) { + received_packet_manager.ack_mode_ = ack_mode; + } } else { connection->received_packet_manager_.ack_mode_ = ack_mode; } @@ -281,8 +286,12 @@ bool fast_ack_after_quiescence) { if (connection->received_packet_manager_.decide_when_to_send_acks()) { if (connection->use_uber_received_packet_manager_) { - connection->uber_received_packet_manager_.received_packet_manager_ - .fast_ack_after_quiescence_ = fast_ack_after_quiescence; + for (auto& received_packet_manager : + connection->uber_received_packet_manager_ + .received_packet_managers_) { + received_packet_manager.fast_ack_after_quiescence_ = + fast_ack_after_quiescence; + } } else { connection->received_packet_manager_.fast_ack_after_quiescence_ = fast_ack_after_quiescence; @@ -297,8 +306,11 @@ float ack_decimation_delay) { if (connection->received_packet_manager_.decide_when_to_send_acks()) { if (connection->use_uber_received_packet_manager_) { - connection->uber_received_packet_manager_.received_packet_manager_ - .ack_decimation_delay_ = ack_decimation_delay; + for (auto& received_packet_manager : + connection->uber_received_packet_manager_ + .received_packet_managers_) { + received_packet_manager.ack_decimation_delay_ = ack_decimation_delay; + } } else { connection->received_packet_manager_.ack_decimation_delay_ = ack_decimation_delay;