| // 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 |