Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(580)

Side by Side Diff: net/quic/quic_unacked_packet_map.cc

Issue 1660533002: Landing Recent QUIC changes until 01/26/2016 18:14 UTC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_bug_tracker.h" 9 #include "net/quic/quic_bug_tracker.h"
10 #include "net/quic/quic_connection_stats.h" 10 #include "net/quic/quic_connection_stats.h"
11 #include "net/quic/quic_flags.h" 11 #include "net/quic/quic_flags.h"
12 #include "net/quic/quic_utils.h" 12 #include "net/quic/quic_utils.h"
13 #include "net/quic/quic_utils_chromium.h" 13 #include "net/quic/quic_utils_chromium.h"
14 14
15 using std::max; 15 using std::max;
16 16
17 namespace net { 17 namespace net {
18 18
19 QuicUnackedPacketMap::QuicUnackedPacketMap() 19 QuicUnackedPacketMap::QuicUnackedPacketMap()
20 : largest_sent_packet_(0), 20 : largest_sent_packet_(0),
21 largest_observed_(0), 21 largest_observed_(0),
22 least_unacked_(1), 22 least_unacked_(1),
23 bytes_in_flight_(0), 23 bytes_in_flight_(0),
24 pending_crypto_packet_count_(0), 24 pending_crypto_packet_count_(0) {}
25 track_single_retransmission_(FLAGS_quic_track_single_retransmission) {}
26 25
27 QuicUnackedPacketMap::~QuicUnackedPacketMap() { 26 QuicUnackedPacketMap::~QuicUnackedPacketMap() {
28 QuicPacketNumber index = least_unacked_; 27 QuicPacketNumber index = least_unacked_;
29 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); 28 for (UnackedPacketMap::iterator it = unacked_packets_.begin();
30 it != unacked_packets_.end(); ++it, ++index) { 29 it != unacked_packets_.end(); ++it, ++index) {
31 QuicUtils::DeleteFrames(&it->retransmittable_frames); 30 QuicUtils::DeleteFrames(&it->retransmittable_frames);
32 // Only delete all_transmissions once, for the newest packet.
33 if (it->all_transmissions != nullptr &&
34 index == *it->all_transmissions->rbegin()) {
35 delete it->all_transmissions;
36 }
37 } 31 }
38 } 32 }
39 33
40 void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* packet, 34 void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* packet,
41 QuicPacketNumber old_packet_number, 35 QuicPacketNumber old_packet_number,
42 TransmissionType transmission_type, 36 TransmissionType transmission_type,
43 QuicTime sent_time, 37 QuicTime sent_time,
44 QuicByteCount bytes_sent, 38 QuicByteCount bytes_sent,
45 bool set_in_flight) { 39 bool set_in_flight) {
46 QuicPacketNumber packet_number = packet->packet_number; 40 QuicPacketNumber packet_number = packet->packet_number;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 info->has_crypto_handshake = transmission_info->has_crypto_handshake; 116 info->has_crypto_handshake = transmission_info->has_crypto_handshake;
123 transmission_info->has_crypto_handshake = false; 117 transmission_info->has_crypto_handshake = false;
124 info->needs_padding = transmission_info->needs_padding; 118 info->needs_padding = transmission_info->needs_padding;
125 119
126 // Transfer the AckListeners if any are present. 120 // Transfer the AckListeners if any are present.
127 info->ack_listeners.swap(transmission_info->ack_listeners); 121 info->ack_listeners.swap(transmission_info->ack_listeners);
128 QUIC_BUG_IF(frames == nullptr) 122 QUIC_BUG_IF(frames == nullptr)
129 << "Attempt to retransmit packet with no " 123 << "Attempt to retransmit packet with no "
130 << "retransmittable frames: " << old_packet_number; 124 << "retransmittable frames: " << old_packet_number;
131 125
132 // Only keep one transmission older than largest observed, because only the
133 // most recent is expected to possibly be a spurious retransmission.
134 if (!track_single_retransmission_) {
135 while (transmission_info->all_transmissions != nullptr &&
136 transmission_info->all_transmissions->size() > 1 &&
137 *(++transmission_info->all_transmissions->begin()) <
138 largest_observed_) {
139 QuicPacketNumber old_transmission =
140 *transmission_info->all_transmissions->begin();
141 TransmissionInfo* old_info =
142 &unacked_packets_[old_transmission - least_unacked_];
143 // Don't remove old packets if they're still in flight.
144 if (old_info->in_flight) {
145 break;
146 }
147 old_info->all_transmissions->pop_front();
148 // This will cause the packet be removed in RemoveObsoletePackets.
149 old_info->all_transmissions = nullptr;
150 }
151 }
152 // Don't link old transmissions to new ones when version or 126 // Don't link old transmissions to new ones when version or
153 // encryption changes. 127 // encryption changes.
154 if (transmission_type == ALL_INITIAL_RETRANSMISSION || 128 if (transmission_type == ALL_INITIAL_RETRANSMISSION ||
155 transmission_type == ALL_UNACKED_RETRANSMISSION) { 129 transmission_type == ALL_UNACKED_RETRANSMISSION) {
156 RemoveAckability(transmission_info); 130 RemoveAckability(transmission_info);
157 } else { 131 } else {
158 if (track_single_retransmission_) { 132 transmission_info->retransmission = new_packet_number;
159 transmission_info->retransmission = new_packet_number;
160 } else {
161 if (transmission_info->all_transmissions == nullptr) {
162 transmission_info->all_transmissions = new PacketNumberList();
163 transmission_info->all_transmissions->push_back(old_packet_number);
164 }
165 transmission_info->all_transmissions->push_back(new_packet_number);
166 }
167 }
168 if (!track_single_retransmission_) {
169 info->all_transmissions = transmission_info->all_transmissions;
170 } 133 }
171 // Proactively remove obsolete packets so the least unacked can be raised. 134 // Proactively remove obsolete packets so the least unacked can be raised.
172 RemoveObsoletePackets(); 135 RemoveObsoletePackets();
173 } 136 }
174 137
175 bool QuicUnackedPacketMap::HasRetransmittableFrames( 138 bool QuicUnackedPacketMap::HasRetransmittableFrames(
176 QuicPacketNumber packet_number) const { 139 QuicPacketNumber packet_number) const {
177 DCHECK_GE(packet_number, least_unacked_); 140 DCHECK_GE(packet_number, least_unacked_);
178 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); 141 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
179 return !unacked_packets_[packet_number - least_unacked_] 142 return !unacked_packets_[packet_number - least_unacked_]
180 .retransmittable_frames.empty(); 143 .retransmittable_frames.empty();
181 } 144 }
182 145
183 void QuicUnackedPacketMap::NackPacket(QuicPacketNumber packet_number, 146 void QuicUnackedPacketMap::NackPacket(QuicPacketNumber packet_number,
184 uint16_t min_nacks) { 147 uint16_t min_nacks) {
185 DCHECK_GE(packet_number, least_unacked_); 148 DCHECK_GE(packet_number, least_unacked_);
186 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); 149 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
187 unacked_packets_[packet_number - least_unacked_].nack_count = max( 150 unacked_packets_[packet_number - least_unacked_].nack_count = max(
188 min_nacks, unacked_packets_[packet_number - least_unacked_].nack_count); 151 min_nacks, unacked_packets_[packet_number - least_unacked_].nack_count);
189 } 152 }
190 153
191 void QuicUnackedPacketMap::RemoveRetransmittability(TransmissionInfo* info) { 154 void QuicUnackedPacketMap::RemoveRetransmittability(TransmissionInfo* info) {
192 if (track_single_retransmission_) { 155 while (info->retransmission != 0) {
193 while (info->retransmission != 0) { 156 const QuicPacketNumber retransmission = info->retransmission;
194 const QuicPacketNumber retransmission = info->retransmission; 157 info->retransmission = 0;
195 info->retransmission = 0; 158 info = &unacked_packets_[retransmission - least_unacked_];
196 info = &unacked_packets_[retransmission - least_unacked_];
197 }
198 MaybeRemoveRetransmittableFrames(info);
199 return;
200 } 159 }
201 PacketNumberList* all_transmissions = info->all_transmissions; 160 MaybeRemoveRetransmittableFrames(info);
202 if (all_transmissions == nullptr) {
203 MaybeRemoveRetransmittableFrames(info);
204 return;
205 }
206 // TODO(ianswett): Consider adding a check to ensure there are retransmittable
207 // frames associated with this packet.
208 for (QuicPacketNumber packet_number : *all_transmissions) {
209 TransmissionInfo* transmission_info =
210 &unacked_packets_[packet_number - least_unacked_];
211 MaybeRemoveRetransmittableFrames(transmission_info);
212 transmission_info->all_transmissions = nullptr;
213 }
214 delete all_transmissions;
215 } 161 }
216 162
217 void QuicUnackedPacketMap::RemoveRetransmittability( 163 void QuicUnackedPacketMap::RemoveRetransmittability(
218 QuicPacketNumber packet_number) { 164 QuicPacketNumber packet_number) {
219 DCHECK_GE(packet_number, least_unacked_); 165 DCHECK_GE(packet_number, least_unacked_);
220 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); 166 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
221 TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_]; 167 TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_];
222 RemoveRetransmittability(info); 168 RemoveRetransmittability(info);
223 } 169 }
224 170
225 void QuicUnackedPacketMap::RemoveAckability(TransmissionInfo* info) { 171 void QuicUnackedPacketMap::RemoveAckability(TransmissionInfo* info) {
226 DCHECK(info->retransmittable_frames.empty()); 172 DCHECK(info->retransmittable_frames.empty());
173 DCHECK_EQ(0u, info->retransmission);
227 info->is_unackable = true; 174 info->is_unackable = true;
228 if (track_single_retransmission_) {
229 DCHECK_EQ(0u, info->retransmission);
230 return;
231 }
232 PacketNumberList* all_transmissions = info->all_transmissions;
233 if (all_transmissions == nullptr) {
234 return;
235 }
236 for (QuicPacketNumber packet_number : *all_transmissions) {
237 TransmissionInfo* transmission_info =
238 &unacked_packets_[packet_number - least_unacked_];
239 transmission_info->all_transmissions = nullptr;
240 transmission_info->is_unackable = true;
241 }
242 delete all_transmissions;
243 } 175 }
244 176
245 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames( 177 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames(
246 TransmissionInfo* transmission_info) { 178 TransmissionInfo* transmission_info) {
247 if (transmission_info->has_crypto_handshake) { 179 if (transmission_info->has_crypto_handshake) {
248 DCHECK(!transmission_info->retransmittable_frames.empty()); 180 DCHECK(!transmission_info->retransmittable_frames.empty());
249 DCHECK_LT(0u, pending_crypto_packet_count_); 181 DCHECK_LT(0u, pending_crypto_packet_count_);
250 --pending_crypto_packet_count_; 182 --pending_crypto_packet_count_;
251 transmission_info->has_crypto_handshake = false; 183 transmission_info->has_crypto_handshake = false;
252 } 184 }
(...skipping 18 matching lines...) Expand all
271 const TransmissionInfo& info) const { 203 const TransmissionInfo& info) const {
272 // Packet contributes to congestion control if it is considered inflight. 204 // Packet contributes to congestion control if it is considered inflight.
273 return info.in_flight; 205 return info.in_flight;
274 } 206 }
275 207
276 bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData( 208 bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
277 const TransmissionInfo& info) const { 209 const TransmissionInfo& info) const {
278 // Packet may have retransmittable frames, or the data may have been 210 // Packet may have retransmittable frames, or the data may have been
279 // retransmitted with a new packet number. 211 // retransmitted with a new packet number.
280 return !info.retransmittable_frames.empty() || 212 return !info.retransmittable_frames.empty() ||
281 info.all_transmissions != nullptr ||
282 // Allow for an extra 1 RTT before stopping to track old packets. 213 // Allow for an extra 1 RTT before stopping to track old packets.
283 info.retransmission > largest_observed_; 214 info.retransmission > largest_observed_;
284 } 215 }
285 216
286 bool QuicUnackedPacketMap::IsPacketUseless(QuicPacketNumber packet_number, 217 bool QuicUnackedPacketMap::IsPacketUseless(QuicPacketNumber packet_number,
287 const TransmissionInfo& info) const { 218 const TransmissionInfo& info) const {
288 return !IsPacketUsefulForMeasuringRtt(packet_number, info) && 219 return !IsPacketUsefulForMeasuringRtt(packet_number, info) &&
289 !IsPacketUsefulForCongestionControl(info) && 220 !IsPacketUsefulForCongestionControl(info) &&
290 !IsPacketUsefulForRetransmittableData(info); 221 !IsPacketUsefulForRetransmittableData(info);
291 } 222 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 } 352 }
422 } 353 }
423 return false; 354 return false;
424 } 355 }
425 356
426 QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const { 357 QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
427 return least_unacked_; 358 return least_unacked_;
428 } 359 }
429 360
430 } // namespace net 361 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_unacked_packet_map.h ('k') | net/quic/test_tools/quic_sent_packet_manager_peer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698