transport_client_socket_pool.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// Use of this source code is governed by a BSD-style license that can be 3c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// found in the LICENSE file. 4c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant#include "net/socket/transport_client_socket_pool.h" 6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant 7c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <algorithm> 8c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 9c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "base/compiler_specific.h" 10c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "base/logging.h" 11c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "base/message_loop.h" 12c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "base/metrics/histogram.h" 13c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "base/string_util.h" 14c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "base/time.h" 15c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "base/values.h" 16c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "net/base/ip_endpoint.h" 17c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "net/base/net_log.h" 18c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "net/base/net_errors.h" 19c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "net/socket/client_socket_factory.h" 20c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "net/socket/client_socket_handle.h" 21c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "net/socket/client_socket_pool_base.h" 22c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "net/socket/socket_net_log_params.h" 23c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include "net/socket/tcp_client_socket.h" 24c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 25c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantusing base::TimeDelta; 26c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 27c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantnamespace net { 28c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 29c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// TODO(willchan): Base this off RTT instead of statically setting it. Note we 30c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// choose a timeout that is different from the backup connect job timer so they 31c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// don't synchronize. 32c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantconst int TransportConnectJob::kIPv6FallbackTimerInMs = 300; 33c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 34c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantnamespace { 35c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 36c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// Returns true iff all addresses in |list| are in the IPv6 family. 37c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantbool AddressListOnlyContainsIPv6(const AddressList& list) { 38c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant DCHECK(!list.empty()); 39c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant for (AddressList::const_iterator iter = list.begin(); iter != list.end(); 40c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant ++iter) { 41c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant if (iter->GetFamily() != AF_INET6) 42c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return false; 43c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 44c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return true; 45c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 46c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 47c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} // namespace 48c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 4973d21a4f0774d3fadab98e690619a359cfb160a3Howard HinnantTransportSocketParams::TransportSocketParams( 50c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant const HostPortPair& host_port_pair, 51c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant RequestPriority priority, 5273d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant bool disable_resolver_cache, 53c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant bool ignore_limits, 54c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant const OnHostResolutionCallback& host_resolution_callback) 5573d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant : destination_(host_port_pair), 56c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant ignore_limits_(ignore_limits), 57c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant host_resolution_callback_(host_resolution_callback) { 5873d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant Initialize(priority, disable_resolver_cache); 59c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 60c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 61c52f43e72dfcea03037729649da84c23b3beb04aHoward HinnantTransportSocketParams::~TransportSocketParams() {} 62c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 63c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantvoid TransportSocketParams::Initialize(RequestPriority priority, 64c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant bool disable_resolver_cache) { 65c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant destination_.set_priority(priority); 6673d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant if (disable_resolver_cache) 67c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant destination_.set_allow_cached_response(false); 68c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 69c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 70c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// TransportConnectJobs will time out after this many seconds. Note this is 71c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// the total time, including both host resolution and TCP connect() times. 72c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// 73c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// TODO(eroman): The use of this constant needs to be re-evaluated. The time 74c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// needed for TCPClientSocketXXX::Connect() can be arbitrarily long, since 7573d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant// the address list may contain many alternatives, and most of those may 76c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// timeout. Even worse, the per-connect timeout threshold varies greatly 77c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// between systems (anywhere from 20 seconds to 190 seconds). 78c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// See comment #12 at http://crbug.com/23364 for specifics. 7973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnantstatic const int kTransportConnectJobTimeoutInSeconds = 240; // 4 minutes. 80c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 81c52f43e72dfcea03037729649da84c23b3beb04aHoward HinnantTransportConnectJob::TransportConnectJob( 82c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant const std::string& group_name, 83c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant const scoped_refptr<TransportSocketParams>& params, 84c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant base::TimeDelta timeout_duration, 85c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant ClientSocketFactory* client_socket_factory, 86c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant HostResolver* host_resolver, 87c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant Delegate* delegate, 88c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant NetLog* net_log) 8973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant : ConnectJob(group_name, timeout_duration, delegate, 90c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), 91c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant params_(params), 92c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant client_socket_factory_(client_socket_factory), 93c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant resolver_(host_resolver), 9473d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant next_state_(STATE_NONE) { 95c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 96c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 97c52f43e72dfcea03037729649da84c23b3beb04aHoward HinnantTransportConnectJob::~TransportConnectJob() { 98c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant // We don't worry about cancelling the host resolution and TCP connect, since 99c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant // ~SingleRequestHostResolver and ~StreamSocket will take care of it. 100c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 101c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 102c52f43e72dfcea03037729649da84c23b3beb04aHoward HinnantLoadState TransportConnectJob::GetLoadState() const { 103c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant switch (next_state_) { 104c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant case STATE_RESOLVE_HOST: 105c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant case STATE_RESOLVE_HOST_COMPLETE: 106c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return LOAD_STATE_RESOLVING_HOST; 107c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant case STATE_TRANSPORT_CONNECT: 108c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant case STATE_TRANSPORT_CONNECT_COMPLETE: 109c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return LOAD_STATE_CONNECTING; 110c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant default: 111c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant NOTREACHED(); 112c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant return LOAD_STATE_IDLE; 113c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant } 114c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant} 115c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant 116c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// static 117c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantvoid TransportConnectJob::MakeAddressListStartWithIPv4(AddressList* list) { 118 for (AddressList::iterator i = list->begin(); i != list->end(); ++i) { 119 if (i->GetFamily() == AF_INET) { 120 std::rotate(list->begin(), i, list->end()); 121 break; 122 } 123 } 124} 125 126void TransportConnectJob::OnIOComplete(int result) { 127 int rv = DoLoop(result); 128 if (rv != ERR_IO_PENDING) 129 NotifyDelegateOfCompletion(rv); // Deletes |this| 130} 131 132int TransportConnectJob::DoLoop(int result) { 133 DCHECK_NE(next_state_, STATE_NONE); 134 135 int rv = result; 136 do { 137 State state = next_state_; 138 next_state_ = STATE_NONE; 139 switch (state) { 140 case STATE_RESOLVE_HOST: 141 DCHECK_EQ(OK, rv); 142 rv = DoResolveHost(); 143 break; 144 case STATE_RESOLVE_HOST_COMPLETE: 145 rv = DoResolveHostComplete(rv); 146 break; 147 case STATE_TRANSPORT_CONNECT: 148 DCHECK_EQ(OK, rv); 149 rv = DoTransportConnect(); 150 break; 151 case STATE_TRANSPORT_CONNECT_COMPLETE: 152 rv = DoTransportConnectComplete(rv); 153 break; 154 default: 155 NOTREACHED(); 156 rv = ERR_FAILED; 157 break; 158 } 159 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 160 161 return rv; 162} 163 164int TransportConnectJob::DoResolveHost() { 165 next_state_ = STATE_RESOLVE_HOST_COMPLETE; 166 return resolver_.Resolve( 167 params_->destination(), &addresses_, 168 base::Bind(&TransportConnectJob::OnIOComplete, base::Unretained(this)), 169 net_log()); 170} 171 172int TransportConnectJob::DoResolveHostComplete(int result) { 173 if (result == OK) { 174 // Invoke callback, and abort if it fails. 175 if (!params_->host_resolution_callback().is_null()) 176 result = params_->host_resolution_callback().Run(addresses_, net_log()); 177 178 if (result == OK) 179 next_state_ = STATE_TRANSPORT_CONNECT; 180 } 181 return result; 182} 183 184int TransportConnectJob::DoTransportConnect() { 185 next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE; 186 transport_socket_.reset(client_socket_factory_->CreateTransportClientSocket( 187 addresses_, net_log().net_log(), net_log().source())); 188 connect_start_time_ = base::TimeTicks::Now(); 189 int rv = transport_socket_->Connect( 190 base::Bind(&TransportConnectJob::OnIOComplete, base::Unretained(this))); 191 if (rv == ERR_IO_PENDING && 192 addresses_.front().GetFamily() == AF_INET6 && 193 !AddressListOnlyContainsIPv6(addresses_)) { 194 fallback_timer_.Start(FROM_HERE, 195 base::TimeDelta::FromMilliseconds(kIPv6FallbackTimerInMs), 196 this, &TransportConnectJob::DoIPv6FallbackTransportConnect); 197 } 198 return rv; 199} 200 201int TransportConnectJob::DoTransportConnectComplete(int result) { 202 if (result == OK) { 203 bool is_ipv4 = addresses_.front().GetFamily() != AF_INET6; 204 DCHECK(connect_start_time_ != base::TimeTicks()); 205 DCHECK(start_time_ != base::TimeTicks()); 206 base::TimeTicks now = base::TimeTicks::Now(); 207 base::TimeDelta total_duration = now - start_time_; 208 UMA_HISTOGRAM_CUSTOM_TIMES( 209 "Net.DNS_Resolution_And_TCP_Connection_Latency2", 210 total_duration, 211 base::TimeDelta::FromMilliseconds(1), 212 base::TimeDelta::FromMinutes(10), 213 100); 214 215 base::TimeDelta connect_duration = now - connect_start_time_; 216 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency", 217 connect_duration, 218 base::TimeDelta::FromMilliseconds(1), 219 base::TimeDelta::FromMinutes(10), 220 100); 221 222 if (is_ipv4) { 223 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv4_No_Race", 224 connect_duration, 225 base::TimeDelta::FromMilliseconds(1), 226 base::TimeDelta::FromMinutes(10), 227 100); 228 } else { 229 if (AddressListOnlyContainsIPv6(addresses_)) { 230 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Solo", 231 connect_duration, 232 base::TimeDelta::FromMilliseconds(1), 233 base::TimeDelta::FromMinutes(10), 234 100); 235 } else { 236 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Raceable", 237 connect_duration, 238 base::TimeDelta::FromMilliseconds(1), 239 base::TimeDelta::FromMinutes(10), 240 100); 241 } 242 } 243 set_socket(transport_socket_.release()); 244 fallback_timer_.Stop(); 245 } else { 246 // Be a bit paranoid and kill off the fallback members to prevent reuse. 247 fallback_transport_socket_.reset(); 248 fallback_addresses_.reset(); 249 } 250 251 return result; 252} 253 254void TransportConnectJob::DoIPv6FallbackTransportConnect() { 255 // The timer should only fire while we're waiting for the main connect to 256 // succeed. 257 if (next_state_ != STATE_TRANSPORT_CONNECT_COMPLETE) { 258 NOTREACHED(); 259 return; 260 } 261 262 DCHECK(!fallback_transport_socket_.get()); 263 DCHECK(!fallback_addresses_.get()); 264 265 fallback_addresses_.reset(new AddressList(addresses_)); 266 MakeAddressListStartWithIPv4(fallback_addresses_.get()); 267 fallback_transport_socket_.reset( 268 client_socket_factory_->CreateTransportClientSocket( 269 *fallback_addresses_, net_log().net_log(), net_log().source())); 270 fallback_connect_start_time_ = base::TimeTicks::Now(); 271 int rv = fallback_transport_socket_->Connect( 272 base::Bind( 273 &TransportConnectJob::DoIPv6FallbackTransportConnectComplete, 274 base::Unretained(this))); 275 if (rv != ERR_IO_PENDING) 276 DoIPv6FallbackTransportConnectComplete(rv); 277} 278 279void TransportConnectJob::DoIPv6FallbackTransportConnectComplete(int result) { 280 // This should only happen when we're waiting for the main connect to succeed. 281 if (next_state_ != STATE_TRANSPORT_CONNECT_COMPLETE) { 282 NOTREACHED(); 283 return; 284 } 285 286 DCHECK_NE(ERR_IO_PENDING, result); 287 DCHECK(fallback_transport_socket_.get()); 288 DCHECK(fallback_addresses_.get()); 289 290 if (result == OK) { 291 DCHECK(fallback_connect_start_time_ != base::TimeTicks()); 292 DCHECK(start_time_ != base::TimeTicks()); 293 base::TimeTicks now = base::TimeTicks::Now(); 294 base::TimeDelta total_duration = now - start_time_; 295 UMA_HISTOGRAM_CUSTOM_TIMES( 296 "Net.DNS_Resolution_And_TCP_Connection_Latency2", 297 total_duration, 298 base::TimeDelta::FromMilliseconds(1), 299 base::TimeDelta::FromMinutes(10), 300 100); 301 302 base::TimeDelta connect_duration = now - fallback_connect_start_time_; 303 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency", 304 connect_duration, 305 base::TimeDelta::FromMilliseconds(1), 306 base::TimeDelta::FromMinutes(10), 307 100); 308 309 UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv4_Wins_Race", 310 connect_duration, 311 base::TimeDelta::FromMilliseconds(1), 312 base::TimeDelta::FromMinutes(10), 313 100); 314 set_socket(fallback_transport_socket_.release()); 315 next_state_ = STATE_NONE; 316 transport_socket_.reset(); 317 } else { 318 // Be a bit paranoid and kill off the fallback members to prevent reuse. 319 fallback_transport_socket_.reset(); 320 fallback_addresses_.reset(); 321 } 322 NotifyDelegateOfCompletion(result); // Deletes |this| 323} 324 325int TransportConnectJob::ConnectInternal() { 326 next_state_ = STATE_RESOLVE_HOST; 327 start_time_ = base::TimeTicks::Now(); 328 return DoLoop(OK); 329} 330 331ConnectJob* 332 TransportClientSocketPool::TransportConnectJobFactory::NewConnectJob( 333 const std::string& group_name, 334 const PoolBase::Request& request, 335 ConnectJob::Delegate* delegate) const { 336 return new TransportConnectJob(group_name, 337 request.params(), 338 ConnectionTimeout(), 339 client_socket_factory_, 340 host_resolver_, 341 delegate, 342 net_log_); 343} 344 345base::TimeDelta 346 TransportClientSocketPool::TransportConnectJobFactory::ConnectionTimeout() 347 const { 348 return base::TimeDelta::FromSeconds(kTransportConnectJobTimeoutInSeconds); 349} 350 351TransportClientSocketPool::TransportClientSocketPool( 352 int max_sockets, 353 int max_sockets_per_group, 354 ClientSocketPoolHistograms* histograms, 355 HostResolver* host_resolver, 356 ClientSocketFactory* client_socket_factory, 357 NetLog* net_log) 358 : base_(max_sockets, max_sockets_per_group, histograms, 359 ClientSocketPool::unused_idle_socket_timeout(), 360 ClientSocketPool::used_idle_socket_timeout(), 361 new TransportConnectJobFactory(client_socket_factory, 362 host_resolver, net_log)) { 363 base_.EnableConnectBackupJobs(); 364} 365 366TransportClientSocketPool::~TransportClientSocketPool() {} 367 368int TransportClientSocketPool::RequestSocket( 369 const std::string& group_name, 370 const void* params, 371 RequestPriority priority, 372 ClientSocketHandle* handle, 373 const CompletionCallback& callback, 374 const BoundNetLog& net_log) { 375 const scoped_refptr<TransportSocketParams>* casted_params = 376 static_cast<const scoped_refptr<TransportSocketParams>*>(params); 377 378 if (net_log.IsLoggingAllEvents()) { 379 // TODO(eroman): Split out the host and port parameters. 380 net_log.AddEvent( 381 NetLog::TYPE_TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET, 382 CreateNetLogHostPortPairCallback( 383 &casted_params->get()->destination().host_port_pair())); 384 } 385 386 return base_.RequestSocket(group_name, *casted_params, priority, handle, 387 callback, net_log); 388} 389 390void TransportClientSocketPool::RequestSockets( 391 const std::string& group_name, 392 const void* params, 393 int num_sockets, 394 const BoundNetLog& net_log) { 395 const scoped_refptr<TransportSocketParams>* casted_params = 396 static_cast<const scoped_refptr<TransportSocketParams>*>(params); 397 398 if (net_log.IsLoggingAllEvents()) { 399 // TODO(eroman): Split out the host and port parameters. 400 net_log.AddEvent( 401 NetLog::TYPE_TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKETS, 402 CreateNetLogHostPortPairCallback( 403 &casted_params->get()->destination().host_port_pair())); 404 } 405 406 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log); 407} 408 409void TransportClientSocketPool::CancelRequest( 410 const std::string& group_name, 411 ClientSocketHandle* handle) { 412 base_.CancelRequest(group_name, handle); 413} 414 415void TransportClientSocketPool::ReleaseSocket( 416 const std::string& group_name, 417 StreamSocket* socket, 418 int id) { 419 base_.ReleaseSocket(group_name, socket, id); 420} 421 422void TransportClientSocketPool::Flush() { 423 base_.Flush(); 424} 425 426bool TransportClientSocketPool::IsStalled() const { 427 return base_.IsStalled(); 428} 429 430void TransportClientSocketPool::CloseIdleSockets() { 431 base_.CloseIdleSockets(); 432} 433 434int TransportClientSocketPool::IdleSocketCount() const { 435 return base_.idle_socket_count(); 436} 437 438int TransportClientSocketPool::IdleSocketCountInGroup( 439 const std::string& group_name) const { 440 return base_.IdleSocketCountInGroup(group_name); 441} 442 443LoadState TransportClientSocketPool::GetLoadState( 444 const std::string& group_name, const ClientSocketHandle* handle) const { 445 return base_.GetLoadState(group_name, handle); 446} 447 448void TransportClientSocketPool::AddLayeredPool(LayeredPool* layered_pool) { 449 base_.AddLayeredPool(layered_pool); 450} 451 452void TransportClientSocketPool::RemoveLayeredPool(LayeredPool* layered_pool) { 453 base_.RemoveLayeredPool(layered_pool); 454} 455 456DictionaryValue* TransportClientSocketPool::GetInfoAsValue( 457 const std::string& name, 458 const std::string& type, 459 bool include_nested_pools) const { 460 return base_.GetInfoAsValue(name, type); 461} 462 463base::TimeDelta TransportClientSocketPool::ConnectionTimeout() const { 464 return base_.ConnectionTimeout(); 465} 466 467ClientSocketPoolHistograms* TransportClientSocketPool::histograms() const { 468 return base_.histograms(); 469} 470 471} // namespace net 472