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.
5 #ifndef NET_QUIC_QUIC_STREAM_FACTORY_H_
6 #define NET_QUIC_QUIC_STREAM_FACTORY_H_
13 #include "base/logging.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/time/time.h"
16 #include "net/base/address_list.h"
17 #include "net/base/completion_callback.h"
18 #include "net/base/host_port_pair.h"
19 #include "net/base/network_change_notifier.h"
20 #include "net/cert/cert_database.h"
21 #include "net/log/net_log.h"
22 #include "net/proxy/proxy_server.h"
23 #include "net/quic/network_connection.h"
24 #include "net/quic/quic_chromium_client_session.h"
25 #include "net/quic/quic_config.h"
26 #include "net/quic/quic_crypto_stream.h"
27 #include "net/quic/quic_http_stream.h"
28 #include "net/quic/quic_protocol.h"
29 #include "net/ssl/ssl_config_service.h"
33 class CertPolicyEnforcer
;
35 class ChannelIDService
;
36 class ClientSocketFactory
;
38 class HttpServerProperties
;
40 class QuicChromiumClientSession
;
41 class QuicConnectionHelper
;
42 class QuicCryptoClientStreamFactory
;
44 class QuicServerInfoFactory
;
46 class QuicStreamFactory
;
47 class TransportSecurityState
;
50 class QuicStreamFactoryPeer
;
53 // Encapsulates a pending request for a QuicHttpStream.
54 // If the request is still pending when it is destroyed, it will
55 // cancel the request with the factory.
56 class NET_EXPORT_PRIVATE QuicStreamRequest
{
58 explicit QuicStreamRequest(QuicStreamFactory
* factory
);
61 // For http, |is_https| is false.
62 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
63 // passed to CertVerifier::Verify.
64 int Request(const HostPortPair
& host_port_pair
,
66 PrivacyMode privacy_mode
,
67 int cert_verify_flags
,
68 base::StringPiece origin_host
,
69 base::StringPiece method
,
70 const BoundNetLog
& net_log
,
71 const CompletionCallback
& callback
);
73 void OnRequestComplete(int rv
);
75 // Helper method that calls |factory_|'s GetTimeDelayForWaitingJob(). It
76 // returns the amount of time waiting job should be delayed.
77 base::TimeDelta
GetTimeDelayForWaitingJob() const;
79 scoped_ptr
<QuicHttpStream
> ReleaseStream();
81 void set_stream(scoped_ptr
<QuicHttpStream
> stream
);
83 const std::string
& origin_host() const { return origin_host_
; }
85 PrivacyMode
privacy_mode() const { return privacy_mode_
; }
87 const BoundNetLog
& net_log() const{
92 QuicStreamFactory
* factory_
;
93 HostPortPair host_port_pair_
;
94 std::string origin_host_
;
96 PrivacyMode privacy_mode_
;
98 CompletionCallback callback_
;
99 scoped_ptr
<QuicHttpStream
> stream_
;
101 DISALLOW_COPY_AND_ASSIGN(QuicStreamRequest
);
104 // A factory for creating new QuicHttpStreams on top of a pool of
105 // QuicChromiumClientSessions.
106 class NET_EXPORT_PRIVATE QuicStreamFactory
107 : public NetworkChangeNotifier::IPAddressObserver
,
108 public SSLConfigService::Observer
,
109 public CertDatabase::Observer
{
112 HostResolver
* host_resolver
,
113 ClientSocketFactory
* client_socket_factory
,
114 base::WeakPtr
<HttpServerProperties
> http_server_properties
,
115 CertVerifier
* cert_verifier
,
116 CertPolicyEnforcer
* cert_policy_enforcer
,
117 ChannelIDService
* channel_id_service
,
118 TransportSecurityState
* transport_security_state
,
119 QuicCryptoClientStreamFactory
* quic_crypto_client_stream_factory
,
120 QuicRandom
* random_generator
,
122 size_t max_packet_length
,
123 const std::string
& user_agent_id
,
124 const QuicVersionVector
& supported_versions
,
125 bool enable_port_selection
,
126 bool always_require_handshake_confirmation
,
127 bool disable_connection_pooling
,
128 float load_server_info_timeout_srtt_multiplier
,
129 bool enable_connection_racing
,
130 bool enable_non_blocking_io
,
131 bool disable_disk_cache
,
133 int max_number_of_lossy_connections
,
134 float packet_loss_threshold
,
135 int max_recent_disabled_reasons
,
136 int threshold_timeouts_with_streams_open
,
137 int threshold_public_resets_post_handshake
,
138 int socket_receive_buffer_size
,
140 const QuicTagVector
& connection_options
);
141 ~QuicStreamFactory() override
;
143 // Creates a new QuicHttpStream to |host_port_pair| which will be
144 // owned by |request|. |is_https| specifies if the protocol is https or not.
145 // If a matching session already exists, this method will return OK. If no
146 // matching session exists, this will return ERR_IO_PENDING and will invoke
147 // OnRequestComplete asynchronously.
148 int Create(const HostPortPair
& host_port_pair
,
150 PrivacyMode privacy_mode
,
151 int cert_verify_flags
,
152 base::StringPiece origin_host
,
153 base::StringPiece method
,
154 const BoundNetLog
& net_log
,
155 QuicStreamRequest
* request
);
157 // If |packet_loss_rate| is greater than or equal to |packet_loss_threshold_|
158 // it marks QUIC as recently broken for the port of the session. Increments
159 // |number_of_lossy_connections_| by port. If |number_of_lossy_connections_|
160 // is greater than or equal to |max_number_of_lossy_connections_| then it
161 // disables QUIC. If QUIC is disabled then it closes the connection.
163 // Returns true if QUIC is disabled for the port of the session.
164 bool OnHandshakeConfirmed(QuicChromiumClientSession
* session
,
165 float packet_loss_rate
);
167 // Returns true if QUIC is disabled for this port.
168 bool IsQuicDisabled(uint16 port
);
170 // Returns reason QUIC is disabled for this port, or QUIC_DISABLED_NOT if not.
171 QuicChromiumClientSession::QuicDisabledReason
QuicDisabledReason(
174 // Returns reason QUIC is disabled as string for net-internals, or
175 // returns empty string if QUIC is not disabled.
176 const char* QuicDisabledReasonString() const;
178 // Called by a session when it becomes idle.
179 void OnIdleSession(QuicChromiumClientSession
* session
);
181 // Called by a session when it is going away and no more streams should be
183 void OnSessionGoingAway(QuicChromiumClientSession
* session
);
185 // Called by a session after it shuts down.
186 void OnSessionClosed(QuicChromiumClientSession
* session
);
188 // Called by a session whose connection has timed out.
189 void OnSessionConnectTimeout(QuicChromiumClientSession
* session
);
191 // Cancels a pending request.
192 void CancelRequest(QuicStreamRequest
* request
);
194 // Closes all current sessions.
195 void CloseAllSessions(int error
);
197 scoped_ptr
<base::Value
> QuicStreamFactoryInfoToValue() const;
199 // Delete all cached state objects in |crypto_config_|.
200 void ClearCachedStatesInCryptoConfig();
202 // NetworkChangeNotifier::IPAddressObserver methods:
204 // Until the servers support roaming, close all connections when the local
205 // IP address changes.
206 void OnIPAddressChanged() override
;
208 // SSLConfigService::Observer methods:
210 // We perform the same flushing as described above when SSL settings change.
211 void OnSSLConfigChanged() override
;
213 // CertDatabase::Observer methods:
215 // We close all sessions when certificate database is changed.
216 void OnCertAdded(const X509Certificate
* cert
) override
;
217 void OnCACertChanged(const X509Certificate
* cert
) override
;
219 bool require_confirmation() const {
220 return require_confirmation_
;
223 void set_require_confirmation(bool require_confirmation
);
225 // It returns the amount of time waiting job should be delayed.
226 base::TimeDelta
GetTimeDelayForWaitingJob(const QuicServerId
& server_id
);
228 QuicConnectionHelper
* helper() { return helper_
.get(); }
230 bool enable_port_selection() const { return enable_port_selection_
; }
232 bool has_quic_server_info_factory() {
233 return quic_server_info_factory_
!= NULL
;
236 void set_quic_server_info_factory(
237 QuicServerInfoFactory
* quic_server_info_factory
) {
238 DCHECK(!quic_server_info_factory_
);
239 quic_server_info_factory_
= quic_server_info_factory
;
242 bool enable_connection_racing() const { return enable_connection_racing_
; }
243 void set_enable_connection_racing(bool enable_connection_racing
) {
244 enable_connection_racing_
= enable_connection_racing
;
247 int socket_receive_buffer_size() const { return socket_receive_buffer_size_
; }
249 bool delay_tcp_race() const { return delay_tcp_race_
; }
253 friend class test::QuicStreamFactoryPeer
;
254 FRIEND_TEST_ALL_PREFIXES(HttpStreamFactoryTest
, QuicLossyProxyMarkedAsBad
);
256 // The key used to find session by ip. Includes
257 // the ip address, port, and scheme.
258 struct NET_EXPORT_PRIVATE IpAliasKey
{
260 IpAliasKey(IPEndPoint ip_endpoint
, bool is_https
);
263 IPEndPoint ip_endpoint
;
266 // Needed to be an element of std::set.
267 bool operator<(const IpAliasKey
&other
) const;
268 bool operator==(const IpAliasKey
&other
) const;
271 typedef std::map
<QuicServerId
, QuicChromiumClientSession
*> SessionMap
;
272 typedef std::map
<QuicChromiumClientSession
*, QuicServerId
> SessionIdMap
;
273 typedef std::set
<QuicServerId
> AliasSet
;
274 typedef std::map
<QuicChromiumClientSession
*, AliasSet
> SessionAliasMap
;
275 typedef std::set
<QuicChromiumClientSession
*> SessionSet
;
276 typedef std::map
<IpAliasKey
, SessionSet
> IPAliasMap
;
277 typedef std::map
<QuicServerId
, QuicCryptoClientConfig
*> CryptoConfigMap
;
278 typedef std::set
<Job
*> JobSet
;
279 typedef std::map
<QuicServerId
, JobSet
> JobMap
;
280 typedef std::map
<QuicStreamRequest
*, QuicServerId
> RequestMap
;
281 typedef std::set
<QuicStreamRequest
*> RequestSet
;
282 typedef std::map
<QuicServerId
, RequestSet
> ServerIDRequestsMap
;
283 typedef std::deque
<enum QuicChromiumClientSession::QuicDisabledReason
>
284 DisabledReasonsQueue
;
286 // Creates a job which doesn't wait for server config to be loaded from the
287 // disk cache. This job is started via a PostTask.
288 void CreateAuxilaryJob(const QuicServerId server_id
,
289 int cert_verify_flags
,
290 bool server_and_origin_have_same_host
,
292 const BoundNetLog
& net_log
);
294 // Returns a newly created QuicHttpStream owned by the caller.
295 scoped_ptr
<QuicHttpStream
> CreateFromSession(QuicChromiumClientSession
*);
297 bool OnResolution(const QuicServerId
& server_id
,
298 const AddressList
& address_list
);
299 void OnJobComplete(Job
* job
, int rv
);
300 bool HasActiveSession(const QuicServerId
& server_id
) const;
301 bool HasActiveJob(const QuicServerId
& server_id
) const;
302 int CreateSession(const QuicServerId
& server_id
,
303 int cert_verify_flags
,
304 scoped_ptr
<QuicServerInfo
> quic_server_info
,
305 const AddressList
& address_list
,
306 base::TimeTicks dns_resolution_end_time
,
307 const BoundNetLog
& net_log
,
308 QuicChromiumClientSession
** session
);
309 void ActivateSession(const QuicServerId
& key
,
310 QuicChromiumClientSession
* session
);
312 // Returns |srtt| in micro seconds from ServerNetworkStats. Returns 0 if there
313 // is no |http_server_properties_| or if |http_server_properties_| doesn't
314 // have ServerNetworkStats for the given |server_id|.
315 int64
GetServerNetworkStatsSmoothedRttInMicroseconds(
316 const QuicServerId
& server_id
) const;
319 bool WasQuicRecentlyBroken(const QuicServerId
& server_id
) const;
321 bool CryptoConfigCacheIsEmpty(const QuicServerId
& server_id
);
323 // Initializes the cached state associated with |server_id| in
324 // |crypto_config_| with the information in |server_info|.
325 void InitializeCachedStateInCryptoConfig(
326 const QuicServerId
& server_id
,
327 const scoped_ptr
<QuicServerInfo
>& server_info
);
329 void ProcessGoingAwaySession(QuicChromiumClientSession
* session
,
330 const QuicServerId
& server_id
,
331 bool was_session_active
);
333 // Collect stats from recent connections, possibly disabling Quic.
334 void MaybeDisableQuic(QuicChromiumClientSession
* session
);
336 bool require_confirmation_
;
337 HostResolver
* host_resolver_
;
338 ClientSocketFactory
* client_socket_factory_
;
339 base::WeakPtr
<HttpServerProperties
> http_server_properties_
;
340 TransportSecurityState
* transport_security_state_
;
341 QuicServerInfoFactory
* quic_server_info_factory_
;
342 QuicCryptoClientStreamFactory
* quic_crypto_client_stream_factory_
;
343 QuicRandom
* random_generator_
;
344 scoped_ptr
<QuicClock
> clock_
;
345 const size_t max_packet_length_
;
347 // The helper used for all connections.
348 scoped_ptr
<QuicConnectionHelper
> helper_
;
350 // Contains owning pointers to all sessions that currently exist.
351 SessionIdMap all_sessions_
;
352 // Contains non-owning pointers to currently active session
353 // (not going away session, once they're implemented).
354 SessionMap active_sessions_
;
355 // Map from session to set of aliases that this session is known by.
356 SessionAliasMap session_aliases_
;
357 // Map from IP address to sessions which are connected to this address.
358 IPAliasMap ip_aliases_
;
360 // Origins which have gone away recently.
361 AliasSet gone_away_aliases_
;
363 const QuicConfig config_
;
364 QuicCryptoClientConfig crypto_config_
;
367 ServerIDRequestsMap job_requests_map_
;
368 RequestMap active_requests_
;
370 QuicVersionVector supported_versions_
;
372 // Determine if we should consistently select a client UDP port. If false,
373 // then we will just let the OS select a random client port for each new
375 bool enable_port_selection_
;
377 // Set if we always require handshake confirmation. If true, this will
378 // introduce at least one RTT for the handshake before the client sends data.
379 bool always_require_handshake_confirmation_
;
381 // Set if we do not want connection pooling.
382 bool disable_connection_pooling_
;
384 // Specifies the ratio between time to load QUIC server information from disk
385 // cache to 'smoothed RTT'. This ratio is used to calculate the timeout in
386 // milliseconds to wait for loading of QUIC server information. If we don't
387 // want to timeout, set |load_server_info_timeout_srtt_multiplier_| to 0.
388 float load_server_info_timeout_srtt_multiplier_
;
390 // Set if we want to race connections - one connection that sends
391 // INCHOATE_HELLO and another connection that sends CHLO after loading server
392 // config from the disk cache.
393 bool enable_connection_racing_
;
395 // Set if experimental non-blocking IO should be used on windows sockets.
396 bool enable_non_blocking_io_
;
398 // Set if we do not want to load server config from the disk cache.
399 bool disable_disk_cache_
;
401 // Set if AES-GCM should be preferred, even if there is no hardware support.
404 // Set if we want to disable QUIC when there is high packet loss rate.
405 // Specifies the maximum number of connections with high packet loss in a row
406 // after which QUIC will be disabled.
407 int max_number_of_lossy_connections_
;
408 // Specifies packet loss rate in fraction after which a connection is closed
409 // and is considered as a lossy connection.
410 float packet_loss_threshold_
;
411 // Count number of lossy connections by port.
412 std::map
<uint16
, int> number_of_lossy_connections_
;
414 // Keep track of stats for recently closed connections, using a
416 int max_disabled_reasons_
;
417 DisabledReasonsQueue disabled_reasons_
;
418 // Events that can trigger disabling QUIC
419 int num_public_resets_post_handshake_
;
420 int num_timeouts_with_open_streams_
;
421 // Keep track the largest values for UMA histograms, that will help
422 // determine good threshold values.
423 int max_public_resets_post_handshake_
;
424 int max_timeouts_with_open_streams_
;
425 // Thresholds if greater than zero, determine when to
426 int threshold_timeouts_with_open_streams_
;
427 int threshold_public_resets_post_handshake_
;
429 // Size of the UDP receive buffer.
430 int socket_receive_buffer_size_
;
432 // Set if we do want to delay TCP connection when it is racing with QUIC.
433 bool delay_tcp_race_
;
435 // Each profile will (probably) have a unique port_seed_ value. This value
436 // is used to help seed a pseudo-random number generator (PortSuggester) so
437 // that we consistently (within this profile) suggest the same ephemeral
438 // port when we re-connect to any given server/port. The differences between
439 // profiles (probablistically) prevent two profiles from colliding in their
440 // ephemeral port requests.
443 // Local address of socket that was created in CreateSession.
444 IPEndPoint local_address_
;
445 bool check_persisted_supports_quic_
;
446 std::set
<HostPortPair
> quic_supported_servers_at_startup_
;
448 NetworkConnection network_connection_
;
450 base::TaskRunner
* task_runner_
;
452 base::WeakPtrFactory
<QuicStreamFactory
> weak_factory_
;
454 DISALLOW_COPY_AND_ASSIGN(QuicStreamFactory
);
459 #endif // NET_QUIC_QUIC_STREAM_FACTORY_H_