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 17namespace net { 18 19namespace { 20 21// Appends information about all |socket_pools| to the end of |list|. 22template <class MapType> 23void 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 37ClientSocketPoolManagerImpl::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 107ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() { 108 CertDatabase::GetInstance()->RemoveObserver(this); 109} 110 111void 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 161void 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 210TransportClientSocketPool* 211ClientSocketPoolManagerImpl::GetTransportSocketPool() { 212 return transport_socket_pool_.get(); 213} 214 215SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() { 216 return ssl_socket_pool_.get(); 217} 218 219SOCKSClientSocketPool* 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 255HttpProxyClientSocketPool* 256ClientSocketPoolManagerImpl::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 335SSLClientSocketPool* 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 367base::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 396void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) { 397 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED); 398} 399 400void 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