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 <list>
      9 #include <map>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/logging.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "net/base/address_list.h"
     16 #include "net/base/completion_callback.h"
     17 #include "net/base/host_port_pair.h"
     18 #include "net/base/net_log.h"
     19 #include "net/base/network_change_notifier.h"
     20 #include "net/cert/cert_database.h"
     21 #include "net/proxy/proxy_server.h"
     22 #include "net/quic/quic_config.h"
     23 #include "net/quic/quic_crypto_stream.h"
     24 #include "net/quic/quic_http_stream.h"
     25 #include "net/quic/quic_protocol.h"
     26 
     27 namespace net {
     28 
     29 class CertVerifier;
     30 class ChannelIDService;
     31 class ClientSocketFactory;
     32 class HostResolver;
     33 class HttpServerProperties;
     34 class QuicClock;
     35 class QuicClientSession;
     36 class QuicConnectionHelper;
     37 class QuicCryptoClientStreamFactory;
     38 class QuicRandom;
     39 class QuicServerInfoFactory;
     40 class QuicServerId;
     41 class QuicStreamFactory;
     42 class TransportSecurityState;
     43 
     44 namespace test {
     45 class QuicStreamFactoryPeer;
     46 }  // namespace test
     47 
     48 // Encapsulates a pending request for a QuicHttpStream.
     49 // If the request is still pending when it is destroyed, it will
     50 // cancel the request with the factory.
     51 class NET_EXPORT_PRIVATE QuicStreamRequest {
     52  public:
     53   explicit QuicStreamRequest(QuicStreamFactory* factory);
     54   ~QuicStreamRequest();
     55 
     56   // For http, |is_https| is false.
     57   int Request(const HostPortPair& host_port_pair,
     58               bool is_https,
     59               PrivacyMode privacy_mode,
     60               base::StringPiece method,
     61               const BoundNetLog& net_log,
     62               const CompletionCallback& callback);
     63 
     64   void OnRequestComplete(int rv);
     65 
     66   scoped_ptr<QuicHttpStream> ReleaseStream();
     67 
     68   void set_stream(scoped_ptr<QuicHttpStream> stream);
     69 
     70   const BoundNetLog& net_log() const{
     71     return net_log_;
     72   }
     73 
     74  private:
     75   QuicStreamFactory* factory_;
     76   HostPortPair host_port_pair_;
     77   bool is_https_;
     78   BoundNetLog net_log_;
     79   CompletionCallback callback_;
     80   scoped_ptr<QuicHttpStream> stream_;
     81 
     82   DISALLOW_COPY_AND_ASSIGN(QuicStreamRequest);
     83 };
     84 
     85 // A factory for creating new QuicHttpStreams on top of a pool of
     86 // QuicClientSessions.
     87 class NET_EXPORT_PRIVATE QuicStreamFactory
     88     : public NetworkChangeNotifier::IPAddressObserver,
     89       public CertDatabase::Observer {
     90  public:
     91   QuicStreamFactory(
     92       HostResolver* host_resolver,
     93       ClientSocketFactory* client_socket_factory,
     94       base::WeakPtr<HttpServerProperties> http_server_properties,
     95       CertVerifier* cert_verifier,
     96       ChannelIDService* channel_id_service,
     97       TransportSecurityState* transport_security_state,
     98       QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory,
     99       QuicRandom* random_generator,
    100       QuicClock* clock,
    101       size_t max_packet_length,
    102       const std::string& user_agent_id,
    103       const QuicVersionVector& supported_versions,
    104       bool enable_port_selection,
    105       bool enable_time_based_loss_detection,
    106       bool always_require_handshake_confirmation,
    107       bool disable_connection_pooling,
    108       const QuicTagVector& connection_options);
    109   virtual ~QuicStreamFactory();
    110 
    111   // Creates a new QuicHttpStream to |host_port_pair| which will be
    112   // owned by |request|. |is_https| specifies if the protocol is https or not.
    113   // If a matching session already exists, this method will return OK.  If no
    114   // matching session exists, this will return ERR_IO_PENDING and will invoke
    115   // OnRequestComplete asynchronously.
    116   int Create(const HostPortPair& host_port_pair,
    117              bool is_https,
    118              PrivacyMode privacy_mode,
    119              base::StringPiece method,
    120              const BoundNetLog& net_log,
    121              QuicStreamRequest* request);
    122 
    123   // Called by a session when it becomes idle.
    124   void OnIdleSession(QuicClientSession* session);
    125 
    126   // Called by a session when it is going away and no more streams should be
    127   // created on it.
    128   void OnSessionGoingAway(QuicClientSession* session);
    129 
    130   // Called by a session after it shuts down.
    131   void OnSessionClosed(QuicClientSession* session);
    132 
    133   // Called by a session whose connection has timed out.
    134   void OnSessionConnectTimeout(QuicClientSession* session);
    135 
    136   // Cancels a pending request.
    137   void CancelRequest(QuicStreamRequest* request);
    138 
    139   // Closes all current sessions.
    140   void CloseAllSessions(int error);
    141 
    142   base::Value* QuicStreamFactoryInfoToValue() const;
    143 
    144   // Delete all cached state objects in |crypto_config_|.
    145   void ClearCachedStatesInCryptoConfig();
    146 
    147   // NetworkChangeNotifier::IPAddressObserver methods:
    148 
    149   // Until the servers support roaming, close all connections when the local
    150   // IP address changes.
    151   virtual void OnIPAddressChanged() OVERRIDE;
    152 
    153   // CertDatabase::Observer methods:
    154 
    155   // We close all sessions when certificate database is changed.
    156   virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE;
    157   virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE;
    158 
    159   bool require_confirmation() const {
    160     return require_confirmation_;
    161   }
    162 
    163   void set_require_confirmation(bool require_confirmation);
    164 
    165   QuicConnectionHelper* helper() { return helper_.get(); }
    166 
    167   bool enable_port_selection() const { return enable_port_selection_; }
    168 
    169   bool has_quic_server_info_factory() {
    170     return quic_server_info_factory_ != NULL;
    171   }
    172 
    173   void set_quic_server_info_factory(
    174       QuicServerInfoFactory* quic_server_info_factory) {
    175     DCHECK(!quic_server_info_factory_);
    176     quic_server_info_factory_ = quic_server_info_factory;
    177   }
    178 
    179  private:
    180   class Job;
    181   friend class test::QuicStreamFactoryPeer;
    182 
    183   // The key used to find session by ip. Includes
    184   // the ip address, port, and scheme.
    185   struct NET_EXPORT_PRIVATE IpAliasKey {
    186     IpAliasKey();
    187     IpAliasKey(IPEndPoint ip_endpoint, bool is_https);
    188     ~IpAliasKey();
    189 
    190     IPEndPoint ip_endpoint;
    191     bool is_https;
    192 
    193     // Needed to be an element of std::set.
    194     bool operator<(const IpAliasKey &other) const;
    195     bool operator==(const IpAliasKey &other) const;
    196   };
    197 
    198   typedef std::map<QuicServerId, QuicClientSession*> SessionMap;
    199   typedef std::map<QuicClientSession*, QuicServerId> SessionIdMap;
    200   typedef std::set<QuicServerId> AliasSet;
    201   typedef std::map<QuicClientSession*, AliasSet> SessionAliasMap;
    202   typedef std::set<QuicClientSession*> SessionSet;
    203   typedef std::map<IpAliasKey, SessionSet> IPAliasMap;
    204   typedef std::map<QuicServerId, QuicCryptoClientConfig*> CryptoConfigMap;
    205   typedef std::map<QuicServerId, Job*> JobMap;
    206   typedef std::map<QuicStreamRequest*, Job*> RequestMap;
    207   typedef std::set<QuicStreamRequest*> RequestSet;
    208   typedef std::map<Job*, RequestSet> JobRequestsMap;
    209 
    210   // Returns a newly created QuicHttpStream owned by the caller, if a
    211   // matching session already exists.  Returns NULL otherwise.
    212   scoped_ptr<QuicHttpStream> CreateIfSessionExists(const QuicServerId& key,
    213                                                    const BoundNetLog& net_log);
    214 
    215   bool OnResolution(const QuicServerId& server_id,
    216                     const AddressList& address_list);
    217   void OnJobComplete(Job* job, int rv);
    218   bool HasActiveSession(const QuicServerId& server_id) const;
    219   bool HasActiveJob(const QuicServerId& server_id) const;
    220   int CreateSession(const QuicServerId& server_id,
    221                     scoped_ptr<QuicServerInfo> quic_server_info,
    222                     const AddressList& address_list,
    223                     const BoundNetLog& net_log,
    224                     QuicClientSession** session);
    225   void ActivateSession(const QuicServerId& key,
    226                        QuicClientSession* session);
    227 
    228   // Initializes the cached state associated with |server_id| in
    229   // |crypto_config_| with the information in |server_info|.
    230   void InitializeCachedStateInCryptoConfig(
    231       const QuicServerId& server_id,
    232       const scoped_ptr<QuicServerInfo>& server_info);
    233 
    234   void ProcessGoingAwaySession(QuicClientSession* session,
    235                                const QuicServerId& server_id,
    236                                bool was_session_active);
    237 
    238   bool require_confirmation_;
    239   HostResolver* host_resolver_;
    240   ClientSocketFactory* client_socket_factory_;
    241   base::WeakPtr<HttpServerProperties> http_server_properties_;
    242   TransportSecurityState* transport_security_state_;
    243   QuicServerInfoFactory* quic_server_info_factory_;
    244   QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory_;
    245   QuicRandom* random_generator_;
    246   scoped_ptr<QuicClock> clock_;
    247   const size_t max_packet_length_;
    248 
    249   // The helper used for all connections.
    250   scoped_ptr<QuicConnectionHelper> helper_;
    251 
    252   // Contains owning pointers to all sessions that currently exist.
    253   SessionIdMap all_sessions_;
    254   // Contains non-owning pointers to currently active session
    255   // (not going away session, once they're implemented).
    256   SessionMap active_sessions_;
    257   // Map from session to set of aliases that this session is known by.
    258   SessionAliasMap session_aliases_;
    259   // Map from IP address to sessions which are connected to this address.
    260   IPAliasMap ip_aliases_;
    261 
    262   // Origins which have gone away recently.
    263   AliasSet gone_away_aliases_;
    264 
    265   const QuicConfig config_;
    266   QuicCryptoClientConfig crypto_config_;
    267 
    268   JobMap active_jobs_;
    269   JobRequestsMap job_requests_map_;
    270   RequestMap active_requests_;
    271 
    272   QuicVersionVector supported_versions_;
    273 
    274   // Determine if we should consistently select a client UDP port. If false,
    275   // then we will just let the OS select a random client port for each new
    276   // connection.
    277   bool enable_port_selection_;
    278 
    279   // Set if we always require handshake confirmation. If true, this will
    280   // introduce at least one RTT for the handshake before the client sends data.
    281   bool always_require_handshake_confirmation_;
    282 
    283   // Set if we do not want connection pooling.
    284   bool disable_connection_pooling_;
    285 
    286   // Each profile will (probably) have a unique port_seed_ value.  This value is
    287   // used to help seed a pseudo-random number generator (PortSuggester) so that
    288   // we consistently (within this profile) suggest the same ephemeral port when
    289   // we re-connect to any given server/port.  The differences between profiles
    290   // (probablistically) prevent two profiles from colliding in their ephemeral
    291   // port requests.
    292   uint64 port_seed_;
    293 
    294   // Local address of socket that was created in CreateSession.
    295   IPEndPoint local_address_;
    296   bool check_persisted_supports_quic_;
    297 
    298   base::WeakPtrFactory<QuicStreamFactory> weak_factory_;
    299 
    300   DISALLOW_COPY_AND_ASSIGN(QuicStreamFactory);
    301 };
    302 
    303 }  // namespace net
    304 
    305 #endif  // NET_QUIC_QUIC_STREAM_FACTORY_H_
    306