#include "net/socket/transport_client_socket_pool.h"
#include <string_view>
#include <utility>
#include "base/auto_reset.h"
#include "base/barrier_closure.h"
#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/containers/contains.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
#include "net/socket/connect_job_factory.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace net {
namespace {
bool g_connect_backup_jobs_enabled = …;
base::Value::Dict NetLogCreateConnectJobParams(
bool backup_job,
const ClientSocketPool::GroupId* group_id) { … }
}
const char TransportClientSocketPool::kCertDatabaseChanged[] = …;
const char TransportClientSocketPool::kCertVerifierChanged[] = …;
const char TransportClientSocketPool::kClosedConnectionReturnedToPool[] = …;
const char TransportClientSocketPool::kDataReceivedUnexpectedly[] = …;
const char TransportClientSocketPool::kIdleTimeLimitExpired[] = …;
const char TransportClientSocketPool::kNetworkChanged[] = …;
const char TransportClientSocketPool::kRemoteSideClosedConnection[] = …;
const char TransportClientSocketPool::kSocketGenerationOutOfDate[] = …;
const char TransportClientSocketPool::kSocketPoolDestroyed[] = …;
const char TransportClientSocketPool::kSslConfigChanged[] = …;
TransportClientSocketPool::Request::Request(
ClientSocketHandle* handle,
CompletionOnceCallback callback,
const ProxyAuthCallback& proxy_auth_callback,
RequestPriority priority,
const SocketTag& socket_tag,
RespectLimits respect_limits,
Flags flags,
scoped_refptr<SocketParams> socket_params,
const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
const NetLogWithSource& net_log)
: … { … }
TransportClientSocketPool::Request::~Request() = default;
void TransportClientSocketPool::Request::AssignJob(ConnectJob* job) { … }
ConnectJob* TransportClientSocketPool::Request::ReleaseJob() { … }
struct TransportClientSocketPool::IdleSocket { … };
TransportClientSocketPool::TransportClientSocketPool(
int max_sockets,
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
const ProxyChain& proxy_chain,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
bool cleanup_on_ip_address_change)
: … { … }
TransportClientSocketPool::~TransportClientSocketPool() { … }
std::unique_ptr<TransportClientSocketPool>
TransportClientSocketPool::CreateForTesting(
int max_sockets,
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
base::TimeDelta used_idle_socket_timeout,
const ProxyChain& proxy_chain,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
std::unique_ptr<ConnectJobFactory> connect_job_factory,
SSLClientContext* ssl_client_context,
bool connect_backup_jobs_enabled) { … }
TransportClientSocketPool::CallbackResultPair::CallbackResultPair()
: … { … }
TransportClientSocketPool::CallbackResultPair::CallbackResultPair(
CompletionOnceCallback callback_in,
int result_in)
: … { … }
TransportClientSocketPool::CallbackResultPair::CallbackResultPair(
TransportClientSocketPool::CallbackResultPair&& other) = default;
TransportClientSocketPool::CallbackResultPair&
TransportClientSocketPool::CallbackResultPair::operator=(
TransportClientSocketPool::CallbackResultPair&& other) = default;
TransportClientSocketPool::CallbackResultPair::~CallbackResultPair() = default;
bool TransportClientSocketPool::IsStalled() const { … }
void TransportClientSocketPool::AddHigherLayeredPool(
HigherLayeredPool* higher_pool) { … }
void TransportClientSocketPool::RemoveHigherLayeredPool(
HigherLayeredPool* higher_pool) { … }
int TransportClientSocketPool::RequestSocket(
const GroupId& group_id,
scoped_refptr<SocketParams> params,
const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
RequestPriority priority,
const SocketTag& socket_tag,
RespectLimits respect_limits,
ClientSocketHandle* handle,
CompletionOnceCallback callback,
const ProxyAuthCallback& proxy_auth_callback,
const NetLogWithSource& net_log) { … }
int TransportClientSocketPool::RequestSockets(
const GroupId& group_id,
scoped_refptr<SocketParams> params,
const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
int num_sockets,
CompletionOnceCallback callback,
const NetLogWithSource& net_log) { … }
int TransportClientSocketPool::RequestSocketInternal(
const GroupId& group_id,
const Request& request,
base::OnceClosure preconnect_done_closure) { … }
bool TransportClientSocketPool::AssignIdleSocketToRequest(
const Request& request,
Group* group) { … }
void TransportClientSocketPool::LogBoundConnectJobToRequest(
const NetLogSource& connect_job_source,
const Request& request) { … }
void TransportClientSocketPool::SetPriority(const GroupId& group_id,
ClientSocketHandle* handle,
RequestPriority priority) { … }
void TransportClientSocketPool::CancelRequest(const GroupId& group_id,
ClientSocketHandle* handle,
bool cancel_connect_job) { … }
void TransportClientSocketPool::CloseIdleSockets(
const char* net_log_reason_utf8) { … }
void TransportClientSocketPool::CloseIdleSocketsInGroup(
const GroupId& group_id,
const char* net_log_reason_utf8) { … }
int TransportClientSocketPool::IdleSocketCount() const { … }
size_t TransportClientSocketPool::IdleSocketCountInGroup(
const GroupId& group_id) const { … }
LoadState TransportClientSocketPool::GetLoadState(
const GroupId& group_id,
const ClientSocketHandle* handle) const { … }
base::Value TransportClientSocketPool::GetInfoAsValue(
const std::string& name,
const std::string& type) const { … }
bool TransportClientSocketPool::HasActiveSocket(const GroupId& group_id) const { … }
bool TransportClientSocketPool::IdleSocket::IsUsable(
const char** net_log_reason_utf8) const { … }
TransportClientSocketPool::TransportClientSocketPool(
int max_sockets,
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
base::TimeDelta used_idle_socket_timeout,
const ProxyChain& proxy_chain,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
bool cleanup_on_ip_address_change,
std::unique_ptr<ConnectJobFactory> connect_job_factory,
SSLClientContext* ssl_client_context,
bool connect_backup_jobs_enabled)
: … { … }
void TransportClientSocketPool::OnSSLConfigChanged(
SSLClientContext::SSLConfigChangeType change_type) { … }
void TransportClientSocketPool::OnSSLConfigForServersChanged(
const base::flat_set<HostPortPair>& servers) { … }
bool TransportClientSocketPool::HasGroup(const GroupId& group_id) const { … }
void TransportClientSocketPool::CleanupIdleSockets(
bool force,
const char* net_log_reason_utf8) { … }
bool TransportClientSocketPool::CloseOneIdleSocket() { … }
bool TransportClientSocketPool::CloseOneIdleConnectionInHigherLayeredPool() { … }
void TransportClientSocketPool::CleanupIdleSocketsInGroup(
bool force,
Group* group,
const base::TimeTicks& now,
const char* net_log_reason_utf8) { … }
TransportClientSocketPool::Group* TransportClientSocketPool::GetOrCreateGroup(
const GroupId& group_id) { … }
void TransportClientSocketPool::RemoveGroup(const GroupId& group_id) { … }
TransportClientSocketPool::GroupMap::iterator
TransportClientSocketPool::RemoveGroup(GroupMap::iterator it) { … }
bool TransportClientSocketPool::connect_backup_jobs_enabled() { … }
bool TransportClientSocketPool::set_connect_backup_jobs_enabled(bool enabled) { … }
void TransportClientSocketPool::IncrementIdleCount() { … }
void TransportClientSocketPool::DecrementIdleCount() { … }
void TransportClientSocketPool::ReleaseSocket(
const GroupId& group_id,
std::unique_ptr<StreamSocket> socket,
int64_t group_generation) { … }
void TransportClientSocketPool::CheckForStalledSocketGroups() { … }
bool TransportClientSocketPool::FindTopStalledGroup(Group** group,
GroupId* group_id) const { … }
void TransportClientSocketPool::OnIPAddressChanged() { … }
void TransportClientSocketPool::FlushWithError(
int error,
const char* net_log_reason_utf8) { … }
void TransportClientSocketPool::RemoveConnectJob(ConnectJob* job,
Group* group) { … }
void TransportClientSocketPool::OnAvailableSocketSlot(const GroupId& group_id,
Group* group) { … }
void TransportClientSocketPool::ProcessPendingRequest(const GroupId& group_id,
Group* group) { … }
void TransportClientSocketPool::HandOutSocket(
std::unique_ptr<StreamSocket> socket,
ClientSocketHandle::SocketReuseType reuse_type,
const LoadTimingInfo::ConnectTiming& connect_timing,
ClientSocketHandle* handle,
base::TimeDelta idle_time,
Group* group,
const NetLogWithSource& net_log) { … }
void TransportClientSocketPool::AddIdleSocket(
std::unique_ptr<StreamSocket> socket,
Group* group) { … }
void TransportClientSocketPool::CancelAllConnectJobs() { … }
void TransportClientSocketPool::CancelAllRequestsWithError(int error) { … }
bool TransportClientSocketPool::ReachedMaxSocketsLimit() const { … }
bool TransportClientSocketPool::CloseOneIdleSocketExceptInGroup(
const Group* exception_group) { … }
void TransportClientSocketPool::OnConnectJobComplete(Group* group,
int result,
ConnectJob* job) { … }
void TransportClientSocketPool::OnNeedsProxyAuth(
Group* group,
const HttpResponseInfo& response,
HttpAuthController* auth_controller,
base::OnceClosure restart_with_auth_callback,
ConnectJob* job) { … }
void TransportClientSocketPool::InvokeUserCallbackLater(
ClientSocketHandle* handle,
CompletionOnceCallback callback,
int rv,
const SocketTag& socket_tag) { … }
void TransportClientSocketPool::InvokeUserCallback(
MayBeDangling<ClientSocketHandle> handle) { … }
void TransportClientSocketPool::TryToCloseSocketsInLayeredPools() { … }
TransportClientSocketPool::GroupMap::iterator
TransportClientSocketPool::RefreshGroup(GroupMap::iterator it,
const base::TimeTicks& now,
const char* net_log_reason_utf8) { … }
TransportClientSocketPool::Group::Group(
const GroupId& group_id,
TransportClientSocketPool* client_socket_pool)
: … { … }
TransportClientSocketPool::Group::~Group() { … }
void TransportClientSocketPool::Group::OnConnectJobComplete(int result,
ConnectJob* job) { … }
void TransportClientSocketPool::Group::OnNeedsProxyAuth(
const HttpResponseInfo& response,
HttpAuthController* auth_controller,
base::OnceClosure restart_with_auth_callback,
ConnectJob* job) { … }
void TransportClientSocketPool::Group::StartBackupJobTimer(
const GroupId& group_id) { … }
bool TransportClientSocketPool::Group::BackupJobTimerIsRunning() const { … }
bool TransportClientSocketPool::Group::TryToUseNeverAssignedConnectJob() { … }
void TransportClientSocketPool::Group::AddJob(std::unique_ptr<ConnectJob> job,
bool is_preconnect) { … }
std::unique_ptr<ConnectJob> TransportClientSocketPool::Group::RemoveUnboundJob(
ConnectJob* job) { … }
void TransportClientSocketPool::Group::OnBackupJobTimerFired(
const GroupId& group_id) { … }
void TransportClientSocketPool::Group::SanityCheck() const { … }
void TransportClientSocketPool::Group::RemoveAllUnboundJobs() { … }
size_t TransportClientSocketPool::Group::ConnectJobCount() const { … }
ConnectJob* TransportClientSocketPool::Group::GetConnectJobForHandle(
const ClientSocketHandle* handle) const { … }
void TransportClientSocketPool::Group::InsertUnboundRequest(
std::unique_ptr<Request> request) { … }
const TransportClientSocketPool::Request*
TransportClientSocketPool::Group::GetNextUnboundRequest() const { … }
std::unique_ptr<TransportClientSocketPool::Request>
TransportClientSocketPool::Group::PopNextUnboundRequest() { … }
std::unique_ptr<TransportClientSocketPool::Request>
TransportClientSocketPool::Group::FindAndRemoveUnboundRequest(
ClientSocketHandle* handle) { … }
void TransportClientSocketPool::Group::SetPendingErrorForAllBoundRequests(
int pending_error) { … }
const TransportClientSocketPool::Request*
TransportClientSocketPool::Group::BindRequestToConnectJob(
ConnectJob* connect_job) { … }
std::optional<TransportClientSocketPool::Group::BoundRequest>
TransportClientSocketPool::Group::FindAndRemoveBoundRequestForConnectJob(
ConnectJob* connect_job) { … }
std::unique_ptr<TransportClientSocketPool::Request>
TransportClientSocketPool::Group::FindAndRemoveBoundRequest(
ClientSocketHandle* client_socket_handle) { … }
void TransportClientSocketPool::Group::SetPriority(ClientSocketHandle* handle,
RequestPriority priority) { … }
bool TransportClientSocketPool::Group::RequestWithHandleHasJobForTesting(
const ClientSocketHandle* handle) const { … }
TransportClientSocketPool::Group::BoundRequest::BoundRequest()
: … { … }
TransportClientSocketPool::Group::BoundRequest::BoundRequest(
std::unique_ptr<ConnectJob> connect_job,
std::unique_ptr<Request> request,
int64_t generation)
: … { … }
TransportClientSocketPool::Group::BoundRequest::BoundRequest(
BoundRequest&& other) = default;
TransportClientSocketPool::Group::BoundRequest&
TransportClientSocketPool::Group::BoundRequest::operator=(
BoundRequest&& other) = default;
TransportClientSocketPool::Group::BoundRequest::~BoundRequest() = default;
std::unique_ptr<TransportClientSocketPool::Request>
TransportClientSocketPool::Group::RemoveUnboundRequest(
const RequestQueue::Pointer& pointer) { … }
TransportClientSocketPool::RequestQueue::Pointer
TransportClientSocketPool::Group::FindUnboundRequestWithJob(
const ConnectJob* job) const { … }
TransportClientSocketPool::RequestQueue::Pointer
TransportClientSocketPool::Group::GetFirstRequestWithoutJob() const { … }
void TransportClientSocketPool::Group::TryToAssignUnassignedJob(
ConnectJob* job) { … }
void TransportClientSocketPool::Group::TryToAssignJobToRequest(
TransportClientSocketPool::RequestQueue::Pointer request_pointer) { … }
void TransportClientSocketPool::Group::TransferJobBetweenRequests(
TransportClientSocketPool::Request* source,
TransportClientSocketPool::Request* dest) { … }
}