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 |