1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/socket/client_socket_pool_manager_impl.h"
7 #include "base/logging.h"
8 #include "base/values.h"
9 #include "net/http/http_network_session.h"
10 #include "net/http/http_proxy_client_socket_pool.h"
11 #include "net/socket/socks_client_socket_pool.h"
12 #include "net/socket/ssl_client_socket_pool.h"
13 #include "net/socket/transport_client_socket_pool.h"
14 #include "net/socket/websocket_transport_client_socket_pool.h"
15 #include "net/ssl/ssl_config_service.h"
21 // Appends information about all |socket_pools| to the end of |list|.
22 template <class MapType
>
23 void AddSocketPoolsToList(base::ListValue
* list
,
24 const MapType
& socket_pools
,
25 const std::string
& type
,
26 bool include_nested_pools
) {
27 for (typename
MapType::const_iterator it
= socket_pools
.begin();
28 it
!= socket_pools
.end(); it
++) {
29 list
->Append(it
->second
->GetInfoAsValue(it
->first
.ToString(),
31 include_nested_pools
));
37 ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
39 ClientSocketFactory
* socket_factory
,
40 HostResolver
* host_resolver
,
41 CertVerifier
* cert_verifier
,
42 ChannelIDService
* channel_id_service
,
43 TransportSecurityState
* transport_security_state
,
44 CTVerifier
* cert_transparency_verifier
,
45 CertPolicyEnforcer
* cert_policy_enforcer
,
46 const std::string
& ssl_session_cache_shard
,
47 SSLConfigService
* ssl_config_service
,
48 HttpNetworkSession::SocketPoolType pool_type
)
50 socket_factory_(socket_factory
),
51 host_resolver_(host_resolver
),
52 cert_verifier_(cert_verifier
),
53 channel_id_service_(channel_id_service
),
54 transport_security_state_(transport_security_state
),
55 cert_transparency_verifier_(cert_transparency_verifier
),
56 cert_policy_enforcer_(cert_policy_enforcer
),
57 ssl_session_cache_shard_(ssl_session_cache_shard
),
58 ssl_config_service_(ssl_config_service
),
59 pool_type_(pool_type
),
60 transport_socket_pool_(
61 pool_type
== HttpNetworkSession::WEBSOCKET_SOCKET_POOL
62 ? new WebSocketTransportClientSocketPool(
63 max_sockets_per_pool(pool_type
),
64 max_sockets_per_group(pool_type
),
68 : new TransportClientSocketPool(max_sockets_per_pool(pool_type
),
69 max_sockets_per_group(pool_type
),
73 ssl_socket_pool_(new SSLClientSocketPool(max_sockets_per_pool(pool_type
),
74 max_sockets_per_group(pool_type
),
77 transport_security_state
,
78 cert_transparency_verifier
,
80 ssl_session_cache_shard
,
82 transport_socket_pool_
.get(),
83 NULL
/* no socks proxy */,
84 NULL
/* no http proxy */,
87 CertDatabase::GetInstance()->AddObserver(this);
90 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
91 CertDatabase::GetInstance()->RemoveObserver(this);
94 void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error
) {
95 // Flush the highest level pools first, since higher level pools may release
96 // stuff to the lower level pools.
98 for (SSLSocketPoolMap::const_iterator it
=
99 ssl_socket_pools_for_proxies_
.begin();
100 it
!= ssl_socket_pools_for_proxies_
.end();
102 it
->second
->FlushWithError(error
);
104 for (HTTPProxySocketPoolMap::const_iterator it
=
105 http_proxy_socket_pools_
.begin();
106 it
!= http_proxy_socket_pools_
.end();
108 it
->second
->FlushWithError(error
);
110 for (SSLSocketPoolMap::const_iterator it
=
111 ssl_socket_pools_for_https_proxies_
.begin();
112 it
!= ssl_socket_pools_for_https_proxies_
.end();
114 it
->second
->FlushWithError(error
);
116 for (TransportSocketPoolMap::const_iterator it
=
117 transport_socket_pools_for_https_proxies_
.begin();
118 it
!= transport_socket_pools_for_https_proxies_
.end();
120 it
->second
->FlushWithError(error
);
122 for (TransportSocketPoolMap::const_iterator it
=
123 transport_socket_pools_for_http_proxies_
.begin();
124 it
!= transport_socket_pools_for_http_proxies_
.end();
126 it
->second
->FlushWithError(error
);
128 for (SOCKSSocketPoolMap::const_iterator it
=
129 socks_socket_pools_
.begin();
130 it
!= socks_socket_pools_
.end();
132 it
->second
->FlushWithError(error
);
134 for (TransportSocketPoolMap::const_iterator it
=
135 transport_socket_pools_for_socks_proxies_
.begin();
136 it
!= transport_socket_pools_for_socks_proxies_
.end();
138 it
->second
->FlushWithError(error
);
140 ssl_socket_pool_
->FlushWithError(error
);
141 transport_socket_pool_
->FlushWithError(error
);
144 void ClientSocketPoolManagerImpl::CloseIdleSockets() {
145 // Close sockets in the highest level pools first, since higher level pools'
146 // sockets may release stuff to the lower level pools.
147 for (SSLSocketPoolMap::const_iterator it
=
148 ssl_socket_pools_for_proxies_
.begin();
149 it
!= ssl_socket_pools_for_proxies_
.end();
151 it
->second
->CloseIdleSockets();
153 for (HTTPProxySocketPoolMap::const_iterator it
=
154 http_proxy_socket_pools_
.begin();
155 it
!= http_proxy_socket_pools_
.end();
157 it
->second
->CloseIdleSockets();
159 for (SSLSocketPoolMap::const_iterator it
=
160 ssl_socket_pools_for_https_proxies_
.begin();
161 it
!= ssl_socket_pools_for_https_proxies_
.end();
163 it
->second
->CloseIdleSockets();
165 for (TransportSocketPoolMap::const_iterator it
=
166 transport_socket_pools_for_https_proxies_
.begin();
167 it
!= transport_socket_pools_for_https_proxies_
.end();
169 it
->second
->CloseIdleSockets();
171 for (TransportSocketPoolMap::const_iterator it
=
172 transport_socket_pools_for_http_proxies_
.begin();
173 it
!= transport_socket_pools_for_http_proxies_
.end();
175 it
->second
->CloseIdleSockets();
177 for (SOCKSSocketPoolMap::const_iterator it
=
178 socks_socket_pools_
.begin();
179 it
!= socks_socket_pools_
.end();
181 it
->second
->CloseIdleSockets();
183 for (TransportSocketPoolMap::const_iterator it
=
184 transport_socket_pools_for_socks_proxies_
.begin();
185 it
!= transport_socket_pools_for_socks_proxies_
.end();
187 it
->second
->CloseIdleSockets();
189 ssl_socket_pool_
->CloseIdleSockets();
190 transport_socket_pool_
->CloseIdleSockets();
193 TransportClientSocketPool
*
194 ClientSocketPoolManagerImpl::GetTransportSocketPool() {
195 return transport_socket_pool_
.get();
198 SSLClientSocketPool
* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
199 return ssl_socket_pool_
.get();
202 SOCKSClientSocketPool
* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
203 const HostPortPair
& socks_proxy
) {
204 SOCKSSocketPoolMap::const_iterator it
= socks_socket_pools_
.find(socks_proxy
);
205 if (it
!= socks_socket_pools_
.end()) {
206 DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_
, socks_proxy
));
210 DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_
, socks_proxy
));
212 std::pair
<TransportSocketPoolMap::iterator
, bool> tcp_ret
=
213 transport_socket_pools_for_socks_proxies_
.insert(
216 new TransportClientSocketPool(
217 max_sockets_per_proxy_server(pool_type_
),
218 max_sockets_per_group(pool_type_
),
222 DCHECK(tcp_ret
.second
);
224 std::pair
<SOCKSSocketPoolMap::iterator
, bool> ret
=
225 socks_socket_pools_
.insert(
226 std::make_pair(socks_proxy
, new SOCKSClientSocketPool(
227 max_sockets_per_proxy_server(pool_type_
),
228 max_sockets_per_group(pool_type_
),
230 tcp_ret
.first
->second
,
233 return ret
.first
->second
;
236 HttpProxyClientSocketPool
*
237 ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
238 const HostPortPair
& http_proxy
) {
239 HTTPProxySocketPoolMap::const_iterator it
=
240 http_proxy_socket_pools_
.find(http_proxy
);
241 if (it
!= http_proxy_socket_pools_
.end()) {
242 DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_
, http_proxy
));
243 DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_
, http_proxy
));
244 DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_
, http_proxy
));
248 DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_
, http_proxy
));
249 DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_
, http_proxy
));
250 DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_
, http_proxy
));
252 std::pair
<TransportSocketPoolMap::iterator
, bool> tcp_http_ret
=
253 transport_socket_pools_for_http_proxies_
.insert(
256 new TransportClientSocketPool(
257 max_sockets_per_proxy_server(pool_type_
),
258 max_sockets_per_group(pool_type_
),
262 DCHECK(tcp_http_ret
.second
);
264 std::pair
<TransportSocketPoolMap::iterator
, bool> tcp_https_ret
=
265 transport_socket_pools_for_https_proxies_
.insert(
268 new TransportClientSocketPool(
269 max_sockets_per_proxy_server(pool_type_
),
270 max_sockets_per_group(pool_type_
),
274 DCHECK(tcp_https_ret
.second
);
276 std::pair
<SSLSocketPoolMap::iterator
, bool> ssl_https_ret
=
277 ssl_socket_pools_for_https_proxies_
.insert(std::make_pair(
278 http_proxy
, new SSLClientSocketPool(
279 max_sockets_per_proxy_server(pool_type_
),
280 max_sockets_per_group(pool_type_
), cert_verifier_
,
281 channel_id_service_
, transport_security_state_
,
282 cert_transparency_verifier_
, cert_policy_enforcer_
,
283 ssl_session_cache_shard_
, socket_factory_
,
284 tcp_https_ret
.first
->second
/* https proxy */,
285 NULL
/* no socks proxy */, NULL
/* no http proxy */,
286 ssl_config_service_
.get(), net_log_
)));
287 DCHECK(tcp_https_ret
.second
);
289 std::pair
<HTTPProxySocketPoolMap::iterator
, bool> ret
=
290 http_proxy_socket_pools_
.insert(
293 new HttpProxyClientSocketPool(
294 max_sockets_per_proxy_server(pool_type_
),
295 max_sockets_per_group(pool_type_
),
296 tcp_http_ret
.first
->second
,
297 ssl_https_ret
.first
->second
,
300 return ret
.first
->second
;
303 SSLClientSocketPool
* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
304 const HostPortPair
& proxy_server
) {
305 SSLSocketPoolMap::const_iterator it
=
306 ssl_socket_pools_for_proxies_
.find(proxy_server
);
307 if (it
!= ssl_socket_pools_for_proxies_
.end())
310 SSLClientSocketPool
* new_pool
= new SSLClientSocketPool(
311 max_sockets_per_proxy_server(pool_type_
),
312 max_sockets_per_group(pool_type_
), cert_verifier_
, channel_id_service_
,
313 transport_security_state_
, cert_transparency_verifier_
,
314 cert_policy_enforcer_
, ssl_session_cache_shard_
, socket_factory_
,
315 NULL
, /* no tcp pool, we always go through a proxy */
316 GetSocketPoolForSOCKSProxy(proxy_server
),
317 GetSocketPoolForHTTPProxy(proxy_server
), ssl_config_service_
.get(),
320 std::pair
<SSLSocketPoolMap::iterator
, bool> ret
=
321 ssl_socket_pools_for_proxies_
.insert(std::make_pair(proxy_server
,
324 return ret
.first
->second
;
327 scoped_ptr
<base::Value
> ClientSocketPoolManagerImpl::SocketPoolInfoToValue()
329 scoped_ptr
<base::ListValue
> list(new base::ListValue());
330 list
->Append(transport_socket_pool_
->GetInfoAsValue("transport_socket_pool",
331 "transport_socket_pool",
333 // Third parameter is false because |ssl_socket_pool_| uses
334 // |transport_socket_pool_| internally, and do not want to add it a second
336 list
->Append(ssl_socket_pool_
->GetInfoAsValue("ssl_socket_pool",
339 AddSocketPoolsToList(list
.get(), http_proxy_socket_pools_
,
340 "http_proxy_socket_pool", true);
341 AddSocketPoolsToList(list
.get(), socks_socket_pools_
, "socks_socket_pool",
344 // Third parameter is false because |ssl_socket_pools_for_proxies_| use
345 // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
346 AddSocketPoolsToList(list
.get(), ssl_socket_pools_for_proxies_
,
347 "ssl_socket_pool_for_proxies", false);
351 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate
* cert
) {
352 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED
);
355 void ClientSocketPoolManagerImpl::OnCACertChanged(
356 const X509Certificate
* cert
) {
357 // We should flush the socket pools if we removed trust from a
358 // cert, because a previously trusted server may have become
361 // We should not flush the socket pools if we added trust to a
364 // Since the OnCACertChanged method doesn't tell us what
365 // kind of change it is, we have to flush the socket
367 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED
);