quic_sent_packet_manager.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file.
4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/quic/quic_sent_packet_manager.h"
6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include <algorithm>
823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/logging.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/stl_util.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/quic/congestion_control/pacing_sender.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/crypto/crypto_protocol.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/quic/quic_ack_notifier_manager.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_connection_stats.h"
15e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_flags.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_utils_chromium.h"
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using std::make_pair;
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using std::max;
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using std::min;
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace net {
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// The length of the recent min rtt window in seconds. Windowing is disabled for
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// values less than or equal to 0.
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint32 FLAGS_quic_recent_min_rtt_window_s = 60;
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static const int kDefaultRetransmissionTimeMs = 500;
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TCP RFC calls for 1 second RTO however Linux differs from this default and
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// define the minimum RTO to 200ms, we will use the same until we have data to
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// support a higher or lower value.
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static const int kMinRetransmissionTimeMs = 200;
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static const int kMaxRetransmissionTimeMs = 60000;
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static const size_t kMaxRetransmissions = 10;
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Only exponentially back off the handshake timer 5 times due to a timeout.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const size_t kMaxHandshakeRetransmissionBackoffs = 5;
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const size_t kMinHandshakeTimeoutMs = 10;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Sends up to two tail loss probes before firing an RTO,
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// per draft RFC draft-dukkipati-tcpm-tcp-loss-probe.
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const size_t kDefaultMaxTailLossProbes = 2;
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const int64 kMinTailLossProbeTimeoutMs = 10;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Number of samples before we force a new recent min rtt to be captured.
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static const size_t kNumMinRttSamplesAfterQuiescence = 2;
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Number of unpaced packets to send after quiescence.
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const size_t kInitialUnpacedBurst = 10;
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use a 1 minute window for Recent Min RTT with BBR.
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool HasCryptoHandshake(const TransmissionInfo& transmission_info) {
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (transmission_info.retransmittable_frames == NULL) {
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return transmission_info.retransmittable_frames->HasCryptoHandshake() ==
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      IS_HANDSHAKE;
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define ENDPOINT (is_server_ ? "Server: " : " Client: ")
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)QuicSentPacketManager::QuicSentPacketManager(
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool is_server,
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const QuicClock* clock,
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    QuicConnectionStats* stats,
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CongestionControlType congestion_control_type,
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LossDetectionType loss_type)
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : unacked_packets_(),
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      is_server_(is_server),
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      clock_(clock),
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stats_(stats),
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      debug_delegate_(NULL),
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      network_change_visitor_(NULL),
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      send_algorithm_(SendAlgorithmInterface::Create(clock,
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                     &rtt_stats_,
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                     congestion_control_type,
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                     stats)),
82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      loss_algorithm_(LossDetectionInterface::Create(loss_type)),
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      largest_observed_(0),
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      first_rto_transmission_(0),
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      consecutive_rto_count_(0),
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      consecutive_tlp_count_(0),
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      consecutive_crypto_retransmission_count_(0),
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      pending_tlp_transmission_(false),
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      max_tail_loss_probes_(kDefaultMaxTailLossProbes),
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      using_pacing_(false) {
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)QuicSentPacketManager::~QuicSentPacketManager() {
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (config.HasReceivedInitialRoundTripTimeUs() &&
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      config.ReceivedInitialRoundTripTimeUs() > 0) {
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    rtt_stats_.set_initial_rtt_us(min(kMaxInitialRoundTripTimeUs,
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                      config.ReceivedInitialRoundTripTimeUs()));
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // TODO(ianswett): BBR is currently a server only feature.
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (config.HasReceivedConnectionOptions() &&
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) {
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (FLAGS_quic_recent_min_rtt_window_s > 0) {
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      rtt_stats_.set_recent_min_rtt_window(
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          QuicTime::Delta::FromSeconds(FLAGS_quic_recent_min_rtt_window_s));
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    send_algorithm_.reset(
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        SendAlgorithmInterface::Create(clock_, &rtt_stats_, kBBR, stats_));
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (config.HasReceivedConnectionOptions() &&
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) {
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    send_algorithm_.reset(
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        SendAlgorithmInterface::Create(clock_, &rtt_stats_, kReno, stats_));
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (config.congestion_feedback() == kPACE ||
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (config.HasReceivedConnectionOptions() &&
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ContainsQuicTag(config.ReceivedConnectionOptions(), kPACE))) {
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    MaybeEnablePacing();
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(ianswett): Remove the "HasReceivedLossDetection" branch once
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the ConnectionOptions code is live everywhere.
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if ((config.HasReceivedLossDetection() &&
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       config.ReceivedLossDetection() == kTIME) ||
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (config.HasReceivedConnectionOptions() &&
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME))) {
128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    loss_algorithm_.reset(LossDetectionInterface::Create(kTime));
129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  send_algorithm_->SetFromConfig(config, is_server_);
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (network_change_visitor_ != NULL) {
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow());
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(ianswett): Combine this method with OnPacketSent once packets are always
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// sent in order and the connection tracks RetransmittableFrames for longer.
139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicSentPacketManager::OnSerializedPacket(
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const SerializedPacket& serialized_packet) {
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (serialized_packet.retransmittable_frames) {
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ack_notifier_manager_.OnSerializedPacket(serialized_packet);
143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unacked_packets_.AddPacket(serialized_packet);
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicSentPacketManager::OnRetransmittedPacket(
149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    QuicPacketSequenceNumber old_sequence_number,
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    QuicPacketSequenceNumber new_sequence_number) {
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TransmissionType transmission_type;
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PendingRetransmissionMap::iterator it =
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      pending_retransmissions_.find(old_sequence_number);
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (it != pending_retransmissions_.end()) {
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    transmission_type = it->second;
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    pending_retransmissions_.erase(it);
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else {
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DLOG(DFATAL) << "Expected sequence number to be in "
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "pending_retransmissions_.  sequence_number: " << old_sequence_number;
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    transmission_type = NOT_RETRANSMISSION;
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A notifier may be waiting to hear about ACKs for the original sequence
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // number. Inform them that the sequence number has changed.
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ack_notifier_manager_.UpdateSequenceNumber(old_sequence_number,
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             new_sequence_number);
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unacked_packets_.OnRetransmittedPacket(old_sequence_number,
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                         new_sequence_number,
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                         transmission_type);
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (debug_delegate_ != NULL) {
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    debug_delegate_->OnRetransmittedPacket(old_sequence_number,
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        new_sequence_number,
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        transmission_type,
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        clock_->ApproximateNow());
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame,
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          QuicTime ack_receive_time) {
182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight();
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We rely on delta_time_largest_observed to compute an RTT estimate, so
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // we only update rtt when the largest observed gets acked.
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool largest_observed_acked = MaybeUpdateRTT(ack_frame, ack_receive_time);
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (largest_observed_ < ack_frame.largest_observed) {
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    largest_observed_ = ack_frame.largest_observed;
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    unacked_packets_.IncreaseLargestObserved(largest_observed_);
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HandleAckForSentPackets(ack_frame);
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  InvokeLossDetection(ack_receive_time);
193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MaybeInvokeCongestionEvent(largest_observed_acked, bytes_in_flight);
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If we have received a truncated ack, then we need to clear out some
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // previous transmissions to allow the peer to actually ACK new packets.
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (ack_frame.is_truncated) {
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    unacked_packets_.ClearPreviousRetransmissions(
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ack_frame.missing_packets.size() / 2);
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Anytime we are making forward progress and have a new RTT estimate, reset
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the backoff counters.
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (largest_observed_acked) {
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Reset all retransmit counters any time a new packet is acked.
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    consecutive_rto_count_ = 0;
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    consecutive_tlp_count_ = 0;
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    consecutive_crypto_retransmission_count_ = 0;
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (debug_delegate_ != NULL) {
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    debug_delegate_->OnIncomingAck(ack_frame,
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   ack_receive_time,
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   largest_observed_,
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   largest_observed_acked,
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   GetLeastUnackedSentPacket());
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void QuicSentPacketManager::MaybeInvokeCongestionEvent(
221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool rtt_updated, QuicByteCount bytes_in_flight) {
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight,
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     packets_acked_, packets_lost_);
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  packets_acked_.clear();
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  packets_lost_.clear();
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (network_change_visitor_ != NULL) {
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow());
231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicSentPacketManager::HandleAckForSentPackets(
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const QuicAckFrame& ack_frame) {
236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Go through the packets we have not received an ack for and see if this
237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // incoming_ack shows they've been seen by the peer.
2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicTime::Delta delta_largest_observed =
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ack_frame.delta_time_largest_observed;
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  while (it != unacked_packets_.end()) {
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    QuicPacketSequenceNumber sequence_number = it->first;
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (sequence_number > ack_frame.largest_observed) {
244e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // These packets are still in flight.
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      break;
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (IsAwaitingPacket(ack_frame, sequence_number)) {
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Consider it multiple nacks when there is a gap between the missing
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // packet and the largest observed, since the purpose of a nack
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // threshold is to tolerate re-ordering.  This handles both StretchAcks
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // and Forward Acks.
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // The nack count only increases when the largest observed increases.
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_t min_nacks = ack_frame.largest_observed - sequence_number;
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Truncated acks can nack the largest observed, so use a min of 1.
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (min_nacks == 0) {
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        min_nacks = 1;
258e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      }
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.NackPacket(sequence_number, min_nacks);
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ++it;
26168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      continue;
26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Packet was acked, so remove it from our unacked packet list.
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DVLOG(1) << ENDPOINT << "Got an ack for packet " << sequence_number;
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // If data is associated with the most recent transmission of this
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // packet, then inform the caller.
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (it->second.in_flight) {
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      packets_acked_[sequence_number] = it->second;
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    it = MarkPacketHandled(it, delta_largest_observed);
27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Discard any retransmittable frames associated with revived packets.
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (SequenceNumberSet::const_iterator revived_it =
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           ack_frame.revived_packets.begin();
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       revived_it != ack_frame.revived_packets.end(); ++revived_it) {
2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MarkPacketRevived(*revived_it, delta_largest_observed);
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool QuicSentPacketManager::HasRetransmittableFrames(
28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number) const {
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return unacked_packets_.HasRetransmittableFrames(sequence_number);
28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::RetransmitUnackedPackets(
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RetransmissionType retransmission_type) {
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (it != unacked_packets_.end()) {
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const RetransmittableFrames* frames = it->second.retransmittable_frames;
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TODO(ianswett): Consider adding a new retransmission type which removes
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // all these old packets from unacked and retransmits them as new sequence
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // numbers with no connection to the previous ones.
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (frames != NULL && (retransmission_type == ALL_PACKETS ||
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           frames->encryption_level() == ENCRYPTION_INITIAL)) {
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      MarkForRetransmission(it->first, ALL_UNACKED_RETRANSMISSION);
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++it;
299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void QuicSentPacketManager::NeuterUnencryptedPackets() {
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (it != unacked_packets_.end()) {
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const RetransmittableFrames* frames = it->second.retransmittable_frames;
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number = it->first;
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++it;
3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (frames != NULL && frames->encryption_level() == ENCRYPTION_NONE) {
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Once you're forward secure, no unencrypted packets will be sent, crypto
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // or otherwise. Unencrypted packets are neutered and abandoned, to ensure
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // they are not retransmitted or considered lost from a congestion control
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // perspective.
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pending_retransmissions_.erase(sequence_number);
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.RemoveFromInFlight(sequence_number);
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // RemoveRetransmittibility is safe because only the newest sequence
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // number can have frames.
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.RemoveRetransmittability(sequence_number);
3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicSentPacketManager::MarkForRetransmission(
32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number,
32468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransmissionType transmission_type) {
325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TransmissionInfo& transmission_info =
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      unacked_packets_.GetTransmissionInfo(sequence_number);
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, transmission_info.retransmittable_frames == NULL);
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (transmission_type != TLP_RETRANSMISSION) {
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    unacked_packets_.RemoveFromInFlight(sequence_number);
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(ianswett): Currently the RTO can fire while there are pending NACK
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // retransmissions for the same data, which is not ideal.
33368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (ContainsKey(pending_retransmissions_, sequence_number)) {
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
33568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
33668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
33768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  pending_retransmissions_[sequence_number] = transmission_type;
33868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
33968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void QuicSentPacketManager::RecordSpuriousRetransmissions(
34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const SequenceNumberSet& all_transmissions,
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    QuicPacketSequenceNumber acked_sequence_number) {
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (acked_sequence_number < first_rto_transmission_) {
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Cancel all pending RTO transmissions and restore their in flight status.
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Replace SRTT with latest_rtt and increase the variance to prevent
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // a spurious RTO from happening again.
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    rtt_stats_.ExpireSmoothedMetrics();
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    for (PendingRetransmissionMap::const_iterator it =
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             pending_retransmissions_.begin();
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         it != pending_retransmissions_.end(); ++it) {
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK_EQ(it->second, RTO_RETRANSMISSION);
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      unacked_packets_.RestoreInFlight(it->first);
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    pending_retransmissions_.clear();
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    send_algorithm_->RevertRetransmissionTimeout();
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    first_rto_transmission_ = 0;
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ++stats_->spurious_rto_count;
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  for (SequenceNumberSet::const_iterator
36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)           it = all_transmissions.upper_bound(acked_sequence_number),
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)           end = all_transmissions.end();
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)       it != end;
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)       ++it) {
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const TransmissionInfo& retransmit_info =
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        unacked_packets_.GetTransmissionInfo(*it);
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent;
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ++stats_->packets_spuriously_retransmitted;
36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (debug_delegate_ != NULL) {
37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      debug_delegate_->OnSpuriousPacketRetransmition(
37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          retransmit_info.transmission_type,
37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          retransmit_info.bytes_sent);
37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
37768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool QuicSentPacketManager::HasPendingRetransmissions() const {
37868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return !pending_retransmissions_.empty();
37968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)QuicSentPacketManager::PendingRetransmission
38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    QuicSentPacketManager::NextPendingRetransmission() {
38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!pending_retransmissions_.empty());
38468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  QuicPacketSequenceNumber sequence_number =
38568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      pending_retransmissions_.begin()->first;
386e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TransmissionType transmission_type = pending_retransmissions_.begin()->second;
387e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (unacked_packets_.HasPendingCryptoPackets()) {
388e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Ensure crypto packets are retransmitted before other packets.
389e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    PendingRetransmissionMap::const_iterator it =
390e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        pending_retransmissions_.begin();
391e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    do {
392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (HasCryptoHandshake(unacked_packets_.GetTransmissionInfo(it->first))) {
393e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        sequence_number = it->first;
394e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        transmission_type = it->second;
395e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        break;
396e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      }
397e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      ++it;
398e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    } while (it != pending_retransmissions_.end());
399e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(unacked_packets_.IsUnacked(sequence_number)) << sequence_number;
401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TransmissionInfo& transmission_info =
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      unacked_packets_.GetTransmissionInfo(sequence_number);
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(transmission_info.retransmittable_frames);
40468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return PendingRetransmission(sequence_number,
406e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                               transmission_type,
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               *transmission_info.retransmittable_frames,
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               transmission_info.sequence_number_length);
40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
41068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid QuicSentPacketManager::MarkPacketRevived(
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number,
4130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    QuicTime::Delta delta_largest_observed) {
4140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!unacked_packets_.IsUnacked(sequence_number)) {
4150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
4160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
418010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TransmissionInfo& transmission_info =
4190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      unacked_packets_.GetTransmissionInfo(sequence_number);
420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicPacketSequenceNumber newest_transmission =
421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *transmission_info.all_transmissions->rbegin();
422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This packet has been revived at the receiver. If we were going to
423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // retransmit it, do not retransmit it anymore.
424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_retransmissions_.erase(newest_transmission);
425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The AckNotifierManager needs to be notified for revived packets,
4270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // since it indicates the packet arrived from the appliction's perspective.
4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (transmission_info.retransmittable_frames) {
4290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ack_notifier_manager_.OnPacketAcked(
430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        newest_transmission, delta_largest_observed);
4310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unacked_packets_.RemoveRetransmittability(sequence_number);
4340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4360529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochQuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled(
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    QuicUnackedPacketMap::const_iterator it,
438010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    QuicTime::Delta delta_largest_observed) {
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LOG_IF(DFATAL, it == unacked_packets_.end())
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      << "MarkPacketHandled must be passed a valid iterator entry.";
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const QuicPacketSequenceNumber sequence_number = it->first;
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const TransmissionInfo& transmission_info = it->second;
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicPacketSequenceNumber newest_transmission =
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      *transmission_info.all_transmissions->rbegin();
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Remove the most recent packet, if it is pending retransmission.
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_retransmissions_.erase(newest_transmission);
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Notify observers about the ACKed packet.
45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // The AckNotifierManager needs to be notified about the most recent
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // transmission, since that's the one only one it tracks.
45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ack_notifier_manager_.OnPacketAcked(newest_transmission,
45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                        delta_largest_observed);
45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (newest_transmission != sequence_number) {
45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      RecordSpuriousRetransmissions(*transmission_info.all_transmissions,
45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    sequence_number);
45846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Two cases for MarkPacketHandled:
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // 1) Handle the most recent or a crypto packet, so remove all transmissions.
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // 2) Handle old transmission, keep all other pending transmissions,
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  //    but disassociate them from one another.
46523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If it's a crypto handshake packet, discard it and all retransmissions,
467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // since they won't be acked now that one has been processed.
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(ianswett): Instead of handling all crypto packets in a special way,
469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // only handle NULL encrypted packets in a special way.
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (HasCryptoHandshake(
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          unacked_packets_.GetTransmissionInfo(newest_transmission))) {
472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    unacked_packets_.RemoveFromInFlight(newest_transmission);
473d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unacked_packets_.RemoveFromInFlight(sequence_number);
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unacked_packets_.RemoveRetransmittability(sequence_number);
47668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicUnackedPacketMap::const_iterator next_unacked = unacked_packets_.begin();
47868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  while (next_unacked != unacked_packets_.end() &&
479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         next_unacked->first <= sequence_number) {
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ++next_unacked;
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return next_unacked;
483d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
484d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
485d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool QuicSentPacketManager::IsUnacked(
486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    QuicPacketSequenceNumber sequence_number) const {
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return unacked_packets_.IsUnacked(sequence_number);
488d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
489d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
490d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool QuicSentPacketManager::HasUnackedPackets() const {
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return unacked_packets_.HasUnackedPackets();
492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
493d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
494d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)QuicPacketSequenceNumber
495d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)QuicSentPacketManager::GetLeastUnackedSentPacket() const {
496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return unacked_packets_.GetLeastUnackedSentPacket();
497d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
498d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicSentPacketManager::OnPacketSent(
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number,
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    QuicTime sent_time,
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    QuicByteCount bytes,
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TransmissionType transmission_type,
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    HasRetransmittableData has_retransmittable_data) {
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_LT(0u, sequence_number);
506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets.";
50746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  pending_tlp_transmission_ = false;
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In rare circumstances, the packet could be serialized, sent, and then acked
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // before OnPacketSent is called.
510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!unacked_packets_.IsUnacked(sequence_number)) {
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (unacked_packets_.bytes_in_flight() == 0) {
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // TODO(ianswett): Consider being less aggressive to force a new
516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // recent_min_rtt, likely by not discarding a relatively new sample.
517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DVLOG(1) << "Sampling a new recent min rtt within 2 samples. currently:"
518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << rtt_stats_.recent_min_rtt().ToMilliseconds() << "ms";
519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    rtt_stats_.SampleNewRecentMinRtt(kNumMinRttSamplesAfterQuiescence);
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Only track packets as in flight that the send algorithm wants us to track.
523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const bool in_flight =
524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      send_algorithm_->OnPacketSent(sent_time,
525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    unacked_packets_.bytes_in_flight(),
526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    sequence_number,
527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    bytes,
528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    has_retransmittable_data);
529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unacked_packets_.SetSent(sequence_number, sent_time, bytes, in_flight);
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (debug_delegate_ != NULL) {
532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    debug_delegate_->OnSentPacket(sequence_number, sent_time, bytes);
533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
534116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reset the retransmission timer anytime a pending packet is sent.
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return in_flight;
537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::OnRetransmissionTimeout() {
540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(unacked_packets_.HasInFlightPackets());
541f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(!pending_tlp_transmission_);
542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Handshake retransmission, timer based loss detection, TLP, and RTO are
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // implemented with a single alarm. The handshake alarm is set when the
544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // handshake has not completed, the loss alarm is set when the loss detection
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // algorithm says to, and the TLP and  RTO alarms are set after that.
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The TLP alarm is always set to run for under an RTO.
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (GetRetransmissionMode()) {
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case HANDSHAKE_MODE:
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++stats_->crypto_retransmit_count;
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RetransmitCryptoPackets();
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case LOSS_MODE: {
553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ++stats_->loss_timeout_count;
554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight();
555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      InvokeLossDetection(clock_->Now());
556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      MaybeInvokeCongestionEvent(false, bytes_in_flight);
557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case TLP_MODE:
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // If no tail loss probe can be sent, because there are no retransmittable
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // packets, execute a conventional RTO to abandon old packets.
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++stats_->tlp_count;
563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ++consecutive_tlp_count_;
56446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      pending_tlp_transmission_ = true;
565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // TLPs prefer sending new data instead of retransmitting data, so
566f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // give the connection a chance to write before completing the TLP.
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RTO_MODE:
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++stats_->rto_count;
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RetransmitAllPackets();
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicSentPacketManager::RetransmitCryptoPackets() {
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(ianswett): Typical TCP implementations only retransmit 5 times.
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  consecutive_crypto_retransmission_count_ =
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      min(kMaxHandshakeRetransmissionBackoffs,
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          consecutive_crypto_retransmission_count_ + 1);
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool packet_retransmitted = false;
582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != unacked_packets_.end(); ++it) {
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number = it->first;
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const RetransmittableFrames* frames = it->second.retransmittable_frames;
586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Only retransmit frames which are in flight, and therefore have been sent.
587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!it->second.in_flight || frames == NULL ||
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        frames->HasCryptoHandshake() != IS_HANDSHAKE) {
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    packet_retransmitted = true;
59223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION);
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(packet_retransmitted) << "No crypto packets found to retransmit.";
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
597f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!pending_tlp_transmission_) {
599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return false;
600f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != unacked_packets_.end(); ++it) {
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number = it->first;
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const RetransmittableFrames* frames = it->second.retransmittable_frames;
605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Only retransmit frames which are in flight, and therefore have been sent.
606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!it->second.in_flight || frames == NULL) {
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake());
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MarkForRetransmission(sequence_number, TLP_RETRANSMISSION);
611f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return true;
612a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DLOG(FATAL)
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    << "No retransmittable packets, so RetransmitOldestPacket failed.";
615f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return false;
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicSentPacketManager::RetransmitAllPackets() {
61946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DVLOG(1) << "RetransmitAllPackets() called with "
620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           << unacked_packets_.GetNumUnackedPackets() << " unacked packets.";
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Request retransmission of all retransmittable packets when the RTO
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // fires, and let the congestion manager decide how many to send
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // immediately and the remaining packets will be queued.
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Abandon any non-retransmittable packets that are sufficiently old.
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool packets_retransmitted = false;
626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (it != unacked_packets_.end()) {
628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const RetransmittableFrames* frames = it->second.retransmittable_frames;
629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number = it->first;
630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++it;
631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (frames != NULL) {
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      packets_retransmitted = true;
633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      MarkForRetransmission(sequence_number, RTO_RETRANSMISSION);
634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.RemoveFromInFlight(sequence_number);
636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  send_algorithm_->OnRetransmissionTimeout(packets_retransmitted);
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (packets_retransmitted) {
641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (consecutive_rto_count_ == 0) {
642116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
643116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ++consecutive_rto_count_;
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (network_change_visitor_ != NULL) {
6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow());
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicSentPacketManager::RetransmissionTimeoutMode
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    QuicSentPacketManager::GetRetransmissionMode() const {
654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(unacked_packets_.HasInFlightPackets());
655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (unacked_packets_.HasPendingCryptoPackets()) {
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return HANDSHAKE_MODE;
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return LOSS_MODE;
660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (consecutive_tlp_count_ < max_tail_loss_probes_) {
662a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (unacked_packets_.HasUnackedRetransmittableFrames()) {
663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return TLP_MODE;
664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return RTO_MODE;
667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame(
670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const QuicCongestionFeedbackFrame& frame,
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const QuicTime& feedback_receive_time) {
672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  send_algorithm_->OnIncomingQuicCongestionFeedbackFrame(
673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      frame, feedback_receive_time);
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SequenceNumberSet lost_packets =
678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      loss_algorithm_->DetectLostPackets(unacked_packets_,
679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         time,
680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         largest_observed_,
681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         rtt_stats_);
682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (SequenceNumberSet::const_iterator it = lost_packets.begin();
683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != lost_packets.end(); ++it) {
684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number = *it;
685010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const TransmissionInfo& transmission_info =
686010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        unacked_packets_.GetTransmissionInfo(sequence_number);
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TODO(ianswett): If it's expected the FEC packet may repair the loss, it
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // should be recorded as a loss to the send algorithm, but not retransmitted
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // until it's known whether the FEC packet arrived.
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ++stats_->packets_lost;
691010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    packets_lost_[sequence_number] = transmission_info;
692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DVLOG(1) << ENDPOINT << "Lost packet " << sequence_number;
693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
694010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (transmission_info.retransmittable_frames != NULL) {
69523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      MarkForRetransmission(sequence_number, LOSS_RETRANSMISSION);
6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Since we will not retransmit this, we need to remove it from
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // unacked_packets_.   This is either the current transmission of
699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // a packet whose previous transmission has been acked, a packet that has
700cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // been TLP retransmitted, or an FEC packet.
701cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.RemoveFromInFlight(sequence_number);
702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
706010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool QuicSentPacketManager::MaybeUpdateRTT(
7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const QuicAckFrame& ack_frame,
708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const QuicTime& ack_receive_time) {
7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!unacked_packets_.IsUnacked(ack_frame.largest_observed)) {
710010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We calculate the RTT based on the highest ACKed sequence number, the lower
713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // sequence numbers will include the ACK aggregation delay.
714010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TransmissionInfo& transmission_info =
7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      unacked_packets_.GetTransmissionInfo(ack_frame.largest_observed);
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Don't update the RTT if it hasn't been sent.
717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (transmission_info.sent_time == QuicTime::Zero()) {
718010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicTime::Delta send_delta =
722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ack_receive_time.Subtract(transmission_info.sent_time);
7235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  rtt_stats_.UpdateRtt(
7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      send_delta, ack_frame.delta_time_largest_observed, ack_receive_time);
725010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)QuicTime::Delta QuicSentPacketManager::TimeUntilSend(
729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    QuicTime now,
730e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    HasRetransmittableData retransmittable) {
731e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // The TLP logic is entirely contained within QuicSentPacketManager, so the
732e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // send algorithm does not need to be consulted.
73346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (pending_tlp_transmission_) {
734e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return QuicTime::Delta::Zero();
735e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return send_algorithm_->TimeUntilSend(
737010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      now, unacked_packets_.bytes_in_flight(), retransmittable);
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Ensures that the Delayed Ack timer is always set to a value lesser
741a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// than the retransmission timer's minimum value (MinRTO). We want the
742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// delayed ack to get back to the QUIC peer before the sender's
743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// retransmission timer triggers.  Since we do not know the
744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// reverse-path one-way delay, we assume equal delays for forward and
745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// reverse paths, and ensure that the timer is set to less than half
746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// of the MinRTO.
747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// There may be a value in making this delay adaptive with the help of
748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// the sender and a signaling mechanism -- if the sender uses a
749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// different MinRTO, we may get spurious retransmissions. May not have
750a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// any benefits, but if the delayed ack becomes a significant source
751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// of (likely, tail) latency, then consider such a mechanism.
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const {
753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2);
754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
755a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
757f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Don't set the timer if there are no packets in flight or we've already
758f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // queued a tlp transmission and it hasn't been sent yet.
759f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!unacked_packets_.HasInFlightPackets() || pending_tlp_transmission_) {
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return QuicTime::Zero();
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (GetRetransmissionMode()) {
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case HANDSHAKE_MODE:
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay());
765a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case LOSS_MODE:
766a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return loss_algorithm_->GetLossTimeout();
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case TLP_MODE: {
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // TODO(ianswett): When CWND is available, it would be preferable to
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // set the timer based on the earliest retransmittable packet.
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Base the updated timer on the send time of the last packet.
771a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay());
773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Ensure the TLP timer never gets set to a time in the past.
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return QuicTime::Max(clock_->ApproximateNow(), tlp_time);
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RTO_MODE: {
777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // The RTO is based on the first outstanding packet.
778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const QuicTime sent_time =
779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          unacked_packets_.GetFirstInFlightPacketSentTime();
780116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      QuicTime rto_time = sent_time.Add(GetRetransmissionDelay());
781116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Wait for TLP packets to be acked before an RTO fires.
782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      QuicTime tlp_time =
783116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          unacked_packets_.GetLastPacketSentTime().Add(GetTailLossProbeDelay());
784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return QuicTime::Max(tlp_time, rto_time);
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(false);
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return QuicTime::Zero();
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const {
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // because crypto handshake messages don't incur a delayed ack time.
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 delay_ms = max<int64>(kMinHandshakeTimeoutMs,
7960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              1.5 * rtt_stats_.SmoothedRtt().ToMilliseconds());
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return QuicTime::Delta::FromMilliseconds(
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delay_ms << consecutive_crypto_retransmission_count_);
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
8020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicTime::Delta srtt = rtt_stats_.SmoothedRtt();
803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!unacked_packets_.HasMultipleInFlightPackets()) {
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return QuicTime::Delta::Max(
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        srtt.Multiply(1.5).Add(DelayedAckTime()), srtt.Multiply(2));
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return QuicTime::Delta::FromMilliseconds(
8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      max(kMinTailLossProbeTimeoutMs,
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          static_cast<int64>(2 * srtt.ToMilliseconds())));
8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
811a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
813a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay();
8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(rch): This code should move to |send_algorithm_|.
815a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (retransmission_delay.IsZero()) {
816a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // We are in the initial state, use default timeout values.
817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    retransmission_delay =
818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) {
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    retransmission_delay =
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs);
822a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Calculate exponential back off.
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  retransmission_delay = retransmission_delay.Multiply(
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      1 << min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
827a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
828a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
829a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
830a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return retransmission_delay;
832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
833a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst RttStats* QuicSentPacketManager::GetRttStats() const {
8350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return &rtt_stats_;
836a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
837a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
838a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)QuicBandwidth QuicSentPacketManager::BandwidthEstimate() const {
839a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return send_algorithm_->BandwidthEstimate();
840a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
841a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
842116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool QuicSentPacketManager::HasReliableBandwidthEstimate() const {
843116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return send_algorithm_->HasReliableBandwidthEstimate();
844116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
845116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
846a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)QuicByteCount QuicSentPacketManager::GetCongestionWindow() const {
847a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return send_algorithm_->GetCongestionWindow();
848a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
850116680a4aac90f2aa7413d9095a592090648e557Ben MurdochQuicByteCount QuicSentPacketManager::GetSlowStartThreshold() const {
851116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return send_algorithm_->GetSlowStartThreshold();
852116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
853116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::MaybeEnablePacing() {
855a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!FLAGS_enable_quic_pacing) {
856a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
857a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
858a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
859a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (using_pacing_) {
860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
861a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
86346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Set up a pacing sender with a 5 millisecond alarm granularity.
864a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  using_pacing_ = true;
865a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  send_algorithm_.reset(
866a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new PacingSender(send_algorithm_.release(),
867116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       QuicTime::Delta::FromMilliseconds(5),
868116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       kInitialUnpacedBurst));
869a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
870a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
871d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace net
872