| // Copyright 2013 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. | 
 |  | 
 | #ifndef QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_ | 
 | #define QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_ | 
 |  | 
 | #include <cstddef> | 
 | #include "quic/core/frames/quic_ack_frequency_frame.h" | 
 | #include "quic/core/quic_config.h" | 
 | #include "quic/core/quic_framer.h" | 
 | #include "quic/core/quic_packets.h" | 
 | #include "quic/platform/api/quic_export.h" | 
 |  | 
 | namespace quic { | 
 |  | 
 | class RttStats; | 
 |  | 
 | namespace test { | 
 | class QuicConnectionPeer; | 
 | class QuicReceivedPacketManagerPeer; | 
 | class UberReceivedPacketManagerPeer; | 
 | }  // namespace test | 
 |  | 
 | struct QuicConnectionStats; | 
 |  | 
 | // 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&) = | 
 |       delete; | 
 |   virtual ~QuicReceivedPacketManager(); | 
 |  | 
 |   void SetFromConfig(const QuicConfig& config, Perspective perspective); | 
 |  | 
 |   // Updates the internal state concerning which packets have been received. | 
 |   // header: the packet header. | 
 |   // timestamp: the arrival time of the packet. | 
 |   virtual void RecordPacketReceived(const QuicPacketHeader& header, | 
 |                                     QuicTime receipt_time); | 
 |  | 
 |   // Checks whether |packet_number| is missing and less than largest observed. | 
 |   virtual bool IsMissing(QuicPacketNumber packet_number); | 
 |  | 
 |   // Checks if we're still waiting for the packet with |packet_number|. | 
 |   virtual bool IsAwaitingPacket(QuicPacketNumber packet_number) const; | 
 |  | 
 |   // Retrieves a frame containing a QuicAckFrame.  The ack frame may not be | 
 |   // changed outside QuicReceivedPacketManager and must be serialized before | 
 |   // another packet is received, or it will change. | 
 |   const QuicFrame GetUpdatedAckFrame(QuicTime approximate_now); | 
 |  | 
 |   // Deletes all missing packets before least unacked. The connection won't | 
 |   // process any packets with packet number before |least_unacked| that it | 
 |   // received after this call. | 
 |   void DontWaitForPacketsBefore(QuicPacketNumber least_unacked); | 
 |  | 
 |   // Called to update ack_timeout_ to the time when an ACK needs to be sent. A | 
 |   // caller can decide whether and when to send an ACK by retrieving | 
 |   // ack_timeout_. If ack_timeout_ is not initialized, no ACK needs to be sent. | 
 |   // Otherwise, ACK needs to be sent by the specified time. | 
 |   void MaybeUpdateAckTimeout(bool should_last_packet_instigate_acks, | 
 |                              QuicPacketNumber last_received_packet_number, | 
 |                              QuicTime now, | 
 |                              const RttStats* rtt_stats); | 
 |  | 
 |   // Resets ACK related states, called after an ACK is successfully sent. | 
 |   void ResetAckStates(); | 
 |  | 
 |   // Returns true if there are any missing packets. | 
 |   bool HasMissingPackets() const; | 
 |  | 
 |   // Returns true when there are new missing packets to be reported within 3 | 
 |   // packets of the largest observed. | 
 |   virtual bool HasNewMissingPackets() const; | 
 |  | 
 |   QuicPacketNumber peer_least_packet_awaiting_ack() const { | 
 |     return peer_least_packet_awaiting_ack_; | 
 |   } | 
 |  | 
 |   virtual bool ack_frame_updated() const; | 
 |  | 
 |   QuicPacketNumber GetLargestObserved() const; | 
 |  | 
 |   // Returns peer first sending packet number to our best knowledge. Considers | 
 |   // least_received_packet_number_ as peer first sending packet number. Please | 
 |   // note, this function should only be called when at least one packet has been | 
 |   // received. | 
 |   QuicPacketNumber PeerFirstSendingPacketNumber() const; | 
 |  | 
 |   // Returns true if ack frame is empty. | 
 |   bool IsAckFrameEmpty() const; | 
 |  | 
 |   void set_connection_stats(QuicConnectionStats* stats) { stats_ = stats; } | 
 |  | 
 |   // For logging purposes. | 
 |   const QuicAckFrame& ack_frame() const { return ack_frame_; } | 
 |  | 
 |   void set_max_ack_ranges(size_t max_ack_ranges) { | 
 |     max_ack_ranges_ = max_ack_ranges; | 
 |   } | 
 |  | 
 |   void set_save_timestamps(bool save_timestamps, bool in_order_packets_only) { | 
 |     save_timestamps_ = save_timestamps; | 
 |     save_timestamps_for_in_order_packets_ = in_order_packets_only; | 
 |   } | 
 |  | 
 |   size_t min_received_before_ack_decimation() const { | 
 |     return min_received_before_ack_decimation_; | 
 |   } | 
 |   void set_min_received_before_ack_decimation(size_t new_value) { | 
 |     min_received_before_ack_decimation_ = new_value; | 
 |   } | 
 |  | 
 |   void set_ack_frequency(size_t new_value) { | 
 |     QUICHE_DCHECK_GT(new_value, 0u); | 
 |     ack_frequency_ = new_value; | 
 |   } | 
 |  | 
 |   void set_local_max_ack_delay(QuicTime::Delta local_max_ack_delay) { | 
 |     local_max_ack_delay_ = local_max_ack_delay; | 
 |   } | 
 |  | 
 |   QuicTime ack_timeout() const { return ack_timeout_; } | 
 |  | 
 |   void OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame); | 
 |  | 
 |  private: | 
 |   friend class test::QuicConnectionPeer; | 
 |   friend class test::QuicReceivedPacketManagerPeer; | 
 |   friend class test::UberReceivedPacketManagerPeer; | 
 |  | 
 |   // Sets ack_timeout_ to |time| if ack_timeout_ is not initialized or > time. | 
 |   void MaybeUpdateAckTimeoutTo(QuicTime time); | 
 |  | 
 |   // Maybe update ack_frequency_ when condition meets. | 
 |   void MaybeUpdateAckFrequency(QuicPacketNumber last_received_packet_number); | 
 |  | 
 |   QuicTime::Delta GetMaxAckDelay(QuicPacketNumber last_received_packet_number, | 
 |                                  const RttStats& rtt_stats) const; | 
 |  | 
 |   bool AckFrequencyFrameReceived() const { | 
 |     return last_ack_frequency_frame_sequence_number_ >= 0; | 
 |   } | 
 |  | 
 |   // Least packet number of the the packet sent by the peer for which it | 
 |   // hasn't received an ack. | 
 |   QuicPacketNumber peer_least_packet_awaiting_ack_; | 
 |  | 
 |   // Received packet information used to produce acks. | 
 |   QuicAckFrame ack_frame_; | 
 |  | 
 |   // True if |ack_frame_| has been updated since UpdateReceivedPacketInfo was | 
 |   // last called. | 
 |   bool ack_frame_updated_; | 
 |  | 
 |   // Maximum number of ack ranges allowed to be stored in the ack frame. | 
 |   size_t max_ack_ranges_; | 
 |  | 
 |   // The time we received the largest_observed packet number, or zero if | 
 |   // no packet numbers have been received since UpdateReceivedPacketInfo. | 
 |   // Needed for calculating ack_delay_time. | 
 |   QuicTime time_largest_observed_; | 
 |  | 
 |   // If true, save timestamps in the ack_frame_. | 
 |   bool save_timestamps_; | 
 |  | 
 |   // If true and |save_timestamps_|, only save timestamps for packets that are | 
 |   // received in order. | 
 |   bool save_timestamps_for_in_order_packets_; | 
 |  | 
 |   // Least packet number received from peer. | 
 |   QuicPacketNumber least_received_packet_number_; | 
 |  | 
 |   QuicConnectionStats* stats_; | 
 |  | 
 |   // How many retransmittable packets have arrived without sending an ack. | 
 |   QuicPacketCount num_retransmittable_packets_received_since_last_ack_sent_; | 
 |   // Ack decimation will start happening after this many packets are received. | 
 |   size_t min_received_before_ack_decimation_; | 
 |   // Ack every n-th packet. | 
 |   size_t ack_frequency_; | 
 |   // The max delay in fraction of min_rtt to use when sending decimated acks. | 
 |   float ack_decimation_delay_; | 
 |   // When true, removes ack decimation's max number of packets(10) before | 
 |   // sending an ack. | 
 |   bool unlimited_ack_decimation_; | 
 |   // When true, only send 1 immediate ACK when reordering is detected. | 
 |   bool one_immediate_ack_; | 
 |   // When true, do not ack immediately upon observation of packet reordering. | 
 |   bool ignore_order_; | 
 |  | 
 |   // The local node's maximum ack delay time. This is the maximum amount of | 
 |   // time to wait before sending an acknowledgement. | 
 |   QuicTime::Delta local_max_ack_delay_; | 
 |   // Time that an ACK needs to be sent. 0 means no ACK is pending. Used when | 
 |   // decide_when_to_send_acks_ is true. | 
 |   QuicTime ack_timeout_; | 
 |  | 
 |   // The time the previous ack-instigating packet was received and processed. | 
 |   QuicTime time_of_previous_received_packet_; | 
 |   // Whether the most recent packet was missing before it was received. | 
 |   bool was_last_packet_missing_; | 
 |  | 
 |   // Last sent largest acked, which gets updated when ACK was successfully sent. | 
 |   QuicPacketNumber last_sent_largest_acked_; | 
 |  | 
 |   // The sequence number of the last received AckFrequencyFrame. Negative if | 
 |   // none received. | 
 |   int64_t last_ack_frequency_frame_sequence_number_; | 
 | }; | 
 |  | 
 | }  // namespace quic | 
 |  | 
 | #endif  // QUICHE_QUIC_CORE_QUIC_RECEIVED_PACKET_MANAGER_H_ |