OLD | NEW |
| (Empty) |
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/transport_client_socket_pool.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/compiler_specific.h" | |
10 #include "base/lazy_instance.h" | |
11 #include "base/logging.h" | |
12 #include "base/message_loop/message_loop.h" | |
13 #include "base/metrics/histogram.h" | |
14 #include "base/strings/string_util.h" | |
15 #include "base/synchronization/lock.h" | |
16 #include "base/time/time.h" | |
17 #include "base/values.h" | |
18 #include "net/base/ip_endpoint.h" | |
19 #include "net/base/net_errors.h" | |
20 #include "net/base/net_log.h" | |
21 #include "net/socket/client_socket_factory.h" | |
22 #include "net/socket/client_socket_handle.h" | |
23 #include "net/socket/client_socket_pool_base.h" | |
24 #include "net/socket/socket_net_log_params.h" | |
25 #include "net/socket/tcp_client_socket.h" | |
26 | |
27 using base::TimeDelta; | |
28 | |
29 namespace net { | |
30 | |
31 // TODO(willchan): Base this off RTT instead of statically setting it. Note we | |
32 // choose a timeout that is different from the backup connect job timer so they | |
33 // don't synchronize. | |
34 const int TransportConnectJobHelper::kIPv6FallbackTimerInMs = 300; | |
35 | |
36 namespace { | |
37 | |
38 // Returns true iff all addresses in |list| are in the IPv6 family. | |
39 bool AddressListOnlyContainsIPv6(const AddressList& list) { | |
40 DCHECK(!list.empty()); | |
41 for (AddressList::const_iterator iter = list.begin(); iter != list.end(); | |
42 ++iter) { | |
43 if (iter->GetFamily() != ADDRESS_FAMILY_IPV6) | |
44 return false; | |
45 } | |
46 return true; | |
47 } | |
48 | |
49 } // namespace | |
50 | |
51 // This lock protects |g_last_connect_time|. | |
52 static base::LazyInstance<base::Lock>::Leaky | |
53 g_last_connect_time_lock = LAZY_INSTANCE_INITIALIZER; | |
54 | |
55 // |g_last_connect_time| has the last time a connect() call is made. | |
56 static base::LazyInstance<base::TimeTicks>::Leaky | |
57 g_last_connect_time = LAZY_INSTANCE_INITIALIZER; | |
58 | |
59 TransportSocketParams::TransportSocketParams( | |
60 const HostPortPair& host_port_pair, | |
61 bool disable_resolver_cache, | |
62 bool ignore_limits, | |
63 const OnHostResolutionCallback& host_resolution_callback, | |
64 CombineConnectAndWritePolicy combine_connect_and_write_if_supported) | |
65 : destination_(host_port_pair), | |
66 ignore_limits_(ignore_limits), | |
67 host_resolution_callback_(host_resolution_callback), | |
68 combine_connect_and_write_(combine_connect_and_write_if_supported) { | |
69 if (disable_resolver_cache) | |
70 destination_.set_allow_cached_response(false); | |
71 // combine_connect_and_write currently translates to TCP FastOpen. | |
72 // Enable TCP FastOpen if user wants it. | |
73 if (combine_connect_and_write_ == COMBINE_CONNECT_AND_WRITE_DEFAULT) { | |
74 IsTCPFastOpenUserEnabled() ? combine_connect_and_write_ = | |
75 COMBINE_CONNECT_AND_WRITE_DESIRED : | |
76 COMBINE_CONNECT_AND_WRITE_PROHIBITED; | |
77 } | |
78 } | |
79 | |
80 TransportSocketParams::~TransportSocketParams() {} | |
81 | |
82 // TransportConnectJobs will time out after this many seconds. Note this is | |
83 // the total time, including both host resolution and TCP connect() times. | |
84 // | |
85 // TODO(eroman): The use of this constant needs to be re-evaluated. The time | |
86 // needed for TCPClientSocketXXX::Connect() can be arbitrarily long, since | |
87 // the address list may contain many alternatives, and most of those may | |
88 // timeout. Even worse, the per-connect timeout threshold varies greatly | |
89 // between systems (anywhere from 20 seconds to 190 seconds). | |
90 // See comment #12 at http://crbug.com/23364 for specifics. | |
91 static const int kTransportConnectJobTimeoutInSeconds = 240; // 4 minutes. | |
92 | |
93 TransportConnectJobHelper::TransportConnectJobHelper( | |
94 const scoped_refptr<TransportSocketParams>& params, | |
95 ClientSocketFactory* client_socket_factory, | |
96 HostResolver* host_resolver, | |
97 LoadTimingInfo::ConnectTiming* connect_timing) | |
98 : params_(params), | |
99 client_socket_factory_(client_socket_factory), | |
100 resolver_(host_resolver), | |
101 next_state_(STATE_NONE), | |
102 connect_timing_(connect_timing) {} | |
103 | |
104 TransportConnectJobHelper::~TransportConnectJobHelper() {} | |
105 | |
106 int TransportConnectJobHelper::DoResolveHost(RequestPriority priority, | |
107 const BoundNetLog& net_log) { | |
108 next_state_ = STATE_RESOLVE_HOST_COMPLETE; | |
109 connect_timing_->dns_start = base::TimeTicks::Now(); | |
110 | |
111 return resolver_.Resolve( | |
112 params_->destination(), priority, &addresses_, on_io_complete_, net_log); | |
113 } | |
114 | |
115 int TransportConnectJobHelper::DoResolveHostComplete( | |
116 int result, | |
117 const BoundNetLog& net_log) { | |
118 connect_timing_->dns_end = base::TimeTicks::Now(); | |
119 // Overwrite connection start time, since for connections that do not go | |
120 // through proxies, |connect_start| should not include dns lookup time. | |
121 connect_timing_->connect_start = connect_timing_->dns_end; | |
122 | |
123 if (result == OK) { | |
124 // Invoke callback, and abort if it fails. | |
125 if (!params_->host_resolution_callback().is_null()) | |
126 result = params_->host_resolution_callback().Run(addresses_, net_log); | |
127 | |
128 if (result == OK) | |
129 next_state_ = STATE_TRANSPORT_CONNECT; | |
130 } | |
131 return result; | |
132 } | |
133 | |
134 base::TimeDelta TransportConnectJobHelper::HistogramDuration( | |
135 ConnectionLatencyHistogram race_result) { | |
136 DCHECK(!connect_timing_->connect_start.is_null()); | |
137 DCHECK(!connect_timing_->dns_start.is_null()); | |
138 base::TimeTicks now = base::TimeTicks::Now(); | |
139 base::TimeDelta total_duration = now - connect_timing_->dns_start; | |
140 UMA_HISTOGRAM_CUSTOM_TIMES("Net.DNS_Resolution_And_TCP_Connection_Latency2", | |
141 total_duration, | |
142 base::TimeDelta::FromMilliseconds(1), | |
143 base::TimeDelta::FromMinutes(10), | |
144 100); | |
145 | |
146 base::TimeDelta connect_duration = now - connect_timing_->connect_start; | |
147 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency", | |
148 connect_duration, | |
149 base::TimeDelta::FromMilliseconds(1), | |
150 base::TimeDelta::FromMinutes(10), | |
151 100); | |
152 | |
153 switch (race_result) { | |
154 case CONNECTION_LATENCY_IPV4_WINS_RACE: | |
155 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv4_Wins_Race", | |
156 connect_duration, | |
157 base::TimeDelta::FromMilliseconds(1), | |
158 base::TimeDelta::FromMinutes(10), | |
159 100); | |
160 break; | |
161 | |
162 case CONNECTION_LATENCY_IPV4_NO_RACE: | |
163 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv4_No_Race", | |
164 connect_duration, | |
165 base::TimeDelta::FromMilliseconds(1), | |
166 base::TimeDelta::FromMinutes(10), | |
167 100); | |
168 break; | |
169 | |
170 case CONNECTION_LATENCY_IPV6_RACEABLE: | |
171 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Raceable", | |
172 connect_duration, | |
173 base::TimeDelta::FromMilliseconds(1), | |
174 base::TimeDelta::FromMinutes(10), | |
175 100); | |
176 break; | |
177 | |
178 case CONNECTION_LATENCY_IPV6_SOLO: | |
179 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Solo", | |
180 connect_duration, | |
181 base::TimeDelta::FromMilliseconds(1), | |
182 base::TimeDelta::FromMinutes(10), | |
183 100); | |
184 break; | |
185 | |
186 default: | |
187 NOTREACHED(); | |
188 break; | |
189 } | |
190 | |
191 return connect_duration; | |
192 } | |
193 | |
194 TransportConnectJob::TransportConnectJob( | |
195 const std::string& group_name, | |
196 RequestPriority priority, | |
197 const scoped_refptr<TransportSocketParams>& params, | |
198 base::TimeDelta timeout_duration, | |
199 ClientSocketFactory* client_socket_factory, | |
200 HostResolver* host_resolver, | |
201 Delegate* delegate, | |
202 NetLog* net_log) | |
203 : ConnectJob(group_name, timeout_duration, priority, delegate, | |
204 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), | |
205 helper_(params, client_socket_factory, host_resolver, &connect_timing_), | |
206 interval_between_connects_(CONNECT_INTERVAL_GT_20MS) { | |
207 helper_.SetOnIOComplete(this); | |
208 } | |
209 | |
210 TransportConnectJob::~TransportConnectJob() { | |
211 // We don't worry about cancelling the host resolution and TCP connect, since | |
212 // ~SingleRequestHostResolver and ~StreamSocket will take care of it. | |
213 } | |
214 | |
215 LoadState TransportConnectJob::GetLoadState() const { | |
216 switch (helper_.next_state()) { | |
217 case TransportConnectJobHelper::STATE_RESOLVE_HOST: | |
218 case TransportConnectJobHelper::STATE_RESOLVE_HOST_COMPLETE: | |
219 return LOAD_STATE_RESOLVING_HOST; | |
220 case TransportConnectJobHelper::STATE_TRANSPORT_CONNECT: | |
221 case TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE: | |
222 return LOAD_STATE_CONNECTING; | |
223 case TransportConnectJobHelper::STATE_NONE: | |
224 return LOAD_STATE_IDLE; | |
225 } | |
226 NOTREACHED(); | |
227 return LOAD_STATE_IDLE; | |
228 } | |
229 | |
230 // static | |
231 void TransportConnectJob::MakeAddressListStartWithIPv4(AddressList* list) { | |
232 for (AddressList::iterator i = list->begin(); i != list->end(); ++i) { | |
233 if (i->GetFamily() == ADDRESS_FAMILY_IPV4) { | |
234 std::rotate(list->begin(), i, list->end()); | |
235 break; | |
236 } | |
237 } | |
238 } | |
239 | |
240 int TransportConnectJob::DoResolveHost() { | |
241 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed. | |
242 tracked_objects::ScopedTracker tracking_profile( | |
243 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
244 "436634 TransportConnectJob::DoResolveHost")); | |
245 | |
246 return helper_.DoResolveHost(priority(), net_log()); | |
247 } | |
248 | |
249 int TransportConnectJob::DoResolveHostComplete(int result) { | |
250 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed. | |
251 tracked_objects::ScopedTracker tracking_profile( | |
252 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
253 "436634 TransportConnectJob::DoResolveHostComplete")); | |
254 | |
255 return helper_.DoResolveHostComplete(result, net_log()); | |
256 } | |
257 | |
258 int TransportConnectJob::DoTransportConnect() { | |
259 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed. | |
260 tracked_objects::ScopedTracker tracking_profile( | |
261 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
262 "436634 TransportConnectJob::DoTransportConnect")); | |
263 | |
264 base::TimeTicks now = base::TimeTicks::Now(); | |
265 base::TimeTicks last_connect_time; | |
266 { | |
267 base::AutoLock lock(g_last_connect_time_lock.Get()); | |
268 last_connect_time = g_last_connect_time.Get(); | |
269 *g_last_connect_time.Pointer() = now; | |
270 } | |
271 if (last_connect_time.is_null()) { | |
272 interval_between_connects_ = CONNECT_INTERVAL_GT_20MS; | |
273 } else { | |
274 int64 interval = (now - last_connect_time).InMilliseconds(); | |
275 if (interval <= 10) | |
276 interval_between_connects_ = CONNECT_INTERVAL_LE_10MS; | |
277 else if (interval <= 20) | |
278 interval_between_connects_ = CONNECT_INTERVAL_LE_20MS; | |
279 else | |
280 interval_between_connects_ = CONNECT_INTERVAL_GT_20MS; | |
281 } | |
282 | |
283 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed. | |
284 tracked_objects::ScopedTracker tracking_profile1( | |
285 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
286 "436634 TransportConnectJob::DoTransportConnect1")); | |
287 | |
288 helper_.set_next_state( | |
289 TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE); | |
290 transport_socket_ = | |
291 helper_.client_socket_factory()->CreateTransportClientSocket( | |
292 helper_.addresses(), net_log().net_log(), net_log().source()); | |
293 | |
294 // If the list contains IPv6 and IPv4 addresses, the first address will | |
295 // be IPv6, and the IPv4 addresses will be tried as fallback addresses, | |
296 // per "Happy Eyeballs" (RFC 6555). | |
297 bool try_ipv6_connect_with_ipv4_fallback = | |
298 helper_.addresses().front().GetFamily() == ADDRESS_FAMILY_IPV6 && | |
299 !AddressListOnlyContainsIPv6(helper_.addresses()); | |
300 | |
301 // Enable TCP FastOpen if indicated by transport socket params. | |
302 // Note: We currently do not turn on TCP FastOpen for destinations where | |
303 // we try a TCP connect over IPv6 with fallback to IPv4. | |
304 if (!try_ipv6_connect_with_ipv4_fallback && | |
305 helper_.params()->combine_connect_and_write() == | |
306 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DESIRED) { | |
307 transport_socket_->EnableTCPFastOpenIfSupported(); | |
308 } | |
309 | |
310 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed. | |
311 tracked_objects::ScopedTracker tracking_profile2( | |
312 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
313 "436634 TransportConnectJob::DoTransportConnect2")); | |
314 | |
315 int rv = transport_socket_->Connect(helper_.on_io_complete()); | |
316 | |
317 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed. | |
318 tracked_objects::ScopedTracker tracking_profile3( | |
319 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
320 "436634 TransportConnectJob::DoTransportConnect3")); | |
321 | |
322 if (rv == ERR_IO_PENDING && try_ipv6_connect_with_ipv4_fallback) { | |
323 fallback_timer_.Start( | |
324 FROM_HERE, | |
325 base::TimeDelta::FromMilliseconds( | |
326 TransportConnectJobHelper::kIPv6FallbackTimerInMs), | |
327 this, | |
328 &TransportConnectJob::DoIPv6FallbackTransportConnect); | |
329 } | |
330 return rv; | |
331 } | |
332 | |
333 int TransportConnectJob::DoTransportConnectComplete(int result) { | |
334 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed. | |
335 tracked_objects::ScopedTracker tracking_profile( | |
336 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
337 "436634 TransportConnectJob::DoTransportConnectComplete")); | |
338 | |
339 if (result == OK) { | |
340 bool is_ipv4 = | |
341 helper_.addresses().front().GetFamily() == ADDRESS_FAMILY_IPV4; | |
342 TransportConnectJobHelper::ConnectionLatencyHistogram race_result = | |
343 TransportConnectJobHelper::CONNECTION_LATENCY_UNKNOWN; | |
344 if (is_ipv4) { | |
345 race_result = TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_NO_RACE; | |
346 } else { | |
347 if (AddressListOnlyContainsIPv6(helper_.addresses())) { | |
348 race_result = TransportConnectJobHelper::CONNECTION_LATENCY_IPV6_SOLO; | |
349 } else { | |
350 race_result = | |
351 TransportConnectJobHelper::CONNECTION_LATENCY_IPV6_RACEABLE; | |
352 } | |
353 } | |
354 base::TimeDelta connect_duration = helper_.HistogramDuration(race_result); | |
355 switch (interval_between_connects_) { | |
356 case CONNECT_INTERVAL_LE_10MS: | |
357 UMA_HISTOGRAM_CUSTOM_TIMES( | |
358 "Net.TCP_Connection_Latency_Interval_LessThanOrEqual_10ms", | |
359 connect_duration, | |
360 base::TimeDelta::FromMilliseconds(1), | |
361 base::TimeDelta::FromMinutes(10), | |
362 100); | |
363 break; | |
364 case CONNECT_INTERVAL_LE_20MS: | |
365 UMA_HISTOGRAM_CUSTOM_TIMES( | |
366 "Net.TCP_Connection_Latency_Interval_LessThanOrEqual_20ms", | |
367 connect_duration, | |
368 base::TimeDelta::FromMilliseconds(1), | |
369 base::TimeDelta::FromMinutes(10), | |
370 100); | |
371 break; | |
372 case CONNECT_INTERVAL_GT_20MS: | |
373 UMA_HISTOGRAM_CUSTOM_TIMES( | |
374 "Net.TCP_Connection_Latency_Interval_GreaterThan_20ms", | |
375 connect_duration, | |
376 base::TimeDelta::FromMilliseconds(1), | |
377 base::TimeDelta::FromMinutes(10), | |
378 100); | |
379 break; | |
380 default: | |
381 NOTREACHED(); | |
382 break; | |
383 } | |
384 | |
385 SetSocket(transport_socket_.Pass()); | |
386 fallback_timer_.Stop(); | |
387 } else { | |
388 // Be a bit paranoid and kill off the fallback members to prevent reuse. | |
389 fallback_transport_socket_.reset(); | |
390 fallback_addresses_.reset(); | |
391 } | |
392 | |
393 return result; | |
394 } | |
395 | |
396 void TransportConnectJob::DoIPv6FallbackTransportConnect() { | |
397 // The timer should only fire while we're waiting for the main connect to | |
398 // succeed. | |
399 if (helper_.next_state() != | |
400 TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE) { | |
401 NOTREACHED(); | |
402 return; | |
403 } | |
404 | |
405 DCHECK(!fallback_transport_socket_.get()); | |
406 DCHECK(!fallback_addresses_.get()); | |
407 | |
408 fallback_addresses_.reset(new AddressList(helper_.addresses())); | |
409 MakeAddressListStartWithIPv4(fallback_addresses_.get()); | |
410 fallback_transport_socket_ = | |
411 helper_.client_socket_factory()->CreateTransportClientSocket( | |
412 *fallback_addresses_, net_log().net_log(), net_log().source()); | |
413 fallback_connect_start_time_ = base::TimeTicks::Now(); | |
414 int rv = fallback_transport_socket_->Connect( | |
415 base::Bind( | |
416 &TransportConnectJob::DoIPv6FallbackTransportConnectComplete, | |
417 base::Unretained(this))); | |
418 if (rv != ERR_IO_PENDING) | |
419 DoIPv6FallbackTransportConnectComplete(rv); | |
420 } | |
421 | |
422 void TransportConnectJob::DoIPv6FallbackTransportConnectComplete(int result) { | |
423 // This should only happen when we're waiting for the main connect to succeed. | |
424 if (helper_.next_state() != | |
425 TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE) { | |
426 NOTREACHED(); | |
427 return; | |
428 } | |
429 | |
430 DCHECK_NE(ERR_IO_PENDING, result); | |
431 DCHECK(fallback_transport_socket_.get()); | |
432 DCHECK(fallback_addresses_.get()); | |
433 | |
434 if (result == OK) { | |
435 DCHECK(!fallback_connect_start_time_.is_null()); | |
436 connect_timing_.connect_start = fallback_connect_start_time_; | |
437 helper_.HistogramDuration( | |
438 TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_WINS_RACE); | |
439 SetSocket(fallback_transport_socket_.Pass()); | |
440 helper_.set_next_state(TransportConnectJobHelper::STATE_NONE); | |
441 transport_socket_.reset(); | |
442 } else { | |
443 // Be a bit paranoid and kill off the fallback members to prevent reuse. | |
444 fallback_transport_socket_.reset(); | |
445 fallback_addresses_.reset(); | |
446 } | |
447 NotifyDelegateOfCompletion(result); // Deletes |this| | |
448 } | |
449 | |
450 int TransportConnectJob::ConnectInternal() { | |
451 return helper_.DoConnectInternal(this); | |
452 } | |
453 | |
454 scoped_ptr<ConnectJob> | |
455 TransportClientSocketPool::TransportConnectJobFactory::NewConnectJob( | |
456 const std::string& group_name, | |
457 const PoolBase::Request& request, | |
458 ConnectJob::Delegate* delegate) const { | |
459 return scoped_ptr<ConnectJob>( | |
460 new TransportConnectJob(group_name, | |
461 request.priority(), | |
462 request.params(), | |
463 ConnectionTimeout(), | |
464 client_socket_factory_, | |
465 host_resolver_, | |
466 delegate, | |
467 net_log_)); | |
468 } | |
469 | |
470 base::TimeDelta | |
471 TransportClientSocketPool::TransportConnectJobFactory::ConnectionTimeout() | |
472 const { | |
473 return base::TimeDelta::FromSeconds(kTransportConnectJobTimeoutInSeconds); | |
474 } | |
475 | |
476 TransportClientSocketPool::TransportClientSocketPool( | |
477 int max_sockets, | |
478 int max_sockets_per_group, | |
479 ClientSocketPoolHistograms* histograms, | |
480 HostResolver* host_resolver, | |
481 ClientSocketFactory* client_socket_factory, | |
482 NetLog* net_log) | |
483 : base_(NULL, max_sockets, max_sockets_per_group, histograms, | |
484 ClientSocketPool::unused_idle_socket_timeout(), | |
485 ClientSocketPool::used_idle_socket_timeout(), | |
486 new TransportConnectJobFactory(client_socket_factory, | |
487 host_resolver, net_log)) { | |
488 base_.EnableConnectBackupJobs(); | |
489 } | |
490 | |
491 TransportClientSocketPool::~TransportClientSocketPool() {} | |
492 | |
493 int TransportClientSocketPool::RequestSocket( | |
494 const std::string& group_name, | |
495 const void* params, | |
496 RequestPriority priority, | |
497 ClientSocketHandle* handle, | |
498 const CompletionCallback& callback, | |
499 const BoundNetLog& net_log) { | |
500 const scoped_refptr<TransportSocketParams>* casted_params = | |
501 static_cast<const scoped_refptr<TransportSocketParams>*>(params); | |
502 | |
503 NetLogTcpClientSocketPoolRequestedSocket(net_log, casted_params); | |
504 | |
505 return base_.RequestSocket(group_name, *casted_params, priority, handle, | |
506 callback, net_log); | |
507 } | |
508 | |
509 void TransportClientSocketPool::NetLogTcpClientSocketPoolRequestedSocket( | |
510 const BoundNetLog& net_log, | |
511 const scoped_refptr<TransportSocketParams>* casted_params) { | |
512 if (net_log.IsLogging()) { | |
513 // TODO(eroman): Split out the host and port parameters. | |
514 net_log.AddEvent( | |
515 NetLog::TYPE_TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET, | |
516 CreateNetLogHostPortPairCallback( | |
517 &casted_params->get()->destination().host_port_pair())); | |
518 } | |
519 } | |
520 | |
521 void TransportClientSocketPool::RequestSockets( | |
522 const std::string& group_name, | |
523 const void* params, | |
524 int num_sockets, | |
525 const BoundNetLog& net_log) { | |
526 const scoped_refptr<TransportSocketParams>* casted_params = | |
527 static_cast<const scoped_refptr<TransportSocketParams>*>(params); | |
528 | |
529 if (net_log.IsLogging()) { | |
530 // TODO(eroman): Split out the host and port parameters. | |
531 net_log.AddEvent( | |
532 NetLog::TYPE_TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKETS, | |
533 CreateNetLogHostPortPairCallback( | |
534 &casted_params->get()->destination().host_port_pair())); | |
535 } | |
536 | |
537 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log); | |
538 } | |
539 | |
540 void TransportClientSocketPool::CancelRequest( | |
541 const std::string& group_name, | |
542 ClientSocketHandle* handle) { | |
543 base_.CancelRequest(group_name, handle); | |
544 } | |
545 | |
546 void TransportClientSocketPool::ReleaseSocket( | |
547 const std::string& group_name, | |
548 scoped_ptr<StreamSocket> socket, | |
549 int id) { | |
550 base_.ReleaseSocket(group_name, socket.Pass(), id); | |
551 } | |
552 | |
553 void TransportClientSocketPool::FlushWithError(int error) { | |
554 base_.FlushWithError(error); | |
555 } | |
556 | |
557 void TransportClientSocketPool::CloseIdleSockets() { | |
558 base_.CloseIdleSockets(); | |
559 } | |
560 | |
561 int TransportClientSocketPool::IdleSocketCount() const { | |
562 return base_.idle_socket_count(); | |
563 } | |
564 | |
565 int TransportClientSocketPool::IdleSocketCountInGroup( | |
566 const std::string& group_name) const { | |
567 return base_.IdleSocketCountInGroup(group_name); | |
568 } | |
569 | |
570 LoadState TransportClientSocketPool::GetLoadState( | |
571 const std::string& group_name, const ClientSocketHandle* handle) const { | |
572 return base_.GetLoadState(group_name, handle); | |
573 } | |
574 | |
575 base::DictionaryValue* TransportClientSocketPool::GetInfoAsValue( | |
576 const std::string& name, | |
577 const std::string& type, | |
578 bool include_nested_pools) const { | |
579 return base_.GetInfoAsValue(name, type); | |
580 } | |
581 | |
582 base::TimeDelta TransportClientSocketPool::ConnectionTimeout() const { | |
583 return base_.ConnectionTimeout(); | |
584 } | |
585 | |
586 ClientSocketPoolHistograms* TransportClientSocketPool::histograms() const { | |
587 return base_.histograms(); | |
588 } | |
589 | |
590 bool TransportClientSocketPool::IsStalled() const { | |
591 return base_.IsStalled(); | |
592 } | |
593 | |
594 void TransportClientSocketPool::AddHigherLayeredPool( | |
595 HigherLayeredPool* higher_pool) { | |
596 base_.AddHigherLayeredPool(higher_pool); | |
597 } | |
598 | |
599 void TransportClientSocketPool::RemoveHigherLayeredPool( | |
600 HigherLayeredPool* higher_pool) { | |
601 base_.RemoveHigherLayeredPool(higher_pool); | |
602 } | |
603 | |
604 } // namespace net | |
OLD | NEW |