| 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" |
| 11 #include "net/quic/congestion_control/pacing_sender.h" | 11 #include "net/quic/congestion_control/pacing_sender.h" |
| 12 #include "net/quic/crypto/crypto_protocol.h" | 12 #include "net/quic/crypto/crypto_protocol.h" |
| 13 #include "net/quic/proto/cached_network_parameters.pb.h" | 13 #include "net/quic/proto/cached_network_parameters.pb.h" |
| 14 #include "net/quic/quic_bug_tracker.h" | 14 #include "net/quic/quic_bug_tracker.h" |
| 15 #include "net/quic/quic_connection_stats.h" | 15 #include "net/quic/quic_connection_stats.h" |
| 16 #include "net/quic/quic_flags.h" | 16 #include "net/quic/quic_flags.h" |
| 17 #include "net/quic/quic_utils_chromium.h" | 17 #include "net/quic/quic_utils_chromium.h" |
| 18 | 18 |
| 19 using std::max; | 19 using std::max; |
| 20 using std::min; | 20 using std::min; |
| 21 using std::pair; |
| 21 | 22 |
| 22 namespace net { | 23 namespace net { |
| 23 | 24 |
| 24 // The length of the recent min rtt window in seconds. Windowing is disabled for | 25 // The length of the recent min rtt window in seconds. Windowing is disabled for |
| 25 // values less than or equal to 0. | 26 // values less than or equal to 0. |
| 26 int32_t FLAGS_quic_recent_min_rtt_window_s = 60; | 27 int32_t FLAGS_quic_recent_min_rtt_window_s = 60; |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 static const int64_t kDefaultRetransmissionTimeMs = 500; | 30 static const int64_t kDefaultRetransmissionTimeMs = 500; |
| 30 // TCP RFC calls for 1 second RTO however Linux differs from this default and | 31 // TCP RFC calls for 1 second RTO however Linux differs from this default and |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 least_packet_awaited_by_peer_(1), | 90 least_packet_awaited_by_peer_(1), |
| 90 first_rto_transmission_(0), | 91 first_rto_transmission_(0), |
| 91 consecutive_rto_count_(0), | 92 consecutive_rto_count_(0), |
| 92 consecutive_tlp_count_(0), | 93 consecutive_tlp_count_(0), |
| 93 consecutive_crypto_retransmission_count_(0), | 94 consecutive_crypto_retransmission_count_(0), |
| 94 pending_timer_transmission_count_(0), | 95 pending_timer_transmission_count_(0), |
| 95 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 96 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
| 96 enable_half_rtt_tail_loss_probe_(false), | 97 enable_half_rtt_tail_loss_probe_(false), |
| 97 using_pacing_(false), | 98 using_pacing_(false), |
| 98 use_new_rto_(false), | 99 use_new_rto_(false), |
| 99 handshake_confirmed_(false), | 100 handshake_confirmed_(false) {} |
| 100 use_general_loss_algorithm_(FLAGS_quic_general_loss_algorithm) {} | |
| 101 | 101 |
| 102 QuicSentPacketManager::~QuicSentPacketManager() {} | 102 QuicSentPacketManager::~QuicSentPacketManager() {} |
| 103 | 103 |
| 104 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | 104 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
| 105 if (config.HasReceivedInitialRoundTripTimeUs() && | 105 if (config.HasReceivedInitialRoundTripTimeUs() && |
| 106 config.ReceivedInitialRoundTripTimeUs() > 0) { | 106 config.ReceivedInitialRoundTripTimeUs() > 0) { |
| 107 rtt_stats_.set_initial_rtt_us( | 107 rtt_stats_.set_initial_rtt_us( |
| 108 max(kMinInitialRoundTripTimeUs, | 108 max(kMinInitialRoundTripTimeUs, |
| 109 min(kMaxInitialRoundTripTimeUs, | 109 min(kMaxInitialRoundTripTimeUs, |
| 110 config.ReceivedInitialRoundTripTimeUs()))); | 110 config.ReceivedInitialRoundTripTimeUs()))); |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 serialized_packet->is_fec_packet ? HAS_RETRANSMITTABLE_DATA | 576 serialized_packet->is_fec_packet ? HAS_RETRANSMITTABLE_DATA |
| 577 : has_retransmittable_data; | 577 : has_retransmittable_data; |
| 578 // TODO(ianswett): Remove sent_time, because it's unused. | 578 // TODO(ianswett): Remove sent_time, because it's unused. |
| 579 const bool in_flight = send_algorithm_->OnPacketSent( | 579 const bool in_flight = send_algorithm_->OnPacketSent( |
| 580 sent_time, unacked_packets_.bytes_in_flight(), packet_number, bytes, | 580 sent_time, unacked_packets_.bytes_in_flight(), packet_number, bytes, |
| 581 has_congestion_controlled_data); | 581 has_congestion_controlled_data); |
| 582 | 582 |
| 583 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number, | 583 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number, |
| 584 transmission_type, sent_time, bytes, | 584 transmission_type, sent_time, bytes, |
| 585 in_flight); | 585 in_flight); |
| 586 | |
| 587 // Take ownership of the retransmittable frames before exiting. | |
| 588 serialized_packet->retransmittable_frames = nullptr; | |
| 589 // Reset the retransmission timer anytime a pending packet is sent. | 586 // Reset the retransmission timer anytime a pending packet is sent. |
| 590 return in_flight; | 587 return in_flight; |
| 591 } | 588 } |
| 592 | 589 |
| 593 void QuicSentPacketManager::OnRetransmissionTimeout() { | 590 void QuicSentPacketManager::OnRetransmissionTimeout() { |
| 594 DCHECK(unacked_packets_.HasInFlightPackets()); | 591 DCHECK(unacked_packets_.HasInFlightPackets()); |
| 595 DCHECK_EQ(0u, pending_timer_transmission_count_); | 592 DCHECK_EQ(0u, pending_timer_transmission_count_); |
| 596 // Handshake retransmission, timer based loss detection, TLP, and RTO are | 593 // Handshake retransmission, timer based loss detection, TLP, and RTO are |
| 597 // implemented with a single alarm. The handshake alarm is set when the | 594 // implemented with a single alarm. The handshake alarm is set when the |
| 598 // handshake has not completed, the loss alarm is set when the loss detection | 595 // handshake has not completed, the loss alarm is set when the loss detection |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 } | 710 } |
| 714 if (consecutive_tlp_count_ < max_tail_loss_probes_) { | 711 if (consecutive_tlp_count_ < max_tail_loss_probes_) { |
| 715 if (unacked_packets_.HasUnackedRetransmittableFrames()) { | 712 if (unacked_packets_.HasUnackedRetransmittableFrames()) { |
| 716 return TLP_MODE; | 713 return TLP_MODE; |
| 717 } | 714 } |
| 718 } | 715 } |
| 719 return RTO_MODE; | 716 return RTO_MODE; |
| 720 } | 717 } |
| 721 | 718 |
| 722 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { | 719 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
| 723 if (use_general_loss_algorithm_) { | 720 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_, |
| 724 loss_algorithm_->DetectLosses(unacked_packets_, time, rtt_stats_, | 721 &packets_lost_); |
| 725 &packets_lost_); | 722 for (const pair<QuicPacketNumber, QuicByteCount>& pair : packets_lost_) { |
| 726 for (const std::pair<QuicPacketNumber, QuicByteCount>& pair : | 723 ++stats_->packets_lost; |
| 727 packets_lost_) { | 724 if (FLAGS_quic_log_loss_event && debug_delegate_ != nullptr) { |
| 728 ++stats_->packets_lost; | 725 debug_delegate_->OnPacketLoss(pair.first, LOSS_RETRANSMISSION, time); |
| 729 if (FLAGS_quic_log_loss_event && debug_delegate_ != nullptr) { | 726 } |
| 730 debug_delegate_->OnPacketLoss(pair.first, LOSS_RETRANSMISSION, time); | |
| 731 } | |
| 732 | 727 |
| 733 // TODO(ianswett): This could be optimized. | 728 // TODO(ianswett): This could be optimized. |
| 734 if (unacked_packets_.HasRetransmittableFrames(pair.first)) { | 729 if (unacked_packets_.HasRetransmittableFrames(pair.first)) { |
| 735 MarkForRetransmission(pair.first, LOSS_RETRANSMISSION); | 730 MarkForRetransmission(pair.first, LOSS_RETRANSMISSION); |
| 736 } else { | |
| 737 // Since we will not retransmit this, we need to remove it from | |
| 738 // unacked_packets_. This is either the current transmission of | |
| 739 // a packet whose previous transmission has been acked, a packet that | |
| 740 // has been TLP retransmitted, or an FEC packet. | |
| 741 unacked_packets_.RemoveFromInFlight(pair.first); | |
| 742 } | |
| 743 } | |
| 744 return; | |
| 745 } | |
| 746 PacketNumberSet lost_packets = loss_algorithm_->DetectLostPackets( | |
| 747 unacked_packets_, time, unacked_packets_.largest_observed(), rtt_stats_); | |
| 748 for (PacketNumberSet::const_iterator it = lost_packets.begin(); | |
| 749 it != lost_packets.end(); ++it) { | |
| 750 QuicPacketNumber packet_number = *it; | |
| 751 const TransmissionInfo& transmission_info = | |
| 752 unacked_packets_.GetTransmissionInfo(packet_number); | |
| 753 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it | |
| 754 // should be recorded as a loss to the send algorithm, but not retransmitted | |
| 755 // until it's known whether the FEC packet arrived. | |
| 756 ++stats_->packets_lost; | |
| 757 packets_lost_.push_back( | |
| 758 std::make_pair(packet_number, transmission_info.bytes_sent)); | |
| 759 DVLOG(1) << ENDPOINT << "Lost packet " << packet_number; | |
| 760 | |
| 761 if (!transmission_info.retransmittable_frames.empty()) { | |
| 762 MarkForRetransmission(packet_number, LOSS_RETRANSMISSION); | |
| 763 } else { | 731 } else { |
| 764 // Since we will not retransmit this, we need to remove it from | 732 // Since we will not retransmit this, we need to remove it from |
| 765 // unacked_packets_. This is either the current transmission of | 733 // unacked_packets_. This is either the current transmission of |
| 766 // a packet whose previous transmission has been acked, a packet that has | 734 // a packet whose previous transmission has been acked, a packet that |
| 767 // been TLP retransmitted, or an FEC packet. | 735 // has been TLP retransmitted, or an FEC packet. |
| 768 unacked_packets_.RemoveFromInFlight(packet_number); | 736 unacked_packets_.RemoveFromInFlight(pair.first); |
| 769 } | 737 } |
| 770 } | 738 } |
| 771 } | 739 } |
| 772 | 740 |
| 773 bool QuicSentPacketManager::MaybeUpdateRTT(const QuicAckFrame& ack_frame, | 741 bool QuicSentPacketManager::MaybeUpdateRTT(const QuicAckFrame& ack_frame, |
| 774 const QuicTime& ack_receive_time) { | 742 const QuicTime& ack_receive_time) { |
| 775 // We rely on ack_delay_time to compute an RTT estimate, so we | 743 // We rely on ack_delay_time to compute an RTT estimate, so we |
| 776 // only update rtt when the largest observed gets acked. | 744 // only update rtt when the largest observed gets acked. |
| 777 // NOTE: If ack is a truncated ack, then the largest observed is in fact | 745 // NOTE: If ack is a truncated ack, then the largest observed is in fact |
| 778 // unacked, and may cause an RTT sample to be taken. | 746 // unacked, and may cause an RTT sample to be taken. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( | 972 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( |
| 1005 QuicPacketNumber packet_number) { | 973 QuicPacketNumber packet_number) { |
| 1006 return unacked_packets_.GetMutableTransmissionInfo(packet_number); | 974 return unacked_packets_.GetMutableTransmissionInfo(packet_number); |
| 1007 } | 975 } |
| 1008 | 976 |
| 1009 void QuicSentPacketManager::RemoveObsoletePackets() { | 977 void QuicSentPacketManager::RemoveObsoletePackets() { |
| 1010 unacked_packets_.RemoveObsoletePackets(); | 978 unacked_packets_.RemoveObsoletePackets(); |
| 1011 } | 979 } |
| 1012 | 980 |
| 1013 } // namespace net | 981 } // namespace net |
| OLD | NEW |