Index: net/quic/congestion_control/tcp_loss_algorithm.cc |
diff --git a/net/quic/congestion_control/tcp_loss_algorithm.cc b/net/quic/congestion_control/tcp_loss_algorithm.cc |
index 9366105e82229c04fb1408fe211c1a374a145c94..f657cc225fe5ac217f57bcdfa6b51f4006728e15 100644 |
--- a/net/quic/congestion_control/tcp_loss_algorithm.cc |
+++ b/net/quic/congestion_control/tcp_loss_algorithm.cc |
@@ -10,10 +10,17 @@ |
namespace net { |
namespace { |
+ |
+// The minimum delay before a packet will be considered lost, |
+// regardless of SRTT. Half of the minimum TLP, since the loss algorithm only |
+// triggers when a nack has been receieved for the packet. |
+static const size_t kMinLossDelayMs = 5; |
+ |
// How many RTTs the algorithm waits before determining a packet is lost due |
// to early retransmission. |
static const double kEarlyRetransmitLossDelayMultiplier = 1.25; |
-} |
+ |
+} // namespace |
TCPLossAlgorithm::TCPLossAlgorithm() |
: loss_detection_timeout_(QuicTime::Zero()) { } |
@@ -30,8 +37,10 @@ SequenceNumberSet TCPLossAlgorithm::DetectLostPackets( |
const RttStats& rtt_stats) { |
SequenceNumberSet lost_packets; |
loss_detection_timeout_ = QuicTime::Zero(); |
- QuicTime::Delta loss_delay = |
- rtt_stats.smoothed_rtt().Multiply(kEarlyRetransmitLossDelayMultiplier); |
+ QuicTime::Delta early_retransmit_delay = QuicTime::Delta::Max( |
+ QuicTime::Delta::FromMilliseconds(kMinLossDelayMs), |
+ rtt_stats.smoothed_rtt().Multiply(kEarlyRetransmitLossDelayMultiplier)); |
+ |
QuicPacketSequenceNumber sequence_number = unacked_packets.GetLeastUnacked(); |
for (QuicUnackedPacketMap::const_iterator it = unacked_packets.begin(); |
it != unacked_packets.end() && sequence_number <= largest_observed; |
@@ -49,6 +58,16 @@ SequenceNumberSet TCPLossAlgorithm::DetectLostPackets( |
continue; |
} |
+ // Immediately lose the packet if it's been an srtt between the sent time |
+ // of it and the largest observed. This speeds recovery from timer based |
+ // retransmissions, such as TLP and RTO, when there may be fewer than |
+ // kNumberOfNacksBeforeRetransmission nacks. |
+ if (it->sent_time.Add(rtt_stats.smoothed_rtt()) < |
+ unacked_packets.GetTransmissionInfo(largest_observed).sent_time) { |
+ lost_packets.insert(sequence_number); |
+ continue; |
+ } |
+ |
// Only early retransmit(RFC5827) when the last packet gets acked and |
// there are retransmittable packets in flight. |
// This also implements a timer-protected variant of FACK. |
@@ -56,12 +75,12 @@ SequenceNumberSet TCPLossAlgorithm::DetectLostPackets( |
unacked_packets.largest_sent_packet() == largest_observed) { |
// Early retransmit marks the packet as lost once 1.25RTTs have passed |
// since the packet was sent and otherwise sets an alarm. |
- if (time >= it->sent_time.Add(loss_delay)) { |
+ if (time >= it->sent_time.Add(early_retransmit_delay)) { |
lost_packets.insert(sequence_number); |
} else { |
// Set the timeout for the earliest retransmittable packet where early |
// retransmit applies. |
- loss_detection_timeout_ = it->sent_time.Add(loss_delay); |
+ loss_detection_timeout_ = it->sent_time.Add(early_retransmit_delay); |
break; |
} |
} |