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_client_session.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/callback_helpers.h" 8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/metrics/histogram.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/metrics/sparse_histogram.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 125e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/io_buffer.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/http/transport_security_state.h" 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/quic/crypto/proof_verifier_chromium.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/quic/crypto/quic_server_info.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_connection_helper.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_crypto_client_stream_factory.h" 21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_server_id.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_stream_factory.h" 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/spdy/spdy_session.h" 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/channel_id_service.h" 2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/ssl/ssl_connection_status_flags.h" 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/ssl/ssl_info.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/udp/datagram_client_socket.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// The length of time to wait for a 0-RTT handshake to complete 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// before allowing the requests to possibly proceed over TCP. 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const int k0RttHandshakeTimeoutMs = 300; 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Histograms for tracking down the crashes from http://crbug.com/354669 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Note: these values must be kept in sync with the corresponding values in: 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// tools/metrics/histograms/histograms.xml 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochenum Location { 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DESTRUCTOR = 0, 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ADD_OBSERVER = 1, 43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch TRY_CREATE_STREAM = 2, 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CREATE_OUTGOING_RELIABLE_STREAM = 3, 45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER = 4, 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NOTIFY_FACTORY_OF_SESSION_CLOSED = 5, 47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NUM_LOCATIONS = 6, 48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid RecordUnexpectedOpenStreams(Location location) { 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.UnexpectedOpenStreams", location, 52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NUM_LOCATIONS); 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid RecordUnexpectedObservers(Location location) { 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.UnexpectedObservers", location, 57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NUM_LOCATIONS); 58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid RecordUnexpectedNotGoingAway(Location location) { 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.UnexpectedNotGoingAway", location, 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NUM_LOCATIONS); 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Histogram for recording the different reasons that a QUIC session is unable 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// to complete the handshake. 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)enum HandshakeFailureReason { 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HANDSHAKE_FAILURE_UNKNOWN = 0, 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HANDSHAKE_FAILURE_BLACK_HOLE = 1, 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HANDSHAKE_FAILURE_PUBLIC_RESET = 2, 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NUM_HANDSHAKE_FAILURE_REASONS = 3, 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RecordHandshakeFailureReason(HandshakeFailureReason reason) { 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "Net.QuicSession.ConnectionClose.HandshakeNotConfirmed.Reason", 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reason, NUM_HANDSHAKE_FAILURE_REASONS); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Note: these values must be kept in sync with the corresponding values in: 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// tools/metrics/histograms/histograms.xml 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)enum HandshakeState { 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) STATE_STARTED = 0, 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) STATE_ENCRYPTION_ESTABLISHED = 1, 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) STATE_HANDSHAKE_CONFIRMED = 2, 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) STATE_FAILED = 3, 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NUM_HANDSHAKE_STATES = 4 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void RecordHandshakeState(HandshakeState state) { 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Net.QuicHandshakeState", state, 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NUM_HANDSHAKE_STATES); 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)QuicClientSession::StreamRequest::StreamRequest() : stream_(NULL) {} 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)QuicClientSession::StreamRequest::~StreamRequest() { 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CancelRequest(); 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int QuicClientSession::StreamRequest::StartRequest( 1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const base::WeakPtr<QuicClientSession>& session, 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) QuicReliableClientStream** stream, 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const CompletionCallback& callback) { 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session_ = session; 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) stream_ = stream; 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int rv = session_->TryCreateStream(this, stream_); 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (rv == ERR_IO_PENDING) { 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback_ = callback; 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return rv; 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void QuicClientSession::StreamRequest::CancelRequest() { 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (session_) 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session_->CancelRequest(this); 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session_.reset(); 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback_.Reset(); 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void QuicClientSession::StreamRequest::OnRequestCompleteSuccess( 125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) QuicReliableClientStream* stream) { 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session_.reset(); 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *stream_ = stream; 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ResetAndReturn(&callback_).Run(OK); 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void QuicClientSession::StreamRequest::OnRequestCompleteFailure(int rv) { 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session_.reset(); 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ResetAndReturn(&callback_).Run(rv); 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)QuicClientSession::QuicClientSession( 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) QuicConnection* connection, 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<DatagramClientSocket> socket, 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) QuicStreamFactory* stream_factory, 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TransportSecurityState* transport_security_state, 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<QuicServerInfo> server_info, 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const QuicConfig& config, 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TaskRunner* task_runner, 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NetLog* net_log) 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : QuicClientSessionBase(connection, config), 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) require_confirmation_(false), 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_factory_(stream_factory), 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) socket_(socket.Pass()), 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_buffer_(new IOBufferWithSize(kMaxPacketSize)), 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_security_state_(transport_security_state), 15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) server_info_(server_info.Pass()), 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_pending_(false), 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_total_streams_(0), 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) task_runner_(task_runner), 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_QUIC_SESSION)), 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logger_(new QuicConnectionLogger(net_log_)), 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) num_packets_read_(0), 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch going_away_(false), 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) weak_factory_(this) { 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci connection->set_debug_visitor(logger_); 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid QuicClientSession::InitializeSession( 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const QuicServerId& server_id, 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci QuicCryptoClientConfig* crypto_config, 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci QuicCryptoClientStreamFactory* crypto_client_stream_factory) { 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci server_host_port_ = server_id.host_port_pair(); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) crypto_stream_.reset( 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) crypto_client_stream_factory ? 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) crypto_client_stream_factory->CreateQuicCryptoClientStream( 171e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch server_id, this, crypto_config) : 172e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch new QuicCryptoClientStream(server_id, this, 173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new ProofVerifyContextChromium(net_log_), 174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch crypto_config)); 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci QuicClientSessionBase::InitializeSession(); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(rch): pass in full host port proxy pair 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log_.BeginEvent( 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetLog::TYPE_QUIC_SESSION, 179e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch NetLog::StringCallback("host", &server_id.host())); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicClientSession::~QuicClientSession() { 183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!streams()->empty()) 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedOpenStreams(DESTRUCTOR); 185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!observers_.empty()) 186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedObservers(DESTRUCTOR); 187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!going_away_) 188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedNotGoingAway(DESTRUCTOR); 189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 190e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch while (!streams()->empty() || 191e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch !observers_.empty() || 192e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch !stream_requests_.empty()) { 193e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // The session must be closed before it is destroyed. 194e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(streams()->empty()); 195e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CloseAllStreams(ERR_UNEXPECTED); 196e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(observers_.empty()); 197e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CloseAllObservers(ERR_UNEXPECTED); 198e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch connection()->set_debug_visitor(NULL); 200e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch net_log_.EndEvent(NetLog::TYPE_QUIC_SESSION); 201e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 202e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch while (!stream_requests_.empty()) { 203e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch StreamRequest* request = stream_requests_.front(); 204e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch stream_requests_.pop_front(); 205e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch request->OnRequestCompleteFailure(ERR_ABORTED); 206e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (connection()->connected()) { 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Ensure that the connection is closed by the time the session is 211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // destroyed. 212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch connection()->CloseConnection(QUIC_INTERNAL_ERROR, false); 213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsEncryptionEstablished()) 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RecordHandshakeState(STATE_ENCRYPTION_ESTABLISHED); 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IsCryptoHandshakeConfirmed()) 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RecordHandshakeState(STATE_HANDSHAKE_CONFIRMED); 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RecordHandshakeState(STATE_FAILED); 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Net.QuicSession.NumTotalStreams", num_total_streams_); 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Net.QuicNumSentClientHellos", 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) crypto_stream_->num_sent_client_hellos()); 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsCryptoHandshakeConfirmed()) 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sending one client_hello means we had zero handshake-round-trips. 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int round_trip_handshakes = crypto_stream_->num_sent_client_hellos() - 1; 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Don't bother with these histogram during tests, which mock out 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // num_sent_client_hellos(). 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (round_trip_handshakes < 0 || !stream_factory_) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool port_selected = stream_factory_->enable_port_selection(); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SSLInfo ssl_info; 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) { 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (port_selected) { 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.ConnectSelectPortForHTTP", 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) round_trip_handshakes, 0, 3, 4); 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.ConnectRandomPortForHTTP", 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) round_trip_handshakes, 0, 3, 4); 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (require_confirmation_) { 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UMA_HISTOGRAM_CUSTOM_COUNTS( 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "Net.QuicSession.ConnectRandomPortRequiringConfirmationForHTTP", 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci round_trip_handshakes, 0, 3, 4); 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (port_selected) { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.ConnectSelectPortForHTTPS", 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) round_trip_handshakes, 0, 3, 4); 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.ConnectRandomPortForHTTPS", 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) round_trip_handshakes, 0, 3, 4); 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (require_confirmation_) { 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UMA_HISTOGRAM_CUSTOM_COUNTS( 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "Net.QuicSession.ConnectRandomPortRequiringConfirmationForHTTPS", 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci round_trip_handshakes, 0, 3, 4); 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const QuicConnectionStats stats = connection()->GetStats(); 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (stats.max_sequence_reordering == 0) 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const uint64 kMaxReordering = 100; 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint64 reordering = kMaxReordering; 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (stats.min_rtt_us > 0 ) { 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reordering = 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GG_UINT64_C(100) * stats.max_time_reordering_us / stats.min_rtt_us; 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.MaxReorderingTime", 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reordering, 0, kMaxReordering, 50); 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (stats.min_rtt_us > 100 * 1000) { 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.MaxReorderingTimeLongRtt", 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reordering, 0, kMaxReordering, 50); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Net.QuicSession.MaxReordering", 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stats.max_sequence_reordering); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid QuicClientSession::OnStreamFrames( 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::vector<QuicStreamFrame>& frames) { 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Record total number of stream frames. 28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Net.QuicNumStreamFramesInPacket", frames.size()); 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Record number of frames per stream in packet. 29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) typedef std::map<QuicStreamId, size_t> FrameCounter; 29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FrameCounter frames_per_stream; 29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < frames.size(); ++i) { 29368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) frames_per_stream[frames[i].stream_id]++; 29468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (FrameCounter::const_iterator it = frames_per_stream.begin(); 29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it != frames_per_stream.end(); ++it) { 29768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Net.QuicNumStreamFramesPerStreamInPacket", 29868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it->second); 29968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return QuicSession::OnStreamFrames(frames); 30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 30368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicClientSession::AddObserver(Observer* observer) { 305e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (going_away_) { 306effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedObservers(ADD_OBSERVER); 307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch observer->OnSessionClosed(ERR_UNEXPECTED); 308e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 309e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!ContainsKey(observers_, observer)); 3128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) observers_.insert(observer); 3138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicClientSession::RemoveObserver(Observer* observer) { 3168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(ContainsKey(observers_, observer)); 3178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) observers_.erase(observer); 3188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int QuicClientSession::TryCreateStream(StreamRequest* request, 321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) QuicReliableClientStream** stream) { 322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!crypto_stream_->encryption_established()) { 323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DLOG(DFATAL) << "Encryption not established."; 324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return ERR_CONNECTION_CLOSED; 325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (goaway_received()) { 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Going away."; 329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return ERR_CONNECTION_CLOSED; 330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!connection()->connected()) { 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Already closed."; 334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return ERR_CONNECTION_CLOSED; 335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (going_away_) { 338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedOpenStreams(TRY_CREATE_STREAM); 339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return ERR_CONNECTION_CLOSED; 340effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 341effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetNumOpenStreams() < get_max_open_streams()) { 343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *stream = CreateOutgoingReliableStreamImpl(); 344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return OK; 345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) stream_requests_.push_back(request); 348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return ERR_IO_PENDING; 349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void QuicClientSession::CancelRequest(StreamRequest* request) { 352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Remove |request| from the queue while preserving the order of the 353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // other elements. 354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StreamRequestQueue::iterator it = 355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::find(stream_requests_.begin(), stream_requests_.end(), request); 356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (it != stream_requests_.end()) { 357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) it = stream_requests_.erase(it); 358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicReliableClientStream* QuicClientSession::CreateOutgoingDataStream() { 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!crypto_stream_->encryption_established()) { 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Encryption not active so no outgoing stream created."; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetNumOpenStreams() >= get_max_open_streams()) { 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Failed to create a new outgoing stream. " 368e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch << "Already " << GetNumOpenStreams() << " open."; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (goaway_received()) { 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Failed to create a new outgoing stream. " 373e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch << "Already received goaway."; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (going_away_) { 377effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedOpenStreams(CREATE_OUTGOING_RELIABLE_STREAM); 378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return NULL; 379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return CreateOutgoingReliableStreamImpl(); 381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)QuicReliableClientStream* 384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)QuicClientSession::CreateOutgoingReliableStreamImpl() { 385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(connection()->connected()); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicReliableClientStream* stream = 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new QuicReliableClientStream(GetNextStreamId(), this, net_log_); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ActivateStream(stream); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++num_total_streams_; 3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UMA_HISTOGRAM_COUNTS("Net.QuicSession.NumOpenStreams", GetNumOpenStreams()); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return stream; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicCryptoClientStream* QuicClientSession::GetCryptoStream() { 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return crypto_stream_.get(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways 39923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// we learn about SSL info (sync vs async vs cached). 40023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool QuicClientSession::GetSSLInfo(SSLInfo* ssl_info) const { 40123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_info->Reset(); 40223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!cert_verify_result_) { 40323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 40423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 40523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 40623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_info->cert_status = cert_verify_result_->cert_status; 40723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_info->cert = cert_verify_result_->verified_cert; 40823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 409c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(wtc): Define QUIC "cipher suites". 410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Report the TLS cipher suite that most closely resembles the crypto 411c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // parameters of the QUIC connection. 412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch QuicTag aead = crypto_stream_->crypto_negotiated_params().aead; 413c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int cipher_suite; 414c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int security_bits; 415c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch switch (aead) { 416c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case kAESG: 417c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cipher_suite = 0xc02f; // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 418c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch security_bits = 128; 419c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 420c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case kCC12: 421c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cipher_suite = 0xcc13; // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 422c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch security_bits = 256; 423c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 424c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch default: 425c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NOTREACHED(); 426c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 427c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 42823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int ssl_connection_status = 0; 42923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_connection_status |= 43023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) (cipher_suite & SSL_CONNECTION_CIPHERSUITE_MASK) << 43123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SSL_CONNECTION_CIPHERSUITE_SHIFT; 43223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_connection_status |= 433c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (SSL_CONNECTION_VERSION_QUIC & SSL_CONNECTION_VERSION_MASK) << 43423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SSL_CONNECTION_VERSION_SHIFT; 43523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 43623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_info->public_key_hashes = cert_verify_result_->public_key_hashes; 43723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_info->is_issued_by_known_root = 43823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) cert_verify_result_->is_issued_by_known_root; 43923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 44023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_info->connection_status = ssl_connection_status; 44123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_info->client_cert_sent = false; 442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ssl_info->channel_id_sent = crypto_stream_->WasChannelIDSent(); 443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ssl_info->security_bits = security_bits; 44423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ssl_info->handshake_type = SSLInfo::HANDSHAKE_FULL; 4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ssl_info->pinning_failure_log = pinning_failure_log_; 44623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return true; 4477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 4487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int QuicClientSession::CryptoConnect(bool require_confirmation, 4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const CompletionCallback& callback) { 4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) require_confirmation_ = require_confirmation; 452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) handshake_start_ = base::TimeTicks::Now(); 453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RecordHandshakeState(STATE_STARTED); 454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(flow_controller()); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!crypto_stream_->CryptoConnect()) { 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(wtc): change crypto_stream_.CryptoConnect() to return a 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // QuicErrorCode and map it to a net error code. 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ERR_CONNECTION_FAILED; 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsCryptoHandshakeConfirmed()) 46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return OK; 46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Unless we require handshake confirmation, activate the session if 46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // we have established initial encryption. 46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!require_confirmation_ && IsEncryptionEstablished()) { 46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // To mitigate the effects of hanging 0-RTT connections, set up a timer to 46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // cancel any requests, if the handshake takes too long. 46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) task_runner_->PostDelayedTask( 47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&QuicClientSession::OnConnectTimeout, 47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) weak_factory_.GetWeakPtr()), 47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::TimeDelta::FromMilliseconds(k0RttHandshakeTimeoutMs)); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return OK; 47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_ = callback; 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ERR_IO_PENDING; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int QuicClientSession::ResumeCryptoConnect(const CompletionCallback& callback) { 48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsCryptoHandshakeConfirmed()) 48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return OK; 48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!connection()->connected()) 48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return ERR_QUIC_HANDSHAKE_FAILED; 48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback_ = callback; 49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return ERR_IO_PENDING; 49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 49346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 49458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)int QuicClientSession::GetNumSentClientHellos() const { 49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return crypto_stream_->num_sent_client_hellos(); 49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 49758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicClientSession::CanPool(const std::string& hostname) const { 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(connection()->connected()); 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SSLInfo ssl_info; 5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) { 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We can always pool with insecure QUIC sessions. 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 50603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return SpdySession::CanPool(transport_security_state_, ssl_info, 50703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) server_host_port_.host(), hostname); 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicDataStream* QuicClientSession::CreateIncomingDataStream( 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicStreamId id) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Server push not supported"; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicClientSession::CloseStream(QuicStreamId stream_id) { 517c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ReliableQuicStream* stream = GetStream(stream_id); 518c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (stream) { 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logger_->UpdateReceivedFrameCounts( 520c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch stream_id, stream->num_frames_received(), 521c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch stream->num_duplicate_frames_received()); 522c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicSession::CloseStream(stream_id); 524424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OnClosedStream(); 525424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 526424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 527424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void QuicClientSession::SendRstStream(QuicStreamId id, 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicRstStreamErrorCode error, 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicStreamOffset bytes_written) { 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicSession::SendRstStream(id, error, bytes_written); 531424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OnClosedStream(); 532424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 534424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void QuicClientSession::OnClosedStream() { 535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (GetNumOpenStreams() < get_max_open_streams() && 536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !stream_requests_.empty() && 537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) crypto_stream_->encryption_established() && 538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) !goaway_received() && 539effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !going_away_ && 540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) connection()->connected()) { 541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) StreamRequest* request = stream_requests_.front(); 542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) stream_requests_.pop_front(); 543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) request->OnRequestCompleteSuccess(CreateOutgoingReliableStreamImpl()); 544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetNumOpenStreams() == 0) { 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_factory_->OnIdleSession(this); 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicClientSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { 5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!callback_.is_null() && 5533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) (!require_confirmation_ || event == HANDSHAKE_CONFIRMED)) { 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(rtenneti): Currently for all CryptoHandshakeEvent events, callback_ 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // could be called because there are no error events in CryptoHandshakeEvent 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // enum. If error events are added to CryptoHandshakeEvent, then the 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // following code needs to changed. 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ResetAndReturn(&callback_).Run(OK); 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (event == HANDSHAKE_CONFIRMED) { 561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Net.QuicSession.HandshakeConfirmedTime", 562f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::TimeTicks::Now() - handshake_start_); 5638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ObserverSet::iterator it = observers_.begin(); 5648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) while (it != observers_.end()) { 5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Observer* observer = *it; 5668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ++it; 5678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) observer->OnCryptoHandshakeConfirmed(); 5688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 570ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch QuicSession::OnCryptoHandshakeEvent(event); 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void QuicClientSession::OnCryptoHandshakeMessageSent( 5743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const CryptoHandshakeMessage& message) { 5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logger_->OnCryptoHandshakeMessageSent(message); 5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void QuicClientSession::OnCryptoHandshakeMessageReceived( 5793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const CryptoHandshakeMessage& message) { 5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logger_->OnCryptoHandshakeMessageReceived(message); 5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void QuicClientSession::OnConnectionClosed(QuicErrorCode error, 5841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool from_peer) { 5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!connection()->connected()); 5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logger_->OnConnectionClosed(error, from_peer); 5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (from_peer) { 5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY( 5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Net.QuicSession.ConnectionCloseErrorCodeServer", error); 5903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 5913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY( 5923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Net.QuicSession.ConnectionCloseErrorCodeClient", error); 5933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 594424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 595424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (error == QUIC_CONNECTION_TIMED_OUT) { 5961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UMA_HISTOGRAM_COUNTS( 597424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "Net.QuicSession.ConnectionClose.NumOpenStreams.TimedOut", 598424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) GetNumOpenStreams()); 59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsCryptoHandshakeConfirmed()) { 60003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (GetNumOpenStreams() > 0) { 60103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN( 60203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "Net.QuicSession.TimedOutWithOpenStreams.HasUnackedPackets", 60303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) connection()->sent_packet_manager().HasUnackedPackets()); 60403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) UMA_HISTOGRAM_COUNTS( 60503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "Net.QuicSession.TimedOutWithOpenStreams.ConsecutiveRTOCount", 60603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) connection()->sent_packet_manager().consecutive_rto_count()); 60703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) UMA_HISTOGRAM_COUNTS( 60803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "Net.QuicSession.TimedOutWithOpenStreams.ConsecutiveTLPCount", 60903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) connection()->sent_packet_manager().consecutive_tlp_count()); 61003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 61103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 612f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UMA_HISTOGRAM_COUNTS( 613f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "Net.QuicSession.ConnectionClose.NumOpenStreams.HandshakeTimedOut", 614f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetNumOpenStreams()); 6151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UMA_HISTOGRAM_COUNTS( 6161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "Net.QuicSession.ConnectionClose.NumTotalStreams.HandshakeTimedOut", 6171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) num_total_streams_); 6181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 619424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 620424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!IsCryptoHandshakeConfirmed()) { 622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error == QUIC_PUBLIC_RESET) { 623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RecordHandshakeFailureReason(HANDSHAKE_FAILURE_PUBLIC_RESET); 624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (connection()->GetStats().packets_received == 0) { 625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RecordHandshakeFailureReason(HANDSHAKE_FAILURE_BLACK_HOLE); 626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY( 627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "Net.QuicSession.ConnectionClose.HandshakeFailureBlackHole.QuicError", 628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error); 629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RecordHandshakeFailureReason(HANDSHAKE_FAILURE_UNKNOWN); 631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY( 632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "Net.QuicSession.ConnectionClose.HandshakeFailureUnknown.QuicError", 633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error); 634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 637ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.QuicVersion", 638ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch connection()->version()); 6398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifyFactoryOfSessionGoingAway(); 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!callback_.is_null()) { 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR); 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) socket_->Close(); 6441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) QuicSession::OnConnectionClosed(error, from_peer); 645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(streams()->empty()); 646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CloseAllStreams(ERR_UNEXPECTED); 647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CloseAllObservers(ERR_UNEXPECTED); 6488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifyFactoryOfSessionClosedLater(); 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 651d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void QuicClientSession::OnSuccessfulVersionNegotiation( 652d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const QuicVersion& version) { 6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logger_->OnSuccessfulVersionNegotiation(version); 654d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) QuicSession::OnSuccessfulVersionNegotiation(version); 655d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 656d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 65723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void QuicClientSession::OnProofValid( 65823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const QuicCryptoClientConfig::CachedState& cached) { 65923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(cached.proof_valid()); 66023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 66123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!server_info_ || !server_info_->IsReadyToPersist()) { 66223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 66323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 66423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 66523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicServerInfo::State* state = server_info_->mutable_state(); 66623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 66723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state->server_config = cached.server_config(); 66823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state->source_address_token = cached.source_address_token(); 66923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state->server_config_sig = cached.signature(); 67023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state->certs = cached.certs(); 67123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 67223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) server_info_->Persist(); 67323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 67423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 67523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void QuicClientSession::OnProofVerifyDetailsAvailable( 67623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const ProofVerifyDetails& verify_details) { 6775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const ProofVerifyDetailsChromium* verify_details_chromium = 6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reinterpret_cast<const ProofVerifyDetailsChromium*>(&verify_details); 67923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CertVerifyResult* result_copy = new CertVerifyResult; 6805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result_copy->CopyFrom(verify_details_chromium->cert_verify_result); 68123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) cert_verify_result_.reset(result_copy); 6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pinning_failure_log_ = verify_details_chromium->pinning_failure_log; 6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logger_->OnCertificateVerified(*cert_verify_result_); 68423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 68523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicClientSession::StartReading() { 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (read_pending_) { 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_pending_ = true; 691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int rv = socket_->Read(read_buffer_.get(), 692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) read_buffer_->size(), 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&QuicClientSession::OnReadComplete, 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_factory_.GetWeakPtr())); 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rv == ERR_IO_PENDING) { 6961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) num_packets_read_ = 0; 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (++num_packets_read_ > 32) { 7011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) num_packets_read_ = 0; 7021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Data was read, process it. 703f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Schedule the work through the message loop to 1) prevent infinite 704f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // recursion and 2) avoid blocking the thread for too long. 7051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::MessageLoop::current()->PostTask( 7061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FROM_HERE, 7071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&QuicClientSession::OnReadComplete, 7081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_factory_.GetWeakPtr(), rv)); 7091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 7101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnReadComplete(rv); 7111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicClientSession::CloseSessionOnError(int error) { 715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.CloseSessionOnError", -error); 71658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CloseSessionOnErrorInner(error, QUIC_INTERNAL_ERROR); 7178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifyFactoryOfSessionClosed(); 718eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 72058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void QuicClientSession::CloseSessionOnErrorInner(int net_error, 72158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) QuicErrorCode quic_error) { 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!callback_.is_null()) { 72358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::ResetAndReturn(&callback_).Run(net_error); 724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CloseAllStreams(net_error); 7268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CloseAllObservers(net_error); 7278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) net_log_.AddEvent( 7288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NetLog::TYPE_QUIC_SESSION_CLOSE_ON_ERROR, 7298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NetLog::IntegerCallback("net_error", net_error)); 7308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (connection()->connected()) 732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) connection()->CloseConnection(quic_error, false); 7338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!connection()->connected()); 7348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicClientSession::CloseAllStreams(int net_error) { 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!streams()->empty()) { 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReliableQuicStream* stream = streams()->begin()->second; 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicStreamId id = stream->id(); 74058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static_cast<QuicReliableClientStream*>(stream)->OnError(net_error); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseStream(id); 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicClientSession::CloseAllObservers(int net_error) { 7468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) while (!observers_.empty()) { 7478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Observer* observer = *observers_.begin(); 7488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) observers_.erase(observer); 7498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) observer->OnSessionClosed(net_error); 7508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Value* QuicClientSession::GetInfoAsValue( 754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::set<HostPortPair>& aliases) { 7557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 756ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch dict->SetString("version", QuicVersionToString(connection()->version())); 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetInteger("open_streams", GetNumOpenStreams()); 758cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::ListValue* stream_list = new base::ListValue(); 759cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (base::hash_map<QuicStreamId, QuicDataStream*>::const_iterator it 760cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) = streams()->begin(); 761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != streams()->end(); 762cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream_list->Append(new base::StringValue( 764cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Uint64ToString(it->second->id()))); 765cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 766cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dict->Set("active_streams", stream_list); 767cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetInteger("total_streams", num_total_streams_); 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->SetString("peer_address", peer_address().ToString()); 770a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dict->SetString("connection_id", base::Uint64ToString(connection_id())); 7711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) dict->SetBoolean("connected", connection()->connected()); 772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const QuicConnectionStats& stats = connection()->GetStats(); 773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dict->SetInteger("packets_sent", stats.packets_sent); 774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dict->SetInteger("packets_received", stats.packets_received); 775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dict->SetInteger("packets_lost", stats.packets_lost); 776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SSLInfo ssl_info; 7771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dict->SetBoolean("secure", GetSSLInfo(&ssl_info) && ssl_info.cert.get()); 7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* alias_list = new base::ListValue(); 780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (std::set<HostPortPair>::const_iterator it = aliases.begin(); 7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != aliases.end(); it++) { 782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) alias_list->Append(new base::StringValue(it->ToString())); 7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dict->Set("aliases", alias_list); 7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dict; 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 789a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)base::WeakPtr<QuicClientSession> QuicClientSession::GetWeakPtr() { 790a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return weak_factory_.GetWeakPtr(); 791a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 792a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void QuicClientSession::OnReadComplete(int result) { 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_pending_ = false; 795b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (result == 0) 796b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) result = ERR_CONNECTION_CLOSED; 797b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 798b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (result < 0) { 799f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Closing session on read error: " << result; 80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ReadError", -result); 8018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifyFactoryOfSessionGoingAway(); 80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CloseSessionOnErrorInner(result, QUIC_PACKET_READ_ERROR); 8038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NotifyFactoryOfSessionClosedLater(); 804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 807f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) QuicEncryptedPacket packet(read_buffer_->data(), result); 808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint local_address; 809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint peer_address; 810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) socket_->GetLocalAddress(&local_address); 811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) socket_->GetPeerAddress(&peer_address); 812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ProcessUdpPacket might result in |this| being deleted, so we 813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // use a weak pointer to be safe. 814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection()->ProcessUdpPacket(local_address, peer_address, packet); 815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!connection()->connected()) { 8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NotifyFactoryOfSessionClosedLater(); 817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartReading(); 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicClientSession::NotifyFactoryOfSessionGoingAway() { 823effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch going_away_ = true; 8248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (stream_factory_) 8258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) stream_factory_->OnSessionGoingAway(this); 8268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 8278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicClientSession::NotifyFactoryOfSessionClosedLater() { 829effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!streams()->empty()) 830effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedOpenStreams(NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER); 831effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 832effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!going_away_) 833effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedNotGoingAway(NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER); 834effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 835effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch going_away_ = true; 836a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK_EQ(0u, GetNumOpenStreams()); 837a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(!connection()->connected()); 838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->PostTask( 839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, 8408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Bind(&QuicClientSession::NotifyFactoryOfSessionClosed, 841eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch weak_factory_.GetWeakPtr())); 842eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 8448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void QuicClientSession::NotifyFactoryOfSessionClosed() { 845effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!streams()->empty()) 846effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedOpenStreams(NOTIFY_FACTORY_OF_SESSION_CLOSED); 847effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 848effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!going_away_) 849effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RecordUnexpectedNotGoingAway(NOTIFY_FACTORY_OF_SESSION_CLOSED); 850effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 851effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch going_away_ = true; 852a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK_EQ(0u, GetNumOpenStreams()); 853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Will delete |this|. 8548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (stream_factory_) 8558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) stream_factory_->OnSessionClosed(this); 856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 857eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 85846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void QuicClientSession::OnConnectTimeout() { 85946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(callback_.is_null()); 86046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(IsEncryptionEstablished()); 86146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 86246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (IsCryptoHandshakeConfirmed()) 86346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 86446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // TODO(rch): re-enable this code once beta is cut. 8666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // if (stream_factory_) 8676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // stream_factory_->OnSessionConnectTimeout(this); 8686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // CloseAllStreams(ERR_QUIC_HANDSHAKE_FAILED); 8696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // DCHECK_EQ(0u, GetNumOpenStreams()); 87046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 87146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 873