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

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

Issue 2547583002: Landing Recent QUIC changes until Fri Nov 18 23:21:04 2016 +0000 (Closed)
Patch Set: Remove explicit HTTP/2 enum usage Created 4 years 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
« no previous file with comments | « net/quic/core/quic_unacked_packet_map.h ('k') | net/quic/core/quic_version_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/core/quic_unacked_packet_map.h" 5 #include "net/quic/core/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/chromium/quic_utils_chromium.h" 9 #include "net/quic/chromium/quic_utils_chromium.h"
10 #include "net/quic/core/quic_bug_tracker.h" 10 #include "net/quic/core/quic_bug_tracker.h"
11 #include "net/quic/core/quic_connection_stats.h" 11 #include "net/quic/core/quic_connection_stats.h"
12 #include "net/quic/core/quic_flags.h" 12 #include "net/quic/core/quic_flags.h"
13 #include "net/quic/core/quic_utils.h" 13 #include "net/quic/core/quic_utils.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_sent_retransmittable_packet_(0), 21 largest_sent_retransmittable_packet_(0),
22 largest_observed_(0), 22 largest_observed_(0),
23 least_unacked_(1), 23 least_unacked_(1),
24 bytes_in_flight_(0), 24 bytes_in_flight_(0),
25 pending_crypto_packet_count_(0) {} 25 pending_crypto_packet_count_(0) {}
26 26
27 QuicUnackedPacketMap::~QuicUnackedPacketMap() { 27 QuicUnackedPacketMap::~QuicUnackedPacketMap() {
28 QuicPacketNumber index = least_unacked_; 28 for (QuicTransmissionInfo& transmission_info : unacked_packets_) {
29 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); 29 DeleteFrames(&(transmission_info.retransmittable_frames));
30 it != unacked_packets_.end(); ++it, ++index) {
31 DeleteFrames(&it->retransmittable_frames);
32 } 30 }
33 } 31 }
34 32
35 void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* packet, 33 void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* packet,
36 QuicPacketNumber old_packet_number, 34 QuicPacketNumber old_packet_number,
37 TransmissionType transmission_type, 35 TransmissionType transmission_type,
38 QuicTime sent_time, 36 QuicTime sent_time,
39 bool set_in_flight) { 37 bool set_in_flight) {
40 QuicPacketNumber packet_number = packet->packet_number; 38 QuicPacketNumber packet_number = packet->packet_number;
41 QuicPacketLength bytes_sent = packet->encrypted_length; 39 QuicPacketLength bytes_sent = packet->encrypted_length;
42 QUIC_BUG_IF(largest_sent_packet_ >= packet_number) << packet_number; 40 QUIC_BUG_IF(largest_sent_packet_ >= packet_number) << packet_number;
43 DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size()); 41 DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size());
44 while (least_unacked_ + unacked_packets_.size() < packet_number) { 42 while (least_unacked_ + unacked_packets_.size() < packet_number) {
45 unacked_packets_.push_back(TransmissionInfo()); 43 unacked_packets_.push_back(QuicTransmissionInfo());
46 unacked_packets_.back().is_unackable = true; 44 unacked_packets_.back().is_unackable = true;
47 } 45 }
48 46
49 const bool has_crypto_handshake = 47 const bool has_crypto_handshake =
50 packet->has_crypto_handshake == IS_HANDSHAKE; 48 packet->has_crypto_handshake == IS_HANDSHAKE;
51 TransmissionInfo info(packet->encryption_level, packet->packet_number_length, 49 QuicTransmissionInfo info(
52 transmission_type, sent_time, bytes_sent, 50 packet->encryption_level, packet->packet_number_length, transmission_type,
53 has_crypto_handshake, packet->num_padding_bytes); 51 sent_time, bytes_sent, has_crypto_handshake, packet->num_padding_bytes);
54 if (old_packet_number > 0) { 52 if (old_packet_number > 0) {
55 TransferRetransmissionInfo(old_packet_number, packet_number, 53 TransferRetransmissionInfo(old_packet_number, packet_number,
56 transmission_type, &info); 54 transmission_type, &info);
57 } 55 }
58 56
59 largest_sent_packet_ = packet_number; 57 largest_sent_packet_ = packet_number;
60 if (set_in_flight) { 58 if (set_in_flight) {
61 bytes_in_flight_ += bytes_sent; 59 bytes_in_flight_ += bytes_sent;
62 info.in_flight = true; 60 info.in_flight = true;
63 largest_sent_retransmittable_packet_ = packet_number; 61 largest_sent_retransmittable_packet_ = packet_number;
(...skipping 20 matching lines...) Expand all
84 82
85 unacked_packets_.pop_front(); 83 unacked_packets_.pop_front();
86 ++least_unacked_; 84 ++least_unacked_;
87 } 85 }
88 } 86 }
89 87
90 void QuicUnackedPacketMap::TransferRetransmissionInfo( 88 void QuicUnackedPacketMap::TransferRetransmissionInfo(
91 QuicPacketNumber old_packet_number, 89 QuicPacketNumber old_packet_number,
92 QuicPacketNumber new_packet_number, 90 QuicPacketNumber new_packet_number,
93 TransmissionType transmission_type, 91 TransmissionType transmission_type,
94 TransmissionInfo* info) { 92 QuicTransmissionInfo* info) {
95 if (old_packet_number < least_unacked_) { 93 if (old_packet_number < least_unacked_) {
96 // This can happen when a retransmission packet is queued because of write 94 // This can happen when a retransmission packet is queued because of write
97 // blocked socket, and the original packet gets acked before the 95 // blocked socket, and the original packet gets acked before the
98 // retransmission gets sent. 96 // retransmission gets sent.
99 return; 97 return;
100 } 98 }
101 if (old_packet_number > largest_sent_packet_) { 99 if (old_packet_number > largest_sent_packet_) {
102 QUIC_BUG << "Old TransmissionInfo never existed for :" << old_packet_number 100 QUIC_BUG << "Old QuicTransmissionInfo never existed for :"
103 << " largest_sent:" << largest_sent_packet_; 101 << old_packet_number << " largest_sent:" << largest_sent_packet_;
104 return; 102 return;
105 } 103 }
106 DCHECK_GE(new_packet_number, least_unacked_ + unacked_packets_.size()); 104 DCHECK_GE(new_packet_number, least_unacked_ + unacked_packets_.size());
107 DCHECK_NE(NOT_RETRANSMISSION, transmission_type); 105 DCHECK_NE(NOT_RETRANSMISSION, transmission_type);
108 106
109 TransmissionInfo* transmission_info = 107 QuicTransmissionInfo* transmission_info =
110 &unacked_packets_.at(old_packet_number - least_unacked_); 108 &unacked_packets_.at(old_packet_number - least_unacked_);
111 QuicFrames* frames = &transmission_info->retransmittable_frames; 109 QuicFrames* frames = &transmission_info->retransmittable_frames;
112 for (AckListenerWrapper& wrapper : transmission_info->ack_listeners) { 110 for (AckListenerWrapper& wrapper : transmission_info->ack_listeners) {
113 wrapper.ack_listener->OnPacketRetransmitted(wrapper.length); 111 wrapper.ack_listener->OnPacketRetransmitted(wrapper.length);
114 } 112 }
115 113
116 // Swap the frames and preserve num_padding_bytes and has_crypto_handshake. 114 // Swap the frames and preserve num_padding_bytes and has_crypto_handshake.
117 frames->swap(info->retransmittable_frames); 115 frames->swap(info->retransmittable_frames);
118 info->has_crypto_handshake = transmission_info->has_crypto_handshake; 116 info->has_crypto_handshake = transmission_info->has_crypto_handshake;
119 transmission_info->has_crypto_handshake = false; 117 transmission_info->has_crypto_handshake = false;
(...skipping 18 matching lines...) Expand all
138 } 136 }
139 137
140 bool QuicUnackedPacketMap::HasRetransmittableFrames( 138 bool QuicUnackedPacketMap::HasRetransmittableFrames(
141 QuicPacketNumber packet_number) const { 139 QuicPacketNumber packet_number) const {
142 DCHECK_GE(packet_number, least_unacked_); 140 DCHECK_GE(packet_number, least_unacked_);
143 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); 141 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
144 return !unacked_packets_[packet_number - least_unacked_] 142 return !unacked_packets_[packet_number - least_unacked_]
145 .retransmittable_frames.empty(); 143 .retransmittable_frames.empty();
146 } 144 }
147 145
148 void QuicUnackedPacketMap::RemoveRetransmittability(TransmissionInfo* info) { 146 void QuicUnackedPacketMap::RemoveRetransmittability(
147 QuicTransmissionInfo* info) {
149 while (info->retransmission != 0) { 148 while (info->retransmission != 0) {
150 const QuicPacketNumber retransmission = info->retransmission; 149 const QuicPacketNumber retransmission = info->retransmission;
151 info->retransmission = 0; 150 info->retransmission = 0;
152 info = &unacked_packets_[retransmission - least_unacked_]; 151 info = &unacked_packets_[retransmission - least_unacked_];
153 } 152 }
154 MaybeRemoveRetransmittableFrames(info); 153
154 if (info->has_crypto_handshake) {
155 DCHECK(!info->retransmittable_frames.empty());
156 DCHECK_LT(0u, pending_crypto_packet_count_);
157 --pending_crypto_packet_count_;
158 info->has_crypto_handshake = false;
159 }
160 DeleteFrames(&info->retransmittable_frames);
155 } 161 }
156 162
157 void QuicUnackedPacketMap::RemoveRetransmittability( 163 void QuicUnackedPacketMap::RemoveRetransmittability(
158 QuicPacketNumber packet_number) { 164 QuicPacketNumber packet_number) {
159 DCHECK_GE(packet_number, least_unacked_); 165 DCHECK_GE(packet_number, least_unacked_);
160 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); 166 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
161 TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_]; 167 QuicTransmissionInfo* info =
168 &unacked_packets_[packet_number - least_unacked_];
162 RemoveRetransmittability(info); 169 RemoveRetransmittability(info);
163 } 170 }
164 171
165 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames(
166 TransmissionInfo* transmission_info) {
167 if (transmission_info->has_crypto_handshake) {
168 DCHECK(!transmission_info->retransmittable_frames.empty());
169 DCHECK_LT(0u, pending_crypto_packet_count_);
170 --pending_crypto_packet_count_;
171 transmission_info->has_crypto_handshake = false;
172 }
173 DeleteFrames(&transmission_info->retransmittable_frames);
174 }
175
176 void QuicUnackedPacketMap::IncreaseLargestObserved( 172 void QuicUnackedPacketMap::IncreaseLargestObserved(
177 QuicPacketNumber largest_observed) { 173 QuicPacketNumber largest_observed) {
178 DCHECK_LE(largest_observed_, largest_observed); 174 DCHECK_LE(largest_observed_, largest_observed);
179 largest_observed_ = largest_observed; 175 largest_observed_ = largest_observed;
180 } 176 }
181 177
182 bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt( 178 bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt(
183 QuicPacketNumber packet_number, 179 QuicPacketNumber packet_number,
184 const TransmissionInfo& info) const { 180 const QuicTransmissionInfo& info) const {
185 // Packet can be used for RTT measurement if it may yet be acked as the 181 // Packet can be used for RTT measurement if it may yet be acked as the
186 // largest observed packet by the receiver. 182 // largest observed packet by the receiver.
187 return !info.is_unackable && packet_number > largest_observed_; 183 return !info.is_unackable && packet_number > largest_observed_;
188 } 184 }
189 185
190 bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl( 186 bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl(
191 const TransmissionInfo& info) const { 187 const QuicTransmissionInfo& info) const {
192 // Packet contributes to congestion control if it is considered inflight. 188 // Packet contributes to congestion control if it is considered inflight.
193 return info.in_flight; 189 return info.in_flight;
194 } 190 }
195 191
196 bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData( 192 bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
197 const TransmissionInfo& info) const { 193 const QuicTransmissionInfo& info) const {
198 // Packet may have retransmittable frames, or the data may have been 194 // Packet may have retransmittable frames, or the data may have been
199 // retransmitted with a new packet number. 195 // retransmitted with a new packet number.
200 return !info.retransmittable_frames.empty() || 196 return !info.retransmittable_frames.empty() ||
201 // Allow for an extra 1 RTT before stopping to track old packets. 197 // Allow for an extra 1 RTT before stopping to track old packets.
202 info.retransmission > largest_observed_; 198 info.retransmission > largest_observed_;
203 } 199 }
204 200
205 bool QuicUnackedPacketMap::IsPacketUseless(QuicPacketNumber packet_number, 201 bool QuicUnackedPacketMap::IsPacketUseless(
206 const TransmissionInfo& info) const { 202 QuicPacketNumber packet_number,
203 const QuicTransmissionInfo& info) const {
207 return !IsPacketUsefulForMeasuringRtt(packet_number, info) && 204 return !IsPacketUsefulForMeasuringRtt(packet_number, info) &&
208 !IsPacketUsefulForCongestionControl(info) && 205 !IsPacketUsefulForCongestionControl(info) &&
209 !IsPacketUsefulForRetransmittableData(info); 206 !IsPacketUsefulForRetransmittableData(info);
210 } 207 }
211 208
212 bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const { 209 bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const {
213 if (packet_number < least_unacked_ || 210 if (packet_number < least_unacked_ ||
214 packet_number >= least_unacked_ + unacked_packets_.size()) { 211 packet_number >= least_unacked_ + unacked_packets_.size()) {
215 return false; 212 return false;
216 } 213 }
217 return !IsPacketUseless(packet_number, 214 return !IsPacketUseless(packet_number,
218 unacked_packets_[packet_number - least_unacked_]); 215 unacked_packets_[packet_number - least_unacked_]);
219 } 216 }
220 217
221 void QuicUnackedPacketMap::NotifyAndClearListeners( 218 void QuicUnackedPacketMap::NotifyAndClearListeners(
222 std::list<AckListenerWrapper>* ack_listeners, 219 std::list<AckListenerWrapper>* ack_listeners,
223 QuicTime::Delta ack_delay_time) { 220 QuicTime::Delta ack_delay_time) {
224 for (const AckListenerWrapper& wrapper : *ack_listeners) { 221 for (const AckListenerWrapper& wrapper : *ack_listeners) {
225 wrapper.ack_listener->OnPacketAcked(wrapper.length, ack_delay_time); 222 wrapper.ack_listener->OnPacketAcked(wrapper.length, ack_delay_time);
226 } 223 }
227 ack_listeners->clear(); 224 ack_listeners->clear();
228 } 225 }
229 226
230 void QuicUnackedPacketMap::NotifyAndClearListeners( 227 void QuicUnackedPacketMap::NotifyAndClearListeners(
231 QuicPacketNumber packet_number, 228 QuicPacketNumber packet_number,
232 QuicTime::Delta ack_delay_time) { 229 QuicTime::Delta ack_delay_time) {
233 DCHECK_GE(packet_number, least_unacked_); 230 DCHECK_GE(packet_number, least_unacked_);
234 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); 231 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
235 TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_]; 232 QuicTransmissionInfo* info =
233 &unacked_packets_[packet_number - least_unacked_];
236 NotifyAndClearListeners(&info->ack_listeners, ack_delay_time); 234 NotifyAndClearListeners(&info->ack_listeners, ack_delay_time);
237 } 235 }
238 236
239 void QuicUnackedPacketMap::RemoveFromInFlight(TransmissionInfo* info) { 237 void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) {
240 if (info->in_flight) { 238 if (info->in_flight) {
241 QUIC_BUG_IF(bytes_in_flight_ < info->bytes_sent); 239 QUIC_BUG_IF(bytes_in_flight_ < info->bytes_sent);
242 bytes_in_flight_ -= info->bytes_sent; 240 bytes_in_flight_ -= info->bytes_sent;
243 info->in_flight = false; 241 info->in_flight = false;
244 } 242 }
245 } 243 }
246 244
247 void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) { 245 void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
248 DCHECK_GE(packet_number, least_unacked_); 246 DCHECK_GE(packet_number, least_unacked_);
249 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); 247 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
250 TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_]; 248 QuicTransmissionInfo* info =
249 &unacked_packets_[packet_number - least_unacked_];
251 RemoveFromInFlight(info); 250 RemoveFromInFlight(info);
252 } 251 }
253 252
254 void QuicUnackedPacketMap::RestoreToInFlight(QuicPacketNumber packet_number) { 253 void QuicUnackedPacketMap::RestoreToInFlight(QuicPacketNumber packet_number) {
255 DCHECK_GE(packet_number, least_unacked_); 254 DCHECK_GE(packet_number, least_unacked_);
256 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size()); 255 DCHECK_LT(packet_number, least_unacked_ + unacked_packets_.size());
257 TransmissionInfo* info = &unacked_packets_[packet_number - least_unacked_]; 256 QuicTransmissionInfo* info =
257 &unacked_packets_[packet_number - least_unacked_];
258 DCHECK(!info->is_unackable); 258 DCHECK(!info->is_unackable);
259 bytes_in_flight_ += info->bytes_sent; 259 bytes_in_flight_ += info->bytes_sent;
260 info->in_flight = true; 260 info->in_flight = true;
261 } 261 }
262 262
263 void QuicUnackedPacketMap::CancelRetransmissionsForStream( 263 void QuicUnackedPacketMap::CancelRetransmissionsForStream(
264 QuicStreamId stream_id) { 264 QuicStreamId stream_id) {
265 QuicPacketNumber packet_number = least_unacked_; 265 QuicPacketNumber packet_number = least_unacked_;
266 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); 266 for (UnackedPacketMap::iterator it = unacked_packets_.begin();
267 it != unacked_packets_.end(); ++it, ++packet_number) { 267 it != unacked_packets_.end(); ++it, ++packet_number) {
268 QuicFrames* frames = &it->retransmittable_frames; 268 QuicFrames* frames = &it->retransmittable_frames;
269 if (frames->empty()) { 269 if (frames->empty()) {
270 continue; 270 continue;
271 } 271 }
272 RemoveFramesForStream(frames, stream_id); 272 RemoveFramesForStream(frames, stream_id);
273 if (frames->empty()) { 273 if (frames->empty()) {
274 RemoveRetransmittability(packet_number); 274 RemoveRetransmittability(packet_number);
275 } 275 }
276 } 276 }
277 } 277 }
278 278
279 bool QuicUnackedPacketMap::HasUnackedPackets() const { 279 bool QuicUnackedPacketMap::HasUnackedPackets() const {
280 return !unacked_packets_.empty(); 280 return !unacked_packets_.empty();
281 } 281 }
282 282
283 bool QuicUnackedPacketMap::HasInFlightPackets() const { 283 bool QuicUnackedPacketMap::HasInFlightPackets() const {
284 return bytes_in_flight_ > 0; 284 return bytes_in_flight_ > 0;
285 } 285 }
286 286
287 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo( 287 const QuicTransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
288 QuicPacketNumber packet_number) const { 288 QuicPacketNumber packet_number) const {
289 return unacked_packets_[packet_number - least_unacked_]; 289 return unacked_packets_[packet_number - least_unacked_];
290 } 290 }
291 291
292 TransmissionInfo* QuicUnackedPacketMap::GetMutableTransmissionInfo( 292 QuicTransmissionInfo* QuicUnackedPacketMap::GetMutableTransmissionInfo(
293 QuicPacketNumber packet_number) { 293 QuicPacketNumber packet_number) {
294 return &unacked_packets_[packet_number - least_unacked_]; 294 return &unacked_packets_[packet_number - least_unacked_];
295 } 295 }
296 296
297 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { 297 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const {
298 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 298 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
299 while (it != unacked_packets_.rend()) { 299 while (it != unacked_packets_.rend()) {
300 if (it->in_flight) { 300 if (it->in_flight) {
301 QUIC_BUG_IF(it->sent_time == QuicTime::Zero()) 301 QUIC_BUG_IF(it->sent_time == QuicTime::Zero())
302 << "Sent time can never be zero for a packet in flight."; 302 << "Sent time can never be zero for a packet in flight.";
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 } 349 }
350 } 350 }
351 return false; 351 return false;
352 } 352 }
353 353
354 QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const { 354 QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
355 return least_unacked_; 355 return least_unacked_;
356 } 356 }
357 357
358 } // namespace net 358 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_unacked_packet_map.h ('k') | net/quic/core/quic_version_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698