xref: /aosp_15_r20/external/cronet/net/socket/client_socket_pool_manager_impl.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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/socket/client_socket_pool_manager_impl.h"
6 
7 #include <algorithm>
8 #include <utility>
9 
10 #include "base/check_op.h"
11 #include "base/values.h"
12 #include "net/base/proxy_chain.h"
13 #include "net/base/proxy_server.h"
14 #include "net/base/proxy_string_util.h"
15 #include "net/http/http_network_session.h"
16 #include "net/socket/socks_connect_job.h"
17 #include "net/socket/ssl_connect_job.h"
18 #include "net/socket/transport_client_socket_pool.h"
19 #include "net/socket/transport_connect_job.h"
20 #include "net/socket/websocket_transport_client_socket_pool.h"
21 
22 namespace net {
23 
24 class SocketPerformanceWatcherFactory;
25 
ClientSocketPoolManagerImpl(const CommonConnectJobParams & common_connect_job_params,const CommonConnectJobParams & websocket_common_connect_job_params,HttpNetworkSession::SocketPoolType pool_type,bool cleanup_on_ip_address_change)26 ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
27     const CommonConnectJobParams& common_connect_job_params,
28     const CommonConnectJobParams& websocket_common_connect_job_params,
29     HttpNetworkSession::SocketPoolType pool_type,
30     bool cleanup_on_ip_address_change)
31     : common_connect_job_params_(common_connect_job_params),
32       websocket_common_connect_job_params_(websocket_common_connect_job_params),
33       pool_type_(pool_type),
34       cleanup_on_ip_address_change_(cleanup_on_ip_address_change) {
35   // |websocket_endpoint_lock_manager| must only be set for websocket
36   // connections.
37   DCHECK(!common_connect_job_params_.websocket_endpoint_lock_manager);
38   DCHECK(websocket_common_connect_job_params.websocket_endpoint_lock_manager);
39 }
40 
~ClientSocketPoolManagerImpl()41 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
42   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
43 }
44 
FlushSocketPoolsWithError(int net_error,const char * net_log_reason_utf8)45 void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(
46     int net_error,
47     const char* net_log_reason_utf8) {
48   for (const auto& it : socket_pools_) {
49     it.second->FlushWithError(net_error, net_log_reason_utf8);
50   }
51 }
52 
CloseIdleSockets(const char * net_log_reason_utf8)53 void ClientSocketPoolManagerImpl::CloseIdleSockets(
54     const char* net_log_reason_utf8) {
55   for (const auto& it : socket_pools_) {
56     it.second->CloseIdleSockets(net_log_reason_utf8);
57   }
58 }
59 
GetSocketPool(const ProxyChain & proxy_chain)60 ClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPool(
61     const ProxyChain& proxy_chain) {
62   SocketPoolMap::const_iterator it = socket_pools_.find(proxy_chain);
63   if (it != socket_pools_.end())
64     return it->second.get();
65 
66   int sockets_per_proxy_chain;
67   int sockets_per_group;
68   if (proxy_chain.is_direct()) {
69     sockets_per_proxy_chain = max_sockets_per_pool(pool_type_);
70     sockets_per_group = max_sockets_per_group(pool_type_);
71   } else {
72     sockets_per_proxy_chain = max_sockets_per_proxy_chain(pool_type_);
73     sockets_per_group =
74         std::min(sockets_per_proxy_chain, max_sockets_per_group(pool_type_));
75   }
76 
77   std::unique_ptr<ClientSocketPool> new_pool;
78 
79   // Use specialized WebSockets pool for WebSockets when no proxies are in use.
80   if (pool_type_ == HttpNetworkSession::WEBSOCKET_SOCKET_POOL &&
81       proxy_chain.is_direct()) {
82     new_pool = std::make_unique<WebSocketTransportClientSocketPool>(
83         sockets_per_proxy_chain, sockets_per_group, proxy_chain,
84         &websocket_common_connect_job_params_);
85   } else {
86     new_pool = std::make_unique<TransportClientSocketPool>(
87         sockets_per_proxy_chain, sockets_per_group,
88         unused_idle_socket_timeout(pool_type_), proxy_chain,
89         pool_type_ == HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
90         &common_connect_job_params_, cleanup_on_ip_address_change_);
91   }
92 
93   std::pair<SocketPoolMap::iterator, bool> ret =
94       socket_pools_.emplace(proxy_chain, std::move(new_pool));
95   return ret.first->second.get();
96 }
97 
SocketPoolInfoToValue() const98 base::Value ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
99   base::Value::List list;
100   for (const auto& socket_pool : socket_pools_) {
101     // TODO(menke): Is this really needed?
102     const char* type;
103     // Note that it's actually the last proxy that determines the type of socket
104     // pool, although for SOCKS proxy chains, multi-proxy chains aren't
105     // supported.
106     const ProxyChain& proxy_chain = socket_pool.first;
107     if (proxy_chain.is_direct()) {
108       type = "transport_socket_pool";
109     } else if (proxy_chain.Last().is_socks()) {
110       type = "socks_socket_pool";
111     } else {
112       type = "http_proxy_socket_pool";
113     }
114     list.Append(
115         socket_pool.second->GetInfoAsValue(proxy_chain.ToDebugString(), type));
116   }
117 
118   return base::Value(std::move(list));
119 }
120 
121 }  // namespace net
122