| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/core/quic_received_packet_manager.h" | 5 #include "net/quic/core/quic_received_packet_manager.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 // The maximum number of packets to ack immediately after a missing packet for | 26 // The maximum number of packets to ack immediately after a missing packet for |
| 27 // fast retransmission to kick in at the sender. This limit is created to | 27 // fast retransmission to kick in at the sender. This limit is created to |
| 28 // reduce the number of acks sent that have no benefit for fast retransmission. | 28 // reduce the number of acks sent that have no benefit for fast retransmission. |
| 29 // Set to the number of nacks needed for fast retransmit plus one for protection | 29 // Set to the number of nacks needed for fast retransmit plus one for protection |
| 30 // against an ack loss | 30 // against an ack loss |
| 31 const size_t kMaxPacketsAfterNewMissing = 4; | 31 const size_t kMaxPacketsAfterNewMissing = 4; |
| 32 } | 32 } |
| 33 | 33 |
| 34 QuicReceivedPacketManager::EntropyTracker::EntropyTracker() | |
| 35 : packets_entropy_hash_(0), first_gap_(1), largest_observed_(0) {} | |
| 36 | |
| 37 QuicReceivedPacketManager::EntropyTracker::~EntropyTracker() {} | |
| 38 | |
| 39 QuicPacketEntropyHash QuicReceivedPacketManager::EntropyTracker::EntropyHash( | |
| 40 QuicPacketNumber packet_number) const { | |
| 41 DCHECK_LE(packet_number, largest_observed_); | |
| 42 if (packet_number == largest_observed_) { | |
| 43 return packets_entropy_hash_; | |
| 44 } | |
| 45 | |
| 46 DCHECK_GE(packet_number, first_gap_); | |
| 47 DCHECK_EQ(first_gap_ + packets_entropy_.size() - 1, largest_observed_); | |
| 48 QuicPacketEntropyHash hash = packets_entropy_hash_; | |
| 49 ReceivedEntropyHashes::const_reverse_iterator it = packets_entropy_.rbegin(); | |
| 50 for (QuicPacketNumber i = 0; i < (largest_observed_ - packet_number); | |
| 51 ++i, ++it) { | |
| 52 hash ^= it->first; | |
| 53 } | |
| 54 return hash; | |
| 55 } | |
| 56 | |
| 57 void QuicReceivedPacketManager::EntropyTracker::RecordPacketEntropyHash( | |
| 58 QuicPacketNumber packet_number, | |
| 59 QuicPacketEntropyHash entropy_hash) { | |
| 60 if (packet_number < first_gap_) { | |
| 61 DVLOG(1) << "Ignoring received packet entropy for packet_number:" | |
| 62 << packet_number | |
| 63 << " less than largest_peer_packet_number:" << first_gap_; | |
| 64 return; | |
| 65 } | |
| 66 // RecordPacketEntropyHash is only intended to be called once per packet. | |
| 67 DCHECK(packet_number > largest_observed_ || | |
| 68 !packets_entropy_[packet_number - first_gap_].second); | |
| 69 | |
| 70 packets_entropy_hash_ ^= entropy_hash; | |
| 71 | |
| 72 // Optimize the typical case of no gaps. | |
| 73 if (packet_number == largest_observed_ + 1 && packets_entropy_.empty()) { | |
| 74 ++first_gap_; | |
| 75 largest_observed_ = packet_number; | |
| 76 return; | |
| 77 } | |
| 78 if (packet_number > largest_observed_) { | |
| 79 for (QuicPacketNumber i = 0; i < (packet_number - largest_observed_ - 1); | |
| 80 ++i) { | |
| 81 packets_entropy_.push_back(std::make_pair(0, false)); | |
| 82 } | |
| 83 packets_entropy_.push_back(std::make_pair(entropy_hash, true)); | |
| 84 largest_observed_ = packet_number; | |
| 85 } else { | |
| 86 packets_entropy_[packet_number - first_gap_] = | |
| 87 std::make_pair(entropy_hash, true); | |
| 88 AdvanceFirstGapAndGarbageCollectEntropyMap(); | |
| 89 } | |
| 90 | |
| 91 DVLOG(2) << "setting cumulative received entropy hash to: " | |
| 92 << static_cast<int>(packets_entropy_hash_) | |
| 93 << " updated with packet number " << packet_number | |
| 94 << " entropy hash: " << static_cast<int>(entropy_hash); | |
| 95 } | |
| 96 | |
| 97 void QuicReceivedPacketManager::EntropyTracker::SetCumulativeEntropyUpTo( | |
| 98 QuicPacketNumber packet_number, | |
| 99 QuicPacketEntropyHash entropy_hash) { | |
| 100 DCHECK_LE(packet_number, largest_observed_); | |
| 101 if (packet_number < first_gap_) { | |
| 102 DVLOG(1) << "Ignoring set entropy at:" << packet_number | |
| 103 << " less than first_gap_:" << first_gap_; | |
| 104 return; | |
| 105 } | |
| 106 while (first_gap_ < packet_number) { | |
| 107 ++first_gap_; | |
| 108 if (!packets_entropy_.empty()) { | |
| 109 packets_entropy_.pop_front(); | |
| 110 } | |
| 111 } | |
| 112 // Compute the current entropy by XORing in all entropies received including | |
| 113 // and since packet_number. | |
| 114 packets_entropy_hash_ = entropy_hash; | |
| 115 for (ReceivedEntropyHashes::const_iterator it = packets_entropy_.begin(); | |
| 116 it != packets_entropy_.end(); ++it) { | |
| 117 packets_entropy_hash_ ^= it->first; | |
| 118 } | |
| 119 | |
| 120 // Garbage collect entries from the beginning of the map. | |
| 121 AdvanceFirstGapAndGarbageCollectEntropyMap(); | |
| 122 } | |
| 123 | |
| 124 void QuicReceivedPacketManager::EntropyTracker:: | |
| 125 AdvanceFirstGapAndGarbageCollectEntropyMap() { | |
| 126 while (!packets_entropy_.empty() && packets_entropy_.front().second) { | |
| 127 ++first_gap_; | |
| 128 packets_entropy_.pop_front(); | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats) | 34 QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats) |
| 133 : peer_least_packet_awaiting_ack_(0), | 35 : peer_least_packet_awaiting_ack_(0), |
| 134 ack_frame_updated_(false), | 36 ack_frame_updated_(false), |
| 135 time_largest_observed_(QuicTime::Zero()), | 37 time_largest_observed_(QuicTime::Zero()), |
| 136 stats_(stats) { | 38 stats_(stats) { |
| 137 ack_frame_.largest_observed = 0; | 39 ack_frame_.largest_observed = 0; |
| 138 ack_frame_.entropy_hash = 0; | |
| 139 } | 40 } |
| 140 | 41 |
| 141 QuicReceivedPacketManager::~QuicReceivedPacketManager() {} | 42 QuicReceivedPacketManager::~QuicReceivedPacketManager() {} |
| 142 | 43 |
| 143 void QuicReceivedPacketManager::RecordPacketReceived( | 44 void QuicReceivedPacketManager::RecordPacketReceived( |
| 144 const QuicPacketHeader& header, | 45 const QuicPacketHeader& header, |
| 145 QuicTime receipt_time) { | 46 QuicTime receipt_time) { |
| 146 QuicPacketNumber packet_number = header.packet_number; | 47 QuicPacketNumber packet_number = header.packet_number; |
| 147 DCHECK(IsAwaitingPacket(packet_number)) << " packet_number:" << packet_number; | 48 DCHECK(IsAwaitingPacket(packet_number)) << " packet_number:" << packet_number; |
| 148 if (!ack_frame_updated_) { | 49 if (!ack_frame_updated_) { |
| 149 ack_frame_.received_packet_times.clear(); | 50 ack_frame_.received_packet_times.clear(); |
| 150 } | 51 } |
| 151 ack_frame_updated_ = true; | 52 ack_frame_updated_ = true; |
| 152 if (ack_frame_.missing) { | 53 ack_frame_.packets.Add(header.packet_number); |
| 153 // Adds the range of packet numbers from max(largest observed + 1, least | |
| 154 // awaiting ack) up to packet_number not including packet_number. | |
| 155 ack_frame_.packets.Add( | |
| 156 max(ack_frame_.largest_observed + 1, peer_least_packet_awaiting_ack_), | |
| 157 packet_number); | |
| 158 } else { | |
| 159 ack_frame_.packets.Add(header.packet_number); | |
| 160 } | |
| 161 | 54 |
| 162 if (ack_frame_.largest_observed > packet_number) { | 55 if (ack_frame_.largest_observed > packet_number) { |
| 163 if (ack_frame_.missing) { | |
| 164 // We've gotten one of the out of order packets - remove it from our | |
| 165 // "missing packets" list. | |
| 166 DVLOG(1) << "Removing " << packet_number << " from missing list"; | |
| 167 ack_frame_.packets.Remove(packet_number); | |
| 168 } | |
| 169 | |
| 170 // Record how out of order stats. | 56 // Record how out of order stats. |
| 171 ++stats_->packets_reordered; | 57 ++stats_->packets_reordered; |
| 172 stats_->max_sequence_reordering = | 58 stats_->max_sequence_reordering = |
| 173 max(stats_->max_sequence_reordering, | 59 max(stats_->max_sequence_reordering, |
| 174 ack_frame_.largest_observed - packet_number); | 60 ack_frame_.largest_observed - packet_number); |
| 175 int64_t reordering_time_us = | 61 int64_t reordering_time_us = |
| 176 (receipt_time - time_largest_observed_).ToMicroseconds(); | 62 (receipt_time - time_largest_observed_).ToMicroseconds(); |
| 177 stats_->max_time_reordering_us = | 63 stats_->max_time_reordering_us = |
| 178 max(stats_->max_time_reordering_us, reordering_time_us); | 64 max(stats_->max_time_reordering_us, reordering_time_us); |
| 179 } | 65 } |
| 180 if (packet_number > ack_frame_.largest_observed) { | 66 if (packet_number > ack_frame_.largest_observed) { |
| 181 ack_frame_.largest_observed = packet_number; | 67 ack_frame_.largest_observed = packet_number; |
| 182 time_largest_observed_ = receipt_time; | 68 time_largest_observed_ = receipt_time; |
| 183 } | 69 } |
| 184 if (ack_frame_.missing) { | |
| 185 entropy_tracker_.RecordPacketEntropyHash(packet_number, | |
| 186 header.entropy_hash); | |
| 187 } | |
| 188 | 70 |
| 189 ack_frame_.received_packet_times.push_back( | 71 ack_frame_.received_packet_times.push_back( |
| 190 std::make_pair(packet_number, receipt_time)); | 72 std::make_pair(packet_number, receipt_time)); |
| 191 } | 73 } |
| 192 | 74 |
| 193 bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) { | 75 bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) { |
| 194 if (ack_frame_.missing) { | |
| 195 return ack_frame_.packets.Contains(packet_number); | |
| 196 } | |
| 197 return packet_number < ack_frame_.largest_observed && | 76 return packet_number < ack_frame_.largest_observed && |
| 198 !ack_frame_.packets.Contains(packet_number); | 77 !ack_frame_.packets.Contains(packet_number); |
| 199 } | 78 } |
| 200 | 79 |
| 201 bool QuicReceivedPacketManager::IsAwaitingPacket( | 80 bool QuicReceivedPacketManager::IsAwaitingPacket( |
| 202 QuicPacketNumber packet_number) { | 81 QuicPacketNumber packet_number) { |
| 203 return ::net::IsAwaitingPacket(ack_frame_, packet_number, | 82 return ::net::IsAwaitingPacket(ack_frame_, packet_number, |
| 204 peer_least_packet_awaiting_ack_); | 83 peer_least_packet_awaiting_ack_); |
| 205 } | 84 } |
| 206 | 85 |
| 207 namespace { | 86 namespace { |
| 208 struct isTooLarge { | 87 struct isTooLarge { |
| 209 explicit isTooLarge(QuicPacketNumber n) : largest_observed_(n) {} | 88 explicit isTooLarge(QuicPacketNumber n) : largest_observed_(n) {} |
| 210 QuicPacketNumber largest_observed_; | 89 QuicPacketNumber largest_observed_; |
| 211 | 90 |
| 212 // Return true if the packet in p is too different from largest_observed_ | 91 // Return true if the packet in p is too different from largest_observed_ |
| 213 // to express. | 92 // to express. |
| 214 bool operator()(const std::pair<QuicPacketNumber, QuicTime>& p) const { | 93 bool operator()(const std::pair<QuicPacketNumber, QuicTime>& p) const { |
| 215 return largest_observed_ - p.first >= std::numeric_limits<uint8_t>::max(); | 94 return largest_observed_ - p.first >= std::numeric_limits<uint8_t>::max(); |
| 216 } | 95 } |
| 217 }; | 96 }; |
| 218 } // namespace | 97 } // namespace |
| 219 | 98 |
| 220 const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame( | 99 const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame( |
| 221 QuicTime approximate_now) { | 100 QuicTime approximate_now) { |
| 222 ack_frame_updated_ = false; | 101 ack_frame_updated_ = false; |
| 223 if (ack_frame_.missing) { | |
| 224 ack_frame_.entropy_hash = EntropyHash(ack_frame_.largest_observed); | |
| 225 } | |
| 226 | |
| 227 if (time_largest_observed_ == QuicTime::Zero()) { | 102 if (time_largest_observed_ == QuicTime::Zero()) { |
| 228 // We have received no packets. | 103 // We have received no packets. |
| 229 ack_frame_.ack_delay_time = QuicTime::Delta::Infinite(); | 104 ack_frame_.ack_delay_time = QuicTime::Delta::Infinite(); |
| 230 } else { | 105 } else { |
| 231 // Ensure the delta is zero if approximate now is "in the past". | 106 // Ensure the delta is zero if approximate now is "in the past". |
| 232 ack_frame_.ack_delay_time = approximate_now < time_largest_observed_ | 107 ack_frame_.ack_delay_time = approximate_now < time_largest_observed_ |
| 233 ? QuicTime::Delta::Zero() | 108 ? QuicTime::Delta::Zero() |
| 234 : approximate_now - time_largest_observed_; | 109 : approximate_now - time_largest_observed_; |
| 235 } | 110 } |
| 236 | 111 |
| 237 // Clear all packet times if any are too far from largest observed. | 112 // Clear all packet times if any are too far from largest observed. |
| 238 // It's expected this is extremely rare. | 113 // It's expected this is extremely rare. |
| 239 for (PacketTimeVector::iterator it = ack_frame_.received_packet_times.begin(); | 114 for (PacketTimeVector::iterator it = ack_frame_.received_packet_times.begin(); |
| 240 it != ack_frame_.received_packet_times.end();) { | 115 it != ack_frame_.received_packet_times.end();) { |
| 241 if (ack_frame_.largest_observed - it->first >= | 116 if (ack_frame_.largest_observed - it->first >= |
| 242 std::numeric_limits<uint8_t>::max()) { | 117 std::numeric_limits<uint8_t>::max()) { |
| 243 it = ack_frame_.received_packet_times.erase(it); | 118 it = ack_frame_.received_packet_times.erase(it); |
| 244 } else { | 119 } else { |
| 245 ++it; | 120 ++it; |
| 246 } | 121 } |
| 247 } | 122 } |
| 248 | 123 |
| 249 return QuicFrame(&ack_frame_); | 124 return QuicFrame(&ack_frame_); |
| 250 } | 125 } |
| 251 | 126 |
| 252 QuicPacketEntropyHash QuicReceivedPacketManager::EntropyHash( | |
| 253 QuicPacketNumber packet_number) const { | |
| 254 return entropy_tracker_.EntropyHash(packet_number); | |
| 255 } | |
| 256 | |
| 257 bool QuicReceivedPacketManager::DontWaitForPacketsBefore( | 127 bool QuicReceivedPacketManager::DontWaitForPacketsBefore( |
| 258 QuicPacketNumber least_unacked) { | 128 QuicPacketNumber least_unacked) { |
| 259 peer_least_packet_awaiting_ack_ = least_unacked; | 129 peer_least_packet_awaiting_ack_ = least_unacked; |
| 260 return ack_frame_.packets.RemoveUpTo(least_unacked); | 130 return ack_frame_.packets.RemoveUpTo(least_unacked); |
| 261 } | 131 } |
| 262 | 132 |
| 263 void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer( | 133 void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer( |
| 264 const QuicStopWaitingFrame& stop_waiting) { | 134 const QuicStopWaitingFrame& stop_waiting) { |
| 265 // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks. | 135 // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks. |
| 266 DCHECK_LE(peer_least_packet_awaiting_ack_, stop_waiting.least_unacked); | 136 DCHECK_LE(peer_least_packet_awaiting_ack_, stop_waiting.least_unacked); |
| 267 if (stop_waiting.least_unacked > peer_least_packet_awaiting_ack_) { | 137 if (stop_waiting.least_unacked > peer_least_packet_awaiting_ack_) { |
| 268 bool packets_updated = DontWaitForPacketsBefore(stop_waiting.least_unacked); | 138 bool packets_updated = DontWaitForPacketsBefore(stop_waiting.least_unacked); |
| 269 if (packets_updated) { | 139 if (packets_updated) { |
| 270 if (ack_frame_.missing) { | |
| 271 DVLOG(1) << "Updating entropy hashed since we missed packets"; | |
| 272 // There were some missing packets that we won't ever get now. | |
| 273 // Recalculate the received entropy hash. | |
| 274 entropy_tracker_.SetCumulativeEntropyUpTo(stop_waiting.least_unacked, | |
| 275 stop_waiting.entropy_hash); | |
| 276 } | |
| 277 // Ack frame gets updated because packets set is updated because of stop | 140 // Ack frame gets updated because packets set is updated because of stop |
| 278 // waiting frame. | 141 // waiting frame. |
| 279 ack_frame_updated_ = true; | 142 ack_frame_updated_ = true; |
| 280 } | 143 } |
| 281 } | 144 } |
| 282 DCHECK(ack_frame_.packets.Empty() || | 145 DCHECK(ack_frame_.packets.Empty() || |
| 283 ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_); | 146 ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_); |
| 284 } | 147 } |
| 285 | 148 |
| 286 bool QuicReceivedPacketManager::HasMissingPackets() const { | 149 bool QuicReceivedPacketManager::HasMissingPackets() const { |
| 287 if (ack_frame_.missing) { | |
| 288 return !ack_frame_.packets.Empty(); | |
| 289 } | |
| 290 | |
| 291 return ack_frame_.packets.NumIntervals() > 1 || | 150 return ack_frame_.packets.NumIntervals() > 1 || |
| 292 (!ack_frame_.packets.Empty() && | 151 (!ack_frame_.packets.Empty() && |
| 293 ack_frame_.packets.Min() > | 152 ack_frame_.packets.Min() > |
| 294 max(QuicPacketNumber(1), peer_least_packet_awaiting_ack_)); | 153 max(QuicPacketNumber(1), peer_least_packet_awaiting_ack_)); |
| 295 } | 154 } |
| 296 | 155 |
| 297 bool QuicReceivedPacketManager::HasNewMissingPackets() const { | 156 bool QuicReceivedPacketManager::HasNewMissingPackets() const { |
| 298 if (ack_frame_.missing) { | |
| 299 return !ack_frame_.packets.Empty() && | |
| 300 (ack_frame_.largest_observed - ack_frame_.packets.Max()) <= | |
| 301 kMaxPacketsAfterNewMissing; | |
| 302 } | |
| 303 | |
| 304 return HasMissingPackets() && | 157 return HasMissingPackets() && |
| 305 ack_frame_.packets.LastIntervalLength() <= kMaxPacketsAfterNewMissing; | 158 ack_frame_.packets.LastIntervalLength() <= kMaxPacketsAfterNewMissing; |
| 306 } | 159 } |
| 307 | 160 |
| 308 size_t QuicReceivedPacketManager::NumTrackedPackets() const { | |
| 309 return entropy_tracker_.size(); | |
| 310 } | |
| 311 | |
| 312 void QuicReceivedPacketManager::SetVersion(QuicVersion version) { | |
| 313 ack_frame_.missing = version <= QUIC_VERSION_33; | |
| 314 } | |
| 315 | |
| 316 bool QuicReceivedPacketManager::ack_frame_updated() const { | 161 bool QuicReceivedPacketManager::ack_frame_updated() const { |
| 317 return ack_frame_updated_; | 162 return ack_frame_updated_; |
| 318 } | 163 } |
| 319 | 164 |
| 320 QuicPacketNumber QuicReceivedPacketManager::GetLargestObserved() const { | 165 QuicPacketNumber QuicReceivedPacketManager::GetLargestObserved() const { |
| 321 return ack_frame_.largest_observed; | 166 return ack_frame_.largest_observed; |
| 322 } | 167 } |
| 323 | 168 |
| 324 } // namespace net | 169 } // namespace net |
| OLD | NEW |