| // 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. | 
 |  | 
 | #include "net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h" | 
 |  | 
 | #include "net/third_party/quiche/src/quic/core/quic_constants.h" | 
 | #include "net/third_party/quiche/src/quic/core/quic_interval.h" | 
 | #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" | 
 | #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" | 
 |  | 
 | namespace quic { | 
 |  | 
 | namespace { | 
 |  | 
 | const QuicPacketCount kMaxPrintRange = 128; | 
 |  | 
 | uint64_t PacketNumberIntervalLength( | 
 |     const QuicInterval<QuicPacketNumber>& interval) { | 
 |   if (interval.Empty()) { | 
 |     return 0u; | 
 |   } | 
 |   return interval.max() - interval.min(); | 
 | } | 
 | }  // namespace | 
 |  | 
 | bool IsAwaitingPacket(const QuicAckFrame& ack_frame, | 
 |                       QuicPacketNumber packet_number, | 
 |                       QuicPacketNumber peer_least_packet_awaiting_ack) { | 
 |   DCHECK(packet_number.IsInitialized()); | 
 |   return (!peer_least_packet_awaiting_ack.IsInitialized() || | 
 |           packet_number >= peer_least_packet_awaiting_ack) && | 
 |          !ack_frame.packets.Contains(packet_number); | 
 | } | 
 |  | 
 | QuicAckFrame::QuicAckFrame() | 
 |     : ack_delay_time(QuicTime::Delta::Infinite()), | 
 |       ecn_counters_populated(false), | 
 |       ect_0_count(0), | 
 |       ect_1_count(0), | 
 |       ecn_ce_count(0) {} | 
 |  | 
 | QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default; | 
 |  | 
 | QuicAckFrame::~QuicAckFrame() {} | 
 |  | 
 | std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) { | 
 |   os << "{ largest_acked: " << LargestAcked(ack_frame) | 
 |      << ", ack_delay_time: " << ack_frame.ack_delay_time.ToMicroseconds() | 
 |      << ", packets: [ " << ack_frame.packets << " ]" | 
 |      << ", received_packets: [ "; | 
 |   for (const std::pair<QuicPacketNumber, QuicTime>& p : | 
 |        ack_frame.received_packet_times) { | 
 |     os << p.first << " at " << p.second.ToDebuggingValue() << " "; | 
 |   } | 
 |   os << " ]"; | 
 |   os << ", ecn_counters_populated: " << ack_frame.ecn_counters_populated; | 
 |   if (ack_frame.ecn_counters_populated) { | 
 |     os << ", ect_0_count: " << ack_frame.ect_0_count | 
 |        << ", ect_1_count: " << ack_frame.ect_1_count | 
 |        << ", ecn_ce_count: " << ack_frame.ecn_ce_count; | 
 |   } | 
 |  | 
 |   os << " }\n"; | 
 |   return os; | 
 | } | 
 |  | 
 | void QuicAckFrame::Clear() { | 
 |   largest_acked.Clear(); | 
 |   ack_delay_time = QuicTime::Delta::Infinite(); | 
 |   received_packet_times.clear(); | 
 |   packets.Clear(); | 
 | } | 
 |  | 
 | PacketNumberQueue::PacketNumberQueue() {} | 
 | PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default; | 
 | PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default; | 
 | PacketNumberQueue::~PacketNumberQueue() {} | 
 |  | 
 | PacketNumberQueue& PacketNumberQueue::operator=( | 
 |     const PacketNumberQueue& other) = default; | 
 | PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) = | 
 |     default; | 
 |  | 
 | void PacketNumberQueue::Add(QuicPacketNumber packet_number) { | 
 |   if (!packet_number.IsInitialized()) { | 
 |     return; | 
 |   } | 
 |   // Check if the deque is empty | 
 |   if (packet_number_deque_.empty()) { | 
 |     packet_number_deque_.push_front( | 
 |         QuicInterval<QuicPacketNumber>(packet_number, packet_number + 1)); | 
 |     return; | 
 |   } | 
 |   QuicInterval<QuicPacketNumber> back = packet_number_deque_.back(); | 
 |  | 
 |   // Check for the typical case, | 
 |   // when the next packet in order is acked | 
 |   if (back.max() == packet_number) { | 
 |     packet_number_deque_.back().SetMax(packet_number + 1); | 
 |     return; | 
 |   } | 
 |   // Check if the next packet in order is skipped | 
 |   if (back.max() < packet_number) { | 
 |     packet_number_deque_.push_back( | 
 |         QuicInterval<QuicPacketNumber>(packet_number, packet_number + 1)); | 
 |     return; | 
 |   } | 
 |  | 
 |   QuicInterval<QuicPacketNumber> front = packet_number_deque_.front(); | 
 |   // Check if the packet can be  popped on the front | 
 |   if (front.min() > packet_number + 1) { | 
 |     packet_number_deque_.push_front( | 
 |         QuicInterval<QuicPacketNumber>(packet_number, packet_number + 1)); | 
 |     return; | 
 |   } | 
 |   if (front.min() == packet_number + 1) { | 
 |     packet_number_deque_.front().SetMin(packet_number); | 
 |     return; | 
 |   } | 
 |  | 
 |   int i = packet_number_deque_.size() - 1; | 
 |   // Iterating through the queue backwards | 
 |   // to find a proper place for the packet | 
 |   while (i >= 0) { | 
 |     QuicInterval<QuicPacketNumber> packet_interval = packet_number_deque_[i]; | 
 |     DCHECK(packet_interval.min() < packet_interval.max()); | 
 |     // Check if the packet is contained in an interval already | 
 |     if (packet_interval.Contains(packet_number)) { | 
 |       return; | 
 |     } | 
 |  | 
 |     // Check if the packet can extend an interval. | 
 |     if (packet_interval.max() == packet_number) { | 
 |       packet_number_deque_[i].SetMax(packet_number + 1); | 
 |       return; | 
 |     } | 
 |     // Check if the packet can extend an interval | 
 |     // and merge two intervals if needed. | 
 |     // There is no need to merge an interval in the previous | 
 |     // if statement, as all merges will happen here. | 
 |     if (packet_interval.min() == packet_number + 1) { | 
 |       packet_number_deque_[i].SetMin(packet_number); | 
 |       if (i > 0 && packet_number == packet_number_deque_[i - 1].max()) { | 
 |         packet_number_deque_[i - 1].SetMax(packet_interval.max()); | 
 |         packet_number_deque_.erase(packet_number_deque_.begin() + i); | 
 |       } | 
 |       return; | 
 |     } | 
 |  | 
 |     // Check if we need to make a new interval for the packet | 
 |     if (packet_interval.max() < packet_number + 1) { | 
 |       packet_number_deque_.insert( | 
 |           packet_number_deque_.begin() + i + 1, | 
 |           QuicInterval<QuicPacketNumber>(packet_number, packet_number + 1)); | 
 |       return; | 
 |     } | 
 |     i--; | 
 |   } | 
 | } | 
 |  | 
 | void PacketNumberQueue::AddRange(QuicPacketNumber lower, | 
 |                                  QuicPacketNumber higher) { | 
 |   if (!lower.IsInitialized() || !higher.IsInitialized() || lower >= higher) { | 
 |     return; | 
 |   } | 
 |   if (packet_number_deque_.empty()) { | 
 |     packet_number_deque_.push_front( | 
 |         QuicInterval<QuicPacketNumber>(lower, higher)); | 
 |     return; | 
 |   } | 
 |   QuicInterval<QuicPacketNumber> back = packet_number_deque_.back(); | 
 |  | 
 |   if (back.max() == lower) { | 
 |     // Check for the typical case, | 
 |     // when the next packet in order is acked | 
 |     packet_number_deque_.back().SetMax(higher); | 
 |     return; | 
 |   } | 
 |   if (back.max() < lower) { | 
 |     // Check if the next packet in order is skipped | 
 |     packet_number_deque_.push_back( | 
 |         QuicInterval<QuicPacketNumber>(lower, higher)); | 
 |     return; | 
 |   } | 
 |   QuicInterval<QuicPacketNumber> front = packet_number_deque_.front(); | 
 |   // Check if the packets are being added in reverse order | 
 |   if (front.min() == higher) { | 
 |     packet_number_deque_.front().SetMin(lower); | 
 |   } else if (front.min() > higher) { | 
 |     packet_number_deque_.push_front( | 
 |         QuicInterval<QuicPacketNumber>(lower, higher)); | 
 |  | 
 |   } else { | 
 |     // Ranges must be above or below all existing ranges. | 
 |     QUIC_BUG << "AddRange only supports adding packets above or below the " | 
 |              << "current min:" << Min() << " and max:" << Max() | 
 |              << ", but adding [" << lower << "," << higher << ")"; | 
 |   } | 
 | } | 
 |  | 
 | bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) { | 
 |   if (!higher.IsInitialized() || Empty()) { | 
 |     return false; | 
 |   } | 
 |   const QuicPacketNumber old_min = Min(); | 
 |   while (!packet_number_deque_.empty()) { | 
 |     QuicInterval<QuicPacketNumber> front = packet_number_deque_.front(); | 
 |     if (front.max() < higher) { | 
 |       packet_number_deque_.pop_front(); | 
 |     } else if (front.min() < higher && front.max() >= higher) { | 
 |       packet_number_deque_.front().SetMin(higher); | 
 |       if (front.max() == higher) { | 
 |         packet_number_deque_.pop_front(); | 
 |       } | 
 |       break; | 
 |     } else { | 
 |       break; | 
 |     } | 
 |   } | 
 |  | 
 |   return Empty() || old_min != Min(); | 
 | } | 
 |  | 
 | void PacketNumberQueue::RemoveSmallestInterval() { | 
 |   QUIC_BUG_IF(packet_number_deque_.size() < 2) | 
 |       << (Empty() ? "No intervals to remove." | 
 |                   : "Can't remove the last interval."); | 
 |   packet_number_deque_.pop_front(); | 
 | } | 
 |  | 
 | void PacketNumberQueue::Clear() { | 
 |   packet_number_deque_.clear(); | 
 | } | 
 |  | 
 | bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const { | 
 |   if (!packet_number.IsInitialized() || packet_number_deque_.empty()) { | 
 |     return false; | 
 |   } | 
 |   if (packet_number_deque_.front().min() > packet_number || | 
 |       packet_number_deque_.back().max() <= packet_number) { | 
 |     return false; | 
 |   } | 
 |   for (QuicInterval<QuicPacketNumber> interval : packet_number_deque_) { | 
 |     if (interval.Contains(packet_number)) { | 
 |       return true; | 
 |     } | 
 |   } | 
 |   return false; | 
 | } | 
 |  | 
 | bool PacketNumberQueue::Empty() const { | 
 |   return packet_number_deque_.empty(); | 
 | } | 
 |  | 
 | QuicPacketNumber PacketNumberQueue::Min() const { | 
 |   DCHECK(!Empty()); | 
 |   return packet_number_deque_.front().min(); | 
 | } | 
 |  | 
 | QuicPacketNumber PacketNumberQueue::Max() const { | 
 |   DCHECK(!Empty()); | 
 |   return packet_number_deque_.back().max() - 1; | 
 | } | 
 |  | 
 | QuicPacketCount PacketNumberQueue::NumPacketsSlow() const { | 
 |   QuicPacketCount n_packets = 0; | 
 |   for (QuicInterval<QuicPacketNumber> interval : packet_number_deque_) { | 
 |     n_packets += PacketNumberIntervalLength(interval); | 
 |   } | 
 |   return n_packets; | 
 | } | 
 |  | 
 | size_t PacketNumberQueue::NumIntervals() const { | 
 |   return packet_number_deque_.size(); | 
 | } | 
 |  | 
 | PacketNumberQueue::const_iterator PacketNumberQueue::begin() const { | 
 |   return packet_number_deque_.begin(); | 
 | } | 
 |  | 
 | PacketNumberQueue::const_iterator PacketNumberQueue::end() const { | 
 |   return packet_number_deque_.end(); | 
 | } | 
 |  | 
 | PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const { | 
 |   return packet_number_deque_.rbegin(); | 
 | } | 
 |  | 
 | PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const { | 
 |   return packet_number_deque_.rend(); | 
 | } | 
 |  | 
 | QuicPacketCount PacketNumberQueue::LastIntervalLength() const { | 
 |   DCHECK(!Empty()); | 
 |   return PacketNumberIntervalLength(packet_number_deque_.back()); | 
 | } | 
 |  | 
 | // Largest min...max range for packet numbers where we print the numbers | 
 | // explicitly. If bigger than this, we print as a range  [a,d] rather | 
 | // than [a b c d] | 
 |  | 
 | std::ostream& operator<<(std::ostream& os, const PacketNumberQueue& q) { | 
 |   for (const QuicInterval<QuicPacketNumber>& interval : q) { | 
 |     // Print as a range if there is a pathological condition. | 
 |     if ((interval.min() >= interval.max()) || | 
 |         (interval.max() - interval.min() > kMaxPrintRange)) { | 
 |       // If min>max, it's really a bug, so QUIC_BUG it to | 
 |       // catch it in development. | 
 |       QUIC_BUG_IF(interval.min() >= interval.max()) | 
 |           << "Ack Range minimum (" << interval.min() << "Not less than max (" | 
 |           << interval.max() << ")"; | 
 |       // print range as min...max rather than full list. | 
 |       // in the event of a bug, the list could be very big. | 
 |       os << interval.min() << "..." << (interval.max() - 1) << " "; | 
 |     } else { | 
 |       for (QuicPacketNumber packet_number = interval.min(); | 
 |            packet_number < interval.max(); ++packet_number) { | 
 |         os << packet_number << " "; | 
 |       } | 
 |     } | 
 |   } | 
 |   return os; | 
 | } | 
 |  | 
 | }  // namespace quic |