| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "quic/core/uber_received_packet_manager.h" |
| |
| #include "quic/core/quic_types.h" |
| #include "quic/core/quic_utils.h" |
| #include "quic/platform/api/quic_bug_tracker.h" |
| |
| namespace quic { |
| |
| UberReceivedPacketManager::UberReceivedPacketManager(QuicConnectionStats* 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) { |
| 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 { |
| 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) { |
| 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) { |
| 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) { |
| 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 now, |
| const RttStats* rtt_stats) { |
| if (!supports_multiple_packet_number_spaces_) { |
| received_packet_managers_[0].MaybeUpdateAckTimeout( |
| should_last_packet_instigate_acks, last_received_packet_number, now, |
| rtt_stats); |
| return; |
| } |
| received_packet_managers_[QuicUtils::GetPacketNumberSpace( |
| decrypted_packet_level)] |
| .MaybeUpdateAckTimeout(should_last_packet_instigate_acks, |
| last_received_packet_number, now, rtt_stats); |
| } |
| |
| 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(); |
| if (encryption_level == ENCRYPTION_INITIAL) { |
| // After one Initial ACK is sent, the others should be sent 'immediately'. |
| received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay( |
| kAlarmGranularity); |
| } |
| } |
| |
| void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport( |
| Perspective perspective) { |
| if (supports_multiple_packet_number_spaces_) { |
| QUIC_BUG(quic_bug_10495_1) |
| << "Multiple packet number spaces has already been enabled"; |
| return; |
| } |
| if (received_packet_managers_[0].GetLargestObserved().IsInitialized()) { |
| QUIC_BUG(quic_bug_10495_2) |
| << "Try to enable multiple packet number spaces support after any " |
| "packet has been received."; |
| return; |
| } |
| // In IETF QUIC, the peer is expected to acknowledge packets in Initial and |
| // Handshake packets with minimal delay. |
| if (perspective == Perspective::IS_CLIENT) { |
| // Delay the first server ACK, because server ACKs are padded to |
| // full size and count towards the amplification limit. |
| received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay( |
| kAlarmGranularity); |
| } |
| received_packet_managers_[HANDSHAKE_DATA].set_local_max_ack_delay( |
| kAlarmGranularity); |
| |
| supports_multiple_packet_number_spaces_ = true; |
| } |
| |
| 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; |
| } |
| |
| 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 { |
| 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; |
| } |
| |
| bool UberReceivedPacketManager::IsAckFrameEmpty( |
| PacketNumberSpace packet_number_space) const { |
| if (!supports_multiple_packet_number_spaces_) { |
| return received_packet_managers_[0].IsAckFrameEmpty(); |
| } |
| return received_packet_managers_[packet_number_space].IsAckFrameEmpty(); |
| } |
| |
| QuicPacketNumber UberReceivedPacketManager::peer_least_packet_awaiting_ack() |
| const { |
| QUICHE_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_managers_[0].min_received_before_ack_decimation(); |
| } |
| |
| void UberReceivedPacketManager::set_min_received_before_ack_decimation( |
| size_t new_value) { |
| for (auto& received_packet_manager : received_packet_managers_) { |
| received_packet_manager.set_min_received_before_ack_decimation(new_value); |
| } |
| } |
| |
| void UberReceivedPacketManager::set_ack_frequency(size_t new_value) { |
| for (auto& received_packet_manager : received_packet_managers_) { |
| received_packet_manager.set_ack_frequency(new_value); |
| } |
| } |
| |
| const QuicAckFrame& UberReceivedPacketManager::ack_frame() const { |
| QUICHE_DCHECK(!supports_multiple_packet_number_spaces_); |
| return received_packet_managers_[0].ack_frame(); |
| } |
| |
| const QuicAckFrame& UberReceivedPacketManager::GetAckFrame( |
| PacketNumberSpace packet_number_space) const { |
| QUICHE_DCHECK(supports_multiple_packet_number_spaces_); |
| return received_packet_managers_[packet_number_space].ack_frame(); |
| } |
| |
| void UberReceivedPacketManager::set_max_ack_ranges(size_t 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) { |
| for (auto& received_packet_manager : received_packet_managers_) { |
| received_packet_manager.set_save_timestamps( |
| save_timestamps, supports_multiple_packet_number_spaces_); |
| } |
| } |
| |
| void UberReceivedPacketManager::OnAckFrequencyFrame( |
| const QuicAckFrequencyFrame& frame) { |
| if (!supports_multiple_packet_number_spaces_) { |
| QUIC_BUG(quic_bug_10495_3) |
| << "Received AckFrequencyFrame when multiple packet number spaces " |
| "is not supported"; |
| return; |
| } |
| received_packet_managers_[APPLICATION_DATA].OnAckFrequencyFrame(frame); |
| } |
| |
| } // namespace quic |