| Index: net/socket/transport_client_socket_pool.cc
|
| diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
|
| index dc481fa4b6d6004afcc102923a9c3194f91b8940..0628eea293329fc4051ba922ba497b9e23b2c1e5 100644
|
| --- a/net/socket/transport_client_socket_pool.cc
|
| +++ b/net/socket/transport_client_socket_pool.cc
|
| @@ -31,7 +31,7 @@ namespace net {
|
| // TODO(willchan): Base this off RTT instead of statically setting it. Note we
|
| // choose a timeout that is different from the backup connect job timer so they
|
| // don't synchronize.
|
| -const int TransportConnectJob::kIPv6FallbackTimerInMs = 300;
|
| +const int TransportConnectJobHelper::kIPv6FallbackTimerInMs = 300;
|
|
|
| namespace {
|
|
|
| @@ -81,6 +81,107 @@ TransportSocketParams::~TransportSocketParams() {}
|
| // See comment #12 at http://crbug.com/23364 for specifics.
|
| static const int kTransportConnectJobTimeoutInSeconds = 240; // 4 minutes.
|
|
|
| +TransportConnectJobHelper::TransportConnectJobHelper(
|
| + const scoped_refptr<TransportSocketParams>& params,
|
| + ClientSocketFactory* client_socket_factory,
|
| + HostResolver* host_resolver,
|
| + LoadTimingInfo::ConnectTiming* connect_timing)
|
| + : params_(params),
|
| + client_socket_factory_(client_socket_factory),
|
| + resolver_(host_resolver),
|
| + next_state_(STATE_NONE),
|
| + connect_timing_(connect_timing) {}
|
| +
|
| +TransportConnectJobHelper::~TransportConnectJobHelper() {}
|
| +
|
| +int TransportConnectJobHelper::DoResolveHost(RequestPriority priority,
|
| + const BoundNetLog& net_log) {
|
| + next_state_ = STATE_RESOLVE_HOST_COMPLETE;
|
| + connect_timing_->dns_start = base::TimeTicks::Now();
|
| +
|
| + return resolver_.Resolve(
|
| + params_->destination(), priority, &addresses_, on_io_complete_, net_log);
|
| +}
|
| +
|
| +int TransportConnectJobHelper::DoResolveHostComplete(
|
| + int result,
|
| + const BoundNetLog& net_log) {
|
| + connect_timing_->dns_end = base::TimeTicks::Now();
|
| + // Overwrite connection start time, since for connections that do not go
|
| + // through proxies, |connect_start| should not include dns lookup time.
|
| + connect_timing_->connect_start = connect_timing_->dns_end;
|
| +
|
| + if (result == OK) {
|
| + // Invoke callback, and abort if it fails.
|
| + if (!params_->host_resolution_callback().is_null())
|
| + result = params_->host_resolution_callback().Run(addresses_, net_log);
|
| +
|
| + if (result == OK)
|
| + next_state_ = STATE_TRANSPORT_CONNECT;
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +base::TimeDelta TransportConnectJobHelper::HistogramDuration(
|
| + ConnectionLatencyHistogram race_result) {
|
| + DCHECK(!connect_timing_->connect_start.is_null());
|
| + DCHECK(!connect_timing_->dns_start.is_null());
|
| + base::TimeTicks now = base::TimeTicks::Now();
|
| + base::TimeDelta total_duration = now - connect_timing_->dns_start;
|
| + UMA_HISTOGRAM_CUSTOM_TIMES("Net.DNS_Resolution_And_TCP_Connection_Latency2",
|
| + total_duration,
|
| + base::TimeDelta::FromMilliseconds(1),
|
| + base::TimeDelta::FromMinutes(10),
|
| + 100);
|
| +
|
| + base::TimeDelta connect_duration = now - connect_timing_->connect_start;
|
| + UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency",
|
| + connect_duration,
|
| + base::TimeDelta::FromMilliseconds(1),
|
| + base::TimeDelta::FromMinutes(10),
|
| + 100);
|
| +
|
| + switch (race_result) {
|
| + case CONNECTION_LATENCY_IPV4_WINS_RACE:
|
| + UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv4_Wins_Race",
|
| + connect_duration,
|
| + base::TimeDelta::FromMilliseconds(1),
|
| + base::TimeDelta::FromMinutes(10),
|
| + 100);
|
| + break;
|
| +
|
| + case CONNECTION_LATENCY_IPV4_NO_RACE:
|
| + UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv4_No_Race",
|
| + connect_duration,
|
| + base::TimeDelta::FromMilliseconds(1),
|
| + base::TimeDelta::FromMinutes(10),
|
| + 100);
|
| + break;
|
| +
|
| + case CONNECTION_LATENCY_IPV6_RACEABLE:
|
| + UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Raceable",
|
| + connect_duration,
|
| + base::TimeDelta::FromMilliseconds(1),
|
| + base::TimeDelta::FromMinutes(10),
|
| + 100);
|
| + break;
|
| +
|
| + case CONNECTION_LATENCY_IPV6_SOLO:
|
| + UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Solo",
|
| + connect_duration,
|
| + base::TimeDelta::FromMilliseconds(1),
|
| + base::TimeDelta::FromMinutes(10),
|
| + 100);
|
| + break;
|
| +
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +
|
| + return connect_duration;
|
| +}
|
| +
|
| TransportConnectJob::TransportConnectJob(
|
| const std::string& group_name,
|
| RequestPriority priority,
|
| @@ -92,11 +193,9 @@ TransportConnectJob::TransportConnectJob(
|
| NetLog* net_log)
|
| : ConnectJob(group_name, timeout_duration, priority, delegate,
|
| BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
|
| - params_(params),
|
| - client_socket_factory_(client_socket_factory),
|
| - resolver_(host_resolver),
|
| - next_state_(STATE_NONE),
|
| + data_(params, client_socket_factory, host_resolver, &connect_timing_),
|
| interval_between_connects_(CONNECT_INTERVAL_GT_20MS) {
|
| + data_.SetOnIOComplete(this);
|
| }
|
|
|
| TransportConnectJob::~TransportConnectJob() {
|
| @@ -105,14 +204,14 @@ TransportConnectJob::~TransportConnectJob() {
|
| }
|
|
|
| LoadState TransportConnectJob::GetLoadState() const {
|
| - switch (next_state_) {
|
| - case STATE_RESOLVE_HOST:
|
| - case STATE_RESOLVE_HOST_COMPLETE:
|
| + switch (data_.next_state()) {
|
| + case TransportConnectJobHelper::STATE_RESOLVE_HOST:
|
| + case TransportConnectJobHelper::STATE_RESOLVE_HOST_COMPLETE:
|
| return LOAD_STATE_RESOLVING_HOST;
|
| - case STATE_TRANSPORT_CONNECT:
|
| - case STATE_TRANSPORT_CONNECT_COMPLETE:
|
| + case TransportConnectJobHelper::STATE_TRANSPORT_CONNECT:
|
| + case TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE:
|
| return LOAD_STATE_CONNECTING;
|
| - case STATE_NONE:
|
| + case TransportConnectJobHelper::STATE_NONE:
|
| return LOAD_STATE_IDLE;
|
| }
|
| NOTREACHED();
|
| @@ -129,71 +228,12 @@ void TransportConnectJob::MakeAddressListStartWithIPv4(AddressList* list) {
|
| }
|
| }
|
|
|
| -void TransportConnectJob::OnIOComplete(int result) {
|
| - int rv = DoLoop(result);
|
| - if (rv != ERR_IO_PENDING)
|
| - NotifyDelegateOfCompletion(rv); // Deletes |this|
|
| -}
|
| -
|
| -int TransportConnectJob::DoLoop(int result) {
|
| - DCHECK_NE(next_state_, STATE_NONE);
|
| -
|
| - int rv = result;
|
| - do {
|
| - State state = next_state_;
|
| - next_state_ = STATE_NONE;
|
| - switch (state) {
|
| - case STATE_RESOLVE_HOST:
|
| - DCHECK_EQ(OK, rv);
|
| - rv = DoResolveHost();
|
| - break;
|
| - case STATE_RESOLVE_HOST_COMPLETE:
|
| - rv = DoResolveHostComplete(rv);
|
| - break;
|
| - case STATE_TRANSPORT_CONNECT:
|
| - DCHECK_EQ(OK, rv);
|
| - rv = DoTransportConnect();
|
| - break;
|
| - case STATE_TRANSPORT_CONNECT_COMPLETE:
|
| - rv = DoTransportConnectComplete(rv);
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - rv = ERR_FAILED;
|
| - break;
|
| - }
|
| - } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
|
| -
|
| - return rv;
|
| -}
|
| -
|
| int TransportConnectJob::DoResolveHost() {
|
| - next_state_ = STATE_RESOLVE_HOST_COMPLETE;
|
| - connect_timing_.dns_start = base::TimeTicks::Now();
|
| -
|
| - return resolver_.Resolve(
|
| - params_->destination(),
|
| - priority(),
|
| - &addresses_,
|
| - base::Bind(&TransportConnectJob::OnIOComplete, base::Unretained(this)),
|
| - net_log());
|
| + return data_.DoResolveHost(priority(), net_log());
|
| }
|
|
|
| int TransportConnectJob::DoResolveHostComplete(int result) {
|
| - connect_timing_.dns_end = base::TimeTicks::Now();
|
| - // Overwrite connection start time, since for connections that do not go
|
| - // through proxies, |connect_start| should not include dns lookup time.
|
| - connect_timing_.connect_start = connect_timing_.dns_end;
|
| -
|
| - if (result == OK) {
|
| - // Invoke callback, and abort if it fails.
|
| - if (!params_->host_resolution_callback().is_null())
|
| - result = params_->host_resolution_callback().Run(addresses_, net_log());
|
| -
|
| - if (result == OK)
|
| - next_state_ = STATE_TRANSPORT_CONNECT;
|
| - }
|
| - return result;
|
| + return data_.DoResolveHostComplete(result, net_log());
|
| }
|
|
|
| int TransportConnectJob::DoTransportConnect() {
|
| @@ -216,42 +256,41 @@ int TransportConnectJob::DoTransportConnect() {
|
| interval_between_connects_ = CONNECT_INTERVAL_GT_20MS;
|
| }
|
|
|
| - next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
|
| - transport_socket_ = client_socket_factory_->CreateTransportClientSocket(
|
| - addresses_, net_log().net_log(), net_log().source());
|
| - int rv = transport_socket_->Connect(
|
| - base::Bind(&TransportConnectJob::OnIOComplete, base::Unretained(this)));
|
| + data_.set_next_state(
|
| + TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE);
|
| + transport_socket_ =
|
| + data_.client_socket_factory()->CreateTransportClientSocket(
|
| + data_.addresses(), net_log().net_log(), net_log().source());
|
| + int rv = transport_socket_->Connect(data_.on_io_complete());
|
| if (rv == ERR_IO_PENDING &&
|
| - addresses_.front().GetFamily() == ADDRESS_FAMILY_IPV6 &&
|
| - !AddressListOnlyContainsIPv6(addresses_)) {
|
| - fallback_timer_.Start(FROM_HERE,
|
| - base::TimeDelta::FromMilliseconds(kIPv6FallbackTimerInMs),
|
| - this, &TransportConnectJob::DoIPv6FallbackTransportConnect);
|
| + data_.addresses().front().GetFamily() == ADDRESS_FAMILY_IPV6 &&
|
| + !AddressListOnlyContainsIPv6(data_.addresses())) {
|
| + fallback_timer_.Start(
|
| + FROM_HERE,
|
| + base::TimeDelta::FromMilliseconds(
|
| + TransportConnectJobHelper::kIPv6FallbackTimerInMs),
|
| + this,
|
| + &TransportConnectJob::DoIPv6FallbackTransportConnect);
|
| }
|
| return rv;
|
| }
|
|
|
| int TransportConnectJob::DoTransportConnectComplete(int result) {
|
| if (result == OK) {
|
| - bool is_ipv4 = addresses_.front().GetFamily() == ADDRESS_FAMILY_IPV4;
|
| - DCHECK(!connect_timing_.connect_start.is_null());
|
| - DCHECK(!connect_timing_.dns_start.is_null());
|
| - base::TimeTicks now = base::TimeTicks::Now();
|
| - base::TimeDelta total_duration = now - connect_timing_.dns_start;
|
| - UMA_HISTOGRAM_CUSTOM_TIMES(
|
| - "Net.DNS_Resolution_And_TCP_Connection_Latency2",
|
| - total_duration,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromMinutes(10),
|
| - 100);
|
| -
|
| - base::TimeDelta connect_duration = now - connect_timing_.connect_start;
|
| - UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency",
|
| - connect_duration,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromMinutes(10),
|
| - 100);
|
| -
|
| + bool is_ipv4 = data_.addresses().front().GetFamily() == ADDRESS_FAMILY_IPV4;
|
| + TransportConnectJobHelper::ConnectionLatencyHistogram race_result =
|
| + TransportConnectJobHelper::CONNECTION_LATENCY_UNKNOWN;
|
| + if (is_ipv4) {
|
| + race_result = TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_NO_RACE;
|
| + } else {
|
| + if (AddressListOnlyContainsIPv6(data_.addresses())) {
|
| + race_result = TransportConnectJobHelper::CONNECTION_LATENCY_IPV6_SOLO;
|
| + } else {
|
| + race_result =
|
| + TransportConnectJobHelper::CONNECTION_LATENCY_IPV6_RACEABLE;
|
| + }
|
| + }
|
| + base::TimeDelta connect_duration = data_.HistogramDuration(race_result);
|
| switch (interval_between_connects_) {
|
| case CONNECT_INTERVAL_LE_10MS:
|
| UMA_HISTOGRAM_CUSTOM_TIMES(
|
| @@ -282,27 +321,6 @@ int TransportConnectJob::DoTransportConnectComplete(int result) {
|
| break;
|
| }
|
|
|
| - if (is_ipv4) {
|
| - UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv4_No_Race",
|
| - connect_duration,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromMinutes(10),
|
| - 100);
|
| - } else {
|
| - if (AddressListOnlyContainsIPv6(addresses_)) {
|
| - UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Solo",
|
| - connect_duration,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromMinutes(10),
|
| - 100);
|
| - } else {
|
| - UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Raceable",
|
| - connect_duration,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromMinutes(10),
|
| - 100);
|
| - }
|
| - }
|
| SetSocket(transport_socket_.Pass());
|
| fallback_timer_.Stop();
|
| } else {
|
| @@ -317,7 +335,8 @@ int TransportConnectJob::DoTransportConnectComplete(int result) {
|
| void TransportConnectJob::DoIPv6FallbackTransportConnect() {
|
| // The timer should only fire while we're waiting for the main connect to
|
| // succeed.
|
| - if (next_state_ != STATE_TRANSPORT_CONNECT_COMPLETE) {
|
| + if (data_.next_state() !=
|
| + TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE) {
|
| NOTREACHED();
|
| return;
|
| }
|
| @@ -325,10 +344,10 @@ void TransportConnectJob::DoIPv6FallbackTransportConnect() {
|
| DCHECK(!fallback_transport_socket_.get());
|
| DCHECK(!fallback_addresses_.get());
|
|
|
| - fallback_addresses_.reset(new AddressList(addresses_));
|
| + fallback_addresses_.reset(new AddressList(data_.addresses()));
|
| MakeAddressListStartWithIPv4(fallback_addresses_.get());
|
| fallback_transport_socket_ =
|
| - client_socket_factory_->CreateTransportClientSocket(
|
| + data_.client_socket_factory()->CreateTransportClientSocket(
|
| *fallback_addresses_, net_log().net_log(), net_log().source());
|
| fallback_connect_start_time_ = base::TimeTicks::Now();
|
| int rv = fallback_transport_socket_->Connect(
|
| @@ -341,7 +360,8 @@ void TransportConnectJob::DoIPv6FallbackTransportConnect() {
|
|
|
| void TransportConnectJob::DoIPv6FallbackTransportConnectComplete(int result) {
|
| // This should only happen when we're waiting for the main connect to succeed.
|
| - if (next_state_ != STATE_TRANSPORT_CONNECT_COMPLETE) {
|
| + if (data_.next_state() !=
|
| + TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE) {
|
| NOTREACHED();
|
| return;
|
| }
|
| @@ -352,30 +372,11 @@ void TransportConnectJob::DoIPv6FallbackTransportConnectComplete(int result) {
|
|
|
| if (result == OK) {
|
| DCHECK(!fallback_connect_start_time_.is_null());
|
| - DCHECK(!connect_timing_.dns_start.is_null());
|
| - base::TimeTicks now = base::TimeTicks::Now();
|
| - base::TimeDelta total_duration = now - connect_timing_.dns_start;
|
| - UMA_HISTOGRAM_CUSTOM_TIMES(
|
| - "Net.DNS_Resolution_And_TCP_Connection_Latency2",
|
| - total_duration,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromMinutes(10),
|
| - 100);
|
| -
|
| - base::TimeDelta connect_duration = now - fallback_connect_start_time_;
|
| - UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency",
|
| - connect_duration,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromMinutes(10),
|
| - 100);
|
| -
|
| - UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv4_Wins_Race",
|
| - connect_duration,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromMinutes(10),
|
| - 100);
|
| + connect_timing_.connect_start = fallback_connect_start_time_;
|
| + data_.HistogramDuration(
|
| + TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_WINS_RACE);
|
| SetSocket(fallback_transport_socket_.Pass());
|
| - next_state_ = STATE_NONE;
|
| + data_.set_next_state(TransportConnectJobHelper::STATE_NONE);
|
| transport_socket_.reset();
|
| } else {
|
| // Be a bit paranoid and kill off the fallback members to prevent reuse.
|
| @@ -386,8 +387,7 @@ void TransportConnectJob::DoIPv6FallbackTransportConnectComplete(int result) {
|
| }
|
|
|
| int TransportConnectJob::ConnectInternal() {
|
| - next_state_ = STATE_RESOLVE_HOST;
|
| - return DoLoop(OK);
|
| + return data_.DoConnectInternal(this);
|
| }
|
|
|
| scoped_ptr<ConnectJob>
|
| @@ -439,6 +439,15 @@ int TransportClientSocketPool::RequestSocket(
|
| const scoped_refptr<TransportSocketParams>* casted_params =
|
| static_cast<const scoped_refptr<TransportSocketParams>*>(params);
|
|
|
| + NetLogTcpClientSocketPoolRequestedSocket(net_log, casted_params);
|
| +
|
| + return base_.RequestSocket(group_name, *casted_params, priority, handle,
|
| + callback, net_log);
|
| +}
|
| +
|
| +void TransportClientSocketPool::NetLogTcpClientSocketPoolRequestedSocket(
|
| + const BoundNetLog& net_log,
|
| + const scoped_refptr<TransportSocketParams>* casted_params) {
|
| if (net_log.IsLogging()) {
|
| // TODO(eroman): Split out the host and port parameters.
|
| net_log.AddEvent(
|
| @@ -446,9 +455,6 @@ int TransportClientSocketPool::RequestSocket(
|
| CreateNetLogHostPortPairCallback(
|
| &casted_params->get()->destination().host_port_pair()));
|
| }
|
| -
|
| - return base_.RequestSocket(group_name, *casted_params, priority, handle,
|
| - callback, net_log);
|
| }
|
|
|
| void TransportClientSocketPool::RequestSockets(
|
|
|