Home | History | Annotate | Download | only in quic
      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_QUIC_QUIC_STREAM_FACTORY_H_
      6 #define NET_QUIC_QUIC_STREAM_FACTORY_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/memory/weak_ptr.h"
     13 #include "net/base/address_list.h"
     14 #include "net/base/completion_callback.h"
     15 #include "net/base/host_port_pair.h"
     16 #include "net/base/net_log.h"
     17 #include "net/base/network_change_notifier.h"
     18 #include "net/cert/cert_database.h"
     19 #include "net/proxy/proxy_server.h"
     20 #include "net/quic/quic_config.h"
     21 #include "net/quic/quic_crypto_stream.h"
     22 #include "net/quic/quic_http_stream.h"
     23 #include "net/quic/quic_protocol.h"
     24 
     25 namespace net {
     26 
     27 class CertVerifier;
     28 class ClientSocketFactory;
     29 class HostResolver;
     30 class HttpServerProperties;
     31 class QuicClock;
     32 class QuicClientSession;
     33 class QuicConnectionHelper;
     34 class QuicCryptoClientStreamFactory;
     35 class QuicRandom;
     36 class QuicStreamFactory;
     37 
     38 namespace test {
     39 class QuicStreamFactoryPeer;
     40 }  // namespace test
     41 
     42 // Encapsulates a pending request for a QuicHttpStream.
     43 // If the request is still pending when it is destroyed, it will
     44 // cancel the request with the factory.
     45 class NET_EXPORT_PRIVATE QuicStreamRequest {
     46  public:
     47   explicit QuicStreamRequest(QuicStreamFactory* factory);
     48   ~QuicStreamRequest();
     49 
     50   // For http, |is_https| is false and |cert_verifier| can be null.
     51   int Request(const HostPortProxyPair& host_port_proxy_pair,
     52               bool is_https,
     53               CertVerifier* cert_verifier,
     54               const BoundNetLog& net_log,
     55               const CompletionCallback& callback);
     56 
     57   void OnRequestComplete(int rv);
     58 
     59   scoped_ptr<QuicHttpStream> ReleaseStream();
     60 
     61   void set_stream(scoped_ptr<QuicHttpStream> stream);
     62 
     63   const BoundNetLog& net_log() const{
     64     return net_log_;
     65   }
     66 
     67  private:
     68   QuicStreamFactory* factory_;
     69   HostPortProxyPair host_port_proxy_pair_;
     70   bool is_https_;
     71   CertVerifier* cert_verifier_;
     72   BoundNetLog net_log_;
     73   CompletionCallback callback_;
     74   scoped_ptr<QuicHttpStream> stream_;
     75 
     76   DISALLOW_COPY_AND_ASSIGN(QuicStreamRequest);
     77 };
     78 
     79 // A factory for creating new QuicHttpStreams on top of a pool of
     80 // QuicClientSessions.
     81 class NET_EXPORT_PRIVATE QuicStreamFactory
     82     : public NetworkChangeNotifier::IPAddressObserver,
     83       public CertDatabase::Observer {
     84  public:
     85   QuicStreamFactory(
     86       HostResolver* host_resolver,
     87       ClientSocketFactory* client_socket_factory,
     88       base::WeakPtr<HttpServerProperties> http_server_properties,
     89       QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory,
     90       QuicRandom* random_generator,
     91       QuicClock* clock,
     92       size_t max_packet_length);
     93   virtual ~QuicStreamFactory();
     94 
     95   // Creates a new QuicHttpStream to |host_port_proxy_pair| which will be
     96   // owned by |request|. |is_https| specifies if the protocol is https or not.
     97   // |cert_verifier| is used by ProofVerifier for verifying the certificate
     98   // chain and signature. For http, this can be null. If a matching session
     99   // already exists, this method will return OK.  If no matching session exists,
    100   // this will return ERR_IO_PENDING and will invoke OnRequestComplete
    101   // asynchronously.
    102   int Create(const HostPortProxyPair& host_port_proxy_pair,
    103              bool is_https,
    104              CertVerifier* cert_verifier,
    105              const BoundNetLog& net_log,
    106              QuicStreamRequest* request);
    107 
    108   // Returns a newly created QuicHttpStream owned by the caller, if a
    109   // matching session already exists.  Returns NULL otherwise.
    110   scoped_ptr<QuicHttpStream> CreateIfSessionExists(
    111       const HostPortProxyPair& host_port_proxy_pair,
    112       const BoundNetLog& net_log);
    113 
    114   // Called by a session when it becomes idle.
    115   void OnIdleSession(QuicClientSession* session);
    116 
    117   // Called by a session when it is going away and no more streams should be
    118   // created on it.
    119   void OnSessionGoingAway(QuicClientSession* session);
    120 
    121   // Called by a session after it shuts down.
    122   void OnSessionClosed(QuicClientSession* session);
    123 
    124   // Cancels a pending request.
    125   void CancelRequest(QuicStreamRequest* request);
    126 
    127   // Closes all current sessions.
    128   void CloseAllSessions(int error);
    129 
    130   base::Value* QuicStreamFactoryInfoToValue() const;
    131 
    132   // NetworkChangeNotifier::IPAddressObserver methods:
    133 
    134   // Until the servers support roaming, close all connections when the local
    135   // IP address changes.
    136   virtual void OnIPAddressChanged() OVERRIDE;
    137 
    138   // CertDatabase::Observer methods:
    139 
    140   // We close all sessions when certificate database is changed.
    141   virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE;
    142   virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE;
    143 
    144   bool require_confirmation() const { return require_confirmation_; }
    145 
    146   void set_require_confirmation(bool require_confirmation) {
    147     require_confirmation_ = require_confirmation;
    148   }
    149 
    150   QuicConnectionHelper* helper() { return helper_.get(); }
    151 
    152  private:
    153   class Job;
    154   friend class test::QuicStreamFactoryPeer;
    155 
    156   typedef std::map<HostPortProxyPair, QuicClientSession*> SessionMap;
    157   typedef std::set<HostPortProxyPair> AliasSet;
    158   typedef std::map<QuicClientSession*, AliasSet> SessionAliasMap;
    159   typedef std::set<QuicClientSession*> SessionSet;
    160   typedef std::map<HostPortProxyPair, QuicCryptoClientConfig*> CryptoConfigMap;
    161   typedef std::map<HostPortPair, HostPortProxyPair> CanonicalHostMap;
    162   typedef std::map<HostPortProxyPair, Job*> JobMap;
    163   typedef std::map<QuicStreamRequest*, Job*> RequestMap;
    164   typedef std::set<QuicStreamRequest*> RequestSet;
    165   typedef std::map<Job*, RequestSet> JobRequestsMap;
    166 
    167   void OnJobComplete(Job* job, int rv);
    168   bool HasActiveSession(const HostPortProxyPair& host_port_proxy_pair);
    169   bool HasActiveJob(const HostPortProxyPair& host_port_proxy_pair);
    170   int CreateSession(const HostPortProxyPair& host_port_proxy_pair,
    171                     bool is_https,
    172                     CertVerifier* cert_verifier,
    173                     const AddressList& address_list,
    174                     const BoundNetLog& net_log,
    175                     QuicClientSession** session);
    176   void ActivateSession(const HostPortProxyPair& host_port_proxy_pair,
    177                        QuicClientSession* session);
    178 
    179   QuicCryptoClientConfig* GetOrCreateCryptoConfig(
    180       const HostPortProxyPair& host_port_proxy_pair);
    181 
    182   // If |host_port_proxy_pair| suffix contains ".c.youtube.com" (in future we
    183   // could support other suffixes), then populate |crypto_config| with a
    184   // canonical server config data from |canonical_hostname_to_origin_map_| for
    185   // that suffix.
    186   void PopulateFromCanonicalConfig(
    187       const HostPortProxyPair& host_port_proxy_pair,
    188       QuicCryptoClientConfig* crypto_config);
    189 
    190   bool require_confirmation_;
    191   HostResolver* host_resolver_;
    192   ClientSocketFactory* client_socket_factory_;
    193   base::WeakPtr<HttpServerProperties> http_server_properties_;
    194   QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory_;
    195   QuicRandom* random_generator_;
    196   scoped_ptr<QuicClock> clock_;
    197   const size_t max_packet_length_;
    198 
    199   // The helper used for all connections.
    200   scoped_ptr<QuicConnectionHelper> helper_;
    201 
    202   // Contains owning pointers to all sessions that currently exist.
    203   SessionSet all_sessions_;
    204   // Contains non-owning pointers to currently active session
    205   // (not going away session, once they're implemented).
    206   SessionMap active_sessions_;
    207   SessionAliasMap session_aliases_;
    208 
    209   // Contains owning pointers to QuicCryptoClientConfig. QuicCryptoClientConfig
    210   // contains configuration and cached state about servers.
    211   // TODO(rtenneti): Persist all_crypto_configs_ to disk and decide when to
    212   // clear the data in the map.
    213   CryptoConfigMap all_crypto_configs_;
    214 
    215   // Contains a map of servers which could share the same server config. Map
    216   // from a Canonical host/port (host is some postfix of host names) to an
    217   // actual origin, which has a plausible set of initial certificates (or at
    218   // least server public key).
    219   CanonicalHostMap canonical_hostname_to_origin_map_;
    220 
    221   // Contains list of suffixes (for exmaple ".c.youtube.com",
    222   // ".googlevideo.com") of cannoncial hostnames.
    223   std::vector<std::string> cannoncial_suffixes_;
    224 
    225   QuicConfig config_;
    226 
    227   JobMap active_jobs_;
    228   JobRequestsMap job_requests_map_;
    229   RequestMap active_requests_;
    230 
    231   base::WeakPtrFactory<QuicStreamFactory> weak_factory_;
    232 
    233   // Each profile will (probably) have a unique port_seed_ value.  This value is
    234   // used to help seed a pseudo-random number generator (PortSuggester) so that
    235   // we consistently (within this profile) suggest the same ephemeral port when
    236   // we re-connect to any given server/port.  The differences between profiles
    237   // (probablistically) prevent two profiles from colliding in their ephemeral
    238   // port requests.
    239   uint64 port_seed_;
    240 
    241   DISALLOW_COPY_AND_ASSIGN(QuicStreamFactory);
    242 };
    243 
    244 }  // namespace net
    245 
    246 #endif  // NET_QUIC_QUIC_STREAM_FACTORY_H_
    247