Home | History | Annotate | Download | only in spdy
      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 <map>
      9 #include <set>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/gtest_prod_util.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "net/base/host_port_pair.h"
     18 #include "net/base/ip_endpoint.h"
     19 #include "net/base/net_errors.h"
     20 #include "net/base/net_export.h"
     21 #include "net/base/network_change_notifier.h"
     22 #include "net/cert/cert_database.h"
     23 #include "net/proxy/proxy_config.h"
     24 #include "net/proxy/proxy_server.h"
     25 #include "net/socket/next_proto.h"
     26 #include "net/spdy/spdy_session_key.h"
     27 #include "net/ssl/ssl_config_service.h"
     28 
     29 namespace net {
     30 
     31 class AddressList;
     32 class BoundNetLog;
     33 class ClientSocketHandle;
     34 class HostResolver;
     35 class HttpServerProperties;
     36 class SpdySession;
     37 
     38 // This is a very simple pool for open SpdySessions.
     39 class NET_EXPORT SpdySessionPool
     40     : public NetworkChangeNotifier::IPAddressObserver,
     41       public SSLConfigService::Observer,
     42       public CertDatabase::Observer {
     43  public:
     44   typedef base::TimeTicks (*TimeFunc)(void);
     45 
     46   // |default_protocol| may be kProtoUnknown (e.g., if SPDY is
     47   // disabled), in which case it's set to a default value. Otherwise,
     48   // it must be a SPDY protocol.
     49   SpdySessionPool(
     50       HostResolver* host_resolver,
     51       SSLConfigService* ssl_config_service,
     52       const base::WeakPtr<HttpServerProperties>& http_server_properties,
     53       bool force_single_domain,
     54       bool enable_ip_pooling,
     55       bool enable_compression,
     56       bool enable_ping_based_connection_checking,
     57       NextProto default_protocol,
     58       size_t stream_initial_recv_window_size,
     59       size_t initial_max_concurrent_streams,
     60       size_t max_concurrent_streams_limit,
     61       SpdySessionPool::TimeFunc time_func,
     62       const std::string& trusted_spdy_proxy);
     63   virtual ~SpdySessionPool();
     64 
     65   // In the functions below, a session is "available" if this pool has
     66   // a reference to it and there is some SpdySessionKey for which
     67   // FindAvailableSession() will return it. A session is "unavailable"
     68   // if this pool has a reference to it but it won't be returned by
     69   // FindAvailableSession() for any SpdySessionKey; for example, this
     70   // can happen when a session receives a GOAWAY frame and is still
     71   // processing existing streams.
     72 
     73   // Create a new SPDY session from an existing socket.  There must
     74   // not already be a session for the given key. This pool must have
     75   // been constructed with a valid |default_protocol| value.
     76   //
     77   // |is_secure| can be false for testing or when SPDY is configured
     78   // to work with non-secure sockets. If |is_secure| is true,
     79   // |certificate_error_code| indicates that the certificate error
     80   // encountered when connecting the SSL socket, with OK meaning there
     81   // was no error.
     82   //
     83   // If successful, OK is returned and |available_session| will be
     84   // non-NULL and available. Otherwise, an error is returned and
     85   // |available_session| will be NULL.
     86   net::Error CreateAvailableSessionFromSocket(
     87       const SpdySessionKey& key,
     88       scoped_ptr<ClientSocketHandle> connection,
     89       const BoundNetLog& net_log,
     90       int certificate_error_code,
     91       base::WeakPtr<SpdySession>* available_session,
     92       bool is_secure);
     93 
     94   // Find an available session for the given key, or NULL if there isn't one.
     95   base::WeakPtr<SpdySession> FindAvailableSession(const SpdySessionKey& key,
     96                                                   const BoundNetLog& net_log);
     97 
     98   // Remove all mappings and aliases for the given session, which must
     99   // still be available. Except for in tests, this must be called by
    100   // the given session itself.
    101   void MakeSessionUnavailable(
    102       const base::WeakPtr<SpdySession>& available_session);
    103 
    104   // Removes an unavailable session from the pool.  Except for in
    105   // tests, this must be called by the given session itself.
    106   void RemoveUnavailableSession(
    107       const base::WeakPtr<SpdySession>& unavailable_session);
    108 
    109   // Close only the currently existing SpdySessions with |error|.
    110   // Let any new ones created while this method is running continue to
    111   // live.
    112   void CloseCurrentSessions(net::Error error);
    113 
    114   // Close only the currently existing SpdySessions that are idle.
    115   // Let any new ones created while this method is running continue to
    116   // live.
    117   void CloseCurrentIdleSessions();
    118 
    119   // Close all SpdySessions, including any new ones created in the process of
    120   // closing the current ones.
    121   void CloseAllSessions();
    122 
    123   // Creates a Value summary of the state of the spdy session pool. The caller
    124   // responsible for deleting the returned value.
    125   base::Value* SpdySessionPoolInfoToValue() const;
    126 
    127   base::WeakPtr<HttpServerProperties> http_server_properties() {
    128     return http_server_properties_;
    129   }
    130 
    131   // NetworkChangeNotifier::IPAddressObserver methods:
    132 
    133   // We flush all idle sessions and release references to the active ones so
    134   // they won't get re-used.  The active ones will either complete successfully
    135   // or error out due to the IP address change.
    136   virtual void OnIPAddressChanged() OVERRIDE;
    137 
    138   // SSLConfigService::Observer methods:
    139 
    140   // We perform the same flushing as described above when SSL settings change.
    141   virtual void OnSSLConfigChanged() OVERRIDE;
    142 
    143   // CertDatabase::Observer methods:
    144 
    145   // We perform the same flushing as described above when certificate database
    146   // is changed.
    147   virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE;
    148   virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE;
    149 
    150  private:
    151   friend class SpdySessionPoolPeer;  // For testing.
    152 
    153   typedef std::set<SpdySession*> SessionSet;
    154   typedef std::vector<base::WeakPtr<SpdySession> > WeakSessionList;
    155   typedef std::map<SpdySessionKey, base::WeakPtr<SpdySession> >
    156       AvailableSessionMap;
    157   typedef std::map<IPEndPoint, SpdySessionKey> AliasMap;
    158 
    159   // Returns true iff |session| is in |available_sessions_|.
    160   bool IsSessionAvailable(const base::WeakPtr<SpdySession>& session) const;
    161 
    162   // Returns a normalized version of the given key suitable for lookup
    163   // into |available_sessions_|.
    164   const SpdySessionKey& NormalizeListKey(const SpdySessionKey& key) const;
    165 
    166   // Map the given key to the given session. There must not already be
    167   // a mapping for |key|.
    168   void MapKeyToAvailableSession(const SpdySessionKey& key,
    169                                 const base::WeakPtr<SpdySession>& session);
    170 
    171   // Returns an iterator into |available_sessions_| for the given key,
    172   // which may be equal to |available_sessions_.end()|.
    173   AvailableSessionMap::iterator LookupAvailableSessionByKey(
    174       const SpdySessionKey& key);
    175 
    176   // Remove the mapping of the given key, which must exist.
    177   void UnmapKey(const SpdySessionKey& key);
    178 
    179   // Remove all aliases for |key| from the aliases table.
    180   void RemoveAliases(const SpdySessionKey& key);
    181 
    182   // Get a copy of the current sessions as a list of WeakPtrs. Used by
    183   // CloseCurrentSessionsHelper() below.
    184   WeakSessionList GetCurrentSessions() const;
    185 
    186   // Close only the currently existing SpdySessions with |error|.  Let
    187   // any new ones created while this method is running continue to
    188   // live. If |idle_only| is true only idle sessions are closed.
    189   void CloseCurrentSessionsHelper(
    190       Error error,
    191       const std::string& description,
    192       bool idle_only);
    193 
    194   const base::WeakPtr<HttpServerProperties> http_server_properties_;
    195 
    196   // The set of all sessions. This is a superset of the sessions in
    197   // |available_sessions_|.
    198   //
    199   // |sessions_| owns all its SpdySession objects.
    200   SessionSet sessions_;
    201 
    202   // This is a map of available sessions by key. A session may appear
    203   // more than once in this map if it has aliases.
    204   AvailableSessionMap available_sessions_;
    205 
    206   // A map of IPEndPoint aliases for sessions.
    207   AliasMap aliases_;
    208 
    209   static bool g_force_single_domain;
    210 
    211   const scoped_refptr<SSLConfigService> ssl_config_service_;
    212   HostResolver* const resolver_;
    213 
    214   // Defaults to true. May be controlled via SpdySessionPoolPeer for tests.
    215   bool verify_domain_authentication_;
    216   bool enable_sending_initial_data_;
    217   bool force_single_domain_;
    218   bool enable_ip_pooling_;
    219   bool enable_compression_;
    220   bool enable_ping_based_connection_checking_;
    221   const NextProto default_protocol_;
    222   size_t stream_initial_recv_window_size_;
    223   size_t initial_max_concurrent_streams_;
    224   size_t max_concurrent_streams_limit_;
    225   TimeFunc time_func_;
    226 
    227   // This SPDY proxy is allowed to push resources from origins that are
    228   // different from those of their associated streams.
    229   HostPortPair trusted_spdy_proxy_;
    230 
    231   DISALLOW_COPY_AND_ASSIGN(SpdySessionPool);
    232 };
    233 
    234 }  // namespace net
    235 
    236 #endif  // NET_SPDY_SPDY_SESSION_POOL_H_
    237