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