15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_connection.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <string.h> 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <sys/types.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <iterator> 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <limits> 1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <memory> 1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <set> 1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <utility> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/debug/stack_trace.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/base/net_errors.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_decrypter.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_encrypter.h" 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/quic/iovector.h" 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/quic/quic_bandwidth.h" 240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/quic/quic_config.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/quic/quic_fec_group.h" 26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_flags.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_utils.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using base::StringPiece; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::hash_map; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::hash_set; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::list; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::make_pair; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::max; 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using std::min; 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using std::numeric_limits; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::set; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::string; 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using std::vector; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class QuicDecrypter; 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class QuicEncrypter; 4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The largest gap in packets we'll accept without closing the connection. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This will likely have to be tuned. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const QuicPacketSequenceNumber kMaxPacketGap = 5000; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Limit the number of FEC groups to two. If we get enough out of order packets 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// that this becomes limiting, we can revisit. 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const size_t kMaxFecGroups = 2; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Limit the number of undecryptable packets we buffer in 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// expectation of the CHLO/SHLO arriving. 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const size_t kMaxUndecryptablePackets = 10; 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Maximum number of acks received before sending an ack in response. 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst size_t kMaxPacketsReceivedBeforeAckSend = 20; 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delta <= kMaxPacketGap; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// An alarm that is scheduled to send an ack if a timeout occurs. 69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass AckAlarm : public QuicAlarm::Delegate { 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public: 71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch explicit AckAlarm(QuicConnection* connection) 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : connection_(connection) { 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual QuicTime OnAlarm() OVERRIDE { 76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch connection_->SendAck(); 77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return QuicTime::Zero(); 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private: 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch QuicConnection* connection_; 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(AckAlarm); 84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// This alarm will be scheduled any time a data-bearing packet is sent out. 87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// When the alarm goes off, the connection checks to see if the oldest packets 88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// have been acked, and retransmit them if they have not. 89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass RetransmissionAlarm : public QuicAlarm::Delegate { 90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public: 91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch explicit RetransmissionAlarm(QuicConnection* connection) 92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : connection_(connection) { 93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual QuicTime OnAlarm() OVERRIDE { 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) connection_->OnRetransmissionTimeout(); 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return QuicTime::Zero(); 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private: 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) QuicConnection* connection_; 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(RetransmissionAlarm); 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// An alarm that is scheduled when the sent scheduler requires a 107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// a delay before sending packets and fires when the packet may be sent. 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass SendAlarm : public QuicAlarm::Delegate { 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public: 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch explicit SendAlarm(QuicConnection* connection) 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : connection_(connection) { 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual QuicTime OnAlarm() OVERRIDE { 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) connection_->WriteIfNotBlocked(); 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Never reschedule the alarm, since CanWrite does that. 117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return QuicTime::Zero(); 118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private: 121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch QuicConnection* connection_; 1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(SendAlarm); 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass TimeoutAlarm : public QuicAlarm::Delegate { 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public: 128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch explicit TimeoutAlarm(QuicConnection* connection) 129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : connection_(connection) { 130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual QuicTime OnAlarm() OVERRIDE { 133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch connection_->CheckForTimeout(); 134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Never reschedule the alarm, since CheckForTimeout does that. 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return QuicTime::Zero(); 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private: 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch QuicConnection* connection_; 1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(TimeoutAlarm); 1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass PingAlarm : public QuicAlarm::Delegate { 1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public: 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch explicit PingAlarm(QuicConnection* connection) 1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : connection_(connection) { 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual QuicTime OnAlarm() OVERRIDE { 1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch connection_->SendPing(); 1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return QuicTime::Zero(); 1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private: 1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicConnection* connection_; 1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(PingAlarm); 159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicConnection::QueuedPacket::QueuedPacket(SerializedPacket packet, 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EncryptionLevel level) 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : serialized_packet(packet), 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) encryption_level(level), 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transmission_type(NOT_RETRANSMISSION), 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci original_sequence_number(0) { 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciQuicConnection::QueuedPacket::QueuedPacket( 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SerializedPacket packet, 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EncryptionLevel level, 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TransmissionType transmission_type, 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci QuicPacketSequenceNumber original_sequence_number) 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : serialized_packet(packet), 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci encryption_level(level), 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transmission_type(transmission_type), 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci original_sequence_number(original_sequence_number) { 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define ENDPOINT (is_server_ ? "Server: " : " Client: ") 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicConnection::QuicConnection(QuicConnectionId connection_id, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPEndPoint address, 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConnectionHelperInterface* helper, 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const PacketWriterFactory& writer_factory, 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool owns_writer, 189558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch bool is_server, 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const QuicVersionVector& supported_versions) 191e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : framer_(supported_versions, helper->GetClock()->ApproximateNow(), 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_server), 193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) helper_(helper), 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) writer_(writer_factory.Create(this)), 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) owns_writer_(owns_writer), 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) encryption_level_(ENCRYPTION_NONE), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clock_(helper->GetClock()), 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) random_generator_(helper->GetRandomGenerator()), 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection_id_(connection_id), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) peer_address_(address), 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) migrating_peer_port_(0), 2025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu last_packet_revived_(false), 2035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu last_size_(0), 2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu last_decrypted_packet_level_(ENCRYPTION_NONE), 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) largest_seen_packet_with_ack_(0), 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) largest_seen_packet_with_stop_waiting_(0), 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) pending_version_negotiation_packet_(false), 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci received_packet_manager_(&stats_), 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ack_queued_(false), 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci num_packets_received_since_last_ack_sent_(0), 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_waiting_count_(0), 212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), 213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), 214ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch send_alarm_(helper->CreateAlarm(new SendAlarm(this))), 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), 216ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), 2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ping_alarm_(helper->CreateAlarm(new PingAlarm(this))), 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packet_generator_(connection_id_, &framer_, random_generator_, this), 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) idle_network_timeout_( 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) overall_connection_timeout_(QuicTime::Delta::Infinite()), 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_of_last_received_packet_( 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FLAGS_quic_timeouts_require_activity 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? QuicTime::Zero() : clock_->ApproximateNow()), 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_of_last_sent_new_packet_( 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FLAGS_quic_timeouts_require_activity 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? QuicTime::Zero() : clock_->ApproximateNow()), 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sequence_number_of_last_sent_packet_(0), 229e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch sent_packet_manager_( 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) is_server, clock_, &stats_, 23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic, 232e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch FLAGS_quic_use_time_loss_detection ? kTime : kNack), 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) version_negotiation_state_(START_NEGOTIATION), 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_server_(is_server), 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connected_(true), 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) peer_ip_changed_(false), 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) peer_port_changed_(false), 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self_ip_changed_(false), 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self_port_changed_(false) { 2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if 0 2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // TODO(rtenneti): Should we enable this code in chromium? 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!is_server_) { 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Pacing will be enabled if the client negotiates it. 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sent_packet_manager_.MaybeEnablePacing(); 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Created connection with connection_id: " 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << connection_id; 249ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framer_.set_visitor(this); 2512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch framer_.set_received_entropy_calculator(&received_packet_manager_); 2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch stats_.connection_creation_time = clock_->ApproximateNow(); 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) sent_packet_manager_.set_network_change_visitor(this); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicConnection::~QuicConnection() { 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (owns_writer_) { 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delete writer_; 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) STLDeleteElements(&undecryptable_packets_); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteValues(&group_map_); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (QueuedPacketList::iterator it = queued_packets_.begin(); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != queued_packets_.end(); ++it) { 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delete it->serialized_packet.retransmittable_frames; 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delete it->serialized_packet.packet; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void QuicConnection::SetFromConfig(const QuicConfig& config) { 2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) SetIdleNetworkTimeout(config.idle_connection_state_lifetime()); 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sent_packet_manager_.SetFromConfig(config); 2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicConnection::SelectMutualVersion( 275558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const QuicVersionVector& available_versions) { 276558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Try to find the highest mutual version by iterating over supported 277558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // versions, starting with the highest, and breaking out of the loop once we 278558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // find a matching version in the provided available_versions vector. 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const QuicVersionVector& supported_versions = framer_.supported_versions(); 2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (size_t i = 0; i < supported_versions.size(); ++i) { 2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const QuicVersion& version = supported_versions[i]; 282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (std::find(available_versions.begin(), available_versions.end(), 283558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch version) != available_versions.end()) { 284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch framer_.set_version(version); 285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return true; 286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::OnError(QuicFramer* framer) { 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Packets that we cannot decrypt are dropped. 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(rch): add stats to measure this. 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!connected_ || framer->error() == QUIC_DECRYPTION_FAILURE) { 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SendConnectionCloseWithDetails(framer->error(), framer->detailed_error()); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicConnection::OnPacket() { 302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(last_stream_frames_.empty() && 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_ack_frames_.empty() && 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_congestion_frames_.empty() && 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_stop_waiting_frames_.empty() && 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_rst_frames_.empty() && 307ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_goaway_frames_.empty() && 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_window_update_frames_.empty() && 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_blocked_frames_.empty() && 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_ping_frames_.empty() && 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_close_frames_.empty()); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicConnection::OnPublicResetPacket( 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const QuicPublicResetPacket& packet) { 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnPublicResetPacket(packet); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseConnection(QUIC_PUBLIC_RESET, true); 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Connection " << connection_id() 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << " closed via QUIC_PUBLIC_RESET from peer."; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool QuicConnection::OnProtocolVersionMismatch(QuicVersion received_version) { 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Received packet with mismatched version " 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << received_version; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(satyamshekhar): Implement no server state in this mode. 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_server_) { 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(DFATAL) << ENDPOINT << "Framer called OnProtocolVersionMismatch. " 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Closing connection."; 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseConnection(QUIC_INTERNAL_ERROR, false); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_NE(version(), received_version); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnProtocolVersionMismatch(received_version); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (version_negotiation_state_) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case START_NEGOTIATION: 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!framer_.IsSupportedVersion(received_version)) { 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendVersionNegotiationPacket(); 345ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch version_negotiation_state_ = NEGOTIATION_IN_PROGRESS; 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 350ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case NEGOTIATION_IN_PROGRESS: 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!framer_.IsSupportedVersion(received_version)) { 3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SendVersionNegotiationPacket(); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case NEGOTIATED_VERSION: 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Might be old packets that were sent by the client before the version 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // was negotiated. Drop these. 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(false); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) version_negotiation_state_ = NEGOTIATED_VERSION; 367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) visitor_->OnSuccessfulVersionNegotiation(received_version); 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (debug_visitor_.get() != NULL) { 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci debug_visitor_->OnSuccessfulVersionNegotiation(received_version); 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "version negotiated " << received_version; 372558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 373558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Store the new version. 374558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch framer_.set_version(received_version); 375558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(satyamshekhar): Store the sequence number of this packet and close the 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // connection if we ever received a packet with incorrect version and whose 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sequence number is greater. 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Handles version negotiation for client connection. 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicConnection::OnVersionNegotiationPacket( 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const QuicVersionNegotiationPacket& packet) { 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_server_) { 38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(DFATAL) << ENDPOINT << "Framer parsed VersionNegotiationPacket." 38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << " Closing connection."; 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseConnection(QUIC_INTERNAL_ERROR, false); 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnVersionNegotiationPacket(packet); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 395ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (version_negotiation_state_ != START_NEGOTIATION) { 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Possibly a duplicate version negotiation packet. 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (std::find(packet.versions.begin(), 4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch packet.versions.end(), version()) != 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) packet.versions.end()) { 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DLOG(WARNING) << ENDPOINT << "The server already supports our version. " 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << "It should have accepted our connection."; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Just drop the connection. 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, false); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!SelectMutualVersion(packet.versions)) { 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendConnectionCloseWithDetails(QUIC_INVALID_VERSION, 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "no common version found"); 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DVLOG(1) << ENDPOINT 41703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << "Negotiated version: " << QuicVersionToString(version()); 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) server_supported_versions_ = packet.versions; 419ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch version_negotiation_state_ = NEGOTIATION_IN_PROGRESS; 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::OnRevivedPacket() { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicConnection::OnUnauthenticatedPublicHeader( 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const QuicPacketPublicHeader& header) { 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) { 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid QuicConnection::OnDecryptedPacket(EncryptionLevel level) { 4365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu last_decrypted_packet_level_ = level; 4375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnPacketHeader(header); 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!ProcessValidatedPacket()) { 44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Will be decrement below if we fall through to return true; 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++stats_.packets_dropped; 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (header.public_header.connection_id != connection_id_) { 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Ignoring packet from unexpected ConnectionId: " 453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << header.public_header.connection_id << " instead of " 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << connection_id_; 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) debug_visitor_->OnIncorrectConnectionId( 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) header.public_header.connection_id); 4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Near(header.packet_sequence_number, 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_header_.packet_sequence_number)) { 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Packet " << header.packet_sequence_number 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " out of bounds. Discarding"; 46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER, 46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "Packet sequence number out of bounds"); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this packet has already been seen, or that the sender 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // has told us will not be retransmitted, then stop processing the packet. 4732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!received_packet_manager_.IsAwaitingPacket( 4742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch header.packet_sequence_number)) { 4755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DVLOG(1) << ENDPOINT << "Packet " << header.packet_sequence_number 4765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << " no longer being waited for. Discarding."; 4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) debug_visitor_->OnDuplicatePacket(header.packet_sequence_number); 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (version_negotiation_state_ != NEGOTIATED_VERSION) { 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_server_) { 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!header.public_header.version_flag) { 4865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DLOG(WARNING) << ENDPOINT << "Packet " << header.packet_sequence_number 4875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << " without version flag before version negotiated."; 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Packets should have the version flag till version negotiation is 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // done. 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseConnection(QUIC_INVALID_VERSION, false); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(1u, header.public_header.versions.size()); 4947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_EQ(header.public_header.versions[0], version()); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) version_negotiation_state_ = NEGOTIATED_VERSION; 496d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) visitor_->OnSuccessfulVersionNegotiation(version()); 4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (debug_visitor_.get() != NULL) { 4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci debug_visitor_->OnSuccessfulVersionNegotiation(version()); 4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!header.public_header.version_flag); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the client gets a packet without the version flag from the server 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it should stop sending version since the version negotiation is done. 505f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packet_generator_.StopSendingVersion(); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) version_negotiation_state_ = NEGOTIATED_VERSION; 507d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) visitor_->OnSuccessfulVersionNegotiation(version()); 5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (debug_visitor_.get() != NULL) { 5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci debug_visitor_->OnSuccessfulVersionNegotiation(version()); 5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --stats_.packets_dropped; 51790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Received packet header: " << header; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_header_ = header; 519ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DCHECK(connected_); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::OnFecProtectedPayload(StringPiece payload) { 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group); 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(0u, last_header_.fec_group); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicFecGroup* group = GetFecGroup(); 52790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (group != NULL) { 528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) group->Update(last_decrypted_packet_level_, last_header_, payload); 52990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) { 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(connected_); 5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnStreamFrame(frame); 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (frame.stream_id != kCryptoStreamId && 5385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu last_decrypted_packet_level_ == ENCRYPTION_NONE) { 5395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DLOG(WARNING) << ENDPOINT 5405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << "Received an unencrypted data frame: closing connection"; 5415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SendConnectionClose(QUIC_UNENCRYPTED_STREAM_DATA); 5425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 5435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_stream_frames_.push_back(frame); 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) { 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(connected_); 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnAckFrame(incoming_ack); 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 55390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DVLOG(1) << ENDPOINT << "OnAckFrame: " << incoming_ack; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_header_.packet_sequence_number <= largest_seen_packet_with_ack_) { 556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Received an old ack frame: ignoring"; 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ValidateAckFrame(incoming_ack)) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendConnectionClose(QUIC_INVALID_ACK_DATA); 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 564d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 565ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_ack_frames_.push_back(incoming_ack); 566ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return connected_; 567ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 568ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 569ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) { 570ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch largest_seen_packet_with_ack_ = last_header_.packet_sequence_number; 5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sent_packet_manager_.OnIncomingAck(incoming_ack, 572e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch time_of_last_received_packet_); 57303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) sent_entropy_manager_.ClearEntropyBefore( 57403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) sent_packet_manager_.least_packet_awaited_by_peer() - 1); 575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (sent_packet_manager_.HasPendingRetransmissions()) { 576a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WriteIfNotBlocked(); 577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 579e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Always reset the retransmission alarm when an ack comes in, since we now 580e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // have a better estimate of the current rtt than when it was set. 58103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime retransmission_time = sent_packet_manager_.GetRetransmissionTime(); 58203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) retransmission_alarm_->Update(retransmission_time, 58303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime::Delta::FromMilliseconds(1)); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicConnection::ProcessStopWaitingFrame( 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const QuicStopWaitingFrame& stop_waiting) { 588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) largest_seen_packet_with_stop_waiting_ = last_header_.packet_sequence_number; 589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) received_packet_manager_.UpdatePacketInformationSentByPeer(stop_waiting); 590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Possibly close any FecGroups which are now irrelevant. 591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseFecGroupsBefore(stop_waiting.least_unacked + 1); 592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicConnection::OnCongestionFeedbackFrame( 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const QuicCongestionFeedbackFrame& feedback) { 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(connected_); 5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnCongestionFeedbackFrame(feedback); 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 600ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_congestion_frames_.push_back(feedback); 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return connected_; 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) { 605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(connected_); 606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (last_header_.packet_sequence_number <= 608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) largest_seen_packet_with_stop_waiting_) { 609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Received an old stop waiting frame: ignoring"; 610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!ValidateStopWaitingFrame(frame)) { 614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendConnectionClose(QUIC_INVALID_STOP_WAITING_DATA); 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) debug_visitor_->OnStopWaitingFrame(frame); 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_stop_waiting_frames_.push_back(frame); 623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return connected_; 624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool QuicConnection::OnPingFrame(const QuicPingFrame& frame) { 6270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(connected_); 6285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 6290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch debug_visitor_->OnPingFrame(frame); 6300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_ping_frames_.push_back(frame); 6320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return true; 6330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 6340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) { 6365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (incoming_ack.largest_observed > packet_generator_.sequence_number()) { 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Peer's observed unsent packet:" 6385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << incoming_ack.largest_observed << " vs " 639f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << packet_generator_.sequence_number(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We got an error for data we have not sent. Error out. 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (incoming_ack.largest_observed < sent_packet_manager_.largest_observed()) { 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Peer's largest_observed packet decreased:" 6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << incoming_ack.largest_observed << " vs " 64703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << sent_packet_manager_.largest_observed(); 648558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // A new ack has a diminished largest_observed value. Error out. 649558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // If this was an old packet, we wouldn't even have checked. 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!incoming_ack.missing_packets.empty() && 6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *incoming_ack.missing_packets.rbegin() > incoming_ack.largest_observed) { 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: " 6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << *incoming_ack.missing_packets.rbegin() 6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " which is greater than largest observed: " 6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << incoming_ack.largest_observed; 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!incoming_ack.missing_packets.empty() && 6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *incoming_ack.missing_packets.begin() < 66403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) sent_packet_manager_.least_packet_awaited_by_peer()) { 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: " 6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << *incoming_ack.missing_packets.begin() 6673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " which is smaller than least_packet_awaited_by_peer_: " 66803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << sent_packet_manager_.least_packet_awaited_by_peer(); 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!sent_entropy_manager_.IsValidEntropy( 6735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) incoming_ack.largest_observed, 6745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) incoming_ack.missing_packets, 6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) incoming_ack.entropy_hash)) { 676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Peer sent invalid entropy."; 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (SequenceNumberSet::const_iterator iter = 6815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) incoming_ack.revived_packets.begin(); 6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) iter != incoming_ack.revived_packets.end(); ++iter) { 6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ContainsKey(incoming_ack.missing_packets, *iter)) { 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DLOG(ERROR) << ENDPOINT 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Peer specified revived packet which was not missing."; 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool QuicConnection::ValidateStopWaitingFrame( 693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const QuicStopWaitingFrame& stop_waiting) { 694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (stop_waiting.least_unacked < 695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) received_packet_manager_.peer_least_packet_awaiting_ack()) { 696a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: " 697a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << stop_waiting.least_unacked << " vs " 698a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << received_packet_manager_.peer_least_packet_awaiting_ack(); 699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We never process old ack frames, so this number should only increase. 700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 702a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 703a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (stop_waiting.least_unacked > 704a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_header_.packet_sequence_number) { 705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Peer sent least_unacked:" 706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << stop_waiting.least_unacked 707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " greater than the enclosing packet sequence number:" 708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << last_header_.packet_sequence_number; 709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::OnFecData(const QuicFecData& fec) { 716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_EQ(IN_FEC_GROUP, last_header_.is_in_fec_group); 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(0u, last_header_.fec_group); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicFecGroup* group = GetFecGroup(); 71990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (group != NULL) { 720010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) group->UpdateFec(last_decrypted_packet_level_, 721010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) last_header_.packet_sequence_number, fec); 72290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) { 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(connected_); 7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnRstStreamFrame(frame); 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Stream reset with error " 731a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << QuicUtils::StreamErrorToString(frame.error_code); 732ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_rst_frames_.push_back(frame); 733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return connected_; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicConnection::OnConnectionCloseFrame( 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuicConnectionCloseFrame& frame) { 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(connected_); 7395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnConnectionCloseFrame(frame); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 742a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Connection " << connection_id() 743a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " closed with error " 744a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << QuicUtils::ErrorToString(frame.error_code) 745a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " " << frame.error_details; 7460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) last_close_frames_.push_back(frame); 7470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return connected_; 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) { 751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(connected_); 7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 753f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) debug_visitor_->OnGoAwayFrame(frame); 754f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Go away received with error " 756a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << QuicUtils::ErrorToString(frame.error_code) 757a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " and reason:" << frame.reason_phrase; 758ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_goaway_frames_.push_back(frame); 759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return connected_; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 762a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) { 763a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(connected_); 7645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) debug_visitor_->OnWindowUpdateFrame(frame); 766f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 767a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << ENDPOINT << "WindowUpdate received for stream: " 768a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << frame.stream_id << " with byte offset: " << frame.byte_offset; 769a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_window_update_frames_.push_back(frame); 770a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return connected_; 771a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 772a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 773a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) { 774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(connected_); 7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 776f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) debug_visitor_->OnBlockedFrame(frame); 777f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Blocked frame received for stream: " 779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << frame.stream_id; 780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_blocked_frames_.push_back(frame); 781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return connected_; 782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::OnPacketComplete() { 78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Don't do anything if this packet closed the connection. 78690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!connected_) { 787ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ClearLastFrames(); 78890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 78990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 79090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << (last_packet_revived_ ? "Revived" : "Got") 792a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " packet " << last_header_.packet_sequence_number 7931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << " with " << last_stream_frames_.size()<< " stream frames " 7941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << last_ack_frames_.size() << " acks, " 795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << last_congestion_frames_.size() << " congestions, " 796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << last_stop_waiting_frames_.size() << " stop_waiting, " 7971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << last_rst_frames_.size() << " rsts, " 798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << last_goaway_frames_.size() << " goaways, " 799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << last_window_update_frames_.size() << " window updates, " 800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << last_blocked_frames_.size() << " blocked, " 8011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << last_ping_frames_.size() << " pings, " 802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << last_close_frames_.size() << " closes, " 8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << "for " << last_header_.public_header.connection_id; 8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++num_packets_received_since_last_ack_sent_; 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Call MaybeQueueAck() before recording the received packet, since we want 8085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // to trigger an ack if the newly received packet was previously missing. 8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MaybeQueueAck(); 8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Record received or revived packet to populate ack info correctly before 8125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // processing stream frames, since the processing may result in a response 8135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // packet with a bundled ack. 8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (last_packet_revived_) { 8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) received_packet_manager_.RecordPacketRevived( 8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_header_.packet_sequence_number); 8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) received_packet_manager_.RecordPacketReceived( 8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_size_, last_header_, time_of_last_received_packet_); 8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!last_stream_frames_.empty()) { 8235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu visitor_->OnStreamFrames(last_stream_frames_); 8245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 8255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < last_stream_frames_.size(); ++i) { 8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stats_.stream_bytes_received += 8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_stream_frames_[i].data.TotalBufferSize(); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 831a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Process window updates, blocked, stream resets, acks, then congestion 832a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // feedback. 833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!last_window_update_frames_.empty()) { 834a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) visitor_->OnWindowUpdateFrames(last_window_update_frames_); 835a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 836a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!last_blocked_frames_.empty()) { 837a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) visitor_->OnBlockedFrames(last_blocked_frames_); 838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 839ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = 0; i < last_goaway_frames_.size(); ++i) { 840ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch visitor_->OnGoAway(last_goaway_frames_[i]); 841ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 842ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = 0; i < last_rst_frames_.size(); ++i) { 843ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch visitor_->OnRstStream(last_rst_frames_[i]); 844ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 845ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = 0; i < last_ack_frames_.size(); ++i) { 846ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ProcessAckFrame(last_ack_frames_[i]); 847ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 848ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (size_t i = 0; i < last_congestion_frames_.size(); ++i) { 849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sent_packet_manager_.OnIncomingQuicCongestionFeedbackFrame( 850ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_congestion_frames_[i], time_of_last_received_packet_); 851ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 852a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; i < last_stop_waiting_frames_.size(); ++i) { 853a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessStopWaitingFrame(last_stop_waiting_frames_[i]); 854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 8550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!last_close_frames_.empty()) { 8560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CloseConnection(last_close_frames_[0].error_code, true); 8570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(!connected_); 8580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 859ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If there are new missing packets to report, send an ack immediately. 8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (received_packet_manager_.HasNewMissingPackets()) { 8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ack_queued_ = true; 8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ack_alarm_->Cancel(); 86468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 86568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 866a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateStopWaitingCount(); 867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 868ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ClearLastFrames(); 869ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 870ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicConnection::MaybeQueueAck() { 8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If the incoming packet was missing, send an ack immediately. 8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ack_queued_ = received_packet_manager_.IsMissing( 8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_header_.packet_sequence_number); 8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ack_queued_ && ShouldLastPacketInstigateAck()) { 8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ack_alarm_->IsSet()) { 8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ack_queued_ = true; 8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 880c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Send an ack much more quickly for crypto handshake packets. 881c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch QuicTime::Delta delayed_ack_time = sent_packet_manager_.DelayedAckTime(); 882c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (last_stream_frames_.size() == 1 && 883c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch last_stream_frames_[0].stream_id == kCryptoStreamId) { 884c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delayed_ack_time = QuicTime::Delta::Zero(); 885c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 886c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ack_alarm_->Set(clock_->ApproximateNow().Add(delayed_ack_time)); 8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "Ack timer set; next packet or timer will trigger ACK."; 8885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ack_queued_) { 8925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ack_alarm_->Cancel(); 8935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 896ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid QuicConnection::ClearLastFrames() { 8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_stream_frames_.clear(); 8981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_ack_frames_.clear(); 8991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_congestion_frames_.clear(); 9001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_stop_waiting_frames_.clear(); 9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_rst_frames_.clear(); 902ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch last_goaway_frames_.clear(); 903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_window_update_frames_.clear(); 904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) last_blocked_frames_.clear(); 9051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_ping_frames_.clear(); 9061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_close_frames_.clear(); 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicAckFrame* QuicConnection::CreateAckFrame() { 9102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch QuicAckFrame* outgoing_ack = new QuicAckFrame(); 9112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch received_packet_manager_.UpdateReceivedPacketInfo( 9125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outgoing_ack, clock_->ApproximateNow()); 9132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch DVLOG(1) << ENDPOINT << "Creating ack frame: " << *outgoing_ack; 9142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch return outgoing_ack; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicCongestionFeedbackFrame* QuicConnection::CreateFeedbackFrame() { 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new QuicCongestionFeedbackFrame(outgoing_congestion_feedback_); 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicStopWaitingFrame* QuicConnection::CreateStopWaitingFrame() { 922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicStopWaitingFrame stop_waiting; 923a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateStopWaiting(&stop_waiting); 924a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return new QuicStopWaitingFrame(stop_waiting); 925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 927a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool QuicConnection::ShouldLastPacketInstigateAck() const { 928ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!last_stream_frames_.empty() || 929ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch !last_goaway_frames_.empty() || 930a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !last_rst_frames_.empty() || 931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !last_window_update_frames_.empty() || 9321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !last_blocked_frames_.empty() || 9331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !last_ping_frames_.empty()) { 934ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 935ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 936ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 9375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!last_ack_frames_.empty() && last_ack_frames_.back().is_truncated) { 938a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 939ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 9401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Always send an ack every 20 packets in order to allow the peer to discard 9411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // information from the SentPacketManager and provide an RTT measurement. 9421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (num_packets_received_since_last_ack_sent_ >= 9431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kMaxPacketsReceivedBeforeAckSend) { 9441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 9451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 946ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 947ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 948ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 949a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicConnection::UpdateStopWaitingCount() { 950a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (last_ack_frames_.empty()) { 951a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 952a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 953a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 954a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the peer is still waiting for a packet that we are no longer planning to 955a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // send, send an ack to raise the high water mark. 9565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!last_ack_frames_.back().missing_packets.empty() && 9575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetLeastUnacked() > *last_ack_frames_.back().missing_packets.begin()) { 958a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++stop_waiting_count_; 959a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 960a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_waiting_count_ = 0; 961a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 962a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 963a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicPacketSequenceNumber QuicConnection::GetLeastUnacked() const { 9651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return sent_packet_manager_.GetLeastUnacked(); 9665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 96768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicConnection::MaybeSendInResponseToPacket() { 9695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!connected_) { 9705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 9715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 972a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedPacketBundler bundler(this, ack_queued_ ? SEND_ACK : NO_ACK); 9733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Now that we have received an ack, we might be able to send packets which 9755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // are queued locally, or drain streams which are blocked. 97646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (CanWrite(HAS_RETRANSMITTABLE_DATA)) { 97746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OnCanWrite(); 978ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicConnection::SendVersionNegotiationPacket() { 9825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(alyssar): implement zero server state negotiation. 9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_version_negotiation_packet_ = true; 9845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (writer_->IsWriteBlocked()) { 9855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visitor_->OnWriteBlocked(); 9865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 98803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Sending version negotiation packet: {" 98903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << QuicVersionVectorToString(framer_.supported_versions()) << "}"; 9904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<QuicEncryptedPacket> version_packet( 991f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packet_generator_.SerializeVersionNegotiationPacket( 9921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) framer_.supported_versions())); 9935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WriteResult result = writer_->WritePacket( 9945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_packet->data(), version_packet->length(), 9955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self_address().address(), peer_address()); 9965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (result.status == WRITE_STATUS_ERROR) { 9984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We can't send an error as the socket is presumably borked. 9994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CloseConnection(QUIC_PACKET_WRITE_ERROR, false); 10005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 10014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result.status == WRITE_STATUS_BLOCKED) { 10035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visitor_->OnWriteBlocked(); 10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (writer_->IsWriteBlockedDataBuffered()) { 10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_version_negotiation_packet_ = false; 10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_version_negotiation_packet_ = false; 10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)QuicConsumedData QuicConnection::SendStreamData( 101458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicStreamId id, 10151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const IOVector& data, 101658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicStreamOffset offset, 101758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool fin, 1018f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FecProtection fec_protection, 101958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicAckNotifier::DelegateInterface* delegate) { 10201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!fin && data.Empty()) { 1021d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LOG(DFATAL) << "Attempt to send empty stream frame"; 1022d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 102368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 102468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // This notifier will be owned by the AckNotifierManager (or deleted below if 1025a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // no data or FIN was consumed). 1026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicAckNotifier* notifier = NULL; 1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (delegate) { 1028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) notifier = new QuicAckNotifier(delegate); 1029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1031c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Opportunistically bundle an ack with every outgoing packet. 10325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Particularly, we want to bundle with handshake packets since we don't know 10335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // which decrypter will be used on an ack packet following a handshake 10345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // packet (a handshake packet from client to server could result in a REJ or a 10355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // SHLO from the server, leading to two different decrypters at the server.) 10365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // 10375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // TODO(jri): Note that ConsumeData may cause a response packet to be sent. 10385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We may end up sending stale ack information if there are undecryptable 10395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // packets hanging around and/or there are revivable packets which may get 10405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // handled after this packet is sent. Change ScopedPacketBundler to do the 10415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // right thing: check ack_queued_, and then check undecryptable packets and 10425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // also if there is possibility of revival. Only bundle an ack if there's no 10435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // processing left that may cause received_info_ to change. 1044c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 104558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicConsumedData consumed_data = 1046f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packet_generator_.ConsumeData(id, data, offset, fin, fec_protection, 1047f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) notifier); 104858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1049a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (notifier && 1050a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (consumed_data.bytes_consumed == 0 && !consumed_data.fin_consumed)) { 1051a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // No data was consumed, nor was a fin consumed, so delete the notifier. 105258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) delete notifier; 105358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 105458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 105558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return consumed_data; 105658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 105758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::SendRstStream(QuicStreamId id, 10595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicRstStreamErrorCode error, 10605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicStreamOffset bytes_written) { 106168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Opportunistically bundle an ack with this outgoing packet. 1062a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 10630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch packet_generator_.AddControlFrame(QuicFrame(new QuicRstStreamFrame( 10640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch id, AdjustErrorForVersion(error, version()), bytes_written))); 10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1067a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicConnection::SendWindowUpdate(QuicStreamId id, 1068a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicStreamOffset byte_offset) { 1069a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Opportunistically bundle an ack with this outgoing packet. 1070a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 1071a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) packet_generator_.AddControlFrame( 1072a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicFrame(new QuicWindowUpdateFrame(id, byte_offset))); 1073a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 1074a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1075a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicConnection::SendBlocked(QuicStreamId id) { 1076a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Opportunistically bundle an ack with this outgoing packet. 1077a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 1078a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) packet_generator_.AddControlFrame(QuicFrame(new QuicBlockedFrame(id))); 1079a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 1080a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const QuicConnectionStats& QuicConnection::GetStats() { 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update rtt and estimated bandwidth. 10830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch stats_.min_rtt_us = 10840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch sent_packet_manager_.GetRttStats()->min_rtt().ToMicroseconds(); 10850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch stats_.srtt_us = 10860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch sent_packet_manager_.GetRttStats()->SmoothedRtt().ToMicroseconds(); 10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stats_.estimated_bandwidth = 1088a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sent_packet_manager_.BandwidthEstimate().ToBytesPerSecond(); 10890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch stats_.congestion_window = sent_packet_manager_.GetCongestionWindow(); 1090116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch stats_.slow_start_threshold = sent_packet_manager_.GetSlowStartThreshold(); 1091f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stats_.max_packet_size = packet_generator_.max_packet_length(); 10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return stats_; 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPEndPoint& peer_address, 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuicEncryptedPacket& packet) { 1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!connected_) { 1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 11015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnPacketReceived(self_address, peer_address, packet); 11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_packet_revived_ = false; 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_size_ = packet.length(); 110690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckForAddressMigration(self_address, peer_address); 11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stats_.bytes_received += packet.length(); 11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++stats_.packets_received; 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!framer_.ProcessPacket(packet)) { 11137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // If we are unable to decrypt this packet, it might be 11147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // because the CHLO or SHLO packet was lost. 11155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (framer_.error() == QUIC_DECRYPTION_FAILURE) { 11165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && 11175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) undecryptable_packets_.size() < kMaxUndecryptablePackets) { 11185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) QueueUndecryptablePacket(packet); 11195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (debug_visitor_.get() != NULL) { 11205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) debug_visitor_->OnUndecryptablePacket(); 11215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 11227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 11237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " 11247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << last_header_.packet_sequence_number; 1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 11275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 11285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ++stats_.packets_processed; 11297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) MaybeProcessUndecryptablePackets(); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeProcessRevivedPacket(); 11315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MaybeSendInResponseToPacket(); 11320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SetPingAlarm(); 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void QuicConnection::CheckForAddressMigration( 1136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const IPEndPoint& self_address, const IPEndPoint& peer_address) { 1137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) peer_ip_changed_ = false; 1138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) peer_port_changed_ = false; 1139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self_ip_changed_ = false; 1140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self_port_changed_ = false; 1141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (peer_address_.address().empty()) { 1143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) peer_address_ = peer_address; 1144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (self_address_.address().empty()) { 1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self_address_ = self_address; 1147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!peer_address.address().empty() && !peer_address_.address().empty()) { 1150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) peer_ip_changed_ = (peer_address.address() != peer_address_.address()); 1151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) peer_port_changed_ = (peer_address.port() != peer_address_.port()); 1152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Store in case we want to migrate connection in ProcessValidatedPacket. 1154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) migrating_peer_port_ = peer_address.port(); 1155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!self_address.address().empty() && !self_address_.address().empty()) { 1158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self_ip_changed_ = (self_address.address() != self_address_.address()); 1159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self_port_changed_ = (self_address.port() != self_address_.port()); 1160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicConnection::OnCanWrite() { 11645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!writer_->IsWriteBlocked()); 11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WriteQueuedPackets(); 116768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WritePendingRetransmissions(); 116868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sending queued packets may have caused the socket to become write blocked, 11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // or the congestion manager to prohibit sending. If we've sent everything 11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // we had queued and we're still not blocked, let the visitor know it can 11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // write more. 117346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) { 1174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 1175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { // Limit the scope of the bundler. 117868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Set |include_ack| to false in bundler; ack inclusion happens elsewhere. 1179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedPacketBundler bundler(this, NO_ACK); 1180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) visitor_->OnCanWrite(); 11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // After the visitor writes, it may have caused the socket to become write 1184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // blocked or the congestion manager to prohibit sending, so check again. 1185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (visitor_->WillingAndAbleToWrite() && 1186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !resume_writes_alarm_->IsSet() && 118746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CanWrite(HAS_RETRANSMITTABLE_DATA)) { 1188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We're not write blocked, but some stream didn't write out all of its 1189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // bytes. Register for 'immediate' resumption so we'll keep writing after 1190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // other connections and events have had a chance to use the thread. 1191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) resume_writes_alarm_->Set(clock_->ApproximateNow()); 1192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 11935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 11945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 11955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicConnection::WriteIfNotBlocked() { 11965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!writer_->IsWriteBlocked()) { 11975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnCanWrite(); 11985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 120190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool QuicConnection::ProcessValidatedPacket() { 12026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (peer_ip_changed_ || self_ip_changed_ || self_port_changed_) { 120390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SendConnectionCloseWithDetails( 120490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) QUIC_ERROR_MIGRATING_ADDRESS, 1205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "Neither IP address migration, nor self port migration are supported."); 120690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 120790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 12096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Peer port migration is supported, do it now if port has changed. 12106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (peer_port_changed_) { 1211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Peer's port changed from " 1212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << peer_address_.port() << " to " << migrating_peer_port_ 1213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << ", migrating connection."; 1214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) peer_address_ = IPEndPoint(peer_address_.address(), migrating_peer_port_); 1215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 121790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) time_of_last_received_packet_ = clock_->Now(); 121890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DVLOG(1) << ENDPOINT << "time of last received packet: " 121990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << time_of_last_received_packet_.ToDebuggingValue(); 1220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (is_server_ && encryption_level_ == ENCRYPTION_NONE && 1222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) last_size_ > packet_generator_.max_packet_length()) { 1223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packet_generator_.set_max_packet_length(last_size_); 1224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 122590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 122690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 122790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicConnection::WriteQueuedPackets() { 12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!writer_->IsWriteBlocked()); 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (pending_version_negotiation_packet_) { 12324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SendVersionNegotiationPacket(); 12334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 12344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QueuedPacketList::iterator packet_iterator = queued_packets_.begin(); 12361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci while (packet_iterator != queued_packets_.end() && 12371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WritePacket(&(*packet_iterator))) { 12381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet_iterator = queued_packets_.erase(packet_iterator); 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 124268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void QuicConnection::WritePendingRetransmissions() { 124368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Keep writing as long as there's a pending retransmission which can be 124468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // written. 124568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) while (sent_packet_manager_.HasPendingRetransmissions()) { 124668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const QuicSentPacketManager::PendingRetransmission pending = 124768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) sent_packet_manager_.NextPendingRetransmission(); 12481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) { 124968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 125068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 125268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Re-packetize the frames with a new sequence number for retransmission. 125368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Retransmitted data packets do not use FEC, even when it's enabled. 125468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Retransmitted packets use the same sequence number length as the 125568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // original. 12566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Flush the packet generator before making a new packet. 125768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(ianswett): Implement ReserializeAllFrames as a separate path that 125868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // does not require the creator to be flushed. 12596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) packet_generator_.FlushAllQueuedFrames(); 1260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SerializedPacket serialized_packet = packet_generator_.ReserializeAllFrames( 126168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending.retransmittable_frames.frames(), 126268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending.sequence_number_length); 126368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Retransmitting " << pending.sequence_number 1265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " as " << serialized_packet.sequence_number; 12661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SendOrQueuePacket( 12671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci QueuedPacket(serialized_packet, 12681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pending.retransmittable_frames.encryption_level(), 12691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pending.transmission_type, 12701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pending.sequence_number)); 127168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 127490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void QuicConnection::RetransmitUnackedPackets( 12751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TransmissionType retransmission_type) { 1276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sent_packet_manager_.RetransmitUnackedPackets(retransmission_type); 1277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 127868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) WriteIfNotBlocked(); 12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void QuicConnection::NeuterUnencryptedPackets() { 1282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sent_packet_manager_.NeuterUnencryptedPackets(); 12835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // This may have changed the retransmission timer, so re-arm it. 12845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu QuicTime retransmission_time = sent_packet_manager_.GetRetransmissionTime(); 128503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) retransmission_alarm_->Update(retransmission_time, 128603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime::Delta::FromMilliseconds(1)); 12875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 12885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 128968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool QuicConnection::ShouldGeneratePacket( 129068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TransmissionType transmission_type, 129168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) HasRetransmittableData retransmittable, 129268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IsHandshake handshake) { 129368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We should serialize handshake packets immediately to ensure that they 129468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // end up sent at the right encryption level. 129568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (handshake == IS_HANDSHAKE) { 129668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return true; 129768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 129868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 129946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return CanWrite(retransmittable); 130068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 130168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 130246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) { 13031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!connected_) { 13041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 13051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 13061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 13075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (writer_->IsWriteBlocked()) { 13085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visitor_->OnWriteBlocked(); 1309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 1310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicTime now = clock_->Now(); 1313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend( 131446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) now, retransmittable); 13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delay.IsInfinite()) { 131603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) send_alarm_->Cancel(); 131790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the scheduler requires a delay, then we can not send this packet now. 13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!delay.IsZero()) { 132203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) send_alarm_->Update(now.Add(delay), QuicTime::Delta::FromMilliseconds(1)); 1323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Delaying sending."; 13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 132603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) send_alarm_->Cancel(); 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool QuicConnection::WritePacket(QueuedPacket* packet) { 13311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!WritePacketInner(packet)) { 13321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 13331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 13341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delete packet->serialized_packet.retransmittable_frames; 13351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delete packet->serialized_packet.packet; 13361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->serialized_packet.retransmittable_frames = NULL; 13371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->serialized_packet.packet = NULL; 13381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 13391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 13401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 13411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool QuicConnection::WritePacketInner(QueuedPacket* packet) { 13421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ShouldDiscardPacket(*packet)) { 13435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ++stats_.packets_discarded; 134490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 134590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 13461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Connection close packets are encrypted and saved, so don't exit early. 13471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (writer_->IsWriteBlocked() && !IsConnectionClose(*packet)) { 13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci QuicPacketSequenceNumber sequence_number = 13521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->serialized_packet.sequence_number; 13534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Some encryption algorithms require the packet sequence numbers not be 13544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // repeated. 1355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_LE(sequence_number_of_last_sent_packet_, sequence_number); 1356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sequence_number_of_last_sent_packet_ = sequence_number; 13574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicEncryptedPacket* encrypted = framer_.EncryptPacket( 13591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->encryption_level, 13601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sequence_number, 13611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *packet->serialized_packet.packet); 13625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (encrypted == NULL) { 1363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LOG(DFATAL) << ENDPOINT << "Failed to encrypt packet number " 1364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << sequence_number; 13655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // CloseConnection does not send close packet, so no infinite loop here. 1366424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CloseConnection(QUIC_ENCRYPTION_FAILURE, false); 1367424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 1368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 13690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Connection close packets are eventually owned by TimeWaitListManager. 1371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Others are deleted at the end of this call. 13725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<QuicEncryptedPacket> encrypted_deleter; 13731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (IsConnectionClose(*packet)) { 1374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(connection_close_packet_.get() == NULL); 13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) connection_close_packet_.reset(encrypted); 13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This assures we won't try to write *forced* packets when blocked. 13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Return true to stop processing. 13785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (writer_->IsWriteBlocked()) { 13795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visitor_->OnWriteBlocked(); 13805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 1383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) encrypted_deleter.reset(encrypted); 1384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 138603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!FLAGS_quic_allow_oversized_packets_for_test) { 138703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK_LE(encrypted->length(), kMaxPacketSize); 138803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 138903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK_LE(encrypted->length(), packet_generator_.max_packet_length()); 13901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << ENDPOINT << "Sending packet " << sequence_number << " : " 13911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << (packet->serialized_packet.packet->is_fec_packet() ? "FEC " : 13921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA 13931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? "data bearing " : " ack only ")) 1394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << ", encryption level: " 13951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << QuicUtils::EncryptionLevelToString(packet->encryption_level) 13961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << ", length:" 13971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << packet->serialized_packet.packet->length() 13981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << ", encrypted length:" 1399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << encrypted->length(); 140090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DVLOG(2) << ENDPOINT << "packet(" << sequence_number << "): " << std::endl 14011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << QuicUtils::StringToHexASCIIDump( 14021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->serialized_packet.packet->AsStringPiece()); 14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WriteResult result = writer_->WritePacket(encrypted->data(), 1405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) encrypted->length(), 1406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self_address().address(), 1407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) peer_address()); 1408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (result.error_code == ERR_IO_PENDING) { 1409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status); 1410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 14115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 14121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Pass the write result to the visitor. 1413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) debug_visitor_->OnPacketSent(sequence_number, 14141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->encryption_level, 14151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->transmission_type, 1416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *encrypted, 1417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result); 14181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 141903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (result.status == WRITE_STATUS_BLOCKED) { 14215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visitor_->OnWriteBlocked(); 14224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If the socket buffers the the data, then the packet should not 14234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // be queued and sent again, which would result in an unnecessary 142403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // duplicate packet being sent. The helper must call OnCanWrite 142503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // when the write completes, and OnWriteError if an error occurs. 142603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!writer_->IsWriteBlockedDataBuffered()) { 142703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 142890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 14294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 143003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime now = clock_->Now(); 14311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (packet->transmission_type == NOT_RETRANSMISSION) { 143203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) time_of_last_sent_new_packet_ = now; 143303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 143403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SetPingAlarm(); 143503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DVLOG(1) << ENDPOINT << "time of last sent packet: " 143603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << now.ToDebuggingValue(); 14374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 143803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // TODO(ianswett): Change the sequence number length and other packet creator 143903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // options by a more explicit API than setting a struct value directly, 144003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // perhaps via the NetworkChangeVisitor. 144103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packet_generator_.UpdateSequenceNumberLength( 144203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) sent_packet_manager_.least_packet_awaited_by_peer(), 144303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) sent_packet_manager_.GetCongestionWindow()); 144403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (packet->original_sequence_number == 0) { 14461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sent_packet_manager_.OnSerializedPacket(packet->serialized_packet); 14471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 14481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (debug_visitor_.get() != NULL) { 14491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci debug_visitor_->OnPacketRetransmitted( 14501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->original_sequence_number, sequence_number); 14511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 14521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sent_packet_manager_.OnRetransmittedPacket(packet->original_sequence_number, 14531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sequence_number); 14541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 14551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool reset_retransmission_alarm = sent_packet_manager_.OnPacketSent( 14561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sequence_number, 14571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci now, 14581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci encrypted->length(), 14591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->transmission_type, 14601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsRetransmittable(*packet)); 14611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The SentPacketManager now owns the retransmittable frames. 14621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet->serialized_packet.retransmittable_frames = NULL; 146303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 146403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (reset_retransmission_alarm || !retransmission_alarm_->IsSet()) { 146503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) retransmission_alarm_->Update(sent_packet_manager_.GetRetransmissionTime(), 146603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime::Delta::FromMilliseconds(1)); 14674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 146803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 146903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) stats_.bytes_sent += result.bytes_written; 147003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ++stats_.packets_sent; 14711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (packet->transmission_type != NOT_RETRANSMISSION) { 147203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) stats_.bytes_retransmitted += result.bytes_written; 147303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ++stats_.packets_retransmitted; 147403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 147503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 147603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (result.status == WRITE_STATUS_ERROR) { 147703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) OnWriteError(result.error_code); 147803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 147903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 148003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 148103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 14824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 14834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 14841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool QuicConnection::ShouldDiscardPacket(const QueuedPacket& packet) { 14851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!connected_) { 1486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT 1487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Not sending packet as connection is disconnected."; 14881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 14891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 14901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 14911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci QuicPacketSequenceNumber sequence_number = 14921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet.serialized_packet.sequence_number; 1493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (encryption_level_ == ENCRYPTION_FORWARD_SECURE && 14941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet.encryption_level == ENCRYPTION_NONE) { 1495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Drop packets that are NULL encrypted since the peer won't accept them 1496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // anymore. 1497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Dropping NULL encrypted packet: " 1498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << sequence_number << " since the connection is forward secure."; 1499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 1500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 15021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If a retransmission has been acked before sending, don't send it. 15031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This occurs if a packet gets serialized, queued, then discarded. 15041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (packet.transmission_type != NOT_RETRANSMISSION && 15051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (!sent_packet_manager_.IsUnacked(packet.original_sequence_number) || 15061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !sent_packet_manager_.HasRetransmittableFrames( 15071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet.original_sequence_number))) { 1508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Dropping unacked packet: " << sequence_number 1509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << " A previous transmission was acked while write blocked."; 15105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 15111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 15121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 15131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 15141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 15151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 151603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void QuicConnection::OnWriteError(int error_code) { 151703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Write failed with error: " << error_code 151803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << " (" << ErrorToString(error_code) << ")"; 151903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // We can't send an error as the socket is presumably borked. 152003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CloseConnection(QUIC_PACKET_WRITE_ERROR, false); 15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid QuicConnection::OnSerializedPacket( 15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SerializedPacket& serialized_packet) { 1525d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (serialized_packet.retransmittable_frames) { 152668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) serialized_packet.retransmittable_frames-> 152768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) set_encryption_level(encryption_level_); 15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 15291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SendOrQueuePacket(QueuedPacket(serialized_packet, encryption_level_)); 1530d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 1531d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 153203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void QuicConnection::OnCongestionWindowChange(QuicByteCount congestion_window) { 153303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) packet_generator_.OnCongestionWindowChange(congestion_window); 153403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) visitor_->OnCongestionWindowChange(clock_->ApproximateNow()); 153503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 153603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 15376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void QuicConnection::OnHandshakeComplete() { 15386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) sent_packet_manager_.SetHandshakeConfirmed(); 15396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 15406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 15411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid QuicConnection::SendOrQueuePacket(QueuedPacket packet) { 15421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The caller of this function is responsible for checking CanWrite(). 15431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (packet.serialized_packet.packet == NULL) { 15445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "NULL packet passed in to SendOrQueuePacket"; 15451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 15465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 15475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 15481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sent_entropy_manager_.RecordPacketEntropyHash( 15491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet.serialized_packet.sequence_number, 15501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet.serialized_packet.entropy_hash); 15511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG_IF(DFATAL, !queued_packets_.empty() && !writer_->IsWriteBlocked()) 15521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << "Packets should only be left queued if we're write blocked."; 15531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!WritePacket(&packet)) { 15541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci queued_packets_.push_back(packet); 15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { 1559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_waiting->least_unacked = GetLeastUnacked(); 156003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) stop_waiting->entropy_hash = sent_entropy_manager_.GetCumulativeEntropy( 1561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_waiting->least_unacked - 1); 15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid QuicConnection::SendPing() { 15650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (retransmission_alarm_->IsSet()) { 15660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 15670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 15685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (version() == QUIC_VERSION_16) { 1569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(rch): remove this when we remove version 15 and 16. 15700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // This is a horrible hideous hack which we should not support. 15710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IOVector data; 15720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch char c_data[] = "C"; 15730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch data.Append(c_data, 1); 15740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicConsumedData consumed_data = 1575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packet_generator_.ConsumeData(kCryptoStreamId, data, 0, false, 1576f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MAY_FEC_PROTECT, NULL); 15770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (consumed_data.bytes_consumed == 0) { 15780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DLOG(ERROR) << "Unable to send ping!?"; 15790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 15800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 15810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame)); 15820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 15830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 15840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::SendAck() { 1586ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ack_alarm_->Cancel(); 1587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_waiting_count_ = 0; 15881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci num_packets_received_since_last_ack_sent_ = 0; 15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool send_feedback = false; 15901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 15911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Deprecating the Congestion Feedback Frame after QUIC_VERSION_22. 15921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (version() <= QUIC_VERSION_22) { 15931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (received_packet_manager_.GenerateCongestionFeedback( 15941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &outgoing_congestion_feedback_)) { 15951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << ENDPOINT << "Sending feedback: " 15961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << outgoing_congestion_feedback_; 15971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci send_feedback = true; 15981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) packet_generator_.SetShouldSendAck(send_feedback, true); 16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 160468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void QuicConnection::OnRetransmissionTimeout() { 160568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!sent_packet_manager_.HasUnackedPackets()) { 1606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1609a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sent_packet_manager_.OnRetransmissionTimeout(); 1610a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WriteIfNotBlocked(); 161103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 161203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // A write failure can result in the connection being closed, don't attempt to 161303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // write further packets, or to set alarms. 161403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!connected_) { 161503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 161603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 161703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1618f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // In the TLP case, the SentPacketManager gives the connection the opportunity 1619f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // to send new data before retransmitting. 1620f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (sent_packet_manager_.MaybeRetransmitTailLossProbe()) { 1621f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Send the pending retransmission now that it's been queued. 1622f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WriteIfNotBlocked(); 1623f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1625f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Ensure the retransmission alarm is always set if there are unacked packets 1626f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // and nothing waiting to be sent. 16275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!HasQueuedData() && !retransmission_alarm_->IsSet()) { 16285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicTime rto_timeout = sent_packet_manager_.GetRetransmissionTime(); 162903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (rto_timeout.IsInitialized()) { 16305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) retransmission_alarm_->Set(rto_timeout); 16315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 16325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicConnection::SetEncrypter(EncryptionLevel level, 1636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicEncrypter* encrypter) { 1637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) framer_.SetEncrypter(level, encrypter); 1638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const QuicEncrypter* QuicConnection::encrypter(EncryptionLevel level) const { 1641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return framer_.encrypter(level); 1642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) { 1645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) encryption_level_ = level; 1646f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packet_generator_.set_encryption_level(level); 1647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid QuicConnection::SetDecrypter(QuicDecrypter* decrypter, 16505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EncryptionLevel level) { 16515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu framer_.SetDecrypter(decrypter, level); 1652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicConnection::SetAlternativeDecrypter(QuicDecrypter* decrypter, 16555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EncryptionLevel level, 1656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool latch_once_used) { 16575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu framer_.SetAlternativeDecrypter(decrypter, level, latch_once_used); 1658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const QuicDecrypter* QuicConnection::decrypter() const { 1661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return framer_.decrypter(); 1662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const QuicDecrypter* QuicConnection::alternative_decrypter() const { 1665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return framer_.alternative_decrypter(); 1666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void QuicConnection::QueueUndecryptablePacket( 16697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const QuicEncryptedPacket& packet) { 16707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Queueing undecryptable packet."; 1671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) undecryptable_packets_.push_back(packet.Clone()); 16727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 16737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 16747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void QuicConnection::MaybeProcessUndecryptablePackets() { 1675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (undecryptable_packets_.empty() || encryption_level_ == ENCRYPTION_NONE) { 16767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 16777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 16787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1679ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch while (connected_ && !undecryptable_packets_.empty()) { 16807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet"; 16817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) QuicEncryptedPacket* packet = undecryptable_packets_.front(); 16827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!framer_.ProcessPacket(*packet) && 16837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) framer_.error() == QUIC_DECRYPTION_FAILURE) { 16847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Unable to process undecryptable packet..."; 16857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 16867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 16877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Processed undecryptable packet!"; 16885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ++stats_.packets_processed; 16897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) delete packet; 16907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) undecryptable_packets_.pop_front(); 16917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 16927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 16937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Once forward secure encryption is in use, there will be no 16947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // new keys installed and hence any undecryptable packets will 16957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // never be able to be decrypted. 16967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (encryption_level_ == ENCRYPTION_FORWARD_SECURE) { 16976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (debug_visitor_.get() != NULL) { 16986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // TODO(rtenneti): perhaps more efficient to pass the number of 16996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // undecryptable packets as the argument to OnUndecryptablePacket so that 17006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // we just need to call OnUndecryptablePacket once? 17015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (size_t i = 0; i < undecryptable_packets_.size(); ++i) { 17025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) debug_visitor_->OnUndecryptablePacket(); 17035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 17045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 17057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) STLDeleteElements(&undecryptable_packets_); 17067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 17077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 17087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::MaybeProcessRevivedPacket() { 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicFecGroup* group = GetFecGroup(); 1711ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!connected_ || group == NULL || !group->CanRevive()) { 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicPacketHeader revived_header; 17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char revived_payload[kMaxPacketSize]; 17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize); 1717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) revived_header.public_header.connection_id = connection_id_; 17180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch revived_header.public_header.connection_id_length = 17190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch last_header_.public_header.connection_id_length; 17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) revived_header.public_header.version_flag = false; 17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) revived_header.public_header.reset_flag = false; 17220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch revived_header.public_header.sequence_number_length = 17230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch last_header_.public_header.sequence_number_length; 17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) revived_header.fec_flag = false; 1725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) revived_header.is_in_fec_group = NOT_IN_FEC_GROUP; 1726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) revived_header.fec_group = 0; 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_map_.erase(last_header_.fec_group); 1728010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) last_decrypted_packet_level_ = group->effective_encryption_level(); 1729010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_LT(last_decrypted_packet_level_, NUM_ENCRYPTION_LEVELS); 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete group; 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_packet_revived_ = true; 17335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (debug_visitor_.get() != NULL) { 17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_->OnRevivedPacket(revived_header, 17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringPiece(revived_payload, len)); 17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++stats_.packets_revived; 17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framer_.ProcessRevivedPacket(&revived_header, 17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringPiece(revived_payload, len)); 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicFecGroup* QuicConnection::GetFecGroup() { 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicFecGroupNumber fec_group_num = last_header_.fec_group; 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fec_group_num == 0) { 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (group_map_.count(fec_group_num) == 0) { 174990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (group_map_.size() >= kMaxFecGroups) { // Too many groups 175090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (fec_group_num < group_map_.begin()->first) { 175190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The group being requested is a group we've seen before and deleted. 175290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Don't recreate it. 175390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return NULL; 175490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 175590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Clear the lowest group number. 175690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete group_map_.begin()->second; 175790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) group_map_.erase(group_map_.begin()); 175890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_map_[fec_group_num] = new QuicFecGroup(); 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return group_map_[fec_group_num]; 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::SendConnectionClose(QuicErrorCode error) { 17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendConnectionCloseWithDetails(error, string()); 17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error, 17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const string& details) { 17705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we're write blocked, WritePacket() will not send, but will capture the 17715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // serialized packet. 17725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendConnectionClosePacket(error, details); 1773a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (connected_) { 1774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // It's possible that while sending the connection close packet, we get a 1775a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // socket error and disconnect right then and there. Avoid a double 1776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // disconnect in that case. 1777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection(error, false); 1778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 17802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1781d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, 1782d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const string& details) { 1783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Force closing " << connection_id() 1784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " with error " << QuicUtils::ErrorToString(error) 1785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " (" << error << ") " << details; 1786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedPacketBundler ack_bundler(this, SEND_ACK); 1787d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(); 1788d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) frame->error_code = error; 1789d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) frame->error_details = details; 1790d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) packet_generator_.AddControlFrame(QuicFrame(frame)); 17916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) packet_generator_.FlushAllQueuedFrames(); 1792d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 1793d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) { 1795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!connected_) { 1796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DLOG(DFATAL) << "Error: attempt to close an already closed connection" 1797a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << base::debug::StackTrace().ToString(); 1798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 1799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connected_ = false; 18016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (debug_visitor_.get() != NULL) { 18026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) debug_visitor_->OnConnectionClosed(error, from_peer); 18036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 18041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) visitor_->OnConnectionClosed(error, from_peer); 18050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Cancel the alarms so they don't trigger any action now that the 18060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // connection is closed. 18070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ack_alarm_->Cancel(); 180803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ping_alarm_->Cancel(); 18090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) resume_writes_alarm_->Cancel(); 18100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) retransmission_alarm_->Cancel(); 18110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) send_alarm_->Cancel(); 18120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) timeout_alarm_->Cancel(); 18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicConnection::SendGoAway(QuicErrorCode error, 18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicStreamId last_good_stream_id, 18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const string& reason) { 1818f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Going away with error " 1819a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << QuicUtils::ErrorToString(error) 1820a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " (" << error << ")"; 182168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 182268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Opportunistically bundle an ack with this outgoing packet. 1823a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); 18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) packet_generator_.AddControlFrame( 18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicFrame(new QuicGoAwayFrame(error, last_good_stream_id, reason))); 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicConnection::CloseFecGroupsBefore( 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPacketSequenceNumber sequence_number) { 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FecGroupMap::iterator it = group_map_.begin(); 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (it != group_map_.end()) { 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is the current group or the group doesn't protect this packet 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we can ignore it. 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_header_.fec_group == it->first || 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !it->second->ProtectsPacketsBefore(sequence_number)) { 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it; 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicFecGroup* fec_group = it->second; 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!fec_group->CanRevive()); 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FecGroupMap::iterator next = it; 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++next; 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_map_.erase(it); 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete fec_group; 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it = next; 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1849f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)size_t QuicConnection::max_packet_length() const { 1850f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return packet_generator_.max_packet_length(); 1851f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 1852f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1853f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void QuicConnection::set_max_packet_length(size_t length) { 1854f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return packet_generator_.set_max_packet_length(length); 1855f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 1856f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicConnection::HasQueuedData() const { 18584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return pending_version_negotiation_packet_ || 18594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) !queued_packets_.empty() || packet_generator_.HasQueuedFrames(); 1860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 18625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicConnection::CanWriteStreamData() { 18635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Don't write stream data if there are negotiation or queued data packets 18645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to send. Otherwise, continue and bundle as many frames as possible. 18655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pending_version_negotiation_packet_ || !queued_packets_.empty()) { 18665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 18675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 18685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? 18705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IS_HANDSHAKE : NOT_HANDSHAKE; 18715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sending queued packets may have caused the socket to become write blocked, 18725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // or the congestion manager to prohibit sending. If we've sent everything 18735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // we had queued and we're still not blocked, let the visitor know it can 18745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // write more. 18755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ShouldGeneratePacket(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, 18765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_handshake); 18775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 18785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) { 188003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Adjust the idle timeout on client and server to prevent clients from 188103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // sending requests to servers which have already closed the connection. 188203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (is_server_) { 188303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) timeout = timeout.Add(QuicTime::Delta::FromSeconds(1)); 188403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else if (timeout > QuicTime::Delta::FromSeconds(1)) { 188503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) timeout = timeout.Subtract(QuicTime::Delta::FromSeconds(1)); 188603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 188703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (timeout < idle_network_timeout_) { 1889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) idle_network_timeout_ = timeout; 1890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CheckForTimeout(); 1891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) idle_network_timeout_ = timeout; 1893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void QuicConnection::SetOverallConnectionTimeout(QuicTime::Delta timeout) { 1897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (timeout < overall_connection_timeout_) { 1898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) overall_connection_timeout_ = timeout; 1899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CheckForTimeout(); 1900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) overall_connection_timeout_ = timeout; 1902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1903b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 1904b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicConnection::CheckForTimeout() { 19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicTime now = clock_->ApproximateNow(); 19075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicTime time_of_last_packet = max(time_of_last_received_packet_, 19085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_of_last_sent_new_packet_); 19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If no packets have been sent or received, then don't timeout. 19111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (FLAGS_quic_timeouts_require_activity && 19121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !time_of_last_packet.IsInitialized()) { 19131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci timeout_alarm_->Cancel(); 19141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci timeout_alarm_->Set(now.Add(idle_network_timeout_)); 19151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 19161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 19171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| 1919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // is accurate time. However, this should not change the behavior of 1920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // timeout handling. 19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicTime::Delta delta = now.Subtract(time_of_last_packet); 192290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DVLOG(1) << ENDPOINT << "last packet " 192390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << time_of_last_packet.ToDebuggingValue() 1924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " now:" << now.ToDebuggingValue() 1925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << " delta:" << delta.ToMicroseconds() 1926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << " network_timeout: " << idle_network_timeout_.ToMicroseconds(); 1927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (delta >= idle_network_timeout_) { 1928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Connection timedout due to no network activity."; 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Next timeout delta. 1934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QuicTime::Delta timeout = idle_network_timeout_.Subtract(delta); 1935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!overall_connection_timeout_.IsInfinite()) { 19370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicTime::Delta connected_time = 19380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch now.Subtract(stats_.connection_creation_time); 1939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << ENDPOINT << "connection time: " 1940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << connected_time.ToMilliseconds() << " overall timeout: " 1941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << overall_connection_timeout_.ToMilliseconds(); 1942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (connected_time >= overall_connection_timeout_) { 1943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DVLOG(1) << ENDPOINT << 1944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Connection timedout due to overall connection timeout."; 19451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SendConnectionClose(QUIC_CONNECTION_OVERALL_TIMED_OUT); 1946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 1947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Take the min timeout. 1950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QuicTime::Delta connection_timeout = 1951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) overall_connection_timeout_.Subtract(connected_time); 1952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (connection_timeout < timeout) { 1953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) timeout = connection_timeout; 1954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1957ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch timeout_alarm_->Cancel(); 195803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) timeout_alarm_->Set(now.Add(timeout)); 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid QuicConnection::SetPingAlarm() { 19630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (is_server_) { 19640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Only clients send pings. 19650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 19660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 19670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!visitor_->HasOpenDataStreams()) { 196803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ping_alarm_->Cancel(); 19690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Don't send a ping unless there are open streams. 19700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 19710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 19720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicTime::Delta ping_timeout = QuicTime::Delta::FromSeconds(kPingTimeoutSecs); 197303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ping_alarm_->Update(clock_->ApproximateNow().Add(ping_timeout), 197403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime::Delta::FromSeconds(1)); 19750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 19760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 197768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)QuicConnection::ScopedPacketBundler::ScopedPacketBundler( 197868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) QuicConnection* connection, 1979a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AckBundling send_ack) 198068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : connection_(connection), 1981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) already_in_batch_mode_(connection != NULL && 1982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) connection->packet_generator_.InBatchMode()) { 1983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (connection_ == NULL) { 1984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 1985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 198668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Move generator into batch mode. If caller wants us to include an ack, 198768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // check the delayed-ack timer to see if there's ack info to be sent. 198868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!already_in_batch_mode_) { 198968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "Entering Batch Mode."; 199068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) connection_->packet_generator_.StartBatchOperations(); 199168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 1992a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Bundle an ack if the alarm is set or with every second packet if we need to 1993a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // raise the peer's least unacked. 1994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool ack_pending = 1995a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection_->ack_alarm_->IsSet() || connection_->stop_waiting_count_ > 1; 1996a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (send_ack == SEND_ACK || (send_ack == BUNDLE_PENDING_ACK && ack_pending)) { 199768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "Bundling ack with outgoing packet."; 199868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) connection_->SendAck(); 199968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 200068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 200168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 200268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)QuicConnection::ScopedPacketBundler::~ScopedPacketBundler() { 2003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (connection_ == NULL) { 2004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 2005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 200668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If we changed the generator's batch state, restore original batch state. 200768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!already_in_batch_mode_) { 200868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DVLOG(1) << "Leaving Batch Mode."; 200968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) connection_->packet_generator_.FinishBatchOperations(); 201068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 201168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(already_in_batch_mode_, 201268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) connection_->packet_generator_.InBatchMode()); 201368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 201468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 20151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciHasRetransmittableData QuicConnection::IsRetransmittable( 20161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const QueuedPacket& packet) { 20171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Retransmitted packets retransmittable frames are owned by the unacked 20181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // packet map, but are not present in the serialized packet. 20191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (packet.transmission_type != NOT_RETRANSMISSION || 20201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet.serialized_packet.retransmittable_frames != NULL) { 20211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return HAS_RETRANSMITTABLE_DATA; 20221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 20231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NO_RETRANSMITTABLE_DATA; 20241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 20251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 20261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 20271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool QuicConnection::IsConnectionClose( 20281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci QueuedPacket packet) { 20291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RetransmittableFrames* retransmittable_frames = 20301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet.serialized_packet.retransmittable_frames; 20311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!retransmittable_frames) { 20321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 20331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 20341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { 20351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { 20361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 20371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 20381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 20391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 20401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 20411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 2043