spdy_session_pool.h revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_SPDY_SPDY_SESSION_POOL_H_
6#define NET_SPDY_SPDY_SESSION_POOL_H_
7
8#include <list>
9#include <map>
10#include <string>
11
12#include "base/basictypes.h"
13#include "base/gtest_prod_util.h"
14#include "base/memory/ref_counted.h"
15#include "net/base/host_port_pair.h"
16#include "net/base/ip_endpoint.h"
17#include "net/base/net_errors.h"
18#include "net/base/net_export.h"
19#include "net/base/network_change_notifier.h"
20#include "net/cert/cert_database.h"
21#include "net/proxy/proxy_config.h"
22#include "net/proxy/proxy_server.h"
23#include "net/socket/next_proto.h"
24#include "net/spdy/spdy_session_key.h"
25#include "net/ssl/ssl_config_service.h"
26
27namespace net {
28
29class AddressList;
30class BoundNetLog;
31class ClientSocketHandle;
32class HostResolver;
33class HttpServerProperties;
34class SpdySession;
35
36// This is a very simple pool for open SpdySessions.
37class NET_EXPORT SpdySessionPool
38    : public NetworkChangeNotifier::IPAddressObserver,
39      public SSLConfigService::Observer,
40      public CertDatabase::Observer {
41 public:
42  typedef base::TimeTicks (*TimeFunc)(void);
43
44  SpdySessionPool(HostResolver* host_resolver,
45                  SSLConfigService* ssl_config_service,
46                  HttpServerProperties* http_server_properties,
47                  size_t max_sessions_per_domain,
48                  bool force_single_domain,
49                  bool enable_ip_pooling,
50                  bool enable_credential_frames,
51                  bool enable_compression,
52                  bool enable_ping_based_connection_checking,
53                  NextProto default_protocol,
54                  size_t stream_initial_recv_window_size,
55                  size_t initial_max_concurrent_streams,
56                  size_t max_concurrent_streams_limit,
57                  SpdySessionPool::TimeFunc time_func,
58                  const std::string& trusted_spdy_proxy);
59  virtual ~SpdySessionPool();
60
61  // Either returns an existing SpdySession or creates a new SpdySession for
62  // use.
63  scoped_refptr<SpdySession> Get(
64      const SpdySessionKey& spdy_session_key,
65      const BoundNetLog& net_log);
66
67  // Only returns a SpdySession if it already exists.
68  scoped_refptr<SpdySession> GetIfExists(
69      const SpdySessionKey& spdy_session_key,
70      const BoundNetLog& net_log);
71
72  // Builds a SpdySession from an existing SSL socket.  Users should try
73  // calling Get() first to use an existing SpdySession so we don't get
74  // multiple SpdySessions per domain.  Note that ownership of |connection| is
75  // transferred from the caller to the SpdySession.
76  // |certificate_error_code| is used to indicate the certificate error
77  // encountered when connecting the SSL socket.  OK means there was no error.
78  // For testing, setting is_secure to false allows Spdy to connect with a
79  // pre-existing TCP socket.
80  // Returns OK on success, and the |spdy_session| will be provided.
81  // Returns an error on failure, and |spdy_session| will be NULL.
82  net::Error GetSpdySessionFromSocket(
83      const SpdySessionKey& spdy_session_key,
84      ClientSocketHandle* connection,
85      const BoundNetLog& net_log,
86      int certificate_error_code,
87      scoped_refptr<SpdySession>* spdy_session,
88      bool is_secure);
89
90  // TODO(willchan): Consider renaming to HasReusableSession, since perhaps we
91  // should be creating a new session. WARNING: Because of IP connection pooling
92  // using the HostCache, if HasSession() returns true at one point, it does not
93  // imply the SpdySessionPool will still have a matching session in the near
94  // future, since the HostCache's entry may have expired.
95  bool HasSession(const SpdySessionKey& spdy_session_key) const;
96
97  // Close all SpdySessions, including any new ones created in the process of
98  // closing the current ones.
99  void CloseAllSessions();
100  // Close only the currently existing SpdySessions with |error|.
101  // Let any new ones created continue to live.
102  void CloseCurrentSessions(net::Error error);
103  // Close only the idle SpdySessions.
104  void CloseIdleSessions();
105
106  // Removes a SpdySession from the SpdySessionPool. This should only be called
107  // by SpdySession, because otherwise session->state_ is not set to CLOSED.
108  void Remove(const scoped_refptr<SpdySession>& session);
109
110  // Creates a Value summary of the state of the spdy session pool. The caller
111  // responsible for deleting the returned value.
112  base::Value* SpdySessionPoolInfoToValue() const;
113
114  HttpServerProperties* http_server_properties() {
115    return http_server_properties_;
116  }
117
118  // NetworkChangeNotifier::IPAddressObserver methods:
119
120  // We flush all idle sessions and release references to the active ones so
121  // they won't get re-used.  The active ones will either complete successfully
122  // or error out due to the IP address change.
123  virtual void OnIPAddressChanged() OVERRIDE;
124
125  // SSLConfigService::Observer methods:
126
127  // We perform the same flushing as described above when SSL settings change.
128  virtual void OnSSLConfigChanged() OVERRIDE;
129
130  // CertDatabase::Observer methods:
131  virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE;
132  virtual void OnCertTrustChanged(const X509Certificate* cert) OVERRIDE;
133
134 private:
135  friend class SpdySessionPoolPeer;  // For testing.
136
137  typedef std::list<scoped_refptr<SpdySession> > SpdySessionList;
138  typedef std::map<SpdySessionKey, SpdySessionList*> SpdySessionsMap;
139  typedef std::map<IPEndPoint, SpdySessionKey> SpdyAliasMap;
140
141
142  scoped_refptr<SpdySession> GetInternal(
143      const SpdySessionKey& spdy_session_key,
144      const BoundNetLog& net_log,
145      bool only_use_existing_sessions);
146  scoped_refptr<SpdySession> GetExistingSession(
147      SpdySessionList* list,
148      const BoundNetLog& net_log) const;
149  scoped_refptr<SpdySession> GetFromAlias(
150      const SpdySessionKey& spdy_session_key,
151      const BoundNetLog& net_log,
152      bool record_histograms) const;
153
154  // Helper functions for manipulating the lists.
155  const SpdySessionKey& NormalizeListKey(
156      const SpdySessionKey& spdy_session_key) const;
157  SpdySessionList* AddSessionList(
158      const SpdySessionKey& spdy_session_key);
159  SpdySessionList* GetSessionList(
160      const SpdySessionKey& spdy_session_key) const;
161  void RemoveSessionList(const SpdySessionKey& spdy_session_key);
162
163  // Does a DNS cache lookup for |spdy_session_key|, and returns
164  // the |addresses| found.
165  // Returns true if addresses found, false otherwise.
166  bool LookupAddresses(const SpdySessionKey& spdy_session_key,
167                       const BoundNetLog& net_log,
168                       AddressList* addresses) const;
169
170  // Add |address| as an IP-equivalent address for |spdy_session_key|.
171  void AddAlias(const IPEndPoint& address,
172                const SpdySessionKey& spdy_session_key);
173
174  // Remove all aliases for |spdy_session_key| from the aliases table.
175  void RemoveAliases(const SpdySessionKey& spdy_session_key);
176
177  // Removes |session| from the session list associated with |spdy_session_key|.
178  // Returns true if the session was removed, false otherwise.
179  bool RemoveFromSessionList(const scoped_refptr<SpdySession>& session,
180                             const SpdySessionKey& spdy_session_key);
181
182  HttpServerProperties* const http_server_properties_;
183
184  // This is our weak session pool - one session per domain.
185  SpdySessionsMap sessions_;
186  // A map of IPEndPoint aliases for sessions.
187  SpdyAliasMap aliases_;
188
189  static bool g_force_single_domain;
190
191  const scoped_refptr<SSLConfigService> ssl_config_service_;
192  HostResolver* const resolver_;
193
194  // Defaults to true. May be controlled via SpdySessionPoolPeer for tests.
195  bool verify_domain_authentication_;
196  bool enable_sending_initial_settings_;
197  size_t max_sessions_per_domain_;
198  bool force_single_domain_;
199  bool enable_ip_pooling_;
200  bool enable_credential_frames_;
201  bool enable_compression_;
202  bool enable_ping_based_connection_checking_;
203  NextProto default_protocol_;
204  size_t stream_initial_recv_window_size_;
205  size_t initial_max_concurrent_streams_;
206  size_t max_concurrent_streams_limit_;
207  TimeFunc time_func_;
208
209  // This SPDY proxy is allowed to push resources from origins that are
210  // different from those of their associated streams.
211  HostPortPair trusted_spdy_proxy_;
212
213  DISALLOW_COPY_AND_ASSIGN(SpdySessionPool);
214};
215
216}  // namespace net
217
218#endif  // NET_SPDY_SPDY_SESSION_POOL_H_
219