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