• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "net/socket/client_socket_pool_manager_impl.h"
6 
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/ssl/ssl_config_service.h"
15 
16 namespace net {
17 
18 namespace {
19 
20 // Appends information about all |socket_pools| to the end of |list|.
21 template <class MapType>
AddSocketPoolsToList(base::ListValue * list,const MapType & socket_pools,const std::string & type,bool include_nested_pools)22 void AddSocketPoolsToList(base::ListValue* list,
23                           const MapType& socket_pools,
24                           const std::string& type,
25                           bool include_nested_pools) {
26   for (typename MapType::const_iterator it = socket_pools.begin();
27        it != socket_pools.end(); it++) {
28     list->Append(it->second->GetInfoAsValue(it->first.ToString(),
29                                             type,
30                                             include_nested_pools));
31   }
32 }
33 
34 }  // namespace
35 
ClientSocketPoolManagerImpl(NetLog * net_log,ClientSocketFactory * socket_factory,HostResolver * host_resolver,CertVerifier * cert_verifier,ServerBoundCertService * server_bound_cert_service,TransportSecurityState * transport_security_state,CTVerifier * cert_transparency_verifier,const std::string & ssl_session_cache_shard,ProxyService * proxy_service,SSLConfigService * ssl_config_service,HttpNetworkSession::SocketPoolType pool_type)36 ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
37     NetLog* net_log,
38     ClientSocketFactory* socket_factory,
39     HostResolver* host_resolver,
40     CertVerifier* cert_verifier,
41     ServerBoundCertService* server_bound_cert_service,
42     TransportSecurityState* transport_security_state,
43     CTVerifier* cert_transparency_verifier,
44     const std::string& ssl_session_cache_shard,
45     ProxyService* proxy_service,
46     SSLConfigService* ssl_config_service,
47     HttpNetworkSession::SocketPoolType pool_type)
48     : net_log_(net_log),
49       socket_factory_(socket_factory),
50       host_resolver_(host_resolver),
51       cert_verifier_(cert_verifier),
52       server_bound_cert_service_(server_bound_cert_service),
53       transport_security_state_(transport_security_state),
54       cert_transparency_verifier_(cert_transparency_verifier),
55       ssl_session_cache_shard_(ssl_session_cache_shard),
56       proxy_service_(proxy_service),
57       ssl_config_service_(ssl_config_service),
58       pool_type_(pool_type),
59       transport_pool_histograms_("TCP"),
60       transport_socket_pool_(new TransportClientSocketPool(
61           max_sockets_per_pool(pool_type), max_sockets_per_group(pool_type),
62           &transport_pool_histograms_,
63           host_resolver,
64           socket_factory_,
65           net_log)),
66       ssl_pool_histograms_("SSL2"),
67       ssl_socket_pool_(new SSLClientSocketPool(
68           max_sockets_per_pool(pool_type), max_sockets_per_group(pool_type),
69           &ssl_pool_histograms_,
70           host_resolver,
71           cert_verifier,
72           server_bound_cert_service,
73           transport_security_state,
74           cert_transparency_verifier,
75           ssl_session_cache_shard,
76           socket_factory,
77           transport_socket_pool_.get(),
78           NULL /* no socks proxy */,
79           NULL /* no http proxy */,
80           ssl_config_service,
81           net_log)),
82       transport_for_socks_pool_histograms_("TCPforSOCKS"),
83       socks_pool_histograms_("SOCK"),
84       transport_for_http_proxy_pool_histograms_("TCPforHTTPProxy"),
85       transport_for_https_proxy_pool_histograms_("TCPforHTTPSProxy"),
86       ssl_for_https_proxy_pool_histograms_("SSLforHTTPSProxy"),
87       http_proxy_pool_histograms_("HTTPProxy"),
88       ssl_socket_pool_for_proxies_histograms_("SSLForProxies") {
89   CertDatabase::GetInstance()->AddObserver(this);
90 }
91 
~ClientSocketPoolManagerImpl()92 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
93   CertDatabase::GetInstance()->RemoveObserver(this);
94 }
95 
FlushSocketPoolsWithError(int error)96 void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error) {
97   // Flush the highest level pools first, since higher level pools may release
98   // stuff to the lower level pools.
99 
100   for (SSLSocketPoolMap::const_iterator it =
101        ssl_socket_pools_for_proxies_.begin();
102        it != ssl_socket_pools_for_proxies_.end();
103        ++it)
104     it->second->FlushWithError(error);
105 
106   for (HTTPProxySocketPoolMap::const_iterator it =
107        http_proxy_socket_pools_.begin();
108        it != http_proxy_socket_pools_.end();
109        ++it)
110     it->second->FlushWithError(error);
111 
112   for (SSLSocketPoolMap::const_iterator it =
113        ssl_socket_pools_for_https_proxies_.begin();
114        it != ssl_socket_pools_for_https_proxies_.end();
115        ++it)
116     it->second->FlushWithError(error);
117 
118   for (TransportSocketPoolMap::const_iterator it =
119        transport_socket_pools_for_https_proxies_.begin();
120        it != transport_socket_pools_for_https_proxies_.end();
121        ++it)
122     it->second->FlushWithError(error);
123 
124   for (TransportSocketPoolMap::const_iterator it =
125        transport_socket_pools_for_http_proxies_.begin();
126        it != transport_socket_pools_for_http_proxies_.end();
127        ++it)
128     it->second->FlushWithError(error);
129 
130   for (SOCKSSocketPoolMap::const_iterator it =
131        socks_socket_pools_.begin();
132        it != socks_socket_pools_.end();
133        ++it)
134     it->second->FlushWithError(error);
135 
136   for (TransportSocketPoolMap::const_iterator it =
137        transport_socket_pools_for_socks_proxies_.begin();
138        it != transport_socket_pools_for_socks_proxies_.end();
139        ++it)
140     it->second->FlushWithError(error);
141 
142   ssl_socket_pool_->FlushWithError(error);
143   transport_socket_pool_->FlushWithError(error);
144 }
145 
CloseIdleSockets()146 void ClientSocketPoolManagerImpl::CloseIdleSockets() {
147   // Close sockets in the highest level pools first, since higher level pools'
148   // sockets may release stuff to the lower level pools.
149   for (SSLSocketPoolMap::const_iterator it =
150        ssl_socket_pools_for_proxies_.begin();
151        it != ssl_socket_pools_for_proxies_.end();
152        ++it)
153     it->second->CloseIdleSockets();
154 
155   for (HTTPProxySocketPoolMap::const_iterator it =
156        http_proxy_socket_pools_.begin();
157        it != http_proxy_socket_pools_.end();
158        ++it)
159     it->second->CloseIdleSockets();
160 
161   for (SSLSocketPoolMap::const_iterator it =
162        ssl_socket_pools_for_https_proxies_.begin();
163        it != ssl_socket_pools_for_https_proxies_.end();
164        ++it)
165     it->second->CloseIdleSockets();
166 
167   for (TransportSocketPoolMap::const_iterator it =
168        transport_socket_pools_for_https_proxies_.begin();
169        it != transport_socket_pools_for_https_proxies_.end();
170        ++it)
171     it->second->CloseIdleSockets();
172 
173   for (TransportSocketPoolMap::const_iterator it =
174        transport_socket_pools_for_http_proxies_.begin();
175        it != transport_socket_pools_for_http_proxies_.end();
176        ++it)
177     it->second->CloseIdleSockets();
178 
179   for (SOCKSSocketPoolMap::const_iterator it =
180        socks_socket_pools_.begin();
181        it != socks_socket_pools_.end();
182        ++it)
183     it->second->CloseIdleSockets();
184 
185   for (TransportSocketPoolMap::const_iterator it =
186        transport_socket_pools_for_socks_proxies_.begin();
187        it != transport_socket_pools_for_socks_proxies_.end();
188        ++it)
189     it->second->CloseIdleSockets();
190 
191   ssl_socket_pool_->CloseIdleSockets();
192   transport_socket_pool_->CloseIdleSockets();
193 }
194 
195 TransportClientSocketPool*
GetTransportSocketPool()196 ClientSocketPoolManagerImpl::GetTransportSocketPool() {
197   return transport_socket_pool_.get();
198 }
199 
GetSSLSocketPool()200 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
201   return ssl_socket_pool_.get();
202 }
203 
GetSocketPoolForSOCKSProxy(const HostPortPair & socks_proxy)204 SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
205     const HostPortPair& socks_proxy) {
206   SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
207   if (it != socks_socket_pools_.end()) {
208     DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
209     return it->second;
210   }
211 
212   DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
213 
214   std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
215       transport_socket_pools_for_socks_proxies_.insert(
216           std::make_pair(
217               socks_proxy,
218               new TransportClientSocketPool(
219                   max_sockets_per_proxy_server(pool_type_),
220                   max_sockets_per_group(pool_type_),
221                   &transport_for_socks_pool_histograms_,
222                   host_resolver_,
223                   socket_factory_,
224                   net_log_)));
225   DCHECK(tcp_ret.second);
226 
227   std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
228       socks_socket_pools_.insert(
229           std::make_pair(socks_proxy, new SOCKSClientSocketPool(
230               max_sockets_per_proxy_server(pool_type_),
231               max_sockets_per_group(pool_type_),
232               &socks_pool_histograms_,
233               host_resolver_,
234               tcp_ret.first->second,
235               net_log_)));
236 
237   return ret.first->second;
238 }
239 
240 HttpProxyClientSocketPool*
GetSocketPoolForHTTPProxy(const HostPortPair & http_proxy)241 ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
242     const HostPortPair& http_proxy) {
243   HTTPProxySocketPoolMap::const_iterator it =
244       http_proxy_socket_pools_.find(http_proxy);
245   if (it != http_proxy_socket_pools_.end()) {
246     DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
247     DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
248     DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
249     return it->second;
250   }
251 
252   DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
253   DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
254   DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
255 
256   std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
257       transport_socket_pools_for_http_proxies_.insert(
258           std::make_pair(
259               http_proxy,
260               new TransportClientSocketPool(
261                   max_sockets_per_proxy_server(pool_type_),
262                   max_sockets_per_group(pool_type_),
263                   &transport_for_http_proxy_pool_histograms_,
264                   host_resolver_,
265                   socket_factory_,
266                   net_log_)));
267   DCHECK(tcp_http_ret.second);
268 
269   std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
270       transport_socket_pools_for_https_proxies_.insert(
271           std::make_pair(
272               http_proxy,
273               new TransportClientSocketPool(
274                   max_sockets_per_proxy_server(pool_type_),
275                   max_sockets_per_group(pool_type_),
276                   &transport_for_https_proxy_pool_histograms_,
277                   host_resolver_,
278                   socket_factory_,
279                   net_log_)));
280   DCHECK(tcp_https_ret.second);
281 
282   std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
283       ssl_socket_pools_for_https_proxies_.insert(std::make_pair(
284           http_proxy,
285           new SSLClientSocketPool(max_sockets_per_proxy_server(pool_type_),
286                                   max_sockets_per_group(pool_type_),
287                                   &ssl_for_https_proxy_pool_histograms_,
288                                   host_resolver_,
289                                   cert_verifier_,
290                                   server_bound_cert_service_,
291                                   transport_security_state_,
292                                   cert_transparency_verifier_,
293                                   ssl_session_cache_shard_,
294                                   socket_factory_,
295                                   tcp_https_ret.first->second /* https proxy */,
296                                   NULL /* no socks proxy */,
297                                   NULL /* no http proxy */,
298                                   ssl_config_service_.get(),
299                                   net_log_)));
300   DCHECK(tcp_https_ret.second);
301 
302   std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
303       http_proxy_socket_pools_.insert(
304           std::make_pair(
305               http_proxy,
306               new HttpProxyClientSocketPool(
307                   max_sockets_per_proxy_server(pool_type_),
308                   max_sockets_per_group(pool_type_),
309                   &http_proxy_pool_histograms_,
310                   host_resolver_,
311                   tcp_http_ret.first->second,
312                   ssl_https_ret.first->second,
313                   net_log_)));
314 
315   return ret.first->second;
316 }
317 
GetSocketPoolForSSLWithProxy(const HostPortPair & proxy_server)318 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
319     const HostPortPair& proxy_server) {
320   SSLSocketPoolMap::const_iterator it =
321       ssl_socket_pools_for_proxies_.find(proxy_server);
322   if (it != ssl_socket_pools_for_proxies_.end())
323     return it->second;
324 
325   SSLClientSocketPool* new_pool = new SSLClientSocketPool(
326       max_sockets_per_proxy_server(pool_type_),
327       max_sockets_per_group(pool_type_),
328       &ssl_pool_histograms_,
329       host_resolver_,
330       cert_verifier_,
331       server_bound_cert_service_,
332       transport_security_state_,
333       cert_transparency_verifier_,
334       ssl_session_cache_shard_,
335       socket_factory_,
336       NULL, /* no tcp pool, we always go through a proxy */
337       GetSocketPoolForSOCKSProxy(proxy_server),
338       GetSocketPoolForHTTPProxy(proxy_server),
339       ssl_config_service_.get(),
340       net_log_);
341 
342   std::pair<SSLSocketPoolMap::iterator, bool> ret =
343       ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
344                                                           new_pool));
345 
346   return ret.first->second;
347 }
348 
SocketPoolInfoToValue() const349 base::Value* ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
350   base::ListValue* list = new base::ListValue();
351   list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
352                                                 "transport_socket_pool",
353                                                 false));
354   // Third parameter is false because |ssl_socket_pool_| uses
355   // |transport_socket_pool_| internally, and do not want to add it a second
356   // time.
357   list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
358                                                 "ssl_socket_pool",
359                                                 false));
360   AddSocketPoolsToList(list,
361                        http_proxy_socket_pools_,
362                        "http_proxy_socket_pool",
363                        true);
364   AddSocketPoolsToList(list,
365                        socks_socket_pools_,
366                        "socks_socket_pool",
367                        true);
368 
369   // Third parameter is false because |ssl_socket_pools_for_proxies_| use
370   // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
371   AddSocketPoolsToList(list,
372                        ssl_socket_pools_for_proxies_,
373                        "ssl_socket_pool_for_proxies",
374                        false);
375   return list;
376 }
377 
OnCertAdded(const X509Certificate * cert)378 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
379   FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
380 }
381 
OnCACertChanged(const X509Certificate * cert)382 void ClientSocketPoolManagerImpl::OnCACertChanged(
383     const X509Certificate* cert) {
384   // We should flush the socket pools if we removed trust from a
385   // cert, because a previously trusted server may have become
386   // untrusted.
387   //
388   // We should not flush the socket pools if we added trust to a
389   // cert.
390   //
391   // Since the OnCACertChanged method doesn't tell us what
392   // kind of change it is, we have to flush the socket
393   // pools to be safe.
394   FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
395 }
396 
397 }  // namespace net
398