// 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 #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::const_iterator; using const_reverse_iterator = QuicIntervalSet::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 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 for when packets arrived. 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_