| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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_sent_packet_manager.h" | 5 #include "net/quic/quic_sent_packet_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. | 37 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. |
| 38 static const size_t kDefaultMaxTailLossProbes = 2; | 38 static const size_t kDefaultMaxTailLossProbes = 2; |
| 39 static const int64 kMinTailLossProbeTimeoutMs = 10; | 39 static const int64 kMinTailLossProbeTimeoutMs = 10; |
| 40 | 40 |
| 41 bool HasCryptoHandshake( | 41 bool HasCryptoHandshake( |
| 42 const QuicUnackedPacketMap::TransmissionInfo& transmission_info) { | 42 const QuicUnackedPacketMap::TransmissionInfo& transmission_info) { |
| 43 if (transmission_info.retransmittable_frames == NULL) { | 43 if (transmission_info.retransmittable_frames == NULL) { |
| 44 return false; | 44 return false; |
| 45 } | 45 } |
| 46 return transmission_info.retransmittable_frames->HasCryptoHandshake() == | 46 return transmission_info.retransmittable_frames->HasCryptoHandshake() == |
| 47 IS_HANDSHAKE; | 47 IS_HANDSHAKE; |
| 48 } | 48 } |
| 49 | 49 |
| 50 } // namespace | 50 } // namespace |
| 51 | 51 |
| 52 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 52 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
| 53 | 53 |
| 54 QuicSentPacketManager::QuicSentPacketManager(bool is_server, | 54 QuicSentPacketManager::QuicSentPacketManager(bool is_server, |
| 55 const QuicClock* clock, | 55 const QuicClock* clock, |
| 56 QuicConnectionStats* stats, | 56 QuicConnectionStats* stats, |
| 57 CongestionFeedbackType type, | 57 CongestionFeedbackType type, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 if (largest_observed_acked) { | 133 if (largest_observed_acked) { |
| 134 // Reset all retransmit counters any time a new packet is acked. | 134 // Reset all retransmit counters any time a new packet is acked. |
| 135 consecutive_rto_count_ = 0; | 135 consecutive_rto_count_ = 0; |
| 136 consecutive_tlp_count_ = 0; | 136 consecutive_tlp_count_ = 0; |
| 137 consecutive_crypto_retransmission_count_ = 0; | 137 consecutive_crypto_retransmission_count_ = 0; |
| 138 } | 138 } |
| 139 } | 139 } |
| 140 | 140 |
| 141 void QuicSentPacketManager::DiscardUnackedPacket( | 141 void QuicSentPacketManager::DiscardUnackedPacket( |
| 142 QuicPacketSequenceNumber sequence_number) { | 142 QuicPacketSequenceNumber sequence_number) { |
| 143 MarkPacketHandled(sequence_number, QuicTime::Delta::Zero(), | 143 MarkPacketHandled( |
| 144 NOT_RECEIVED_BY_PEER); | 144 sequence_number, QuicTime::Delta::Zero(), NOT_RECEIVED_BY_PEER); |
| 145 } | 145 } |
| 146 | 146 |
| 147 void QuicSentPacketManager::HandleAckForSentPackets( | 147 void QuicSentPacketManager::HandleAckForSentPackets( |
| 148 const ReceivedPacketInfo& received_info) { | 148 const ReceivedPacketInfo& received_info) { |
| 149 // Go through the packets we have not received an ack for and see if this | 149 // Go through the packets we have not received an ack for and see if this |
| 150 // incoming_ack shows they've been seen by the peer. | 150 // incoming_ack shows they've been seen by the peer. |
| 151 QuicTime::Delta delta_largest_observed = | 151 QuicTime::Delta delta_largest_observed = |
| 152 received_info.delta_time_largest_observed; | 152 received_info.delta_time_largest_observed; |
| 153 QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 153 QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 154 while (it != unacked_packets_.end()) { | 154 while (it != unacked_packets_.end()) { |
| 155 QuicPacketSequenceNumber sequence_number = it->first; | 155 QuicPacketSequenceNumber sequence_number = it->first; |
| 156 if (sequence_number > received_info.largest_observed) { | 156 if (sequence_number > received_info.largest_observed) { |
| 157 // These packets are still in flight. | 157 // These packets are still in flight. |
| 158 break; | 158 break; |
| 159 } | 159 } |
| 160 | 160 |
| 161 if (IsAwaitingPacket(received_info, sequence_number)) { | 161 if (IsAwaitingPacket(received_info, sequence_number)) { |
| 162 // Remove any packets not being tracked by the send algorithm, allowing | 162 // Remove any packets not being tracked by the send algorithm, allowing |
| 163 // the high water mark to be raised if necessary. | 163 // the high water mark to be raised if necessary. |
| 164 if (QuicUnackedPacketMap::IsSentAndNotPending(it->second)) { | 164 if (QuicUnackedPacketMap::IsSentAndNotPending(it->second)) { |
| 165 it = MarkPacketHandled(sequence_number, delta_largest_observed, | 165 it = MarkPacketHandled( |
| 166 NOT_RECEIVED_BY_PEER); | 166 sequence_number, delta_largest_observed, NOT_RECEIVED_BY_PEER); |
| 167 } else { | 167 } else { |
| 168 ++it; | 168 ++it; |
| 169 } | 169 } |
| 170 continue; | 170 continue; |
| 171 } | 171 } |
| 172 | 172 |
| 173 // Packet was acked, so remove it from our unacked packet list. | 173 // Packet was acked, so remove it from our unacked packet list. |
| 174 DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number; | 174 DVLOG(1) << ENDPOINT << "Got an ack for packet " << sequence_number; |
| 175 // If data is associated with the most recent transmission of this | 175 // If data is associated with the most recent transmission of this |
| 176 // packet, then inform the caller. | 176 // packet, then inform the caller. |
| 177 it = MarkPacketHandled(sequence_number, delta_largest_observed, | 177 it = MarkPacketHandled( |
| 178 RECEIVED_BY_PEER); | 178 sequence_number, delta_largest_observed, RECEIVED_BY_PEER); |
| 179 } | 179 } |
| 180 | 180 |
| 181 // Discard any retransmittable frames associated with revived packets. | 181 // Discard any retransmittable frames associated with revived packets. |
| 182 for (SequenceNumberSet::const_iterator revived_it = | 182 for (SequenceNumberSet::const_iterator revived_it = |
| 183 received_info.revived_packets.begin(); | 183 received_info.revived_packets.begin(); |
| 184 revived_it != received_info.revived_packets.end(); ++revived_it) { | 184 revived_it != received_info.revived_packets.end(); |
| 185 ++revived_it) { |
| 185 MarkPacketRevived(*revived_it, delta_largest_observed); | 186 MarkPacketRevived(*revived_it, delta_largest_observed); |
| 186 } | 187 } |
| 187 | 188 |
| 188 // If we have received a truncated ack, then we need to | 189 // If we have received a truncated ack, then we need to |
| 189 // clear out some previous transmissions to allow the peer | 190 // clear out some previous transmissions to allow the peer |
| 190 // to actually ACK new packets. | 191 // to actually ACK new packets. |
| 191 if (received_info.is_truncated) { | 192 if (received_info.is_truncated) { |
| 192 unacked_packets_.ClearPreviousRetransmissions( | 193 unacked_packets_.ClearPreviousRetransmissions( |
| 193 received_info.missing_packets.size() / 2); | 194 received_info.missing_packets.size() / 2); |
| 194 } | 195 } |
| 195 } | 196 } |
| 196 | 197 |
| 197 bool QuicSentPacketManager::HasRetransmittableFrames( | 198 bool QuicSentPacketManager::HasRetransmittableFrames( |
| 198 QuicPacketSequenceNumber sequence_number) const { | 199 QuicPacketSequenceNumber sequence_number) const { |
| 199 return unacked_packets_.HasRetransmittableFrames(sequence_number); | 200 return unacked_packets_.HasRetransmittableFrames(sequence_number); |
| 200 } | 201 } |
| 201 | 202 |
| 202 void QuicSentPacketManager::RetransmitUnackedPackets( | 203 void QuicSentPacketManager::RetransmitUnackedPackets( |
| 203 RetransmissionType retransmission_type) { | 204 RetransmissionType retransmission_type) { |
| 204 QuicUnackedPacketMap::const_iterator unacked_it = unacked_packets_.begin(); | 205 QuicUnackedPacketMap::const_iterator unacked_it = unacked_packets_.begin(); |
| 205 while (unacked_it != unacked_packets_.end()) { | 206 while (unacked_it != unacked_packets_.end()) { |
| 206 const RetransmittableFrames* frames = | 207 const RetransmittableFrames* frames = |
| 207 unacked_it->second.retransmittable_frames; | 208 unacked_it->second.retransmittable_frames; |
| 208 // Only mark it as handled if it can't be retransmitted and there are no | 209 // Only mark it as handled if it can't be retransmitted and there are no |
| 209 // pending retransmissions which would be cleared. | 210 // pending retransmissions which would be cleared. |
| 210 if (frames == NULL && unacked_it->second.all_transmissions->size() == 1 && | 211 if (frames == NULL && unacked_it->second.all_transmissions->size() == 1 && |
| 211 retransmission_type == ALL_PACKETS) { | 212 retransmission_type == ALL_PACKETS) { |
| 212 unacked_it = MarkPacketHandled(unacked_it->first, QuicTime::Delta::Zero(), | 213 unacked_it = MarkPacketHandled( |
| 213 NOT_RECEIVED_BY_PEER); | 214 unacked_it->first, QuicTime::Delta::Zero(), NOT_RECEIVED_BY_PEER); |
| 214 continue; | 215 continue; |
| 215 } | 216 } |
| 216 // If it had no other transmissions, we handle it above. If it has | 217 // If it had no other transmissions, we handle it above. If it has |
| 217 // other transmissions, one of them must have retransmittable frames, | 218 // other transmissions, one of them must have retransmittable frames, |
| 218 // so that gets resolved the same way as other retransmissions. | 219 // so that gets resolved the same way as other retransmissions. |
| 219 // TODO(ianswett): Consider adding a new retransmission type which removes | 220 // TODO(ianswett): Consider adding a new retransmission type which removes |
| 220 // all these old packets from unacked and retransmits them as new sequence | 221 // all these old packets from unacked and retransmits them as new sequence |
| 221 // numbers with no connection to the previous ones. | 222 // numbers with no connection to the previous ones. |
| 222 if (frames != NULL && (retransmission_type == ALL_PACKETS || | 223 if (frames != NULL && (retransmission_type == ALL_PACKETS || |
| 223 frames->encryption_level() == ENCRYPTION_INITIAL)) { | 224 frames->encryption_level() == ENCRYPTION_INITIAL)) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 } | 260 } |
| 260 | 261 |
| 261 pending_retransmissions_[sequence_number] = transmission_type; | 262 pending_retransmissions_[sequence_number] = transmission_type; |
| 262 } | 263 } |
| 263 | 264 |
| 264 bool QuicSentPacketManager::HasPendingRetransmissions() const { | 265 bool QuicSentPacketManager::HasPendingRetransmissions() const { |
| 265 return !pending_retransmissions_.empty(); | 266 return !pending_retransmissions_.empty(); |
| 266 } | 267 } |
| 267 | 268 |
| 268 QuicSentPacketManager::PendingRetransmission | 269 QuicSentPacketManager::PendingRetransmission |
| 269 QuicSentPacketManager::NextPendingRetransmission() { | 270 QuicSentPacketManager::NextPendingRetransmission() { |
| 270 DCHECK(!pending_retransmissions_.empty()); | 271 DCHECK(!pending_retransmissions_.empty()); |
| 271 QuicPacketSequenceNumber sequence_number = | 272 QuicPacketSequenceNumber sequence_number = |
| 272 pending_retransmissions_.begin()->first; | 273 pending_retransmissions_.begin()->first; |
| 273 TransmissionType transmission_type = pending_retransmissions_.begin()->second; | 274 TransmissionType transmission_type = pending_retransmissions_.begin()->second; |
| 274 if (unacked_packets_.HasPendingCryptoPackets()) { | 275 if (unacked_packets_.HasPendingCryptoPackets()) { |
| 275 // Ensure crypto packets are retransmitted before other packets. | 276 // Ensure crypto packets are retransmitted before other packets. |
| 276 PendingRetransmissionMap::const_iterator it = | 277 PendingRetransmissionMap::const_iterator it = |
| 277 pending_retransmissions_.begin(); | 278 pending_retransmissions_.begin(); |
| 278 do { | 279 do { |
| 279 if (HasCryptoHandshake( | 280 if (HasCryptoHandshake(unacked_packets_.GetTransmissionInfo(it->first))) { |
| 280 unacked_packets_.GetTransmissionInfo(it->first))) { | |
| 281 sequence_number = it->first; | 281 sequence_number = it->first; |
| 282 transmission_type = it->second; | 282 transmission_type = it->second; |
| 283 break; | 283 break; |
| 284 } | 284 } |
| 285 ++it; | 285 ++it; |
| 286 } while (it != pending_retransmissions_.end()); | 286 } while (it != pending_retransmissions_.end()); |
| 287 } | 287 } |
| 288 DCHECK(unacked_packets_.IsUnacked(sequence_number)); | 288 DCHECK(unacked_packets_.IsUnacked(sequence_number)); |
| 289 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = | 289 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = |
| 290 unacked_packets_.GetTransmissionInfo(sequence_number); | 290 unacked_packets_.GetTransmissionInfo(sequence_number); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 304 } | 304 } |
| 305 // This packet has been revived at the receiver. If we were going to | 305 // This packet has been revived at the receiver. If we were going to |
| 306 // retransmit it, do not retransmit it anymore. | 306 // retransmit it, do not retransmit it anymore. |
| 307 pending_retransmissions_.erase(sequence_number); | 307 pending_retransmissions_.erase(sequence_number); |
| 308 | 308 |
| 309 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = | 309 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = |
| 310 unacked_packets_.GetTransmissionInfo(sequence_number); | 310 unacked_packets_.GetTransmissionInfo(sequence_number); |
| 311 // The AckNotifierManager needs to be notified for revived packets, | 311 // The AckNotifierManager needs to be notified for revived packets, |
| 312 // since it indicates the packet arrived from the appliction's perspective. | 312 // since it indicates the packet arrived from the appliction's perspective. |
| 313 if (transmission_info.retransmittable_frames) { | 313 if (transmission_info.retransmittable_frames) { |
| 314 ack_notifier_manager_.OnPacketAcked( | 314 ack_notifier_manager_.OnPacketAcked(sequence_number, |
| 315 sequence_number, delta_largest_observed); | 315 delta_largest_observed); |
| 316 } | 316 } |
| 317 | 317 |
| 318 if (!transmission_info.pending) { | 318 if (!transmission_info.pending) { |
| 319 unacked_packets_.RemovePacket(sequence_number); | 319 unacked_packets_.RemovePacket(sequence_number); |
| 320 } else { | 320 } else { |
| 321 unacked_packets_.NeuterPacket(sequence_number); | 321 unacked_packets_.NeuterPacket(sequence_number); |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 | 324 |
| 325 QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( | 325 QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( |
| 326 QuicPacketSequenceNumber sequence_number, | 326 QuicPacketSequenceNumber sequence_number, |
| 327 QuicTime::Delta delta_largest_observed, ReceivedByPeer received_by_peer) { | 327 QuicTime::Delta delta_largest_observed, |
| 328 ReceivedByPeer received_by_peer) { |
| 328 if (!unacked_packets_.IsUnacked(sequence_number)) { | 329 if (!unacked_packets_.IsUnacked(sequence_number)) { |
| 329 LOG(DFATAL) << "Packet is not unacked: " << sequence_number; | 330 LOG(DFATAL) << "Packet is not unacked: " << sequence_number; |
| 330 return unacked_packets_.end(); | 331 return unacked_packets_.end(); |
| 331 } | 332 } |
| 332 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = | 333 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = |
| 333 unacked_packets_.GetTransmissionInfo(sequence_number); | 334 unacked_packets_.GetTransmissionInfo(sequence_number); |
| 334 // If this packet is pending, remove it and inform the send algorithm. | 335 // If this packet is pending, remove it and inform the send algorithm. |
| 335 if (transmission_info.pending) { | 336 if (transmission_info.pending) { |
| 336 if (received_by_peer == RECEIVED_BY_PEER) { | 337 if (received_by_peer == RECEIVED_BY_PEER) { |
| 337 send_algorithm_->OnPacketAcked(sequence_number, | 338 send_algorithm_->OnPacketAcked(sequence_number, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 | 394 |
| 394 bool QuicSentPacketManager::IsUnacked( | 395 bool QuicSentPacketManager::IsUnacked( |
| 395 QuicPacketSequenceNumber sequence_number) const { | 396 QuicPacketSequenceNumber sequence_number) const { |
| 396 return unacked_packets_.IsUnacked(sequence_number); | 397 return unacked_packets_.IsUnacked(sequence_number); |
| 397 } | 398 } |
| 398 | 399 |
| 399 bool QuicSentPacketManager::HasUnackedPackets() const { | 400 bool QuicSentPacketManager::HasUnackedPackets() const { |
| 400 return unacked_packets_.HasUnackedPackets(); | 401 return unacked_packets_.HasUnackedPackets(); |
| 401 } | 402 } |
| 402 | 403 |
| 403 QuicPacketSequenceNumber | 404 QuicPacketSequenceNumber QuicSentPacketManager::GetLeastUnackedSentPacket() |
| 404 QuicSentPacketManager::GetLeastUnackedSentPacket() const { | 405 const { |
| 405 return unacked_packets_.GetLeastUnackedSentPacket(); | 406 return unacked_packets_.GetLeastUnackedSentPacket(); |
| 406 } | 407 } |
| 407 | 408 |
| 408 bool QuicSentPacketManager::OnPacketSent( | 409 bool QuicSentPacketManager::OnPacketSent( |
| 409 QuicPacketSequenceNumber sequence_number, | 410 QuicPacketSequenceNumber sequence_number, |
| 410 QuicTime sent_time, | 411 QuicTime sent_time, |
| 411 QuicByteCount bytes, | 412 QuicByteCount bytes, |
| 412 TransmissionType transmission_type, | 413 TransmissionType transmission_type, |
| 413 HasRetransmittableData has_retransmittable_data) { | 414 HasRetransmittableData has_retransmittable_data) { |
| 414 DCHECK_LT(0u, sequence_number); | 415 DCHECK_LT(0u, sequence_number); |
| 415 LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets."; | 416 LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets."; |
| 416 // In rare circumstances, the packet could be serialized, sent, and then acked | 417 // In rare circumstances, the packet could be serialized, sent, and then acked |
| 417 // before OnPacketSent is called. | 418 // before OnPacketSent is called. |
| 418 if (!unacked_packets_.IsUnacked(sequence_number)) { | 419 if (!unacked_packets_.IsUnacked(sequence_number)) { |
| 419 return false; | 420 return false; |
| 420 } | 421 } |
| 421 | 422 |
| 422 // Only track packets as pending that the send algorithm wants us to track. | 423 // Only track packets as pending that the send algorithm wants us to track. |
| 423 if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes, | 424 if (!send_algorithm_->OnPacketSent( |
| 424 has_retransmittable_data)) { | 425 sent_time, sequence_number, bytes, has_retransmittable_data)) { |
| 425 unacked_packets_.SetSent(sequence_number, sent_time, bytes, false); | 426 unacked_packets_.SetSent(sequence_number, sent_time, bytes, false); |
| 426 // Do not reset the retransmission timer, since the packet isn't tracked. | 427 // Do not reset the retransmission timer, since the packet isn't tracked. |
| 427 return false; | 428 return false; |
| 428 } | 429 } |
| 429 | 430 |
| 430 const bool set_retransmission_timer = !unacked_packets_.HasPendingPackets(); | 431 const bool set_retransmission_timer = !unacked_packets_.HasPendingPackets(); |
| 431 | 432 |
| 432 unacked_packets_.SetSent(sequence_number, sent_time, bytes, true); | 433 unacked_packets_.SetSent(sequence_number, sent_time, bytes, true); |
| 433 | 434 |
| 434 // Reset the retransmission timer anytime a packet is sent in tail loss probe | 435 // Reset the retransmission timer anytime a packet is sent in tail loss probe |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 } | 467 } |
| 467 | 468 |
| 468 void QuicSentPacketManager::RetransmitCryptoPackets() { | 469 void QuicSentPacketManager::RetransmitCryptoPackets() { |
| 469 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); | 470 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); |
| 470 // TODO(ianswett): Typical TCP implementations only retransmit 5 times. | 471 // TODO(ianswett): Typical TCP implementations only retransmit 5 times. |
| 471 consecutive_crypto_retransmission_count_ = | 472 consecutive_crypto_retransmission_count_ = |
| 472 min(kMaxHandshakeRetransmissionBackoffs, | 473 min(kMaxHandshakeRetransmissionBackoffs, |
| 473 consecutive_crypto_retransmission_count_ + 1); | 474 consecutive_crypto_retransmission_count_ + 1); |
| 474 bool packet_retransmitted = false; | 475 bool packet_retransmitted = false; |
| 475 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 476 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 476 it != unacked_packets_.end(); ++it) { | 477 it != unacked_packets_.end(); |
| 478 ++it) { |
| 477 QuicPacketSequenceNumber sequence_number = it->first; | 479 QuicPacketSequenceNumber sequence_number = it->first; |
| 478 const RetransmittableFrames* frames = it->second.retransmittable_frames; | 480 const RetransmittableFrames* frames = it->second.retransmittable_frames; |
| 479 // Only retransmit frames which are pending, and therefore have been sent. | 481 // Only retransmit frames which are pending, and therefore have been sent. |
| 480 if (!it->second.pending || frames == NULL || | 482 if (!it->second.pending || frames == NULL || |
| 481 frames->HasCryptoHandshake() != IS_HANDSHAKE) { | 483 frames->HasCryptoHandshake() != IS_HANDSHAKE) { |
| 482 continue; | 484 continue; |
| 483 } | 485 } |
| 484 packet_retransmitted = true; | 486 packet_retransmitted = true; |
| 485 MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION); | 487 MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION); |
| 486 // Abandon all the crypto retransmissions now so they're not lost later. | 488 // Abandon all the crypto retransmissions now so they're not lost later. |
| 487 OnPacketAbandoned(sequence_number); | 489 OnPacketAbandoned(sequence_number); |
| 488 } | 490 } |
| 489 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; | 491 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; |
| 490 } | 492 } |
| 491 | 493 |
| 492 void QuicSentPacketManager::RetransmitOldestPacket() { | 494 void QuicSentPacketManager::RetransmitOldestPacket() { |
| 493 DCHECK_EQ(TLP_MODE, GetRetransmissionMode()); | 495 DCHECK_EQ(TLP_MODE, GetRetransmissionMode()); |
| 494 ++consecutive_tlp_count_; | 496 ++consecutive_tlp_count_; |
| 495 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 497 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 496 it != unacked_packets_.end(); ++it) { | 498 it != unacked_packets_.end(); |
| 499 ++it) { |
| 497 QuicPacketSequenceNumber sequence_number = it->first; | 500 QuicPacketSequenceNumber sequence_number = it->first; |
| 498 const RetransmittableFrames* frames = it->second.retransmittable_frames; | 501 const RetransmittableFrames* frames = it->second.retransmittable_frames; |
| 499 // Only retransmit frames which are pending, and therefore have been sent. | 502 // Only retransmit frames which are pending, and therefore have been sent. |
| 500 if (!it->second.pending || frames == NULL) { | 503 if (!it->second.pending || frames == NULL) { |
| 501 continue; | 504 continue; |
| 502 } | 505 } |
| 503 DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake()); | 506 DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake()); |
| 504 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); | 507 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); |
| 505 return; | 508 return; |
| 506 } | 509 } |
| 507 DLOG(FATAL) | 510 DLOG(FATAL) |
| 508 << "No retransmittable packets, so RetransmitOldestPacket failed."; | 511 << "No retransmittable packets, so RetransmitOldestPacket failed."; |
| 509 } | 512 } |
| 510 | 513 |
| 511 void QuicSentPacketManager::RetransmitAllPackets() { | 514 void QuicSentPacketManager::RetransmitAllPackets() { |
| 512 // Abandon all retransmittable packets and packets older than the | 515 // Abandon all retransmittable packets and packets older than the |
| 513 // retransmission delay. | 516 // retransmission delay. |
| 514 | 517 |
| 515 DVLOG(1) << "OnRetransmissionTimeout() fired with " | 518 DVLOG(1) << "OnRetransmissionTimeout() fired with " |
| 516 << unacked_packets_.GetNumUnackedPackets() << " unacked packets."; | 519 << unacked_packets_.GetNumUnackedPackets() << " unacked packets."; |
| 517 | 520 |
| 518 // Request retransmission of all retransmittable packets when the RTO | 521 // Request retransmission of all retransmittable packets when the RTO |
| 519 // fires, and let the congestion manager decide how many to send | 522 // fires, and let the congestion manager decide how many to send |
| 520 // immediately and the remaining packets will be queued. | 523 // immediately and the remaining packets will be queued. |
| 521 // Abandon any non-retransmittable packets that are sufficiently old. | 524 // Abandon any non-retransmittable packets that are sufficiently old. |
| 522 bool packets_retransmitted = false; | 525 bool packets_retransmitted = false; |
| 523 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 526 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 524 it != unacked_packets_.end(); ++it) { | 527 it != unacked_packets_.end(); |
| 528 ++it) { |
| 525 unacked_packets_.SetNotPending(it->first); | 529 unacked_packets_.SetNotPending(it->first); |
| 526 if (it->second.retransmittable_frames != NULL) { | 530 if (it->second.retransmittable_frames != NULL) { |
| 527 packets_retransmitted = true; | 531 packets_retransmitted = true; |
| 528 MarkForRetransmission(it->first, RTO_RETRANSMISSION); | 532 MarkForRetransmission(it->first, RTO_RETRANSMISSION); |
| 529 } | 533 } |
| 530 } | 534 } |
| 531 | 535 |
| 532 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); | 536 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); |
| 533 if (packets_retransmitted) { | 537 if (packets_retransmitted) { |
| 534 ++consecutive_rto_count_; | 538 ++consecutive_rto_count_; |
| 535 } | 539 } |
| 536 } | 540 } |
| 537 | 541 |
| 538 QuicSentPacketManager::RetransmissionTimeoutMode | 542 QuicSentPacketManager::RetransmissionTimeoutMode |
| 539 QuicSentPacketManager::GetRetransmissionMode() const { | 543 QuicSentPacketManager::GetRetransmissionMode() const { |
| 540 DCHECK(unacked_packets_.HasPendingPackets()); | 544 DCHECK(unacked_packets_.HasPendingPackets()); |
| 541 if (unacked_packets_.HasPendingCryptoPackets()) { | 545 if (unacked_packets_.HasPendingCryptoPackets()) { |
| 542 return HANDSHAKE_MODE; | 546 return HANDSHAKE_MODE; |
| 543 } | 547 } |
| 544 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) { | 548 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) { |
| 545 return LOSS_MODE; | 549 return LOSS_MODE; |
| 546 } | 550 } |
| 547 if (consecutive_tlp_count_ < max_tail_loss_probes_) { | 551 if (consecutive_tlp_count_ < max_tail_loss_probes_) { |
| 548 if (unacked_packets_.HasUnackedRetransmittableFrames()) { | 552 if (unacked_packets_.HasUnackedRetransmittableFrames()) { |
| 549 return TLP_MODE; | 553 return TLP_MODE; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 560 LOG_IF(DFATAL, transmission_info.bytes_sent == 0); | 564 LOG_IF(DFATAL, transmission_info.bytes_sent == 0); |
| 561 send_algorithm_->OnPacketAbandoned(sequence_number, | 565 send_algorithm_->OnPacketAbandoned(sequence_number, |
| 562 transmission_info.bytes_sent); | 566 transmission_info.bytes_sent); |
| 563 unacked_packets_.SetNotPending(sequence_number); | 567 unacked_packets_.SetNotPending(sequence_number); |
| 564 } | 568 } |
| 565 } | 569 } |
| 566 | 570 |
| 567 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( | 571 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( |
| 568 const QuicCongestionFeedbackFrame& frame, | 572 const QuicCongestionFeedbackFrame& frame, |
| 569 const QuicTime& feedback_receive_time) { | 573 const QuicTime& feedback_receive_time) { |
| 570 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( | 574 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame(frame, |
| 571 frame, feedback_receive_time); | 575 feedback_receive_time); |
| 572 } | 576 } |
| 573 | 577 |
| 574 void QuicSentPacketManager::MaybeRetransmitOnAckFrame( | 578 void QuicSentPacketManager::MaybeRetransmitOnAckFrame( |
| 575 const ReceivedPacketInfo& received_info, | 579 const ReceivedPacketInfo& received_info, |
| 576 const QuicTime& ack_receive_time) { | 580 const QuicTime& ack_receive_time) { |
| 577 // Go through all pending packets up to the largest observed and count nacks. | 581 // Go through all pending packets up to the largest observed and count nacks. |
| 578 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 582 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 579 it != unacked_packets_.end() && | 583 it != unacked_packets_.end() && |
| 580 it->first <= received_info.largest_observed; ++it) { | 584 it->first <= received_info.largest_observed; |
| 585 ++it) { |
| 581 if (!it->second.pending) { | 586 if (!it->second.pending) { |
| 582 continue; | 587 continue; |
| 583 } | 588 } |
| 584 QuicPacketSequenceNumber sequence_number = it->first; | 589 QuicPacketSequenceNumber sequence_number = it->first; |
| 585 DVLOG(1) << "still missing packet " << sequence_number; | 590 DVLOG(1) << "still missing packet " << sequence_number; |
| 586 // Acks must be handled previously, so ensure it's missing and not acked. | 591 // Acks must be handled previously, so ensure it's missing and not acked. |
| 587 DCHECK(IsAwaitingPacket(received_info, sequence_number)); | 592 DCHECK(IsAwaitingPacket(received_info, sequence_number)); |
| 588 | 593 |
| 589 // Consider it multiple nacks when there is a gap between the missing packet | 594 // Consider it multiple nacks when there is a gap between the missing packet |
| 590 // and the largest observed, since the purpose of a nack threshold is to | 595 // and the largest observed, since the purpose of a nack threshold is to |
| 591 // tolerate re-ordering. This handles both StretchAcks and Forward Acks. | 596 // tolerate re-ordering. This handles both StretchAcks and Forward Acks. |
| 592 // The nack count only increases when the largest observed increases. | 597 // The nack count only increases when the largest observed increases. |
| 593 size_t min_nacks = received_info.largest_observed - sequence_number; | 598 size_t min_nacks = received_info.largest_observed - sequence_number; |
| 594 // Truncated acks can nack the largest observed, so set the nack count to 1. | 599 // Truncated acks can nack the largest observed, so set the nack count to 1. |
| 595 if (min_nacks == 0) { | 600 if (min_nacks == 0) { |
| 596 min_nacks = 1; | 601 min_nacks = 1; |
| 597 } | 602 } |
| 598 unacked_packets_.NackPacket(sequence_number, min_nacks); | 603 unacked_packets_.NackPacket(sequence_number, min_nacks); |
| 599 } | 604 } |
| 600 | 605 |
| 601 InvokeLossDetection(ack_receive_time); | 606 InvokeLossDetection(ack_receive_time); |
| 602 } | 607 } |
| 603 | 608 |
| 604 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { | 609 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
| 605 SequenceNumberSet lost_packets = | 610 SequenceNumberSet lost_packets = loss_algorithm_->DetectLostPackets( |
| 606 loss_algorithm_->DetectLostPackets(unacked_packets_, | 611 unacked_packets_, time, largest_observed_, rtt_stats_); |
| 607 time, | |
| 608 largest_observed_, | |
| 609 rtt_stats_); | |
| 610 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); | 612 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); |
| 611 it != lost_packets.end(); ++it) { | 613 it != lost_packets.end(); |
| 614 ++it) { |
| 612 QuicPacketSequenceNumber sequence_number = *it; | 615 QuicPacketSequenceNumber sequence_number = *it; |
| 613 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it | 616 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it |
| 614 // should be recorded as a loss to the send algorithm, but not retransmitted | 617 // should be recorded as a loss to the send algorithm, but not retransmitted |
| 615 // until it's known whether the FEC packet arrived. | 618 // until it's known whether the FEC packet arrived. |
| 616 ++stats_->packets_lost; | 619 ++stats_->packets_lost; |
| 617 send_algorithm_->OnPacketLost(sequence_number, time); | 620 send_algorithm_->OnPacketLost(sequence_number, time); |
| 618 OnPacketAbandoned(sequence_number); | 621 OnPacketAbandoned(sequence_number); |
| 619 | 622 |
| 620 if (unacked_packets_.HasRetransmittableFrames(sequence_number)) { | 623 if (unacked_packets_.HasRetransmittableFrames(sequence_number)) { |
| 621 MarkForRetransmission(sequence_number, LOSS_RETRANSMISSION); | 624 MarkForRetransmission(sequence_number, LOSS_RETRANSMISSION); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 // retransmission timer triggers. Since we do not know the | 672 // retransmission timer triggers. Since we do not know the |
| 670 // reverse-path one-way delay, we assume equal delays for forward and | 673 // reverse-path one-way delay, we assume equal delays for forward and |
| 671 // reverse paths, and ensure that the timer is set to less than half | 674 // reverse paths, and ensure that the timer is set to less than half |
| 672 // of the MinRTO. | 675 // of the MinRTO. |
| 673 // There may be a value in making this delay adaptive with the help of | 676 // There may be a value in making this delay adaptive with the help of |
| 674 // the sender and a signaling mechanism -- if the sender uses a | 677 // the sender and a signaling mechanism -- if the sender uses a |
| 675 // different MinRTO, we may get spurious retransmissions. May not have | 678 // different MinRTO, we may get spurious retransmissions. May not have |
| 676 // any benefits, but if the delayed ack becomes a significant source | 679 // any benefits, but if the delayed ack becomes a significant source |
| 677 // of (likely, tail) latency, then consider such a mechanism. | 680 // of (likely, tail) latency, then consider such a mechanism. |
| 678 const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { | 681 const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { |
| 679 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); | 682 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs / 2); |
| 680 } | 683 } |
| 681 | 684 |
| 682 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { | 685 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
| 683 // Don't set the timer if there are no pending packets. | 686 // Don't set the timer if there are no pending packets. |
| 684 if (!unacked_packets_.HasPendingPackets()) { | 687 if (!unacked_packets_.HasPendingPackets()) { |
| 685 return QuicTime::Zero(); | 688 return QuicTime::Zero(); |
| 686 } | 689 } |
| 687 switch (GetRetransmissionMode()) { | 690 switch (GetRetransmissionMode()) { |
| 688 case HANDSHAKE_MODE: | 691 case HANDSHAKE_MODE: |
| 689 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); | 692 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); |
| 690 case LOSS_MODE: | 693 case LOSS_MODE: |
| 691 return loss_algorithm_->GetLossTimeout(); | 694 return loss_algorithm_->GetLossTimeout(); |
| 692 case TLP_MODE: { | 695 case TLP_MODE: { |
| 693 // TODO(ianswett): When CWND is available, it would be preferable to | 696 // TODO(ianswett): When CWND is available, it would be preferable to |
| 694 // set the timer based on the earliest retransmittable packet. | 697 // set the timer based on the earliest retransmittable packet. |
| 695 // Base the updated timer on the send time of the last packet. | 698 // Base the updated timer on the send time of the last packet. |
| 696 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); | 699 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); |
| 697 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); | 700 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); |
| 698 // Ensure the tlp timer never gets set to a time in the past. | 701 // Ensure the tlp timer never gets set to a time in the past. |
| 699 return QuicTime::Max(clock_->ApproximateNow(), tlp_time); | 702 return QuicTime::Max(clock_->ApproximateNow(), tlp_time); |
| 700 } | 703 } |
| 701 case RTO_MODE: { | 704 case RTO_MODE: { |
| 702 // The RTO is based on the first pending packet. | 705 // The RTO is based on the first pending packet. |
| 703 const QuicTime sent_time = | 706 const QuicTime sent_time = |
| 704 unacked_packets_.GetFirstPendingPacketSentTime(); | 707 unacked_packets_.GetFirstPendingPacketSentTime(); |
| 705 QuicTime rto_timeout = sent_time.Add(GetRetransmissionDelay()); | 708 QuicTime rto_timeout = sent_time.Add(GetRetransmissionDelay()); |
| 706 // Always wait at least 1.5 * RTT from now. | 709 // Always wait at least 1.5 * RTT from now. |
| 707 QuicTime min_timeout = clock_->ApproximateNow().Add( | 710 QuicTime min_timeout = |
| 708 rtt_stats_.SmoothedRtt().Multiply(1.5)); | 711 clock_->ApproximateNow().Add(rtt_stats_.SmoothedRtt().Multiply(1.5)); |
| 709 | 712 |
| 710 return QuicTime::Max(min_timeout, rto_timeout); | 713 return QuicTime::Max(min_timeout, rto_timeout); |
| 711 } | 714 } |
| 712 } | 715 } |
| 713 DCHECK(false); | 716 DCHECK(false); |
| 714 return QuicTime::Zero(); | 717 return QuicTime::Zero(); |
| 715 } | 718 } |
| 716 | 719 |
| 717 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() | 720 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() |
| 718 const { | 721 const { |
| 719 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive | 722 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive |
| 720 // because crypto handshake messages don't incur a delayed ack time. | 723 // because crypto handshake messages don't incur a delayed ack time. |
| 721 int64 delay_ms = max<int64>(kMinHandshakeTimeoutMs, | 724 int64 delay_ms = max<int64>(kMinHandshakeTimeoutMs, |
| 722 1.5 * rtt_stats_.SmoothedRtt().ToMilliseconds()); | 725 1.5 * rtt_stats_.SmoothedRtt().ToMilliseconds()); |
| 723 return QuicTime::Delta::FromMilliseconds( | 726 return QuicTime::Delta::FromMilliseconds( |
| 724 delay_ms << consecutive_crypto_retransmission_count_); | 727 delay_ms << consecutive_crypto_retransmission_count_); |
| 725 } | 728 } |
| 726 | 729 |
| 727 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { | 730 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { |
| 728 QuicTime::Delta srtt = rtt_stats_.SmoothedRtt(); | 731 QuicTime::Delta srtt = rtt_stats_.SmoothedRtt(); |
| 729 if (!unacked_packets_.HasMultiplePendingPackets()) { | 732 if (!unacked_packets_.HasMultiplePendingPackets()) { |
| 730 return QuicTime::Delta::Max( | 733 return QuicTime::Delta::Max(srtt.Multiply(1.5).Add(DelayedAckTime()), |
| 731 srtt.Multiply(1.5).Add(DelayedAckTime()), srtt.Multiply(2)); | 734 srtt.Multiply(2)); |
| 732 } | 735 } |
| 733 return QuicTime::Delta::FromMilliseconds( | 736 return QuicTime::Delta::FromMilliseconds( |
| 734 max(kMinTailLossProbeTimeoutMs, | 737 max(kMinTailLossProbeTimeoutMs, |
| 735 static_cast<int64>(2 * srtt.ToMilliseconds()))); | 738 static_cast<int64>(2 * srtt.ToMilliseconds()))); |
| 736 } | 739 } |
| 737 | 740 |
| 738 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { | 741 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { |
| 739 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); | 742 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); |
| 740 // TODO(rch): This code should move to |send_algorithm_|. | 743 // TODO(rch): This code should move to |send_algorithm_|. |
| 741 if (retransmission_delay.IsZero()) { | 744 if (retransmission_delay.IsZero()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 772 void QuicSentPacketManager::MaybeEnablePacing() { | 775 void QuicSentPacketManager::MaybeEnablePacing() { |
| 773 if (!FLAGS_enable_quic_pacing) { | 776 if (!FLAGS_enable_quic_pacing) { |
| 774 return; | 777 return; |
| 775 } | 778 } |
| 776 | 779 |
| 777 if (using_pacing_) { | 780 if (using_pacing_) { |
| 778 return; | 781 return; |
| 779 } | 782 } |
| 780 | 783 |
| 781 using_pacing_ = true; | 784 using_pacing_ = true; |
| 782 send_algorithm_.reset( | 785 send_algorithm_.reset(new PacingSender(send_algorithm_.release(), |
| 783 new PacingSender(send_algorithm_.release(), | 786 QuicTime::Delta::FromMicroseconds(1))); |
| 784 QuicTime::Delta::FromMicroseconds(1))); | |
| 785 } | 787 } |
| 786 | 788 |
| 787 } // namespace net | 789 } // namespace net |
| OLD | NEW |