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 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 92 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() { 93 CertDatabase::GetInstance()->RemoveObserver(this); 94 } 95 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 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* 196 ClientSocketPoolManagerImpl::GetTransportSocketPool() { 197 return transport_socket_pool_.get(); 198 } 199 200 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() { 201 return ssl_socket_pool_.get(); 202 } 203 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* 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 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 349 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 378 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) { 379 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED); 380 } 381 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