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 eefb320842ad808629f2e5d7bd1cf7faa20cc6ec..eaf66bd0fe94f396c79424ca28eb6b4a887c36b2 100644 |
--- a/net/quic/quic_sent_packet_manager.cc |
+++ b/net/quic/quic_sent_packet_manager.cc |
@@ -126,8 +126,11 @@ void QuicSentPacketManager::OnIncomingAck( |
// We rely on delta_time_largest_observed to compute an RTT estimate, so |
// we only update rtt when the largest observed gets acked. |
- largest_observed_ = received_info.largest_observed; |
bool largest_observed_acked = MaybeUpdateRTT(received_info, ack_receive_time); |
+ if (largest_observed_ < received_info.largest_observed) { |
+ largest_observed_ = received_info.largest_observed; |
+ unacked_packets_.IncreaseLargestObserved(largest_observed_); |
+ } |
HandleAckForSentPackets(received_info); |
InvokeLossDetection(ack_receive_time); |
MaybeInvokeCongestionEvent(largest_observed_acked, bytes_in_flight); |
@@ -175,36 +178,28 @@ void QuicSentPacketManager::HandleAckForSentPackets( |
} |
if (IsAwaitingPacket(received_info, sequence_number)) { |
- // Remove any rtt only packets less than or equal to the largest observed, |
- // since they will not produce an RTT measurement. |
- if (QuicUnackedPacketMap::IsForRttOnly(it->second)) { |
- ++it; |
- unacked_packets_.RemoveRttOnlyPacket(sequence_number); |
- } else { |
- // 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. |
- // The nack count only increases when the largest observed increases. |
- size_t min_nacks = received_info.largest_observed - sequence_number; |
- // Truncated acks can nack the largest observed, so use a min of 1. |
- if (min_nacks == 0) { |
- min_nacks = 1; |
- } |
- unacked_packets_.NackPacket(sequence_number, min_nacks); |
- ++it; |
+ // 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. |
+ // The nack count only increases when the largest observed increases. |
+ size_t min_nacks = received_info.largest_observed - sequence_number; |
+ // Truncated acks can nack the largest observed, so use a min of 1. |
+ if (min_nacks == 0) { |
+ min_nacks = 1; |
} |
+ unacked_packets_.NackPacket(sequence_number, min_nacks); |
+ ++it; |
continue; |
} |
- |
// Packet was acked, so remove it from our unacked packet list. |
DVLOG(1) << ENDPOINT << "Got an ack for packet " << sequence_number; |
// If data is associated with the most recent transmission of this |
// packet, then inform the caller. |
- if (it->second.pending) { |
+ if (it->second.in_flight) { |
packets_acked_[sequence_number] = it->second; |
} |
- it = MarkPacketHandled(sequence_number, delta_largest_observed); |
+ it = MarkPacketHandled(it, delta_largest_observed); |
} |
// Discard any retransmittable frames associated with revived packets. |
@@ -222,45 +217,36 @@ bool QuicSentPacketManager::HasRetransmittableFrames( |
void QuicSentPacketManager::RetransmitUnackedPackets( |
RetransmissionType retransmission_type) { |
- QuicUnackedPacketMap::const_iterator unacked_it = unacked_packets_.begin(); |
- while (unacked_it != unacked_packets_.end()) { |
- const RetransmittableFrames* frames = |
- unacked_it->second.retransmittable_frames; |
- // Only mark it as handled if it can't be retransmitted and there are no |
- // pending retransmissions which would be cleared. |
- if (frames == NULL && unacked_it->second.all_transmissions->size() == 1 && |
- retransmission_type == ALL_PACKETS) { |
- unacked_it = MarkPacketHandled(unacked_it->first, |
- QuicTime::Delta::Zero()); |
- continue; |
- } |
- // If it had no other transmissions, we handle it above. If it has |
- // other transmissions, one of them must have retransmittable frames, |
- // so that gets resolved the same way as other retransmissions. |
+ QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
+ while (it != unacked_packets_.end()) { |
+ const RetransmittableFrames* frames = it->second.retransmittable_frames; |
// TODO(ianswett): Consider adding a new retransmission type which removes |
// all these old packets from unacked and retransmits them as new sequence |
// numbers with no connection to the previous ones. |
if (frames != NULL && (retransmission_type == ALL_PACKETS || |
frames->encryption_level() == ENCRYPTION_INITIAL)) { |
- MarkForRetransmission(unacked_it->first, ALL_UNACKED_RETRANSMISSION); |
+ MarkForRetransmission(it->first, ALL_UNACKED_RETRANSMISSION); |
} |
- ++unacked_it; |
+ ++it; |
} |
} |
void QuicSentPacketManager::NeuterUnencryptedPackets() { |
- for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
- it != unacked_packets_.end(); ++it) { |
- const RetransmittableFrames* frames = |
- it->second.retransmittable_frames; |
+ QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
+ while (it != unacked_packets_.end()) { |
+ const RetransmittableFrames* frames = it->second.retransmittable_frames; |
+ QuicPacketSequenceNumber sequence_number = it->first; |
+ ++it; |
if (frames != NULL && frames->encryption_level() == ENCRYPTION_NONE) { |
// Once you're forward secure, no unencrypted packets will be sent, crypto |
// or otherwise. Unencrypted packets are neutered and abandoned, to ensure |
// they are not retransmitted or considered lost from a congestion control |
// perspective. |
- pending_retransmissions_.erase(it->first); |
- unacked_packets_.RemoveRetransmittability(it->first, largest_observed_); |
- unacked_packets_.SetNotPending(it->first); |
+ pending_retransmissions_.erase(sequence_number); |
+ unacked_packets_.RemoveFromInFlight(sequence_number); |
+ // RemoveRetransmittibility is safe because only the newest sequence |
+ // number can have frames. |
+ unacked_packets_.RemoveRetransmittability(sequence_number); |
} |
} |
} |
@@ -272,7 +258,7 @@ void QuicSentPacketManager::MarkForRetransmission( |
unacked_packets_.GetTransmissionInfo(sequence_number); |
LOG_IF(DFATAL, transmission_info.retransmittable_frames == NULL); |
if (transmission_type != TLP_RETRANSMISSION) { |
- unacked_packets_.SetNotPending(sequence_number); |
+ unacked_packets_.RemoveFromInFlight(sequence_number); |
} |
// TODO(ianswett): Currently the RTO can fire while there are pending NACK |
// retransmissions for the same data, which is not ideal. |
@@ -339,18 +325,16 @@ void QuicSentPacketManager::MarkPacketRevived( |
newest_transmission, delta_largest_observed); |
} |
- unacked_packets_.RemoveRetransmittability(sequence_number, largest_observed_); |
+ unacked_packets_.RemoveRetransmittability(sequence_number); |
} |
QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( |
- QuicPacketSequenceNumber sequence_number, |
+ QuicUnackedPacketMap::const_iterator it, |
QuicTime::Delta delta_largest_observed) { |
- if (!unacked_packets_.IsUnacked(sequence_number)) { |
- LOG(DFATAL) << "Packet is not unacked: " << sequence_number; |
- return unacked_packets_.end(); |
- } |
- const TransmissionInfo& transmission_info = |
- unacked_packets_.GetTransmissionInfo(sequence_number); |
+ LOG_IF(DFATAL, it == unacked_packets_.end()) |
+ << "MarkPacketHandled must be passed a valid iterator entry."; |
+ const QuicPacketSequenceNumber sequence_number = it->first; |
+ const TransmissionInfo& transmission_info = it->second; |
QuicPacketSequenceNumber newest_transmission = |
*transmission_info.all_transmissions->rbegin(); |
@@ -377,10 +361,10 @@ QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( |
// only handle NULL encrypted packets in a special way. |
if (HasCryptoHandshake( |
unacked_packets_.GetTransmissionInfo(newest_transmission))) { |
- unacked_packets_.SetNotPending(newest_transmission); |
+ unacked_packets_.RemoveFromInFlight(newest_transmission); |
} |
- unacked_packets_.SetNotPending(sequence_number); |
- unacked_packets_.RemoveRetransmittability(sequence_number, largest_observed_); |
+ unacked_packets_.RemoveFromInFlight(sequence_number); |
+ unacked_packets_.RemoveRetransmittability(sequence_number); |
QuicUnackedPacketMap::const_iterator next_unacked = unacked_packets_.begin(); |
while (next_unacked != unacked_packets_.end() && |
@@ -426,21 +410,21 @@ bool QuicSentPacketManager::OnPacketSent( |
rtt_stats_.SampleNewRecentMinRtt(kNumMinRttSamplesAfterQuiescence); |
} |
- // Only track packets as pending that the send algorithm wants us to track. |
- const bool pending = |
+ // Only track packets as in flight that the send algorithm wants us to track. |
+ const bool in_flight = |
send_algorithm_->OnPacketSent(sent_time, |
unacked_packets_.bytes_in_flight(), |
sequence_number, |
bytes, |
has_retransmittable_data); |
- unacked_packets_.SetSent(sequence_number, sent_time, bytes, pending); |
+ unacked_packets_.SetSent(sequence_number, sent_time, bytes, in_flight); |
// Reset the retransmission timer anytime a pending packet is sent. |
- return pending; |
+ return in_flight; |
} |
void QuicSentPacketManager::OnRetransmissionTimeout() { |
- DCHECK(unacked_packets_.HasPendingPackets()); |
+ DCHECK(unacked_packets_.HasInFlightPackets()); |
// Handshake retransmission, timer based loss detection, TLP, and RTO are |
// implemented with a single alarm. The handshake alarm is set when the |
// handshake has not completed, the loss alarm is set when the loss detection |
@@ -482,8 +466,8 @@ void QuicSentPacketManager::RetransmitCryptoPackets() { |
it != unacked_packets_.end(); ++it) { |
QuicPacketSequenceNumber sequence_number = it->first; |
const RetransmittableFrames* frames = it->second.retransmittable_frames; |
- // Only retransmit frames which are pending, and therefore have been sent. |
- if (!it->second.pending || frames == NULL || |
+ // Only retransmit frames which are in flight, and therefore have been sent. |
+ if (!it->second.in_flight || frames == NULL || |
frames->HasCryptoHandshake() != IS_HANDSHAKE) { |
continue; |
} |
@@ -500,8 +484,8 @@ void QuicSentPacketManager::RetransmitOldestPacket() { |
it != unacked_packets_.end(); ++it) { |
QuicPacketSequenceNumber sequence_number = it->first; |
const RetransmittableFrames* frames = it->second.retransmittable_frames; |
- // Only retransmit frames which are pending, and therefore have been sent. |
- if (!it->second.pending || frames == NULL) { |
+ // Only retransmit frames which are in flight, and therefore have been sent. |
+ if (!it->second.in_flight || frames == NULL) { |
continue; |
} |
DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake()); |
@@ -524,13 +508,16 @@ void QuicSentPacketManager::RetransmitAllPackets() { |
// immediately and the remaining packets will be queued. |
// Abandon any non-retransmittable packets that are sufficiently old. |
bool packets_retransmitted = false; |
- for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
- it != unacked_packets_.end(); ++it) { |
- if (it->second.retransmittable_frames != NULL) { |
+ QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
+ while (it != unacked_packets_.end()) { |
+ const RetransmittableFrames* frames = it->second.retransmittable_frames; |
+ QuicPacketSequenceNumber sequence_number = it->first; |
+ ++it; |
+ if (frames != NULL) { |
packets_retransmitted = true; |
- MarkForRetransmission(it->first, RTO_RETRANSMISSION); |
+ MarkForRetransmission(sequence_number, RTO_RETRANSMISSION); |
} else { |
- unacked_packets_.SetNotPending(it->first); |
+ unacked_packets_.RemoveFromInFlight(sequence_number); |
} |
} |
@@ -542,7 +529,7 @@ void QuicSentPacketManager::RetransmitAllPackets() { |
QuicSentPacketManager::RetransmissionTimeoutMode |
QuicSentPacketManager::GetRetransmissionMode() const { |
- DCHECK(unacked_packets_.HasPendingPackets()); |
+ DCHECK(unacked_packets_.HasInFlightPackets()); |
if (unacked_packets_.HasPendingCryptoPackets()) { |
return HANDSHAKE_MODE; |
} |
@@ -589,10 +576,7 @@ void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
// unacked_packets_. This is either the current transmission of |
// a packet whose previous transmission has been acked, a packet that has |
// been TLP retransmitted, or an FEC packet. |
- unacked_packets_.SetNotPending(sequence_number); |
- if (QuicUnackedPacketMap::IsForRttOnly(transmission_info)) { |
- unacked_packets_.RemoveRttOnlyPacket(sequence_number); |
- } |
+ unacked_packets_.RemoveFromInFlight(sequence_number); |
} |
} |
} |
@@ -649,8 +633,8 @@ const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { |
} |
const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
- // Don't set the timer if there are no pending packets. |
- if (!unacked_packets_.HasPendingPackets()) { |
+ // Don't set the timer if there are no packets in flight. |
+ if (!unacked_packets_.HasInFlightPackets()) { |
return QuicTime::Zero(); |
} |
switch (GetRetransmissionMode()) { |
@@ -668,9 +652,9 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
return QuicTime::Max(clock_->ApproximateNow(), tlp_time); |
} |
case RTO_MODE: { |
- // The RTO is based on the first pending packet. |
+ // The RTO is based on the first outstanding packet. |
const QuicTime sent_time = |
- unacked_packets_.GetFirstPendingPacketSentTime(); |
+ unacked_packets_.GetFirstInFlightPacketSentTime(); |
QuicTime rto_timeout = sent_time.Add(GetRetransmissionDelay()); |
// Always wait at least 1.5 * RTT from now. |
QuicTime min_timeout = clock_->ApproximateNow().Add( |
@@ -695,7 +679,7 @@ const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() |
const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { |
QuicTime::Delta srtt = rtt_stats_.SmoothedRtt(); |
- if (!unacked_packets_.HasMultiplePendingPackets()) { |
+ if (!unacked_packets_.HasMultipleInFlightPackets()) { |
return QuicTime::Delta::Max( |
srtt.Multiply(1.5).Add(DelayedAckTime()), srtt.Multiply(2)); |
} |