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