| 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 af9a507a59c00a3ffd3328f7253be710173ecd7f..820800494ba52f2ac77fd8a65f9d3d6d0a5ca6b1 100644
|
| --- a/net/quic/quic_sent_packet_manager.cc
|
| +++ b/net/quic/quic_sent_packet_manager.cc
|
| @@ -104,6 +104,7 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
|
| << "Client did not set an initial RTT, but did negotiate one.";
|
| rtt_sample_ =
|
| QuicTime::Delta::FromMicroseconds(config.initial_round_trip_time_us());
|
| + send_algorithm_->UpdateRtt(rtt_sample_);
|
| }
|
| if (config.congestion_control() == kPACE) {
|
| MaybeEnablePacing();
|
| @@ -181,19 +182,17 @@ void QuicSentPacketManager::OnRetransmittedPacket(
|
|
|
| bool QuicSentPacketManager::OnIncomingAck(
|
| const ReceivedPacketInfo& received_info, QuicTime ack_receive_time) {
|
| - // Determine if the least unacked sequence number is being acked.
|
| - QuicPacketSequenceNumber least_unacked_sent_before =
|
| - GetLeastUnackedSentPacket();
|
| - // TODO(ianswett): Consider a non-TCP metric for determining the connection
|
| - // is making progress, since QUIC has out of order delivery.
|
| - bool new_least_unacked = !IsAwaitingPacket(received_info,
|
| - least_unacked_sent_before);
|
| -
|
| + // We rely on delta_time_largest_observed to compute an RTT estimate, so
|
| + // we only update rtt when the largest observed gets acked.
|
| + bool largest_observed_acked =
|
| + ContainsKey(unacked_packets_, received_info.largest_observed);
|
| MaybeUpdateRTT(received_info, ack_receive_time);
|
| HandleAckForSentPackets(received_info);
|
| MaybeRetransmitOnAckFrame(received_info, ack_receive_time);
|
|
|
| - if (new_least_unacked) {
|
| + // Anytime we are making forward progress and have a new RTT estimate, reset
|
| + // the backoff counters.
|
| + if (largest_observed_acked) {
|
| // Reset all retransmit counters any time a new packet is acked.
|
| consecutive_rto_count_ = 0;
|
| consecutive_tlp_count_ = 0;
|
| @@ -304,15 +303,9 @@ void QuicSentPacketManager::RetransmitUnackedPackets(
|
| unacked_it != unacked_packets_.end(); ++unacked_it) {
|
| const RetransmittableFrames* frames =
|
| unacked_it->second.retransmittable_frames;
|
| - if (frames == NULL) {
|
| - continue;
|
| - }
|
| if (retransmission_type == ALL_PACKETS ||
|
| - frames->encryption_level() == ENCRYPTION_INITIAL) {
|
| - // TODO(satyamshekhar): Think about congestion control here.
|
| - // Specifically, about the retransmission count of packets being sent
|
| - // proactively to achieve 0 (minimal) RTT.
|
| - if (unacked_it->second.retransmittable_frames) {
|
| + (frames != NULL && frames->encryption_level() == ENCRYPTION_INITIAL)) {
|
| + if (frames) {
|
| OnPacketAbandoned(unacked_it);
|
| MarkForRetransmission(unacked_it->first, NACK_RETRANSMISSION);
|
| } else {
|
| @@ -398,7 +391,7 @@ QuicSentPacketManager::MarkPacketHandled(
|
| if (it->second.pending) {
|
| size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent();
|
| if (received_by_peer == RECEIVED_BY_PEER) {
|
| - send_algorithm_->OnPacketAcked(sequence_number, bytes_sent, rtt_sample_);
|
| + send_algorithm_->OnPacketAcked(sequence_number, bytes_sent);
|
| } else {
|
| // It's been abandoned.
|
| send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent);
|
| @@ -550,18 +543,13 @@ bool QuicSentPacketManager::OnPacketSent(
|
| TransmissionType transmission_type,
|
| HasRetransmittableData has_retransmittable_data) {
|
| DCHECK_LT(0u, sequence_number);
|
| - // In some edge cases, on some platforms (such as Windows), it is possible
|
| - // that we were write-blocked when we tried to send a packet, and then decided
|
| - // not to send the packet (such as when the encryption key changes, and we
|
| - // "discard" the unsent packet). In that rare case, we may indeed
|
| - // asynchronously (later) send the packet, calling this method, but the
|
| - // sequence number may already be erased from unacked_packets_ map. In that
|
| - // case, we can just return false since the packet will not be tracked for
|
| - // retransmission.
|
| - if (!ContainsKey(unacked_packets_, sequence_number))
|
| - return false;
|
| - DCHECK(!unacked_packets_[sequence_number].pending);
|
| UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
|
| + // In rare circumstances, the packet could be serialized, sent, and then acked
|
| + // before OnPacketSent is called.
|
| + if (it == unacked_packets_.end()) {
|
| + return false;
|
| + }
|
| + DCHECK(!it->second.pending);
|
|
|
| // Only track packets the send algorithm wants us to track.
|
| if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes,
|
| @@ -805,6 +793,10 @@ void QuicSentPacketManager::MaybeUpdateRTT(
|
| if (transmission_info == NULL) {
|
| return;
|
| }
|
| + // Don't update the RTT if it hasn't been sent.
|
| + if (transmission_info->sent_time == QuicTime::Zero()) {
|
| + return;
|
| + }
|
|
|
| QuicTime::Delta send_delta =
|
| ack_receive_time.Subtract(transmission_info->sent_time);
|
| @@ -817,6 +809,7 @@ void QuicSentPacketManager::MaybeUpdateRTT(
|
| // approximation until we get a better estimate.
|
| rtt_sample_ = send_delta;
|
| }
|
| + send_algorithm_->UpdateRtt(rtt_sample_);
|
| }
|
|
|
| QuicTime::Delta QuicSentPacketManager::TimeUntilSend(
|
|
|