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