summaryrefslogtreecommitdiffstats
path: root/net/quic/quic_sent_packet_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/quic/quic_sent_packet_manager.cc')
-rw-r--r--net/quic/quic_sent_packet_manager.cc59
1 files changed, 13 insertions, 46 deletions
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc
index 8fa0bd7..17cd836 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) {