blob: c9c46d41d3c45dfb983e1e4d8109f9ad0022fd98 [file] [log] [blame]
// Copyright (c) 2016 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_FRAMES_QUIC_ACK_FRAME_H_
#define QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
#include <ostream>
#include "quic/core/quic_interval.h"
#include "quic/core/quic_interval_set.h"
#include "quic/core/quic_types.h"
#include "quic/platform/api/quic_containers.h"
#include "quic/platform/api/quic_export.h"
#include "quic/platform/api/quic_flags.h"
namespace quic {
// A sequence of packet numbers where each number is unique. Intended to be used
// in a sliding window fashion, where smaller old packet numbers are removed and
// larger new packet numbers are added, with the occasional random access.
class QUIC_EXPORT_PRIVATE PacketNumberQueue {
public:
PacketNumberQueue();
PacketNumberQueue(const PacketNumberQueue& other);
PacketNumberQueue(PacketNumberQueue&& other);
~PacketNumberQueue();
PacketNumberQueue& operator=(const PacketNumberQueue& other);
PacketNumberQueue& operator=(PacketNumberQueue&& other);
using const_iterator = QuicIntervalSet<QuicPacketNumber>::const_iterator;
using const_reverse_iterator =
QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator;
// Adds |packet_number| to the set of packets in the queue.
void Add(QuicPacketNumber packet_number);
// Adds packets between [lower, higher) to the set of packets in the queue.
// No-op if |higher| < |lower|.
// NOTE(wub): Only used in tests as of Nov 2019.
void AddRange(QuicPacketNumber lower, QuicPacketNumber higher);
// Removes packets with values less than |higher| from the set of packets in
// the queue. Returns true if packets were removed.
bool RemoveUpTo(QuicPacketNumber higher);
// Removes the smallest interval in the queue.
void RemoveSmallestInterval();
// Clear this packet number queue.
void Clear();
// Returns true if the queue contains |packet_number|.
bool Contains(QuicPacketNumber packet_number) const;
// Returns true if the queue is empty.
bool Empty() const;
// Returns the minimum packet number stored in the queue. It is undefined
// behavior to call this if the queue is empty.
QuicPacketNumber Min() const;
// Returns the maximum packet number stored in the queue. It is undefined
// behavior to call this if the queue is empty.
QuicPacketNumber Max() const;
// Returns the number of unique packets stored in the queue. Inefficient; only
// exposed for testing.
QuicPacketCount NumPacketsSlow() const;
// Returns the number of disjoint packet number intervals contained in the
// queue.
size_t NumIntervals() const;
// Returns the length of last interval.
QuicPacketCount LastIntervalLength() const;
// Returns iterators over the packet number intervals.
const_iterator begin() const;
const_iterator end() const;
const_reverse_iterator rbegin() const;
const_reverse_iterator rend() const;
friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
std::ostream& os,
const PacketNumberQueue& q);
private:
QuicIntervalSet<QuicPacketNumber> packet_number_intervals_;
};
struct QUIC_EXPORT_PRIVATE QuicAckFrame {
QuicAckFrame();
QuicAckFrame(const QuicAckFrame& other);
~QuicAckFrame();
void Clear();
friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
std::ostream& os,
const QuicAckFrame& ack_frame);
// The highest packet number we've observed from the peer. When |packets| is
// not empty, it should always be equal to packets.Max(). The |LargestAcked|
// function ensures this invariant in debug mode.
QuicPacketNumber largest_acked;
// Time elapsed since largest_observed() was received until this Ack frame was
// sent.
QuicTime::Delta ack_delay_time = QuicTime::Delta::Infinite();
// Vector of <packet_number, time> for when packets arrived.
// For IETF versions, packet numbers and timestamps in this vector are both in
// ascending orders. Packets received out of order are not saved here.
PacketTimeVector received_packet_times;
// Set of packets.
PacketNumberQueue packets;
// ECN counters, used only in version 99's ACK frame and valid only when
// |ecn_counters_populated| is true.
bool ecn_counters_populated = false;
QuicPacketCount ect_0_count = 0;
QuicPacketCount ect_1_count = 0;
QuicPacketCount ecn_ce_count = 0;
};
// The highest acked packet number we've observed from the peer. If no packets
// have been observed, return 0.
inline QUIC_EXPORT_PRIVATE QuicPacketNumber
LargestAcked(const QuicAckFrame& frame) {
QUICHE_DCHECK(frame.packets.Empty() ||
frame.packets.Max() == frame.largest_acked);
return frame.largest_acked;
}
// True if the packet number is greater than largest_observed or is listed
// as missing.
// Always returns false for packet numbers less than least_unacked.
QUIC_EXPORT_PRIVATE bool IsAwaitingPacket(
const QuicAckFrame& ack_frame,
QuicPacketNumber packet_number,
QuicPacketNumber peer_least_packet_awaiting_ack);
} // namespace quic
#endif // QUICHE_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_