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 14 matching lines...) Expand all Loading... |
25 // values less than or equal to 0. | 25 // values less than or equal to 0. |
26 int32 FLAGS_quic_recent_min_rtt_window_s = 60; | 26 int32 FLAGS_quic_recent_min_rtt_window_s = 60; |
27 | 27 |
28 namespace { | 28 namespace { |
29 static const int64 kDefaultRetransmissionTimeMs = 500; | 29 static const int64 kDefaultRetransmissionTimeMs = 500; |
30 // TCP RFC calls for 1 second RTO however Linux differs from this default and | 30 // TCP RFC calls for 1 second RTO however Linux differs from this default and |
31 // define the minimum RTO to 200ms, we will use the same until we have data to | 31 // define the minimum RTO to 200ms, we will use the same until we have data to |
32 // support a higher or lower value. | 32 // support a higher or lower value. |
33 static const int64 kMinRetransmissionTimeMs = 200; | 33 static const int64 kMinRetransmissionTimeMs = 200; |
34 static const int64 kMaxRetransmissionTimeMs = 60000; | 34 static const int64 kMaxRetransmissionTimeMs = 60000; |
| 35 // Maximum number of exponential backoffs used for RTO timeouts. |
35 static const size_t kMaxRetransmissions = 10; | 36 static const size_t kMaxRetransmissions = 10; |
| 37 // Maximum number of packets retransmitted upon an RTO. |
| 38 static const size_t kMaxRetransmissionsOnTimeout = 2; |
36 | 39 |
37 // Ensure the handshake timer isnt't faster than 10ms. | 40 // Ensure the handshake timer isnt't faster than 10ms. |
38 // This limits the tenth retransmitted packet to 10s after the initial CHLO. | 41 // This limits the tenth retransmitted packet to 10s after the initial CHLO. |
39 static const int64 kMinHandshakeTimeoutMs = 10; | 42 static const int64 kMinHandshakeTimeoutMs = 10; |
40 | 43 |
41 // Sends up to two tail loss probes before firing an RTO, | 44 // Sends up to two tail loss probes before firing an RTO, |
42 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. | 45 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. |
43 static const size_t kDefaultMaxTailLossProbes = 2; | 46 static const size_t kDefaultMaxTailLossProbes = 2; |
44 static const int64 kMinTailLossProbeTimeoutMs = 10; | 47 static const int64 kMinTailLossProbeTimeoutMs = 10; |
45 | 48 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 | 228 |
226 // If we have received a truncated ack, then we need to clear out some | 229 // If we have received a truncated ack, then we need to clear out some |
227 // previous transmissions to allow the peer to actually ACK new packets. | 230 // previous transmissions to allow the peer to actually ACK new packets. |
228 if (ack_frame.is_truncated) { | 231 if (ack_frame.is_truncated) { |
229 unacked_packets_.ClearAllPreviousRetransmissions(); | 232 unacked_packets_.ClearAllPreviousRetransmissions(); |
230 } | 233 } |
231 | 234 |
232 // Anytime we are making forward progress and have a new RTT estimate, reset | 235 // Anytime we are making forward progress and have a new RTT estimate, reset |
233 // the backoff counters. | 236 // the backoff counters. |
234 if (rtt_updated) { | 237 if (rtt_updated) { |
| 238 if (FLAGS_quic_use_new_rto && consecutive_rto_count_ > 0) { |
| 239 // If the ack acknowledges data sent prior to the RTO, |
| 240 // the RTO was spurious. |
| 241 if (ack_frame.largest_observed < first_rto_transmission_) { |
| 242 // Replace SRTT with latest_rtt and increase the variance to prevent |
| 243 // a spurious RTO from happening again. |
| 244 rtt_stats_.ExpireSmoothedMetrics(); |
| 245 } else { |
| 246 send_algorithm_->OnRetransmissionTimeout(true); |
| 247 } |
| 248 } |
235 // Reset all retransmit counters any time a new packet is acked. | 249 // Reset all retransmit counters any time a new packet is acked. |
236 consecutive_rto_count_ = 0; | 250 consecutive_rto_count_ = 0; |
237 consecutive_tlp_count_ = 0; | 251 consecutive_tlp_count_ = 0; |
238 consecutive_crypto_retransmission_count_ = 0; | 252 consecutive_crypto_retransmission_count_ = 0; |
239 } | 253 } |
240 | 254 |
241 if (debug_delegate_ != nullptr) { | 255 if (debug_delegate_ != nullptr) { |
242 debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time, | 256 debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time, |
243 unacked_packets_.largest_observed(), | 257 unacked_packets_.largest_observed(), |
244 rtt_updated, GetLeastUnacked()); | 258 rtt_updated, GetLeastUnacked()); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 } | 372 } |
359 } | 373 } |
360 } | 374 } |
361 | 375 |
362 void QuicSentPacketManager::MarkForRetransmission( | 376 void QuicSentPacketManager::MarkForRetransmission( |
363 QuicPacketSequenceNumber sequence_number, | 377 QuicPacketSequenceNumber sequence_number, |
364 TransmissionType transmission_type) { | 378 TransmissionType transmission_type) { |
365 const TransmissionInfo& transmission_info = | 379 const TransmissionInfo& transmission_info = |
366 unacked_packets_.GetTransmissionInfo(sequence_number); | 380 unacked_packets_.GetTransmissionInfo(sequence_number); |
367 LOG_IF(DFATAL, transmission_info.retransmittable_frames == nullptr); | 381 LOG_IF(DFATAL, transmission_info.retransmittable_frames == nullptr); |
368 if (transmission_type != TLP_RETRANSMISSION) { | 382 // Both TLP and the new RTO leave the packets in flight and let the loss |
| 383 // detection decide if packets are lost. |
| 384 if (transmission_type != TLP_RETRANSMISSION && |
| 385 (!FLAGS_quic_use_new_rto || transmission_type != RTO_RETRANSMISSION)) { |
369 unacked_packets_.RemoveFromInFlight(sequence_number); | 386 unacked_packets_.RemoveFromInFlight(sequence_number); |
370 } | 387 } |
371 // TODO(ianswett): Currently the RTO can fire while there are pending NACK | 388 // TODO(ianswett): Currently the RTO can fire while there are pending NACK |
372 // retransmissions for the same data, which is not ideal. | 389 // retransmissions for the same data, which is not ideal. |
373 if (ContainsKey(pending_retransmissions_, sequence_number)) { | 390 if (ContainsKey(pending_retransmissions_, sequence_number)) { |
374 return; | 391 return; |
375 } | 392 } |
376 | 393 |
377 pending_retransmissions_[sequence_number] = transmission_type; | 394 pending_retransmissions_[sequence_number] = transmission_type; |
378 } | 395 } |
379 | 396 |
380 void QuicSentPacketManager::RecordSpuriousRetransmissions( | 397 void QuicSentPacketManager::RecordSpuriousRetransmissions( |
381 const SequenceNumberList& all_transmissions, | 398 const SequenceNumberList& all_transmissions, |
382 QuicPacketSequenceNumber acked_sequence_number) { | 399 QuicPacketSequenceNumber acked_sequence_number) { |
383 if (acked_sequence_number < first_rto_transmission_) { | 400 if (!FLAGS_quic_use_new_rto && |
| 401 acked_sequence_number < first_rto_transmission_) { |
384 // Cancel all pending RTO transmissions and restore their in flight status. | 402 // Cancel all pending RTO transmissions and restore their in flight status. |
385 // Replace SRTT with latest_rtt and increase the variance to prevent | 403 // Replace SRTT with latest_rtt and increase the variance to prevent |
386 // a spurious RTO from happening again. | 404 // a spurious RTO from happening again. |
387 rtt_stats_.ExpireSmoothedMetrics(); | 405 rtt_stats_.ExpireSmoothedMetrics(); |
388 for (PendingRetransmissionMap::const_iterator it = | 406 for (PendingRetransmissionMap::const_iterator it = |
389 pending_retransmissions_.begin(); | 407 pending_retransmissions_.begin(); |
390 it != pending_retransmissions_.end(); ++it) { | 408 it != pending_retransmissions_.end(); ++it) { |
391 DCHECK_EQ(it->second, RTO_RETRANSMISSION); | 409 DCHECK_EQ(it->second, RTO_RETRANSMISSION); |
392 unacked_packets_.RestoreInFlight(it->first); | 410 unacked_packets_.RestoreInFlight(it->first); |
393 } | 411 } |
394 pending_retransmissions_.clear(); | 412 pending_retransmissions_.clear(); |
395 send_algorithm_->RevertRetransmissionTimeout(); | 413 send_algorithm_->RevertRetransmissionTimeout(); |
396 first_rto_transmission_ = 0; | 414 first_rto_transmission_ = 0; |
397 ++stats_->spurious_rto_count; | 415 ++stats_->spurious_rto_count; |
398 } | 416 } |
399 for (SequenceNumberList::const_reverse_iterator it = | 417 for (SequenceNumberList::const_reverse_iterator it = |
400 all_transmissions.rbegin(); | 418 all_transmissions.rbegin(); |
401 it != all_transmissions.rend() && *it > acked_sequence_number; ++it) { | 419 it != all_transmissions.rend() && *it > acked_sequence_number; ++it) { |
402 const TransmissionInfo& retransmit_info = | 420 const TransmissionInfo& retransmit_info = |
403 unacked_packets_.GetTransmissionInfo(*it); | 421 unacked_packets_.GetTransmissionInfo(*it); |
404 | 422 |
405 stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent; | 423 stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent; |
406 ++stats_->packets_spuriously_retransmitted; | 424 ++stats_->packets_spuriously_retransmitted; |
407 if (debug_delegate_ != nullptr) { | 425 if (debug_delegate_ != nullptr) { |
408 debug_delegate_->OnSpuriousPacketRetransmition( | 426 debug_delegate_->OnSpuriousPacketRetransmission( |
409 retransmit_info.transmission_type, | 427 retransmit_info.transmission_type, retransmit_info.bytes_sent); |
410 retransmit_info.bytes_sent); | |
411 } | 428 } |
412 } | 429 } |
413 } | 430 } |
414 | 431 |
415 bool QuicSentPacketManager::HasPendingRetransmissions() const { | 432 bool QuicSentPacketManager::HasPendingRetransmissions() const { |
416 return !pending_retransmissions_.empty(); | 433 return !pending_retransmissions_.empty(); |
417 } | 434 } |
418 | 435 |
419 QuicSentPacketManager::PendingRetransmission | 436 QuicSentPacketManager::PendingRetransmission |
420 QuicSentPacketManager::NextPendingRetransmission() { | 437 QuicSentPacketManager::NextPendingRetransmission() { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 QuicTime sent_time, | 545 QuicTime sent_time, |
529 QuicByteCount bytes, | 546 QuicByteCount bytes, |
530 TransmissionType transmission_type, | 547 TransmissionType transmission_type, |
531 HasRetransmittableData has_retransmittable_data) { | 548 HasRetransmittableData has_retransmittable_data) { |
532 QuicPacketSequenceNumber sequence_number = serialized_packet->sequence_number; | 549 QuicPacketSequenceNumber sequence_number = serialized_packet->sequence_number; |
533 DCHECK_LT(0u, sequence_number); | 550 DCHECK_LT(0u, sequence_number); |
534 DCHECK(!unacked_packets_.IsUnacked(sequence_number)); | 551 DCHECK(!unacked_packets_.IsUnacked(sequence_number)); |
535 LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets."; | 552 LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets."; |
536 | 553 |
537 if (original_sequence_number == 0) { | 554 if (original_sequence_number == 0) { |
538 if (serialized_packet->retransmittable_frames) { | 555 if (!FLAGS_quic_ack_notifier_informed_on_serialized && |
| 556 serialized_packet->retransmittable_frames) { |
539 ack_notifier_manager_.OnSerializedPacket(*serialized_packet); | 557 ack_notifier_manager_.OnSerializedPacket(*serialized_packet); |
540 } | 558 } |
541 } else { | 559 } else { |
542 PendingRetransmissionMap::iterator it = | 560 PendingRetransmissionMap::iterator it = |
543 pending_retransmissions_.find(original_sequence_number); | 561 pending_retransmissions_.find(original_sequence_number); |
544 if (it != pending_retransmissions_.end()) { | 562 if (it != pending_retransmissions_.end()) { |
545 pending_retransmissions_.erase(it); | 563 pending_retransmissions_.erase(it); |
546 } else { | 564 } else { |
547 DLOG(DFATAL) << "Expected sequence number to be in " | 565 DLOG(DFATAL) << "Expected sequence number to be in " |
548 << "pending_retransmissions_. sequence_number: " | 566 << "pending_retransmissions_. sequence_number: " |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 // If no tail loss probe can be sent, because there are no retransmittable | 634 // If no tail loss probe can be sent, because there are no retransmittable |
617 // packets, execute a conventional RTO to abandon old packets. | 635 // packets, execute a conventional RTO to abandon old packets. |
618 ++stats_->tlp_count; | 636 ++stats_->tlp_count; |
619 ++consecutive_tlp_count_; | 637 ++consecutive_tlp_count_; |
620 pending_timer_transmission_count_ = 1; | 638 pending_timer_transmission_count_ = 1; |
621 // TLPs prefer sending new data instead of retransmitting data, so | 639 // TLPs prefer sending new data instead of retransmitting data, so |
622 // give the connection a chance to write before completing the TLP. | 640 // give the connection a chance to write before completing the TLP. |
623 return; | 641 return; |
624 case RTO_MODE: | 642 case RTO_MODE: |
625 ++stats_->rto_count; | 643 ++stats_->rto_count; |
626 RetransmitAllPackets(); | 644 if (FLAGS_quic_use_new_rto) { |
| 645 RetransmitRtoPackets(); |
| 646 } else { |
| 647 RetransmitAllPackets(); |
| 648 } |
627 return; | 649 return; |
628 } | 650 } |
629 } | 651 } |
630 | 652 |
631 void QuicSentPacketManager::RetransmitCryptoPackets() { | 653 void QuicSentPacketManager::RetransmitCryptoPackets() { |
632 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); | 654 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); |
633 ++consecutive_crypto_retransmission_count_; | 655 ++consecutive_crypto_retransmission_count_; |
634 bool packet_retransmitted = false; | 656 bool packet_retransmitted = false; |
635 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | 657 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); |
636 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 658 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
(...skipping 25 matching lines...) Expand all Loading... |
662 DCHECK_NE(IS_HANDSHAKE, it->retransmittable_frames->HasCryptoHandshake()); | 684 DCHECK_NE(IS_HANDSHAKE, it->retransmittable_frames->HasCryptoHandshake()); |
663 } | 685 } |
664 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); | 686 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); |
665 return true; | 687 return true; |
666 } | 688 } |
667 DLOG(FATAL) | 689 DLOG(FATAL) |
668 << "No retransmittable packets, so RetransmitOldestPacket failed."; | 690 << "No retransmittable packets, so RetransmitOldestPacket failed."; |
669 return false; | 691 return false; |
670 } | 692 } |
671 | 693 |
| 694 void QuicSentPacketManager::RetransmitRtoPackets() { |
| 695 LOG_IF(DFATAL, pending_timer_transmission_count_ > 0) |
| 696 << "Retransmissions already queued:" << pending_timer_transmission_count_; |
| 697 // Mark two packets for retransmission. |
| 698 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); |
| 699 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 700 it != unacked_packets_.end(); ++it, ++sequence_number) { |
| 701 if (it->retransmittable_frames != nullptr && |
| 702 pending_timer_transmission_count_ < kMaxRetransmissionsOnTimeout) { |
| 703 MarkForRetransmission(sequence_number, RTO_RETRANSMISSION); |
| 704 ++pending_timer_transmission_count_; |
| 705 } |
| 706 // Abandon non-retransmittable data that's in flight to ensure it doesn't |
| 707 // fill up the congestion window. |
| 708 if (it->retransmittable_frames == nullptr && it->in_flight && |
| 709 it->all_transmissions == nullptr) { |
| 710 unacked_packets_.RemoveFromInFlight(sequence_number); |
| 711 } |
| 712 } |
| 713 if (pending_timer_transmission_count_ > 0) { |
| 714 if (consecutive_rto_count_ == 0) { |
| 715 first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1; |
| 716 } |
| 717 ++consecutive_rto_count_; |
| 718 } |
| 719 } |
| 720 |
672 void QuicSentPacketManager::RetransmitAllPackets() { | 721 void QuicSentPacketManager::RetransmitAllPackets() { |
673 DVLOG(1) << "RetransmitAllPackets() called with " | 722 DVLOG(1) << "RetransmitAllPackets() called with " |
674 << unacked_packets_.GetNumUnackedPacketsDebugOnly() | 723 << unacked_packets_.GetNumUnackedPacketsDebugOnly() |
675 << " unacked packets."; | 724 << " unacked packets."; |
676 // Request retransmission of all retransmittable packets when the RTO | 725 // Request retransmission of all retransmittable packets when the RTO |
677 // fires, and let the congestion manager decide how many to send | 726 // fires, and let the congestion manager decide how many to send |
678 // immediately and the remaining packets will be queued. | 727 // immediately and the remaining packets will be queued. |
679 // Abandon any non-retransmittable packets that are sufficiently old. | 728 // Abandon any non-retransmittable packets that are sufficiently old. |
680 bool packets_retransmitted = false; | 729 bool packets_retransmitted = false; |
681 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); | 730 QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked(); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 } | 988 } |
940 | 989 |
941 QuicPacketCount QuicSentPacketManager::GetCongestionWindowInTcpMss() const { | 990 QuicPacketCount QuicSentPacketManager::GetCongestionWindowInTcpMss() const { |
942 return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS; | 991 return send_algorithm_->GetCongestionWindow() / kDefaultTCPMSS; |
943 } | 992 } |
944 | 993 |
945 QuicPacketCount QuicSentPacketManager::GetSlowStartThresholdInTcpMss() const { | 994 QuicPacketCount QuicSentPacketManager::GetSlowStartThresholdInTcpMss() const { |
946 return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS; | 995 return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS; |
947 } | 996 } |
948 | 997 |
| 998 void QuicSentPacketManager::OnSerializedPacket( |
| 999 const SerializedPacket& serialized_packet) { |
| 1000 ack_notifier_manager_.OnSerializedPacket(serialized_packet); |
| 1001 } |
| 1002 |
949 void QuicSentPacketManager::EnablePacing() { | 1003 void QuicSentPacketManager::EnablePacing() { |
950 if (using_pacing_) { | 1004 if (using_pacing_) { |
951 return; | 1005 return; |
952 } | 1006 } |
953 | 1007 |
954 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as | 1008 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as |
955 // the default granularity of the Linux kernel's FQ qdisc. | 1009 // the default granularity of the Linux kernel's FQ qdisc. |
956 using_pacing_ = true; | 1010 using_pacing_ = true; |
957 send_algorithm_.reset( | 1011 send_algorithm_.reset( |
958 new PacingSender(send_algorithm_.release(), | 1012 new PacingSender(send_algorithm_.release(), |
959 QuicTime::Delta::FromMilliseconds(1), | 1013 QuicTime::Delta::FromMilliseconds(1), |
960 kInitialUnpacedBurst)); | 1014 kInitialUnpacedBurst)); |
961 } | 1015 } |
962 | 1016 |
963 } // namespace net | 1017 } // namespace net |
OLD | NEW |