| 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" |
| 11 | 11 |
| 12 using std::max; | 12 using std::max; |
| 13 | 13 |
| 14 namespace net { | 14 namespace net { |
| 15 | 15 |
| 16 QuicUnackedPacketMap::QuicUnackedPacketMap() | 16 QuicUnackedPacketMap::QuicUnackedPacketMap() |
| 17 : largest_sent_packet_(0), | 17 : largest_sent_packet_(0), |
| 18 largest_observed_(0), |
| 18 bytes_in_flight_(0), | 19 bytes_in_flight_(0), |
| 19 pending_crypto_packet_count_(0) { | 20 pending_crypto_packet_count_(0) { |
| 20 } | 21 } |
| 21 | 22 |
| 22 QuicUnackedPacketMap::~QuicUnackedPacketMap() { | 23 QuicUnackedPacketMap::~QuicUnackedPacketMap() { |
| 23 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); | 24 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 24 it != unacked_packets_.end(); ++it) { | 25 it != unacked_packets_.end(); ++it) { |
| 25 delete it->second.retransmittable_frames; | 26 delete it->second.retransmittable_frames; |
| 26 // Only delete all_transmissions once, for the newest packet. | 27 // Only delete all_transmissions once, for the newest packet. |
| 27 if (it->first == *it->second.all_transmissions->rbegin()) { | 28 if (it->first == *it->second.all_transmissions->rbegin()) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 TransmissionInfo(frames, | 77 TransmissionInfo(frames, |
| 77 new_sequence_number, | 78 new_sequence_number, |
| 78 transmission_info->sequence_number_length, | 79 transmission_info->sequence_number_length, |
| 79 transmission_info->all_transmissions); | 80 transmission_info->all_transmissions); |
| 80 } | 81 } |
| 81 | 82 |
| 82 void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) { | 83 void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) { |
| 83 UnackedPacketMap::iterator it = unacked_packets_.begin(); | 84 UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 84 while (it != unacked_packets_.end() && num_to_clear > 0) { | 85 while (it != unacked_packets_.end() && num_to_clear > 0) { |
| 85 QuicPacketSequenceNumber sequence_number = it->first; | 86 QuicPacketSequenceNumber sequence_number = it->first; |
| 86 // If this is a pending packet, or has retransmittable data, then there is | 87 // If this packet is in flight, or has retransmittable data, then there is |
| 87 // no point in clearing out any further packets, because they would not | 88 // no point in clearing out any further packets, because they would not |
| 88 // affect the high water mark. | 89 // affect the high water mark. |
| 89 if (it->second.pending || it->second.retransmittable_frames != NULL) { | 90 if (it->second.in_flight || it->second.retransmittable_frames != NULL) { |
| 90 break; | 91 break; |
| 91 } | 92 } |
| 92 | 93 |
| 93 it->second.all_transmissions->erase(sequence_number); | 94 it->second.all_transmissions->erase(sequence_number); |
| 94 LOG_IF(DFATAL, it->second.all_transmissions->empty()) | 95 LOG_IF(DFATAL, it->second.all_transmissions->empty()) |
| 95 << "Previous retransmissions must have a newer transmission."; | 96 << "Previous retransmissions must have a newer transmission."; |
| 96 ++it; | 97 ++it; |
| 97 unacked_packets_.erase(sequence_number); | 98 unacked_packets_.erase(sequence_number); |
| 98 --num_to_clear; | 99 --num_to_clear; |
| 99 } | 100 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 116 if (it == unacked_packets_.end()) { | 117 if (it == unacked_packets_.end()) { |
| 117 LOG(DFATAL) << "NackPacket called for packet that is not unacked: " | 118 LOG(DFATAL) << "NackPacket called for packet that is not unacked: " |
| 118 << sequence_number; | 119 << sequence_number; |
| 119 return; | 120 return; |
| 120 } | 121 } |
| 121 | 122 |
| 122 it->second.nack_count = max(min_nacks, it->second.nack_count); | 123 it->second.nack_count = max(min_nacks, it->second.nack_count); |
| 123 } | 124 } |
| 124 | 125 |
| 125 void QuicUnackedPacketMap::RemoveRetransmittability( | 126 void QuicUnackedPacketMap::RemoveRetransmittability( |
| 126 QuicPacketSequenceNumber sequence_number, | 127 QuicPacketSequenceNumber sequence_number) { |
| 127 QuicPacketSequenceNumber largest_observed) { | |
| 128 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 128 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
| 129 if (it == unacked_packets_.end()) { | 129 if (it == unacked_packets_.end()) { |
| 130 LOG(DFATAL) << "packet is not unacked: " << sequence_number; | 130 DVLOG(1) << "packet is not in unacked_packets: " << sequence_number; |
| 131 return; | 131 return; |
| 132 } | 132 } |
| 133 SequenceNumberSet* all_transmissions = it->second.all_transmissions; | 133 SequenceNumberSet* all_transmissions = it->second.all_transmissions; |
| 134 // TODO(ianswett): Consider optimizing this for lone packets. | 134 // TODO(ianswett): Consider optimizing this for lone packets. |
| 135 // TODO(ianswett): Consider adding a check to ensure there are retranmittable | 135 // TODO(ianswett): Consider adding a check to ensure there are retransmittable |
| 136 // frames associated with this packet. | 136 // frames associated with this packet. |
| 137 for (SequenceNumberSet::reverse_iterator it = all_transmissions->rbegin(); | 137 for (SequenceNumberSet::reverse_iterator it = all_transmissions->rbegin(); |
| 138 it != all_transmissions->rend(); ++it) { | 138 it != all_transmissions->rend(); ++it) { |
| 139 TransmissionInfo* transmission_info = FindOrNull(unacked_packets_, *it); | 139 TransmissionInfo* transmission_info = FindOrNull(unacked_packets_, *it); |
| 140 if (transmission_info == NULL) { | 140 if (transmission_info == NULL) { |
| 141 LOG(DFATAL) << "All transmissions in all_transmissions must be present " | 141 LOG(DFATAL) << "All transmissions in all_transmissions must be present " |
| 142 << "in the unacked packet map."; | 142 << "in the unacked packet map."; |
| 143 continue; | 143 continue; |
| 144 } | 144 } |
| 145 MaybeRemoveRetransmittableFrames(transmission_info); | 145 MaybeRemoveRetransmittableFrames(transmission_info); |
| 146 if (sequence_number <= largest_observed && !transmission_info->pending) { | 146 if (*it <= largest_observed_ && !transmission_info->in_flight) { |
| 147 unacked_packets_.erase(*it); | 147 unacked_packets_.erase(*it); |
| 148 } else { | 148 } else { |
| 149 transmission_info->all_transmissions = new SequenceNumberSet(); | 149 transmission_info->all_transmissions = new SequenceNumberSet(); |
| 150 transmission_info->all_transmissions->insert(*it); | 150 transmission_info->all_transmissions->insert(*it); |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 | 153 |
| 154 delete all_transmissions; | 154 delete all_transmissions; |
| 155 } | 155 } |
| 156 | 156 |
| 157 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames( | 157 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames( |
| 158 TransmissionInfo* transmission_info) { | 158 TransmissionInfo* transmission_info) { |
| 159 if (transmission_info->retransmittable_frames != NULL) { | 159 if (transmission_info->retransmittable_frames != NULL) { |
| 160 if (transmission_info->retransmittable_frames->HasCryptoHandshake() | 160 if (transmission_info->retransmittable_frames->HasCryptoHandshake() |
| 161 == IS_HANDSHAKE) { | 161 == IS_HANDSHAKE) { |
| 162 --pending_crypto_packet_count_; | 162 --pending_crypto_packet_count_; |
| 163 } | 163 } |
| 164 delete transmission_info->retransmittable_frames; | 164 delete transmission_info->retransmittable_frames; |
| 165 transmission_info->retransmittable_frames = NULL; | 165 transmission_info->retransmittable_frames = NULL; |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 | 168 |
| 169 void QuicUnackedPacketMap::RemoveRttOnlyPacket( | 169 void QuicUnackedPacketMap::IncreaseLargestObserved( |
| 170 QuicPacketSequenceNumber sequence_number) { | 170 QuicPacketSequenceNumber largest_observed) { |
| 171 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 171 DCHECK_LT(largest_observed_, largest_observed); |
| 172 if (it == unacked_packets_.end()) { | 172 largest_observed_ = largest_observed; |
| 173 LOG(DFATAL) << "packet is not unacked: " << sequence_number; | 173 UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 174 return; | 174 while (it != unacked_packets_.end() && it->first <= largest_observed_) { |
| 175 if (!IsPacketUseless(it)) { |
| 176 ++it; |
| 177 continue; |
| 178 } |
| 179 delete it->second.all_transmissions; |
| 180 QuicPacketSequenceNumber sequence_number = it->first; |
| 181 ++it; |
| 182 unacked_packets_.erase(sequence_number); |
| 175 } | 183 } |
| 176 TransmissionInfo* transmission_info = &it->second; | |
| 177 DCHECK(!transmission_info->pending); | |
| 178 DCHECK(transmission_info->retransmittable_frames == NULL); | |
| 179 DCHECK_EQ(1u, transmission_info->all_transmissions->size()); | |
| 180 delete transmission_info->all_transmissions; | |
| 181 unacked_packets_.erase(it); | |
| 182 } | 184 } |
| 183 | 185 |
| 184 // static | 186 bool QuicUnackedPacketMap::IsPacketUseless( |
| 185 bool QuicUnackedPacketMap::IsForRttOnly( | 187 UnackedPacketMap::const_iterator it) const { |
| 186 const TransmissionInfo& transmission_info) { | 188 return it->first <= largest_observed_ && |
| 187 return !transmission_info.pending && | 189 !it->second.in_flight && |
| 188 transmission_info.retransmittable_frames == NULL && | 190 it->second.retransmittable_frames == NULL && |
| 189 transmission_info.all_transmissions->size() == 1; | 191 it->second.all_transmissions->size() == 1; |
| 190 } | 192 } |
| 191 | 193 |
| 192 bool QuicUnackedPacketMap::IsUnacked( | 194 bool QuicUnackedPacketMap::IsUnacked( |
| 193 QuicPacketSequenceNumber sequence_number) const { | 195 QuicPacketSequenceNumber sequence_number) const { |
| 194 return ContainsKey(unacked_packets_, sequence_number); | 196 return ContainsKey(unacked_packets_, sequence_number); |
| 195 } | 197 } |
| 196 | 198 |
| 197 void QuicUnackedPacketMap::SetNotPending( | 199 void QuicUnackedPacketMap::RemoveFromInFlight( |
| 198 QuicPacketSequenceNumber sequence_number) { | 200 QuicPacketSequenceNumber sequence_number) { |
| 199 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 201 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
| 200 if (it == unacked_packets_.end()) { | 202 if (it == unacked_packets_.end()) { |
| 201 LOG(DFATAL) << "SetNotPending called for packet that is not unacked: " | 203 LOG(DFATAL) << "RemoveFromFlight called for packet that is not unacked: " |
| 202 << sequence_number; | 204 << sequence_number; |
| 203 return; | 205 return; |
| 204 } | 206 } |
| 205 if (it->second.pending) { | 207 if (it->second.in_flight) { |
| 206 LOG_IF(DFATAL, bytes_in_flight_ < it->second.bytes_sent); | 208 LOG_IF(DFATAL, bytes_in_flight_ < it->second.bytes_sent); |
| 207 bytes_in_flight_ -= it->second.bytes_sent; | 209 bytes_in_flight_ -= it->second.bytes_sent; |
| 208 it->second.pending = false; | 210 it->second.in_flight = false; |
| 211 } |
| 212 if (IsPacketUseless(it)) { |
| 213 delete it->second.all_transmissions; |
| 214 unacked_packets_.erase(it); |
| 209 } | 215 } |
| 210 } | 216 } |
| 211 | 217 |
| 212 bool QuicUnackedPacketMap::HasUnackedPackets() const { | 218 bool QuicUnackedPacketMap::HasUnackedPackets() const { |
| 213 return !unacked_packets_.empty(); | 219 return !unacked_packets_.empty(); |
| 214 } | 220 } |
| 215 | 221 |
| 216 bool QuicUnackedPacketMap::HasPendingPackets() const { | 222 bool QuicUnackedPacketMap::HasInFlightPackets() const { |
| 217 return bytes_in_flight_ > 0; | 223 return bytes_in_flight_ > 0; |
| 218 } | 224 } |
| 219 | 225 |
| 220 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo( | 226 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo( |
| 221 QuicPacketSequenceNumber sequence_number) const { | 227 QuicPacketSequenceNumber sequence_number) const { |
| 222 return unacked_packets_.find(sequence_number)->second; | 228 return unacked_packets_.find(sequence_number)->second; |
| 223 } | 229 } |
| 224 | 230 |
| 225 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { | 231 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { |
| 226 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); | 232 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); |
| 227 while (it != unacked_packets_.rend()) { | 233 while (it != unacked_packets_.rend()) { |
| 228 if (it->second.pending) { | 234 if (it->second.in_flight) { |
| 229 LOG_IF(DFATAL, it->second.sent_time == QuicTime::Zero()) | 235 LOG_IF(DFATAL, it->second.sent_time == QuicTime::Zero()) |
| 230 << "Sent time can never be zero for a pending packet."; | 236 << "Sent time can never be zero for a packet in flight."; |
| 231 return it->second.sent_time; | 237 return it->second.sent_time; |
| 232 } | 238 } |
| 233 ++it; | 239 ++it; |
| 234 } | 240 } |
| 235 LOG(DFATAL) << "Unable to find sent time. " | 241 LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets."; |
| 236 << "This method is only intended when there are pending packets."; | |
| 237 return QuicTime::Zero(); | 242 return QuicTime::Zero(); |
| 238 } | 243 } |
| 239 | 244 |
| 240 QuicTime QuicUnackedPacketMap::GetFirstPendingPacketSentTime() const { | 245 QuicTime QuicUnackedPacketMap::GetFirstInFlightPacketSentTime() const { |
| 241 UnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 246 UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 242 while (it != unacked_packets_.end() && !it->second.pending) { | 247 while (it != unacked_packets_.end() && !it->second.in_flight) { |
| 243 ++it; | 248 ++it; |
| 244 } | 249 } |
| 245 if (it == unacked_packets_.end()) { | 250 if (it == unacked_packets_.end()) { |
| 246 LOG(DFATAL) << "No pending packets"; | 251 LOG(DFATAL) << "GetFirstInFlightPacketSentTime requires in flight packets."; |
| 247 return QuicTime::Zero(); | 252 return QuicTime::Zero(); |
| 248 } | 253 } |
| 249 return it->second.sent_time; | 254 return it->second.sent_time; |
| 250 } | 255 } |
| 251 | 256 |
| 252 size_t QuicUnackedPacketMap::GetNumUnackedPackets() const { | 257 size_t QuicUnackedPacketMap::GetNumUnackedPackets() const { |
| 253 return unacked_packets_.size(); | 258 return unacked_packets_.size(); |
| 254 } | 259 } |
| 255 | 260 |
| 256 bool QuicUnackedPacketMap::HasMultiplePendingPackets() const { | 261 bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const { |
| 257 size_t num_pending = 0; | 262 size_t num_in_flight = 0; |
| 258 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); | 263 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); |
| 259 it != unacked_packets_.rend(); ++it) { | 264 it != unacked_packets_.rend(); ++it) { |
| 260 if (it->second.pending) { | 265 if (it->second.in_flight) { |
| 261 ++num_pending; | 266 ++num_in_flight; |
| 262 } | 267 } |
| 263 if (num_pending > 1) { | 268 if (num_in_flight > 1) { |
| 264 return true; | 269 return true; |
| 265 } | 270 } |
| 266 } | 271 } |
| 267 return false; | 272 return false; |
| 268 } | 273 } |
| 269 | 274 |
| 270 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { | 275 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { |
| 271 return pending_crypto_packet_count_ > 0; | 276 return pending_crypto_packet_count_ > 0; |
| 272 } | 277 } |
| 273 | 278 |
| 274 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { | 279 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { |
| 275 for (UnackedPacketMap::const_reverse_iterator it = | 280 for (UnackedPacketMap::const_reverse_iterator it = |
| 276 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { | 281 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { |
| 277 if (it->second.pending && it->second.retransmittable_frames) { | 282 if (it->second.in_flight && it->second.retransmittable_frames) { |
| 278 return true; | 283 return true; |
| 279 } | 284 } |
| 280 } | 285 } |
| 281 return false; | 286 return false; |
| 282 } | 287 } |
| 283 | 288 |
| 284 QuicPacketSequenceNumber | 289 QuicPacketSequenceNumber |
| 285 QuicUnackedPacketMap::GetLeastUnackedSentPacket() const { | 290 QuicUnackedPacketMap::GetLeastUnackedSentPacket() const { |
| 286 if (unacked_packets_.empty()) { | 291 if (unacked_packets_.empty()) { |
| 287 // If there are no unacked packets, return 0. | 292 // If there are no unacked packets, return 0. |
| 288 return 0; | 293 return 0; |
| 289 } | 294 } |
| 290 | 295 |
| 291 return unacked_packets_.begin()->first; | 296 return unacked_packets_.begin()->first; |
| 292 } | 297 } |
| 293 | 298 |
| 294 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, | 299 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, |
| 295 QuicTime sent_time, | 300 QuicTime sent_time, |
| 296 QuicByteCount bytes_sent, | 301 QuicByteCount bytes_sent, |
| 297 bool set_pending) { | 302 bool set_in_flight) { |
| 298 DCHECK_LT(0u, sequence_number); | 303 DCHECK_LT(0u, sequence_number); |
| 299 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 304 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
| 300 if (it == unacked_packets_.end()) { | 305 if (it == unacked_packets_.end()) { |
| 301 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " | 306 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " |
| 302 << sequence_number; | 307 << sequence_number; |
| 303 return; | 308 return; |
| 304 } | 309 } |
| 305 DCHECK(!it->second.pending); | 310 DCHECK(!it->second.in_flight); |
| 306 | 311 |
| 307 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); | 312 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); |
| 308 it->second.sent_time = sent_time; | 313 it->second.sent_time = sent_time; |
| 309 if (set_pending) { | 314 if (set_in_flight) { |
| 310 bytes_in_flight_ += bytes_sent; | 315 bytes_in_flight_ += bytes_sent; |
| 311 it->second.bytes_sent = bytes_sent; | 316 it->second.bytes_sent = bytes_sent; |
| 312 it->second.pending = true; | 317 it->second.in_flight = true; |
| 313 } | 318 } |
| 314 } | 319 } |
| 315 | 320 |
| 316 } // namespace net | 321 } // namespace net |
| OLD | NEW |