blob: 1d24651e2e0015a372afde8ba4e621512039ea13 [file] [log] [blame]
// 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.
#include <cstddef>
#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
#include "quiche/quic/core/quic_config.h"
#include "quiche/quic/core/quic_framer.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/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 QUICHE_EXPORT QuicReceivedPacketManager {
explicit QuicReceivedPacketManager(QuicConnectionStats* stats);
QuicReceivedPacketManager(const QuicReceivedPacketManager&) = delete;
QuicReceivedPacketManager& operator=(const QuicReceivedPacketManager&) =
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,
QuicEcnCodepoint ecn);
// 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 last_packet_receipt_time, 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;
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);
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;
void MaybeTrimAckRanges();
// 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