Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1305)

Unified Diff: net/quic/quic_sent_packet_manager.cc

Issue 300683008: Land Recent QUIC Changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_sent_packet_manager.h ('k') | net/quic/quic_sent_packet_manager_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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));
}
« no previous file with comments | « net/quic/quic_sent_packet_manager.h ('k') | net/quic/quic_sent_packet_manager_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698