// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_QUIC_QUIC_STREAM_FACTORY_H_ #define NET_QUIC_QUIC_STREAM_FACTORY_H_ #include #include #include #include "base/memory/weak_ptr.h" #include "net/base/address_list.h" #include "net/base/completion_callback.h" #include "net/base/host_port_pair.h" #include "net/base/net_log.h" #include "net/base/network_change_notifier.h" #include "net/cert/cert_database.h" #include "net/proxy/proxy_server.h" #include "net/quic/quic_config.h" #include "net/quic/quic_crypto_stream.h" #include "net/quic/quic_http_stream.h" #include "net/quic/quic_protocol.h" namespace net { class CertVerifier; class ClientSocketFactory; class HostResolver; class HttpServerProperties; class QuicClock; class QuicClientSession; class QuicConnectionHelper; class QuicCryptoClientStreamFactory; class QuicRandom; class QuicStreamFactory; namespace test { class QuicStreamFactoryPeer; } // namespace test // Encapsulates a pending request for a QuicHttpStream. // If the request is still pending when it is destroyed, it will // cancel the request with the factory. class NET_EXPORT_PRIVATE QuicStreamRequest { public: explicit QuicStreamRequest(QuicStreamFactory* factory); ~QuicStreamRequest(); // For http, |is_https| is false and |cert_verifier| can be null. int Request(const HostPortProxyPair& host_port_proxy_pair, bool is_https, CertVerifier* cert_verifier, const BoundNetLog& net_log, const CompletionCallback& callback); void OnRequestComplete(int rv); scoped_ptr ReleaseStream(); void set_stream(scoped_ptr stream); const BoundNetLog& net_log() const{ return net_log_; } private: QuicStreamFactory* factory_; HostPortProxyPair host_port_proxy_pair_; bool is_https_; CertVerifier* cert_verifier_; BoundNetLog net_log_; CompletionCallback callback_; scoped_ptr stream_; DISALLOW_COPY_AND_ASSIGN(QuicStreamRequest); }; // A factory for creating new QuicHttpStreams on top of a pool of // QuicClientSessions. class NET_EXPORT_PRIVATE QuicStreamFactory : public NetworkChangeNotifier::IPAddressObserver, public CertDatabase::Observer { public: QuicStreamFactory( HostResolver* host_resolver, ClientSocketFactory* client_socket_factory, base::WeakPtr http_server_properties, QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, QuicRandom* random_generator, QuicClock* clock, size_t max_packet_length); virtual ~QuicStreamFactory(); // Creates a new QuicHttpStream to |host_port_proxy_pair| which will be // owned by |request|. |is_https| specifies if the protocol is https or not. // |cert_verifier| is used by ProofVerifier for verifying the certificate // chain and signature. For http, this can be null. If a matching session // already exists, this method will return OK. If no matching session exists, // this will return ERR_IO_PENDING and will invoke OnRequestComplete // asynchronously. int Create(const HostPortProxyPair& host_port_proxy_pair, bool is_https, CertVerifier* cert_verifier, const BoundNetLog& net_log, QuicStreamRequest* request); // Returns a newly created QuicHttpStream owned by the caller, if a // matching session already exists. Returns NULL otherwise. scoped_ptr CreateIfSessionExists( const HostPortProxyPair& host_port_proxy_pair, const BoundNetLog& net_log); // Called by a session when it becomes idle. void OnIdleSession(QuicClientSession* session); // Called by a session when it is going away and no more streams should be // created on it. void OnSessionGoingAway(QuicClientSession* session); // Called by a session after it shuts down. void OnSessionClosed(QuicClientSession* session); // Cancels a pending request. void CancelRequest(QuicStreamRequest* request); // Closes all current sessions. void CloseAllSessions(int error); base::Value* QuicStreamFactoryInfoToValue() const; // NetworkChangeNotifier::IPAddressObserver methods: // Until the servers support roaming, close all connections when the local // IP address changes. virtual void OnIPAddressChanged() OVERRIDE; // CertDatabase::Observer methods: // We close all sessions when certificate database is changed. virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE; virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE; bool require_confirmation() const { return require_confirmation_; } void set_require_confirmation(bool require_confirmation) { require_confirmation_ = require_confirmation; } QuicConnectionHelper* helper() { return helper_.get(); } private: class Job; friend class test::QuicStreamFactoryPeer; typedef std::map SessionMap; typedef std::set AliasSet; typedef std::map SessionAliasMap; typedef std::set SessionSet; typedef std::map CryptoConfigMap; typedef std::map CanonicalHostMap; typedef std::map JobMap; typedef std::map RequestMap; typedef std::set RequestSet; typedef std::map JobRequestsMap; void OnJobComplete(Job* job, int rv); bool HasActiveSession(const HostPortProxyPair& host_port_proxy_pair); bool HasActiveJob(const HostPortProxyPair& host_port_proxy_pair); int CreateSession(const HostPortProxyPair& host_port_proxy_pair, bool is_https, CertVerifier* cert_verifier, const AddressList& address_list, const BoundNetLog& net_log, QuicClientSession** session); void ActivateSession(const HostPortProxyPair& host_port_proxy_pair, QuicClientSession* session); QuicCryptoClientConfig* GetOrCreateCryptoConfig( const HostPortProxyPair& host_port_proxy_pair); // If |host_port_proxy_pair| suffix contains ".c.youtube.com" (in future we // could support other suffixes), then populate |crypto_config| with a // canonical server config data from |canonical_hostname_to_origin_map_| for // that suffix. void PopulateFromCanonicalConfig( const HostPortProxyPair& host_port_proxy_pair, QuicCryptoClientConfig* crypto_config); bool require_confirmation_; HostResolver* host_resolver_; ClientSocketFactory* client_socket_factory_; base::WeakPtr http_server_properties_; QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory_; QuicRandom* random_generator_; scoped_ptr clock_; const size_t max_packet_length_; // The helper used for all connections. scoped_ptr helper_; // Contains owning pointers to all sessions that currently exist. SessionSet all_sessions_; // Contains non-owning pointers to currently active session // (not going away session, once they're implemented). SessionMap active_sessions_; SessionAliasMap session_aliases_; // Contains owning pointers to QuicCryptoClientConfig. QuicCryptoClientConfig // contains configuration and cached state about servers. // TODO(rtenneti): Persist all_crypto_configs_ to disk and decide when to // clear the data in the map. CryptoConfigMap all_crypto_configs_; // Contains a map of servers which could share the same server config. Map // from a Canonical host/port (host is some postfix of host names) to an // actual origin, which has a plausible set of initial certificates (or at // least server public key). CanonicalHostMap canonical_hostname_to_origin_map_; // Contains list of suffixes (for exmaple ".c.youtube.com", // ".googlevideo.com") of cannoncial hostnames. std::vector cannoncial_suffixes_; QuicConfig config_; JobMap active_jobs_; JobRequestsMap job_requests_map_; RequestMap active_requests_; base::WeakPtrFactory weak_factory_; // Each profile will (probably) have a unique port_seed_ value. This value is // used to help seed a pseudo-random number generator (PortSuggester) so that // we consistently (within this profile) suggest the same ephemeral port when // we re-connect to any given server/port. The differences between profiles // (probablistically) prevent two profiles from colliding in their ephemeral // port requests. uint64 port_seed_; DISALLOW_COPY_AND_ASSIGN(QuicStreamFactory); }; } // namespace net #endif // NET_QUIC_QUIC_STREAM_FACTORY_H_