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
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool HasCryptoHandshake(const TransmissionInfo& transmission_info) {
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (transmission_info.retransmittable_frames == NULL) {
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return transmission_info.retransmittable_frames->HasCryptoHandshake() ==
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      IS_HANDSHAKE;
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define ENDPOINT (is_server_ ? "Server: " : " Client: ")
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)QuicSentPacketManager::QuicSentPacketManager(
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool is_server,
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const QuicClock* clock,
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    QuicConnectionStats* stats,
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CongestionControlType congestion_control_type,
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LossDetectionType loss_type)
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : unacked_packets_(),
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      is_server_(is_server),
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      clock_(clock),
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stats_(stats),
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      debug_delegate_(NULL),
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      network_change_visitor_(NULL),
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      send_algorithm_(SendAlgorithmInterface::Create(clock,
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                     &rtt_stats_,
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                     congestion_control_type,
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                     stats)),
80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      loss_algorithm_(LossDetectionInterface::Create(loss_type)),
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      least_packet_awaited_by_peer_(1),
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      first_rto_transmission_(0),
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      consecutive_rto_count_(0),
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      consecutive_tlp_count_(0),
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      consecutive_crypto_retransmission_count_(0),
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      pending_timer_transmission_count_(0),
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      max_tail_loss_probes_(kDefaultMaxTailLossProbes),
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      using_pacing_(false),
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      handshake_confirmed_(false) {
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)QuicSentPacketManager::~QuicSentPacketManager() {
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (config.HasReceivedInitialRoundTripTimeUs() &&
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      config.ReceivedInitialRoundTripTimeUs() > 0) {
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    rtt_stats_.set_initial_rtt_us(min(kMaxInitialRoundTripTimeUs,
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                      config.ReceivedInitialRoundTripTimeUs()));
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (config.HasInitialRoundTripTimeUsToSend()) {
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    rtt_stats_.set_initial_rtt_us(
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        min(kMaxInitialRoundTripTimeUs,
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            config.GetInitialRoundTripTimeUsToSend()));
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // TODO(ianswett): BBR is currently a server only feature.
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (config.HasReceivedConnectionOptions() &&
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) {
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (FLAGS_quic_recent_min_rtt_window_s > 0) {
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      rtt_stats_.set_recent_min_rtt_window(
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          QuicTime::Delta::FromSeconds(FLAGS_quic_recent_min_rtt_window_s));
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    send_algorithm_.reset(
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        SendAlgorithmInterface::Create(clock_, &rtt_stats_, kBBR, stats_));
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (config.HasReceivedConnectionOptions() &&
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) {
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    send_algorithm_.reset(
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        SendAlgorithmInterface::Create(clock_, &rtt_stats_, kReno, stats_));
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (is_server_) {
12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (config.HasReceivedConnectionOptions() &&
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        ContainsQuicTag(config.ReceivedConnectionOptions(), kPACE)) {
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      EnablePacing();
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else if (config.HasSendConnectionOptions() &&
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)             ContainsQuicTag(config.SendConnectionOptions(), kPACE)) {
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EnablePacing();
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(ianswett): Remove the "HasReceivedLossDetection" branch once
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the ConnectionOptions code is live everywhere.
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if ((config.HasReceivedLossDetection() &&
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       config.ReceivedLossDetection() == kTIME) ||
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (config.HasReceivedConnectionOptions() &&
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME))) {
135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    loss_algorithm_.reset(LossDetectionInterface::Create(kTime));
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  send_algorithm_->SetFromConfig(config, is_server_);
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (network_change_visitor_ != NULL) {
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow());
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(ianswett): Combine this method with OnPacketSent once packets are always
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// sent in order and the connection tracks RetransmittableFrames for longer.
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicSentPacketManager::OnSerializedPacket(
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const SerializedPacket& serialized_packet) {
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (serialized_packet.retransmittable_frames) {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ack_notifier_manager_.OnSerializedPacket(serialized_packet);
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unacked_packets_.AddPacket(serialized_packet);
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (debug_delegate_ != NULL) {
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    debug_delegate_->OnSerializedPacket(serialized_packet);
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicSentPacketManager::OnRetransmittedPacket(
159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    QuicPacketSequenceNumber old_sequence_number,
160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    QuicPacketSequenceNumber new_sequence_number) {
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TransmissionType transmission_type;
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PendingRetransmissionMap::iterator it =
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      pending_retransmissions_.find(old_sequence_number);
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (it != pending_retransmissions_.end()) {
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    transmission_type = it->second;
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    pending_retransmissions_.erase(it);
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else {
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DLOG(DFATAL) << "Expected sequence number to be in "
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        "pending_retransmissions_.  sequence_number: " << old_sequence_number;
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    transmission_type = NOT_RETRANSMISSION;
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A notifier may be waiting to hear about ACKs for the original sequence
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // number. Inform them that the sequence number has changed.
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ack_notifier_manager_.UpdateSequenceNumber(old_sequence_number,
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             new_sequence_number);
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unacked_packets_.OnRetransmittedPacket(old_sequence_number,
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                         new_sequence_number,
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                         transmission_type);
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (debug_delegate_ != NULL) {
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    debug_delegate_->OnRetransmittedPacket(old_sequence_number,
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        new_sequence_number,
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        transmission_type,
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        clock_->ApproximateNow());
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame,
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          QuicTime ack_receive_time) {
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight();
193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  UpdatePacketInformationReceivedByPeer(ack_frame);
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We rely on delta_time_largest_observed to compute an RTT estimate, so
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // we only update rtt when the largest observed gets acked.
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool largest_observed_acked = MaybeUpdateRTT(ack_frame, ack_receive_time);
19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK_GE(ack_frame.largest_observed, unacked_packets_.largest_observed());
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  unacked_packets_.IncreaseLargestObserved(ack_frame.largest_observed);
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HandleAckForSentPackets(ack_frame);
202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  InvokeLossDetection(ack_receive_time);
203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MaybeInvokeCongestionEvent(largest_observed_acked, bytes_in_flight);
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unacked_packets_.RemoveObsoletePackets();
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  sustained_bandwidth_recorder_.RecordEstimate(
20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      send_algorithm_->InRecovery(),
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      send_algorithm_->InSlowStart(),
20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      send_algorithm_->BandwidthEstimate(),
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ack_receive_time,
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      clock_->WallNow(),
21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      rtt_stats_.SmoothedRtt());
21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If we have received a truncated ack, then we need to clear out some
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // previous transmissions to allow the peer to actually ACK new packets.
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (ack_frame.is_truncated) {
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    unacked_packets_.ClearAllPreviousRetransmissions();
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Anytime we are making forward progress and have a new RTT estimate, reset
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the backoff counters.
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (largest_observed_acked) {
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Reset all retransmit counters any time a new packet is acked.
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    consecutive_rto_count_ = 0;
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    consecutive_tlp_count_ = 0;
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    consecutive_crypto_retransmission_count_ = 0;
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (debug_delegate_ != NULL) {
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    debug_delegate_->OnIncomingAck(ack_frame,
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   ack_receive_time,
23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   unacked_packets_.largest_observed(),
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   largest_observed_acked,
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                   GetLeastUnacked());
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void QuicSentPacketManager::UpdatePacketInformationReceivedByPeer(
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const QuicAckFrame& ack_frame) {
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (ack_frame.missing_packets.empty()) {
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    least_packet_awaited_by_peer_ = ack_frame.largest_observed + 1;
24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else {
24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    least_packet_awaited_by_peer_ = *(ack_frame.missing_packets.begin());
24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void QuicSentPacketManager::MaybeInvokeCongestionEvent(
248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool rtt_updated, QuicByteCount bytes_in_flight) {
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) {
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight,
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     packets_acked_, packets_lost_);
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  packets_acked_.clear();
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  packets_lost_.clear();
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (network_change_visitor_ != NULL) {
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow());
258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicSentPacketManager::HandleAckForSentPackets(
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const QuicAckFrame& ack_frame) {
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Go through the packets we have not received an ack for and see if this
264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // incoming_ack shows they've been seen by the peer.
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicTime::Delta delta_largest_observed =
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ack_frame.delta_time_largest_observed;
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked();
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != unacked_packets_.end(); ++it, ++sequence_number) {
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (sequence_number > ack_frame.largest_observed) {
271e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // These packets are still in flight.
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      break;
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (ContainsKey(ack_frame.missing_packets, sequence_number)) {
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Don't continue to increase the nack count for packets not in flight.
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!it->in_flight) {
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        continue;
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Consider it multiple nacks when there is a gap between the missing
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // packet and the largest observed, since the purpose of a nack
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // threshold is to tolerate re-ordering.  This handles both StretchAcks
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // and Forward Acks.
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // The nack count only increases when the largest observed increases.
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_t min_nacks = ack_frame.largest_observed - sequence_number;
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Truncated acks can nack the largest observed, so use a min of 1.
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (min_nacks == 0) {
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        min_nacks = 1;
289e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      }
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.NackPacket(sequence_number, min_nacks);
29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      continue;
29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Packet was acked, so remove it from our unacked packet list.
294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DVLOG(1) << ENDPOINT << "Got an ack for packet " << sequence_number;
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // If data is associated with the most recent transmission of this
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // packet, then inform the caller.
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (it->in_flight) {
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      packets_acked_.push_back(make_pair(sequence_number, *it));
299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MarkPacketHandled(sequence_number, *it, delta_largest_observed);
30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Discard any retransmittable frames associated with revived packets.
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (SequenceNumberSet::const_iterator revived_it =
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           ack_frame.revived_packets.begin();
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       revived_it != ack_frame.revived_packets.end(); ++revived_it) {
3070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MarkPacketRevived(*revived_it, delta_largest_observed);
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
31168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool QuicSentPacketManager::HasRetransmittableFrames(
31268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number) const {
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return unacked_packets_.HasRetransmittableFrames(sequence_number);
31468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::RetransmitUnackedPackets(
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TransmissionType retransmission_type) {
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         retransmission_type == ALL_INITIAL_RETRANSMISSION);
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked();
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != unacked_packets_.end(); ++it, ++sequence_number) {
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const RetransmittableFrames* frames = it->retransmittable_frames;
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (frames != NULL && (retransmission_type == ALL_UNACKED_RETRANSMISSION ||
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           frames->encryption_level() == ENCRYPTION_INITIAL)) {
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MarkForRetransmission(sequence_number, retransmission_type);
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void QuicSentPacketManager::NeuterUnencryptedPackets() {
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked();
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != unacked_packets_.end(); ++it, ++sequence_number) {
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const RetransmittableFrames* frames = it->retransmittable_frames;
3365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (frames != NULL && frames->encryption_level() == ENCRYPTION_NONE) {
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Once you're forward secure, no unencrypted packets will be sent, crypto
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // or otherwise. Unencrypted packets are neutered and abandoned, to ensure
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // they are not retransmitted or considered lost from a congestion control
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // perspective.
341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      pending_retransmissions_.erase(sequence_number);
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.RemoveFromInFlight(sequence_number);
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.RemoveRetransmittability(sequence_number);
3445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicSentPacketManager::MarkForRetransmission(
34968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number,
35068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    TransmissionType transmission_type) {
351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TransmissionInfo& transmission_info =
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      unacked_packets_.GetTransmissionInfo(sequence_number);
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, transmission_info.retransmittable_frames == NULL);
354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (transmission_type != TLP_RETRANSMISSION) {
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    unacked_packets_.RemoveFromInFlight(sequence_number);
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(ianswett): Currently the RTO can fire while there are pending NACK
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // retransmissions for the same data, which is not ideal.
35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (ContainsKey(pending_retransmissions_, sequence_number)) {
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
36168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
36268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
36368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  pending_retransmissions_[sequence_number] = transmission_type;
36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void QuicSentPacketManager::RecordSpuriousRetransmissions(
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const SequenceNumberList& all_transmissions,
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    QuicPacketSequenceNumber acked_sequence_number) {
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (acked_sequence_number < first_rto_transmission_) {
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Cancel all pending RTO transmissions and restore their in flight status.
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Replace SRTT with latest_rtt and increase the variance to prevent
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // a spurious RTO from happening again.
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    rtt_stats_.ExpireSmoothedMetrics();
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    for (PendingRetransmissionMap::const_iterator it =
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             pending_retransmissions_.begin();
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         it != pending_retransmissions_.end(); ++it) {
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK_EQ(it->second, RTO_RETRANSMISSION);
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      unacked_packets_.RestoreInFlight(it->first);
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    pending_retransmissions_.clear();
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    send_algorithm_->RevertRetransmissionTimeout();
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    first_rto_transmission_ = 0;
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ++stats_->spurious_rto_count;
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (SequenceNumberList::const_reverse_iterator it =
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           all_transmissions.rbegin();
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != all_transmissions.rend() && *it > acked_sequence_number; ++it) {
38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const TransmissionInfo& retransmit_info =
38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        unacked_packets_.GetTransmissionInfo(*it);
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent;
39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ++stats_->packets_spuriously_retransmitted;
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (debug_delegate_ != NULL) {
39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      debug_delegate_->OnSpuriousPacketRetransmition(
39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          retransmit_info.transmission_type,
39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          retransmit_info.bytes_sent);
39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
40168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool QuicSentPacketManager::HasPendingRetransmissions() const {
40268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return !pending_retransmissions_.empty();
40368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
40468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)QuicSentPacketManager::PendingRetransmission
40668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    QuicSentPacketManager::NextPendingRetransmission() {
40768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!pending_retransmissions_.empty());
40868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  QuicPacketSequenceNumber sequence_number =
40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      pending_retransmissions_.begin()->first;
410e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TransmissionType transmission_type = pending_retransmissions_.begin()->second;
411e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (unacked_packets_.HasPendingCryptoPackets()) {
412e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Ensure crypto packets are retransmitted before other packets.
413e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    PendingRetransmissionMap::const_iterator it =
414e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        pending_retransmissions_.begin();
415e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    do {
416010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (HasCryptoHandshake(unacked_packets_.GetTransmissionInfo(it->first))) {
417e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        sequence_number = it->first;
418e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        transmission_type = it->second;
419e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        break;
420e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      }
421e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      ++it;
422e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    } while (it != pending_retransmissions_.end());
423e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(unacked_packets_.IsUnacked(sequence_number)) << sequence_number;
425010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TransmissionInfo& transmission_info =
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      unacked_packets_.GetTransmissionInfo(sequence_number);
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(transmission_info.retransmittable_frames);
42868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
42968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return PendingRetransmission(sequence_number,
430e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                               transmission_type,
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               *transmission_info.retransmittable_frames,
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               transmission_info.sequence_number_length);
43368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
43468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid QuicSentPacketManager::MarkPacketRevived(
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number,
4370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    QuicTime::Delta delta_largest_observed) {
4380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!unacked_packets_.IsUnacked(sequence_number)) {
4390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
4400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
442010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TransmissionInfo& transmission_info =
4430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      unacked_packets_.GetTransmissionInfo(sequence_number);
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicPacketSequenceNumber newest_transmission =
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      transmission_info.all_transmissions == NULL ?
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          sequence_number : *transmission_info.all_transmissions->rbegin();
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This packet has been revived at the receiver. If we were going to
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // retransmit it, do not retransmit it anymore.
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_retransmissions_.erase(newest_transmission);
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The AckNotifierManager needs to be notified for revived packets,
4520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // since it indicates the packet arrived from the appliction's perspective.
4530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (transmission_info.retransmittable_frames) {
4540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ack_notifier_manager_.OnPacketAcked(
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        newest_transmission, delta_largest_observed);
4560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unacked_packets_.RemoveRetransmittability(sequence_number);
4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid QuicSentPacketManager::MarkPacketHandled(
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    QuicPacketSequenceNumber sequence_number,
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const TransmissionInfo& info,
464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    QuicTime::Delta delta_largest_observed) {
465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  QuicPacketSequenceNumber newest_transmission =
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      info.all_transmissions == NULL ?
4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          sequence_number : *info.all_transmissions->rbegin();
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Remove the most recent packet, if it is pending retransmission.
469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_retransmissions_.erase(newest_transmission);
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The AckNotifierManager needs to be notified about the most recent
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // transmission, since that's the one only one it tracks.
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ack_notifier_manager_.OnPacketAcked(newest_transmission,
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      delta_largest_observed);
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (newest_transmission != sequence_number) {
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RecordSpuriousRetransmissions(*info.all_transmissions, sequence_number);
4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Remove the most recent packet from flight if it's a crypto handshake
4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // packet, since they won't be acked now that one has been processed.
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Other crypto handshake packets won't be in flight, only the newest
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // transmission of a crypto packet is in flight at once.
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(ianswett): Instead of handling all crypto packets special,
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // only handle NULL encrypted packets in a special way.
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (HasCryptoHandshake(
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        unacked_packets_.GetTransmissionInfo(newest_transmission))) {
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      unacked_packets_.RemoveFromInFlight(newest_transmission);
48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unacked_packets_.RemoveFromInFlight(sequence_number);
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unacked_packets_.RemoveRetransmittability(sequence_number);
491d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
493d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool QuicSentPacketManager::IsUnacked(
494d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    QuicPacketSequenceNumber sequence_number) const {
495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return unacked_packets_.IsUnacked(sequence_number);
496d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
497d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
498d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool QuicSentPacketManager::HasUnackedPackets() const {
499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return unacked_packets_.HasUnackedPackets();
500d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
501d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
502d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)QuicPacketSequenceNumber
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciQuicSentPacketManager::GetLeastUnacked() const {
5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return unacked_packets_.GetLeastUnacked();
505d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicSentPacketManager::OnPacketSent(
508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number,
509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    QuicTime sent_time,
510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    QuicByteCount bytes,
511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TransmissionType transmission_type,
512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    HasRetransmittableData has_retransmittable_data) {
513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_LT(0u, sequence_number);
51403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(unacked_packets_.IsUnacked(sequence_number));
515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets.";
51603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (pending_timer_transmission_count_ > 0) {
51703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    --pending_timer_transmission_count_;
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (unacked_packets_.bytes_in_flight() == 0) {
521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // TODO(ianswett): Consider being less aggressive to force a new
522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // recent_min_rtt, likely by not discarding a relatively new sample.
523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DVLOG(1) << "Sampling a new recent min rtt within 2 samples. currently:"
524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << rtt_stats_.recent_min_rtt().ToMilliseconds() << "ms";
525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    rtt_stats_.SampleNewRecentMinRtt(kNumMinRttSamplesAfterQuiescence);
526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Only track packets as in flight that the send algorithm wants us to track.
529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const bool in_flight =
530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      send_algorithm_->OnPacketSent(sent_time,
531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    unacked_packets_.bytes_in_flight(),
532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    sequence_number,
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    bytes,
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    has_retransmittable_data);
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unacked_packets_.SetSent(sequence_number, sent_time, bytes, in_flight);
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (debug_delegate_ != NULL) {
5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    debug_delegate_->OnSentPacket(
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        sequence_number, sent_time, bytes, transmission_type);
540116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
541116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reset the retransmission timer anytime a pending packet is sent.
543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return in_flight;
544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::OnRetransmissionTimeout() {
547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(unacked_packets_.HasInFlightPackets());
54803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK_EQ(0u, pending_timer_transmission_count_);
549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Handshake retransmission, timer based loss detection, TLP, and RTO are
550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // implemented with a single alarm. The handshake alarm is set when the
551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // handshake has not completed, the loss alarm is set when the loss detection
552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // algorithm says to, and the TLP and  RTO alarms are set after that.
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The TLP alarm is always set to run for under an RTO.
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (GetRetransmissionMode()) {
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case HANDSHAKE_MODE:
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++stats_->crypto_retransmit_count;
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RetransmitCryptoPackets();
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case LOSS_MODE: {
560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ++stats_->loss_timeout_count;
561010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight();
562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      InvokeLossDetection(clock_->Now());
563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      MaybeInvokeCongestionEvent(false, bytes_in_flight);
564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
565010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case TLP_MODE:
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // If no tail loss probe can be sent, because there are no retransmittable
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // packets, execute a conventional RTO to abandon old packets.
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++stats_->tlp_count;
570f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ++consecutive_tlp_count_;
57103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      pending_timer_transmission_count_ = 1;
572f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // TLPs prefer sending new data instead of retransmitting data, so
573f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // give the connection a chance to write before completing the TLP.
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RTO_MODE:
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++stats_->rto_count;
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RetransmitAllPackets();
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicSentPacketManager::RetransmitCryptoPackets() {
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(ianswett): Typical TCP implementations only retransmit 5 times.
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  consecutive_crypto_retransmission_count_ =
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      min(kMaxHandshakeRetransmissionBackoffs,
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          consecutive_crypto_retransmission_count_ + 1);
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool packet_retransmitted = false;
5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked();
590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != unacked_packets_.end(); ++it, ++sequence_number) {
592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Only retransmit frames which are in flight, and therefore have been sent.
5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!it->in_flight || it->retransmittable_frames == NULL ||
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        it->retransmittable_frames->HasCryptoHandshake() != IS_HANDSHAKE) {
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    packet_retransmitted = true;
59823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION);
59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ++pending_timer_transmission_count_;
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(packet_retransmitted) << "No crypto packets found to retransmit.";
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
604f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() {
60503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (pending_timer_transmission_count_ == 0) {
606f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return false;
607f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked();
609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != unacked_packets_.end(); ++it, ++sequence_number) {
611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Only retransmit frames which are in flight, and therefore have been sent.
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!it->in_flight || it->retransmittable_frames == NULL) {
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
6156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!handshake_confirmed_) {
6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK_NE(IS_HANDSHAKE, it->retransmittable_frames->HasCryptoHandshake());
6176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MarkForRetransmission(sequence_number, TLP_RETRANSMISSION);
619f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return true;
620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DLOG(FATAL)
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    << "No retransmittable packets, so RetransmitOldestPacket failed.";
623f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return false;
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicSentPacketManager::RetransmitAllPackets() {
62746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DVLOG(1) << "RetransmitAllPackets() called with "
6281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           << unacked_packets_.GetNumUnackedPacketsDebugOnly()
6291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           << " unacked packets.";
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Request retransmission of all retransmittable packets when the RTO
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // fires, and let the congestion manager decide how many to send
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // immediately and the remaining packets will be queued.
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Abandon any non-retransmittable packets that are sufficiently old.
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool packets_retransmitted = false;
6351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked();
6361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
6371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != unacked_packets_.end(); ++it, ++sequence_number) {
6381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (it->retransmittable_frames != NULL) {
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      packets_retransmitted = true;
640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      MarkForRetransmission(sequence_number, RTO_RETRANSMISSION);
641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.RemoveFromInFlight(sequence_number);
643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  send_algorithm_->OnRetransmissionTimeout(packets_retransmitted);
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (packets_retransmitted) {
648116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (consecutive_rto_count_ == 0) {
649116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      first_rto_transmission_ = unacked_packets_.largest_sent_packet() + 1;
650116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ++consecutive_rto_count_;
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (network_change_visitor_ != NULL) {
6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    network_change_visitor_->OnCongestionWindowChange(GetCongestionWindow());
6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicSentPacketManager::RetransmissionTimeoutMode
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    QuicSentPacketManager::GetRetransmissionMode() const {
661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(unacked_packets_.HasInFlightPackets());
6626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!handshake_confirmed_ && unacked_packets_.HasPendingCryptoPackets()) {
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return HANDSHAKE_MODE;
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) {
666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return LOSS_MODE;
667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (consecutive_tlp_count_ < max_tail_loss_probes_) {
669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (unacked_packets_.HasUnackedRetransmittableFrames()) {
670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return TLP_MODE;
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return RTO_MODE;
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame(
677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const QuicCongestionFeedbackFrame& frame,
678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const QuicTime& feedback_receive_time) {
679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  send_algorithm_->OnIncomingQuicCongestionFeedbackFrame(
680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      frame, feedback_receive_time);
681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
682a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SequenceNumberSet lost_packets =
685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      loss_algorithm_->DetectLostPackets(unacked_packets_,
686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         time,
68703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                         unacked_packets_.largest_observed(),
688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         rtt_stats_);
689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (SequenceNumberSet::const_iterator it = lost_packets.begin();
690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != lost_packets.end(); ++it) {
691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuicPacketSequenceNumber sequence_number = *it;
692010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const TransmissionInfo& transmission_info =
693010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        unacked_packets_.GetTransmissionInfo(sequence_number);
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TODO(ianswett): If it's expected the FEC packet may repair the loss, it
6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // should be recorded as a loss to the send algorithm, but not retransmitted
6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // until it's known whether the FEC packet arrived.
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ++stats_->packets_lost;
6981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    packets_lost_.push_back(make_pair(sequence_number, transmission_info));
699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DVLOG(1) << ENDPOINT << "Lost packet " << sequence_number;
700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
701010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (transmission_info.retransmittable_frames != NULL) {
70223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      MarkForRetransmission(sequence_number, LOSS_RETRANSMISSION);
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Since we will not retransmit this, we need to remove it from
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // unacked_packets_.   This is either the current transmission of
706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // a packet whose previous transmission has been acked, a packet that has
707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // been TLP retransmitted, or an FEC packet.
708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      unacked_packets_.RemoveFromInFlight(sequence_number);
709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
713010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool QuicSentPacketManager::MaybeUpdateRTT(
7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const QuicAckFrame& ack_frame,
715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const QuicTime& ack_receive_time) {
7165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!unacked_packets_.IsUnacked(ack_frame.largest_observed)) {
717010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We calculate the RTT based on the highest ACKed sequence number, the lower
720a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // sequence numbers will include the ACK aggregation delay.
721010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TransmissionInfo& transmission_info =
7225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      unacked_packets_.GetTransmissionInfo(ack_frame.largest_observed);
7231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Ensure the packet has a valid sent time.
724a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (transmission_info.sent_time == QuicTime::Zero()) {
7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(DFATAL) << "Acked packet has zero sent time, largest_observed:"
7261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                << ack_frame.largest_observed;
727010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicTime::Delta send_delta =
731a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ack_receive_time.Subtract(transmission_info.sent_time);
7325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  rtt_stats_.UpdateRtt(
7335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      send_delta, ack_frame.delta_time_largest_observed, ack_receive_time);
734010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)QuicTime::Delta QuicSentPacketManager::TimeUntilSend(
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    QuicTime now,
739e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    HasRetransmittableData retransmittable) {
740e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // The TLP logic is entirely contained within QuicSentPacketManager, so the
741e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // send algorithm does not need to be consulted.
74203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (pending_timer_transmission_count_ > 0) {
743e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return QuicTime::Delta::Zero();
744e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
745010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return send_algorithm_->TimeUntilSend(
746010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      now, unacked_packets_.bytes_in_flight(), retransmittable);
747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Uses a 25ms delayed ack timer. Also helps with better signaling
7506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// in low-bandwidth (< ~384 kbps), where an ack is sent per packet.
751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Ensures that the Delayed Ack timer is always set to a value lesser
752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// than the retransmission timer's minimum value (MinRTO). We want the
753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// delayed ack to get back to the QUIC peer before the sender's
754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// retransmission timer triggers.  Since we do not know the
755a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// reverse-path one-way delay, we assume equal delays for forward and
756a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// reverse paths, and ensure that the timer is set to less than half
757a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// of the MinRTO.
758a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// There may be a value in making this delay adaptive with the help of
759a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// the sender and a signaling mechanism -- if the sender uses a
760a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// different MinRTO, we may get spurious retransmissions. May not have
761a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// any benefits, but if the delayed ack becomes a significant source
762a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// of (likely, tail) latency, then consider such a mechanism.
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const {
76403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return QuicTime::Delta::FromMilliseconds(min(kMaxDelayedAckTimeMs,
7656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                               kMinRetransmissionTimeMs/2));
766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
767a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
769f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Don't set the timer if there are no packets in flight or we've already
770f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // queued a tlp transmission and it hasn't been sent yet.
77103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!unacked_packets_.HasInFlightPackets() ||
77203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      pending_timer_transmission_count_ > 0) {
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return QuicTime::Zero();
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (GetRetransmissionMode()) {
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case HANDSHAKE_MODE:
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay());
778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case LOSS_MODE:
779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return loss_algorithm_->GetLossTimeout();
7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case TLP_MODE: {
7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // TODO(ianswett): When CWND is available, it would be preferable to
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // set the timer based on the earliest retransmittable packet.
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Base the updated timer on the send time of the last packet.
784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime();
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay());
786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Ensure the TLP timer never gets set to a time in the past.
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return QuicTime::Max(clock_->ApproximateNow(), tlp_time);
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RTO_MODE: {
790cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // The RTO is based on the first outstanding packet.
791a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const QuicTime sent_time =
792cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          unacked_packets_.GetFirstInFlightPacketSentTime();
793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      QuicTime rto_time = sent_time.Add(GetRetransmissionDelay());
794116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Wait for TLP packets to be acked before an RTO fires.
795116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      QuicTime tlp_time =
796116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          unacked_packets_.GetLastPacketSentTime().Add(GetTailLossProbeDelay());
797116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return QuicTime::Max(tlp_time, rto_time);
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(false);
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return QuicTime::Zero();
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const {
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This is equivalent to the TailLossProbeDelay, but slightly more aggressive
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // because crypto handshake messages don't incur a delayed ack time.
8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 delay_ms = max<int64>(kMinHandshakeTimeoutMs,
8090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              1.5 * rtt_stats_.SmoothedRtt().ToMilliseconds());
8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return QuicTime::Delta::FromMilliseconds(
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delay_ms << consecutive_crypto_retransmission_count_);
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
8150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicTime::Delta srtt = rtt_stats_.SmoothedRtt();
816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!unacked_packets_.HasMultipleInFlightPackets()) {
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return QuicTime::Delta::Max(
8186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        srtt.Multiply(2), srtt.Multiply(1.5)
8196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          .Add(QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2)));
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return QuicTime::Delta::FromMilliseconds(
8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      max(kMinTailLossProbeTimeoutMs,
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          static_cast<int64>(2 * srtt.ToMilliseconds())));
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
825a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
827a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay();
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(rch): This code should move to |send_algorithm_|.
829a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (retransmission_delay.IsZero()) {
830a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // We are in the initial state, use default timeout values.
831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    retransmission_delay =
832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) {
8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    retransmission_delay =
8355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs);
836a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
838a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Calculate exponential back off.
8395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  retransmission_delay = retransmission_delay.Multiply(
8405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      1 << min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
841a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
842a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
843a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
845a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return retransmission_delay;
846a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
847a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst RttStats* QuicSentPacketManager::GetRttStats() const {
8490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return &rtt_stats_;
850a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
851a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
852a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)QuicBandwidth QuicSentPacketManager::BandwidthEstimate() const {
853a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return send_algorithm_->BandwidthEstimate();
854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
855a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
856116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool QuicSentPacketManager::HasReliableBandwidthEstimate() const {
857116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return send_algorithm_->HasReliableBandwidthEstimate();
858116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
859116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
86003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const QuicSustainedBandwidthRecorder&
86103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)QuicSentPacketManager::SustainedBandwidthRecorder() const {
86203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return sustained_bandwidth_recorder_;
86303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
86403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
865a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)QuicByteCount QuicSentPacketManager::GetCongestionWindow() const {
866a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return send_algorithm_->GetCongestionWindow();
867a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
868a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
869116680a4aac90f2aa7413d9095a592090648e557Ben MurdochQuicByteCount QuicSentPacketManager::GetSlowStartThreshold() const {
870116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return send_algorithm_->GetSlowStartThreshold();
871116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
872116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
87303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void QuicSentPacketManager::EnablePacing() {
874a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (using_pacing_) {
875a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
876a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
877a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
87846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Set up a pacing sender with a 5 millisecond alarm granularity.
879a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  using_pacing_ = true;
880a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  send_algorithm_.reset(
881a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new PacingSender(send_algorithm_.release(),
882116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       QuicTime::Delta::FromMilliseconds(5),
883116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       kInitialUnpacedBurst));
884a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
885a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
886d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace net
887