OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/logging.h" | 7 #include "base/logging.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "net/base/address_list.h" | 10 #include "net/base/address_list.h" |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 if (!list) | 140 if (!list) |
141 list = AddSessionList(host_port_proxy_pair); | 141 list = AddSessionList(host_port_proxy_pair); |
142 DCHECK(list->empty()); | 142 DCHECK(list->empty()); |
143 list->push_back(*spdy_session); | 143 list->push_back(*spdy_session); |
144 | 144 |
145 net_log.AddEvent( | 145 net_log.AddEvent( |
146 NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET, | 146 NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET, |
147 make_scoped_refptr(new NetLogSourceParameter( | 147 make_scoped_refptr(new NetLogSourceParameter( |
148 "session", (*spdy_session)->net_log().source()))); | 148 "session", (*spdy_session)->net_log().source()))); |
149 | 149 |
| 150 // We have a new session. Lookup the IP address for this session so that we |
| 151 // can match future Sessions (potentially to different domains) which can |
| 152 // potentially be pooled with this one. Because GetPeerAddress() reports the |
| 153 // proxy's address instead of the origin server, check to see if this is a |
| 154 // direct connection. |
| 155 if (g_enable_ip_pooling && host_port_proxy_pair.second.is_direct()) { |
| 156 AddressList addresses; |
| 157 if (connection->socket()->GetPeerAddress(&addresses) == OK) { |
| 158 const addrinfo* address = addresses.head(); |
| 159 AddAlias(address, host_port_proxy_pair); |
| 160 } |
| 161 } |
| 162 |
150 // Now we can initialize the session with the SSL socket. | 163 // Now we can initialize the session with the SSL socket. |
151 return (*spdy_session)->InitializeWithSocket(connection, is_secure, | 164 return (*spdy_session)->InitializeWithSocket(connection, is_secure, |
152 certificate_error_code); | 165 certificate_error_code); |
153 } | 166 } |
154 | 167 |
155 bool SpdySessionPool::HasSession( | 168 bool SpdySessionPool::HasSession( |
156 const HostPortProxyPair& host_port_proxy_pair) const { | 169 const HostPortProxyPair& host_port_proxy_pair) const { |
157 if (GetSessionList(host_port_proxy_pair)) | 170 if (GetSessionList(host_port_proxy_pair)) |
158 return true; | 171 return true; |
159 | 172 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 return *single_domain_pair; | 306 return *single_domain_pair; |
294 } | 307 } |
295 | 308 |
296 SpdySessionPool::SpdySessionList* | 309 SpdySessionPool::SpdySessionList* |
297 SpdySessionPool::AddSessionList( | 310 SpdySessionPool::AddSessionList( |
298 const HostPortProxyPair& host_port_proxy_pair) { | 311 const HostPortProxyPair& host_port_proxy_pair) { |
299 const HostPortProxyPair& pair = NormalizeListPair(host_port_proxy_pair); | 312 const HostPortProxyPair& pair = NormalizeListPair(host_port_proxy_pair); |
300 DCHECK(sessions_.find(pair) == sessions_.end()); | 313 DCHECK(sessions_.find(pair) == sessions_.end()); |
301 SpdySessionPool::SpdySessionList* list = new SpdySessionList(); | 314 SpdySessionPool::SpdySessionList* list = new SpdySessionList(); |
302 sessions_[pair] = list; | 315 sessions_[pair] = list; |
303 | |
304 // We have a new session. Lookup the IP addresses for this session so that | |
305 // we can match future Sessions (potentially to different domains) which can | |
306 // potentially be pooled with this one. | |
307 if (g_enable_ip_pooling) { | |
308 AddressList addresses; | |
309 if (LookupAddresses(host_port_proxy_pair, &addresses)) | |
310 AddAliases(addresses, host_port_proxy_pair); | |
311 } | |
312 | |
313 return list; | 316 return list; |
314 } | 317 } |
315 | 318 |
316 SpdySessionPool::SpdySessionList* | 319 SpdySessionPool::SpdySessionList* |
317 SpdySessionPool::GetSessionList( | 320 SpdySessionPool::GetSessionList( |
318 const HostPortProxyPair& host_port_proxy_pair) const { | 321 const HostPortProxyPair& host_port_proxy_pair) const { |
319 const HostPortProxyPair& pair = NormalizeListPair(host_port_proxy_pair); | 322 const HostPortProxyPair& pair = NormalizeListPair(host_port_proxy_pair); |
320 SpdySessionsMap::const_iterator it = sessions_.find(pair); | 323 SpdySessionsMap::const_iterator it = sessions_.find(pair); |
321 if (it != sessions_.end()) | 324 if (it != sessions_.end()) |
322 return it->second; | 325 return it->second; |
(...skipping 19 matching lines...) Expand all Loading... |
342 resolve_info.set_only_use_cached_response(true); | 345 resolve_info.set_only_use_cached_response(true); |
343 int rv = resolver_->Resolve(resolve_info, | 346 int rv = resolver_->Resolve(resolve_info, |
344 addresses, | 347 addresses, |
345 NULL, | 348 NULL, |
346 NULL, | 349 NULL, |
347 net::BoundNetLog()); | 350 net::BoundNetLog()); |
348 DCHECK_NE(ERR_IO_PENDING, rv); | 351 DCHECK_NE(ERR_IO_PENDING, rv); |
349 return rv == OK; | 352 return rv == OK; |
350 } | 353 } |
351 | 354 |
352 void SpdySessionPool::AddAliases(const AddressList& addresses, | 355 void SpdySessionPool::AddAlias(const addrinfo* address, |
353 const HostPortProxyPair& pair) { | 356 const HostPortProxyPair& pair) { |
354 // Note: it is possible to think of strange overlapping sets of ip addresses | 357 DCHECK(g_enable_ip_pooling); |
355 // for hosts such that a new session can override the alias for an IP | 358 DCHECK(address); |
356 // address that was previously aliased to a different host. This is probably | 359 IPEndPoint endpoint; |
357 // undesirable, but seemingly unlikely and complicated to fix. | 360 endpoint.FromSockAddr(address->ai_addr, address->ai_addrlen); |
358 // Example: | 361 aliases_[endpoint] = pair; |
359 // host1 = 1.1.1.1, 1.1.1.4 | |
360 // host2 = 1.1.1.4, 1.1.1.5 | |
361 // host3 = 1.1.1.3, 1.1.1.5 | |
362 // Creating session1 (to host1), creates an alias for host2 to host1. | |
363 // Creating session2 (to host3), overrides the alias for host2 to host3. | |
364 | |
365 const addrinfo* address = addresses.head(); | |
366 while (address) { | |
367 IPEndPoint endpoint; | |
368 endpoint.FromSockAddr(address->ai_addr, address->ai_addrlen); | |
369 aliases_[endpoint] = pair; | |
370 address = address->ai_next; | |
371 } | |
372 } | 362 } |
373 | 363 |
374 void SpdySessionPool::RemoveAliases(const HostPortProxyPair& pair) { | 364 void SpdySessionPool::RemoveAliases(const HostPortProxyPair& pair) { |
375 // Walk the aliases map, find references to this pair. | 365 // Walk the aliases map, find references to this pair. |
376 // TODO(mbelshe): Figure out if this is too expensive. | 366 // TODO(mbelshe): Figure out if this is too expensive. |
377 SpdyAliasMap::iterator alias_it = aliases_.begin(); | 367 SpdyAliasMap::iterator alias_it = aliases_.begin(); |
378 while (alias_it != aliases_.end()) { | 368 while (alias_it != aliases_.end()) { |
379 if (HostPortProxyPairsAreEqual(alias_it->second, pair)) { | 369 if (HostPortProxyPairsAreEqual(alias_it->second, pair)) { |
380 aliases_.erase(alias_it); | 370 aliases_.erase(alias_it); |
381 alias_it = aliases_.begin(); // Iterator was invalidated. | 371 alias_it = aliases_.begin(); // Iterator was invalidated. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 delete list; | 410 delete list; |
421 RemoveAliases(old_map.begin()->first); | 411 RemoveAliases(old_map.begin()->first); |
422 old_map.erase(old_map.begin()->first); | 412 old_map.erase(old_map.begin()->first); |
423 } | 413 } |
424 } | 414 } |
425 DCHECK(sessions_.empty()); | 415 DCHECK(sessions_.empty()); |
426 DCHECK(aliases_.empty()); | 416 DCHECK(aliases_.empty()); |
427 } | 417 } |
428 | 418 |
429 } // namespace net | 419 } // namespace net |
OLD | NEW |