Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / net / socket / client_socket_pool_manager_impl.cc
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>
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
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
107 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
108   CertDatabase::GetInstance()->RemoveObserver(this);
109 }
110
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
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*
211 ClientSocketPoolManagerImpl::GetTransportSocketPool() {
212   return transport_socket_pool_.get();
213 }
214
215 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
216   return ssl_socket_pool_.get();
217 }
218
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*
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
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
367 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
396 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
397   FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
398 }
399
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