| 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/quic_received_packet_manager.h" | 5 #include "net/quic/quic_received_packet_manager.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "net/base/linked_hash_map.h" | 9 #include "net/base/linked_hash_map.h" |
| 10 #include "net/quic/quic_connection_stats.h" | 10 #include "net/quic/quic_connection_stats.h" |
| 11 | 11 |
| 12 using std::make_pair; | 12 using std::make_pair; |
| 13 using std::max; | 13 using std::max; |
| 14 using std::min; | 14 using std::min; |
| 15 | 15 |
| 16 namespace net { | 16 namespace net { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 // The maximum number of packets to ack immediately after a missing packet for | 20 // The maximum number of packets to ack immediately after a missing packet for |
| 21 // fast retransmission to kick in at the sender. This limit is created to | 21 // fast retransmission to kick in at the sender. This limit is created to |
| 22 // reduce the number of acks sent that have no benefit for fast retransmission. | 22 // reduce the number of acks sent that have no benefit for fast retransmission. |
| 23 // Set to the number of nacks needed for fast retransmit plus one for protection | 23 // Set to the number of nacks needed for fast retransmit plus one for protection |
| 24 // against an ack loss | 24 // against an ack loss |
| 25 const size_t kMaxPacketsAfterNewMissing = 4; | 25 const size_t kMaxPacketsAfterNewMissing = 4; |
| 26 | |
| 27 } | 26 } |
| 28 | 27 |
| 29 QuicReceivedPacketManager::QuicReceivedPacketManager( | 28 QuicReceivedPacketManager::QuicReceivedPacketManager( |
| 30 CongestionFeedbackType congestion_type, | 29 CongestionFeedbackType congestion_type, |
| 31 QuicConnectionStats* stats) | 30 QuicConnectionStats* stats) |
| 32 : packets_entropy_hash_(0), | 31 : packets_entropy_hash_(0), |
| 33 largest_sequence_number_(0), | 32 largest_sequence_number_(0), |
| 34 peer_largest_observed_packet_(0), | 33 peer_largest_observed_packet_(0), |
| 35 least_packet_awaited_by_peer_(1), | 34 least_packet_awaited_by_peer_(1), |
| 36 peer_least_packet_awaiting_ack_(0), | 35 peer_least_packet_awaiting_ack_(0), |
| 37 time_largest_observed_(QuicTime::Zero()), | 36 time_largest_observed_(QuicTime::Zero()), |
| 38 receive_algorithm_(ReceiveAlgorithmInterface::Create(congestion_type)), | 37 receive_algorithm_(ReceiveAlgorithmInterface::Create(congestion_type)), |
| 39 stats_(stats) { | 38 stats_(stats) { |
| 40 received_info_.largest_observed = 0; | 39 received_info_.largest_observed = 0; |
| 41 received_info_.entropy_hash = 0; | 40 received_info_.entropy_hash = 0; |
| 42 } | 41 } |
| 43 | 42 |
| 44 QuicReceivedPacketManager::~QuicReceivedPacketManager() {} | 43 QuicReceivedPacketManager::~QuicReceivedPacketManager() { |
| 44 } |
| 45 | 45 |
| 46 void QuicReceivedPacketManager::RecordPacketReceived( | 46 void QuicReceivedPacketManager::RecordPacketReceived( |
| 47 QuicByteCount bytes, | 47 QuicByteCount bytes, |
| 48 const QuicPacketHeader& header, | 48 const QuicPacketHeader& header, |
| 49 QuicTime receipt_time) { | 49 QuicTime receipt_time) { |
| 50 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; | 50 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; |
| 51 DCHECK(IsAwaitingPacket(sequence_number)); | 51 DCHECK(IsAwaitingPacket(sequence_number)); |
| 52 | 52 |
| 53 InsertMissingPacketsBetween( | 53 InsertMissingPacketsBetween( |
| 54 &received_info_, | 54 &received_info_, |
| 55 max(received_info_.largest_observed + 1, peer_least_packet_awaiting_ack_), | 55 max(received_info_.largest_observed + 1, peer_least_packet_awaiting_ack_), |
| 56 header.packet_sequence_number); | 56 header.packet_sequence_number); |
| 57 | 57 |
| 58 if (received_info_.largest_observed > header.packet_sequence_number) { | 58 if (received_info_.largest_observed > header.packet_sequence_number) { |
| 59 // We've gotten one of the out of order packets - remove it from our | 59 // We've gotten one of the out of order packets - remove it from our |
| 60 // "missing packets" list. | 60 // "missing packets" list. |
| 61 DVLOG(1) << "Removing " << sequence_number << " from missing list"; | 61 DVLOG(1) << "Removing " << sequence_number << " from missing list"; |
| 62 received_info_.missing_packets.erase(sequence_number); | 62 received_info_.missing_packets.erase(sequence_number); |
| 63 | 63 |
| 64 // Record how out of order stats. | 64 // Record how out of order stats. |
| 65 ++stats_->packets_reordered; | 65 ++stats_->packets_reordered; |
| 66 uint32 sequence_gap = received_info_.largest_observed - sequence_number; | 66 uint32 sequence_gap = received_info_.largest_observed - sequence_number; |
| 67 stats_->max_sequence_reordering = | 67 stats_->max_sequence_reordering = |
| 68 max(stats_->max_sequence_reordering, sequence_gap); | 68 max(stats_->max_sequence_reordering, sequence_gap); |
| 69 uint32 reordering_time_us = | 69 uint32 reordering_time_us = |
| 70 receipt_time.Subtract(time_largest_observed_).ToMicroseconds(); | 70 receipt_time.Subtract(time_largest_observed_).ToMicroseconds(); |
| 71 stats_->max_time_reordering_us = max(stats_->max_time_reordering_us, | 71 stats_->max_time_reordering_us = |
| 72 reordering_time_us); | 72 max(stats_->max_time_reordering_us, reordering_time_us); |
| 73 } | 73 } |
| 74 if (header.packet_sequence_number > received_info_.largest_observed) { | 74 if (header.packet_sequence_number > received_info_.largest_observed) { |
| 75 received_info_.largest_observed = header.packet_sequence_number; | 75 received_info_.largest_observed = header.packet_sequence_number; |
| 76 time_largest_observed_ = receipt_time; | 76 time_largest_observed_ = receipt_time; |
| 77 } | 77 } |
| 78 RecordPacketEntropyHash(sequence_number, header.entropy_hash); | 78 RecordPacketEntropyHash(sequence_number, header.entropy_hash); |
| 79 | 79 |
| 80 receive_algorithm_->RecordIncomingPacket( | 80 receive_algorithm_->RecordIncomingPacket( |
| 81 bytes, sequence_number, receipt_time); | 81 bytes, sequence_number, receipt_time); |
| 82 } | 82 } |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 received_info_.missing_packets.lower_bound(least_unacked)); | 218 received_info_.missing_packets.lower_bound(least_unacked)); |
| 219 return missing_packets_count != received_info_.missing_packets.size(); | 219 return missing_packets_count != received_info_.missing_packets.size(); |
| 220 } | 220 } |
| 221 | 221 |
| 222 void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer( | 222 void QuicReceivedPacketManager::UpdatePacketInformationSentByPeer( |
| 223 const QuicStopWaitingFrame& stop_waiting) { | 223 const QuicStopWaitingFrame& stop_waiting) { |
| 224 // ValidateAck() should fail if peer_least_packet_awaiting_ack_ shrinks. | 224 // ValidateAck() should fail if peer_least_packet_awaiting_ack_ shrinks. |
| 225 DCHECK_LE(peer_least_packet_awaiting_ack_, stop_waiting.least_unacked); | 225 DCHECK_LE(peer_least_packet_awaiting_ack_, stop_waiting.least_unacked); |
| 226 if (stop_waiting.least_unacked > peer_least_packet_awaiting_ack_) { | 226 if (stop_waiting.least_unacked > peer_least_packet_awaiting_ack_) { |
| 227 bool missed_packets = DontWaitForPacketsBefore(stop_waiting.least_unacked); | 227 bool missed_packets = DontWaitForPacketsBefore(stop_waiting.least_unacked); |
| 228 if (missed_packets || stop_waiting.least_unacked > | 228 if (missed_packets || |
| 229 received_info_.largest_observed + 1) { | 229 stop_waiting.least_unacked > received_info_.largest_observed + 1) { |
| 230 DVLOG(1) << "Updating entropy hashed since we missed packets"; | 230 DVLOG(1) << "Updating entropy hashed since we missed packets"; |
| 231 // There were some missing packets that we won't ever get now. Recalculate | 231 // There were some missing packets that we won't ever get now. Recalculate |
| 232 // the received entropy hash. | 232 // the received entropy hash. |
| 233 RecalculateEntropyHash(stop_waiting.least_unacked, | 233 RecalculateEntropyHash(stop_waiting.least_unacked, |
| 234 stop_waiting.entropy_hash); | 234 stop_waiting.entropy_hash); |
| 235 } | 235 } |
| 236 peer_least_packet_awaiting_ack_ = stop_waiting.least_unacked; | 236 peer_least_packet_awaiting_ack_ = stop_waiting.least_unacked; |
| 237 } | 237 } |
| 238 DCHECK(received_info_.missing_packets.empty() || | 238 DCHECK(received_info_.missing_packets.empty() || |
| 239 *received_info_.missing_packets.begin() >= | 239 *received_info_.missing_packets.begin() >= |
| 240 peer_least_packet_awaiting_ack_); | 240 peer_least_packet_awaiting_ack_); |
| 241 } | 241 } |
| 242 | 242 |
| 243 bool QuicReceivedPacketManager::HasMissingPackets() { | 243 bool QuicReceivedPacketManager::HasMissingPackets() { |
| 244 return !received_info_.missing_packets.empty(); | 244 return !received_info_.missing_packets.empty(); |
| 245 } | 245 } |
| 246 | 246 |
| 247 bool QuicReceivedPacketManager::HasNewMissingPackets() { | 247 bool QuicReceivedPacketManager::HasNewMissingPackets() { |
| 248 return HasMissingPackets() && | 248 return HasMissingPackets() && |
| 249 (received_info_.largest_observed - | 249 (received_info_.largest_observed - |
| 250 *received_info_.missing_packets.rbegin()) <= kMaxPacketsAfterNewMissing; | 250 *received_info_.missing_packets.rbegin()) <= |
| 251 kMaxPacketsAfterNewMissing; |
| 251 } | 252 } |
| 252 | 253 |
| 253 } // namespace net | 254 } // namespace net |
| OLD | NEW |