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