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 net_log()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 require_confirmation()159 bool require_confirmation() const { 160 return require_confirmation_; 161 } 162 163 void set_require_confirmation(bool require_confirmation); 164 helper()165 QuicConnectionHelper* helper() { return helper_.get(); } 166 enable_port_selection()167 bool enable_port_selection() const { return enable_port_selection_; } 168 has_quic_server_info_factory()169 bool has_quic_server_info_factory() { 170 return quic_server_info_factory_ != NULL; 171 } 172 set_quic_server_info_factory(QuicServerInfoFactory * quic_server_info_factory)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