OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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/base/ssl_config_service.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 | |
15 namespace net { | |
16 | |
17 namespace { | |
18 | |
19 // Appends information about all |socket_pools| to the end of |list|. | |
20 template <class MapType> | |
21 void AddSocketPoolsToList(ListValue* list, | |
22 const MapType& socket_pools, | |
23 const std::string& type, | |
24 bool include_nested_pools) { | |
25 for (typename MapType::const_iterator it = socket_pools.begin(); | |
26 it != socket_pools.end(); it++) { | |
27 list->Append(it->second->GetInfoAsValue(it->first.ToString(), | |
28 type, | |
29 include_nested_pools)); | |
30 } | |
31 } | |
32 | |
33 } // namespace | |
34 | |
35 ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl( | |
36 NetLog* net_log, | |
37 ClientSocketFactory* socket_factory, | |
38 HostResolver* host_resolver, | |
39 CertVerifier* cert_verifier, | |
40 OriginBoundCertService* origin_bound_cert_service, | |
41 DnsRRResolver* dnsrr_resolver, | |
42 DnsCertProvenanceChecker* dns_cert_checker, | |
43 SSLHostInfoFactory* ssl_host_info_factory, | |
44 ProxyService* proxy_service, | |
45 SSLConfigService* ssl_config_service) | |
46 : net_log_(net_log), | |
47 socket_factory_(socket_factory), | |
48 host_resolver_(host_resolver), | |
49 cert_verifier_(cert_verifier), | |
50 origin_bound_cert_service_(origin_bound_cert_service), | |
51 dnsrr_resolver_(dnsrr_resolver), | |
52 dns_cert_checker_(dns_cert_checker), | |
53 ssl_host_info_factory_(ssl_host_info_factory), | |
54 proxy_service_(proxy_service), | |
55 ssl_config_service_(ssl_config_service), | |
56 transport_pool_histograms_("TCP"), | |
57 transport_socket_pool_(new TransportClientSocketPool( | |
58 max_sockets_per_pool(), max_sockets_per_group(), | |
59 &transport_pool_histograms_, | |
60 host_resolver, | |
61 socket_factory_, | |
62 net_log)), | |
63 ssl_pool_histograms_("SSL2"), | |
64 ssl_socket_pool_(new SSLClientSocketPool( | |
65 max_sockets_per_pool(), max_sockets_per_group(), | |
66 &ssl_pool_histograms_, | |
67 host_resolver, | |
68 cert_verifier, | |
69 origin_bound_cert_service, | |
70 dnsrr_resolver, | |
71 dns_cert_checker, | |
72 ssl_host_info_factory, | |
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::AddObserver(this); | |
87 } | |
88 | |
89 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() { | |
90 CertDatabase::RemoveObserver(this); | |
91 } | |
92 | |
93 void ClientSocketPoolManagerImpl::FlushSocketPools() { | |
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->Flush(); | |
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->Flush(); | |
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->Flush(); | |
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->Flush(); | |
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->Flush(); | |
126 | |
127 for (SOCKSSocketPoolMap::const_iterator it = | |
128 socks_socket_pools_.begin(); | |
129 it != socks_socket_pools_.end(); | |
130 ++it) | |
131 it->second->Flush(); | |
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->Flush(); | |
138 | |
139 ssl_socket_pool_->Flush(); | |
140 transport_socket_pool_->Flush(); | |
141 } | |
142 | |
143 TransportClientSocketPool* | |
144 ClientSocketPoolManagerImpl::GetTransportSocketPool() { | |
mmenke
2011/11/16 16:12:03
nit: This method and the next should be below the
willchan no longer on Chromium
2011/11/16 17:26:06
Done.
| |
145 return transport_socket_pool_.get(); | |
146 } | |
147 | |
148 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() { | |
149 return ssl_socket_pool_.get(); | |
150 } | |
151 | |
152 void ClientSocketPoolManagerImpl::CloseIdleSockets() { | |
153 // Close sockets in the highest level pools first, since higher level pools' | |
154 // sockets may release stuff to the lower level pools. | |
155 for (SSLSocketPoolMap::const_iterator it = | |
156 ssl_socket_pools_for_proxies_.begin(); | |
157 it != ssl_socket_pools_for_proxies_.end(); | |
158 ++it) | |
159 it->second->CloseIdleSockets(); | |
160 | |
161 for (HTTPProxySocketPoolMap::const_iterator it = | |
162 http_proxy_socket_pools_.begin(); | |
163 it != http_proxy_socket_pools_.end(); | |
164 ++it) | |
165 it->second->CloseIdleSockets(); | |
166 | |
167 for (SSLSocketPoolMap::const_iterator it = | |
168 ssl_socket_pools_for_https_proxies_.begin(); | |
169 it != ssl_socket_pools_for_https_proxies_.end(); | |
170 ++it) | |
171 it->second->CloseIdleSockets(); | |
172 | |
173 for (TransportSocketPoolMap::const_iterator it = | |
174 transport_socket_pools_for_https_proxies_.begin(); | |
175 it != transport_socket_pools_for_https_proxies_.end(); | |
176 ++it) | |
177 it->second->CloseIdleSockets(); | |
178 | |
179 for (TransportSocketPoolMap::const_iterator it = | |
180 transport_socket_pools_for_http_proxies_.begin(); | |
181 it != transport_socket_pools_for_http_proxies_.end(); | |
182 ++it) | |
183 it->second->CloseIdleSockets(); | |
184 | |
185 for (SOCKSSocketPoolMap::const_iterator it = | |
186 socks_socket_pools_.begin(); | |
187 it != socks_socket_pools_.end(); | |
188 ++it) | |
189 it->second->CloseIdleSockets(); | |
190 | |
191 for (TransportSocketPoolMap::const_iterator it = | |
192 transport_socket_pools_for_socks_proxies_.begin(); | |
193 it != transport_socket_pools_for_socks_proxies_.end(); | |
194 ++it) | |
195 it->second->CloseIdleSockets(); | |
196 | |
197 ssl_socket_pool_->CloseIdleSockets(); | |
198 transport_socket_pool_->CloseIdleSockets(); | |
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(), | |
217 max_sockets_per_group(), | |
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(), | |
228 max_sockets_per_group(), | |
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(), | |
259 max_sockets_per_group(), | |
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(), | |
272 max_sockets_per_group(), | |
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( | |
281 std::make_pair( | |
282 http_proxy, | |
283 new SSLClientSocketPool( | |
284 max_sockets_per_proxy_server(), | |
285 max_sockets_per_group(), | |
286 &ssl_for_https_proxy_pool_histograms_, | |
287 host_resolver_, | |
288 cert_verifier_, | |
289 origin_bound_cert_service_, | |
290 dnsrr_resolver_, | |
291 dns_cert_checker_, | |
292 ssl_host_info_factory_, | |
293 socket_factory_, | |
294 tcp_https_ret.first->second /* https proxy */, | |
295 NULL /* no socks proxy */, | |
296 NULL /* no http proxy */, | |
297 ssl_config_service_, net_log_))); | |
298 DCHECK(tcp_https_ret.second); | |
299 | |
300 std::pair<HTTPProxySocketPoolMap::iterator, bool> ret = | |
301 http_proxy_socket_pools_.insert( | |
302 std::make_pair( | |
303 http_proxy, | |
304 new HttpProxyClientSocketPool( | |
305 max_sockets_per_proxy_server(), | |
306 max_sockets_per_group(), | |
307 &http_proxy_pool_histograms_, | |
308 host_resolver_, | |
309 tcp_http_ret.first->second, | |
310 ssl_https_ret.first->second, | |
311 net_log_))); | |
312 | |
313 return ret.first->second; | |
314 } | |
315 | |
316 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy( | |
317 const HostPortPair& proxy_server) { | |
318 SSLSocketPoolMap::const_iterator it = | |
319 ssl_socket_pools_for_proxies_.find(proxy_server); | |
320 if (it != ssl_socket_pools_for_proxies_.end()) | |
321 return it->second; | |
322 | |
323 SSLClientSocketPool* new_pool = new SSLClientSocketPool( | |
324 max_sockets_per_proxy_server(), max_sockets_per_group(), | |
325 &ssl_pool_histograms_, | |
326 host_resolver_, | |
327 cert_verifier_, | |
328 origin_bound_cert_service_, | |
329 dnsrr_resolver_, | |
330 dns_cert_checker_, | |
331 ssl_host_info_factory_, | |
332 socket_factory_, | |
333 NULL, /* no tcp pool, we always go through a proxy */ | |
334 GetSocketPoolForSOCKSProxy(proxy_server), | |
335 GetSocketPoolForHTTPProxy(proxy_server), | |
336 ssl_config_service_, | |
337 net_log_); | |
338 | |
339 std::pair<SSLSocketPoolMap::iterator, bool> ret = | |
340 ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server, | |
341 new_pool)); | |
342 | |
343 return ret.first->second; | |
344 } | |
345 | |
346 Value* ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const { | |
347 ListValue* list = new ListValue(); | |
348 list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool", | |
349 "transport_socket_pool", | |
350 false)); | |
351 // Third parameter is false because |ssl_socket_pool_| uses | |
352 // |transport_socket_pool_| internally, and do not want to add it a second | |
353 // time. | |
354 list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool", | |
355 "ssl_socket_pool", | |
356 false)); | |
357 AddSocketPoolsToList(list, | |
358 http_proxy_socket_pools_, | |
359 "http_proxy_socket_pool", | |
360 true); | |
361 AddSocketPoolsToList(list, | |
362 socks_socket_pools_, | |
363 "socks_socket_pool", | |
364 true); | |
365 | |
366 // Third parameter is false because |ssl_socket_pools_for_proxies_| use | |
367 // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|. | |
368 AddSocketPoolsToList(list, | |
369 ssl_socket_pools_for_proxies_, | |
370 "ssl_socket_pool_for_proxies", | |
371 false); | |
372 return list; | |
373 } | |
374 | |
375 void ClientSocketPoolManagerImpl::OnUserCertAdded(const X509Certificate* cert) { | |
376 FlushSocketPools(); | |
377 } | |
378 | |
379 void ClientSocketPoolManagerImpl::OnCertTrustChanged( | |
380 const X509Certificate* cert) { | |
381 // We should flush the socket pools if we removed trust from a | |
382 // cert, because a previously trusted server may have become | |
383 // untrusted. | |
384 // | |
385 // We should not flush the socket pools if we added trust to a | |
386 // cert. | |
387 // | |
388 // Since the OnCertTrustChanged method doesn't tell us what | |
389 // kind of trust change it is, we have to flush the socket | |
390 // pools to be safe. | |
391 FlushSocketPools(); | |
392 } | |
393 | |
394 } // namespace net | |
OLD | NEW |