Add IS_TIZEN_DA to fix build break in standard build.
[platform/framework/web/chromium-efl.git] / net / quic / quic_stream_factory.cc
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/quic_stream_factory.h"
6
7 #include <memory>
8 #include <set>
9 #include <tuple>
10 #include <utility>
11
12 #include "base/containers/contains.h"
13 #include "base/feature_list.h"
14 #include "base/functional/bind.h"
15 #include "base/location.h"
16 #include "base/memory/memory_pressure_monitor.h"
17 #include "base/memory/raw_ptr.h"
18 #include "base/memory/raw_ptr_exclusion.h"
19 #include "base/metrics/field_trial.h"
20 #include "base/metrics/histogram_functions.h"
21 #include "base/metrics/histogram_macros.h"
22 #include "base/no_destructor.h"
23 #include "base/numerics/safe_conversions.h"
24 #include "base/ranges/algorithm.h"
25 #include "base/strings/string_number_conversions.h"
26 #include "base/strings/string_util.h"
27 #include "base/strings/stringprintf.h"
28 #include "base/task/sequenced_task_runner.h"
29 #include "base/task/single_thread_task_runner.h"
30 #include "base/time/default_clock.h"
31 #include "base/time/default_tick_clock.h"
32 #include "base/values.h"
33 #include "crypto/openssl_util.h"
34 #include "net/base/address_list.h"
35 #include "net/base/features.h"
36 #include "net/base/ip_address.h"
37 #include "net/base/net_errors.h"
38 #include "net/base/trace_constants.h"
39 #include "net/base/tracing.h"
40 #include "net/cert/cert_verifier.h"
41 #include "net/dns/host_resolver.h"
42 #include "net/dns/public/secure_dns_policy.h"
43 #include "net/log/net_log.h"
44 #include "net/log/net_log_capture_mode.h"
45 #include "net/log/net_log_event_type.h"
46 #include "net/log/net_log_source_type.h"
47 #include "net/quic/address_utils.h"
48 #include "net/quic/crypto/proof_verifier_chromium.h"
49 #include "net/quic/properties_based_quic_server_info.h"
50 #include "net/quic/quic_chromium_alarm_factory.h"
51 #include "net/quic/quic_chromium_connection_helper.h"
52 #include "net/quic/quic_chromium_packet_reader.h"
53 #include "net/quic/quic_chromium_packet_writer.h"
54 #include "net/quic/quic_context.h"
55 #include "net/quic/quic_crypto_client_stream_factory.h"
56 #include "net/quic/quic_http_stream.h"
57 #include "net/quic/quic_server_info.h"
58 #include "net/socket/client_socket_factory.h"
59 #include "net/socket/next_proto.h"
60 #include "net/socket/socket_performance_watcher.h"
61 #include "net/socket/socket_performance_watcher_factory.h"
62 #include "net/socket/udp_client_socket.h"
63 #include "net/third_party/quiche/src/quiche/quic/core/crypto/null_decrypter.h"
64 #include "net/third_party/quiche/src/quiche/quic/core/crypto/proof_verifier.h"
65 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_client_session_cache.h"
66 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_random.h"
67 #include "net/third_party/quiche/src/quiche/quic/core/quic_clock.h"
68 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"
69 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
70 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h"
71 #include "third_party/boringssl/src/include/openssl/aead.h"
72 #include "url/gurl.h"
73 #include "url/scheme_host_port.h"
74 #include "url/url_constants.h"
75
76 namespace net {
77
78 namespace {
79
80 enum InitialRttEstimateSource {
81   INITIAL_RTT_DEFAULT,
82   INITIAL_RTT_CACHED,
83   INITIAL_RTT_2G,
84   INITIAL_RTT_3G,
85   INITIAL_RTT_SOURCE_MAX,
86 };
87
88 enum class JobProtocolErrorLocation {
89   kSessionStartReadingFailedAsync = 0,
90   kSessionStartReadingFailedSync = 1,
91   kCreateSessionFailedAsync = 2,
92   kCreateSessionFailedSync = 3,
93   kCryptoConnectFailedSync = 4,
94   kCryptoConnectFailedAsync = 5,
95   kMaxValue = kCryptoConnectFailedAsync,
96 };
97
98 base::Value::Dict NetLogQuicStreamFactoryJobParams(
99     const QuicStreamFactory::QuicSessionAliasKey* key) {
100   return base::Value::Dict()
101       .Set("host", key->server_id().host())
102       .Set("port", key->server_id().port())
103       .Set("privacy_mode",
104            PrivacyModeToDebugString(key->session_key().privacy_mode()))
105       .Set("network_anonymization_key",
106            key->session_key().network_anonymization_key().ToDebugString());
107 }
108
109 std::string QuicPlatformNotificationToString(
110     QuicPlatformNotification notification) {
111   switch (notification) {
112     case NETWORK_CONNECTED:
113       return "OnNetworkConnected";
114     case NETWORK_MADE_DEFAULT:
115       return "OnNetworkMadeDefault";
116     case NETWORK_DISCONNECTED:
117       return "OnNetworkDisconnected";
118     case NETWORK_SOON_TO_DISCONNECT:
119       return "OnNetworkSoonToDisconnect";
120     case NETWORK_IP_ADDRESS_CHANGED:
121       return "OnIPAddressChanged";
122     default:
123       QUICHE_NOTREACHED();
124       break;
125   }
126   return "InvalidNotification";
127 }
128
129 void HistogramCreateSessionFailure(enum CreateSessionFailure error) {
130   UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error,
131                             CREATION_ERROR_MAX);
132 }
133
134 void HistogramProtocolErrorLocation(enum JobProtocolErrorLocation location) {
135   UMA_HISTOGRAM_ENUMERATION("Net.QuicStreamFactory.DoConnectFailureLocation",
136                             location);
137 }
138
139 void LogConnectionIpPooling(bool pooled) {
140   UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ConnectionIpPooled", pooled);
141 }
142
143 void LogStaleConnectionTime(base::TimeTicks start_time) {
144   UMA_HISTOGRAM_TIMES("Net.QuicSession.StaleConnectionTime",
145                       base::TimeTicks::Now() - start_time);
146 }
147
148 void LogValidConnectionTime(base::TimeTicks start_time) {
149   UMA_HISTOGRAM_TIMES("Net.QuicSession.ValidConnectionTime",
150                       base::TimeTicks::Now() - start_time);
151 }
152
153 void SetInitialRttEstimate(base::TimeDelta estimate,
154                            enum InitialRttEstimateSource source,
155                            quic::QuicConfig* config) {
156   UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.InitialRttEsitmateSource", source,
157                             INITIAL_RTT_SOURCE_MAX);
158   if (estimate != base::TimeDelta())
159     config->SetInitialRoundTripTimeUsToSend(
160         base::checked_cast<uint64_t>(estimate.InMicroseconds()));
161 }
162
163 // An implementation of quic::QuicCryptoClientConfig::ServerIdFilter that wraps
164 // an |origin_filter|.
165 class ServerIdOriginFilter
166     : public quic::QuicCryptoClientConfig::ServerIdFilter {
167  public:
168   explicit ServerIdOriginFilter(
169       const base::RepeatingCallback<bool(const GURL&)> origin_filter)
170       : origin_filter_(origin_filter) {}
171
172   bool Matches(const quic::QuicServerId& server_id) const override {
173     if (origin_filter_.is_null())
174       return true;
175
176     GURL url(base::StringPrintf("%s%s%s:%d", url::kHttpsScheme,
177                                 url::kStandardSchemeSeparator,
178                                 server_id.host().c_str(), server_id.port()));
179     DCHECK(url.is_valid());
180     return origin_filter_.Run(url);
181   }
182
183  private:
184   const base::RepeatingCallback<bool(const GURL&)> origin_filter_;
185 };
186
187 std::set<std::string> HostsFromOrigins(std::set<HostPortPair> origins) {
188   std::set<std::string> hosts;
189   for (const auto& origin : origins) {
190     hosts.insert(origin.host());
191   }
192   return hosts;
193 }
194
195 }  // namespace
196
197 // Refcounted class that owns quic::QuicCryptoClientConfig and tracks how many
198 // consumers are using it currently. When the last reference is freed, the
199 // QuicCryptoClientConfigHandle informs the owning QuicStreamFactory, moves it
200 // into an MRU cache.
201 class QuicStreamFactory::QuicCryptoClientConfigOwner {
202  public:
203   QuicCryptoClientConfigOwner(
204       std::unique_ptr<quic::ProofVerifier> proof_verifier,
205       std::unique_ptr<quic::QuicClientSessionCache> session_cache,
206       QuicStreamFactory* quic_stream_factory)
207       : config_(std::move(proof_verifier), std::move(session_cache)),
208         clock_(base::DefaultClock::GetInstance()),
209         quic_stream_factory_(quic_stream_factory) {
210     DCHECK(quic_stream_factory_);
211     memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
212         FROM_HERE,
213         base::BindRepeating(&QuicCryptoClientConfigOwner::OnMemoryPressure,
214                             base::Unretained(this)));
215     if (quic_stream_factory_->ssl_config_service_->GetSSLContextConfig()
216             .PostQuantumKeyAgreementEnabled()) {
217       config_.set_preferred_groups({SSL_GROUP_X25519_KYBER768_DRAFT00,
218                                     SSL_GROUP_X25519, SSL_GROUP_SECP256R1,
219                                     SSL_GROUP_SECP384R1});
220     }
221   }
222
223   QuicCryptoClientConfigOwner(const QuicCryptoClientConfigOwner&) = delete;
224   QuicCryptoClientConfigOwner& operator=(const QuicCryptoClientConfigOwner&) =
225       delete;
226
227   ~QuicCryptoClientConfigOwner() { DCHECK_EQ(num_refs_, 0); }
228
229   quic::QuicCryptoClientConfig* config() { return &config_; }
230
231   int num_refs() const { return num_refs_; }
232
233   QuicStreamFactory* quic_stream_factory() { return quic_stream_factory_; }
234
235   void OnMemoryPressure(
236       base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
237     quic::SessionCache* session_cache = config_.session_cache();
238     if (!session_cache) {
239       return;
240     }
241     time_t now = clock_->Now().ToTimeT();
242     uint64_t now_u64 = 0;
243     if (now > 0) {
244       now_u64 = static_cast<uint64_t>(now);
245     }
246     switch (memory_pressure_level) {
247       case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
248         break;
249       case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
250         session_cache->RemoveExpiredEntries(
251             quic::QuicWallTime::FromUNIXSeconds(now_u64));
252         break;
253       case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
254         session_cache->Clear();
255         break;
256     }
257   }
258
259  private:
260   friend class CryptoClientConfigHandle;
261
262   // Simple ref counting. Not using scoped_refptr allows for both keeping around
263   // an MRU cache of 0-reference objects, and DCHECKing that there are no
264   // outstanding referenced QuicCryptoClientConfigOwner on destruction. Private
265   // so that only CryptoClientConfigHandle can add and remove refs.
266
267   void AddRef() { num_refs_++; }
268
269   void ReleaseRef() {
270     DCHECK_GT(num_refs_, 0);
271     num_refs_--;
272   }
273
274   int num_refs_ = 0;
275   quic::QuicCryptoClientConfig config_;
276   raw_ptr<base::Clock> clock_;
277   std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
278   const raw_ptr<QuicStreamFactory> quic_stream_factory_;
279 };
280
281 // Class that owns a reference to a QuicCryptoClientConfigOwner. Handles
282 // incrementing the refcount on construction, and decrementing it on
283 // destruction.
284 class QuicStreamFactory::CryptoClientConfigHandle
285     : public QuicCryptoClientConfigHandle {
286  public:
287   explicit CryptoClientConfigHandle(
288       const QuicCryptoClientConfigMap::iterator& map_iterator)
289       : map_iterator_(map_iterator) {
290     DCHECK_GE(map_iterator_->second->num_refs(), 0);
291     map_iterator->second->AddRef();
292   }
293
294   CryptoClientConfigHandle(const CryptoClientConfigHandle& other)
295       : CryptoClientConfigHandle(other.map_iterator_) {}
296
297   CryptoClientConfigHandle& operator=(const CryptoClientConfigHandle&) = delete;
298
299   ~CryptoClientConfigHandle() override {
300     DCHECK_GT(map_iterator_->second->num_refs(), 0);
301     map_iterator_->second->ReleaseRef();
302     if (map_iterator_->second->num_refs() == 0) {
303       map_iterator_->second->quic_stream_factory()
304           ->OnAllCryptoClientRefReleased(map_iterator_);
305     }
306   }
307
308   quic::QuicCryptoClientConfig* GetConfig() const override {
309     return map_iterator_->second->config();
310   }
311
312  private:
313   QuicCryptoClientConfigMap::iterator map_iterator_;
314 };
315
316 // Responsible for creating a new QUIC session to the specified server, and
317 // for notifying any associated requests when complete. |client_config_handle|
318 // is not actually used, but serves to keep the corresponding CryptoClientConfig
319 // alive until the Job completes.
320 class QuicStreamFactory::Job {
321  public:
322   Job(QuicStreamFactory* factory,
323       quic::ParsedQuicVersion quic_version,
324       HostResolver* host_resolver,
325       const QuicSessionAliasKey& key,
326       std::unique_ptr<CryptoClientConfigHandle> client_config_handle,
327       bool was_alternative_service_recently_broken,
328       bool retry_on_alternate_network_before_handshake,
329       RequestPriority priority,
330       bool use_dns_aliases,
331       bool require_dns_https_alpn,
332       int cert_verify_flags,
333       const NetLogWithSource& net_log);
334
335   Job(const Job&) = delete;
336   Job& operator=(const Job&) = delete;
337
338   ~Job();
339
340   int Run(CompletionOnceCallback callback);
341
342   int DoLoop(int rv);
343   int DoResolveHost();
344   int DoResolveHostComplete(int rv);
345   int DoCreateSession();
346   int DoCreateSessionComplete(int rv);
347   int DoConnect(int rv);
348   int DoConnectComplete(int rv);
349   int DoConfirmConnection(int rv);
350
351   void OnCreateSessionComplete(int rv);
352   void OnResolveHostComplete(int rv);
353   void OnCryptoConnectComplete(int rv);
354
355   const QuicSessionAliasKey& key() const { return key_; }
356
357   const NetLogWithSource& net_log() const { return net_log_; }
358
359   base::WeakPtr<Job> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
360
361   void PopulateNetErrorDetails(NetErrorDetails* details) const;
362
363   void AddRequest(QuicStreamRequest* request) {
364     stream_requests_.insert(request);
365     if (!host_resolution_finished_) {
366       request->ExpectOnHostResolution();
367     }
368     // Callers do not need to wait for OnQuicSessionCreationComplete if the
369     // kAsyncQuicSession flag is not set because session creation will be fully
370     // synchronous, so no need to call ExpectQuicSessionCreation.
371     if (base::FeatureList::IsEnabled(net::features::kAsyncQuicSession) &&
372         !session_creation_finished_) {
373       request->ExpectQuicSessionCreation();
374     }
375   }
376
377   void RemoveRequest(QuicStreamRequest* request) {
378     auto request_iter = stream_requests_.find(request);
379     DCHECK(request_iter != stream_requests_.end());
380     stream_requests_.erase(request_iter);
381   }
382
383   void SetPriority(RequestPriority priority) {
384     if (priority_ == priority)
385       return;
386
387     priority_ = priority;
388     if (resolve_host_request_ && !host_resolution_finished_) {
389       resolve_host_request_->ChangeRequestPriority(priority);
390     }
391   }
392
393   const std::set<QuicStreamRequest*>& stream_requests() {
394     return stream_requests_;
395   }
396
397   RequestPriority priority() const { return priority_; }
398
399  private:
400   enum IoState {
401     STATE_NONE,
402     STATE_RESOLVE_HOST,
403     STATE_RESOLVE_HOST_COMPLETE,
404     STATE_CREATE_SESSION,
405     STATE_CREATE_SESSION_COMPLETE,
406     STATE_CONNECT,
407     STATE_CONFIRM_CONNECTION,
408   };
409
410   void CloseStaleHostConnection() {
411     DVLOG(1) << "Closing connection from stale host.";
412     if (session_) {
413       QuicChromiumClientSession* session = session_;
414       session_ = nullptr;
415       // Use ERR_FAILED instead of ERR_ABORTED out of paranoia - ERR_ABORTED
416       // should only be used when the next layer up cancels a request, and has
417       // special semantic meaning for some consumers when they see it.
418       session->CloseSessionOnErrorLater(
419           ERR_FAILED, quic::QUIC_STALE_CONNECTION_CANCELLED,
420           quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
421     }
422   }
423
424   // Returns whether the client should be SVCB-optional when connecting to
425   // `results`.
426   bool IsSvcbOptional(
427       base::span<const HostResolverEndpointResult> results) const {
428     // If SVCB/HTTPS resolution succeeded, the client supports ECH, and all
429     // routes support ECH, disable the A/AAAA fallback. See Section 10.1 of
430     // draft-ietf-dnsop-svcb-https-11.
431     if (!factory_->ssl_config_service_->GetSSLContextConfig()
432              .EncryptedClientHelloEnabled() ||
433         !base::FeatureList::IsEnabled(features::kEncryptedClientHelloQuic)) {
434       return true;  // ECH is not supported for this request.
435     }
436
437     return !HostResolver::AllProtocolEndpointsHaveEch(results);
438   }
439
440   // Returns the QUIC version that would be used with `endpoint_result`, or
441   // `quic::ParsedQuicVersion::Unsupported()` if `endpoint_result` cannot be
442   // used with QUIC.
443   quic::ParsedQuicVersion SelectQuicVersion(
444       const HostResolverEndpointResult& endpoint_result,
445       bool svcb_optional) const {
446     // TODO(davidben): `require_dns_https_alpn_` only exists to be `DCHECK`ed
447     // for consistency against `quic_version_`. Remove the parameter?
448     DCHECK_EQ(require_dns_https_alpn_, !quic_version_.IsKnown());
449
450     if (endpoint_result.metadata.supported_protocol_alpns.empty()) {
451       // `endpoint_result` came from A/AAAA records directly, without HTTPS/SVCB
452       // records. If we know the QUIC ALPN to use externally, i.e. via Alt-Svc,
453       // use it in SVCB-optional mode. Otherwise, `endpoint_result` is not
454       // eligible for QUIC.
455       return svcb_optional ? quic_version_
456                            : quic::ParsedQuicVersion::Unsupported();
457     }
458
459     // Otherwise, `endpoint_result` came from an HTTPS/SVCB record. We can use
460     // QUIC if a suitable match is found in the record's ALPN list.
461     // Additionally, if this connection attempt came from Alt-Svc, the DNS
462     // result must be consistent with it. See
463     // https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-11.html#name-interaction-with-alt-svc
464     if (quic_version_.IsKnown()) {
465       std::string expected_alpn = quic::AlpnForVersion(quic_version_);
466       if (base::Contains(endpoint_result.metadata.supported_protocol_alpns,
467                          quic::AlpnForVersion(quic_version_))) {
468         return quic_version_;
469       }
470       return quic::ParsedQuicVersion::Unsupported();
471     }
472
473     for (const auto& alpn : endpoint_result.metadata.supported_protocol_alpns) {
474       for (const auto& supported_version : factory_->supported_versions()) {
475         if (alpn == AlpnForVersion(supported_version)) {
476           return supported_version;
477         }
478       }
479     }
480
481     return quic::ParsedQuicVersion::Unsupported();
482   }
483
484   void LogStaleAndFreshHostMatched(bool matched) {
485     if (matched) {
486       net_log_.AddEvent(
487           NetLogEventType::
488               QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_MATCHED);
489     } else {
490       net_log_.AddEvent(
491           NetLogEventType::
492               QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_NO_MATCH);
493     }
494     UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.StaleAndFreshHostMatched", matched);
495   }
496
497   IoState io_state_ = STATE_RESOLVE_HOST;
498   raw_ptr<QuicStreamFactory> factory_;
499   quic::ParsedQuicVersion quic_version_;
500   quic::ParsedQuicVersion quic_version_used_ =
501       quic::ParsedQuicVersion::Unsupported();
502   raw_ptr<HostResolver> host_resolver_;
503   const QuicSessionAliasKey key_;
504   const std::unique_ptr<CryptoClientConfigHandle> client_config_handle_;
505   RequestPriority priority_;
506   const bool use_dns_aliases_;
507   const bool require_dns_https_alpn_;
508   const int cert_verify_flags_;
509   const bool was_alternative_service_recently_broken_;
510   const bool retry_on_alternate_network_before_handshake_;
511   const NetLogWithSource net_log_;
512   bool host_resolution_finished_ = false;
513   bool session_creation_finished_ = false;
514   bool connection_retried_ = false;
515   // This field is not a raw_ptr<> because it was filtered by the rewriter for:
516   // #addr-of
517   RAW_PTR_EXCLUSION QuicChromiumClientSession* session_ = nullptr;
518   HostResolverEndpointResult endpoint_result_;
519   // If connection migraiton is supported, |network_| denotes the network on
520   // which |session_| is created.
521   handles::NetworkHandle network_;
522   CompletionOnceCallback host_resolution_callback_;
523   CompletionOnceCallback callback_;
524   std::unique_ptr<HostResolver::ResolveHostRequest> resolve_host_request_;
525   base::TimeTicks dns_resolution_start_time_;
526   base::TimeTicks dns_resolution_end_time_;
527   base::TimeTicks quic_connection_start_time_;
528   std::set<QuicStreamRequest*> stream_requests_;
529   base::WeakPtrFactory<Job> weak_factory_{this};
530 };
531
532 QuicStreamFactory::Job::Job(
533     QuicStreamFactory* factory,
534     quic::ParsedQuicVersion quic_version,
535     HostResolver* host_resolver,
536     const QuicSessionAliasKey& key,
537     std::unique_ptr<CryptoClientConfigHandle> client_config_handle,
538     bool was_alternative_service_recently_broken,
539     bool retry_on_alternate_network_before_handshake,
540     RequestPriority priority,
541     bool use_dns_aliases,
542     bool require_dns_https_alpn,
543     int cert_verify_flags,
544     const NetLogWithSource& net_log)
545     : factory_(factory),
546       quic_version_(quic_version),
547       host_resolver_(host_resolver),
548       key_(key),
549       client_config_handle_(std::move(client_config_handle)),
550       priority_(priority),
551       use_dns_aliases_(use_dns_aliases),
552       require_dns_https_alpn_(require_dns_https_alpn),
553       cert_verify_flags_(cert_verify_flags),
554       was_alternative_service_recently_broken_(
555           was_alternative_service_recently_broken),
556       retry_on_alternate_network_before_handshake_(
557           retry_on_alternate_network_before_handshake),
558       net_log_(
559           NetLogWithSource::Make(net_log.net_log(),
560                                  NetLogSourceType::QUIC_STREAM_FACTORY_JOB)),
561       network_(handles::kInvalidNetworkHandle) {
562   DCHECK_EQ(quic_version.IsKnown(), !require_dns_https_alpn);
563   net_log_.BeginEvent(NetLogEventType::QUIC_STREAM_FACTORY_JOB,
564                       [&] { return NetLogQuicStreamFactoryJobParams(&key_); });
565   // Associate |net_log_| with |net_log|.
566   net_log_.AddEventReferencingSource(
567       NetLogEventType::QUIC_STREAM_FACTORY_JOB_BOUND_TO_HTTP_STREAM_JOB,
568       net_log.source());
569   net_log.AddEventReferencingSource(
570       NetLogEventType::HTTP_STREAM_JOB_BOUND_TO_QUIC_STREAM_FACTORY_JOB,
571       net_log_.source());
572 }
573
574 QuicStreamFactory::Job::~Job() {
575   net_log_.EndEvent(NetLogEventType::QUIC_STREAM_FACTORY_JOB);
576   // If |this| is destroyed in QuicStreamFactory's destructor, |callback_| is
577   // non-null.
578 }
579
580 int QuicStreamFactory::Job::Run(CompletionOnceCallback callback) {
581   int rv = DoLoop(OK);
582   if (rv == ERR_IO_PENDING)
583     callback_ = std::move(callback);
584
585   return rv > 0 ? OK : rv;
586 }
587
588 int QuicStreamFactory::Job::DoLoop(int rv) {
589   TRACE_EVENT0(NetTracingCategory(), "QuicStreamFactory::Job::DoLoop");
590
591   do {
592     IoState state = io_state_;
593     io_state_ = STATE_NONE;
594     switch (state) {
595       case STATE_RESOLVE_HOST:
596         CHECK_EQ(OK, rv);
597         rv = DoResolveHost();
598         break;
599       case STATE_RESOLVE_HOST_COMPLETE:
600         rv = DoResolveHostComplete(rv);
601         break;
602       case STATE_CREATE_SESSION:
603         rv = DoCreateSession();
604         break;
605       case STATE_CREATE_SESSION_COMPLETE:
606         rv = DoCreateSessionComplete(rv);
607         break;
608       case STATE_CONNECT:
609         rv = DoConnect(rv);
610         break;
611       case STATE_CONFIRM_CONNECTION:
612         rv = DoConfirmConnection(rv);
613         break;
614       default:
615         NOTREACHED() << "io_state_: " << io_state_;
616         break;
617     }
618   } while (io_state_ != STATE_NONE && rv != ERR_IO_PENDING);
619   return rv;
620 }
621
622 void QuicStreamFactory::Job::OnResolveHostComplete(int rv) {
623   DCHECK(!host_resolution_finished_);
624   io_state_ = STATE_RESOLVE_HOST_COMPLETE;
625   rv = DoLoop(rv);
626
627   for (auto* request : stream_requests_) {
628     request->OnHostResolutionComplete(rv);
629   }
630
631   if (rv != ERR_IO_PENDING && !callback_.is_null())
632     std::move(callback_).Run(rv);
633 }
634
635 void QuicStreamFactory::Job::OnCryptoConnectComplete(int rv) {
636   // This early return will be triggered when CloseSessionOnError is called
637   // before crypto handshake has completed.
638   if (!session_) {
639     LogStaleConnectionTime(quic_connection_start_time_);
640     return;
641   }
642
643   if (rv == ERR_QUIC_PROTOCOL_ERROR) {
644     HistogramProtocolErrorLocation(
645         JobProtocolErrorLocation::kCryptoConnectFailedAsync);
646   }
647
648   io_state_ = STATE_CONFIRM_CONNECTION;
649   rv = DoLoop(rv);
650   if (rv != ERR_IO_PENDING && !callback_.is_null())
651     std::move(callback_).Run(rv);
652 }
653
654 void QuicStreamFactory::Job::PopulateNetErrorDetails(
655     NetErrorDetails* details) const {
656   if (!session_)
657     return;
658   details->connection_info = QuicHttpStream::ConnectionInfoFromQuicVersion(
659       session_->connection()->version());
660   details->quic_connection_error = session_->error();
661 }
662
663 int QuicStreamFactory::Job::DoResolveHost() {
664   dns_resolution_start_time_ = base::TimeTicks::Now();
665
666   io_state_ = STATE_RESOLVE_HOST_COMPLETE;
667
668   HostResolver::ResolveHostParameters parameters;
669   parameters.initial_priority = priority_;
670   parameters.secure_dns_policy = key_.session_key().secure_dns_policy();
671   resolve_host_request_ = host_resolver_->CreateRequest(
672       key_.destination(), key_.session_key().network_anonymization_key(),
673       net_log_, parameters);
674   // Unretained is safe because |this| owns the request, ensuring cancellation
675   // on destruction.
676   return resolve_host_request_->Start(base::BindOnce(
677       &QuicStreamFactory::Job::OnResolveHostComplete, base::Unretained(this)));
678 }
679
680 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) {
681   host_resolution_finished_ = true;
682   dns_resolution_end_time_ = base::TimeTicks::Now();
683   if (rv != OK)
684     return rv;
685
686   DCHECK(!factory_->HasActiveSession(key_.session_key()));
687
688   // Inform the factory of this resolution, which will set up
689   // a session alias, if possible.
690   const bool svcb_optional =
691       IsSvcbOptional(*resolve_host_request_->GetEndpointResults());
692   for (const auto& endpoint : *resolve_host_request_->GetEndpointResults()) {
693     // Only consider endpoints that would have been eligible for QUIC.
694     if (!SelectQuicVersion(endpoint, svcb_optional).IsKnown()) {
695       continue;
696     }
697     if (factory_->HasMatchingIpSession(
698             key_, endpoint.ip_endpoints,
699             *resolve_host_request_->GetDnsAliasResults(), use_dns_aliases_)) {
700       LogConnectionIpPooling(true);
701       return OK;
702     }
703   }
704   io_state_ = STATE_CREATE_SESSION;
705   return OK;
706 }
707
708 void QuicStreamFactory::Job::OnCreateSessionComplete(int rv) {
709   if (rv != OK) {
710     DCHECK(!session_);
711     if (rv == ERR_QUIC_PROTOCOL_ERROR) {
712       HistogramProtocolErrorLocation(
713           JobProtocolErrorLocation::kCreateSessionFailedAsync);
714     }
715     for (auto* request : stream_requests_) {
716       request->OnQuicSessionCreationComplete(rv);
717     }
718     if (!callback_.is_null()) {
719       std::move(callback_).Run(rv);
720     }
721     return;
722   }
723   DCHECK(session_);
724   DVLOG(1) << "Created session on network: " << network_;
725   io_state_ = STATE_CREATE_SESSION_COMPLETE;
726   rv = DoLoop(rv);
727
728   for (auto* request : stream_requests_) {
729     request->OnQuicSessionCreationComplete(rv);
730   }
731
732   if (rv != ERR_IO_PENDING && !callback_.is_null()) {
733     std::move(callback_).Run(rv);
734   }
735 }
736
737 int QuicStreamFactory::Job::DoCreateSession() {
738   // TODO(https://crbug.com/1416409): This logic only knows how to try one
739   // endpoint result.
740   bool svcb_optional =
741       IsSvcbOptional(*resolve_host_request_->GetEndpointResults());
742   bool found = false;
743   for (const auto& candidate : *resolve_host_request_->GetEndpointResults()) {
744     quic::ParsedQuicVersion version =
745         SelectQuicVersion(candidate, svcb_optional);
746     if (version.IsKnown()) {
747       found = true;
748       quic_version_used_ = version;
749       endpoint_result_ = candidate;
750       break;
751     }
752   }
753   if (!found) {
754     return ERR_DNS_NO_MATCHING_SUPPORTED_ALPN;
755   }
756
757   quic_connection_start_time_ = base::TimeTicks::Now();
758   DCHECK(dns_resolution_end_time_ != base::TimeTicks());
759   io_state_ = STATE_CREATE_SESSION_COMPLETE;
760   bool require_confirmation = was_alternative_service_recently_broken_;
761   net_log_.AddEntryWithBoolParams(
762       NetLogEventType::QUIC_STREAM_FACTORY_JOB_CONNECT, NetLogEventPhase::BEGIN,
763       "require_confirmation", require_confirmation);
764
765   DCHECK_NE(quic_version_used_, quic::ParsedQuicVersion::Unsupported());
766   if (base::FeatureList::IsEnabled(net::features::kAsyncQuicSession)) {
767     return factory_->CreateSessionAsync(
768         base::BindOnce(&QuicStreamFactory::Job::OnCreateSessionComplete,
769                        GetWeakPtr()),
770         key_, quic_version_used_, cert_verify_flags_, require_confirmation,
771         endpoint_result_, dns_resolution_start_time_, dns_resolution_end_time_,
772         net_log_, &session_, &network_);
773   }
774   int rv = factory_->CreateSessionSync(
775       key_, quic_version_used_, cert_verify_flags_, require_confirmation,
776       endpoint_result_, dns_resolution_start_time_, dns_resolution_end_time_,
777       net_log_, &session_, &network_);
778
779   DVLOG(1) << "Created session on network: " << network_;
780
781   if (rv == ERR_QUIC_PROTOCOL_ERROR) {
782     DCHECK(!session_);
783     HistogramProtocolErrorLocation(
784         JobProtocolErrorLocation::kCreateSessionFailedSync);
785   }
786
787   return rv;
788 }
789 int QuicStreamFactory::Job::DoCreateSessionComplete(int rv) {
790   session_creation_finished_ = true;
791   if (rv != OK) {
792     return rv;
793   }
794   io_state_ = STATE_CONNECT;
795   if (!session_->connection()->connected()) {
796     return ERR_CONNECTION_CLOSED;
797   }
798
799   session_->StartReading();
800   if (!session_->connection()->connected()) {
801     if (base::FeatureList::IsEnabled(net::features::kAsyncQuicSession)) {
802       HistogramProtocolErrorLocation(
803           JobProtocolErrorLocation::kSessionStartReadingFailedAsync);
804     } else {
805       HistogramProtocolErrorLocation(
806           JobProtocolErrorLocation::kSessionStartReadingFailedSync);
807     }
808     return ERR_QUIC_PROTOCOL_ERROR;
809   }
810   return OK;
811 }
812
813 int QuicStreamFactory::Job::DoConnect(int rv) {
814   if (rv != OK) {
815     return rv;
816   }
817   DCHECK(session_);
818   io_state_ = STATE_CONFIRM_CONNECTION;
819   rv = session_->CryptoConnect(base::BindOnce(
820       &QuicStreamFactory::Job::OnCryptoConnectComplete, GetWeakPtr()));
821
822   if (rv != ERR_IO_PENDING) {
823     LogValidConnectionTime(quic_connection_start_time_);
824   }
825
826   if (!session_->connection()->connected() &&
827       session_->error() == quic::QUIC_PROOF_INVALID) {
828     return ERR_QUIC_HANDSHAKE_FAILED;
829   }
830
831   if (rv == ERR_QUIC_PROTOCOL_ERROR) {
832     HistogramProtocolErrorLocation(
833         JobProtocolErrorLocation::kCryptoConnectFailedSync);
834   }
835
836   return rv;
837 }
838
839 int QuicStreamFactory::Job::DoConfirmConnection(int rv) {
840   UMA_HISTOGRAM_TIMES("Net.QuicSession.TimeFromResolveHostToConfirmConnection",
841                       base::TimeTicks::Now() - dns_resolution_start_time_);
842   net_log_.EndEvent(NetLogEventType::QUIC_STREAM_FACTORY_JOB_CONNECT);
843
844   if (was_alternative_service_recently_broken_)
845     UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ConnectAfterBroken", rv == OK);
846
847   if (retry_on_alternate_network_before_handshake_ && session_ &&
848       !session_->OneRttKeysAvailable() &&
849       network_ == factory_->default_network()) {
850     if (session_->error() == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
851         session_->error() == quic::QUIC_HANDSHAKE_TIMEOUT ||
852         session_->error() == quic::QUIC_PACKET_WRITE_ERROR) {
853       // Retry the connection on an alternate network if crypto handshake failed
854       // with network idle time out or handshake time out.
855       DCHECK(network_ != handles::kInvalidNetworkHandle);
856       network_ = factory_->FindAlternateNetwork(network_);
857       connection_retried_ = network_ != handles::kInvalidNetworkHandle;
858       UMA_HISTOGRAM_BOOLEAN(
859           "Net.QuicStreamFactory.AttemptMigrationBeforeHandshake",
860           connection_retried_);
861       UMA_HISTOGRAM_ENUMERATION(
862           "Net.QuicStreamFactory.AttemptMigrationBeforeHandshake."
863           "FailedConnectionType",
864           NetworkChangeNotifier::GetNetworkConnectionType(
865               factory_->default_network()),
866           NetworkChangeNotifier::ConnectionType::CONNECTION_LAST + 1);
867       if (connection_retried_) {
868         UMA_HISTOGRAM_ENUMERATION(
869             "Net.QuicStreamFactory.MigrationBeforeHandshake.NewConnectionType",
870             NetworkChangeNotifier::GetNetworkConnectionType(network_),
871             NetworkChangeNotifier::ConnectionType::CONNECTION_LAST + 1);
872         net_log_.AddEvent(
873             NetLogEventType::
874                 QUIC_STREAM_FACTORY_JOB_RETRY_ON_ALTERNATE_NETWORK);
875         // Notify requests that connection on the default network failed.
876         for (auto* request : stream_requests_) {
877           request->OnConnectionFailedOnDefaultNetwork();
878         }
879         DVLOG(1) << "Retry connection on alternate network: " << network_;
880         session_ = nullptr;
881         io_state_ = STATE_CREATE_SESSION;
882         return OK;
883       }
884     }
885   }
886
887   if (connection_retried_) {
888     UMA_HISTOGRAM_BOOLEAN("Net.QuicStreamFactory.MigrationBeforeHandshake2",
889                           rv == OK);
890     if (rv == OK) {
891       UMA_HISTOGRAM_BOOLEAN(
892           "Net.QuicStreamFactory.NetworkChangeDuringMigrationBeforeHandshake",
893           network_ == factory_->default_network());
894     } else {
895       base::UmaHistogramSparse(
896           "Net.QuicStreamFactory.MigrationBeforeHandshakeFailedReason", -rv);
897     }
898   } else if (network_ != handles::kInvalidNetworkHandle &&
899              network_ != factory_->default_network()) {
900     UMA_HISTOGRAM_BOOLEAN("Net.QuicStreamFactory.ConnectionOnNonDefaultNetwork",
901                           rv == OK);
902   }
903
904   if (rv != OK)
905     return rv;
906
907   DCHECK(!factory_->HasActiveSession(key_.session_key()));
908   // There may well now be an active session for this IP.  If so, use the
909   // existing session instead.
910   if (factory_->HasMatchingIpSession(
911           key_, {ToIPEndPoint(session_->connection()->peer_address())},
912           /*aliases=*/{}, use_dns_aliases_)) {
913     LogConnectionIpPooling(true);
914     session_->connection()->CloseConnection(
915         quic::QUIC_CONNECTION_IP_POOLED,
916         "An active session exists for the given IP.",
917         quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
918     session_ = nullptr;
919     return OK;
920   }
921   LogConnectionIpPooling(false);
922
923   std::set<std::string> dns_aliases =
924       use_dns_aliases_ && resolve_host_request_->GetDnsAliasResults()
925           ? *resolve_host_request_->GetDnsAliasResults()
926           : std::set<std::string>();
927   factory_->ActivateSession(key_, session_, std::move(dns_aliases));
928
929   return OK;
930 }
931
932 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory)
933     : factory_(factory) {}
934
935 QuicStreamRequest::~QuicStreamRequest() {
936   if (factory_ && !callback_.is_null())
937     factory_->CancelRequest(this);
938 }
939
940 int QuicStreamRequest::Request(
941     url::SchemeHostPort destination,
942     quic::ParsedQuicVersion quic_version,
943     PrivacyMode privacy_mode,
944     RequestPriority priority,
945     const SocketTag& socket_tag,
946     const NetworkAnonymizationKey& network_anonymization_key,
947     SecureDnsPolicy secure_dns_policy,
948     bool use_dns_aliases,
949     bool require_dns_https_alpn,
950     int cert_verify_flags,
951     const GURL& url,
952     const NetLogWithSource& net_log,
953     NetErrorDetails* net_error_details,
954     CompletionOnceCallback failed_on_default_network_callback,
955     CompletionOnceCallback callback) {
956   DCHECK_EQ(quic_version.IsKnown(), !require_dns_https_alpn);
957   DCHECK(net_error_details);
958   DCHECK(callback_.is_null());
959   DCHECK(host_resolution_callback_.is_null());
960   DCHECK(factory_);
961
962   net_error_details_ = net_error_details;
963   failed_on_default_network_callback_ =
964       std::move(failed_on_default_network_callback);
965
966   session_key_ = QuicSessionKey(HostPortPair::FromURL(url), privacy_mode,
967                                 socket_tag, network_anonymization_key,
968                                 secure_dns_policy, require_dns_https_alpn);
969
970   int rv = factory_->Create(session_key_, std::move(destination), quic_version,
971                             priority, use_dns_aliases, cert_verify_flags, url,
972                             net_log, this);
973   if (rv == ERR_IO_PENDING) {
974     net_log_ = net_log;
975     callback_ = std::move(callback);
976   } else {
977     DCHECK(!expect_on_host_resolution_);
978     factory_ = nullptr;
979   }
980
981   if (rv == OK)
982     DCHECK(session_);
983   return rv;
984 }
985
986 bool QuicStreamRequest::WaitForHostResolution(CompletionOnceCallback callback) {
987   DCHECK(host_resolution_callback_.is_null());
988   if (expect_on_host_resolution_) {
989     host_resolution_callback_ = std::move(callback);
990   }
991   return expect_on_host_resolution_;
992 }
993
994 void QuicStreamRequest::ExpectOnHostResolution() {
995   expect_on_host_resolution_ = true;
996 }
997
998 void QuicStreamRequest::OnHostResolutionComplete(int rv) {
999   DCHECK(expect_on_host_resolution_);
1000   expect_on_host_resolution_ = false;
1001   if (!host_resolution_callback_.is_null()) {
1002     std::move(host_resolution_callback_).Run(rv);
1003   }
1004 }
1005
1006 bool QuicStreamRequest::WaitForQuicSessionCreation(
1007     CompletionOnceCallback callback) {
1008   DCHECK(create_session_callback_.is_null());
1009   if (expect_on_quic_session_creation_) {
1010     create_session_callback_ = std::move(callback);
1011   }
1012   return expect_on_quic_session_creation_;
1013 }
1014
1015 void QuicStreamRequest::ExpectQuicSessionCreation() {
1016   expect_on_quic_session_creation_ = true;
1017 }
1018
1019 void QuicStreamRequest::OnQuicSessionCreationComplete(int rv) {
1020   // DCHECK(expect_on_quic_session_creation_);
1021   expect_on_quic_session_creation_ = false;
1022   if (!create_session_callback_.is_null()) {
1023     std::move(create_session_callback_).Run(rv);
1024   }
1025 }
1026
1027 void QuicStreamRequest::OnRequestComplete(int rv) {
1028   factory_ = nullptr;
1029   std::move(callback_).Run(rv);
1030 }
1031
1032 void QuicStreamRequest::OnConnectionFailedOnDefaultNetwork() {
1033   if (!failed_on_default_network_callback_.is_null())
1034     std::move(failed_on_default_network_callback_).Run(OK);
1035 }
1036
1037 base::TimeDelta QuicStreamRequest::GetTimeDelayForWaitingJob() const {
1038   if (!factory_)
1039     return base::TimeDelta();
1040   return factory_->GetTimeDelayForWaitingJob(session_key_);
1041 }
1042
1043 void QuicStreamRequest::SetPriority(RequestPriority priority) {
1044   if (factory_)
1045     factory_->SetRequestPriority(this, priority);
1046 }
1047
1048 std::unique_ptr<QuicChromiumClientSession::Handle>
1049 QuicStreamRequest::ReleaseSessionHandle() {
1050   if (!session_ || !session_->IsConnected())
1051     return nullptr;
1052
1053   return std::move(session_);
1054 }
1055
1056 void QuicStreamRequest::SetSession(
1057     std::unique_ptr<QuicChromiumClientSession::Handle> session) {
1058   session_ = std::move(session);
1059 }
1060
1061 bool QuicStreamRequest::CanUseExistingSession(
1062     const GURL& url,
1063     PrivacyMode privacy_mode,
1064     const SocketTag& socket_tag,
1065     const NetworkAnonymizationKey& network_anonymization_key,
1066     SecureDnsPolicy secure_dns_policy,
1067     bool require_dns_https_alpn,
1068     const url::SchemeHostPort& destination) const {
1069   return factory_->CanUseExistingSession(
1070       QuicSessionKey(HostPortPair::FromURL(url), privacy_mode, socket_tag,
1071                      network_anonymization_key, secure_dns_policy,
1072                      require_dns_https_alpn),
1073       destination);
1074 }
1075
1076 QuicStreamFactory::QuicSessionAliasKey::QuicSessionAliasKey(
1077     url::SchemeHostPort destination,
1078     QuicSessionKey session_key)
1079     : destination_(std::move(destination)),
1080       session_key_(std::move(session_key)) {}
1081
1082 bool QuicStreamFactory::QuicSessionAliasKey::operator<(
1083     const QuicSessionAliasKey& other) const {
1084   return std::tie(destination_, session_key_) <
1085          std::tie(other.destination_, other.session_key_);
1086 }
1087
1088 bool QuicStreamFactory::QuicSessionAliasKey::operator==(
1089     const QuicSessionAliasKey& other) const {
1090   return destination_ == other.destination_ &&
1091          session_key_ == other.session_key_;
1092 }
1093
1094 QuicStreamFactory::QuicStreamFactory(
1095     NetLog* net_log,
1096     HostResolver* host_resolver,
1097     SSLConfigService* ssl_config_service,
1098     ClientSocketFactory* client_socket_factory,
1099     HttpServerProperties* http_server_properties,
1100     CertVerifier* cert_verifier,
1101     CTPolicyEnforcer* ct_policy_enforcer,
1102     TransportSecurityState* transport_security_state,
1103     SCTAuditingDelegate* sct_auditing_delegate,
1104     SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
1105     QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory,
1106     QuicContext* quic_context)
1107     : net_log_(NetLogWithSource::Make(net_log,
1108                                       NetLogSourceType::QUIC_STREAM_FACTORY)),
1109       host_resolver_(host_resolver),
1110       client_socket_factory_(client_socket_factory),
1111       http_server_properties_(http_server_properties),
1112       cert_verifier_(cert_verifier),
1113       ct_policy_enforcer_(ct_policy_enforcer),
1114       transport_security_state_(transport_security_state),
1115       sct_auditing_delegate_(sct_auditing_delegate),
1116       quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory),
1117       random_generator_(quic_context->random_generator()),
1118       clock_(quic_context->clock()),
1119       // TODO(vasilvv): figure out how to avoid having multiple copies of
1120       // QuicParams.
1121       params_(*quic_context->params()),
1122       clock_skew_detector_(base::TimeTicks::Now(), base::Time::Now()),
1123       socket_performance_watcher_factory_(socket_performance_watcher_factory),
1124       recent_crypto_config_map_(kMaxRecentCryptoConfigs),
1125       config_(InitializeQuicConfig(*quic_context->params())),
1126       ping_timeout_(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs)),
1127       reduced_ping_timeout_(quic::QuicTime::Delta::FromMicroseconds(
1128           quic_context->params()->reduced_ping_timeout.InMicroseconds())),
1129       retransmittable_on_wire_timeout_(quic::QuicTime::Delta::FromMicroseconds(
1130           quic_context->params()
1131               ->retransmittable_on_wire_timeout.InMicroseconds())),
1132       yield_after_packets_(kQuicYieldAfterPacketsRead),
1133       yield_after_duration_(quic::QuicTime::Delta::FromMilliseconds(
1134           kQuicYieldAfterDurationMilliseconds)),
1135       default_network_(handles::kInvalidNetworkHandle),
1136       connectivity_monitor_(default_network_),
1137       ssl_config_service_(ssl_config_service),
1138       use_network_anonymization_key_for_crypto_configs_(
1139           NetworkAnonymizationKey::IsPartitioningEnabled()) {
1140   DCHECK(transport_security_state_);
1141   DCHECK(http_server_properties_);
1142   if (params_.disable_tls_zero_rtt)
1143     SetQuicFlag(quic_disable_client_tls_zero_rtt, true);
1144   InitializeMigrationOptions();
1145   cert_verifier_->AddObserver(this);
1146   CertDatabase::GetInstance()->AddObserver(this);
1147 }
1148
1149 QuicStreamFactory::~QuicStreamFactory() {
1150   UMA_HISTOGRAM_COUNTS_1000("Net.NumQuicSessionsAtShutdown",
1151                             all_sessions_.size());
1152   CloseAllSessions(ERR_ABORTED, quic::QUIC_CONNECTION_CANCELLED);
1153   while (!all_sessions_.empty()) {
1154     delete all_sessions_.begin()->first;
1155     all_sessions_.erase(all_sessions_.begin());
1156   }
1157   active_jobs_.clear();
1158
1159   DCHECK(dns_aliases_by_session_key_.empty());
1160
1161   // This should have been moved to the recent map when all consumers of
1162   // QuicCryptoClientConfigs were deleted, in the above lines.
1163   DCHECK(active_crypto_config_map_.empty());
1164
1165   CertDatabase::GetInstance()->RemoveObserver(this);
1166   cert_verifier_->RemoveObserver(this);
1167   if (params_.close_sessions_on_ip_change ||
1168       params_.goaway_sessions_on_ip_change) {
1169     NetworkChangeNotifier::RemoveIPAddressObserver(this);
1170   }
1171   if (NetworkChangeNotifier::AreNetworkHandlesSupported()) {
1172     NetworkChangeNotifier::RemoveNetworkObserver(this);
1173   }
1174 }
1175
1176 bool QuicStreamFactory::CanUseExistingSession(
1177     const QuicSessionKey& session_key,
1178     const url::SchemeHostPort& destination) const {
1179   if (base::Contains(active_sessions_, session_key))
1180     return true;
1181
1182   for (const auto& key_value : active_sessions_) {
1183     QuicChromiumClientSession* session = key_value.second;
1184     const auto& it = all_sessions_.find(session);
1185     if ((it != all_sessions_.end()) &&
1186         (destination == it->second.destination()) &&
1187         session->CanPool(session_key.host(), session_key)) {
1188       return true;
1189     }
1190   }
1191
1192   return false;
1193 }
1194
1195 int QuicStreamFactory::Create(const QuicSessionKey& session_key,
1196                               url::SchemeHostPort destination,
1197                               quic::ParsedQuicVersion quic_version,
1198                               RequestPriority priority,
1199                               bool use_dns_aliases,
1200                               int cert_verify_flags,
1201                               const GURL& url,
1202                               const NetLogWithSource& net_log,
1203                               QuicStreamRequest* request) {
1204   if (clock_skew_detector_.ClockSkewDetected(base::TimeTicks::Now(),
1205                                              base::Time::Now())) {
1206     MarkAllActiveSessionsGoingAway(kClockSkewDetected);
1207   }
1208   DCHECK(HostPortPair(session_key.server_id().host(),
1209                       session_key.server_id().port())
1210              .Equals(HostPortPair::FromURL(url)));
1211
1212   // Use active session for |session_key| if such exists.
1213   auto active_session = active_sessions_.find(session_key);
1214   if (active_session != active_sessions_.end()) {
1215     QuicChromiumClientSession* session = active_session->second;
1216     request->SetSession(session->CreateHandle(std::move(destination)));
1217     return OK;
1218   }
1219
1220   // Associate with active job to |session_key| if such exists.
1221   auto active_job = active_jobs_.find(session_key);
1222   if (active_job != active_jobs_.end()) {
1223     const NetLogWithSource& job_net_log = active_job->second->net_log();
1224     job_net_log.AddEventReferencingSource(
1225         NetLogEventType::QUIC_STREAM_FACTORY_JOB_BOUND_TO_HTTP_STREAM_JOB,
1226         net_log.source());
1227     net_log.AddEventReferencingSource(
1228         NetLogEventType::HTTP_STREAM_JOB_BOUND_TO_QUIC_STREAM_FACTORY_JOB,
1229         job_net_log.source());
1230     active_job->second->AddRequest(request);
1231     return ERR_IO_PENDING;
1232   }
1233
1234   // Pool to active session to |destination| if possible.
1235   if (!active_sessions_.empty()) {
1236     for (const auto& key_value : active_sessions_) {
1237       QuicChromiumClientSession* session = key_value.second;
1238       if (destination == all_sessions_[session].destination() &&
1239           session->CanPool(session_key.server_id().host(), session_key)) {
1240         request->SetSession(session->CreateHandle(std::move(destination)));
1241         return OK;
1242       }
1243     }
1244   }
1245
1246   // TODO(rtenneti): |task_runner_| is used by the Job. Initialize task_runner_
1247   // in the constructor after WebRequestActionWithThreadsTest.* tests are fixed.
1248   if (!task_runner_)
1249     task_runner_ = base::SequencedTaskRunner::GetCurrentDefault().get();
1250
1251   if (!tick_clock_)
1252     tick_clock_ = base::DefaultTickClock::GetInstance();
1253
1254   QuicSessionAliasKey key(destination, session_key);
1255   std::unique_ptr<Job> job = std::make_unique<Job>(
1256       this, quic_version, host_resolver_, key,
1257       CreateCryptoConfigHandle(session_key.network_anonymization_key()),
1258       WasQuicRecentlyBroken(session_key),
1259       params_.retry_on_alternate_network_before_handshake, priority,
1260       use_dns_aliases, session_key.require_dns_https_alpn(), cert_verify_flags,
1261       net_log);
1262   int rv = job->Run(base::BindOnce(&QuicStreamFactory::OnJobComplete,
1263                                    weak_factory_.GetWeakPtr(), job.get()));
1264   if (rv == ERR_IO_PENDING) {
1265     job->AddRequest(request);
1266     active_jobs_[session_key] = std::move(job);
1267     return rv;
1268   }
1269   if (rv == OK) {
1270     auto it = active_sessions_.find(session_key);
1271     DCHECK(it != active_sessions_.end());
1272     if (it == active_sessions_.end())
1273       return ERR_QUIC_PROTOCOL_ERROR;
1274     QuicChromiumClientSession* session = it->second;
1275     request->SetSession(session->CreateHandle(std::move(destination)));
1276   }
1277   return rv;
1278 }
1279
1280 void QuicStreamFactory::OnSessionGoingAway(QuicChromiumClientSession* session) {
1281   const AliasSet& aliases = session_aliases_[session];
1282   for (const auto& alias : aliases) {
1283     const QuicSessionKey& session_key = alias.session_key();
1284     DCHECK(active_sessions_.count(session_key));
1285     DCHECK_EQ(session, active_sessions_[session_key]);
1286     // Track sessions which have recently gone away so that we can disable
1287     // port suggestions.
1288     if (session->goaway_received())
1289       gone_away_aliases_.insert(alias);
1290
1291     active_sessions_.erase(session_key);
1292     ProcessGoingAwaySession(session, session_key.server_id(), true);
1293   }
1294   ProcessGoingAwaySession(session, all_sessions_[session].server_id(), false);
1295   if (!aliases.empty()) {
1296     DCHECK(base::Contains(session_peer_ip_, session));
1297     const IPEndPoint peer_address = session_peer_ip_[session];
1298     ip_aliases_[peer_address].erase(session);
1299     if (ip_aliases_[peer_address].empty())
1300       ip_aliases_.erase(peer_address);
1301     session_peer_ip_.erase(session);
1302   }
1303   UnmapSessionFromSessionAliases(session);
1304 }
1305
1306 void QuicStreamFactory::OnSessionClosed(QuicChromiumClientSession* session) {
1307   DCHECK_EQ(0u, session->GetNumActiveStreams());
1308   OnSessionGoingAway(session);
1309   delete session;
1310   all_sessions_.erase(session);
1311 }
1312
1313 void QuicStreamFactory::OnBlackholeAfterHandshakeConfirmed(
1314     QuicChromiumClientSession* session) {
1315   // Reduce PING timeout when connection blackholes after the handshake.
1316   if (ping_timeout_ > reduced_ping_timeout_)
1317     ping_timeout_ = reduced_ping_timeout_;
1318 }
1319
1320 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) {
1321   auto job_iter = active_jobs_.find(request->session_key());
1322   CHECK(job_iter != active_jobs_.end());
1323   job_iter->second->RemoveRequest(request);
1324 }
1325
1326 void QuicStreamFactory::SetRequestPriority(QuicStreamRequest* request,
1327                                            RequestPriority priority) {
1328   auto job_iter = active_jobs_.find(request->session_key());
1329   if (job_iter == active_jobs_.end())
1330     return;
1331   job_iter->second->SetPriority(priority);
1332 }
1333
1334 void QuicStreamFactory::CloseAllSessions(int error,
1335                                          quic::QuicErrorCode quic_error) {
1336   net_log_.AddEvent(NetLogEventType::QUIC_STREAM_FACTORY_CLOSE_ALL_SESSIONS);
1337   base::UmaHistogramSparse("Net.QuicSession.CloseAllSessionsError", -error);
1338   while (!active_sessions_.empty()) {
1339     size_t initial_size = active_sessions_.size();
1340     active_sessions_.begin()->second->CloseSessionOnError(
1341         error, quic_error,
1342         quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1343     DCHECK_NE(initial_size, active_sessions_.size());
1344   }
1345   while (!all_sessions_.empty()) {
1346     size_t initial_size = all_sessions_.size();
1347     all_sessions_.begin()->first->CloseSessionOnError(
1348         error, quic_error,
1349         quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1350     DCHECK_NE(initial_size, all_sessions_.size());
1351   }
1352   DCHECK(all_sessions_.empty());
1353 }
1354
1355 base::Value QuicStreamFactory::QuicStreamFactoryInfoToValue() const {
1356   base::Value::List list;
1357
1358   for (const auto& active_session : active_sessions_) {
1359     const quic::QuicServerId& server_id = active_session.first.server_id();
1360     QuicChromiumClientSession* session = active_session.second;
1361     const AliasSet& aliases = session_aliases_.find(session)->second;
1362     // Only add a session to the list once.
1363     if (server_id == aliases.begin()->server_id()) {
1364       std::set<HostPortPair> hosts;
1365       for (const auto& alias : aliases) {
1366         hosts.insert(
1367             HostPortPair(alias.server_id().host(), alias.server_id().port()));
1368       }
1369       list.Append(session->GetInfoAsValue(hosts));
1370     }
1371   }
1372   return base::Value(std::move(list));
1373 }
1374
1375 void QuicStreamFactory::ClearCachedStatesInCryptoConfig(
1376     const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {
1377   ServerIdOriginFilter filter(origin_filter);
1378   for (const auto& crypto_config : active_crypto_config_map_) {
1379     crypto_config.second->config()->ClearCachedStates(filter);
1380   }
1381
1382   for (const auto& crypto_config : recent_crypto_config_map_) {
1383     crypto_config.second->config()->ClearCachedStates(filter);
1384   }
1385 }
1386
1387 int QuicStreamFactory::ConnectAndConfigureSocket(
1388     CompletionOnceCallback callback,
1389     DatagramClientSocket* socket,
1390     IPEndPoint addr,
1391     handles::NetworkHandle network,
1392     const SocketTag& socket_tag) {
1393   socket->UseNonBlockingIO();
1394
1395   int rv;
1396   auto split_callback = base::SplitOnceCallback(std::move(callback));
1397   CompletionOnceCallback connect_callback =
1398       base::BindOnce(&QuicStreamFactory::FinishConnectAndConfigureSocket,
1399                      weak_factory_.GetWeakPtr(),
1400                      std::move(split_callback.first), socket, socket_tag);
1401   if (!params_.migrate_sessions_on_network_change_v2) {
1402     rv = socket->ConnectAsync(addr, std::move(connect_callback));
1403   } else if (network == handles::kInvalidNetworkHandle) {
1404     // If caller leaves network unspecified, use current default network.
1405     rv = socket->ConnectUsingDefaultNetworkAsync(addr,
1406                                                  std::move(connect_callback));
1407   } else {
1408     rv = socket->ConnectUsingNetworkAsync(network, addr,
1409                                           std::move(connect_callback));
1410   }
1411   // Both callbacks within `split_callback` will always be run asynchronously,
1412   // even if a Connect call returns synchronously. Therefore we always return
1413   // ERR_IO_PENDING.
1414   if (rv != ERR_IO_PENDING) {
1415     FinishConnectAndConfigureSocket(std::move(split_callback.second), socket,
1416                                     socket_tag, rv);
1417   }
1418   return ERR_IO_PENDING;
1419 }
1420
1421 void QuicStreamFactory::FinishConnectAndConfigureSocket(
1422     CompletionOnceCallback callback,
1423     DatagramClientSocket* socket,
1424     const SocketTag& socket_tag,
1425     int rv) {
1426   if (rv != OK) {
1427     OnFinishConnectAndConfigureSocketError(
1428         std::move(callback), CREATION_ERROR_CONNECTING_SOCKET, rv);
1429     return;
1430   }
1431
1432   socket->ApplySocketTag(socket_tag);
1433
1434   rv = socket->SetReceiveBufferSize(kQuicSocketReceiveBufferSize);
1435   if (rv != OK) {
1436     OnFinishConnectAndConfigureSocketError(
1437         std::move(callback), CREATION_ERROR_SETTING_RECEIVE_BUFFER, rv);
1438     return;
1439   }
1440
1441   rv = socket->SetDoNotFragment();
1442   // SetDoNotFragment is not implemented on all platforms, so ignore errors.
1443   if (rv != OK && rv != ERR_NOT_IMPLEMENTED) {
1444     OnFinishConnectAndConfigureSocketError(
1445         std::move(callback), CREATION_ERROR_SETTING_DO_NOT_FRAGMENT, rv);
1446     return;
1447   }
1448
1449   if (base::FeatureList::IsEnabled(net::features::kReceiveEcn)) {
1450     rv = socket->SetRecvEcn();
1451     if (rv != OK) {
1452       OnFinishConnectAndConfigureSocketError(
1453           std::move(callback), CREATION_ERROR_SETTING_RECEIVE_ECN, rv);
1454       return;
1455     }
1456   }
1457
1458   // Set a buffer large enough to contain the initial CWND's worth of packet
1459   // to work around the problem with CHLO packets being sent out with the
1460   // wrong encryption level, when the send buffer is full.
1461   rv = socket->SetSendBufferSize(quic::kMaxOutgoingPacketSize * 20);
1462   if (rv != OK) {
1463     OnFinishConnectAndConfigureSocketError(
1464         std::move(callback), CREATION_ERROR_SETTING_SEND_BUFFER, rv);
1465     return;
1466   }
1467
1468   if (params_.ios_network_service_type > 0) {
1469     socket->SetIOSNetworkServiceType(params_.ios_network_service_type);
1470   }
1471
1472   socket->GetLocalAddress(&local_address_);
1473   if (need_to_check_persisted_supports_quic_) {
1474     need_to_check_persisted_supports_quic_ = false;
1475     if (http_server_properties_->WasLastLocalAddressWhenQuicWorked(
1476             local_address_.address())) {
1477       is_quic_known_to_work_on_current_network_ = true;
1478       // Clear the persisted IP address, in case the network no longer supports
1479       // QUIC so the next restart will require confirmation. It will be
1480       // re-persisted when the first job completes successfully.
1481       http_server_properties_->ClearLastLocalAddressWhenQuicWorked();
1482     }
1483   }
1484
1485   base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
1486       FROM_HERE,
1487       base::BindOnce(&QuicStreamFactory::DoCallback, weak_factory_.GetWeakPtr(),
1488                      std::move(callback), rv));
1489 }
1490
1491 void QuicStreamFactory::OnFinishConnectAndConfigureSocketError(
1492     CompletionOnceCallback callback,
1493     enum CreateSessionFailure error,
1494     int rv) {
1495   DCHECK(callback);
1496   HistogramCreateSessionFailure(error);
1497   base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
1498       FROM_HERE,
1499       base::BindOnce(&QuicStreamFactory::DoCallback, weak_factory_.GetWeakPtr(),
1500                      std::move(callback), rv));
1501 }
1502
1503 void QuicStreamFactory::DoCallback(CompletionOnceCallback callback, int rv) {
1504   std::move(callback).Run(rv);
1505 }
1506
1507 int QuicStreamFactory::ConfigureSocket(DatagramClientSocket* socket,
1508                                        IPEndPoint addr,
1509                                        handles::NetworkHandle network,
1510                                        const SocketTag& socket_tag) {
1511   socket->UseNonBlockingIO();
1512
1513   int rv;
1514   if (!params_.migrate_sessions_on_network_change_v2) {
1515     rv = socket->Connect(addr);
1516   } else if (network == handles::kInvalidNetworkHandle) {
1517     // If caller leaves network unspecified, use current default network.
1518     rv = socket->ConnectUsingDefaultNetwork(addr);
1519   } else {
1520     rv = socket->ConnectUsingNetwork(network, addr);
1521   }
1522   if (rv != OK) {
1523     HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET);
1524     return rv;
1525   }
1526
1527   socket->ApplySocketTag(socket_tag);
1528
1529   rv = socket->SetReceiveBufferSize(kQuicSocketReceiveBufferSize);
1530   if (rv != OK) {
1531     HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER);
1532     return rv;
1533   }
1534
1535   rv = socket->SetDoNotFragment();
1536   // SetDoNotFragment is not implemented on all platforms, so ignore errors.
1537   if (rv != OK && rv != ERR_NOT_IMPLEMENTED) {
1538     HistogramCreateSessionFailure(CREATION_ERROR_SETTING_DO_NOT_FRAGMENT);
1539     return rv;
1540   }
1541
1542   if (base::FeatureList::IsEnabled(net::features::kReceiveEcn)) {
1543     rv = socket->SetRecvEcn();
1544     if (rv != OK) {
1545       HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_ECN);
1546       return rv;
1547     }
1548   }
1549
1550   // Set a buffer large enough to contain the initial CWND's worth of packet
1551   // to work around the problem with CHLO packets being sent out with the
1552   // wrong encryption level, when the send buffer is full.
1553   rv = socket->SetSendBufferSize(quic::kMaxOutgoingPacketSize * 20);
1554   if (rv != OK) {
1555     HistogramCreateSessionFailure(CREATION_ERROR_SETTING_SEND_BUFFER);
1556     return rv;
1557   }
1558
1559   if (params_.ios_network_service_type > 0) {
1560     socket->SetIOSNetworkServiceType(params_.ios_network_service_type);
1561   }
1562
1563   socket->GetLocalAddress(&local_address_);
1564   if (need_to_check_persisted_supports_quic_) {
1565     need_to_check_persisted_supports_quic_ = false;
1566     if (http_server_properties_->WasLastLocalAddressWhenQuicWorked(
1567             local_address_.address())) {
1568       is_quic_known_to_work_on_current_network_ = true;
1569       // Clear the persisted IP address, in case the network no longer supports
1570       // QUIC so the next restart will require confirmation. It will be
1571       // re-persisted when the first job completes successfully.
1572       http_server_properties_->ClearLastLocalAddressWhenQuicWorked();
1573     }
1574   }
1575
1576   return OK;
1577 }
1578
1579 handles::NetworkHandle QuicStreamFactory::FindAlternateNetwork(
1580     handles::NetworkHandle old_network) {
1581   // Find a new network that sessions bound to |old_network| can be migrated to.
1582   NetworkChangeNotifier::NetworkList network_list;
1583   NetworkChangeNotifier::GetConnectedNetworks(&network_list);
1584   for (handles::NetworkHandle new_network : network_list) {
1585     if (new_network != old_network)
1586       return new_network;
1587   }
1588   return handles::kInvalidNetworkHandle;
1589 }
1590
1591 std::unique_ptr<DatagramClientSocket> QuicStreamFactory::CreateSocket(
1592     NetLog* net_log,
1593     const NetLogSource& source) {
1594   auto socket = client_socket_factory_->CreateDatagramClientSocket(
1595       DatagramSocket::DEFAULT_BIND, net_log, source);
1596   if (params_.enable_socket_recv_optimization)
1597     socket->EnableRecvOptimization();
1598   return socket;
1599 }
1600
1601 void QuicStreamFactory::OnIPAddressChanged() {
1602   net_log_.AddEvent(NetLogEventType::QUIC_STREAM_FACTORY_ON_IP_ADDRESS_CHANGED);
1603   CollectDataOnPlatformNotification(NETWORK_IP_ADDRESS_CHANGED,
1604                                     handles::kInvalidNetworkHandle);
1605   // Do nothing if connection migration is turned on.
1606   if (params_.migrate_sessions_on_network_change_v2)
1607     return;
1608
1609   connectivity_monitor_.OnIPAddressChanged();
1610
1611   set_is_quic_known_to_work_on_current_network(false);
1612   if (params_.close_sessions_on_ip_change) {
1613     CloseAllSessions(ERR_NETWORK_CHANGED, quic::QUIC_IP_ADDRESS_CHANGED);
1614   } else {
1615     DCHECK(params_.goaway_sessions_on_ip_change);
1616     MarkAllActiveSessionsGoingAway(kIPAddressChanged);
1617   }
1618 }
1619
1620 void QuicStreamFactory::OnNetworkConnected(handles::NetworkHandle network) {
1621   CollectDataOnPlatformNotification(NETWORK_CONNECTED, network);
1622   if (params_.migrate_sessions_on_network_change_v2) {
1623     net_log_.AddEventWithStringParams(
1624         NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, "signal",
1625         "OnNetworkConnected");
1626   }
1627   // Broadcast network connected to all sessions.
1628   // If migration is not turned on, session will not migrate but collect data.
1629   auto it = all_sessions_.begin();
1630   // Sessions may be deleted while iterating through the map.
1631   while (it != all_sessions_.end()) {
1632     QuicChromiumClientSession* session = it->first;
1633     ++it;
1634     session->OnNetworkConnected(network);
1635   }
1636 }
1637
1638 void QuicStreamFactory::OnNetworkDisconnected(handles::NetworkHandle network) {
1639   CollectDataOnPlatformNotification(NETWORK_DISCONNECTED, network);
1640   if (params_.migrate_sessions_on_network_change_v2) {
1641     net_log_.AddEventWithStringParams(
1642         NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, "signal",
1643         "OnNetworkDisconnected");
1644   }
1645   // Broadcast network disconnected to all sessions.
1646   // If migration is not turned on, session will not migrate but collect data.
1647   auto it = all_sessions_.begin();
1648   // Sessions may be deleted while iterating through the map.
1649   while (it != all_sessions_.end()) {
1650     QuicChromiumClientSession* session = it->first;
1651     ++it;
1652     session->OnNetworkDisconnectedV2(/*disconnected_network*/ network);
1653   }
1654 }
1655
1656 // This method is expected to only be called when migrating from Cellular to
1657 // WiFi on Android, and should always be preceded by OnNetworkMadeDefault().
1658 void QuicStreamFactory::OnNetworkSoonToDisconnect(
1659     handles::NetworkHandle network) {
1660   CollectDataOnPlatformNotification(NETWORK_SOON_TO_DISCONNECT, network);
1661 }
1662
1663 void QuicStreamFactory::OnNetworkMadeDefault(handles::NetworkHandle network) {
1664   CollectDataOnPlatformNotification(NETWORK_MADE_DEFAULT, network);
1665   connectivity_monitor_.OnDefaultNetworkUpdated(network);
1666
1667   // Clear alternative services that were marked as broken until default network
1668   // changes.
1669   if (params_.retry_on_alternate_network_before_handshake &&
1670       default_network_ != handles::kInvalidNetworkHandle &&
1671       network != default_network_) {
1672     http_server_properties_->OnDefaultNetworkChanged();
1673   }
1674
1675   DCHECK_NE(handles::kInvalidNetworkHandle, network);
1676   default_network_ = network;
1677
1678   if (params_.migrate_sessions_on_network_change_v2) {
1679     net_log_.AddEventWithStringParams(
1680         NetLogEventType::QUIC_STREAM_FACTORY_PLATFORM_NOTIFICATION, "signal",
1681         "OnNetworkMadeDefault");
1682   }
1683
1684   auto it = all_sessions_.begin();
1685   // Sessions may be deleted while iterating through the map.
1686   while (it != all_sessions_.end()) {
1687     QuicChromiumClientSession* session = it->first;
1688     ++it;
1689     session->OnNetworkMadeDefault(network);
1690   }
1691   if (params_.migrate_sessions_on_network_change_v2)
1692     set_is_quic_known_to_work_on_current_network(false);
1693 }
1694
1695 void QuicStreamFactory::OnTrustStoreChanged() {
1696   // We should flush the sessions if we removed trust from a
1697   // cert, because a previously trusted server may have become
1698   // untrusted.
1699   //
1700   // We should not flush the sessions if we added trust to a cert.
1701   //
1702   // Since the OnTrustStoreChanged method doesn't tell us what
1703   // kind of change it is, we have to flush the socket
1704   // pools to be safe.
1705   MarkAllActiveSessionsGoingAway(kCertDBChanged);
1706 }
1707
1708 void QuicStreamFactory::OnCertVerifierChanged() {
1709   // Flush sessions if the CertCerifier configuration has changed.
1710   MarkAllActiveSessionsGoingAway(kCertVerifierChanged);
1711 }
1712
1713 void QuicStreamFactory::set_is_quic_known_to_work_on_current_network(
1714     bool is_quic_known_to_work_on_current_network) {
1715   is_quic_known_to_work_on_current_network_ =
1716       is_quic_known_to_work_on_current_network;
1717   if (!(local_address_ == IPEndPoint())) {
1718     if (is_quic_known_to_work_on_current_network_) {
1719       http_server_properties_->SetLastLocalAddressWhenQuicWorked(
1720           local_address_.address());
1721     } else {
1722       http_server_properties_->ClearLastLocalAddressWhenQuicWorked();
1723     }
1724   }
1725 }
1726
1727 base::TimeDelta QuicStreamFactory::GetTimeDelayForWaitingJob(
1728     const QuicSessionKey& session_key) {
1729   // If |is_quic_known_to_work_on_current_network_| is false, then one of the
1730   // following is true:
1731   // 1) This is startup and QuicStreamFactory::CreateSession() and
1732   // ConfigureSocket() have yet to be called, and it is not yet known
1733   // if the current network is the last one where QUIC worked.
1734   // 2) Startup has been completed, and QUIC has not been used
1735   // successfully since startup, or on this network before.
1736   if (!is_quic_known_to_work_on_current_network_) {
1737     // If |need_to_check_persisted_supports_quic_| is false, this is case 1)
1738     // above. If HasLastLocalAddressWhenQuicWorked() is also true, then there's
1739     // a chance the current network is the last one on which QUIC worked. So
1740     // only delay the request if there's no chance that is the case.
1741     if (!need_to_check_persisted_supports_quic_ ||
1742         !http_server_properties_->HasLastLocalAddressWhenQuicWorked()) {
1743       return base::TimeDelta();
1744     }
1745   }
1746
1747   // QUIC was recently broken. Do not delay the main job.
1748   if (WasQuicRecentlyBroken(session_key)) {
1749     return base::TimeDelta();
1750   }
1751
1752   int64_t srtt = 1.5 * GetServerNetworkStatsSmoothedRttInMicroseconds(
1753                            session_key.server_id(),
1754                            session_key.network_anonymization_key());
1755   // Picked 300ms based on mean time from
1756   // Net.QuicSession.HostResolution.HandshakeConfirmedTime histogram.
1757   const int kDefaultRTT = 300 * quic::kNumMicrosPerMilli;
1758   if (!srtt)
1759     srtt = kDefaultRTT;
1760   return base::Microseconds(srtt);
1761 }
1762
1763 const std::set<std::string>& QuicStreamFactory::GetDnsAliasesForSessionKey(
1764     const QuicSessionKey& key) const {
1765   auto it = dns_aliases_by_session_key_.find(key);
1766
1767   if (it == dns_aliases_by_session_key_.end()) {
1768     static const base::NoDestructor<std::set<std::string>> emptyvector_result;
1769     return *emptyvector_result;
1770   }
1771
1772   return it->second;
1773 }
1774
1775 bool QuicStreamFactory::HasMatchingIpSession(
1776     const QuicSessionAliasKey& key,
1777     const std::vector<IPEndPoint>& ip_endpoints,
1778     const std::set<std::string>& aliases,
1779     bool use_dns_aliases) {
1780   const quic::QuicServerId& server_id(key.server_id());
1781   DCHECK(!HasActiveSession(key.session_key()));
1782   for (const auto& address : ip_endpoints) {
1783     if (!base::Contains(ip_aliases_, address))
1784       continue;
1785
1786     const SessionSet& sessions = ip_aliases_[address];
1787     for (QuicChromiumClientSession* session : sessions) {
1788       if (!session->CanPool(server_id.host(), key.session_key()))
1789         continue;
1790       active_sessions_[key.session_key()] = session;
1791
1792       std::set<std::string> dns_aliases;
1793       if (use_dns_aliases) {
1794         dns_aliases = aliases;
1795       }
1796
1797       MapSessionToAliasKey(session, key, std::move(dns_aliases));
1798
1799       return true;
1800     }
1801   }
1802   return false;
1803 }
1804
1805 void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
1806   auto iter = active_jobs_.find(job->key().session_key());
1807   DCHECK(iter != active_jobs_.end());
1808   if (rv == OK) {
1809     if (!is_quic_known_to_work_on_current_network_) {
1810       set_is_quic_known_to_work_on_current_network(true);
1811     }
1812
1813     auto session_it = active_sessions_.find(job->key().session_key());
1814     CHECK(session_it != active_sessions_.end());
1815     QuicChromiumClientSession* session = session_it->second;
1816     for (auto* request : iter->second->stream_requests()) {
1817       // Do not notify |request| yet.
1818       request->SetSession(session->CreateHandle(job->key().destination()));
1819     }
1820   }
1821
1822   for (auto* request : iter->second->stream_requests()) {
1823     // Even though we're invoking callbacks here, we don't need to worry
1824     // about |this| being deleted, because the factory is owned by the
1825     // profile which can not be deleted via callbacks.
1826     if (rv < 0) {
1827       job->PopulateNetErrorDetails(request->net_error_details());
1828     }
1829     request->OnRequestComplete(rv);
1830   }
1831   active_jobs_.erase(iter);
1832 }
1833
1834 bool QuicStreamFactory::HasActiveSession(
1835     const QuicSessionKey& session_key) const {
1836   return base::Contains(active_sessions_, session_key);
1837 }
1838
1839 bool QuicStreamFactory::HasActiveJob(const QuicSessionKey& session_key) const {
1840   return base::Contains(active_jobs_, session_key);
1841 }
1842
1843 int QuicStreamFactory::CreateSessionSync(
1844     const QuicSessionAliasKey& key,
1845     quic::ParsedQuicVersion quic_version,
1846     int cert_verify_flags,
1847     bool require_confirmation,
1848     const HostResolverEndpointResult& endpoint_result,
1849     base::TimeTicks dns_resolution_start_time,
1850     base::TimeTicks dns_resolution_end_time,
1851     const NetLogWithSource& net_log,
1852     QuicChromiumClientSession** session,
1853     handles::NetworkHandle* network) {
1854   TRACE_EVENT0(NetTracingCategory(), "QuicStreamFactory::CreateSession");
1855   // TODO(https://crbug.com/1416409): This logic only knows how to try one IP
1856   // endpoint.
1857   IPEndPoint addr = endpoint_result.ip_endpoints.front();
1858   std::unique_ptr<DatagramClientSocket> socket(
1859       CreateSocket(net_log.net_log(), net_log.source()));
1860
1861   // If migrate_sessions_on_network_change_v2 is on, passing in
1862   // handles::kInvalidNetworkHandle will bind the socket to the default network.
1863   int rv = ConfigureSocket(socket.get(), addr, *network,
1864                            key.session_key().socket_tag());
1865   if (rv != OK) {
1866     return rv;
1867   }
1868   bool closed_during_initialize = CreateSessionHelper(
1869       key, quic_version, cert_verify_flags, require_confirmation,
1870       endpoint_result, dns_resolution_start_time, dns_resolution_end_time,
1871       net_log, session, network, std::move(socket));
1872   if (closed_during_initialize) {
1873     DLOG(DFATAL) << "Session closed during initialize";
1874     *session = nullptr;
1875
1876     return ERR_CONNECTION_CLOSED;
1877   }
1878
1879   return OK;
1880 }
1881
1882 int QuicStreamFactory::CreateSessionAsync(
1883     CompletionOnceCallback callback,
1884     const QuicSessionAliasKey& key,
1885     quic::ParsedQuicVersion quic_version,
1886     int cert_verify_flags,
1887     bool require_confirmation,
1888     const HostResolverEndpointResult& endpoint_result,
1889     base::TimeTicks dns_resolution_start_time,
1890     base::TimeTicks dns_resolution_end_time,
1891     const NetLogWithSource& net_log,
1892     QuicChromiumClientSession** session,
1893     handles::NetworkHandle* network) {
1894   TRACE_EVENT0(NetTracingCategory(), "QuicStreamFactory::CreateSession");
1895   // TODO(https://crbug.com/1416409): This logic only knows how to try one IP
1896   // endpoint.
1897   IPEndPoint addr = endpoint_result.ip_endpoints.front();
1898   std::unique_ptr<DatagramClientSocket> socket(
1899       CreateSocket(net_log.net_log(), net_log.source()));
1900   DatagramClientSocket* socket_ptr = socket.get();
1901   CompletionOnceCallback connect_and_configure_callback = base::BindOnce(
1902       &QuicStreamFactory::FinishCreateSession, weak_factory_.GetWeakPtr(),
1903       std::move(callback), key, quic_version, cert_verify_flags,
1904       require_confirmation, endpoint_result, dns_resolution_start_time,
1905       dns_resolution_end_time, net_log, session, network, std::move(socket));
1906
1907   // If migrate_sessions_on_network_change_v2 is on, passing in
1908   // handles::kInvalidNetworkHandle will bind the socket to the default network.
1909   return ConnectAndConfigureSocket(std::move(connect_and_configure_callback),
1910                                    socket_ptr, addr, *network,
1911                                    key.session_key().socket_tag());
1912 }
1913
1914 void QuicStreamFactory::FinishCreateSession(
1915     CompletionOnceCallback callback,
1916     const QuicSessionAliasKey& key,
1917     quic::ParsedQuicVersion quic_version,
1918     int cert_verify_flags,
1919     bool require_confirmation,
1920     const HostResolverEndpointResult& endpoint_result,
1921     base::TimeTicks dns_resolution_start_time,
1922     base::TimeTicks dns_resolution_end_time,
1923     const NetLogWithSource& net_log,
1924     QuicChromiumClientSession** session,
1925     handles::NetworkHandle* network,
1926     std::unique_ptr<DatagramClientSocket> socket,
1927     int rv) {
1928   if (rv != OK) {
1929     std::move(callback).Run(rv);
1930     return;
1931   }
1932   bool closed_during_initialize = CreateSessionHelper(
1933       key, quic_version, cert_verify_flags, require_confirmation,
1934       endpoint_result, dns_resolution_start_time, dns_resolution_end_time,
1935       net_log, session, network, std::move(socket));
1936   if (closed_during_initialize) {
1937     DLOG(DFATAL) << "Session closed during initialize";
1938     *session = nullptr;
1939
1940     std::move(callback).Run(ERR_CONNECTION_CLOSED);
1941     return;
1942   }
1943
1944   std::move(callback).Run(OK);
1945 }
1946
1947 bool QuicStreamFactory::CreateSessionHelper(
1948     const QuicSessionAliasKey& key,
1949     quic::ParsedQuicVersion quic_version,
1950     int cert_verify_flags,
1951     bool require_confirmation,
1952     const HostResolverEndpointResult& endpoint_result,
1953     base::TimeTicks dns_resolution_start_time,
1954     base::TimeTicks dns_resolution_end_time,
1955     const NetLogWithSource& net_log,
1956     QuicChromiumClientSession** session,
1957     handles::NetworkHandle* network,
1958     std::unique_ptr<DatagramClientSocket> socket) {
1959   // TODO(https://crbug.com/1416409): This logic only knows how to try one IP
1960   // endpoint.
1961   IPEndPoint addr = endpoint_result.ip_endpoints.front();
1962   const quic::QuicServerId& server_id = key.server_id();
1963
1964   if (params_.migrate_sessions_on_network_change_v2 &&
1965       *network == handles::kInvalidNetworkHandle) {
1966     *network = socket->GetBoundNetwork();
1967     if (default_network_ == handles::kInvalidNetworkHandle) {
1968       // QuicStreamFactory may miss the default network signal before its
1969       // creation, update |default_network_| when the first socket is bound
1970       // to the default network.
1971       default_network_ = *network;
1972       connectivity_monitor_.SetInitialDefaultNetwork(default_network_);
1973     } else {
1974       UMA_HISTOGRAM_BOOLEAN("Net.QuicStreamFactory.DefaultNetworkMatch",
1975                             default_network_ == *network);
1976     }
1977   }
1978
1979   if (!helper_.get()) {
1980     helper_ = std::make_unique<QuicChromiumConnectionHelper>(clock_,
1981                                                              random_generator_);
1982   }
1983
1984   if (!alarm_factory_.get()) {
1985     alarm_factory_ = std::make_unique<QuicChromiumAlarmFactory>(
1986         base::SingleThreadTaskRunner::GetCurrentDefault().get(), clock_);
1987   }
1988
1989   quic::QuicConnectionId connection_id =
1990       quic::QuicUtils::CreateRandomConnectionId(random_generator_);
1991   std::unique_ptr<QuicServerInfo> server_info;
1992   if (params_.max_server_configs_stored_in_properties > 0) {
1993     server_info = std::make_unique<PropertiesBasedQuicServerInfo>(
1994         server_id, key.session_key().network_anonymization_key(),
1995         http_server_properties_);
1996   }
1997   std::unique_ptr<CryptoClientConfigHandle> crypto_config_handle =
1998       CreateCryptoConfigHandle(key.session_key().network_anonymization_key());
1999   InitializeCachedStateInCryptoConfig(*crypto_config_handle, server_id,
2000                                       server_info);
2001
2002   QuicChromiumPacketWriter* writer =
2003       new QuicChromiumPacketWriter(socket.get(), task_runner_);
2004   quic::QuicConnection* connection = new quic::QuicConnection(
2005       connection_id, quic::QuicSocketAddress(), ToQuicSocketAddress(addr),
2006       helper_.get(), alarm_factory_.get(), writer, true /* owns_writer */,
2007       quic::Perspective::IS_CLIENT, {quic_version}, connection_id_generator_);
2008   connection->set_keep_alive_ping_timeout(ping_timeout_);
2009   connection->SetMaxPacketLength(params_.max_packet_length);
2010
2011   quic::QuicConfig config = config_;
2012   ConfigureInitialRttEstimate(
2013       server_id, key.session_key().network_anonymization_key(), &config);
2014
2015   // Use the factory to create a new socket performance watcher, and pass the
2016   // ownership to QuicChromiumClientSession.
2017   std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher;
2018   if (socket_performance_watcher_factory_) {
2019     socket_performance_watcher =
2020         socket_performance_watcher_factory_->CreateSocketPerformanceWatcher(
2021             SocketPerformanceWatcherFactory::PROTOCOL_QUIC, addr.address());
2022   }
2023
2024   // Wait for handshake confirmation before allowing streams to be created if
2025   // either this session or the factory require confirmation.
2026   if (!is_quic_known_to_work_on_current_network_) {
2027     require_confirmation = true;
2028   }
2029
2030   *session = new QuicChromiumClientSession(
2031       connection, std::move(socket), this, quic_crypto_client_stream_factory_,
2032       clock_, transport_security_state_, ssl_config_service_,
2033       std::move(server_info), key.session_key(), require_confirmation,
2034       params_.migrate_sessions_early_v2,
2035       params_.migrate_sessions_on_network_change_v2, default_network_,
2036       retransmittable_on_wire_timeout_, params_.migrate_idle_sessions,
2037       params_.allow_port_migration, params_.idle_session_migration_period,
2038       params_.max_time_on_non_default_network,
2039       params_.max_migrations_to_non_default_network_on_write_error,
2040       params_.max_migrations_to_non_default_network_on_path_degrading,
2041       yield_after_packets_, yield_after_duration_, cert_verify_flags, config,
2042       std::move(crypto_config_handle), dns_resolution_start_time,
2043       dns_resolution_end_time, tick_clock_, task_runner_,
2044       std::move(socket_performance_watcher), endpoint_result,
2045       net_log.net_log());
2046
2047   all_sessions_[*session] = key;  // owning pointer
2048   writer->set_delegate(*session);
2049   (*session)->AddConnectivityObserver(&connectivity_monitor_);
2050
2051   (*session)->Initialize();
2052   bool closed_during_initialize = !base::Contains(all_sessions_, *session) ||
2053                                   !(*session)->connection()->connected();
2054   UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession",
2055                         closed_during_initialize);
2056   return closed_during_initialize;
2057 }
2058
2059 void QuicStreamFactory::ActivateSession(const QuicSessionAliasKey& key,
2060                                         QuicChromiumClientSession* session,
2061                                         std::set<std::string> dns_aliases) {
2062   DCHECK(!HasActiveSession(key.session_key()));
2063   UMA_HISTOGRAM_COUNTS_1M("Net.QuicActiveSessions", active_sessions_.size());
2064   active_sessions_[key.session_key()] = session;
2065   MapSessionToAliasKey(session, key, std::move(dns_aliases));
2066   const IPEndPoint peer_address =
2067       ToIPEndPoint(session->connection()->peer_address());
2068   DCHECK(!base::Contains(ip_aliases_[peer_address], session));
2069   ip_aliases_[peer_address].insert(session);
2070   DCHECK(!base::Contains(session_peer_ip_, session));
2071   session_peer_ip_[session] = peer_address;
2072 }
2073
2074 void QuicStreamFactory::MarkAllActiveSessionsGoingAway(
2075     AllActiveSessionsGoingAwayReason reason) {
2076   net_log_.AddEvent(
2077       NetLogEventType::QUIC_STREAM_FACTORY_MARK_ALL_ACTIVE_SESSIONS_GOING_AWAY);
2078   while (!active_sessions_.empty()) {
2079     QuicChromiumClientSession* session = active_sessions_.begin()->second;
2080     // If IP address change is detected, disable session's connectivity
2081     // monitoring by remove the Delegate.
2082     if (reason == kIPAddressChanged)
2083       connectivity_monitor_.OnSessionGoingAwayOnIPAddressChange(session);
2084     OnSessionGoingAway(session);
2085   }
2086 }
2087
2088 void QuicStreamFactory::ConfigureInitialRttEstimate(
2089     const quic::QuicServerId& server_id,
2090     const NetworkAnonymizationKey& network_anonymization_key,
2091     quic::QuicConfig* config) {
2092   const base::TimeDelta* srtt =
2093       GetServerNetworkStatsSmoothedRtt(server_id, network_anonymization_key);
2094   // Sometimes *srtt is negative. See https://crbug.com/1225616.
2095   // TODO(ricea): When the root cause of the negative value is fixed, change the
2096   // non-negative assertion to a DCHECK.
2097   if (srtt && srtt->is_positive()) {
2098     SetInitialRttEstimate(*srtt, INITIAL_RTT_CACHED, config);
2099     return;
2100   }
2101
2102   NetworkChangeNotifier::ConnectionType type =
2103       network_connection_.connection_type();
2104   if (type == NetworkChangeNotifier::CONNECTION_2G) {
2105     SetInitialRttEstimate(base::Milliseconds(1200), INITIAL_RTT_CACHED, config);
2106     return;
2107   }
2108
2109   if (type == NetworkChangeNotifier::CONNECTION_3G) {
2110     SetInitialRttEstimate(base::Milliseconds(400), INITIAL_RTT_CACHED, config);
2111     return;
2112   }
2113
2114   if (params_.initial_rtt_for_handshake.is_positive()) {
2115     SetInitialRttEstimate(
2116         base::Microseconds(params_.initial_rtt_for_handshake.InMicroseconds()),
2117         INITIAL_RTT_DEFAULT, config);
2118     return;
2119   }
2120
2121   SetInitialRttEstimate(base::TimeDelta(), INITIAL_RTT_DEFAULT, config);
2122 }
2123
2124 int64_t QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds(
2125     const quic::QuicServerId& server_id,
2126     const NetworkAnonymizationKey& network_anonymization_key) const {
2127   const base::TimeDelta* srtt =
2128       GetServerNetworkStatsSmoothedRtt(server_id, network_anonymization_key);
2129   return srtt == nullptr ? 0 : srtt->InMicroseconds();
2130 }
2131
2132 const base::TimeDelta* QuicStreamFactory::GetServerNetworkStatsSmoothedRtt(
2133     const quic::QuicServerId& server_id,
2134     const NetworkAnonymizationKey& network_anonymization_key) const {
2135   url::SchemeHostPort server("https", server_id.host(), server_id.port());
2136   const ServerNetworkStats* stats =
2137       http_server_properties_->GetServerNetworkStats(server,
2138                                                      network_anonymization_key);
2139   if (stats == nullptr)
2140     return nullptr;
2141   return &(stats->srtt);
2142 }
2143
2144 bool QuicStreamFactory::WasQuicRecentlyBroken(
2145     const QuicSessionKey& session_key) const {
2146   const AlternativeService alternative_service(
2147       kProtoQUIC, HostPortPair(session_key.server_id().host(),
2148                                session_key.server_id().port()));
2149   return http_server_properties_->WasAlternativeServiceRecentlyBroken(
2150       alternative_service, session_key.network_anonymization_key());
2151 }
2152
2153 void QuicStreamFactory::InitializeMigrationOptions() {
2154   // The following list of options cannot be set immediately until
2155   // prerequisites are met. Cache the initial setting in local variables and
2156   // reset them in |params_|.
2157   bool migrate_sessions_on_network_change =
2158       params_.migrate_sessions_on_network_change_v2;
2159   bool migrate_sessions_early = params_.migrate_sessions_early_v2;
2160   bool retry_on_alternate_network_before_handshake =
2161       params_.retry_on_alternate_network_before_handshake;
2162   bool migrate_idle_sessions = params_.migrate_idle_sessions;
2163   bool allow_port_migration = params_.allow_port_migration;
2164   params_.migrate_sessions_on_network_change_v2 = false;
2165   params_.migrate_sessions_early_v2 = false;
2166   params_.allow_port_migration = false;
2167   params_.retry_on_alternate_network_before_handshake = false;
2168   params_.migrate_idle_sessions = false;
2169
2170   // TODO(zhongyi): deprecate |goaway_sessions_on_ip_change| if the experiment
2171   // is no longer needed.
2172   // goaway_sessions_on_ip_change and close_sessions_on_ip_change should never
2173   // be simultaneously set to true.
2174   DCHECK(!(params_.close_sessions_on_ip_change &&
2175            params_.goaway_sessions_on_ip_change));
2176
2177   bool handle_ip_change = params_.close_sessions_on_ip_change ||
2178                           params_.goaway_sessions_on_ip_change;
2179   // If IP address changes are handled explicitly, connection migration should
2180   // not be set.
2181   DCHECK(!(handle_ip_change && migrate_sessions_on_network_change));
2182
2183   if (handle_ip_change)
2184     NetworkChangeNotifier::AddIPAddressObserver(this);
2185
2186   if (allow_port_migration) {
2187     params_.allow_port_migration = true;
2188     if (migrate_idle_sessions) {
2189       params_.migrate_idle_sessions = true;
2190     }
2191   }
2192
2193   if (!NetworkChangeNotifier::AreNetworkHandlesSupported())
2194     return;
2195
2196   NetworkChangeNotifier::AddNetworkObserver(this);
2197   // Perform checks on the connection migration options.
2198   if (!migrate_sessions_on_network_change) {
2199     DCHECK(!migrate_sessions_early);
2200     return;
2201   }
2202
2203   // Enable migration on platform notifications.
2204   params_.migrate_sessions_on_network_change_v2 = true;
2205
2206   if (!migrate_sessions_early) {
2207     DCHECK(!retry_on_alternate_network_before_handshake);
2208     return;
2209   }
2210
2211   // Enable migration on path degrading.
2212   params_.migrate_sessions_early_v2 = true;
2213   // Set retransmittable on wire timeout for migration on path degrading if no
2214   // value is specified.
2215   if (retransmittable_on_wire_timeout_.IsZero()) {
2216     retransmittable_on_wire_timeout_ = quic::QuicTime::Delta::FromMicroseconds(
2217         kDefaultRetransmittableOnWireTimeout.InMicroseconds());
2218   }
2219
2220   // Enable retry on alternate network before handshake.
2221   if (retry_on_alternate_network_before_handshake)
2222     params_.retry_on_alternate_network_before_handshake = true;
2223
2224   // Enable migration for idle sessions.
2225   if (migrate_idle_sessions)
2226     params_.migrate_idle_sessions = true;
2227 }
2228
2229 void QuicStreamFactory::InitializeCachedStateInCryptoConfig(
2230     const CryptoClientConfigHandle& crypto_config_handle,
2231     const quic::QuicServerId& server_id,
2232     const std::unique_ptr<QuicServerInfo>& server_info) {
2233   quic::QuicCryptoClientConfig::CachedState* cached =
2234       crypto_config_handle.GetConfig()->LookupOrCreate(server_id);
2235
2236   if (!cached->IsEmpty()) {
2237     return;
2238   }
2239
2240   if (!server_info || !server_info->Load()) {
2241     return;
2242   }
2243
2244   cached->Initialize(server_info->state().server_config,
2245                      server_info->state().source_address_token,
2246                      server_info->state().certs, server_info->state().cert_sct,
2247                      server_info->state().chlo_hash,
2248                      server_info->state().server_config_sig, clock_->WallNow(),
2249                      quic::QuicWallTime::Zero());
2250 }
2251
2252 void QuicStreamFactory::ProcessGoingAwaySession(
2253     QuicChromiumClientSession* session,
2254     const quic::QuicServerId& server_id,
2255     bool session_was_active) {
2256   if (!http_server_properties_)
2257     return;
2258
2259   const quic::QuicConnectionStats& stats = session->connection()->GetStats();
2260   const AlternativeService alternative_service(
2261       kProtoQUIC, HostPortPair(server_id.host(), server_id.port()));
2262
2263   url::SchemeHostPort server("https", server_id.host(), server_id.port());
2264   // Do nothing if QUIC is currently marked as broken.
2265   if (http_server_properties_->IsAlternativeServiceBroken(
2266           alternative_service,
2267           session->quic_session_key().network_anonymization_key())) {
2268     return;
2269   }
2270
2271   if (session->OneRttKeysAvailable()) {
2272     http_server_properties_->ConfirmAlternativeService(
2273         alternative_service,
2274         session->quic_session_key().network_anonymization_key());
2275     ServerNetworkStats network_stats;
2276     network_stats.srtt = base::Microseconds(stats.srtt_us);
2277     network_stats.bandwidth_estimate = stats.estimated_bandwidth;
2278     http_server_properties_->SetServerNetworkStats(
2279         server, session->quic_session_key().network_anonymization_key(),
2280         network_stats);
2281     return;
2282   }
2283
2284   http_server_properties_->ClearServerNetworkStats(
2285       server, session->quic_session_key().network_anonymization_key());
2286
2287   UMA_HISTOGRAM_COUNTS_1M("Net.QuicHandshakeNotConfirmedNumPacketsReceived",
2288                           stats.packets_received);
2289
2290   if (!session_was_active)
2291     return;
2292
2293   // TODO(rch):  In the special case where the session has received no packets
2294   // from the peer, we should consider blocking this differently so that we
2295   // still race TCP but we don't consider the session connected until the
2296   // handshake has been confirmed.
2297   HistogramBrokenAlternateProtocolLocation(
2298       BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_STREAM_FACTORY);
2299
2300   // Since the session was active, there's no longer an HttpStreamFactory::Job
2301   // running which can mark it broken, unless the TCP job also fails. So to
2302   // avoid not using QUIC when we otherwise could, we mark it as recently
2303   // broken, which means that 0-RTT will be disabled but we'll still race.
2304   http_server_properties_->MarkAlternativeServiceRecentlyBroken(
2305       alternative_service,
2306       session->quic_session_key().network_anonymization_key());
2307 }
2308
2309 void QuicStreamFactory::MapSessionToAliasKey(
2310     QuicChromiumClientSession* session,
2311     const QuicSessionAliasKey& key,
2312     std::set<std::string> dns_aliases) {
2313   session_aliases_[session].insert(key);
2314   dns_aliases_by_session_key_[key.session_key()] = std::move(dns_aliases);
2315 }
2316
2317 void QuicStreamFactory::UnmapSessionFromSessionAliases(
2318     QuicChromiumClientSession* session) {
2319   for (const auto& key : session_aliases_[session])
2320     dns_aliases_by_session_key_.erase(key.session_key());
2321   session_aliases_.erase(session);
2322 }
2323
2324 std::unique_ptr<QuicStreamFactory::CryptoClientConfigHandle>
2325 QuicStreamFactory::CreateCryptoConfigHandle(
2326     const NetworkAnonymizationKey& network_anonymization_key) {
2327   NetworkAnonymizationKey actual_network_anonymization_key =
2328       use_network_anonymization_key_for_crypto_configs_
2329           ? network_anonymization_key
2330           : NetworkAnonymizationKey();
2331
2332   // If there's a matching entry in |active_crypto_config_map_|, create a
2333   // CryptoClientConfigHandle for it.
2334   auto map_iterator =
2335       active_crypto_config_map_.find(actual_network_anonymization_key);
2336   if (map_iterator != active_crypto_config_map_.end()) {
2337     DCHECK_GT(map_iterator->second->num_refs(), 0);
2338
2339     // If there's an active matching crypto config, there shouldn't also be an
2340     // inactive matching crypto config.
2341     DCHECK(recent_crypto_config_map_.Peek(actual_network_anonymization_key) ==
2342            recent_crypto_config_map_.end());
2343
2344     return std::make_unique<CryptoClientConfigHandle>(map_iterator);
2345   }
2346
2347   // If there's a matching entry in |recent_crypto_config_map_|, move it to
2348   // |active_crypto_config_map_| and create a CryptoClientConfigHandle for it.
2349   auto mru_iterator =
2350       recent_crypto_config_map_.Peek(actual_network_anonymization_key);
2351   if (mru_iterator != recent_crypto_config_map_.end()) {
2352     DCHECK_EQ(mru_iterator->second->num_refs(), 0);
2353
2354     map_iterator = active_crypto_config_map_
2355                        .emplace(std::make_pair(actual_network_anonymization_key,
2356                                                std::move(mru_iterator->second)))
2357                        .first;
2358     recent_crypto_config_map_.Erase(mru_iterator);
2359     return std::make_unique<CryptoClientConfigHandle>(map_iterator);
2360   }
2361
2362   // Otherwise, create a new QuicCryptoClientConfigOwner and add it to
2363   // |active_crypto_config_map_|.
2364   std::unique_ptr<QuicCryptoClientConfigOwner> crypto_config_owner =
2365       std::make_unique<QuicCryptoClientConfigOwner>(
2366           std::make_unique<ProofVerifierChromium>(
2367               cert_verifier_, ct_policy_enforcer_, transport_security_state_,
2368               sct_auditing_delegate_,
2369               HostsFromOrigins(params_.origins_to_force_quic_on),
2370               actual_network_anonymization_key),
2371           std::make_unique<quic::QuicClientSessionCache>(), this);
2372
2373   quic::QuicCryptoClientConfig* crypto_config = crypto_config_owner->config();
2374   crypto_config->AddCanonicalSuffix(".c.youtube.com");
2375   crypto_config->AddCanonicalSuffix(".ggpht.com");
2376   crypto_config->AddCanonicalSuffix(".googlevideo.com");
2377   crypto_config->AddCanonicalSuffix(".googleusercontent.com");
2378   crypto_config->AddCanonicalSuffix(".gvt1.com");
2379
2380   ConfigureQuicCryptoClientConfig(*crypto_config);
2381
2382   if (!prefer_aes_gcm_recorded_) {
2383     bool prefer_aes_gcm =
2384         !crypto_config->aead.empty() && (crypto_config->aead[0] == quic::kAESG);
2385     UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.PreferAesGcm", prefer_aes_gcm);
2386     prefer_aes_gcm_recorded_ = true;
2387   }
2388
2389   map_iterator = active_crypto_config_map_
2390                      .emplace(std::make_pair(actual_network_anonymization_key,
2391                                              std::move(crypto_config_owner)))
2392                      .first;
2393   return std::make_unique<CryptoClientConfigHandle>(map_iterator);
2394 }
2395
2396 void QuicStreamFactory::OnAllCryptoClientRefReleased(
2397     QuicCryptoClientConfigMap::iterator& map_iterator) {
2398   DCHECK_EQ(0, map_iterator->second->num_refs());
2399   recent_crypto_config_map_.Put(map_iterator->first,
2400                                 std::move(map_iterator->second));
2401   active_crypto_config_map_.erase(map_iterator);
2402 }
2403
2404 void QuicStreamFactory::CollectDataOnPlatformNotification(
2405     enum QuicPlatformNotification notification,
2406     handles::NetworkHandle affected_network) const {
2407   UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.PlatformNotification",
2408                             notification, NETWORK_NOTIFICATION_MAX);
2409   connectivity_monitor_.RecordConnectivityStatsToHistograms(
2410       QuicPlatformNotificationToString(notification), affected_network);
2411 }
2412
2413 std::unique_ptr<QuicCryptoClientConfigHandle>
2414 QuicStreamFactory::GetCryptoConfigForTesting(
2415     const NetworkAnonymizationKey& network_anonymization_key) {
2416   return CreateCryptoConfigHandle(network_anonymization_key);
2417 }
2418
2419 bool QuicStreamFactory::CryptoConfigCacheIsEmptyForTesting(
2420     const quic::QuicServerId& server_id,
2421     const NetworkAnonymizationKey& network_anonymization_key) {
2422   quic::QuicCryptoClientConfig::CachedState* cached = nullptr;
2423   NetworkAnonymizationKey actual_network_anonymization_key =
2424       use_network_anonymization_key_for_crypto_configs_
2425           ? network_anonymization_key
2426           : NetworkAnonymizationKey();
2427   auto map_iterator =
2428       active_crypto_config_map_.find(actual_network_anonymization_key);
2429   if (map_iterator != active_crypto_config_map_.end()) {
2430     cached = map_iterator->second->config()->LookupOrCreate(server_id);
2431   } else {
2432     auto mru_iterator =
2433         recent_crypto_config_map_.Peek(actual_network_anonymization_key);
2434     if (mru_iterator != recent_crypto_config_map_.end()) {
2435       cached = mru_iterator->second->config()->LookupOrCreate(server_id);
2436     }
2437   }
2438   return !cached || cached->IsEmpty();
2439 }
2440
2441 }  // namespace net