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 |