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