OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/spdy_session_pool.h" | 5 #include "net/spdy/spdy_session_pool.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 18 matching lines...) Expand all Loading... | |
29 bool HostPortProxyPairsAreEqual(const HostPortProxyPair& a, | 29 bool HostPortProxyPairsAreEqual(const HostPortProxyPair& a, |
30 const HostPortProxyPair& b) { | 30 const HostPortProxyPair& b) { |
31 return a.first.Equals(b.first) && a.second == b.second; | 31 return a.first.Equals(b.first) && a.second == b.second; |
32 } | 32 } |
33 | 33 |
34 } | 34 } |
35 | 35 |
36 // The maximum number of sessions to open to a single domain. | 36 // The maximum number of sessions to open to a single domain. |
37 static const size_t kMaxSessionsPerDomain = 1; | 37 static const size_t kMaxSessionsPerDomain = 1; |
38 | 38 |
39 size_t SpdySessionPool::g_max_sessions_per_domain = kMaxSessionsPerDomain; | |
40 bool SpdySessionPool::g_force_single_domain = false; | |
41 bool SpdySessionPool::g_enable_ip_pooling = true; | |
42 | |
43 SpdySessionPool::SpdySessionPool( | 39 SpdySessionPool::SpdySessionPool( |
44 HostResolver* resolver, | 40 HostResolver* resolver, |
45 SSLConfigService* ssl_config_service, | 41 SSLConfigService* ssl_config_service, |
46 HttpServerProperties* http_server_properties, | 42 HttpServerProperties* http_server_properties, |
43 size_t max_sessions_per_domain, | |
44 bool force_single_domain, | |
45 bool enable_ip_pooling, | |
46 bool enable_credential_frames, | |
47 bool enable_compression, | |
48 bool enable_ping_based_connection_checking, | |
49 NextProto default_protocol, | |
50 size_t initial_recv_window_size, | |
51 size_t initial_max_concurrent_streams, | |
52 size_t max_concurrent_streams_limit, | |
53 SpdySessionPool::TimeFunc time_func, | |
47 const std::string& trusted_spdy_proxy) | 54 const std::string& trusted_spdy_proxy) |
48 : http_server_properties_(http_server_properties), | 55 : http_server_properties_(http_server_properties), |
49 ssl_config_service_(ssl_config_service), | 56 ssl_config_service_(ssl_config_service), |
50 resolver_(resolver), | 57 resolver_(resolver), |
51 verify_domain_authentication_(true), | 58 verify_domain_authentication_(true), |
52 enable_sending_initial_settings_(true), | 59 enable_sending_initial_settings_(true), |
60 max_sessions_per_domain_(max_sessions_per_domain == 0 ? | |
61 kMaxSessionsPerDomain : | |
62 max_sessions_per_domain), | |
63 force_single_domain_(force_single_domain), | |
64 enable_ip_pooling_(enable_ip_pooling), | |
65 enable_credential_frames_(enable_credential_frames), | |
66 enable_compression_(enable_compression), | |
67 enable_ping_based_connection_checking_( | |
68 enable_ping_based_connection_checking), | |
69 default_protocol_(default_protocol), | |
70 initial_recv_window_size_(initial_recv_window_size), | |
71 initial_max_concurrent_streams_(initial_max_concurrent_streams), | |
72 max_concurrent_streams_limit_(max_concurrent_streams_limit), | |
73 time_func_(time_func), | |
53 trusted_spdy_proxy_( | 74 trusted_spdy_proxy_( |
54 HostPortPair::FromString(trusted_spdy_proxy)) { | 75 HostPortPair::FromString(trusted_spdy_proxy)) { |
76 //DCHECK(!enable_compression_); | |
willchan no longer on Chromium
2012/12/01 20:49:13
Delete?
Ryan Hamilton
2012/12/01 23:02:25
Done.
| |
55 NetworkChangeNotifier::AddIPAddressObserver(this); | 77 NetworkChangeNotifier::AddIPAddressObserver(this); |
56 if (ssl_config_service_) | 78 if (ssl_config_service_) |
57 ssl_config_service_->AddObserver(this); | 79 ssl_config_service_->AddObserver(this); |
58 CertDatabase::GetInstance()->AddObserver(this); | 80 CertDatabase::GetInstance()->AddObserver(this); |
59 } | 81 } |
60 | 82 |
61 SpdySessionPool::~SpdySessionPool() { | 83 SpdySessionPool::~SpdySessionPool() { |
62 CloseAllSessions(); | 84 CloseAllSessions(); |
63 | 85 |
64 if (ssl_config_service_) | 86 if (ssl_config_service_) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 list->push_back(spdy_session); | 122 list->push_back(spdy_session); |
101 spdy_session->AddPooledAlias(host_port_proxy_pair); | 123 spdy_session->AddPooledAlias(host_port_proxy_pair); |
102 return spdy_session; | 124 return spdy_session; |
103 } else if (only_use_existing_sessions) { | 125 } else if (only_use_existing_sessions) { |
104 return NULL; | 126 return NULL; |
105 } | 127 } |
106 list = AddSessionList(host_port_proxy_pair); | 128 list = AddSessionList(host_port_proxy_pair); |
107 } | 129 } |
108 | 130 |
109 DCHECK(list); | 131 DCHECK(list); |
110 if (list->size() && list->size() == g_max_sessions_per_domain) { | 132 if (list->size() && list->size() == max_sessions_per_domain_) { |
111 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", | 133 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", |
112 FOUND_EXISTING, | 134 FOUND_EXISTING, |
113 SPDY_SESSION_GET_MAX); | 135 SPDY_SESSION_GET_MAX); |
114 spdy_session = GetExistingSession(list, net_log); | 136 spdy_session = GetExistingSession(list, net_log); |
115 net_log.AddEvent( | 137 net_log.AddEvent( |
116 NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION, | 138 NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION, |
117 spdy_session->net_log().source().ToEventParametersCallback()); | 139 spdy_session->net_log().source().ToEventParametersCallback()); |
118 return spdy_session; | 140 return spdy_session; |
119 } | 141 } |
120 | 142 |
121 DCHECK(!only_use_existing_sessions); | 143 DCHECK(!only_use_existing_sessions); |
122 | 144 |
123 spdy_session = new SpdySession(host_port_proxy_pair, this, | 145 spdy_session = new SpdySession(host_port_proxy_pair, this, |
124 http_server_properties_, | 146 http_server_properties_, |
125 verify_domain_authentication_, | 147 verify_domain_authentication_, |
126 enable_sending_initial_settings_, | 148 enable_sending_initial_settings_, |
149 enable_credential_frames_, | |
150 enable_compression_, | |
151 enable_ping_based_connection_checking_, | |
152 default_protocol_, | |
153 initial_recv_window_size_, | |
154 initial_max_concurrent_streams_, | |
155 max_concurrent_streams_limit_, | |
156 time_func_, | |
127 trusted_spdy_proxy_, | 157 trusted_spdy_proxy_, |
128 net_log.net_log()); | 158 net_log.net_log()); |
129 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", | 159 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", |
130 CREATED_NEW, | 160 CREATED_NEW, |
131 SPDY_SESSION_GET_MAX); | 161 SPDY_SESSION_GET_MAX); |
132 list->push_back(spdy_session); | 162 list->push_back(spdy_session); |
133 net_log.AddEvent( | 163 net_log.AddEvent( |
134 NetLog::TYPE_SPDY_SESSION_POOL_CREATED_NEW_SESSION, | 164 NetLog::TYPE_SPDY_SESSION_POOL_CREATED_NEW_SESSION, |
135 spdy_session->net_log().source().ToEventParametersCallback()); | 165 spdy_session->net_log().source().ToEventParametersCallback()); |
136 DCHECK_LE(list->size(), g_max_sessions_per_domain); | 166 DCHECK_LE(list->size(), max_sessions_per_domain_); |
137 return spdy_session; | 167 return spdy_session; |
138 } | 168 } |
139 | 169 |
140 net::Error SpdySessionPool::GetSpdySessionFromSocket( | 170 net::Error SpdySessionPool::GetSpdySessionFromSocket( |
141 const HostPortProxyPair& host_port_proxy_pair, | 171 const HostPortProxyPair& host_port_proxy_pair, |
142 ClientSocketHandle* connection, | 172 ClientSocketHandle* connection, |
143 const BoundNetLog& net_log, | 173 const BoundNetLog& net_log, |
144 int certificate_error_code, | 174 int certificate_error_code, |
145 scoped_refptr<SpdySession>* spdy_session, | 175 scoped_refptr<SpdySession>* spdy_session, |
146 bool is_secure) { | 176 bool is_secure) { |
147 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", | 177 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", |
148 IMPORTED_FROM_SOCKET, | 178 IMPORTED_FROM_SOCKET, |
149 SPDY_SESSION_GET_MAX); | 179 SPDY_SESSION_GET_MAX); |
150 // Create the SPDY session and add it to the pool. | 180 // Create the SPDY session and add it to the pool. |
151 *spdy_session = new SpdySession(host_port_proxy_pair, this, | 181 *spdy_session = new SpdySession(host_port_proxy_pair, this, |
152 http_server_properties_, | 182 http_server_properties_, |
153 verify_domain_authentication_, | 183 verify_domain_authentication_, |
154 enable_sending_initial_settings_, | 184 enable_sending_initial_settings_, |
185 enable_credential_frames_, | |
186 enable_compression_, | |
187 enable_ping_based_connection_checking_, | |
188 default_protocol_, | |
189 initial_recv_window_size_, | |
190 initial_max_concurrent_streams_, | |
191 max_concurrent_streams_limit_, | |
192 time_func_, | |
155 trusted_spdy_proxy_, | 193 trusted_spdy_proxy_, |
156 net_log.net_log()); | 194 net_log.net_log()); |
157 SpdySessionList* list = GetSessionList(host_port_proxy_pair); | 195 SpdySessionList* list = GetSessionList(host_port_proxy_pair); |
158 if (!list) | 196 if (!list) |
159 list = AddSessionList(host_port_proxy_pair); | 197 list = AddSessionList(host_port_proxy_pair); |
160 DCHECK(list->empty()); | 198 DCHECK(list->empty()); |
161 list->push_back(*spdy_session); | 199 list->push_back(*spdy_session); |
162 | 200 |
163 net_log.AddEvent( | 201 net_log.AddEvent( |
164 NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET, | 202 NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET, |
165 (*spdy_session)->net_log().source().ToEventParametersCallback()); | 203 (*spdy_session)->net_log().source().ToEventParametersCallback()); |
166 | 204 |
167 // We have a new session. Lookup the IP address for this session so that we | 205 // We have a new session. Lookup the IP address for this session so that we |
168 // can match future Sessions (potentially to different domains) which can | 206 // can match future Sessions (potentially to different domains) which can |
169 // potentially be pooled with this one. Because GetPeerAddress() reports the | 207 // potentially be pooled with this one. Because GetPeerAddress() reports the |
170 // proxy's address instead of the origin server, check to see if this is a | 208 // proxy's address instead of the origin server, check to see if this is a |
171 // direct connection. | 209 // direct connection. |
172 if (g_enable_ip_pooling && host_port_proxy_pair.second.is_direct()) { | 210 if (enable_ip_pooling_ && host_port_proxy_pair.second.is_direct()) { |
173 IPEndPoint address; | 211 IPEndPoint address; |
174 if (connection->socket()->GetPeerAddress(&address) == OK) | 212 if (connection->socket()->GetPeerAddress(&address) == OK) |
175 AddAlias(address, host_port_proxy_pair); | 213 AddAlias(address, host_port_proxy_pair); |
176 } | 214 } |
177 | 215 |
178 // Now we can initialize the session with the SSL socket. | 216 // Now we can initialize the session with the SSL socket. |
179 return (*spdy_session)->InitializeWithSocket(connection, is_secure, | 217 return (*spdy_session)->InitializeWithSocket(connection, is_secure, |
180 certificate_error_code); | 218 certificate_error_code); |
181 } | 219 } |
182 | 220 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 return spdy_session; | 298 return spdy_session; |
261 } | 299 } |
262 | 300 |
263 scoped_refptr<SpdySession> SpdySessionPool::GetFromAlias( | 301 scoped_refptr<SpdySession> SpdySessionPool::GetFromAlias( |
264 const HostPortProxyPair& host_port_proxy_pair, | 302 const HostPortProxyPair& host_port_proxy_pair, |
265 const BoundNetLog& net_log, | 303 const BoundNetLog& net_log, |
266 bool record_histograms) const { | 304 bool record_histograms) const { |
267 // We should only be checking aliases when there is no direct session. | 305 // We should only be checking aliases when there is no direct session. |
268 DCHECK(!GetSessionList(host_port_proxy_pair)); | 306 DCHECK(!GetSessionList(host_port_proxy_pair)); |
269 | 307 |
270 if (!g_enable_ip_pooling) | 308 if (!enable_ip_pooling_) |
271 return NULL; | 309 return NULL; |
272 | 310 |
273 AddressList addresses; | 311 AddressList addresses; |
274 if (!LookupAddresses(host_port_proxy_pair, net_log, &addresses)) | 312 if (!LookupAddresses(host_port_proxy_pair, net_log, &addresses)) |
275 return NULL; | 313 return NULL; |
276 for (AddressList::const_iterator iter = addresses.begin(); | 314 for (AddressList::const_iterator iter = addresses.begin(); |
277 iter != addresses.end(); | 315 iter != addresses.end(); |
278 ++iter) { | 316 ++iter) { |
279 SpdyAliasMap::const_iterator alias_iter = aliases_.find(*iter); | 317 SpdyAliasMap::const_iterator alias_iter = aliases_.find(*iter); |
280 if (alias_iter == aliases_.end()) | 318 if (alias_iter == aliases_.end()) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 void SpdySessionPool::OnCertTrustChanged(const X509Certificate* cert) { | 354 void SpdySessionPool::OnCertTrustChanged(const X509Certificate* cert) { |
317 // Per wtc, we actually only need to CloseCurrentSessions when trust is | 355 // Per wtc, we actually only need to CloseCurrentSessions when trust is |
318 // reduced. CloseCurrentSessions now because OnCertTrustChanged does not | 356 // reduced. CloseCurrentSessions now because OnCertTrustChanged does not |
319 // tell us this. | 357 // tell us this. |
320 // See comments in ClientSocketPoolManager::OnCertTrustChanged. | 358 // See comments in ClientSocketPoolManager::OnCertTrustChanged. |
321 CloseCurrentSessions(); | 359 CloseCurrentSessions(); |
322 } | 360 } |
323 | 361 |
324 const HostPortProxyPair& SpdySessionPool::NormalizeListPair( | 362 const HostPortProxyPair& SpdySessionPool::NormalizeListPair( |
325 const HostPortProxyPair& host_port_proxy_pair) const { | 363 const HostPortProxyPair& host_port_proxy_pair) const { |
326 if (!g_force_single_domain) | 364 if (!force_single_domain_) |
327 return host_port_proxy_pair; | 365 return host_port_proxy_pair; |
328 | 366 |
329 static HostPortProxyPair* single_domain_pair = NULL; | 367 static HostPortProxyPair* single_domain_pair = NULL; |
330 if (!single_domain_pair) { | 368 if (!single_domain_pair) { |
331 HostPortPair single_domain = HostPortPair("singledomain.com", 80); | 369 HostPortPair single_domain = HostPortPair("singledomain.com", 80); |
332 single_domain_pair = new HostPortProxyPair(single_domain, | 370 single_domain_pair = new HostPortProxyPair(single_domain, |
333 ProxyServer::Direct()); | 371 ProxyServer::Direct()); |
334 } | 372 } |
335 return *single_domain_pair; | 373 return *single_domain_pair; |
336 } | 374 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 const BoundNetLog& net_log, | 410 const BoundNetLog& net_log, |
373 AddressList* addresses) const { | 411 AddressList* addresses) const { |
374 net::HostResolver::RequestInfo resolve_info(pair.first); | 412 net::HostResolver::RequestInfo resolve_info(pair.first); |
375 int rv = resolver_->ResolveFromCache(resolve_info, addresses, net_log); | 413 int rv = resolver_->ResolveFromCache(resolve_info, addresses, net_log); |
376 DCHECK_NE(ERR_IO_PENDING, rv); | 414 DCHECK_NE(ERR_IO_PENDING, rv); |
377 return rv == OK; | 415 return rv == OK; |
378 } | 416 } |
379 | 417 |
380 void SpdySessionPool::AddAlias(const IPEndPoint& endpoint, | 418 void SpdySessionPool::AddAlias(const IPEndPoint& endpoint, |
381 const HostPortProxyPair& pair) { | 419 const HostPortProxyPair& pair) { |
382 DCHECK(g_enable_ip_pooling); | 420 DCHECK(enable_ip_pooling_); |
383 aliases_[endpoint] = pair; | 421 aliases_[endpoint] = pair; |
384 } | 422 } |
385 | 423 |
386 void SpdySessionPool::RemoveAliases(const HostPortProxyPair& pair) { | 424 void SpdySessionPool::RemoveAliases(const HostPortProxyPair& pair) { |
387 // Walk the aliases map, find references to this pair. | 425 // Walk the aliases map, find references to this pair. |
388 // TODO(mbelshe): Figure out if this is too expensive. | 426 // TODO(mbelshe): Figure out if this is too expensive. |
389 SpdyAliasMap::iterator alias_it = aliases_.begin(); | 427 SpdyAliasMap::iterator alias_it = aliases_.begin(); |
390 while (alias_it != aliases_.end()) { | 428 while (alias_it != aliases_.end()) { |
391 if (HostPortProxyPairsAreEqual(alias_it->second, pair)) { | 429 if (HostPortProxyPairsAreEqual(alias_it->second, pair)) { |
392 aliases_.erase(alias_it); | 430 aliases_.erase(alias_it); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 const scoped_refptr<SpdySession>& session = *session_it; | 490 const scoped_refptr<SpdySession>& session = *session_it; |
453 CHECK(session); | 491 CHECK(session); |
454 if (!session->is_active()) { | 492 if (!session->is_active()) { |
455 session->CloseSessionOnError( | 493 session->CloseSessionOnError( |
456 net::ERR_ABORTED, true, "Closing idle sessions."); | 494 net::ERR_ABORTED, true, "Closing idle sessions."); |
457 } | 495 } |
458 } | 496 } |
459 } | 497 } |
460 | 498 |
461 } // namespace net | 499 } // namespace net |
OLD | NEW |