Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7121)

Unified Diff: chrome/browser/net/network_stats.cc

Issue 1031203002: [Clean-up] Remove NetworkStats code, which has been dead code since July 2014. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/net/network_stats.cc
diff --git a/chrome/browser/net/network_stats.cc b/chrome/browser/net/network_stats.cc
deleted file mode 100644
index 51df4c21bde5e997b6742d511a3b59de17186167..0000000000000000000000000000000000000000
--- a/chrome/browser/net/network_stats.cc
+++ /dev/null
@@ -1,962 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/net/network_stats.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram.h"
-#include "base/profiler/scoped_tracker.h"
-#include "base/rand_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
-#include "chrome/common/chrome_version_info.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/base/network_change_notifier.h"
-#include "net/base/test_completion_callback.h"
-#include "net/dns/single_request_host_resolver.h"
-#include "net/proxy/proxy_service.h"
-#include "net/socket/client_socket_factory.h"
-#include "net/udp/datagram_client_socket.h"
-#include "url/gurl.h"
-
-using content::BrowserThread;
-
-namespace chrome_browser_net {
-
-// static
-uint32 NetworkStats::maximum_tests_ = 8;
-// static
-uint32 NetworkStats::maximum_sequential_packets_ = 21;
-// static
-uint32 NetworkStats::maximum_NAT_packets_ = 2;
-// static
-uint32 NetworkStats::maximum_NAT_idle_seconds_ = 300;
-// static
-bool NetworkStats::start_test_after_connect_ = true;
-
-// Specify the possible choices of probe packet sizes.
-const uint32 kProbePacketBytes[] = {100, 500, 1200};
-const uint32 kPacketSizeChoices = arraysize(kProbePacketBytes);
-
-// List of ports used for probing test.
-const uint16 kPorts[] = {443, 80};
-
-// Number of first few packets that are recorded in a packet-correlation
-// histogram, which shows exactly what sequence of packets were received.
-// We use this to deduce specific packet loss correlation.
-const uint32 kCorrelatedLossPacketCount = 6;
-
-// This specifies the maximum message (payload) size of one packet.
-const uint32 kMaxMessageSize = 1600;
-
-// This specifies the maximum udp receiver buffer size.
-const uint32 kMaxUdpReceiveBufferSize = 63000;
-
-// This specifies the maximum udp receiver buffer size.
-const uint32 kMaxUdpSendBufferSize = 4096;
-
-// This should match TestType except for the last one.
-const char* kTestName[] = {"TokenRequest", "StartPacket", "NonPacedPacket",
- "PacedPacket", "NATBind", "PacketSizeTest"};
-
-// Perform Pacing/Non-pacing test only if at least 2 packets are received
-// in the StartPacketTest.
-const uint32 kMinimumReceivedPacketsForPacingTest = 2;
-// Perform NAT binding test only if at least 10 packets are received.
-const uint32 kMinimumReceivedPacketsForNATTest = 10;
-
-// Maximum inter-packet pacing interval in microseconds.
-const uint32 kMaximumPacingMicros = 1000000;
-// Timeout value for getting the token.
-const uint32 kGetTokenTimeoutSeconds = 10;
-// Timeout value for StartPacket and NonPacedPacket if the client does not get
-// reply. For PacedPacket test, the timeout value is this number plus the total
-// pacing interval.
-const uint32 kReadDataTimeoutSeconds = 30;
-// This is the timeout for NAT without Idle periods.
-// For NAT test with idle periods, the timeout is the Idle period + this value.
-const uint32 kReadNATTimeoutSeconds = 10;
-// This is the timeout for PACKET_SIZE_TEST.
-const uint32 kReadPacketSizeTimeoutSeconds = 10;
-// This is the maxmium number of packets we would send for PACKET_SIZE_TEST.
-uint32 kMaximumPacketSizeTestPackets = 1;
-
-// These helper functions are similar to UMA_HISTOGRAM_XXX except that they do
-// not create a static histogram_pointer.
-void DynamicHistogramEnumeration(const std::string& name,
- uint32 sample,
- uint32 boundary_value) {
- base::HistogramBase* histogram_pointer = base::LinearHistogram::FactoryGet(
- name,
- 1,
- boundary_value,
- boundary_value + 1,
- base::HistogramBase::kUmaTargetedHistogramFlag);
- histogram_pointer->Add(sample);
-}
-
-void DynamicHistogramTimes(const std::string& name,
- const base::TimeDelta& sample) {
- base::HistogramBase* histogram_pointer = base::Histogram::FactoryTimeGet(
- name,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromSeconds(30),
- 50,
- base::HistogramBase::kUmaTargetedHistogramFlag);
- histogram_pointer->AddTime(sample);
-}
-
-void DynamicHistogramCounts(const std::string& name,
- uint32 sample,
- uint32 min,
- uint32 max,
- uint32 bucket_count) {
- base::HistogramBase* histogram_pointer = base::Histogram::FactoryGet(
- name, min, max, bucket_count,
- base::HistogramBase::kUmaTargetedHistogramFlag);
- histogram_pointer->Add(sample);
-}
-
-NetworkStats::NetworkStats(net::ClientSocketFactory* socket_factory)
- : socket_factory_(socket_factory),
- histogram_port_(0),
- has_proxy_server_(false),
- probe_packet_bytes_(0),
- bytes_for_packet_size_test_(0),
- current_test_index_(0),
- read_state_(READ_STATE_IDLE),
- write_state_(WRITE_STATE_IDLE),
- weak_factory_(this) {
- ResetData();
-}
-
-NetworkStats::~NetworkStats() {}
-
-bool NetworkStats::Start(net::HostResolver* host_resolver,
- const net::HostPortPair& server_host_port_pair,
- uint16 histogram_port,
- bool has_proxy_server,
- uint32 probe_bytes,
- uint32 bytes_for_packet_size_test,
- const net::CompletionCallback& finished_callback) {
- DCHECK(host_resolver);
- histogram_port_ = histogram_port;
- has_proxy_server_ = has_proxy_server;
- probe_packet_bytes_ = probe_bytes;
- bytes_for_packet_size_test_ = bytes_for_packet_size_test;
- finished_callback_ = finished_callback;
- test_sequence_.clear();
- test_sequence_.push_back(TOKEN_REQUEST);
-
- ResetData();
-
- scoped_ptr<net::SingleRequestHostResolver> resolver(
- new net::SingleRequestHostResolver(host_resolver));
- net::HostResolver::RequestInfo request(server_host_port_pair);
- int rv =
- resolver->Resolve(request,
- net::DEFAULT_PRIORITY,
- &addresses_,
- base::Bind(base::IgnoreResult(&NetworkStats::DoConnect),
- base::Unretained(this)),
- net::BoundNetLog());
- if (rv == net::ERR_IO_PENDING) {
- resolver_.swap(resolver);
- return true;
- }
- return DoConnect(rv);
-}
-
-void NetworkStats::StartOneTest() {
- if (test_sequence_[current_test_index_] == TOKEN_REQUEST) {
- DCHECK_EQ(WRITE_STATE_IDLE, write_state_);
- write_buffer_ = NULL;
- SendHelloRequest();
- } else {
- SendProbeRequest();
- }
-}
-
-void NetworkStats::ResetData() {
- DCHECK_EQ(WRITE_STATE_IDLE, write_state_);
- write_buffer_ = NULL;
- packets_received_mask_.reset();
- first_arrival_time_ = base::TimeTicks();
- last_arrival_time_ = base::TimeTicks();
-
- packet_rtt_.clear();
- packet_rtt_.resize(maximum_sequential_packets_);
- probe_request_time_ = base::TimeTicks();
- // Note: inter_arrival_time_ should not be reset here because it is used in
- // subsequent tests.
-}
-
-bool NetworkStats::DoConnect(int result) {
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/436634 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION("436634 NetworkStats::DoConnect"));
-
- if (result != net::OK) {
- TestPhaseComplete(RESOLVE_FAILED, result);
- return false;
- }
-
- scoped_ptr<net::DatagramClientSocket> udp_socket =
- socket_factory_->CreateDatagramClientSocket(
- net::DatagramSocket::DEFAULT_BIND,
- net::RandIntCallback(),
- NULL,
- net::NetLog::Source());
- DCHECK(udp_socket);
- DCHECK(!socket_);
- socket_ = udp_socket.Pass();
-
- const net::IPEndPoint& endpoint = addresses_.front();
- int rv = socket_->Connect(endpoint);
- if (rv < 0) {
- TestPhaseComplete(CONNECT_FAILED, rv);
- return false;
- }
-
- socket_->SetSendBufferSize(kMaxUdpSendBufferSize);
- socket_->SetReceiveBufferSize(kMaxUdpReceiveBufferSize);
- return ConnectComplete(rv);
-}
-
-bool NetworkStats::ConnectComplete(int result) {
- if (result < 0) {
- TestPhaseComplete(CONNECT_FAILED, result);
- return false;
- }
-
- if (start_test_after_connect_) {
- // Reads data for all HelloReply and all subsequent probe tests.
- if (ReadData() != net::ERR_IO_PENDING) {
- TestPhaseComplete(READ_FAILED, result);
- return false;
- }
- SendHelloRequest();
- } else {
- // For unittesting. Only run the callback, do not destroy it.
- if (!finished_callback_.is_null())
- finished_callback_.Run(result);
- }
- return true;
-}
-
-void NetworkStats::SendHelloRequest() {
- StartReadDataTimer(kGetTokenTimeoutSeconds, current_test_index_);
- ProbePacket probe_packet;
- probe_message_.SetPacketHeader(ProbePacket_Type_HELLO_REQUEST, &probe_packet);
- probe_packet.set_group_id(current_test_index_);
- std::string output = probe_message_.MakeEncodedPacket(probe_packet);
-
- int result = SendData(output);
- if (result < 0 && result != net::ERR_IO_PENDING)
- TestPhaseComplete(WRITE_FAILED, result);
-}
-
-void NetworkStats::SendProbeRequest() {
- ResetData();
- // Use default timeout except for the NAT bind test.
- uint32 timeout_seconds = kReadDataTimeoutSeconds;
- uint32 number_packets = maximum_sequential_packets_;
- uint32 probe_bytes = probe_packet_bytes_;
- pacing_interval_ = base::TimeDelta();
- switch (test_sequence_[current_test_index_]) {
- case START_PACKET_TEST:
- case NON_PACED_PACKET_TEST:
- break;
- case PACED_PACKET_TEST: {
- pacing_interval_ =
- std::min(inter_arrival_time_,
- base::TimeDelta::FromMicroseconds(kMaximumPacingMicros));
- timeout_seconds += pacing_interval_.InMicroseconds() *
- (maximum_sequential_packets_ - 1) / 1000000;
- break;
- }
- case NAT_BIND_TEST: {
- // Make sure no integer overflow.
- DCHECK_LE(maximum_NAT_idle_seconds_, 4000U);
- int nat_test_idle_seconds = base::RandInt(1, maximum_NAT_idle_seconds_);
- pacing_interval_ = base::TimeDelta::FromSeconds(nat_test_idle_seconds);
- timeout_seconds = nat_test_idle_seconds + kReadNATTimeoutSeconds;
- number_packets = maximum_NAT_packets_;
- break;
- }
- case PACKET_SIZE_TEST: {
- number_packets = kMaximumPacketSizeTestPackets;
- probe_bytes = bytes_for_packet_size_test_;
- timeout_seconds = kReadPacketSizeTimeoutSeconds;
- break;
- }
- default:
- NOTREACHED();
- return;
- }
- DVLOG(1) << "NetworkStat: Probe pacing " << pacing_interval_.InMicroseconds()
- << " microseconds. Time out " << timeout_seconds << " seconds";
- ProbePacket probe_packet;
- probe_message_.GenerateProbeRequest(token_,
- current_test_index_,
- probe_bytes,
- pacing_interval_.InMicroseconds(),
- number_packets,
- &probe_packet);
- std::string output = probe_message_.MakeEncodedPacket(probe_packet);
-
- StartReadDataTimer(timeout_seconds, current_test_index_);
- probe_request_time_ = base::TimeTicks::Now();
- int result = SendData(output);
- if (result < 0 && result != net::ERR_IO_PENDING)
- TestPhaseComplete(WRITE_FAILED, result);
-}
-
-int NetworkStats::ReadData() {
- if (!socket_.get())
- return 0;
-
- if (read_state_ == READ_STATE_READ_PENDING)
- return net::ERR_IO_PENDING;
-
- int rv = 0;
- while (true) {
- DCHECK(!read_buffer_.get());
- read_buffer_ = new net::IOBuffer(kMaxMessageSize);
-
- rv = socket_->Read(
- read_buffer_.get(),
- kMaxMessageSize,
- base::Bind(&NetworkStats::OnReadComplete, weak_factory_.GetWeakPtr()));
- if (rv <= 0)
- break;
- if (ReadComplete(rv))
- return rv;
- }
- if (rv == net::ERR_IO_PENDING)
- read_state_ = READ_STATE_READ_PENDING;
- return rv;
-}
-
-void NetworkStats::OnReadComplete(int result) {
- DCHECK_NE(net::ERR_IO_PENDING, result);
- DCHECK_EQ(READ_STATE_READ_PENDING, read_state_);
-
- read_state_ = READ_STATE_IDLE;
- if (!ReadComplete(result)) {
- // Called ReadData() via PostDelayedTask() to avoid recursion. Added a delay
- // of 1ms so that the time-out will fire before we have time to really hog
- // the CPU too extensively (waiting for the time-out) in case of an infinite
- // loop.
- base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(&NetworkStats::ReadData),
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(1));
- }
-}
-
-bool NetworkStats::ReadComplete(int result) {
- DCHECK(socket_.get());
- DCHECK_NE(net::ERR_IO_PENDING, result);
- if (result < 0) {
- // Something is wrong, finish the test.
- read_buffer_ = NULL;
- TestPhaseComplete(READ_FAILED, result);
- return true;
- }
-
- std::string encoded_message(read_buffer_->data(),
- read_buffer_->data() + result);
- read_buffer_ = NULL;
- ProbePacket probe_packet;
- if (!probe_message_.ParseInput(encoded_message, &probe_packet))
- return false;
- // Discard if the packet is for a different test.
- if (probe_packet.group_id() != current_test_index_)
- return false;
-
- // Whether all packets in the current test have been received.
- bool current_test_complete = false;
- switch (probe_packet.header().type()) {
- case ProbePacket_Type_HELLO_REPLY:
- token_ = probe_packet.token();
- if (current_test_index_ == 0)
- test_sequence_.push_back(START_PACKET_TEST);
- current_test_complete = true;
- break;
- case ProbePacket_Type_PROBE_REPLY:
- current_test_complete = UpdateReception(probe_packet);
- break;
- default:
- DVLOG(1) << "Received unexpected packet type: "
- << probe_packet.header().type();
- }
-
- if (!current_test_complete) {
- // All packets have not been received for the current test.
- return false;
- }
- // All packets are received for the current test.
- // Read completes if all tests are done (if TestPhaseComplete didn't start
- // another test).
- return TestPhaseComplete(SUCCESS, net::OK);
-}
-
-bool NetworkStats::UpdateReception(const ProbePacket& probe_packet) {
- uint32 packet_index = probe_packet.packet_index();
- if (packet_index >= packet_rtt_.size())
- return false;
- packets_received_mask_.set(packet_index);
- TestType test_type = test_sequence_[current_test_index_];
- uint32 received_packets = packets_received_mask_.count();
-
- base::TimeTicks current_time = base::TimeTicks::Now();
- last_arrival_time_ = current_time;
- if (first_arrival_time_.is_null())
- first_arrival_time_ = current_time;
-
- // Need to do this after updating the last_arrival_time_ since NAT_BIND_TEST
- // and PACKET_SIZE_TEST record the SendToLastRecvDelay.
- if (test_type == NAT_BIND_TEST) {
- return received_packets >= maximum_NAT_packets_;
- }
- if (test_type == PACKET_SIZE_TEST) {
- return received_packets >= kMaximumPacketSizeTestPackets;
- }
-
- base::TimeDelta rtt =
- current_time - probe_request_time_ -
- base::TimeDelta::FromMicroseconds(std::max(
- static_cast<int64>(0), probe_packet.server_processing_micros()));
- base::TimeDelta min_rtt = base::TimeDelta::FromMicroseconds(1L);
- packet_rtt_[packet_index] = (rtt >= min_rtt) ? rtt : min_rtt;
-
- if (received_packets < maximum_sequential_packets_)
- return false;
- // All packets in the current test are received.
- inter_arrival_time_ = (last_arrival_time_ - first_arrival_time_) /
- std::max(1U, (received_packets - 1));
- if (test_type == START_PACKET_TEST) {
- test_sequence_.push_back(PACKET_SIZE_TEST);
- test_sequence_.push_back(TOKEN_REQUEST);
- // No need to add TOKEN_REQUEST here when all packets are received.
- test_sequence_.push_back(base::RandInt(0, 1) ? PACED_PACKET_TEST
- : NON_PACED_PACKET_TEST);
- test_sequence_.push_back(TOKEN_REQUEST);
- test_sequence_.push_back(NAT_BIND_TEST);
- test_sequence_.push_back(TOKEN_REQUEST);
- }
- return true;
-}
-
-int NetworkStats::SendData(const std::string& output) {
- if (write_buffer_.get() || !socket_.get() ||
- write_state_ == WRITE_STATE_WRITE_PENDING) {
- return net::ERR_UNEXPECTED;
- }
- scoped_refptr<net::StringIOBuffer> buffer(new net::StringIOBuffer(output));
- write_buffer_ = new net::DrainableIOBuffer(buffer.get(), buffer->size());
-
- int bytes_written = socket_->Write(
- write_buffer_.get(),
- write_buffer_->BytesRemaining(),
- base::Bind(&NetworkStats::OnWriteComplete, weak_factory_.GetWeakPtr()));
- if (bytes_written < 0) {
- if (bytes_written == net::ERR_IO_PENDING)
- write_state_ = WRITE_STATE_WRITE_PENDING;
- return bytes_written;
- }
- UpdateSendBuffer(bytes_written);
- return net::OK;
-}
-
-void NetworkStats::OnWriteComplete(int result) {
- DCHECK_NE(net::ERR_IO_PENDING, result);
- DCHECK_EQ(WRITE_STATE_WRITE_PENDING, write_state_);
- write_state_ = WRITE_STATE_IDLE;
- if (result < 0 || !socket_.get() || write_buffer_.get() == NULL) {
- TestPhaseComplete(WRITE_FAILED, result);
- return;
- }
- UpdateSendBuffer(result);
-}
-
-void NetworkStats::UpdateSendBuffer(int bytes_sent) {
- write_buffer_->DidConsume(bytes_sent);
- DCHECK_EQ(write_buffer_->BytesRemaining(), 0);
- DCHECK_EQ(WRITE_STATE_IDLE, write_state_);
- write_buffer_ = NULL;
-}
-
-void NetworkStats::StartReadDataTimer(uint32 seconds, uint32 test_index) {
- base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&NetworkStats::OnReadDataTimeout,
- weak_factory_.GetWeakPtr(),
- test_index),
- base::TimeDelta::FromSeconds(seconds));
-}
-
-void NetworkStats::OnReadDataTimeout(uint32 test_index) {
- // If the current_test_index_ has changed since we set the timeout,
- // the current test has been completed, so do nothing.
- if (test_index != current_test_index_)
- return;
- // If test_type is TOKEN_REQUEST, it will do nothing but call
- // TestPhaseComplete().
- TestType test_type = test_sequence_[current_test_index_];
-
- uint32 received_packets = packets_received_mask_.count();
- if (received_packets >= 2) {
- inter_arrival_time_ =
- (last_arrival_time_ - first_arrival_time_) / (received_packets - 1);
- }
- // Add other tests if this is START_PACKET_TEST.
- if (test_type == START_PACKET_TEST) {
- if (received_packets >= kMinimumReceivedPacketsForPacingTest) {
- test_sequence_.push_back(TOKEN_REQUEST);
- test_sequence_.push_back(PACKET_SIZE_TEST);
- test_sequence_.push_back(TOKEN_REQUEST);
- test_sequence_.push_back(base::RandInt(0, 1) ? PACED_PACKET_TEST
- : NON_PACED_PACKET_TEST);
- }
- if (received_packets >= kMinimumReceivedPacketsForNATTest) {
- test_sequence_.push_back(TOKEN_REQUEST);
- test_sequence_.push_back(NAT_BIND_TEST);
- test_sequence_.push_back(TOKEN_REQUEST);
- }
- }
- TestPhaseComplete(READ_TIMED_OUT, net::ERR_FAILED);
-}
-
-bool NetworkStats::TestPhaseComplete(Status status, int result) {
- // If there is no valid token, do nothing and delete self.
- // This includes all connection error, name resolve error, etc.
- if (write_state_ == WRITE_STATE_WRITE_PENDING) {
- UMA_HISTOGRAM_BOOLEAN("NetConnectivity5.TestFailed.WritePending", true);
- } else if (status == SUCCESS || status == READ_TIMED_OUT) {
- TestType current_test = test_sequence_[current_test_index_];
- DCHECK_LT(current_test, TEST_TYPE_MAX);
- if (current_test != TOKEN_REQUEST) {
- RecordHistograms(current_test);
- } else if (current_test_index_ > 0) {
- if (test_sequence_[current_test_index_ - 1] == NAT_BIND_TEST) {
- // We record the NATTestReceivedHistograms after the succeeding
- // TokenRequest.
- RecordNATTestReceivedHistograms(status);
- } else if (test_sequence_[current_test_index_ - 1] == PACKET_SIZE_TEST) {
- // We record the PacketSizeTestReceivedHistograms after the succeeding
- // TokenRequest.
- RecordPacketSizeTestReceivedHistograms(status);
- }
- }
-
- // Move to the next test.
- current_test = GetNextTest();
- if (current_test_index_ <= maximum_tests_ && current_test < TEST_TYPE_MAX) {
- DVLOG(1) << "NetworkStat: Start Probe test: " << current_test;
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&NetworkStats::StartOneTest, weak_factory_.GetWeakPtr()));
- return false;
- }
- }
-
- // All tests are done.
- DoFinishCallback(result);
-
- // Close the socket so that there are no more IO operations.
- if (socket_.get())
- socket_->Close();
-
- DVLOG(1) << "NetworkStat: schedule delete self at test index "
- << current_test_index_;
- delete this;
- return true;
-}
-
-NetworkStats::TestType NetworkStats::GetNextTest() {
- ++current_test_index_;
- if (current_test_index_ >= test_sequence_.size())
- return TEST_TYPE_MAX;
- return test_sequence_[current_test_index_];
-}
-
-void NetworkStats::DoFinishCallback(int result) {
- if (!finished_callback_.is_null()) {
- net::CompletionCallback callback = finished_callback_;
- finished_callback_.Reset();
- callback.Run(result);
- }
-}
-
-void NetworkStats::RecordHistograms(TestType test_type) {
- switch (test_type) {
- case START_PACKET_TEST:
- case NON_PACED_PACKET_TEST:
- case PACED_PACKET_TEST: {
- RecordInterArrivalHistograms(test_type);
- RecordPacketLossSeriesHistograms(test_type);
- RecordPacketsReceivedHistograms(test_type);
- // Only record RTT for these packet indices.
- uint32 rtt_indices[] = {0, 1, 2, 9, 19};
- for (uint32 i = 0; i < arraysize(rtt_indices); ++i) {
- if (rtt_indices[i] < packet_rtt_.size())
- RecordRTTHistograms(test_type, rtt_indices[i]);
- }
- RecordSendToLastRecvDelayHistograms(test_type);
- return;
- }
- case NAT_BIND_TEST:
- RecordSendToLastRecvDelayHistograms(test_type);
- return;
- case PACKET_SIZE_TEST:
- // No need to record RTT for PacketSizeTest.
- return;
- default:
- DVLOG(1) << "Unexpected test type " << test_type
- << " in RecordHistograms.";
- }
-}
-
-void NetworkStats::RecordInterArrivalHistograms(TestType test_type) {
- DCHECK_NE(test_type, PACKET_SIZE_TEST);
- std::string histogram_name =
- base::StringPrintf("NetConnectivity5.%s.Sent%d.PacketDelay.%d.%dB",
- kTestName[test_type],
- maximum_sequential_packets_,
- histogram_port_,
- probe_packet_bytes_);
- // Record the time normalized to 20 packet inter-arrivals.
- DynamicHistogramTimes(histogram_name, inter_arrival_time_ * 20);
-}
-
-void NetworkStats::RecordPacketsReceivedHistograms(TestType test_type) {
- DCHECK_NE(test_type, PACKET_SIZE_TEST);
- const char* test_name = kTestName[test_type];
- std::string histogram_prefix = base::StringPrintf(
- "NetConnectivity5.%s.Sent%d.", test_name, maximum_sequential_packets_);
- std::string histogram_suffix =
- base::StringPrintf(".%d.%dB", histogram_port_, probe_packet_bytes_);
- std::string name = histogram_prefix + "GotAPacket" + histogram_suffix;
- base::HistogramBase* histogram_pointer = base::BooleanHistogram::FactoryGet(
- name, base::HistogramBase::kUmaTargetedHistogramFlag);
- histogram_pointer->Add(packets_received_mask_.any());
-
- DynamicHistogramEnumeration(
- histogram_prefix + "PacketsRecv" + histogram_suffix,
- packets_received_mask_.count(),
- maximum_sequential_packets_ + 1);
-
- if (!packets_received_mask_.any())
- return;
-
- base::HistogramBase* received_nth_packet_histogram =
- base::Histogram::FactoryGet(
- histogram_prefix + "RecvNthPacket" + histogram_suffix,
- 1,
- maximum_sequential_packets_ + 1,
- maximum_sequential_packets_ + 2,
- base::HistogramBase::kUmaTargetedHistogramFlag);
-
- int count = 0;
- for (size_t j = 0; j < maximum_sequential_packets_; ++j) {
- int packet_number = j + 1;
- if (packets_received_mask_.test(j)) {
- received_nth_packet_histogram->Add(packet_number);
- ++count;
- }
- std::string histogram_name =
- base::StringPrintf("%sNumRecvFromFirst%02dPackets%s",
- histogram_prefix.c_str(),
- packet_number,
- histogram_suffix.c_str());
- DynamicHistogramEnumeration(histogram_name, count, packet_number + 1);
- }
-}
-
-void NetworkStats::RecordNATTestReceivedHistograms(Status status) {
- const char* test_name = kTestName[NAT_BIND_TEST];
- bool test_result = status == SUCCESS;
- std::string middle_name = test_result ? "Connectivity.Success"
- : "Connectivity.Failure";
- // Record whether the HelloRequest got reply successfully.
- std::string histogram_name =
- base::StringPrintf("NetConnectivity5.%s.Sent%d.%s.%d.%dB",
- test_name,
- maximum_NAT_packets_,
- middle_name.c_str(),
- histogram_port_,
- probe_packet_bytes_);
- uint32 bucket_count = std::min(maximum_NAT_idle_seconds_ + 2, 50U);
- DynamicHistogramCounts(histogram_name,
- pacing_interval_.InSeconds(),
- 1,
- maximum_NAT_idle_seconds_ + 1,
- bucket_count);
-
- // Record the NAT bind result only if the HelloRequest successfully got the
- // token and the first NAT test packet is received.
- if (!test_result || !packets_received_mask_.test(0))
- return;
-
- middle_name = packets_received_mask_.test(1) ? "Bind.Success"
- : "Bind.Failure";
- histogram_name = base::StringPrintf("NetConnectivity5.%s.Sent%d.%s.%d.%dB",
- test_name,
- maximum_NAT_packets_,
- middle_name.c_str(),
- histogram_port_,
- probe_packet_bytes_);
- DynamicHistogramCounts(histogram_name,
- pacing_interval_.InSeconds(),
- 1,
- maximum_NAT_idle_seconds_ + 1,
- bucket_count);
-}
-
-void NetworkStats::RecordPacketSizeTestReceivedHistograms(Status status) {
- const char* test_name = kTestName[PACKET_SIZE_TEST];
- bool test_result = (status == SUCCESS && packets_received_mask_.test(0));
- std::string middle_name = test_result ? "Connectivity.Success"
- : "Connectivity.Failure";
- // Record whether the HelloRequest got reply successfully.
- std::string histogram_name =
- base::StringPrintf("NetConnectivity5.%s.%s.%d",
- test_name,
- middle_name.c_str(),
- histogram_port_);
- base::HistogramBase* histogram_pointer = base::LinearHistogram::FactoryGet(
- histogram_name, kProbePacketBytes[kPacketSizeChoices - 1],
- ProbeMessage::kMaxProbePacketBytes, 60,
- base::HistogramBase::kUmaTargetedHistogramFlag);
- histogram_pointer->Add(bytes_for_packet_size_test_);
-}
-
-void NetworkStats::RecordPacketLossSeriesHistograms(TestType test_type) {
- DCHECK_NE(test_type, PACKET_SIZE_TEST);
- const char* test_name = kTestName[test_type];
- // Build "NetConnectivity5.<TestName>.First6.SeriesRecv.<port>.<probe_size>"
- // histogram name. Total 3(tests) x 12 histograms.
- std::string series_acked_histogram_name =
- base::StringPrintf("NetConnectivity5.%s.First6.SeriesRecv.%d.%dB",
- test_name,
- histogram_port_,
- probe_packet_bytes_);
- uint32 histogram_boundary = 1 << kCorrelatedLossPacketCount;
- uint32 correlated_packet_mask =
- (histogram_boundary - 1) & packets_received_mask_.to_ulong();
- DynamicHistogramEnumeration(
- series_acked_histogram_name, correlated_packet_mask, histogram_boundary);
-
- // If we are running without a proxy, we'll generate an extra histogram with
- // the ".NoProxy" suffix.
- if (!has_proxy_server_) {
- series_acked_histogram_name.append(".NoProxy");
- DynamicHistogramEnumeration(series_acked_histogram_name,
- correlated_packet_mask,
- histogram_boundary);
- }
-}
-
-void NetworkStats::RecordRTTHistograms(TestType test_type, uint32 index) {
- DCHECK_NE(test_type, PACKET_SIZE_TEST);
- DCHECK_LT(index, packet_rtt_.size());
-
- if (!packets_received_mask_.test(index))
- return; // Probe packet never received.
-
- std::string rtt_histogram_name = base::StringPrintf(
- "NetConnectivity5.%s.Sent%d.Success.RTT.Packet%02d.%d.%dB",
- kTestName[test_type],
- maximum_sequential_packets_,
- index + 1,
- histogram_port_,
- probe_packet_bytes_);
- DynamicHistogramTimes(rtt_histogram_name, packet_rtt_[index]);
-}
-
-void NetworkStats::RecordSendToLastRecvDelayHistograms(TestType test_type) {
- DCHECK_NE(test_type, PACKET_SIZE_TEST);
- if (packets_received_mask_.count() < 2)
- return; // Too few packets are received.
- uint32 packets_sent = test_type == NAT_BIND_TEST
- ? maximum_NAT_packets_ : maximum_sequential_packets_;
- std::string histogram_name = base::StringPrintf(
- "NetConnectivity5.%s.Sent%d.SendToLastRecvDelay.%d.%dB",
- kTestName[test_type],
- packets_sent,
- histogram_port_,
- probe_packet_bytes_);
- base::TimeDelta send_to_last_recv_time =
- std::max(last_arrival_time_ - probe_request_time_ -
- pacing_interval_ * (packets_sent - 1),
- base::TimeDelta::FromMilliseconds(0));
- DynamicHistogramTimes(histogram_name, send_to_last_recv_time);
-}
-
-// ProxyDetector methods and members.
-ProxyDetector::ProxyDetector(net::ProxyService* proxy_service,
- const net::HostPortPair& server_address,
- OnResolvedCallback callback)
- : proxy_service_(proxy_service),
- server_address_(server_address),
- callback_(callback),
- has_pending_proxy_resolution_(false) {}
-
-ProxyDetector::~ProxyDetector() {
- CHECK(!has_pending_proxy_resolution_);
-}
-
-void ProxyDetector::StartResolveProxy() {
- std::string url =
- base::StringPrintf("https://%s", server_address_.ToString().c_str());
- GURL gurl(url);
-
- has_pending_proxy_resolution_ = true;
- DCHECK(proxy_service_);
- int rv = proxy_service_->ResolveProxy(
- gurl,
- net::LOAD_NORMAL,
- &proxy_info_,
- base::Bind(&ProxyDetector::OnResolveProxyComplete,
- base::Unretained(this)),
- NULL,
- NULL,
- net::BoundNetLog());
- if (rv != net::ERR_IO_PENDING)
- OnResolveProxyComplete(rv);
-}
-
-void ProxyDetector::OnResolveProxyComplete(int result) {
- has_pending_proxy_resolution_ = false;
- bool has_proxy_server =
- (result == net::OK && proxy_info_.proxy_server().is_valid() &&
- !proxy_info_.proxy_server().is_direct());
-
- OnResolvedCallback callback = callback_;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE, base::Bind(callback, has_proxy_server));
-
- // TODO(rtenneti): Will we leak if ProxyResolve is cancelled (or proxy
- // resolution never completes).
- delete this;
-}
-
-void CollectNetworkStats(const std::string& network_stats_server,
- IOThread* io_thread) {
- if (network_stats_server.empty())
- return;
-
- // If we are not on IO Thread, then post a task to call CollectNetworkStats on
- // IO Thread.
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&CollectNetworkStats, network_stats_server, io_thread));
- return;
- }
-
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- if (net::NetworkChangeNotifier::IsOffline()) {
- return;
- }
-
- CR_DEFINE_STATIC_LOCAL(scoped_refptr<base::FieldTrial>, trial, ());
- static bool collect_stats = false;
-
- if (!trial.get()) {
- // Set up a field trial to collect network stats for UDP.
- const base::FieldTrial::Probability kDivisor = 1000;
-
- // Enable the connectivity testing for 0.5% of the users in stable channel.
- base::FieldTrial::Probability probability_per_group = kDivisor / 200;
-
- chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
- if (channel == chrome::VersionInfo::CHANNEL_CANARY) {
- // Enable the connectivity testing for 50% of the users in canary channel.
- probability_per_group = kDivisor / 2;
- } else if (channel == chrome::VersionInfo::CHANNEL_DEV) {
- // Enable the connectivity testing for 10% of the users in dev channel.
- probability_per_group = kDivisor / 10;
- } else if (channel == chrome::VersionInfo::CHANNEL_BETA) {
- // Enable the connectivity testing for 1% of the users in beta channel.
- probability_per_group = kDivisor / 100;
- }
-
- // After July 31, 2014 builds, it will always be in default group
- // (disable_network_stats).
- trial = base::FieldTrialList::FactoryGetFieldTrial(
- "NetworkConnectivity", kDivisor, "disable_network_stats",
- 2014, 7, 31, base::FieldTrial::SESSION_RANDOMIZED, NULL);
-
- // Add option to collect_stats for NetworkConnectivity.
- int collect_stats_group =
- trial->AppendGroup("collect_stats", probability_per_group);
- if (trial->group() == collect_stats_group)
- collect_stats = true;
- }
-
- if (!collect_stats)
- return;
-
- // Run test kMaxNumberOfTests times.
- const size_t kMaxNumberOfTests = INT_MAX;
- static size_t number_of_tests_done = 0;
- if (number_of_tests_done > kMaxNumberOfTests)
- return;
- ++number_of_tests_done;
-
- net::HostResolver* host_resolver = io_thread->globals()->host_resolver.get();
- DCHECK(host_resolver);
-
- uint32 port_index = base::RandInt(0, arraysize(kPorts) - 1);
- uint16 histogram_port = kPorts[port_index];
- net::HostPortPair server_address(network_stats_server, histogram_port);
-
- net::ProxyService* proxy_service =
- io_thread->globals()->system_proxy_service.get();
- DCHECK(proxy_service);
-
- ProxyDetector::OnResolvedCallback callback = base::Bind(
- &StartNetworkStatsTest, host_resolver, server_address, histogram_port);
-
- ProxyDetector* proxy_client =
- new ProxyDetector(proxy_service, server_address, callback);
- proxy_client->StartResolveProxy();
-}
-
-void StartNetworkStatsTest(net::HostResolver* host_resolver,
- const net::HostPortPair& server_address,
- uint16 histogram_port,
- bool has_proxy_server) {
- int probe_choice = base::RandInt(0, kPacketSizeChoices - 1);
-
- DCHECK_LE(ProbeMessage::kMaxProbePacketBytes, kMaxMessageSize);
- // Pick a packet size between 1200 and kMaxProbePacketBytes bytes.
- uint32 bytes_for_packet_size_test =
- base::RandInt(kProbePacketBytes[kPacketSizeChoices - 1],
- ProbeMessage::kMaxProbePacketBytes);
-
- // |udp_stats_client| is owned and deleted in the class NetworkStats.
- NetworkStats* udp_stats_client =
- new NetworkStats(net::ClientSocketFactory::GetDefaultFactory());
- udp_stats_client->Start(host_resolver,
- server_address,
- histogram_port,
- has_proxy_server,
- kProbePacketBytes[probe_choice],
- bytes_for_packet_size_test,
- net::CompletionCallback());
-}
-
-} // namespace chrome_browser_net

Powered by Google App Engine
This is Rietveld 408576698