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_POOL_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_SPDY_SPDY_SESSION_POOL_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <list> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/gtest_prod_util.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/cert_database.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/host_port_pair.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/ip_endpoint.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/network_change_notifier.h" 223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/ssl_config_service.h" 233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/proxy/proxy_config.h" 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/proxy/proxy_server.h" 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/spdy/spdy_settings_storage.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass AddressList; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BoundNetLog; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ClientSocketHandle; 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass HostResolver; 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HttpNetworkSession; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdySession; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is a very simple pool for open SpdySessions. 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdySessionPool 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : public NetworkChangeNotifier::IPAddressObserver, 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public SSLConfigService::Observer, 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public CertDatabase::Observer { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen explicit SpdySessionPool(HostResolver* host_resolver, 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SSLConfigService* ssl_config_service); 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual ~SpdySessionPool(); 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Either returns an existing SpdySession or creates a new SpdySession for 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // use. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<SpdySession> Get( 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HostPortProxyPair& host_port_proxy_pair, 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log); 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the maximum concurrent sessions per domain. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void set_max_sessions_per_domain(int max) { 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (max >= 1) 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_max_sessions_per_domain = max; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Builds a SpdySession from an existing SSL socket. Users should try 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // calling Get() first to use an existing SpdySession so we don't get 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // multiple SpdySessions per domain. Note that ownership of |connection| is 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // transferred from the caller to the SpdySession. 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |certificate_error_code| is used to indicate the certificate error 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // encountered when connecting the SSL socket. OK means there was no error. 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // For testing, setting is_secure to false allows Spdy to connect with a 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // pre-existing TCP socket. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns OK on success, and the |spdy_session| will be provided. 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns an error on failure, and |spdy_session| will be NULL. 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::Error GetSpdySessionFromSocket( 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HostPortProxyPair& host_port_proxy_pair, 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClientSocketHandle* connection, 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log, 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int certificate_error_code, 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<SpdySession>* spdy_session, 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool is_secure); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(willchan): Consider renaming to HasReusableSession, since perhaps we 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // should be creating a new session. 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool HasSession(const HostPortProxyPair& host_port_proxy_pair) const; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Close all SpdySessions, including any new ones created in the process of 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // closing the current ones. 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CloseAllSessions(); 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Close only the currently existing SpdySessions. Let any new ones created 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // continue to live. 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void CloseCurrentSessions(); 8693a4a82bca0155ddfbec36777ade7d6dad6bfb61Kristian Monsen // Close only the idle SpdySessions. 8793a4a82bca0155ddfbec36777ade7d6dad6bfb61Kristian Monsen void CloseIdleSessions(); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Removes a SpdySession from the SpdySessionPool. This should only be called 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // by SpdySession, because otherwise session->state_ is not set to CLOSED. 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Remove(const scoped_refptr<SpdySession>& session); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Creates a Value summary of the state of the spdy session pool. The caller 94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // responsible for deleting the returned value. 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Value* SpdySessionPoolInfoToValue() const; 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SpdySettingsStorage* mutable_spdy_settings() { return &spdy_settings_; } 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const SpdySettingsStorage& spdy_settings() const { return spdy_settings_; } 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // NetworkChangeNotifier::IPAddressObserver methods: 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We flush all idle sessions and release references to the active ones so 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // they won't get re-used. The active ones will either complete successfully 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // or error out due to the IP address change. 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnIPAddressChanged(); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // SSLConfigService::Observer methods: 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We perform the same flushing as described above when SSL settings change. 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void OnSSLConfigChanged(); 1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // A debugging mode where we compress all accesses through a single domain. 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static void ForceSingleDomain() { g_force_single_domain = true; } 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Controls whether the pool allows use of a common session for domains 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // which share IP address resolutions. 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static void enable_ip_pooling(bool value) { g_enable_ip_pooling = value; } 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // CertDatabase::Observer methods: 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void OnUserCertAdded(const X509Certificate* cert); 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void OnCertTrustChanged(const X509Certificate* cert); 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class SpdySessionPoolPeer; // For testing. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class SpdyNetworkTransactionTest; // For testing. 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateOverflow); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::list<scoped_refptr<SpdySession> > SpdySessionList; 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick typedef std::map<HostPortProxyPair, SpdySessionList*> SpdySessionsMap; 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::map<IPEndPoint, HostPortProxyPair> SpdyAliasMap; 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<SpdySession> GetExistingSession( 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SpdySessionList* list, 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const BoundNetLog& net_log) const; 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<SpdySession> GetFromAlias( 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const HostPortProxyPair& host_port_proxy_pair, 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const BoundNetLog& net_log, 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool record_histograms) const; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Helper functions for manipulating the lists. 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HostPortProxyPair& NormalizeListPair( 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const HostPortProxyPair& host_port_proxy_pair) const; 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySessionList* AddSessionList( 1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HostPortProxyPair& host_port_proxy_pair); 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SpdySessionList* GetSessionList( 1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HostPortProxyPair& host_port_proxy_pair) const; 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void RemoveSessionList(const HostPortProxyPair& host_port_proxy_pair); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Does a DNS cache lookup for |pair|, and returns the |addresses| found. 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Returns true if addresses found, false otherwise. 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool LookupAddresses(const HostPortProxyPair& pair, 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AddressList* addresses) const; 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Add a set of |addresses| as IP-equivalent addresses for |pair|. 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void AddAliases(const AddressList& addresses, const HostPortProxyPair& pair); 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Remove all aliases for |pair| from the aliases table. 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void RemoveAliases(const HostPortProxyPair& pair); 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SpdySettingsStorage spdy_settings_; 161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is our weak session pool - one session per domain. 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SpdySessionsMap sessions_; 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A map of IPEndPoint aliases for sessions. 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SpdyAliasMap aliases_; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static size_t g_max_sessions_per_domain; 168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static bool g_force_single_domain; 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static bool g_enable_ip_pooling; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const scoped_refptr<SSLConfigService> ssl_config_service_; 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HostResolver* resolver_; 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(SpdySessionPool); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // NET_SPDY_SPDY_SESSION_POOL_H_ 180