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