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 "net/base/address_list.h"
16 #include "net/base/completion_callback.h"
17 #include "net/base/host_port_pair.h"
18 #include "net/base/network_change_notifier.h"
19 #include "net/cert/cert_database.h"
20 #include "net/log/net_log.h"
21 #include "net/proxy/proxy_server.h"
22 #include "net/quic/network_connection.h"
23 #include "net/quic/quic_chromium_client_session.h"
24 #include "net/quic/quic_config.h"
25 #include "net/quic/quic_crypto_stream.h"
26 #include "net/quic/quic_http_stream.h"
27 #include "net/quic/quic_protocol.h"
31 class CertPolicyEnforcer
;
33 class ChannelIDService
;
34 class ClientSocketFactory
;
36 class HttpServerProperties
;
38 class QuicChromiumClientSession
;
39 class QuicConnectionHelper
;
40 class QuicCryptoClientStreamFactory
;
42 class QuicServerInfoFactory
;
44 class QuicStreamFactory
;
45 class TransportSecurityState
;
48 class QuicStreamFactoryPeer
;
51 // Encapsulates a pending request for a QuicHttpStream.
52 // If the request is still pending when it is destroyed, it will
53 // cancel the request with the factory.
54 class NET_EXPORT_PRIVATE QuicStreamRequest
{
56 explicit QuicStreamRequest(QuicStreamFactory
* factory
);
59 // For http, |is_https| is false.
60 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
61 // passed to CertVerifier::Verify.
62 int Request(const HostPortPair
& host_port_pair
,
64 PrivacyMode privacy_mode
,
65 int cert_verify_flags
,
66 base::StringPiece origin_host
,
67 base::StringPiece method
,
68 const BoundNetLog
& net_log
,
69 const CompletionCallback
& callback
);
71 void OnRequestComplete(int rv
);
73 scoped_ptr
<QuicHttpStream
> ReleaseStream();
75 void set_stream(scoped_ptr
<QuicHttpStream
> stream
);
77 const std::string
origin_host() const { return origin_host_
; }
79 PrivacyMode
privacy_mode() const { return privacy_mode_
; }
81 const BoundNetLog
& net_log() const{
86 QuicStreamFactory
* factory_
;
87 HostPortPair host_port_pair_
;
88 std::string origin_host_
;
89 PrivacyMode privacy_mode_
;
91 CompletionCallback callback_
;
92 scoped_ptr
<QuicHttpStream
> stream_
;
94 DISALLOW_COPY_AND_ASSIGN(QuicStreamRequest
);
97 // A factory for creating new QuicHttpStreams on top of a pool of
98 // QuicChromiumClientSessions.
99 class NET_EXPORT_PRIVATE QuicStreamFactory
100 : public NetworkChangeNotifier::IPAddressObserver
,
101 public CertDatabase::Observer
{
104 HostResolver
* host_resolver
,
105 ClientSocketFactory
* client_socket_factory
,
106 base::WeakPtr
<HttpServerProperties
> http_server_properties
,
107 CertVerifier
* cert_verifier
,
108 CertPolicyEnforcer
* cert_policy_enforcer
,
109 ChannelIDService
* channel_id_service
,
110 TransportSecurityState
* transport_security_state
,
111 QuicCryptoClientStreamFactory
* quic_crypto_client_stream_factory
,
112 QuicRandom
* random_generator
,
114 size_t max_packet_length
,
115 const std::string
& user_agent_id
,
116 const QuicVersionVector
& supported_versions
,
117 bool enable_port_selection
,
118 bool always_require_handshake_confirmation
,
119 bool disable_connection_pooling
,
120 float load_server_info_timeout_srtt_multiplier
,
121 bool enable_connection_racing
,
122 bool enable_non_blocking_io
,
123 bool disable_disk_cache
,
125 int max_number_of_lossy_connections
,
126 float packet_loss_threshold
,
127 int max_recent_disabled_reasons
,
128 int threshold_timeouts_with_streams_open
,
129 int threshold_public_resets_post_handshake
,
130 int socket_receive_buffer_size
,
131 const QuicTagVector
& connection_options
);
132 ~QuicStreamFactory() override
;
134 // Creates a new QuicHttpStream to |host_port_pair| which will be
135 // owned by |request|. |is_https| specifies if the protocol is https or not.
136 // If a matching session already exists, this method will return OK. If no
137 // matching session exists, this will return ERR_IO_PENDING and will invoke
138 // OnRequestComplete asynchronously.
139 int Create(const HostPortPair
& host_port_pair
,
141 PrivacyMode privacy_mode
,
142 int cert_verify_flags
,
143 base::StringPiece origin_host
,
144 base::StringPiece method
,
145 const BoundNetLog
& net_log
,
146 QuicStreamRequest
* request
);
148 // If |packet_loss_rate| is greater than or equal to |packet_loss_threshold_|
149 // it marks QUIC as recently broken for the port of the session. Increments
150 // |number_of_lossy_connections_| by port. If |number_of_lossy_connections_|
151 // is greater than or equal to |max_number_of_lossy_connections_| then it
152 // disables QUIC. If QUIC is disabled then it closes the connection.
154 // Returns true if QUIC is disabled for the port of the session.
155 bool OnHandshakeConfirmed(QuicChromiumClientSession
* session
,
156 float packet_loss_rate
);
158 // Returns true if QUIC is disabled for this port.
159 bool IsQuicDisabled(uint16 port
);
161 // Returns reason QUIC is disabled for this port, or QUIC_DISABLED_NOT if not.
162 QuicChromiumClientSession::QuicDisabledReason
QuicDisabledReason(
165 // Returns reason QUIC is disabled as string for net-internals, or
166 // returns empty string if QUIC is not disabled.
167 const char* QuicDisabledReasonString() const;
169 // Called by a session when it becomes idle.
170 void OnIdleSession(QuicChromiumClientSession
* session
);
172 // Called by a session when it is going away and no more streams should be
174 void OnSessionGoingAway(QuicChromiumClientSession
* session
);
176 // Called by a session after it shuts down.
177 void OnSessionClosed(QuicChromiumClientSession
* session
);
179 // Called by a session whose connection has timed out.
180 void OnSessionConnectTimeout(QuicChromiumClientSession
* session
);
182 // Cancels a pending request.
183 void CancelRequest(QuicStreamRequest
* request
);
185 // Closes all current sessions.
186 void CloseAllSessions(int error
);
188 scoped_ptr
<base::Value
> QuicStreamFactoryInfoToValue() const;
190 // Delete all cached state objects in |crypto_config_|.
191 void ClearCachedStatesInCryptoConfig();
193 // NetworkChangeNotifier::IPAddressObserver methods:
195 // Until the servers support roaming, close all connections when the local
196 // IP address changes.
197 void OnIPAddressChanged() override
;
199 // CertDatabase::Observer methods:
201 // We close all sessions when certificate database is changed.
202 void OnCertAdded(const X509Certificate
* cert
) override
;
203 void OnCACertChanged(const X509Certificate
* cert
) override
;
205 bool require_confirmation() const {
206 return require_confirmation_
;
209 void set_require_confirmation(bool require_confirmation
);
211 QuicConnectionHelper
* helper() { return helper_
.get(); }
213 bool enable_port_selection() const { return enable_port_selection_
; }
215 bool has_quic_server_info_factory() {
216 return quic_server_info_factory_
!= NULL
;
219 void set_quic_server_info_factory(
220 QuicServerInfoFactory
* quic_server_info_factory
) {
221 DCHECK(!quic_server_info_factory_
);
222 quic_server_info_factory_
= quic_server_info_factory
;
225 bool enable_connection_racing() const { return enable_connection_racing_
; }
226 void set_enable_connection_racing(bool enable_connection_racing
) {
227 enable_connection_racing_
= enable_connection_racing
;
230 int socket_receive_buffer_size() const { return socket_receive_buffer_size_
; }
234 friend class test::QuicStreamFactoryPeer
;
235 FRIEND_TEST_ALL_PREFIXES(HttpStreamFactoryTest
, QuicLossyProxyMarkedAsBad
);
237 // The key used to find session by ip. Includes
238 // the ip address, port, and scheme.
239 struct NET_EXPORT_PRIVATE IpAliasKey
{
241 IpAliasKey(IPEndPoint ip_endpoint
, bool is_https
);
244 IPEndPoint ip_endpoint
;
247 // Needed to be an element of std::set.
248 bool operator<(const IpAliasKey
&other
) const;
249 bool operator==(const IpAliasKey
&other
) const;
252 typedef std::map
<QuicServerId
, QuicChromiumClientSession
*> SessionMap
;
253 typedef std::map
<QuicChromiumClientSession
*, QuicServerId
> SessionIdMap
;
254 typedef std::set
<QuicServerId
> AliasSet
;
255 typedef std::map
<QuicChromiumClientSession
*, AliasSet
> SessionAliasMap
;
256 typedef std::set
<QuicChromiumClientSession
*> SessionSet
;
257 typedef std::map
<IpAliasKey
, SessionSet
> IPAliasMap
;
258 typedef std::map
<QuicServerId
, QuicCryptoClientConfig
*> CryptoConfigMap
;
259 typedef std::set
<Job
*> JobSet
;
260 typedef std::map
<QuicServerId
, JobSet
> JobMap
;
261 typedef std::map
<QuicStreamRequest
*, QuicServerId
> RequestMap
;
262 typedef std::set
<QuicStreamRequest
*> RequestSet
;
263 typedef std::map
<QuicServerId
, RequestSet
> ServerIDRequestsMap
;
264 typedef std::deque
<enum QuicChromiumClientSession::QuicDisabledReason
>
265 DisabledReasonsQueue
;
267 // Creates a job which doesn't wait for server config to be loaded from the
268 // disk cache. This job is started via a PostTask.
269 void CreateAuxilaryJob(const QuicServerId server_id
,
270 int cert_verify_flags
,
271 bool server_and_origin_have_same_host
,
273 const BoundNetLog
& net_log
);
275 // Returns a newly created QuicHttpStream owned by the caller.
276 scoped_ptr
<QuicHttpStream
> CreateFromSession(QuicChromiumClientSession
*);
278 bool OnResolution(const QuicServerId
& server_id
,
279 const AddressList
& address_list
);
280 void OnJobComplete(Job
* job
, int rv
);
281 bool HasActiveSession(const QuicServerId
& server_id
) const;
282 bool HasActiveJob(const QuicServerId
& server_id
) const;
283 int CreateSession(const QuicServerId
& server_id
,
284 int cert_verify_flags
,
285 scoped_ptr
<QuicServerInfo
> quic_server_info
,
286 const AddressList
& address_list
,
287 base::TimeTicks dns_resolution_end_time
,
288 const BoundNetLog
& net_log
,
289 QuicChromiumClientSession
** session
);
290 void ActivateSession(const QuicServerId
& key
,
291 QuicChromiumClientSession
* session
);
293 // Returns |srtt| in micro seconds from ServerNetworkStats. Returns 0 if there
294 // is no |http_server_properties_| or if |http_server_properties_| doesn't
295 // have ServerNetworkStats for the given |server_id|.
296 int64
GetServerNetworkStatsSmoothedRttInMicroseconds(
297 const QuicServerId
& server_id
) const;
300 bool WasQuicRecentlyBroken(const QuicServerId
& server_id
) const;
301 bool CryptoConfigCacheIsEmpty(const QuicServerId
& server_id
);
303 // Initializes the cached state associated with |server_id| in
304 // |crypto_config_| with the information in |server_info|.
305 void InitializeCachedStateInCryptoConfig(
306 const QuicServerId
& server_id
,
307 const scoped_ptr
<QuicServerInfo
>& server_info
);
309 void ProcessGoingAwaySession(QuicChromiumClientSession
* session
,
310 const QuicServerId
& server_id
,
311 bool was_session_active
);
313 // Collect stats from recent connections, possibly disabling Quic.
314 void MaybeDisableQuic(QuicChromiumClientSession
* session
);
316 bool require_confirmation_
;
317 HostResolver
* host_resolver_
;
318 ClientSocketFactory
* client_socket_factory_
;
319 base::WeakPtr
<HttpServerProperties
> http_server_properties_
;
320 TransportSecurityState
* transport_security_state_
;
321 QuicServerInfoFactory
* quic_server_info_factory_
;
322 QuicCryptoClientStreamFactory
* quic_crypto_client_stream_factory_
;
323 QuicRandom
* random_generator_
;
324 scoped_ptr
<QuicClock
> clock_
;
325 const size_t max_packet_length_
;
327 // The helper used for all connections.
328 scoped_ptr
<QuicConnectionHelper
> helper_
;
330 // Contains owning pointers to all sessions that currently exist.
331 SessionIdMap all_sessions_
;
332 // Contains non-owning pointers to currently active session
333 // (not going away session, once they're implemented).
334 SessionMap active_sessions_
;
335 // Map from session to set of aliases that this session is known by.
336 SessionAliasMap session_aliases_
;
337 // Map from IP address to sessions which are connected to this address.
338 IPAliasMap ip_aliases_
;
340 // Origins which have gone away recently.
341 AliasSet gone_away_aliases_
;
343 const QuicConfig config_
;
344 QuicCryptoClientConfig crypto_config_
;
347 ServerIDRequestsMap job_requests_map_
;
348 RequestMap active_requests_
;
350 QuicVersionVector supported_versions_
;
352 // Determine if we should consistently select a client UDP port. If false,
353 // then we will just let the OS select a random client port for each new
355 bool enable_port_selection_
;
357 // Set if we always require handshake confirmation. If true, this will
358 // introduce at least one RTT for the handshake before the client sends data.
359 bool always_require_handshake_confirmation_
;
361 // Set if we do not want connection pooling.
362 bool disable_connection_pooling_
;
364 // Specifies the ratio between time to load QUIC server information from disk
365 // cache to 'smoothed RTT'. This ratio is used to calculate the timeout in
366 // milliseconds to wait for loading of QUIC server information. If we don't
367 // want to timeout, set |load_server_info_timeout_srtt_multiplier_| to 0.
368 float load_server_info_timeout_srtt_multiplier_
;
370 // Set if we want to race connections - one connection that sends
371 // INCHOATE_HELLO and another connection that sends CHLO after loading server
372 // config from the disk cache.
373 bool enable_connection_racing_
;
375 // Set if experimental non-blocking IO should be used on windows sockets.
376 bool enable_non_blocking_io_
;
378 // Set if we do not want to load server config from the disk cache.
379 bool disable_disk_cache_
;
381 // Set if AES-GCM should be preferred, even if there is no hardware support.
384 // Set if we want to disable QUIC when there is high packet loss rate.
385 // Specifies the maximum number of connections with high packet loss in a row
386 // after which QUIC will be disabled.
387 int max_number_of_lossy_connections_
;
388 // Specifies packet loss rate in fraction after which a connection is closed
389 // and is considered as a lossy connection.
390 float packet_loss_threshold_
;
391 // Count number of lossy connections by port.
392 std::map
<uint16
, int> number_of_lossy_connections_
;
394 // Keep track of stats for recently closed connections, using a
396 int max_disabled_reasons_
;
397 DisabledReasonsQueue disabled_reasons_
;
398 // Events that can trigger disabling QUIC
399 int num_public_resets_post_handshake_
;
400 int num_timeouts_with_open_streams_
;
401 // Keep track the largest values for UMA histograms, that will help
402 // determine good threshold values.
403 int max_public_resets_post_handshake_
;
404 int max_timeouts_with_open_streams_
;
405 // Thresholds if greater than zero, determine when to
406 int threshold_timeouts_with_open_streams_
;
407 int threshold_public_resets_post_handshake_
;
409 // Size of the UDP receive buffer.
410 int socket_receive_buffer_size_
;
412 // Each profile will (probably) have a unique port_seed_ value. This value
413 // is used to help seed a pseudo-random number generator (PortSuggester) so
414 // that we consistently (within this profile) suggest the same ephemeral
415 // port when we re-connect to any given server/port. The differences between
416 // profiles (probablistically) prevent two profiles from colliding in their
417 // ephemeral port requests.
420 // Local address of socket that was created in CreateSession.
421 IPEndPoint local_address_
;
422 bool check_persisted_supports_quic_
;
423 std::set
<HostPortPair
> quic_supported_servers_at_startup_
;
425 NetworkConnection network_connection_
;
427 base::TaskRunner
* task_runner_
;
429 base::WeakPtrFactory
<QuicStreamFactory
> weak_factory_
;
431 DISALLOW_COPY_AND_ASSIGN(QuicStreamFactory
);
436 #endif // NET_QUIC_QUIC_STREAM_FACTORY_H_