[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 1 | // Copyright 2013 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_sent_packet_manager.h" |
| 6 | |
| 7 | #include "base/logging.h" |
| 8 | #include "base/stl_util.h" |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 9 | #include "net/quic/congestion_control/pacing_sender.h" |
[email protected] | 0741d71 | 2013-10-08 00:10:11 | [diff] [blame] | 10 | #include "net/quic/quic_ack_notifier_manager.h" |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 11 | |
| 12 | using std::make_pair; |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 13 | using std::min; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 14 | |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 15 | // TODO(rtenneti): Remove this. |
| 16 | // Do not flip this flag until the flakiness of the |
| 17 | // net/tools/quic/end_to_end_test is fixed. |
| 18 | // If true, then QUIC connections will track the retransmission history of a |
| 19 | // packet so that an ack of a previous transmission will ack the data of all |
| 20 | // other transmissions. |
| 21 | bool FLAGS_track_retransmission_history = false; |
| 22 | |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 23 | // A test-only flag to prevent the RTO from backing off when multiple sequential |
| 24 | // tail drops occur. |
| 25 | bool FLAGS_limit_rto_increase_for_tests = false; |
| 26 | |
| 27 | // Do not remove this flag until the Finch-trials described in b/11706275 |
| 28 | // are complete. |
| 29 | // If true, QUIC connections will support the use of a pacing algorithm when |
| 30 | // sending packets, in an attempt to reduce packet loss. The client must also |
| 31 | // request pacing for the server to enable it. |
| 32 | bool FLAGS_enable_quic_pacing = false; |
| 33 | |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 34 | namespace net { |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 35 | namespace { |
| 36 | static const int kBitrateSmoothingPeriodMs = 1000; |
| 37 | static const int kHistoryPeriodMs = 5000; |
| 38 | |
| 39 | static const int kDefaultRetransmissionTimeMs = 500; |
| 40 | // TCP RFC calls for 1 second RTO however Linux differs from this default and |
| 41 | // define the minimum RTO to 200ms, we will use the same until we have data to |
| 42 | // support a higher or lower value. |
| 43 | static const int kMinRetransmissionTimeMs = 200; |
| 44 | static const int kMaxRetransmissionTimeMs = 60000; |
| 45 | static const size_t kMaxRetransmissions = 10; |
| 46 | |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 47 | // We only retransmit 2 packets per ack. |
| 48 | static const size_t kMaxRetransmissionsPerAck = 2; |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 49 | |
| 50 | // TCP retransmits after 3 nacks. |
| 51 | static const size_t kNumberOfNacksBeforeRetransmission = 3; |
| 52 | |
| 53 | COMPILE_ASSERT(kHistoryPeriodMs >= kBitrateSmoothingPeriodMs, |
| 54 | history_must_be_longer_or_equal_to_the_smoothing_period); |
| 55 | } // namespace |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 56 | |
| 57 | #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
| 58 | |
| 59 | QuicSentPacketManager::HelperInterface::~HelperInterface() { |
| 60 | } |
| 61 | |
| 62 | QuicSentPacketManager::QuicSentPacketManager(bool is_server, |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 63 | HelperInterface* helper, |
| 64 | const QuicClock* clock, |
| 65 | CongestionFeedbackType type) |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 66 | : is_server_(is_server), |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 67 | helper_(helper), |
| 68 | clock_(clock), |
| 69 | send_algorithm_(SendAlgorithmInterface::Create(clock, type)), |
| 70 | rtt_sample_(QuicTime::Delta::Infinite()), |
| 71 | consecutive_rto_count_(0), |
| 72 | using_pacing_(false) { |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 73 | } |
| 74 | |
| 75 | QuicSentPacketManager::~QuicSentPacketManager() { |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 76 | for (UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 77 | it != unacked_packets_.end(); ++it) { |
| 78 | delete it->second.retransmittable_frames; |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 79 | // Only delete previous_transmissions once, for the newest packet. |
| 80 | if (it->second.previous_transmissions != NULL && |
| 81 | it->first == *it->second.previous_transmissions->rbegin()) { |
| 82 | delete it->second.previous_transmissions; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 83 | } |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 84 | } |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 85 | STLDeleteValues(&packet_history_map_); |
| 86 | } |
| 87 | |
| 88 | void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
| 89 | if (config.initial_round_trip_time_us() > 0 && |
| 90 | rtt_sample_.IsInfinite()) { |
| 91 | // The initial rtt should already be set on the client side. |
| 92 | DVLOG_IF(1, !is_server_) |
| 93 | << "Client did not set an initial RTT, but did negotiate one."; |
| 94 | rtt_sample_ = |
| 95 | QuicTime::Delta::FromMicroseconds(config.initial_round_trip_time_us()); |
| 96 | } |
| 97 | if (config.congestion_control() == kPACE) { |
| 98 | MaybeEnablePacing(); |
| 99 | } |
| 100 | send_algorithm_->SetFromConfig(config, is_server_); |
| 101 | } |
| 102 | |
| 103 | void QuicSentPacketManager::SetMaxPacketSize(QuicByteCount max_packet_size) { |
| 104 | send_algorithm_->SetMaxPacketSize(max_packet_size); |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 105 | } |
| 106 | |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 107 | // TODO(ianswett): Combine this method with OnPacketSent once packets are always |
| 108 | // sent in order and the connection tracks RetransmittableFrames for longer. |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 109 | void QuicSentPacketManager::OnSerializedPacket( |
[email protected] | 457d695 | 2013-12-13 09:24:58 | [diff] [blame] | 110 | const SerializedPacket& serialized_packet) { |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 111 | if (serialized_packet.retransmittable_frames) { |
| 112 | ack_notifier_manager_.OnSerializedPacket(serialized_packet); |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | DCHECK(unacked_packets_.empty() || |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 116 | unacked_packets_.rbegin()->first < serialized_packet.sequence_number); |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 117 | unacked_packets_[serialized_packet.sequence_number] = |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 118 | TransmissionInfo(serialized_packet.retransmittable_frames, |
| 119 | serialized_packet.sequence_number_length); |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | void QuicSentPacketManager::OnRetransmittedPacket( |
| 123 | QuicPacketSequenceNumber old_sequence_number, |
| 124 | QuicPacketSequenceNumber new_sequence_number) { |
| 125 | DCHECK(ContainsKey(unacked_packets_, old_sequence_number)); |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 126 | DCHECK(ContainsKey(pending_retransmissions_, old_sequence_number)); |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 127 | DCHECK(unacked_packets_.empty() || |
| 128 | unacked_packets_.rbegin()->first < new_sequence_number); |
| 129 | |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 130 | pending_retransmissions_.erase(old_sequence_number); |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 131 | // TODO(ianswett): Discard and lose the packet lazily instead of immediately. |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 132 | |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 133 | UnackedPacketMap::iterator unacked_it = |
| 134 | unacked_packets_.find(old_sequence_number); |
| 135 | RetransmittableFrames* frames = unacked_it->second.retransmittable_frames; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 136 | DCHECK(frames); |
[email protected] | 0741d71 | 2013-10-08 00:10:11 | [diff] [blame] | 137 | |
| 138 | // A notifier may be waiting to hear about ACKs for the original sequence |
| 139 | // number. Inform them that the sequence number has changed. |
| 140 | ack_notifier_manager_.UpdateSequenceNumber(old_sequence_number, |
| 141 | new_sequence_number); |
| 142 | |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 143 | // We keep the old packet in the unacked packet list until it, or one of |
| 144 | // the retransmissions of it are acked. |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 145 | unacked_it->second.retransmittable_frames = NULL; |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 146 | unacked_packets_[new_sequence_number] = |
| 147 | TransmissionInfo(frames, GetSequenceNumberLength(old_sequence_number)); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 148 | |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 149 | // Keep track of all sequence numbers that this packet |
| 150 | // has been transmitted as. |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 151 | SequenceNumberSet* previous_transmissions = |
| 152 | unacked_it->second.previous_transmissions; |
| 153 | if (previous_transmissions == NULL) { |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 154 | // This is the first retransmission of this packet, so create a new entry. |
| 155 | previous_transmissions = new SequenceNumberSet; |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 156 | unacked_it->second.previous_transmissions = previous_transmissions; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 157 | previous_transmissions->insert(old_sequence_number); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 158 | } |
| 159 | previous_transmissions->insert(new_sequence_number); |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 160 | unacked_packets_[new_sequence_number].previous_transmissions = |
| 161 | previous_transmissions; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 162 | |
| 163 | DCHECK(HasRetransmittableFrames(new_sequence_number)); |
| 164 | } |
| 165 | |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 166 | bool QuicSentPacketManager::OnIncomingAck( |
| 167 | const ReceivedPacketInfo& received_info, QuicTime ack_receive_time) { |
| 168 | // Determine if the least unacked sequence number is being acked. |
| 169 | QuicPacketSequenceNumber least_unacked_sent_before = |
[email protected] | 457d695 | 2013-12-13 09:24:58 | [diff] [blame] | 170 | GetLeastUnackedSentPacket(); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 171 | bool new_least_unacked = !IsAwaitingPacket(received_info, |
| 172 | least_unacked_sent_before); |
| 173 | |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 174 | MaybeUpdateRTT(received_info, ack_receive_time); |
[email protected] | e6ccc1a6 | 2013-12-02 07:02:12 | [diff] [blame] | 175 | HandleAckForSentPackets(received_info); |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 176 | MaybeRetransmitOnAckFrame(received_info, ack_receive_time); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 177 | |
| 178 | if (new_least_unacked) { |
| 179 | consecutive_rto_count_ = 0; |
| 180 | } |
| 181 | |
| 182 | return new_least_unacked; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | void QuicSentPacketManager::DiscardUnackedPacket( |
| 186 | QuicPacketSequenceNumber sequence_number) { |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 187 | MarkPacketHandled(sequence_number, NOT_RECEIVED_BY_PEER); |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 188 | } |
| 189 | |
| 190 | void QuicSentPacketManager::HandleAckForSentPackets( |
[email protected] | e6ccc1a6 | 2013-12-02 07:02:12 | [diff] [blame] | 191 | const ReceivedPacketInfo& received_info) { |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 192 | // Go through the packets we have not received an ack for and see if this |
| 193 | // incoming_ack shows they've been seen by the peer. |
| 194 | UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 195 | while (it != unacked_packets_.end()) { |
| 196 | QuicPacketSequenceNumber sequence_number = it->first; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 197 | if (sequence_number > received_info.largest_observed) { |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 198 | // These are very new sequence_numbers. |
| 199 | break; |
| 200 | } |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 201 | |
[email protected] | 622f9476 | 2013-11-20 21:58:10 | [diff] [blame] | 202 | if (IsAwaitingPacket(received_info, sequence_number)) { |
| 203 | ++it; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 204 | continue; |
| 205 | } |
| 206 | |
[email protected] | 622f9476 | 2013-11-20 21:58:10 | [diff] [blame] | 207 | // Packet was acked, so remove it from our unacked packet list. |
| 208 | DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number; |
| 209 | // If data is associated with the most recent transmission of this |
| 210 | // packet, then inform the caller. |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 211 | it = MarkPacketHandled(sequence_number, RECEIVED_BY_PEER); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 212 | |
[email protected] | 622f9476 | 2013-11-20 21:58:10 | [diff] [blame] | 213 | // The AckNotifierManager is informed of every ACKed sequence number. |
| 214 | ack_notifier_manager_.OnPacketAcked(sequence_number); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 215 | } |
| 216 | |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 217 | // If we have received a truncated ack, then we need to |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 218 | // clear out some previous transmissions to allow the peer |
| 219 | // to actually ACK new packets. |
[email protected] | e6ccc1a6 | 2013-12-02 07:02:12 | [diff] [blame] | 220 | if (received_info.is_truncated) { |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 221 | ClearPreviousRetransmissions(received_info.missing_packets.size() / 2); |
| 222 | } |
| 223 | } |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 224 | |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 225 | void QuicSentPacketManager::ClearPreviousRetransmissions(size_t num_to_clear) { |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 226 | UnackedPacketMap::iterator it = unacked_packets_.begin(); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 227 | while (it != unacked_packets_.end() && num_to_clear > 0) { |
| 228 | QuicPacketSequenceNumber sequence_number = it->first; |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 229 | // If this is not a previous transmission then there is no point |
| 230 | // in clearing out any further packets, because it will not affect |
| 231 | // the high water mark. |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 232 | SequenceNumberSet* previous_transmissions = |
| 233 | it->second.previous_transmissions; |
| 234 | if (previous_transmissions == NULL) { |
| 235 | break; |
| 236 | } |
| 237 | QuicPacketSequenceNumber newest_transmission = |
| 238 | *previous_transmissions->rbegin(); |
| 239 | if (sequence_number == newest_transmission) { |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 240 | break; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 241 | } |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 242 | |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 243 | DCHECK(it->second.retransmittable_frames == NULL); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 244 | previous_transmissions->erase(sequence_number); |
| 245 | if (previous_transmissions->size() == 1) { |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 246 | unacked_packets_[newest_transmission].previous_transmissions = NULL; |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 247 | delete previous_transmissions; |
| 248 | } |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 249 | unacked_packets_.erase(it++); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 250 | --num_to_clear; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 251 | } |
| 252 | } |
| 253 | |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 254 | bool QuicSentPacketManager::HasRetransmittableFrames( |
| 255 | QuicPacketSequenceNumber sequence_number) const { |
| 256 | if (!ContainsKey(unacked_packets_, sequence_number)) { |
| 257 | return false; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 258 | } |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 259 | |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 260 | return unacked_packets_.find( |
| 261 | sequence_number)->second.retransmittable_frames != NULL; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 262 | } |
| 263 | |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 264 | void QuicSentPacketManager::RetransmitUnackedPackets( |
| 265 | RetransmissionType retransmission_type) { |
| 266 | if (unacked_packets_.empty()) { |
| 267 | return; |
| 268 | } |
| 269 | |
| 270 | for (UnackedPacketMap::const_iterator unacked_it = unacked_packets_.begin(); |
| 271 | unacked_it != unacked_packets_.end(); ++unacked_it) { |
| 272 | const RetransmittableFrames* frames = |
| 273 | unacked_it->second.retransmittable_frames; |
| 274 | if (frames == NULL) { |
| 275 | continue; |
| 276 | } |
| 277 | if (retransmission_type == ALL_PACKETS || |
| 278 | frames->encryption_level() == ENCRYPTION_INITIAL) { |
| 279 | // TODO(satyamshekhar): Think about congestion control here. |
| 280 | // Specifically, about the retransmission count of packets being sent |
| 281 | // proactively to achieve 0 (minimal) RTT. |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 282 | if (unacked_it->second.retransmittable_frames) { |
| 283 | OnPacketAbandoned(unacked_it->first); |
| 284 | MarkForRetransmission(unacked_it->first, NACK_RETRANSMISSION); |
| 285 | } else { |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 286 | DiscardUnackedPacket(unacked_it->first); |
| 287 | } |
| 288 | } |
| 289 | } |
| 290 | } |
| 291 | |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 292 | void QuicSentPacketManager::MarkForRetransmission( |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 293 | QuicPacketSequenceNumber sequence_number, |
| 294 | TransmissionType transmission_type) { |
| 295 | DCHECK(ContainsKey(unacked_packets_, sequence_number)); |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 296 | DCHECK(HasRetransmittableFrames(sequence_number)); |
| 297 | // TODO(ianswett): Currently the RTO can fire while there are pending NACK |
| 298 | // retransmissions for the same data, which is not ideal. |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 299 | if (ContainsKey(pending_retransmissions_, sequence_number)) { |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 300 | return; |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 301 | } |
| 302 | |
| 303 | pending_retransmissions_[sequence_number] = transmission_type; |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 304 | } |
| 305 | |
| 306 | bool QuicSentPacketManager::HasPendingRetransmissions() const { |
| 307 | return !pending_retransmissions_.empty(); |
| 308 | } |
| 309 | |
| 310 | QuicSentPacketManager::PendingRetransmission |
| 311 | QuicSentPacketManager::NextPendingRetransmission() { |
| 312 | DCHECK(!pending_retransmissions_.empty()); |
| 313 | QuicPacketSequenceNumber sequence_number = |
| 314 | pending_retransmissions_.begin()->first; |
| 315 | DCHECK(ContainsKey(unacked_packets_, sequence_number)); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 316 | const RetransmittableFrames* retransmittable_frames = |
| 317 | unacked_packets_[sequence_number].retransmittable_frames; |
| 318 | DCHECK(retransmittable_frames); |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 319 | |
| 320 | return PendingRetransmission(sequence_number, |
| 321 | pending_retransmissions_.begin()->second, |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 322 | *retransmittable_frames, |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 323 | GetSequenceNumberLength(sequence_number)); |
| 324 | } |
| 325 | |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 326 | bool QuicSentPacketManager::IsPreviousTransmission( |
| 327 | QuicPacketSequenceNumber sequence_number) const { |
| 328 | DCHECK(ContainsKey(unacked_packets_, sequence_number)); |
| 329 | |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 330 | UnackedPacketMap::const_iterator it = unacked_packets_.find(sequence_number); |
| 331 | if (it->second.previous_transmissions == NULL) { |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 332 | return false; |
| 333 | } |
| 334 | |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 335 | SequenceNumberSet* previous_transmissions = it->second.previous_transmissions; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 336 | DCHECK(!previous_transmissions->empty()); |
| 337 | return *previous_transmissions->rbegin() != sequence_number; |
| 338 | } |
| 339 | |
| 340 | QuicSentPacketManager::UnackedPacketMap::iterator |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 341 | QuicSentPacketManager::MarkPacketHandled( |
| 342 | QuicPacketSequenceNumber sequence_number, ReceivedByPeer received_by_peer) { |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 343 | DCHECK(ContainsKey(unacked_packets_, sequence_number)); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 344 | |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 345 | // If this packet is pending, remove it and inform the send algorithm. |
| 346 | if (pending_packets_.erase(sequence_number)) { |
| 347 | size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent(); |
| 348 | if (received_by_peer == RECEIVED_BY_PEER) { |
| 349 | send_algorithm_->OnPacketAcked(sequence_number, bytes_sent, rtt_sample_); |
| 350 | } else { |
| 351 | // It's been abandoned. |
| 352 | send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent); |
| 353 | } |
| 354 | } |
| 355 | |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 356 | // If this packet has never been retransmitted, then simply drop it. |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 357 | UnackedPacketMap::const_iterator previous_it = |
| 358 | unacked_packets_.find(sequence_number); |
| 359 | if (previous_it->second.previous_transmissions == NULL) { |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 360 | UnackedPacketMap::iterator next_unacked = |
| 361 | unacked_packets_.find(sequence_number); |
| 362 | ++next_unacked; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 363 | DiscardPacket(sequence_number); |
| 364 | return next_unacked; |
| 365 | } |
| 366 | |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 367 | SequenceNumberSet* previous_transmissions = |
| 368 | previous_it->second.previous_transmissions; |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 369 | DCHECK(!previous_transmissions->empty()); |
| 370 | SequenceNumberSet::reverse_iterator previous_transmissions_it = |
| 371 | previous_transmissions->rbegin(); |
| 372 | QuicPacketSequenceNumber newest_transmission = *previous_transmissions_it; |
| 373 | if (newest_transmission == sequence_number) { |
| 374 | DiscardPacket(newest_transmission); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 375 | } else { |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 376 | // If we have received an ack for a previous transmission of a packet, |
| 377 | // we want to keep the "new" transmission of the packet unacked, |
| 378 | // but prevent the data from being retransmitted. |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 379 | delete unacked_packets_[newest_transmission].retransmittable_frames; |
| 380 | unacked_packets_[newest_transmission].retransmittable_frames = NULL; |
[email protected] | c05a6d22 | 2013-12-16 19:42:03 | [diff] [blame] | 381 | unacked_packets_[newest_transmission].previous_transmissions = NULL; |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 382 | pending_retransmissions_.erase(newest_transmission); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 383 | } |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 384 | |
| 385 | // Clear out information all previous transmissions. |
| 386 | ++previous_transmissions_it; |
| 387 | while (previous_transmissions_it != previous_transmissions->rend()) { |
| 388 | QuicPacketSequenceNumber previous_transmission = *previous_transmissions_it; |
| 389 | ++previous_transmissions_it; |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 390 | DiscardPacket(previous_transmission); |
| 391 | } |
| 392 | |
| 393 | delete previous_transmissions; |
| 394 | |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 395 | UnackedPacketMap::iterator next_unacked = unacked_packets_.begin(); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 396 | while (next_unacked != unacked_packets_.end() && |
| 397 | next_unacked->first < sequence_number) { |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 398 | ++next_unacked; |
| 399 | } |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 400 | return next_unacked; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 401 | } |
| 402 | |
| 403 | void QuicSentPacketManager::DiscardPacket( |
| 404 | QuicPacketSequenceNumber sequence_number) { |
| 405 | UnackedPacketMap::iterator unacked_it = |
| 406 | unacked_packets_.find(sequence_number); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 407 | // Packet was not meant to be retransmitted. |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 408 | if (unacked_it == unacked_packets_.end()) { |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 409 | return; |
| 410 | } |
| 411 | |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 412 | // Delete the retransmittable frames. |
| 413 | delete unacked_it->second.retransmittable_frames; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 414 | unacked_packets_.erase(unacked_it); |
[email protected] | 45a3e15 | 2013-09-25 16:35:11 | [diff] [blame] | 415 | pending_retransmissions_.erase(sequence_number); |
[email protected] | c67a82cb | 2013-09-24 02:53:21 | [diff] [blame] | 416 | return; |
| 417 | } |
| 418 | |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 419 | bool QuicSentPacketManager::IsUnacked( |
| 420 | QuicPacketSequenceNumber sequence_number) const { |
| 421 | return ContainsKey(unacked_packets_, sequence_number); |
| 422 | } |
| 423 | |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 424 | QuicSequenceNumberLength QuicSentPacketManager::GetSequenceNumberLength( |
| 425 | QuicPacketSequenceNumber sequence_number) const { |
| 426 | DCHECK(ContainsKey(unacked_packets_, sequence_number)); |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 427 | |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 428 | return unacked_packets_.find(sequence_number)->second.sequence_number_length; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 429 | } |
| 430 | |
| 431 | bool QuicSentPacketManager::HasUnackedPackets() const { |
| 432 | return !unacked_packets_.empty(); |
| 433 | } |
| 434 | |
[email protected] | 0ac0c5b | 2013-11-20 05:55:58 | [diff] [blame] | 435 | size_t QuicSentPacketManager::GetNumRetransmittablePackets() const { |
| 436 | size_t num_unacked_packets = 0; |
| 437 | for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 438 | it != unacked_packets_.end(); ++it) { |
| 439 | QuicPacketSequenceNumber sequence_number = it->first; |
| 440 | if (HasRetransmittableFrames(sequence_number)) { |
| 441 | ++num_unacked_packets; |
| 442 | } |
| 443 | } |
| 444 | return num_unacked_packets; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 445 | } |
| 446 | |
| 447 | QuicPacketSequenceNumber |
| 448 | QuicSentPacketManager::GetLeastUnackedSentPacket() const { |
| 449 | if (unacked_packets_.empty()) { |
| 450 | // If there are no unacked packets, set the least unacked packet to |
| 451 | // the sequence number of the next packet sent. |
| 452 | return helper_->GetNextPacketSequenceNumber(); |
| 453 | } |
| 454 | |
| 455 | return unacked_packets_.begin()->first; |
| 456 | } |
| 457 | |
[email protected] | efecff9 | 2013-09-24 07:49:23 | [diff] [blame] | 458 | SequenceNumberSet QuicSentPacketManager::GetUnackedPackets() const { |
| 459 | SequenceNumberSet unacked_packets; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 460 | for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 461 | it != unacked_packets_.end(); ++it) { |
[email protected] | efecff9 | 2013-09-24 07:49:23 | [diff] [blame] | 462 | unacked_packets.insert(it->first); |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 463 | } |
[email protected] | efecff9 | 2013-09-24 07:49:23 | [diff] [blame] | 464 | return unacked_packets; |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 465 | } |
| 466 | |
[email protected] | 2115d33ba | 2014-01-02 21:53:52 | [diff] [blame^] | 467 | bool QuicSentPacketManager::OnPacketSent( |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 468 | QuicPacketSequenceNumber sequence_number, |
| 469 | QuicTime sent_time, |
| 470 | QuicByteCount bytes, |
| 471 | TransmissionType transmission_type, |
| 472 | HasRetransmittableData has_retransmittable_data) { |
| 473 | DCHECK_LT(0u, sequence_number); |
| 474 | DCHECK(!ContainsKey(pending_packets_, sequence_number)); |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 475 | DCHECK(ContainsKey(unacked_packets_, sequence_number)); |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 476 | |
| 477 | // Only track packets the send algorithm wants us to track. |
| 478 | if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes, |
| 479 | transmission_type, |
| 480 | has_retransmittable_data)) { |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 481 | DCHECK(unacked_packets_[sequence_number].retransmittable_frames == NULL); |
| 482 | unacked_packets_.erase(sequence_number); |
[email protected] | 2115d33ba | 2014-01-02 21:53:52 | [diff] [blame^] | 483 | // Do not reset the retransmission timer, since the packet isn't tracked. |
| 484 | return false; |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 485 | } |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 486 | |
[email protected] | 2115d33ba | 2014-01-02 21:53:52 | [diff] [blame^] | 487 | // Set the retransmission timer for the first pending packet. |
| 488 | const bool set_retransmission_timer = pending_packets_.empty(); |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 489 | unacked_packets_[sequence_number].sent_time = sent_time; |
| 490 | packet_history_map_[sequence_number] = |
| 491 | new SendAlgorithmInterface::SentPacket(bytes, sent_time); |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 492 | pending_packets_.insert(sequence_number); |
| 493 | CleanupPacketHistory(); |
[email protected] | 2115d33ba | 2014-01-02 21:53:52 | [diff] [blame^] | 494 | |
| 495 | return set_retransmission_timer; |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 496 | } |
| 497 | |
| 498 | void QuicSentPacketManager::OnRetransmissionTimeout() { |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 499 | // Abandon all pending packets to ensure the congestion window |
| 500 | // opens up before we attempt to retransmit packets. |
[email protected] | 457d695 | 2013-12-13 09:24:58 | [diff] [blame] | 501 | QuicTime::Delta retransmission_delay = GetRetransmissionDelay(); |
| 502 | QuicTime max_send_time = |
| 503 | clock_->ApproximateNow().Subtract(retransmission_delay); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 504 | |
| 505 | // Attempt to send all the unacked packets when the RTO fires, let the |
| 506 | // congestion manager decide how many to send immediately and the remaining |
| 507 | // packets will be queued for future sending. |
| 508 | DVLOG(1) << "OnRetransmissionTimeout() fired with " |
| 509 | << unacked_packets_.size() << " unacked packets."; |
| 510 | |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 511 | // Retransmit any packet with retransmittable frames and abandon the rest. |
[email protected] | 457d695 | 2013-12-13 09:24:58 | [diff] [blame] | 512 | bool packets_retransmitted = false; |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 513 | for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 514 | it != unacked_packets_.end(); ++it) { |
| 515 | if (it->second.retransmittable_frames != NULL) { |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 516 | OnPacketAbandoned(it->first); |
[email protected] | 457d695 | 2013-12-13 09:24:58 | [diff] [blame] | 517 | packets_retransmitted = true; |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 518 | MarkForRetransmission(it->first, RTO_RETRANSMISSION); |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 519 | } else if (it->second.sent_time <= max_send_time) { |
| 520 | OnPacketAbandoned(it->first); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 521 | } |
| 522 | } |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 523 | |
[email protected] | 457d695 | 2013-12-13 09:24:58 | [diff] [blame] | 524 | // Only inform the sent packet manager of an RTO if data was retransmitted. |
| 525 | if (packets_retransmitted) { |
| 526 | ++consecutive_rto_count_; |
| 527 | send_algorithm_->OnRetransmissionTimeout(); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 528 | } |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 529 | } |
| 530 | |
| 531 | void QuicSentPacketManager::OnPacketAbandoned( |
| 532 | QuicPacketSequenceNumber sequence_number) { |
| 533 | SequenceNumberSet::iterator it = pending_packets_.find(sequence_number); |
| 534 | if (it != pending_packets_.end()) { |
| 535 | DCHECK(ContainsKey(packet_history_map_, sequence_number)); |
| 536 | send_algorithm_->OnPacketAbandoned( |
| 537 | sequence_number, packet_history_map_[sequence_number]->bytes_sent()); |
| 538 | pending_packets_.erase(it); |
| 539 | } |
| 540 | } |
| 541 | |
| 542 | void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 543 | const QuicCongestionFeedbackFrame& frame, |
| 544 | const QuicTime& feedback_receive_time) { |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 545 | send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( |
| 546 | frame, feedback_receive_time, packet_history_map_); |
| 547 | } |
| 548 | |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 549 | void QuicSentPacketManager::MaybeRetransmitOnAckFrame( |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 550 | const ReceivedPacketInfo& received_info, |
| 551 | const QuicTime& ack_receive_time) { |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 552 | // Go through all pending packets up to the largest observed and see if any |
| 553 | // need to be retransmitted or lost. |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 554 | SequenceNumberSet::iterator it = pending_packets_.begin(); |
| 555 | SequenceNumberSet::iterator it_upper = |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 556 | pending_packets_.upper_bound(received_info.largest_observed); |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 557 | |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 558 | size_t num_retransmitted = 0; |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 559 | SequenceNumberSet lost_packets; |
| 560 | while (it != it_upper) { |
| 561 | QuicPacketSequenceNumber sequence_number = *it; |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 562 | DVLOG(1) << "still missing packet " << sequence_number; |
| 563 | // Acks must be handled previously, so ensure it's missing and not acked. |
| 564 | DCHECK(IsAwaitingPacket(received_info, sequence_number)); |
| 565 | DCHECK(ContainsKey(packet_history_map_, sequence_number)); |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 566 | const SendAlgorithmInterface::SentPacket* sent_packet = |
| 567 | packet_history_map_[sequence_number]; |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 568 | const TransmissionInfo& transmission_info = |
| 569 | unacked_packets_[sequence_number]; |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 570 | |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 571 | // Consider it multiple nacks when there is a gap between the missing packet |
| 572 | // and the largest observed, since the purpose of a nack threshold is to |
| 573 | // tolerate re-ordering. This handles both StretchAcks and Forward Acks. |
| 574 | // TODO(ianswett): This relies heavily on sequential reception of packets, |
| 575 | // and makes an assumption that the congestion control uses TCP style nacks. |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 576 | size_t min_nacks = received_info.largest_observed - sequence_number; |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 577 | packet_history_map_[sequence_number]->Nack(min_nacks); |
| 578 | |
| 579 | size_t num_nacks_needed = kNumberOfNacksBeforeRetransmission; |
| 580 | // Check for early retransmit(RFC5827) when the last packet gets acked and |
| 581 | // the there are fewer than 4 pending packets. |
| 582 | if (pending_packets_.size() <= kNumberOfNacksBeforeRetransmission && |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 583 | transmission_info.retransmittable_frames && |
| 584 | packet_history_map_.rbegin()->first == received_info.largest_observed) { |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 585 | num_nacks_needed = received_info.largest_observed - sequence_number; |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 586 | } |
| 587 | |
| 588 | if (sent_packet->nack_count() < num_nacks_needed) { |
| 589 | ++it; |
| 590 | continue; |
| 591 | } |
| 592 | |
| 593 | // If the number of retransmissions has maxed out, don't lose or retransmit |
| 594 | // any more packets. |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 595 | if (num_retransmitted >= kMaxRetransmissionsPerAck) { |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 596 | ++it; |
| 597 | continue; |
| 598 | } |
| 599 | |
| 600 | lost_packets.insert(sequence_number); |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 601 | if (transmission_info.retransmittable_frames) { |
| 602 | ++num_retransmitted; |
| 603 | MarkForRetransmission(*it, NACK_RETRANSMISSION); |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 604 | } |
| 605 | |
| 606 | ++it; |
| 607 | } |
| 608 | // Abandon packets after the loop over pending packets, because otherwise it |
| 609 | // changes the early retransmit logic and iteration. |
| 610 | for (SequenceNumberSet::const_iterator it = lost_packets.begin(); |
| 611 | it != lost_packets.end(); ++it) { |
| 612 | // TODO(ianswett): OnPacketLost is also called from TCPCubicSender when |
| 613 | // an FEC packet is lost, but FEC loss information should be shared among |
| 614 | // congestion managers. Additionally, if it's expected the FEC packet may |
| 615 | // repair the loss, it should be recorded as a loss to the congestion |
| 616 | // manager, but not retransmitted until it's known whether the FEC packet |
| 617 | // arrived. |
| 618 | send_algorithm_->OnPacketLost(*it, ack_receive_time); |
| 619 | OnPacketAbandoned(*it); |
| 620 | } |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 621 | } |
| 622 | |
[email protected] | 41fb637 | 2013-12-10 05:26:40 | [diff] [blame] | 623 | void QuicSentPacketManager::MaybeUpdateRTT( |
| 624 | const ReceivedPacketInfo& received_info, |
| 625 | const QuicTime& ack_receive_time) { |
| 626 | // We calculate the RTT based on the highest ACKed sequence number, the lower |
| 627 | // sequence numbers will include the ACK aggregation delay. |
| 628 | SendAlgorithmInterface::SentPacketsMap::iterator history_it = |
| 629 | packet_history_map_.find(received_info.largest_observed); |
| 630 | // TODO(satyamshekhar): largest_observed might be missing. |
| 631 | if (history_it == packet_history_map_.end()) { |
| 632 | return; |
| 633 | } |
| 634 | |
| 635 | QuicTime::Delta send_delta = ack_receive_time.Subtract( |
| 636 | history_it->second->send_timestamp()); |
| 637 | if (send_delta > received_info.delta_time_largest_observed) { |
| 638 | rtt_sample_ = send_delta.Subtract( |
| 639 | received_info.delta_time_largest_observed); |
| 640 | } else if (rtt_sample_.IsInfinite()) { |
| 641 | // Even though we received information from the peer suggesting |
| 642 | // an invalid (negative) RTT, we can use the send delta as an |
| 643 | // approximation until we get a better estimate. |
| 644 | rtt_sample_ = send_delta; |
| 645 | } |
| 646 | } |
| 647 | |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 648 | QuicTime::Delta QuicSentPacketManager::TimeUntilSend( |
| 649 | QuicTime now, |
| 650 | TransmissionType transmission_type, |
| 651 | HasRetransmittableData retransmittable, |
| 652 | IsHandshake handshake) { |
| 653 | return send_algorithm_->TimeUntilSend(now, transmission_type, retransmittable, |
| 654 | handshake); |
| 655 | } |
| 656 | |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 657 | // Ensures that the Delayed Ack timer is always set to a value lesser |
| 658 | // than the retransmission timer's minimum value (MinRTO). We want the |
| 659 | // delayed ack to get back to the QUIC peer before the sender's |
| 660 | // retransmission timer triggers. Since we do not know the |
| 661 | // reverse-path one-way delay, we assume equal delays for forward and |
| 662 | // reverse paths, and ensure that the timer is set to less than half |
| 663 | // of the MinRTO. |
| 664 | // There may be a value in making this delay adaptive with the help of |
| 665 | // the sender and a signaling mechanism -- if the sender uses a |
| 666 | // different MinRTO, we may get spurious retransmissions. May not have |
| 667 | // any benefits, but if the delayed ack becomes a significant source |
| 668 | // of (likely, tail) latency, then consider such a mechanism. |
| 669 | |
[email protected] | 2115d33ba | 2014-01-02 21:53:52 | [diff] [blame^] | 670 | const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 671 | return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); |
| 672 | } |
| 673 | |
[email protected] | c068020 | 2013-12-18 04:52:34 | [diff] [blame] | 674 | const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
| 675 | if (pending_packets_.empty()) { |
| 676 | return QuicTime::Zero(); |
| 677 | } |
| 678 | return clock_->ApproximateNow().Add(GetRetransmissionDelay()); |
| 679 | } |
| 680 | |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 681 | const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { |
| 682 | size_t number_retransmissions = consecutive_rto_count_; |
| 683 | if (FLAGS_limit_rto_increase_for_tests) { |
| 684 | const size_t kTailDropWindowSize = 5; |
| 685 | const size_t kTailDropMaxRetransmissions = 4; |
| 686 | if (pending_packets_.size() <= kTailDropWindowSize) { |
| 687 | // Avoid exponential backoff of RTO when there are only a few packets |
| 688 | // outstanding. This helps avoid the situation where fake packet loss |
| 689 | // causes a packet and it's retransmission to be dropped causing |
| 690 | // test timouts. |
| 691 | if (number_retransmissions <= kTailDropMaxRetransmissions) { |
| 692 | number_retransmissions = 0; |
| 693 | } else { |
| 694 | number_retransmissions -= kTailDropMaxRetransmissions; |
| 695 | } |
| 696 | } |
| 697 | } |
| 698 | |
| 699 | QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); |
| 700 | if (retransmission_delay.IsZero()) { |
| 701 | // We are in the initial state, use default timeout values. |
| 702 | retransmission_delay = |
| 703 | QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
| 704 | } |
| 705 | // Calculate exponential back off. |
| 706 | retransmission_delay = QuicTime::Delta::FromMilliseconds( |
| 707 | retransmission_delay.ToMilliseconds() * static_cast<size_t>( |
| 708 | (1 << min<size_t>(number_retransmissions, kMaxRetransmissions)))); |
| 709 | |
| 710 | // TODO(rch): This code should move to |send_algorithm_|. |
| 711 | if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { |
| 712 | return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); |
| 713 | } |
| 714 | if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) { |
| 715 | return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs); |
| 716 | } |
| 717 | return retransmission_delay; |
| 718 | } |
| 719 | |
| 720 | const QuicTime::Delta QuicSentPacketManager::SmoothedRtt() const { |
| 721 | return send_algorithm_->SmoothedRtt(); |
| 722 | } |
| 723 | |
| 724 | QuicBandwidth QuicSentPacketManager::BandwidthEstimate() const { |
| 725 | return send_algorithm_->BandwidthEstimate(); |
| 726 | } |
| 727 | |
| 728 | QuicByteCount QuicSentPacketManager::GetCongestionWindow() const { |
| 729 | return send_algorithm_->GetCongestionWindow(); |
| 730 | } |
| 731 | |
[email protected] | 2adef90e | 2013-12-02 20:26:57 | [diff] [blame] | 732 | void QuicSentPacketManager::CleanupPacketHistory() { |
| 733 | const QuicTime::Delta kHistoryPeriod = |
| 734 | QuicTime::Delta::FromMilliseconds(kHistoryPeriodMs); |
| 735 | QuicTime now = clock_->ApproximateNow(); |
| 736 | |
| 737 | SendAlgorithmInterface::SentPacketsMap::iterator history_it = |
| 738 | packet_history_map_.begin(); |
| 739 | for (; history_it != packet_history_map_.end(); ++history_it) { |
| 740 | if (now.Subtract(history_it->second->send_timestamp()) <= kHistoryPeriod) { |
| 741 | return; |
| 742 | } |
| 743 | // Don't remove packets which have not been acked. |
| 744 | if (ContainsKey(pending_packets_, history_it->first)) { |
| 745 | continue; |
| 746 | } |
| 747 | delete history_it->second; |
| 748 | packet_history_map_.erase(history_it); |
| 749 | history_it = packet_history_map_.begin(); |
| 750 | } |
| 751 | } |
| 752 | |
| 753 | void QuicSentPacketManager::MaybeEnablePacing() { |
| 754 | if (!FLAGS_enable_quic_pacing) { |
| 755 | return; |
| 756 | } |
| 757 | |
| 758 | if (using_pacing_) { |
| 759 | return; |
| 760 | } |
| 761 | |
| 762 | using_pacing_ = true; |
| 763 | send_algorithm_.reset( |
| 764 | new PacingSender(send_algorithm_.release(), |
| 765 | QuicTime::Delta::FromMicroseconds(1))); |
| 766 | } |
| 767 | |
[email protected] | 4d1789c3 | 2013-09-18 23:54:36 | [diff] [blame] | 768 | } // namespace net |