1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_HTTP_HTTP_STREAM_POOL_ATTEMPT_MANAGER_H_
#define NET_HTTP_HTTP_STREAM_POOL_ATTEMPT_MANAGER_H_
#include <memory>
#include <optional>
#include <set>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/types/expected.h"
#include "net/base/completion_once_callback.h"
#include "net/base/ip_endpoint.h"
#include "net/base/load_states.h"
#include "net/base/load_timing_info.h"
#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
#include "net/base/priority_queue.h"
#include "net/base/request_priority.h"
#include "net/base/tracing.h"
#include "net/dns/host_resolver.h"
#include "net/dns/public/resolve_error_info.h"
#include "net/http/http_stream_pool.h"
#include "net/http/http_stream_pool_ip_endpoint_state_tracker.h"
#include "net/http/http_stream_pool_job.h"
#include "net/http/http_stream_request.h"
#include "net/log/net_log_with_source.h"
#include "net/quic/quic_session_pool.h"
#include "net/socket/connection_attempts.h"
#include "net/socket/next_proto.h"
#include "net/socket/stream_attempt.h"
#include "net/socket/stream_socket_close_reason.h"
#include "net/socket/stream_socket_handle.h"
#include "net/socket/tls_stream_attempt.h"
#include "net/spdy/multiplexed_session_creation_initiator.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
namespace net {
class HttpNetworkSession;
class NetLog;
class HttpStreamKey;
// Drives connection attempts for a single destination.
//
// Maintains multiple in-flight Jobs for a single destination keyed by
// HttpStreamKey. Peforms DNS resolution and manages connection attempts.
// Delegates QUIC connection attempts to QuicAttempt. Upon successful HttpStream
// creations or fatal error occurrence, notify jobs of success or failure.
//
// Created by an HttpStreamPool::Group when new connection attempts are needed
// and destroyed when all jobs, in-flight attempts, and the QuicAttempt are
// completed.
class HttpStreamPool::AttemptManager
: public HostResolver::ServiceEndpointRequest::Delegate,
public IPEndPointStateTracker::Delegate {
public:
// Represents the initial attempt state of this manager.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(InitialAttemptState)
enum class InitialAttemptState {
kOther = 0,
// CanUseQuic() && quic_version_.IsKnown() && !SupportsSpdy()
kCanUseQuicWithKnownVersion = 1,
// CanUseQuic() && quic_version_.IsKnown() && SupportsSpdy()
kCanUseQuicWithKnownVersionAndSupportsSpdy = 2,
// CanUseQuic() && !quic_version_.IsKnown() && !SupportsSpdy()
kCanUseQuicWithUnknownVersion = 3,
// CanUseQuic() && !quic_version_.IsKnown() && SupportsSpdy()
kCanUseQuicWithUnknownVersionAndSupportsSpdy = 4,
// !CanUseQuic() && quic_version_.IsKnown() && !SupportsSpdy()
kCannotUseQuicWithKnownVersion = 5,
// !CanUseQuic() && quic_version_.IsKnown() && SupportsSpdy()
kCannotUseQuicWithKnownVersionAndSupportsSpdy = 6,
// !CanUseQuic() && !quic_version_.IsKnown() && !SupportsSpdy()
kCannotUseQuicWithUnknownVersion = 7,
// !CanUseQuic() && !quic_version_.IsKnown() && SupportsSpdy()
kCannotUseQuicWithUnknownVersionAndSupportsSpdy = 8,
kMaxValue = kCannotUseQuicWithUnknownVersionAndSupportsSpdy,
};
// LINT.ThenChange(//tools/metrics/histograms/metadata/net/enums.xml:HttpStreamPoolInitialAttemptState)
// Time to delay connection attempts more than one when the destination is
// known to support HTTP/2, to avoid unnecessary socket connection
// establishments. See https://crbug.com/718576
static constexpr base::TimeDelta kSpdyThrottleDelay = base::Milliseconds(300);
// `group` must outlive `this`.
AttemptManager(Group* group, NetLog* net_log);
AttemptManager(const AttemptManager&) = delete;
AttemptManager& operator=(const AttemptManager&) = delete;
~AttemptManager() override;
const HttpStreamKey& stream_key() const;
const SpdySessionKey& spdy_session_key() const;
const QuicSessionAliasKey& quic_session_alias_key() const;
HttpNetworkSession* http_network_session() const;
SpdySessionPool* spdy_session_pool() const;
QuicSessionPool* quic_session_pool() const;
HttpStreamPool* pool();
const HttpStreamPool* pool() const;
Group* group() { return group_; }
HostResolver::ServiceEndpointRequest* service_endpoint_request() {
return service_endpoint_request_.get();
}
const perfetto::Track& track() const { return track_; }
std::optional<InitialAttemptState> initial_attempt_state() const {
return initial_attempt_state_;
}
bool is_shutting_down() const {
return availability_state_ != AvailabilityState::kAvailable;
}
int final_error_to_notify_jobs() const;
base::TimeTicks dns_resolution_start_time() const {
return dns_resolution_start_time_;
}
base::TimeTicks dns_resolution_end_time() const {
return dns_resolution_end_time_;
}
const NetLogWithSource& net_log();
// Starts `job` for a stream request. Will call one of Job::Delegate methods
// to notify results.
void RequestStream(Job* job);
// Creates idle streams or sessions for `num_streams` be opened.
// Note that `job` will be notified once `this` has enough streams/sessions
// for `num_streams` be opened. This means that when there are two preconnect
// requests with `num_streams = 1`, all jobs are notified when one
// stream/session is established (not two).
void Preconnect(Job* job);
// HostResolver::ServiceEndpointRequest::Delegate implementation:
void OnServiceEndpointsUpdated() override;
void OnServiceEndpointRequestFinished(int rv) override;
// IPEndPointStateTracker::Delegate implementation:
HostResolver::ServiceEndpointRequest* GetServiceEndpointRequest() override;
bool IsSvcbOptional() override;
bool HasEnoughTcpBasedAttemptsForSlowIPEndPoint(
const IPEndPoint& ip_endpoint) override;
bool IsEndpointUsableForTcpBasedAttempt(const ServiceEndpoint& endpoint,
bool svcb_optional) override;
// Tries to process a single pending request/preconnect.
void ProcessPendingJob();
// Returns the number of request jobs that haven't yet been notified success
// or failure.
size_t RequestJobCount() const { return request_jobs_.size(); }
// Returns the number of request jobs that have already been notified success
// or failure.
size_t NotifiedRequestJobCount() const { return notified_jobs_.size(); }
// Returns the number of in-flight TCP based attempts.
size_t TcpBasedAttemptCount() const { return tcp_based_attempts_.size(); }
// Cancels all in-flight TCP based attempts.
void CancelTcpBasedAttempts(StreamSocketCloseReason reason);
// Called when `job` is going to be destroyed.
void OnJobComplete(Job* job);
// Cancels all jobs.
void CancelJobs(int error);
// Cancels the QuicAttempt if it exists.
void CancelQuicAttempt(int error);
// Returns the number of pending requests/preconnects. The number is
// calculated by subtracting the number of in-flight attempts (excluding slow
// attempts) from the number of total jobs.
size_t PendingRequestJobCount() const;
size_t PendingPreconnectCount() const;
// Returns the current load state.
LoadState GetLoadState() const;
// Called when the priority of `job` is set.
void SetJobPriority(Job* job, RequestPriority priority);
// Returns the highest priority in `jobs_` when there is at least one job.
// Otherwise, returns IDLE assuming this manager is doing preconnects.
RequestPriority GetPriority() const;
// Returns true when `this` is blocked by the pool's stream limit.
bool IsStalledByPoolLimit();
base::expected<SSLConfig, TlsStreamAttempt::GetSSLConfigError> GetSSLConfig(
const IPEndPoint& endpoint);
void OnTcpBasedAttemptComplete(TcpBasedAttempt* raw_attempt, int rv);
void OnTcpBasedAttemptSlow(TcpBasedAttempt* raw_attempt);
bool CanUseExistingQuicSession();
// Runs the TCP based attempt delay timer if TCP based attempts are blocked
// and the timer is not running. TcpBasedAttemptDelayBehavior specifies when
// this method is called.
void MaybeRunTcpBasedAttemptDelayTimer();
// Called when the QuicAttempt owned by `this` is completed.
void OnQuicAttemptComplete(QuicAttemptOutcome result);
// Called when the QuicAttempt owned by `this` is slow.
void OnQuicAttemptSlow();
// Retrieves information on the current state of `this` as a base::Value.
base::Value::Dict GetInfoAsValue() const;
base::Value::Dict GetStatesAsNetLogParams() const;
MultiplexedSessionCreationInitiator
CalculateMultiplexedSessionCreationInitiator();
// TODO(crbug.com/383606724): Remove this once we move unittests from
// HttpStreamPoolAttemptManagerTest to
// HttpStreamPoolIPEndPointStateTrackerTest
const IPEndPointStateTracker& ip_endpoint_state_tracker() const {
return ip_endpoint_state_tracker_;
}
std::optional<int> GetQuicAttemptResultForTesting() {
return quic_attempt_result_;
}
base::WeakPtr<AttemptManager> GetWeakPtrForTesting() {
return weak_ptr_factory_.GetWeakPtr();
}
QuicAttempt* quic_attempt_for_testing() const { return quic_attempt_.get(); }
void SetOnCompleteCallbackForTesting(base::OnceClosure callback);
private:
FRIEND_TEST_ALL_PREFIXES(HttpStreamPoolAttemptManagerTest,
GetIPEndPointToAttempt);
// Represents the availability of this instance. If not kAvailable, `this`
// can't handle new Jobs and this should not have in-flight attempts.
enum class AvailabilityState {
// Can handle new Jobs and make connection attempts.
kAvailable = 0,
// Is in preparation of a successful completion.
kDraining = 1,
// Is handling a fatal error.
kFailing = 2,
};
// Represents failure of connection attempts. Used to notify job of completion
// for failure cases.
enum class FailureKind {
kStreamFailed,
kCertifcateError,
kNeedsClientAuth,
};
// Represents reasons if future connection attempts could be blocked or not.
enum class CanAttemptResult {
kAttempt,
kNoPendingJob,
kBlockedTcpBasedAttempt,
kThrottledForSpdy,
kReachedGroupLimit,
kReachedPoolLimit,
};
// The state of TCP/TLS connection attempts.
enum class TcpBasedAttemptState {
kNotStarted,
kAttempting,
kSucceededAtLeastOnce,
kAllEndpointsFailed,
};
std::string_view InitialAttemptStateToString(InitialAttemptState state);
using JobQueue = PriorityQueue<raw_ptr<Job>>;
static std::string_view CanAttemptResultToString(CanAttemptResult result);
static std::string_view TcpBasedAttemptStateToString(
TcpBasedAttemptState state);
bool is_service_endpoint_request_finished() const {
return service_endpoint_request_finished_;
}
void SetInitialAttemptState();
InitialAttemptState CalculateInitialAttemptState();
bool UsingTls() const;
void StartInternal(Job* job);
void ResolveServiceEndpoint(RequestPriority initial_priority);
// Helper methods to reset ServiceEndpointRequest later.
// TODO(crbug.com/421299722, crbug.com/397597592): Remove these helper
// methods and reset ServiceEndpointRequest without PostTask(). We need to
// update the HostResolver's object management first. See comment #8 of
// crbug.com/397597592.
void ResetServiceEndpointRequestLater();
void ResetServiceEndpointRequest();
void RestrictAllowedProtocols(NextProtoSet allowed_alpns);
void MaybeChangeServiceEndpointRequestPriority();
// Called when service endpoint results have changed or finished.
void ProcessServiceEndpointChanges();
// Returns an active QUIC session when there is an active QUIC session that
// can be used for on-going jobs after service endpoint results have changed.
QuicChromiumClientSession* CanUseExistingQuicSessionAfterEndpointChanges();
// Returns an active SPDY session when there is an active SPDY session that
// can be used for on-going jobs after service endpoint results have changed.
base::WeakPtr<SpdySession> CanUseExistingSpdySessionAfterEndpointChanges();
// If `this` is ready to start cryptographic handshakes, notifies TCP based
// attempts that SSLConfigs are ready.
void MaybeNotifySSLConfigReady();
// Attempts QUIC sessions if QUIC can be used and `this` is ready to start
// cryptographic connection handshakes.
void MaybeAttemptQuic();
// Attempts connections if there are pending jobs and IPEndPoints that
// haven't failed. If `exclude_ip_endpoint` is given, exclude the IPEndPoint
// from attempts. If `max_attempts` is given, attempts connections up to
// `max_attempts`.
void MaybeAttemptTcpBased(
std::optional<IPEndPoint> exclude_ip_endpoint = std::nullopt,
std::optional<size_t> max_attempts = std::nullopt);
// Returns true if there are pending jobs and the pool and the group
// haven't reached stream limits. If the pool reached the stream limit, may
// close idle sockets in other groups. Also may cancel preconnects or trigger
// `spdy_throttle_timer_`.
bool IsTcpBasedAttemptReady();
// Actual implementation of IsConnectionAttemptReady(), without having side
// effects.
CanAttemptResult CanAttemptConnection() const;
// Returns true only when there are no jobs that ignore the pool and group
// limits.
bool ShouldRespectLimits() const;
// Returns true only when there are no jobs that disable IP based pooling.
bool IsIpBasedPoolingEnabled() const;
// Returns true only when there are no jobs that disable alternative services.
bool IsAlternativeServiceEnabled() const;
// Returns true when the destination is known to support HTTP/2. Note that
// this could return false while initializing HttpServerProperties.
bool SupportsSpdy() const;
// Returns true when connection attempts should be throttled because there is
// an in-flight TCP based attempt and the destination is known to support
// HTTP/2.
bool ShouldThrottleAttemptForSpdy() const;
// Calculates the maximum streams counts requested by preconnects.
size_t CalculateMaxPreconnectCount() const;
// Helper method to calculate pending jobs.
size_t PendingCountInternal(size_t pending_count) const;
// Returns a QUIC endpoint to make a connection attempt. See the comments in
// QuicSessionPool::SelectQuicVersion() for the criteria to select a QUIC
// endpoint.
std::optional<QuicEndpoint> GetQuicEndpointToAttempt();
// Called when this gets a fatal error. Notifies all jobs of the failure and
// cancels in-flight TCP based attempts and QuicAttempt's, if they exist.
void HandleFinalError(int error);
// Calculate the failure kind to notify jobs of failure. Used to call one of
// the job's methods.
FailureKind DetermineFailureKind();
// Notifies a failure to a single request job. Used by NotifyFailure().
void NotifyJobOfFailure();
// Notifies all preconnects of completion.
void NotifyPreconnectsComplete(int rv);
// Called after completion of a connection attempt to decrement stream
// counts in preconnect entries. Invokes the callback of an entry when the
// entry's stream counts is less than or equal to `active_stream_count`
// (i.e., `this` has enough streams).
void ProcessPreconnectsAfterAttemptComplete(int rv,
size_t active_stream_count);
// Notifies a job of preconnect completion.
void NotifyJobOfPreconnectComplete(raw_ptr<Job> job, int rv);
// Creates a text based stream and Notifies the highest priority job.
void CreateTextBasedStreamAndNotify(
std::unique_ptr<StreamSocket> stream_socket,
StreamSocketHandle::SocketReuseType reuse_type,
LoadTimingInfo::ConnectTiming connect_timing);
bool HasAvailableSpdySession() const;
void MaybeStartDraining();
void MaybeCreateSpdyStreamAndNotify(base::WeakPtr<SpdySession> spdy_session);
void MaybeCreateQuicStreamAndNotify(QuicChromiumClientSession* quic_session);
void NotifyStreamReady(std::unique_ptr<HttpStream> stream,
NextProto negotiated_protocol);
// Called when a SPDY session is ready to use. Cancels in-flight attempts.
// Closes idle streams. Completes request/preconnect jobs.
void HandleSpdySessionReady(base::WeakPtr<SpdySession> spdy_session,
StreamSocketCloseReason refresh_group_reason);
// Called when a QUIC session is ready to use. Cancels in-flight attempts.
// Closes idle streams. Completes request/preconnect jobs.
void HandleQuicSessionReady(QuicChromiumClientSession* quic_session,
StreamSocketCloseReason refresh_group_reason);
// Extracts an entry from `request_jobs_` of which priority is highest. The
// ownership of the entry is moved to `notified_jobs_`.
Job* ExtractFirstJobToNotify();
// Remove the pointeee of `job_pointer` from `request_jobs_`. May cancel
// in-flight TCP based attempts when there are no limit ignoring jobs after
// removing the job and in-flight TCP based attempts count is larger than the
// limit.
raw_ptr<Job> RemoveJobFromQueue(JobQueue::Pointer job_pointer);
// Transfers the ownership of `raw_attempt` to the caller.
std::unique_ptr<TcpBasedAttempt> ExtractTcpBasedAttempt(
TcpBasedAttempt* raw_attempt);
void HandleTcpBasedAttemptFailure(
std::unique_ptr<TcpBasedAttempt> tcp_based_attempt,
int rv);
void OnSpdyThrottleDelayPassed();
// Returns the delay for TCP based attempts in favor of QUIC.
base::TimeDelta GetTcpBasedAttemptDelay();
// Updates whether TCP based attempts should be blocked or not. May cancel
// `tcp_based_attempt_delay_timer_`.
void UpdateTcpBasedAttemptState();
// Cancels `tcp_based_attempt_delay_timer_`.
void CancelTcpBasedAttemptDelayTimer();
// Called when `tcp_based_attempt_delay_timer_` is fired.
void OnTcpBasedAttemptDelayPassed();
bool CanUseTcpBasedProtocols();
bool CanUseQuic();
bool IsEchEnabled() const;
// Mark QUIC brokenness if QUIC attempts failed but TCP/TLS attempts succeeded
// or not attempted.
void MaybeMarkQuicBroken();
// Returns true when this can complete.
bool CanComplete() const;
// Notifies `group_` that `this` has completed and can be destroyed.
void MaybeComplete();
// If `this` is ready to complete, posts a task to call MaybeComplete().
void MaybeCompleteLater();
const raw_ptr<Group> group_;
const NetLogWithSource net_log_;
// For trace events.
const perfetto::Track track_;
const base::TimeTicks created_time_;
// Keeps the initial attempt state. Set when `this` attempts a TCP based
// attempt for the first time.
std::optional<InitialAttemptState> initial_attempt_state_;
NextProtoSet allowed_alpns_ = NextProtoSet::All();
// Holds request jobs that are waiting for notifications.
JobQueue request_jobs_;
// Holds preconnect jobs that are waiting for notifications.
std::set<raw_ptr<Job>> preconnect_jobs_;
// Holds jobs that are already notified results. We need to keep them to avoid
// dangling pointers.
std::set<raw_ptr<Job>> notified_jobs_;
base::flat_set<raw_ptr<Job>> limit_ignoring_jobs_;
base::flat_set<raw_ptr<Job>> ip_based_pooling_disabling_jobs_;
base::flat_set<raw_ptr<Job>> alternative_service_disabling_jobs_;
std::unique_ptr<HostResolver::ServiceEndpointRequest>
service_endpoint_request_;
bool service_endpoint_request_finished_ = false;
base::TimeTicks dns_resolution_start_time_;
base::TimeTicks dns_resolution_end_time_;
AvailabilityState availability_state_ = AvailabilityState::kAvailable;
NetErrorDetails net_error_details_;
ResolveErrorInfo resolve_error_info_;
ConnectionAttempts connection_attempts_;
// TODO(crbug.com/406936736): Remove this once we identify the cause of the
// bug.
bool ip_matching_spdy_session_found_ = false;
// An error code to notify jobs when `this` cannot make any further progress.
// Set to an error from service endpoint resolution failure, the last stream
// attempt failure, network change events, or QUIC task failure.
std::optional<int> final_error_to_notify_jobs_;
// Set to the most recent TCP based attempt failure, if any.
std::optional<int> most_recent_tcp_error_;
// Set to a SSLInfo when an attempt has failed with a certificate error. Used
// to notify jobs.
std::optional<SSLInfo> cert_error_ssl_info_;
// Set to a SSLCertRequestInfo when an attempt has requested a client cert.
// Used to notify jobs.
scoped_refptr<SSLCertRequestInfo> client_auth_cert_info_;
// Base SSLConfig for TCP based attempts, Allowed bad certificates are set
// from the newest job.
std::optional<SSLConfig> base_ssl_config_;
std::set<std::unique_ptr<TcpBasedAttempt>, base::UniquePtrComparator>
tcp_based_attempts_;
// The number of in-flight TCP based attempts that are treated as slow.
size_t slow_tcp_based_attempt_count_ = 0;
base::OneShotTimer spdy_throttle_timer_;
bool spdy_throttle_delay_passed_ = false;
// Tracks the states of IPEndPoints.
IPEndPointStateTracker ip_endpoint_state_tracker_{this};
// The current state of TCP/TLS connection attempts.
TcpBasedAttemptState tcp_based_attempt_state_ =
TcpBasedAttemptState::kNotStarted;
// QUIC version that is known to be used for the destination, usually coming
// from Alt-Svc.
quic::ParsedQuicVersion quic_version_ =
quic::ParsedQuicVersion::Unsupported();
// Created when attempting a QUIC session.
std::unique_ptr<QuicAttempt> quic_attempt_;
// Set when `quic_attempt_` is completed.
std::optional<int> quic_attempt_result_;
// The delay for TCP based stream attempts in favor of QUIC.
base::TimeDelta tcp_based_attempt_delay_;
// Set to true when TCP based attempts should be blocked.
bool should_block_tcp_based_attempt_ = false;
base::OneShotTimer tcp_based_attempt_delay_timer_;
base::OnceClosure on_complete_callback_for_testing_;
base::WeakPtrFactory<AttemptManager> weak_ptr_factory_{this};
};
} // namespace net
#endif // NET_HTTP_HTTP_STREAM_POOL_ATTEMPT_MANAGER_H_
|