| // 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 "quiche/quic/core/quic_interval.h" |
| #include "quiche/quic/core/quic_interval_set.h" |
| #include "quiche/quic/core/quic_types.h" |
| #include "quiche/quic/platform/api/quic_export.h" |
| #include "quiche/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. |
| absl::optional<QuicEcnCounts> ecn_counters; |
| }; |
| |
| // 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_ |