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