quic_unacked_packet_map.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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 3// found in the LICENSE file. 4 5#include "net/quic/quic_unacked_packet_map.h" 6 7#include "base/logging.h" 8#include "base/stl_util.h" 9#include "net/quic/quic_connection_stats.h" 10#include "net/quic/quic_utils_chromium.h" 11 12using std::max; 13 14namespace net { 15 16QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo() 17 : retransmittable_frames(NULL), 18 sequence_number_length(PACKET_1BYTE_SEQUENCE_NUMBER), 19 sent_time(QuicTime::Zero()), 20 bytes_sent(0), 21 nack_count(0), 22 all_transmissions(NULL), 23 pending(false) { } 24 25QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo( 26 RetransmittableFrames* retransmittable_frames, 27 QuicPacketSequenceNumber sequence_number, 28 QuicSequenceNumberLength sequence_number_length) 29 : retransmittable_frames(retransmittable_frames), 30 sequence_number_length(sequence_number_length), 31 sent_time(QuicTime::Zero()), 32 bytes_sent(0), 33 nack_count(0), 34 all_transmissions(new SequenceNumberSet), 35 pending(false) { 36 all_transmissions->insert(sequence_number); 37} 38 39QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo( 40 RetransmittableFrames* retransmittable_frames, 41 QuicPacketSequenceNumber sequence_number, 42 QuicSequenceNumberLength sequence_number_length, 43 SequenceNumberSet* all_transmissions) 44 : retransmittable_frames(retransmittable_frames), 45 sequence_number_length(sequence_number_length), 46 sent_time(QuicTime::Zero()), 47 bytes_sent(0), 48 nack_count(0), 49 all_transmissions(all_transmissions), 50 pending(false) { 51 all_transmissions->insert(sequence_number); 52} 53 54QuicUnackedPacketMap::QuicUnackedPacketMap() 55 : largest_sent_packet_(0), 56 bytes_in_flight_(0), 57 pending_crypto_packet_count_(0) { 58} 59 60QuicUnackedPacketMap::~QuicUnackedPacketMap() { 61 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); 62 it != unacked_packets_.end(); ++it) { 63 delete it->second.retransmittable_frames; 64 // Only delete all_transmissions once, for the newest packet. 65 if (it->first == *it->second.all_transmissions->rbegin()) { 66 delete it->second.all_transmissions; 67 } 68 } 69} 70 71// TODO(ianswett): Combine this method with OnPacketSent once packets are always 72// sent in order and the connection tracks RetransmittableFrames for longer. 73void QuicUnackedPacketMap::AddPacket( 74 const SerializedPacket& serialized_packet) { 75 if (!unacked_packets_.empty()) { 76 bool is_old_packet = unacked_packets_.rbegin()->first >= 77 serialized_packet.sequence_number; 78 LOG_IF(DFATAL, is_old_packet) << "Old packet serialized: " 79 << serialized_packet.sequence_number 80 << " vs: " 81 << unacked_packets_.rbegin()->first; 82 } 83 84 unacked_packets_[serialized_packet.sequence_number] = 85 TransmissionInfo(serialized_packet.retransmittable_frames, 86 serialized_packet.sequence_number, 87 serialized_packet.sequence_number_length); 88 if (serialized_packet.retransmittable_frames != NULL && 89 serialized_packet.retransmittable_frames->HasCryptoHandshake() 90 == IS_HANDSHAKE) { 91 ++pending_crypto_packet_count_; 92 } 93} 94 95void QuicUnackedPacketMap::OnRetransmittedPacket( 96 QuicPacketSequenceNumber old_sequence_number, 97 QuicPacketSequenceNumber new_sequence_number) { 98 DCHECK(ContainsKey(unacked_packets_, old_sequence_number)); 99 DCHECK(unacked_packets_.empty() || 100 unacked_packets_.rbegin()->first < new_sequence_number); 101 102 // TODO(ianswett): Discard and lose the packet lazily instead of immediately. 103 TransmissionInfo* transmission_info = 104 FindOrNull(unacked_packets_, old_sequence_number); 105 RetransmittableFrames* frames = transmission_info->retransmittable_frames; 106 LOG_IF(DFATAL, frames == NULL) << "Attempt to retransmit packet with no " 107 << "retransmittable frames: " 108 << old_sequence_number; 109 110 // We keep the old packet in the unacked packet list until it, or one of 111 // the retransmissions of it are acked. 112 transmission_info->retransmittable_frames = NULL; 113 unacked_packets_[new_sequence_number] = 114 TransmissionInfo(frames, 115 new_sequence_number, 116 transmission_info->sequence_number_length, 117 transmission_info->all_transmissions); 118} 119 120void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) { 121 UnackedPacketMap::iterator it = unacked_packets_.begin(); 122 while (it != unacked_packets_.end() && num_to_clear > 0) { 123 QuicPacketSequenceNumber sequence_number = it->first; 124 // If this is a pending packet, or has retransmittable data, then there is 125 // no point in clearing out any further packets, because they would not 126 // affect the high water mark. 127 if (it->second.pending || it->second.retransmittable_frames != NULL) { 128 break; 129 } 130 131 ++it; 132 RemovePacket(sequence_number); 133 --num_to_clear; 134 } 135} 136 137bool QuicUnackedPacketMap::HasRetransmittableFrames( 138 QuicPacketSequenceNumber sequence_number) const { 139 const TransmissionInfo* transmission_info = 140 FindOrNull(unacked_packets_, sequence_number); 141 if (transmission_info == NULL) { 142 return false; 143 } 144 145 return transmission_info->retransmittable_frames != NULL; 146} 147 148void QuicUnackedPacketMap::NackPacket(QuicPacketSequenceNumber sequence_number, 149 size_t min_nacks) { 150 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 151 if (it == unacked_packets_.end()) { 152 LOG(DFATAL) << "NackPacket called for packet that is not unacked: " 153 << sequence_number; 154 return; 155 } 156 157 it->second.nack_count = max(min_nacks, it->second.nack_count); 158} 159 160void QuicUnackedPacketMap::RemovePacket( 161 QuicPacketSequenceNumber sequence_number) { 162 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 163 if (it == unacked_packets_.end()) { 164 LOG(DFATAL) << "packet is not unacked: " << sequence_number; 165 return; 166 } 167 const TransmissionInfo& transmission_info = it->second; 168 transmission_info.all_transmissions->erase(sequence_number); 169 if (transmission_info.all_transmissions->empty()) { 170 delete transmission_info.all_transmissions; 171 } 172 if (transmission_info.retransmittable_frames != NULL) { 173 if (transmission_info.retransmittable_frames->HasCryptoHandshake() 174 == IS_HANDSHAKE) { 175 --pending_crypto_packet_count_; 176 } 177 delete transmission_info.retransmittable_frames; 178 } 179 unacked_packets_.erase(it); 180} 181 182void QuicUnackedPacketMap::NeuterPacket( 183 QuicPacketSequenceNumber sequence_number) { 184 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 185 if (it == unacked_packets_.end()) { 186 LOG(DFATAL) << "packet is not unacked: " << sequence_number; 187 return; 188 } 189 TransmissionInfo* transmission_info = &it->second; 190 if (transmission_info->all_transmissions->size() > 1) { 191 transmission_info->all_transmissions->erase(sequence_number); 192 transmission_info->all_transmissions = new SequenceNumberSet(); 193 transmission_info->all_transmissions->insert(sequence_number); 194 } 195 if (transmission_info->retransmittable_frames != NULL) { 196 delete transmission_info->retransmittable_frames; 197 transmission_info->retransmittable_frames = NULL; 198 } 199} 200 201// static 202bool QuicUnackedPacketMap::IsSentAndNotPending( 203 const TransmissionInfo& transmission_info) { 204 return !transmission_info.pending && 205 transmission_info.sent_time != QuicTime::Zero() && 206 transmission_info.bytes_sent == 0; 207} 208 209bool QuicUnackedPacketMap::IsUnacked( 210 QuicPacketSequenceNumber sequence_number) const { 211 return ContainsKey(unacked_packets_, sequence_number); 212} 213 214bool QuicUnackedPacketMap::IsPending( 215 QuicPacketSequenceNumber sequence_number) const { 216 const TransmissionInfo* transmission_info = 217 FindOrNull(unacked_packets_, sequence_number); 218 return transmission_info != NULL && transmission_info->pending; 219} 220 221void QuicUnackedPacketMap::SetNotPending( 222 QuicPacketSequenceNumber sequence_number) { 223 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 224 if (it == unacked_packets_.end()) { 225 LOG(DFATAL) << "SetNotPending called for packet that is not unacked: " 226 << sequence_number; 227 return; 228 } 229 if (it->second.pending) { 230 LOG_IF(DFATAL, bytes_in_flight_ < it->second.bytes_sent); 231 bytes_in_flight_ -= it->second.bytes_sent; 232 it->second.pending = false; 233 } 234} 235 236bool QuicUnackedPacketMap::HasUnackedPackets() const { 237 return !unacked_packets_.empty(); 238} 239 240bool QuicUnackedPacketMap::HasPendingPackets() const { 241 for (UnackedPacketMap::const_reverse_iterator it = 242 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { 243 if (it->second.pending) { 244 return true; 245 } 246 } 247 return false; 248} 249 250const QuicUnackedPacketMap::TransmissionInfo& 251 QuicUnackedPacketMap::GetTransmissionInfo( 252 QuicPacketSequenceNumber sequence_number) const { 253 return unacked_packets_.find(sequence_number)->second; 254} 255 256QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { 257 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 258 while (it != unacked_packets_.rend() && 259 (!it->second.pending || 260 it->second.retransmittable_frames == NULL)) { 261 ++it; 262 } 263 if (it == unacked_packets_.rend()) { 264 LOG(DFATAL) << "Unable to find sent time."; 265 return QuicTime::Zero(); 266 } 267 return it->second.sent_time; 268} 269 270QuicTime QuicUnackedPacketMap::GetFirstPendingPacketSentTime() const { 271 UnackedPacketMap::const_iterator it = unacked_packets_.begin(); 272 while (it != unacked_packets_.end() && !it->second.pending) { 273 ++it; 274 } 275 if (it == unacked_packets_.end()) { 276 LOG(DFATAL) << "No pending packets"; 277 return QuicTime::Zero(); 278 } 279 return it->second.sent_time; 280} 281 282size_t QuicUnackedPacketMap::GetNumUnackedPackets() const { 283 return unacked_packets_.size(); 284} 285 286bool QuicUnackedPacketMap::HasMultiplePendingPackets() const { 287 size_t num_pending = 0; 288 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 289 it != unacked_packets_.rend(); ++it) { 290 if (it->second.pending) { 291 ++num_pending; 292 } 293 if (num_pending > 1) { 294 return true; 295 } 296 } 297 return false; 298} 299 300bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { 301 return pending_crypto_packet_count_ > 0; 302} 303 304bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { 305 for (UnackedPacketMap::const_reverse_iterator it = 306 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { 307 if (it->second.pending && it->second.retransmittable_frames) { 308 return true; 309 } 310 } 311 return false; 312} 313 314size_t QuicUnackedPacketMap::GetNumRetransmittablePackets() const { 315 size_t num_unacked_packets = 0; 316 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); 317 it != unacked_packets_.end(); ++it) { 318 if (it->second.retransmittable_frames != NULL) { 319 ++num_unacked_packets; 320 } 321 } 322 return num_unacked_packets; 323} 324 325QuicPacketSequenceNumber 326QuicUnackedPacketMap::GetLeastUnackedSentPacket() const { 327 if (unacked_packets_.empty()) { 328 // If there are no unacked packets, return 0. 329 return 0; 330 } 331 332 return unacked_packets_.begin()->first; 333} 334 335SequenceNumberSet QuicUnackedPacketMap::GetUnackedPackets() const { 336 SequenceNumberSet unacked_packets; 337 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); 338 it != unacked_packets_.end(); ++it) { 339 unacked_packets.insert(it->first); 340 } 341 return unacked_packets; 342} 343 344void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, 345 QuicTime sent_time, 346 QuicByteCount bytes_sent, 347 bool set_pending) { 348 DCHECK_LT(0u, sequence_number); 349 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 350 if (it == unacked_packets_.end()) { 351 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " 352 << sequence_number; 353 return; 354 } 355 DCHECK(!it->second.pending); 356 357 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); 358 it->second.sent_time = sent_time; 359 if (set_pending) { 360 bytes_in_flight_ += bytes_sent; 361 it->second.bytes_sent = bytes_sent; 362 it->second.pending = true; 363 } 364} 365 366} // namespace net 367