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