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 ce595610ea5f4bae8e4403e1e5ffa39676836812..7a57ab39b632995602769a5eccffcca8f49ff00f 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,28 +178,20 @@ 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 |
@@ -238,18 +233,22 @@ void QuicSentPacketManager::RetransmitUnackedPackets( |
} |
void QuicSentPacketManager::NeuterUnencryptedPackets() { |
- for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
- it != unacked_packets_.end(); ++it) { |
+ 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_.SetNotPending(sequence_number); |
+ // RemoveRetransmittibility is safe because only the newest sequence |
+ // number can have frames. |
+ unacked_packets_.RemoveRetransmittability(sequence_number); |
} |
} |
} |
@@ -328,7 +327,7 @@ 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( |
@@ -367,7 +366,7 @@ QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled( |
unacked_packets_.SetNotPending(newest_transmission); |
} |
unacked_packets_.SetNotPending(sequence_number); |
- unacked_packets_.RemoveRetransmittability(sequence_number, largest_observed_); |
+ unacked_packets_.RemoveRetransmittability(sequence_number); |
QuicUnackedPacketMap::const_iterator next_unacked = unacked_packets_.begin(); |
while (next_unacked != unacked_packets_.end() && |
@@ -511,13 +510,17 @@ 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_.SetNotPending(sequence_number); |
} |
} |
@@ -577,9 +580,6 @@ void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
// 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); |
- } |
} |
} |
} |