Index: net/quic/quic_sent_packet_manager.cc |
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc |
index 8fa0bd718a1dcab6c424745b474becf3b1c53eca..17cd836b812c12fd2b6463e51830fc9977180053 100644 |
--- a/net/quic/quic_sent_packet_manager.cc |
+++ b/net/quic/quic_sent_packet_manager.cc |
@@ -41,9 +41,6 @@ static const int kMinRetransmissionTimeMs = 200; |
static const int kMaxRetransmissionTimeMs = 60000; |
static const size_t kMaxRetransmissions = 10; |
-// TCP retransmits after 3 nacks. |
-static const size_t kNumberOfNacksBeforeRetransmission = 3; |
- |
// Only exponentially back off the handshake timer 5 times due to a timeout. |
static const size_t kMaxHandshakeRetransmissionBackoffs = 5; |
static const size_t kMinHandshakeTimeoutMs = 10; |
@@ -75,7 +72,9 @@ QuicSentPacketManager::QuicSentPacketManager(bool is_server, |
clock_(clock), |
stats_(stats), |
send_algorithm_(SendAlgorithmInterface::Create(clock, type)), |
+ loss_algorithm_(LossDetectionInterface::Create()), |
rtt_sample_(QuicTime::Delta::Infinite()), |
+ largest_observed_(0), |
pending_crypto_packet_count_(0), |
consecutive_rto_count_(0), |
consecutive_tlp_count_(0), |
@@ -141,6 +140,7 @@ bool QuicSentPacketManager::OnIncomingAck( |
// we only update rtt when the largest observed gets acked. |
bool largest_observed_acked = |
unacked_packets_.IsUnacked(received_info.largest_observed); |
+ largest_observed_ = received_info.largest_observed; |
MaybeUpdateRTT(received_info, ack_receive_time); |
HandleAckForSentPackets(received_info); |
MaybeRetransmitOnAckFrame(received_info, ack_receive_time); |
@@ -305,7 +305,6 @@ QuicSentPacketManager::MarkPacketHandled( |
unacked_packets_.SetNotPending(sequence_number); |
} |
- |
SequenceNumberSet all_transmissions = *transmission_info.all_transmissions; |
SequenceNumberSet::reverse_iterator all_transmissions_it = |
all_transmissions.rbegin(); |
@@ -528,8 +527,7 @@ void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( |
void QuicSentPacketManager::MaybeRetransmitOnAckFrame( |
const ReceivedPacketInfo& received_info, |
const QuicTime& ack_receive_time) { |
- // Go through all pending packets up to the largest observed and see if any |
- // need to be retransmitted or lost. |
+ // Go through all pending packets up to the largest observed and count nacks. |
for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
it != unacked_packets_.end() && |
it->first <= received_info.largest_observed; ++it) { |
@@ -544,16 +542,19 @@ void QuicSentPacketManager::MaybeRetransmitOnAckFrame( |
// Consider it multiple nacks when there is a gap between the missing packet |
// and the largest observed, since the purpose of a nack threshold is to |
// tolerate re-ordering. This handles both StretchAcks and Forward Acks. |
- // TODO(ianswett): This relies heavily on sequential reception of packets, |
- // and makes an assumption that the congestion control uses TCP style nacks. |
size_t min_nacks = received_info.largest_observed - sequence_number; |
unacked_packets_.NackPacket(sequence_number, min_nacks); |
} |
+ InvokeLossDetection(ack_receive_time); |
+} |
+ |
+void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
SequenceNumberSet lost_packets = |
- DetectLostPackets(unacked_packets_, |
- ack_receive_time, |
- received_info.largest_observed); |
+ loss_algorithm_->DetectLostPackets(unacked_packets_, |
+ time, |
+ largest_observed_, |
+ send_algorithm_->SmoothedRtt()); |
for (SequenceNumberSet::const_iterator it = lost_packets.begin(); |
it != lost_packets.end(); ++it) { |
QuicPacketSequenceNumber sequence_number = *it; |
@@ -561,7 +562,7 @@ void QuicSentPacketManager::MaybeRetransmitOnAckFrame( |
// should be recorded as a loss to the send algorithm, but not retransmitted |
// until it's known whether the FEC packet arrived. |
++stats_->packets_lost; |
- send_algorithm_->OnPacketLost(sequence_number, ack_receive_time); |
+ send_algorithm_->OnPacketLost(sequence_number, time); |
OnPacketAbandoned(sequence_number); |
if (unacked_packets_.HasRetransmittableFrames(sequence_number)) { |
@@ -576,40 +577,6 @@ void QuicSentPacketManager::MaybeRetransmitOnAckFrame( |
} |
} |
-// static |
-SequenceNumberSet QuicSentPacketManager::DetectLostPackets( |
- const QuicUnackedPacketMap& unacked_packets, |
- const QuicTime& time, |
- QuicPacketSequenceNumber largest_observed) { |
- SequenceNumberSet lost_packets; |
- |
- for (QuicUnackedPacketMap::const_iterator it = unacked_packets.begin(); |
- it != unacked_packets.end() && it->first <= largest_observed; ++it) { |
- if (!it->second.pending) { |
- continue; |
- } |
- size_t num_nacks_needed = kNumberOfNacksBeforeRetransmission; |
- // Check for early retransmit(RFC5827) when the last packet gets acked and |
- // the there are fewer than 4 pending packets. |
- // TODO(ianswett): Set a retransmission timer instead of losing the packet |
- // and retransmitting immediately. Also consider only invoking OnPacketLost |
- // and OnPacketAbandoned when they're actually retransmitted in case they |
- // arrive while queued for retransmission. |
- if (it->second.retransmittable_frames && |
- unacked_packets.largest_sent_packet() == largest_observed) { |
- num_nacks_needed = largest_observed - it->first; |
- } |
- |
- if (it->second.nack_count < num_nacks_needed) { |
- continue; |
- } |
- |
- lost_packets.insert(it->first); |
- } |
- |
- return lost_packets; |
-} |
- |
void QuicSentPacketManager::MaybeUpdateRTT( |
const ReceivedPacketInfo& received_info, |
const QuicTime& ack_receive_time) { |