QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 1 | // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h" |
| 6 | |
| 7 | #include "net/third_party/quiche/src/quic/core/quic_constants.h" |
| 8 | #include "net/third_party/quiche/src/quic/core/quic_interval.h" |
| 9 | #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" |
| 10 | #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" |
| 11 | |
| 12 | namespace quic { |
| 13 | |
| 14 | namespace { |
| 15 | |
| 16 | const QuicPacketCount kMaxPrintRange = 128; |
| 17 | |
| 18 | uint64_t PacketNumberIntervalLength( |
| 19 | const QuicInterval<QuicPacketNumber>& interval) { |
| 20 | if (interval.Empty()) { |
| 21 | return 0u; |
| 22 | } |
| 23 | return interval.max() - interval.min(); |
| 24 | } |
| 25 | } // namespace |
| 26 | |
| 27 | bool IsAwaitingPacket(const QuicAckFrame& ack_frame, |
| 28 | QuicPacketNumber packet_number, |
| 29 | QuicPacketNumber peer_least_packet_awaiting_ack) { |
| 30 | DCHECK(packet_number.IsInitialized()); |
| 31 | return (!peer_least_packet_awaiting_ack.IsInitialized() || |
| 32 | packet_number >= peer_least_packet_awaiting_ack) && |
| 33 | !ack_frame.packets.Contains(packet_number); |
| 34 | } |
| 35 | |
| 36 | QuicAckFrame::QuicAckFrame() |
| 37 | : ack_delay_time(QuicTime::Delta::Infinite()), |
| 38 | ecn_counters_populated(false), |
| 39 | ect_0_count(0), |
| 40 | ect_1_count(0), |
| 41 | ecn_ce_count(0) {} |
| 42 | |
| 43 | QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default; |
| 44 | |
| 45 | QuicAckFrame::~QuicAckFrame() {} |
| 46 | |
| 47 | std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) { |
| 48 | os << "{ largest_acked: " << LargestAcked(ack_frame) |
| 49 | << ", ack_delay_time: " << ack_frame.ack_delay_time.ToMicroseconds() |
| 50 | << ", packets: [ " << ack_frame.packets << " ]" |
| 51 | << ", received_packets: [ "; |
| 52 | for (const std::pair<QuicPacketNumber, QuicTime>& p : |
| 53 | ack_frame.received_packet_times) { |
| 54 | os << p.first << " at " << p.second.ToDebuggingValue() << " "; |
| 55 | } |
| 56 | os << " ]"; |
| 57 | os << ", ecn_counters_populated: " << ack_frame.ecn_counters_populated; |
| 58 | if (ack_frame.ecn_counters_populated) { |
| 59 | os << ", ect_0_count: " << ack_frame.ect_0_count |
| 60 | << ", ect_1_count: " << ack_frame.ect_1_count |
| 61 | << ", ecn_ce_count: " << ack_frame.ecn_ce_count; |
| 62 | } |
| 63 | |
| 64 | os << " }\n"; |
| 65 | return os; |
| 66 | } |
| 67 | |
| 68 | void QuicAckFrame::Clear() { |
| 69 | largest_acked.Clear(); |
| 70 | ack_delay_time = QuicTime::Delta::Infinite(); |
| 71 | received_packet_times.clear(); |
| 72 | packets.Clear(); |
| 73 | } |
| 74 | |
| 75 | PacketNumberQueue::PacketNumberQueue() {} |
| 76 | PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default; |
| 77 | PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default; |
| 78 | PacketNumberQueue::~PacketNumberQueue() {} |
| 79 | |
| 80 | PacketNumberQueue& PacketNumberQueue::operator=( |
| 81 | const PacketNumberQueue& other) = default; |
| 82 | PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) = |
| 83 | default; |
| 84 | |
| 85 | void PacketNumberQueue::Add(QuicPacketNumber packet_number) { |
| 86 | if (!packet_number.IsInitialized()) { |
| 87 | return; |
| 88 | } |
| 89 | // Check if the deque is empty |
| 90 | if (packet_number_deque_.empty()) { |
| 91 | packet_number_deque_.push_front( |
| 92 | QuicInterval<QuicPacketNumber>(packet_number, packet_number + 1)); |
| 93 | return; |
| 94 | } |
| 95 | QuicInterval<QuicPacketNumber> back = packet_number_deque_.back(); |
| 96 | |
| 97 | // Check for the typical case, |
| 98 | // when the next packet in order is acked |
| 99 | if (back.max() == packet_number) { |
| 100 | packet_number_deque_.back().SetMax(packet_number + 1); |
| 101 | return; |
| 102 | } |
| 103 | // Check if the next packet in order is skipped |
| 104 | if (back.max() < packet_number) { |
| 105 | packet_number_deque_.push_back( |
| 106 | QuicInterval<QuicPacketNumber>(packet_number, packet_number + 1)); |
| 107 | return; |
| 108 | } |
| 109 | |
| 110 | QuicInterval<QuicPacketNumber> front = packet_number_deque_.front(); |
| 111 | // Check if the packet can be popped on the front |
| 112 | if (front.min() > packet_number + 1) { |
| 113 | packet_number_deque_.push_front( |
| 114 | QuicInterval<QuicPacketNumber>(packet_number, packet_number + 1)); |
| 115 | return; |
| 116 | } |
| 117 | if (front.min() == packet_number + 1) { |
| 118 | packet_number_deque_.front().SetMin(packet_number); |
| 119 | return; |
| 120 | } |
| 121 | |
| 122 | int i = packet_number_deque_.size() - 1; |
| 123 | // Iterating through the queue backwards |
| 124 | // to find a proper place for the packet |
| 125 | while (i >= 0) { |
| 126 | QuicInterval<QuicPacketNumber> packet_interval = packet_number_deque_[i]; |
| 127 | DCHECK(packet_interval.min() < packet_interval.max()); |
| 128 | // Check if the packet is contained in an interval already |
| 129 | if (packet_interval.Contains(packet_number)) { |
| 130 | return; |
| 131 | } |
| 132 | |
| 133 | // Check if the packet can extend an interval. |
| 134 | if (packet_interval.max() == packet_number) { |
| 135 | packet_number_deque_[i].SetMax(packet_number + 1); |
| 136 | return; |
| 137 | } |
| 138 | // Check if the packet can extend an interval |
| 139 | // and merge two intervals if needed. |
| 140 | // There is no need to merge an interval in the previous |
| 141 | // if statement, as all merges will happen here. |
| 142 | if (packet_interval.min() == packet_number + 1) { |
| 143 | packet_number_deque_[i].SetMin(packet_number); |
| 144 | if (i > 0 && packet_number == packet_number_deque_[i - 1].max()) { |
| 145 | packet_number_deque_[i - 1].SetMax(packet_interval.max()); |
| 146 | packet_number_deque_.erase(packet_number_deque_.begin() + i); |
| 147 | } |
| 148 | return; |
| 149 | } |
| 150 | |
| 151 | // Check if we need to make a new interval for the packet |
| 152 | if (packet_interval.max() < packet_number + 1) { |
| 153 | packet_number_deque_.insert( |
| 154 | packet_number_deque_.begin() + i + 1, |
| 155 | QuicInterval<QuicPacketNumber>(packet_number, packet_number + 1)); |
| 156 | return; |
| 157 | } |
| 158 | i--; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | void PacketNumberQueue::AddRange(QuicPacketNumber lower, |
| 163 | QuicPacketNumber higher) { |
| 164 | if (!lower.IsInitialized() || !higher.IsInitialized() || lower >= higher) { |
| 165 | return; |
| 166 | } |
| 167 | if (packet_number_deque_.empty()) { |
| 168 | packet_number_deque_.push_front( |
| 169 | QuicInterval<QuicPacketNumber>(lower, higher)); |
| 170 | return; |
| 171 | } |
| 172 | QuicInterval<QuicPacketNumber> back = packet_number_deque_.back(); |
| 173 | |
| 174 | if (back.max() == lower) { |
| 175 | // Check for the typical case, |
| 176 | // when the next packet in order is acked |
| 177 | packet_number_deque_.back().SetMax(higher); |
| 178 | return; |
| 179 | } |
| 180 | if (back.max() < lower) { |
| 181 | // Check if the next packet in order is skipped |
| 182 | packet_number_deque_.push_back( |
| 183 | QuicInterval<QuicPacketNumber>(lower, higher)); |
| 184 | return; |
| 185 | } |
| 186 | QuicInterval<QuicPacketNumber> front = packet_number_deque_.front(); |
| 187 | // Check if the packets are being added in reverse order |
| 188 | if (front.min() == higher) { |
| 189 | packet_number_deque_.front().SetMin(lower); |
| 190 | } else if (front.min() > higher) { |
| 191 | packet_number_deque_.push_front( |
| 192 | QuicInterval<QuicPacketNumber>(lower, higher)); |
| 193 | |
| 194 | } else { |
| 195 | // Ranges must be above or below all existing ranges. |
| 196 | QUIC_BUG << "AddRange only supports adding packets above or below the " |
| 197 | << "current min:" << Min() << " and max:" << Max() |
| 198 | << ", but adding [" << lower << "," << higher << ")"; |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) { |
| 203 | if (!higher.IsInitialized() || Empty()) { |
| 204 | return false; |
| 205 | } |
| 206 | const QuicPacketNumber old_min = Min(); |
| 207 | while (!packet_number_deque_.empty()) { |
| 208 | QuicInterval<QuicPacketNumber> front = packet_number_deque_.front(); |
| 209 | if (front.max() < higher) { |
| 210 | packet_number_deque_.pop_front(); |
| 211 | } else if (front.min() < higher && front.max() >= higher) { |
| 212 | packet_number_deque_.front().SetMin(higher); |
| 213 | if (front.max() == higher) { |
| 214 | packet_number_deque_.pop_front(); |
| 215 | } |
| 216 | break; |
| 217 | } else { |
| 218 | break; |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | return Empty() || old_min != Min(); |
| 223 | } |
| 224 | |
| 225 | void PacketNumberQueue::RemoveSmallestInterval() { |
| 226 | QUIC_BUG_IF(packet_number_deque_.size() < 2) |
| 227 | << (Empty() ? "No intervals to remove." |
| 228 | : "Can't remove the last interval."); |
| 229 | packet_number_deque_.pop_front(); |
| 230 | } |
| 231 | |
| 232 | void PacketNumberQueue::Clear() { |
| 233 | packet_number_deque_.clear(); |
| 234 | } |
| 235 | |
| 236 | bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const { |
| 237 | if (!packet_number.IsInitialized() || packet_number_deque_.empty()) { |
| 238 | return false; |
| 239 | } |
| 240 | if (packet_number_deque_.front().min() > packet_number || |
| 241 | packet_number_deque_.back().max() <= packet_number) { |
| 242 | return false; |
| 243 | } |
| 244 | for (QuicInterval<QuicPacketNumber> interval : packet_number_deque_) { |
| 245 | if (interval.Contains(packet_number)) { |
| 246 | return true; |
| 247 | } |
| 248 | } |
| 249 | return false; |
| 250 | } |
| 251 | |
| 252 | bool PacketNumberQueue::Empty() const { |
| 253 | return packet_number_deque_.empty(); |
| 254 | } |
| 255 | |
| 256 | QuicPacketNumber PacketNumberQueue::Min() const { |
| 257 | DCHECK(!Empty()); |
| 258 | return packet_number_deque_.front().min(); |
| 259 | } |
| 260 | |
| 261 | QuicPacketNumber PacketNumberQueue::Max() const { |
| 262 | DCHECK(!Empty()); |
| 263 | return packet_number_deque_.back().max() - 1; |
| 264 | } |
| 265 | |
| 266 | QuicPacketCount PacketNumberQueue::NumPacketsSlow() const { |
| 267 | QuicPacketCount n_packets = 0; |
| 268 | for (QuicInterval<QuicPacketNumber> interval : packet_number_deque_) { |
| 269 | n_packets += PacketNumberIntervalLength(interval); |
| 270 | } |
| 271 | return n_packets; |
| 272 | } |
| 273 | |
| 274 | size_t PacketNumberQueue::NumIntervals() const { |
| 275 | return packet_number_deque_.size(); |
| 276 | } |
| 277 | |
| 278 | PacketNumberQueue::const_iterator PacketNumberQueue::begin() const { |
| 279 | return packet_number_deque_.begin(); |
| 280 | } |
| 281 | |
| 282 | PacketNumberQueue::const_iterator PacketNumberQueue::end() const { |
| 283 | return packet_number_deque_.end(); |
| 284 | } |
| 285 | |
| 286 | PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const { |
| 287 | return packet_number_deque_.rbegin(); |
| 288 | } |
| 289 | |
| 290 | PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const { |
| 291 | return packet_number_deque_.rend(); |
| 292 | } |
| 293 | |
| 294 | QuicPacketCount PacketNumberQueue::LastIntervalLength() const { |
| 295 | DCHECK(!Empty()); |
| 296 | return PacketNumberIntervalLength(packet_number_deque_.back()); |
| 297 | } |
| 298 | |
| 299 | // Largest min...max range for packet numbers where we print the numbers |
| 300 | // explicitly. If bigger than this, we print as a range [a,d] rather |
| 301 | // than [a b c d] |
| 302 | |
| 303 | std::ostream& operator<<(std::ostream& os, const PacketNumberQueue& q) { |
| 304 | for (const QuicInterval<QuicPacketNumber>& interval : q) { |
| 305 | // Print as a range if there is a pathological condition. |
| 306 | if ((interval.min() >= interval.max()) || |
| 307 | (interval.max() - interval.min() > kMaxPrintRange)) { |
| 308 | // If min>max, it's really a bug, so QUIC_BUG it to |
| 309 | // catch it in development. |
| 310 | QUIC_BUG_IF(interval.min() >= interval.max()) |
| 311 | << "Ack Range minimum (" << interval.min() << "Not less than max (" |
| 312 | << interval.max() << ")"; |
| 313 | // print range as min...max rather than full list. |
| 314 | // in the event of a bug, the list could be very big. |
| 315 | os << interval.min() << "..." << (interval.max() - 1) << " "; |
| 316 | } else { |
| 317 | for (QuicPacketNumber packet_number = interval.min(); |
| 318 | packet_number < interval.max(); ++packet_number) { |
| 319 | os << packet_number << " "; |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | return os; |
| 324 | } |
| 325 | |
| 326 | } // namespace quic |