| 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" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 it != unacked_packets_.end(); ++it, ++index) { | 27 it != unacked_packets_.end(); ++it, ++index) { |
| 28 delete it->retransmittable_frames; | 28 delete it->retransmittable_frames; |
| 29 // Only delete all_transmissions once, for the newest packet. | 29 // Only delete all_transmissions once, for the newest packet. |
| 30 if (it->all_transmissions != nullptr && | 30 if (it->all_transmissions != nullptr && |
| 31 index == *it->all_transmissions->rbegin()) { | 31 index == *it->all_transmissions->rbegin()) { |
| 32 delete it->all_transmissions; | 32 delete it->all_transmissions; |
| 33 } | 33 } |
| 34 } | 34 } |
| 35 } | 35 } |
| 36 | 36 |
| 37 // TODO(ianswett): Combine this method with OnPacketSent once packets are always | 37 void QuicUnackedPacketMap::AddSentPacket( |
| 38 // sent in order and the connection tracks RetransmittableFrames for longer. | 38 const SerializedPacket& packet, |
| 39 void QuicUnackedPacketMap::AddPacket( | 39 QuicPacketSequenceNumber old_sequence_number, |
| 40 const SerializedPacket& serialized_packet) { | 40 TransmissionType transmission_type, |
| 41 DCHECK_GE(serialized_packet.sequence_number, | 41 QuicTime sent_time, |
| 42 least_unacked_ + unacked_packets_.size()); | 42 QuicByteCount bytes_sent, |
| 43 while (least_unacked_ + unacked_packets_.size() < | 43 bool set_in_flight) { |
| 44 serialized_packet.sequence_number) { | 44 QuicPacketSequenceNumber sequence_number = packet.sequence_number; |
| 45 DCHECK_LT(largest_sent_packet_, sequence_number); |
| 46 DCHECK_GE(sequence_number, least_unacked_ + unacked_packets_.size()); |
| 47 while (least_unacked_ + unacked_packets_.size() < sequence_number) { |
| 45 unacked_packets_.push_back(TransmissionInfo()); | 48 unacked_packets_.push_back(TransmissionInfo()); |
| 46 unacked_packets_.back().is_unackable = true; | 49 unacked_packets_.back().is_unackable = true; |
| 47 } | 50 } |
| 48 unacked_packets_.push_back( | 51 |
| 49 TransmissionInfo(serialized_packet.retransmittable_frames, | 52 TransmissionInfo info; |
| 50 serialized_packet.sequence_number_length)); | 53 if (old_sequence_number == 0) { |
| 51 if (serialized_packet.retransmittable_frames != nullptr && | 54 if (packet.retransmittable_frames != nullptr && |
| 52 serialized_packet.retransmittable_frames->HasCryptoHandshake() == | 55 packet.retransmittable_frames->HasCryptoHandshake() == IS_HANDSHAKE) { |
| 53 IS_HANDSHAKE) { | 56 ++pending_crypto_packet_count_; |
| 54 ++pending_crypto_packet_count_; | 57 } |
| 58 info = TransmissionInfo(packet.retransmittable_frames, |
| 59 packet.sequence_number_length); |
| 60 } else { |
| 61 info = OnRetransmittedPacket( |
| 62 old_sequence_number, sequence_number, transmission_type); |
| 55 } | 63 } |
| 64 info.sent_time = sent_time; |
| 65 |
| 66 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); |
| 67 if (set_in_flight) { |
| 68 bytes_in_flight_ += bytes_sent; |
| 69 info.bytes_sent = bytes_sent; |
| 70 info.in_flight = true; |
| 71 } |
| 72 unacked_packets_.push_back(info); |
| 56 } | 73 } |
| 57 | 74 |
| 58 void QuicUnackedPacketMap::RemoveObsoletePackets() { | 75 void QuicUnackedPacketMap::RemoveObsoletePackets() { |
| 59 while (!unacked_packets_.empty()) { | 76 while (!unacked_packets_.empty()) { |
| 60 if (!IsPacketRemovable(least_unacked_, unacked_packets_.front())) { | 77 if (!IsPacketRemovable(least_unacked_, unacked_packets_.front())) { |
| 61 break; | 78 break; |
| 62 } | 79 } |
| 63 unacked_packets_.pop_front(); | 80 unacked_packets_.pop_front(); |
| 64 ++least_unacked_; | 81 ++least_unacked_; |
| 65 } | 82 } |
| 66 } | 83 } |
| 67 | 84 |
| 68 void QuicUnackedPacketMap::OnRetransmittedPacket( | 85 TransmissionInfo QuicUnackedPacketMap::OnRetransmittedPacket( |
| 69 QuicPacketSequenceNumber old_sequence_number, | 86 QuicPacketSequenceNumber old_sequence_number, |
| 70 QuicPacketSequenceNumber new_sequence_number, | 87 QuicPacketSequenceNumber new_sequence_number, |
| 71 TransmissionType transmission_type) { | 88 TransmissionType transmission_type) { |
| 72 DCHECK_GE(old_sequence_number, least_unacked_); | 89 DCHECK_GE(old_sequence_number, least_unacked_); |
| 73 DCHECK_LT(old_sequence_number, least_unacked_ + unacked_packets_.size()); | 90 DCHECK_LT(old_sequence_number, least_unacked_ + unacked_packets_.size()); |
| 74 DCHECK_GE(new_sequence_number, least_unacked_ + unacked_packets_.size()); | 91 DCHECK_GE(new_sequence_number, least_unacked_ + unacked_packets_.size()); |
| 75 while (least_unacked_ + unacked_packets_.size() < new_sequence_number) { | 92 DCHECK_NE(NOT_RETRANSMISSION, transmission_type); |
| 76 unacked_packets_.push_back(TransmissionInfo()); | |
| 77 unacked_packets_.back().is_unackable = true; | |
| 78 } | |
| 79 | 93 |
| 80 // TODO(ianswett): Discard and lose the packet lazily instead of immediately. | 94 // TODO(ianswett): Discard and lose the packet lazily instead of immediately. |
| 81 TransmissionInfo* transmission_info = | 95 TransmissionInfo* transmission_info = |
| 82 &unacked_packets_.at(old_sequence_number - least_unacked_); | 96 &unacked_packets_.at(old_sequence_number - least_unacked_); |
| 83 RetransmittableFrames* frames = transmission_info->retransmittable_frames; | 97 RetransmittableFrames* frames = transmission_info->retransmittable_frames; |
| 98 transmission_info->retransmittable_frames = nullptr; |
| 84 LOG_IF(DFATAL, frames == nullptr) | 99 LOG_IF(DFATAL, frames == nullptr) |
| 85 << "Attempt to retransmit packet with no " | 100 << "Attempt to retransmit packet with no " |
| 86 << "retransmittable frames: " << old_sequence_number; | 101 << "retransmittable frames: " << old_sequence_number; |
| 87 | 102 |
| 88 // We keep the old packet in the unacked packet list until it, or one of | |
| 89 // the retransmissions of it are acked. | |
| 90 transmission_info->retransmittable_frames = nullptr; | |
| 91 // Only keep one transmission older than largest observed, because only the | 103 // Only keep one transmission older than largest observed, because only the |
| 92 // most recent is expected to possibly be a spurious retransmission. | 104 // most recent is expected to possibly be a spurious retransmission. |
| 93 while (transmission_info->all_transmissions != nullptr && | 105 while (transmission_info->all_transmissions != nullptr && |
| 94 transmission_info->all_transmissions->size() > 1 && | 106 transmission_info->all_transmissions->size() > 1 && |
| 95 *(++transmission_info->all_transmissions->begin()) < | 107 *(++transmission_info->all_transmissions->begin()) < |
| 96 largest_observed_) { | 108 largest_observed_) { |
| 97 QuicPacketSequenceNumber old_transmission = | 109 QuicPacketSequenceNumber old_transmission = |
| 98 *transmission_info->all_transmissions->begin(); | 110 *transmission_info->all_transmissions->begin(); |
| 99 TransmissionInfo* old_info = | 111 TransmissionInfo* old_info = |
| 100 &unacked_packets_[old_transmission - least_unacked_]; | 112 &unacked_packets_[old_transmission - least_unacked_]; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 111 if (transmission_type == ALL_INITIAL_RETRANSMISSION || | 123 if (transmission_type == ALL_INITIAL_RETRANSMISSION || |
| 112 transmission_type == ALL_UNACKED_RETRANSMISSION) { | 124 transmission_type == ALL_UNACKED_RETRANSMISSION) { |
| 113 RemoveAckability(transmission_info); | 125 RemoveAckability(transmission_info); |
| 114 } else { | 126 } else { |
| 115 if (transmission_info->all_transmissions == nullptr) { | 127 if (transmission_info->all_transmissions == nullptr) { |
| 116 transmission_info->all_transmissions = new SequenceNumberList(); | 128 transmission_info->all_transmissions = new SequenceNumberList(); |
| 117 transmission_info->all_transmissions->push_back(old_sequence_number); | 129 transmission_info->all_transmissions->push_back(old_sequence_number); |
| 118 } | 130 } |
| 119 transmission_info->all_transmissions->push_back(new_sequence_number); | 131 transmission_info->all_transmissions->push_back(new_sequence_number); |
| 120 } | 132 } |
| 121 unacked_packets_.push_back( | 133 TransmissionInfo info = |
| 122 TransmissionInfo(frames, | 134 TransmissionInfo(frames, |
| 123 transmission_info->sequence_number_length, | 135 transmission_info->sequence_number_length, |
| 124 transmission_type, | 136 transmission_type, |
| 125 transmission_info->all_transmissions)); | 137 transmission_info->all_transmissions); |
| 138 // Proactively remove obsolete packets so the least unacked can be raised. |
| 126 RemoveObsoletePackets(); | 139 RemoveObsoletePackets(); |
| 140 return info; |
| 127 } | 141 } |
| 128 | 142 |
| 129 void QuicUnackedPacketMap::ClearAllPreviousRetransmissions() { | 143 void QuicUnackedPacketMap::ClearAllPreviousRetransmissions() { |
| 130 while (!unacked_packets_.empty() && least_unacked_ < largest_observed_) { | 144 while (!unacked_packets_.empty() && least_unacked_ < largest_observed_) { |
| 131 // If this packet is in flight, or has retransmittable data, then there is | 145 // If this packet is in flight, or has retransmittable data, then there is |
| 132 // no point in clearing out any further packets, because they would not | 146 // no point in clearing out any further packets, because they would not |
| 133 // affect the high water mark. | 147 // affect the high water mark. |
| 134 TransmissionInfo* info = &unacked_packets_.front(); | 148 TransmissionInfo* info = &unacked_packets_.front(); |
| 135 if (info->in_flight || info->retransmittable_frames != nullptr) { | 149 if (info->in_flight || info->retransmittable_frames != nullptr) { |
| 136 break; | 150 break; |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 } | 363 } |
| 350 } | 364 } |
| 351 return false; | 365 return false; |
| 352 } | 366 } |
| 353 | 367 |
| 354 QuicPacketSequenceNumber | 368 QuicPacketSequenceNumber |
| 355 QuicUnackedPacketMap::GetLeastUnacked() const { | 369 QuicUnackedPacketMap::GetLeastUnacked() const { |
| 356 return least_unacked_; | 370 return least_unacked_; |
| 357 } | 371 } |
| 358 | 372 |
| 359 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, | |
| 360 QuicTime sent_time, | |
| 361 QuicByteCount bytes_sent, | |
| 362 bool set_in_flight) { | |
| 363 DCHECK_GE(sequence_number, least_unacked_); | |
| 364 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); | |
| 365 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; | |
| 366 DCHECK(!info->in_flight); | |
| 367 | |
| 368 DCHECK_LT(largest_sent_packet_, sequence_number); | |
| 369 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); | |
| 370 info->sent_time = sent_time; | |
| 371 if (set_in_flight) { | |
| 372 bytes_in_flight_ += bytes_sent; | |
| 373 info->bytes_sent = bytes_sent; | |
| 374 info->in_flight = true; | |
| 375 } | |
| 376 } | |
| 377 | |
| 378 void QuicUnackedPacketMap::RestoreInFlight( | 373 void QuicUnackedPacketMap::RestoreInFlight( |
| 379 QuicPacketSequenceNumber sequence_number) { | 374 QuicPacketSequenceNumber sequence_number) { |
| 380 DCHECK_GE(sequence_number, least_unacked_); | 375 DCHECK_GE(sequence_number, least_unacked_); |
| 381 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); | 376 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); |
| 382 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; | 377 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; |
| 383 DCHECK(!info->in_flight); | 378 DCHECK(!info->in_flight); |
| 384 DCHECK_NE(0u, info->bytes_sent); | 379 DCHECK_NE(0u, info->bytes_sent); |
| 385 DCHECK(info->sent_time.IsInitialized()); | 380 DCHECK(info->sent_time.IsInitialized()); |
| 386 | 381 |
| 387 bytes_in_flight_ += info->bytes_sent; | 382 bytes_in_flight_ += info->bytes_sent; |
| 388 info->in_flight = true; | 383 info->in_flight = true; |
| 389 } | 384 } |
| 390 | 385 |
| 391 } // namespace net | 386 } // namespace net |
| OLD | NEW |