1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NET_SPDY_SPDY_SESSION_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_SPDY_SPDY_SESSION_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <deque> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <list> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <queue> 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/gtest_prod_util.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/linked_ptr.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/task.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/io_buffer.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/load_states.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/request_priority.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/ssl_config_service.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/upload_data_stream.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/client_socket.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/client_socket_handle.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_framer.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_io_buffer.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_protocol.h" 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_session_pool.h" 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This is somewhat arbitrary and not really fixed, but it will always work 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// reasonably with ethernet. Chop the world into 2-packet chunks. This is 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// somewhat arbitrary, but is reasonably small and ensures that we elicit 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ACKs quickly from TCP (because TCP tries to only ACK every other packet). 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int kMss = 1430; 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int kMaxSpdyFrameChunkSize = (2 * kMss) - spdy::SpdyFrame::size(); 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BoundNetLog; 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SpdySettingsStorage; 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SpdyStream; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SSLInfo; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdySession : public base::RefCounted<SpdySession>, 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public spdy::SpdyFramerVisitorInterface { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a new SpdySession. 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |host_port_proxy_pair| is the host/port that this session connects to, and 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the proxy configuration settings that it's using. 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // |spdy_session_pool| is the SpdySessionPool that owns us. Its lifetime must 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // strictly be greater than |this|. 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |session| is the HttpNetworkSession. |net_log| is the NetLog that we log 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // network events to. 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySession(const HostPortProxyPair& host_port_proxy_pair, 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySessionPool* spdy_session_pool, 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySettingsStorage* spdy_settings, 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog* net_log); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HostPortPair& host_port_pair() const { 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return host_port_proxy_pair_.first; 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HostPortProxyPair& host_port_proxy_pair() const { 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return host_port_proxy_pair_; 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get a pushed stream for a given |url|. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the server initiates a stream, it might already exist for a given path. 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The server might also not have initiated the stream yet, but indicated it 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // will via X-Associated-Content. Writes the stream out to |spdy_stream|. 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns a net error code. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int GetPushStream( 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<SpdyStream>* spdy_stream, 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& stream_net_log); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a new stream for a given |url|. Writes it out to |spdy_stream|. 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns a net error code, possibly ERR_IO_PENDING. 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int CreateStream( 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RequestPriority priority, 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<SpdyStream>* spdy_stream, 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& stream_net_log, 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove PendingCreateStream objects on transaction deletion 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CancelPendingCreateStreams(const scoped_refptr<SpdyStream>* spdy_stream); 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Used by SpdySessionPool to initialize with a pre-existing SSL socket. For 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // testing, setting is_secure to false allows initialization with a 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // pre-existing TCP socket. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns OK on success, or an error on failure. 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::Error InitializeWithSocket(ClientSocketHandle* connection, 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool is_secure, 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int certificate_error_code); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check to see if this SPDY session can support an additional domain. 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If the session is un-authenticated, then this call always returns true. 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // For SSL-based sessions, verifies that the certificate in use by this 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // session provides authentication for the domain. 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // NOTE: This function can have false negatives on some platforms. 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool VerifyDomainAuthentication(const std::string& domain); 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1062c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Send the SYN frame for |stream_id|. This also sends PING message to check 1072c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // the status of the connection. 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int WriteSynStream( 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyStreamId stream_id, 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RequestPriority priority, 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyControlFlags flags, 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const linked_ptr<spdy::SpdyHeaderBlock>& headers); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Write a data frame to the stream. 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Used to create and queue a data frame for the given stream. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int WriteStreamData(spdy::SpdyStreamId stream_id, net::IOBuffer* data, 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int len, 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyDataFlags flags); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Close a stream. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CloseStream(spdy::SpdyStreamId stream_id, int status); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reset a stream by sending a RST_STREAM frame with given status code. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Also closes the stream. Was not piggybacked to CloseStream since not 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // all of the calls to CloseStream necessitate sending a RST_STREAM. 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ResetStream(spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if a stream is active. 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool IsStreamActive(spdy::SpdyStreamId stream_id) const; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The LoadState is used for informing the user of the current network 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // status, such as "resolving host", "connecting", etc. 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LoadState GetLoadState() const; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fills SSL info in |ssl_info| and returns true when SSL is in use. 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Fills SSL Certificate Request info |cert_request_info| and returns 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // true when SSL is in use. 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Enable or disable SSL. 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void SetSSLMode(bool enable) { use_ssl_ = enable; } 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static bool SSLMode() { return use_ssl_; } 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Enable or disable flow control. 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static void set_flow_control(bool enable) { use_flow_control_ = enable; } 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static bool flow_control() { return use_flow_control_; } 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Sets the max concurrent streams per session. 151513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch static void set_max_concurrent_streams(size_t value) { 152513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch max_concurrent_stream_limit_ = value; 153513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 154513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch static size_t max_concurrent_streams() { 155513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return max_concurrent_stream_limit_; 156513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 157513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1582c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Enable sending of PING frame with each request. 1592c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static void set_enable_ping_based_connection_checking(bool enable) { 1602c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun enable_ping_based_connection_checking_ = enable; 1612c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 1622c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static bool enable_ping_based_connection_checking() { 1632c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return enable_ping_based_connection_checking_; 1642c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 1652c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Send WINDOW_UPDATE frame, called by a stream whenever receive window 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // size is increased. 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void SendWindowUpdate(spdy::SpdyStreamId stream_id, int delta_window_size); 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If session is closed, no new streams/transactions should be created. 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool IsClosed() const { return state_ == CLOSED; } 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Closes this session. This will close all active streams and mark 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the session as permanently closed. 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |err| should not be OK; this function is intended to be called on 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // error. 1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |remove_from_pool| indicates whether to also remove the session from the 1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // session pool. 1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void CloseSessionOnError(net::Error err, bool remove_from_pool); 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Retrieves information on the current state of the SPDY session as a 182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Value. Caller takes possession of the returned value. 183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Value* GetInfoAsValue() const; 184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Indicates whether the session is being reused after having successfully 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // used to send/receive data in the past. 1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool IsReused() const { 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return frames_received_ > 0; 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Returns true if the underlying transport socket ever had any reads or 192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // writes. 193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool WasEverUsed() const { 194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return connection_->socket()->WasEverUsed(); 195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void set_spdy_session_pool(SpdySessionPool* pool) { 198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick spdy_session_pool_ = NULL; 199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 20193a4a82bca0155ddfbec36777ade7d6dad6bfb61Kristian Monsen // Returns true if session is not currently active 20293a4a82bca0155ddfbec36777ade7d6dad6bfb61Kristian Monsen bool is_active() const { 20393a4a82bca0155ddfbec36777ade7d6dad6bfb61Kristian Monsen return !active_streams_.empty(); 20493a4a82bca0155ddfbec36777ade7d6dad6bfb61Kristian Monsen } 20593a4a82bca0155ddfbec36777ade7d6dad6bfb61Kristian Monsen 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Access to the number of active and pending streams. These are primarily 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // available for testing and diagnostics. 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t num_active_streams() const { return active_streams_.size(); } 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t num_unclaimed_pushed_streams() const { 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return unclaimed_pushed_streams_.size(); 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const BoundNetLog& net_log() const { return net_log_; } 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int GetPeerAddress(AddressList* address) const; 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int GetLocalAddress(IPEndPoint* address) const; 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class base::RefCounted<SpdySession>; 2202c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Allow tests to access our innards for testing purposes. 2212c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, Ping); 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, GetActivePushStream); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct PendingCreateStream { 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingCreateStream(const GURL& url, RequestPriority priority, 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<SpdyStream>* spdy_stream, 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& stream_net_log, 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback) 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : url(&url), priority(priority), spdy_stream(spdy_stream), 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch stream_net_log(&stream_net_log), callback(callback) { } 23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const GURL* url; 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen RequestPriority priority; 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<SpdyStream>* spdy_stream; 23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const BoundNetLog* stream_net_log; 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CompletionCallback* callback; 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::queue<PendingCreateStream, std::list< PendingCreateStream> > 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingCreateStreamQueue; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap; 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only HTTP push a stream. 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick typedef std::map<std::string, scoped_refptr<SpdyStream> > PushedStreamMap; 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::priority_queue<SpdyIOBuffer> OutputQueue; 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 245201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch struct CallbackResultPair { 246201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CallbackResultPair() : callback(NULL), result(OK) {} 247201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CallbackResultPair(CompletionCallback* callback_in, int result_in) 248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch : callback(callback_in), result(result_in) {} 249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CompletionCallback* callback; 251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int result; 252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch typedef std::map<const scoped_refptr<SpdyStream>*, CallbackResultPair> 255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch PendingCallbackMap; 256201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen enum State { 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IDLE, 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CONNECTING, 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CONNECTED, 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CLOSED 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen enum { kDefaultMaxConcurrentStreams = 10 }; 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~SpdySession(); 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ProcessPendingCreateStreams(); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int CreateStreamImpl( 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RequestPriority priority, 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<SpdyStream>* spdy_stream, 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& stream_net_log); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Control frame handlers. 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnSyn(const spdy::SpdySynStreamControlFrame& frame, 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const linked_ptr<spdy::SpdyHeaderBlock>& headers); 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnSynReply(const spdy::SpdySynReplyControlFrame& frame, 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const linked_ptr<spdy::SpdyHeaderBlock>& headers); 280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void OnHeaders(const spdy::SpdyHeadersControlFrame& frame, 281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const linked_ptr<spdy::SpdyHeaderBlock>& headers); 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void OnRst(const spdy::SpdyRstStreamControlFrame& frame); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame); 2842c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void OnPing(const spdy::SpdyPingControlFrame& frame); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnSettings(const spdy::SpdySettingsControlFrame& frame); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnWindowUpdate(const spdy::SpdyWindowUpdateControlFrame& frame); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // IO Callbacks 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnReadComplete(int result); 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnWriteComplete(int result); 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Send relevant SETTINGS. This is generally called on connection setup. 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void SendSettings(); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Handle SETTINGS. Either when we send settings, or when we receive a 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // SETTINGS ontrol frame, update our SpdySession accordingly. 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void HandleSettings(const spdy::SpdySettings& settings); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2992c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Send the PING (preface-PING and trailing-PING) frames. 3002c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void SendPrefacePingIfNoneInFlight(); 3012c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3022c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Send PING if there are no PINGs in flight and we haven't heard from server. 3032c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void SendPrefacePing(); 3042c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3052c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Send a PING after delay. Don't post a PING if there is already 3062c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // a trailing PING pending. 3072c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void PlanToSendTrailingPing(); 3082c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3092c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Send a PING if there is no |trailing_ping_pending_|. This PING verifies 3102c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // that the requests are being received by the server. 3112c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void SendTrailingPing(); 3122c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3132c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Send the PING frame. 3142c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void WritePingFrame(uint32 unique_id); 3152c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3162c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Post a CheckPingStatus call after delay. Don't post if there is already 3172c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // CheckPingStatus running. 3182c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void PlanToCheckPingStatus(); 3192c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3202c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Check the status of the connection. It calls |CloseSessionOnError| if we 3212c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // haven't received any data in |kHungInterval| time period. 3222c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun void CheckPingStatus(base::TimeTicks last_check_time); 3232c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Start reading from the socket. 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns OK on success, or an error on failure. 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::Error ReadSocket(); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Write current data to the socket. 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void WriteSocketLater(); 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void WriteSocket(); 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get a new stream id. 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int GetNewStreamId(); 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Queue a frame for sending. 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |frame| is the frame to send. 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |priority| is the priority for insertion into the queue. 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |stream| is the stream which this IO is associated with (or NULL). 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void QueueFrame(spdy::SpdyFrame* frame, spdy::SpdyPriority priority, 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyStream* stream); 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Track active streams in the active stream list. 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ActivateStream(SpdyStream* stream); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void DeleteStream(spdy::SpdyStreamId id, int status); 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Removes this session from the session pool. 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RemoveFromPool(); 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if we have a pending pushed-stream for this url 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the stream if found (and returns it from the pending 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // list), returns NULL otherwise. 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<SpdyStream> GetActivePushStream(const std::string& url); 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Calls OnResponseReceived(). 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if successful. 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool Respond(const spdy::SpdyHeaderBlock& headers, 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const scoped_refptr<SpdyStream> stream); 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RecordHistograms(); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Closes all streams. Used as part of shutdown. 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CloseAllStreams(net::Error status); 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Invokes a user callback for stream creation. We provide this method so it 365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // can be deferred to the MessageLoop, so we avoid re-entrancy problems. 366201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch void InvokeUserStreamCreationCallback(scoped_refptr<SpdyStream>* stream); 367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 36872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // SpdyFramerVisitorInterface: 36972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void OnError(spdy::SpdyFramer*); 37072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id, 37172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const char* data, 37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t len); 37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void OnControl(const spdy::SpdyControlFrame* frame); 37472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3752c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun virtual bool OnControlFrameHeaderData(spdy::SpdyStreamId stream_id, 3762c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun const char* header_data, 3772c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun size_t len); 3782c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3792c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun virtual void OnDataFrameHeader(const spdy::SpdyDataFrame* frame); 3802c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3812c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // -------------------------- 3822c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Helper methods for testing 3832c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // -------------------------- 3842c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static void set_connection_at_risk_of_loss_ms(int duration) { 3852c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun connection_at_risk_of_loss_ms_ = duration; 3862c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 3872c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static int connection_at_risk_of_loss_ms() { 3882c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return connection_at_risk_of_loss_ms_; 3892c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 3902c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3912c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static void set_trailing_ping_delay_time_ms(int duration) { 3922c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun trailing_ping_delay_time_ms_ = duration; 3932c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 3942c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static int trailing_ping_delay_time_ms() { 3952c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return trailing_ping_delay_time_ms_; 3962c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 3972c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 3982c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static void set_hung_interval_ms(int duration) { 3992c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun hung_interval_ms_ = duration; 4002c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 4012c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static int hung_interval_ms() { 4022c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun return hung_interval_ms_; 4032c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun } 4042c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 4052c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun int64 pings_in_flight() const { return pings_in_flight_; } 4062c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 4072c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun uint32 next_ping_id() const { return next_ping_id_; } 4082c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 4092c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun base::TimeTicks received_data_time() const { return received_data_time_; } 4102c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 4112c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun bool trailing_ping_pending() const { return trailing_ping_pending_; } 4122c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 4132c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun bool check_ping_status_pending() const { return check_ping_status_pending_; } 4142c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Callbacks for the Spdy session. 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallbackImpl<SpdySession> read_callback_; 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallbackImpl<SpdySession> write_callback_; 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Used for posting asynchronous IO tasks. We use this even though 4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SpdySession is refcounted because we don't need to keep the SpdySession 4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // alive if the last reference is within a RunnableMethod. Just revoke the 4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // method. 4233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ScopedRunnableMethodFactory<SpdySession> method_factory_; 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 425201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Map of the SpdyStreams for which we have a pending Task to invoke a 426201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // callback. This is necessary since, before we invoke said callback, it's 427201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // possible that the request is cancelled. 428201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch PendingCallbackMap pending_callback_map_; 429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The domain this session is connected to. 4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HostPortProxyPair host_port_proxy_pair_; 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 433731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // |spdy_session_pool_| owns us, therefore its lifetime must exceed ours. We 434731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // set this to NULL after we are removed from the pool. 435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SpdySessionPool* spdy_session_pool_; 436731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SpdySettingsStorage* const spdy_settings_; 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The socket handle for this session. 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ClientSocketHandle> connection_; 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The read buffer used to read data from the socket. 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<IOBuffer> read_buffer_; 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool read_pending_; 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int stream_hi_water_mark_; // The next stream id to use. 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Queue, for each priority, of pending Create Streams that have not 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // yet been satisfied 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PendingCreateStreamQueue create_stream_queues_[NUM_PRIORITIES]; 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Map from stream id to all active streams. Streams are active in the sense 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that they have a consumer (typically SpdyNetworkTransaction and regardless 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of whether or not there is currently any ongoing IO [might be waiting for 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the server to start pushing the stream]) or there are still network events 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // incoming even though the consumer has already gone away (cancellation). 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(willchan): Perhaps we should separate out cancelled streams and move 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // them into a separate ActiveStreamMap, and not deliver network events to 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // them? 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ActiveStreamMap active_streams_; 4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Map of all the streams that have already started to be pushed by the 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // server, but do not have consumers yet. 4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PushedStreamMap unclaimed_pushed_streams_; 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // As we gather data to be sent, we put it into the output queue. 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OutputQueue queue_; 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The packet we are currently sending. 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool write_pending_; // Will be true when a write is in progress. 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdyIOBuffer in_flight_write_; // This is the write buffer in progress. 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flag if we have a pending message scheduled for WriteSocket. 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool delayed_write_pending_; 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flag if we're using an SSL connection for this SpdySession. 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_secure_; 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Certificate error code when using a secure connection. 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int certificate_error_code_; 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Spdy Frame state. 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyFramer spdy_framer_; 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If an error has occurred on the session, the session is effectively 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // dead. Record this error here. When no error has occurred, |error_| will 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // be OK. 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::Error error_; 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch State state_; 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Limits 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t max_concurrent_streams_; // 0 if no limit 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Some statistics counters for the session. 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int streams_initiated_count_; 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int streams_pushed_count_; 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int streams_pushed_and_claimed_count_; 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int streams_abandoned_count_; 4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int frames_received_; 49821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int bytes_received_; 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool sent_settings_; // Did this session send settings when it started. 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool received_settings_; // Did this session receive at least one settings 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // frame. 50221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int stalled_streams_; // Count of streams that were ever stalled. 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5042c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Count of all pings on the wire, for which we have not gotten a response. 5052c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun int64 pings_in_flight_; 5062c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5072c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // This is the next ping_id (unique_id) to be sent in PING frame. 5082c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun uint32 next_ping_id_; 5092c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5102c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // This is the last time we have received data. 5112c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun base::TimeTicks received_data_time_; 5122c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5132c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Indicate if we have already scheduled a delayed task to send a trailing 5142c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // ping (and we never have more than one scheduled at a time). 5152c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun bool trailing_ping_pending_; 5162c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5172c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Indicate if we have already scheduled a delayed task to check the ping 5182c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // status. 5192c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun bool check_ping_status_pending_; 5202c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5212c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Indicate if we need to send a ping (generally, a trailing ping). This helps 5222c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // us to decide if we need yet another trailing ping, or if it would be a 5232c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // waste of effort (and MUST not be done). 5242c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun bool need_to_send_ping_; 5252c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Initial send window size for the session; can be changed by an 5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // arriving SETTINGS frame; newly created streams use this value for the 5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // initial send window size. 5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int initial_send_window_size_; 5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Initial receive window size for the session; there are plans to add a 5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // command line switch that would cause a SETTINGS frame with window size 5333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // announcement to be sent on startup; newly created streams will use 5343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // this value for the initial receive window size. 5353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int initial_recv_window_size_; 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog net_log_; 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static bool use_ssl_; 5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static bool use_flow_control_; 541513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch static size_t max_concurrent_stream_limit_; 5422c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5432c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // This enables or disables connection health checking system. 5442c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static bool enable_ping_based_connection_checking_; 5452c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5462c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // |connection_at_risk_of_loss_ms_| is an optimization to avoid sending 5472c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // wasteful preface pings (when we just got some data). 5482c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // 5492c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // If it is zero (the most conservative figure), then we always send the 5502c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // preface ping (when none are in flight). 5512c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // 5522c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // It is common for TCP/IP sessions to time out in about 3-5 minutes. 5532c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // Certainly if it has been more than 3 minutes, we do want to send a preface 5542c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // ping. 5552c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // 5562c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // We don't think any connection will time out in under about 10 seconds. So 5572c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // this might as well be set to something conservative like 10 seconds. Later, 5582c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // we could adjust it to send fewer pings perhaps. 5592c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static int connection_at_risk_of_loss_ms_; 5602c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5612c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // This is the amount of time (in milliseconds) we wait before sending a 5622c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // trailing ping. We use a trailing ping (sent after all data) to get an 5632c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // effective acknowlegement from the server that it has indeed received all 5642c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // (prior) data frames. With that assurance, we are willing to enter into a 5652c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // wait state for responses to our last data frame(s) without further pings. 5662c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static int trailing_ping_delay_time_ms_; 5672c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun 5682c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // The amount of time (in milliseconds) that we are willing to tolerate with 5692c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // no data received (of any form), while there is a ping in flight, before we 5702c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun // declare the connection to be hung. 5712c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun static int hung_interval_ms_; 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass NetLogSpdySynParameter : public NetLog::EventParameters { 5754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch public: 5764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch NetLogSpdySynParameter(const linked_ptr<spdy::SpdyHeaderBlock>& headers, 5774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch spdy::SpdyControlFlags flags, 578201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SpdyStreamId id, 579201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch spdy::SpdyStreamId associated_stream); 5804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const linked_ptr<spdy::SpdyHeaderBlock>& GetHeaders() const { 5824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return headers_; 5834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 5844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 58572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual Value* ToValue() const; 58672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch private: 5884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch virtual ~NetLogSpdySynParameter(); 5894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const linked_ptr<spdy::SpdyHeaderBlock> headers_; 5914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const spdy::SpdyControlFlags flags_; 5924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const spdy::SpdyStreamId id_; 593201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const spdy::SpdyStreamId associated_stream_; 5944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 5954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DISALLOW_COPY_AND_ASSIGN(NetLogSpdySynParameter); 5964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}; 5974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // NET_SPDY_SPDY_SESSION_H_ 601