OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_unacked_packet_map.h" | 5 #include "net/quic/quic_unacked_packet_map.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/quic/quic_connection_stats.h" | 9 #include "net/quic/quic_connection_stats.h" |
10 #include "net/quic/quic_utils_chromium.h" | 10 #include "net/quic/quic_utils_chromium.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 it != unacked_packets_.end(); ++it, ++index) { | 27 it != unacked_packets_.end(); ++it, ++index) { |
28 delete it->retransmittable_frames; | 28 delete it->retransmittable_frames; |
29 // Only delete all_transmissions once, for the newest packet. | 29 // Only delete all_transmissions once, for the newest packet. |
30 if (it->all_transmissions != nullptr && | 30 if (it->all_transmissions != nullptr && |
31 index == *it->all_transmissions->rbegin()) { | 31 index == *it->all_transmissions->rbegin()) { |
32 delete it->all_transmissions; | 32 delete it->all_transmissions; |
33 } | 33 } |
34 } | 34 } |
35 } | 35 } |
36 | 36 |
37 // TODO(ianswett): Combine this method with OnPacketSent once packets are always | 37 void QuicUnackedPacketMap::AddSentPacket( |
38 // sent in order and the connection tracks RetransmittableFrames for longer. | 38 const SerializedPacket& packet, |
39 void QuicUnackedPacketMap::AddPacket( | 39 QuicPacketSequenceNumber old_sequence_number, |
40 const SerializedPacket& serialized_packet) { | 40 TransmissionType transmission_type, |
41 DCHECK_GE(serialized_packet.sequence_number, | 41 QuicTime sent_time, |
42 least_unacked_ + unacked_packets_.size()); | 42 QuicByteCount bytes_sent, |
43 while (least_unacked_ + unacked_packets_.size() < | 43 bool set_in_flight) { |
44 serialized_packet.sequence_number) { | 44 QuicPacketSequenceNumber sequence_number = packet.sequence_number; |
| 45 DCHECK_LT(largest_sent_packet_, sequence_number); |
| 46 DCHECK_GE(sequence_number, least_unacked_ + unacked_packets_.size()); |
| 47 while (least_unacked_ + unacked_packets_.size() < sequence_number) { |
45 unacked_packets_.push_back(TransmissionInfo()); | 48 unacked_packets_.push_back(TransmissionInfo()); |
46 unacked_packets_.back().is_unackable = true; | 49 unacked_packets_.back().is_unackable = true; |
47 } | 50 } |
48 unacked_packets_.push_back( | 51 |
49 TransmissionInfo(serialized_packet.retransmittable_frames, | 52 TransmissionInfo info; |
50 serialized_packet.sequence_number_length)); | 53 if (old_sequence_number == 0) { |
51 if (serialized_packet.retransmittable_frames != nullptr && | 54 if (packet.retransmittable_frames != nullptr && |
52 serialized_packet.retransmittable_frames->HasCryptoHandshake() == | 55 packet.retransmittable_frames->HasCryptoHandshake() == IS_HANDSHAKE) { |
53 IS_HANDSHAKE) { | 56 ++pending_crypto_packet_count_; |
54 ++pending_crypto_packet_count_; | 57 } |
| 58 info = TransmissionInfo(packet.retransmittable_frames, |
| 59 packet.sequence_number_length); |
| 60 } else { |
| 61 info = OnRetransmittedPacket( |
| 62 old_sequence_number, sequence_number, transmission_type); |
55 } | 63 } |
| 64 info.sent_time = sent_time; |
| 65 |
| 66 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); |
| 67 if (set_in_flight) { |
| 68 bytes_in_flight_ += bytes_sent; |
| 69 info.bytes_sent = bytes_sent; |
| 70 info.in_flight = true; |
| 71 } |
| 72 unacked_packets_.push_back(info); |
56 } | 73 } |
57 | 74 |
58 void QuicUnackedPacketMap::RemoveObsoletePackets() { | 75 void QuicUnackedPacketMap::RemoveObsoletePackets() { |
59 while (!unacked_packets_.empty()) { | 76 while (!unacked_packets_.empty()) { |
60 if (!IsPacketRemovable(least_unacked_, unacked_packets_.front())) { | 77 if (!IsPacketRemovable(least_unacked_, unacked_packets_.front())) { |
61 break; | 78 break; |
62 } | 79 } |
63 unacked_packets_.pop_front(); | 80 unacked_packets_.pop_front(); |
64 ++least_unacked_; | 81 ++least_unacked_; |
65 } | 82 } |
66 } | 83 } |
67 | 84 |
68 void QuicUnackedPacketMap::OnRetransmittedPacket( | 85 TransmissionInfo QuicUnackedPacketMap::OnRetransmittedPacket( |
69 QuicPacketSequenceNumber old_sequence_number, | 86 QuicPacketSequenceNumber old_sequence_number, |
70 QuicPacketSequenceNumber new_sequence_number, | 87 QuicPacketSequenceNumber new_sequence_number, |
71 TransmissionType transmission_type) { | 88 TransmissionType transmission_type) { |
72 DCHECK_GE(old_sequence_number, least_unacked_); | 89 DCHECK_GE(old_sequence_number, least_unacked_); |
73 DCHECK_LT(old_sequence_number, least_unacked_ + unacked_packets_.size()); | 90 DCHECK_LT(old_sequence_number, least_unacked_ + unacked_packets_.size()); |
74 DCHECK_GE(new_sequence_number, least_unacked_ + unacked_packets_.size()); | 91 DCHECK_GE(new_sequence_number, least_unacked_ + unacked_packets_.size()); |
75 while (least_unacked_ + unacked_packets_.size() < new_sequence_number) { | 92 DCHECK_NE(NOT_RETRANSMISSION, transmission_type); |
76 unacked_packets_.push_back(TransmissionInfo()); | |
77 unacked_packets_.back().is_unackable = true; | |
78 } | |
79 | 93 |
80 // TODO(ianswett): Discard and lose the packet lazily instead of immediately. | 94 // TODO(ianswett): Discard and lose the packet lazily instead of immediately. |
81 TransmissionInfo* transmission_info = | 95 TransmissionInfo* transmission_info = |
82 &unacked_packets_.at(old_sequence_number - least_unacked_); | 96 &unacked_packets_.at(old_sequence_number - least_unacked_); |
83 RetransmittableFrames* frames = transmission_info->retransmittable_frames; | 97 RetransmittableFrames* frames = transmission_info->retransmittable_frames; |
| 98 transmission_info->retransmittable_frames = nullptr; |
84 LOG_IF(DFATAL, frames == nullptr) | 99 LOG_IF(DFATAL, frames == nullptr) |
85 << "Attempt to retransmit packet with no " | 100 << "Attempt to retransmit packet with no " |
86 << "retransmittable frames: " << old_sequence_number; | 101 << "retransmittable frames: " << old_sequence_number; |
87 | 102 |
88 // We keep the old packet in the unacked packet list until it, or one of | |
89 // the retransmissions of it are acked. | |
90 transmission_info->retransmittable_frames = nullptr; | |
91 // Only keep one transmission older than largest observed, because only the | 103 // Only keep one transmission older than largest observed, because only the |
92 // most recent is expected to possibly be a spurious retransmission. | 104 // most recent is expected to possibly be a spurious retransmission. |
93 while (transmission_info->all_transmissions != nullptr && | 105 while (transmission_info->all_transmissions != nullptr && |
94 transmission_info->all_transmissions->size() > 1 && | 106 transmission_info->all_transmissions->size() > 1 && |
95 *(++transmission_info->all_transmissions->begin()) < | 107 *(++transmission_info->all_transmissions->begin()) < |
96 largest_observed_) { | 108 largest_observed_) { |
97 QuicPacketSequenceNumber old_transmission = | 109 QuicPacketSequenceNumber old_transmission = |
98 *transmission_info->all_transmissions->begin(); | 110 *transmission_info->all_transmissions->begin(); |
99 TransmissionInfo* old_info = | 111 TransmissionInfo* old_info = |
100 &unacked_packets_[old_transmission - least_unacked_]; | 112 &unacked_packets_[old_transmission - least_unacked_]; |
(...skipping 10 matching lines...) Expand all Loading... |
111 if (transmission_type == ALL_INITIAL_RETRANSMISSION || | 123 if (transmission_type == ALL_INITIAL_RETRANSMISSION || |
112 transmission_type == ALL_UNACKED_RETRANSMISSION) { | 124 transmission_type == ALL_UNACKED_RETRANSMISSION) { |
113 RemoveAckability(transmission_info); | 125 RemoveAckability(transmission_info); |
114 } else { | 126 } else { |
115 if (transmission_info->all_transmissions == nullptr) { | 127 if (transmission_info->all_transmissions == nullptr) { |
116 transmission_info->all_transmissions = new SequenceNumberList(); | 128 transmission_info->all_transmissions = new SequenceNumberList(); |
117 transmission_info->all_transmissions->push_back(old_sequence_number); | 129 transmission_info->all_transmissions->push_back(old_sequence_number); |
118 } | 130 } |
119 transmission_info->all_transmissions->push_back(new_sequence_number); | 131 transmission_info->all_transmissions->push_back(new_sequence_number); |
120 } | 132 } |
121 unacked_packets_.push_back( | 133 TransmissionInfo info = |
122 TransmissionInfo(frames, | 134 TransmissionInfo(frames, |
123 transmission_info->sequence_number_length, | 135 transmission_info->sequence_number_length, |
124 transmission_type, | 136 transmission_type, |
125 transmission_info->all_transmissions)); | 137 transmission_info->all_transmissions); |
| 138 // Proactively remove obsolete packets so the least unacked can be raised. |
126 RemoveObsoletePackets(); | 139 RemoveObsoletePackets(); |
| 140 return info; |
127 } | 141 } |
128 | 142 |
129 void QuicUnackedPacketMap::ClearAllPreviousRetransmissions() { | 143 void QuicUnackedPacketMap::ClearAllPreviousRetransmissions() { |
130 while (!unacked_packets_.empty() && least_unacked_ < largest_observed_) { | 144 while (!unacked_packets_.empty() && least_unacked_ < largest_observed_) { |
131 // If this packet is in flight, or has retransmittable data, then there is | 145 // If this packet is in flight, or has retransmittable data, then there is |
132 // no point in clearing out any further packets, because they would not | 146 // no point in clearing out any further packets, because they would not |
133 // affect the high water mark. | 147 // affect the high water mark. |
134 TransmissionInfo* info = &unacked_packets_.front(); | 148 TransmissionInfo* info = &unacked_packets_.front(); |
135 if (info->in_flight || info->retransmittable_frames != nullptr) { | 149 if (info->in_flight || info->retransmittable_frames != nullptr) { |
136 break; | 150 break; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 } | 363 } |
350 } | 364 } |
351 return false; | 365 return false; |
352 } | 366 } |
353 | 367 |
354 QuicPacketSequenceNumber | 368 QuicPacketSequenceNumber |
355 QuicUnackedPacketMap::GetLeastUnacked() const { | 369 QuicUnackedPacketMap::GetLeastUnacked() const { |
356 return least_unacked_; | 370 return least_unacked_; |
357 } | 371 } |
358 | 372 |
359 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, | |
360 QuicTime sent_time, | |
361 QuicByteCount bytes_sent, | |
362 bool set_in_flight) { | |
363 DCHECK_GE(sequence_number, least_unacked_); | |
364 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); | |
365 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; | |
366 DCHECK(!info->in_flight); | |
367 | |
368 DCHECK_LT(largest_sent_packet_, sequence_number); | |
369 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); | |
370 info->sent_time = sent_time; | |
371 if (set_in_flight) { | |
372 bytes_in_flight_ += bytes_sent; | |
373 info->bytes_sent = bytes_sent; | |
374 info->in_flight = true; | |
375 } | |
376 } | |
377 | |
378 void QuicUnackedPacketMap::RestoreInFlight( | 373 void QuicUnackedPacketMap::RestoreInFlight( |
379 QuicPacketSequenceNumber sequence_number) { | 374 QuicPacketSequenceNumber sequence_number) { |
380 DCHECK_GE(sequence_number, least_unacked_); | 375 DCHECK_GE(sequence_number, least_unacked_); |
381 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); | 376 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); |
382 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; | 377 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; |
383 DCHECK(!info->in_flight); | 378 DCHECK(!info->in_flight); |
384 DCHECK_NE(0u, info->bytes_sent); | 379 DCHECK_NE(0u, info->bytes_sent); |
385 DCHECK(info->sent_time.IsInitialized()); | 380 DCHECK(info->sent_time.IsInitialized()); |
386 | 381 |
387 bytes_in_flight_ += info->bytes_sent; | 382 bytes_in_flight_ += info->bytes_sent; |
388 info->in_flight = true; | 383 info->in_flight = true; |
389 } | 384 } |
390 | 385 |
391 } // namespace net | 386 } // namespace net |
OLD | NEW |