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

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

Issue 10913037: Network connectivity - packet pacing and FEC tests for packet loss. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 3 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
« no previous file with comments | « no previous file | chrome/browser/net/network_stats.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/net/network_stats.h
===================================================================
--- chrome/browser/net/network_stats.h (revision 152367)
+++ chrome/browser/net/network_stats.h (working copy)
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_NET_NETWORK_STATS_H_
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
@@ -22,27 +23,26 @@
#include "net/base/test_data_stream.h"
#include "net/proxy/proxy_info.h"
#include "net/socket/socket.h"
+
namespace chrome_browser_net {
-// This class is used for live experiment of network connectivity (either TCP or
-// UDP) metrics. A small percentage of users participate in this experiment. All
+// This class is used for live experiment of network connectivity (for UDP)
+// metrics. A small percentage of users participate in this experiment. All
// users (who are in the experiment) must have enabled "UMA upload".
//
// This class collects the following stats from users who have opted in.
-// a) What percentage of users can get a message end-to-end to a UDP server?
-// b) What percentage of users can get a message end-to-end to a TCP server?
-// c) What is the latency for UDP and TCP.
-// d) If connectivity failed, at what stage (Connect or Write or Read) did it
-// fail?
+// a) Success/failure, to estimate reachability for users.
+// b) RTT for some select set of messages.
+// c) Perform packet loss tests for correlation and FEC experiments.
//
// The following is the overview of the echo message protocol.
//
-// We send the "echo request" to the TCP/UDP servers in the following format:
+// We send the "echo request" to the UDP echo servers in the following format:
// <version><checksum><payload_size><payload>. <version> is the version number
// of the "echo request". <checksum> is the checksum of the <payload>.
// <payload_size> specifies the number of bytes in the <payload>.
//
-// TCP/UDP servers respond to the "echo request" by returning "echo response".
+// UDP echo servers respond to the "echo request" by returning "echo response".
// "echo response" is of the format:
// "<version><checksum><payload_size><key><encoded_payload>". <payload_size>
// specifies the number of bytes in the <encoded_payload>. <key> is used to
@@ -50,47 +50,66 @@
class NetworkStats {
public:
- enum Status { // Used in HISTOGRAM_ENUMERATION.
- SUCCESS, // Successfully received bytes from the server.
- IP_STRING_PARSE_FAILED, // Parsing of IP string failed.
- SOCKET_CREATE_FAILED, // Socket creation failed.
- RESOLVE_FAILED, // Host resolution failed.
- CONNECT_FAILED, // Connection to the server failed.
- WRITE_FAILED, // Sending an echo message to the server failed.
- READ_TIMED_OUT, // Reading the reply from the server timed out.
- READ_FAILED, // Reading the reply from the server failed.
- ZERO_LENGTH_ERROR, // Zero length message.
- NO_CHECKSUM_ERROR, // Message doesn't have a checksum.
- NO_KEY_ERROR, // Message doesn't have a key.
- NO_PAYLOAD_SIZE_ERROR, // Message doesn't have a payload size.
- NO_PAYLOAD_ERROR, // Message doesn't have a payload.
- INVALID_KEY_ERROR, // Invalid key in the message.
- TOO_SHORT_PAYLOAD, // Message is shorter than payload.
- TOO_LONG_PAYLOAD, // Message is longer than payload.
- INVALID_CHECKSUM, // Checksum verification failed.
- PATTERN_CHANGED, // Pattern in payload has changed.
- INVALID_PACKET_NUMBER, // Packet number didn't match.
- TOO_MANY_PACKETS, // Received more packets than the packets sent.
- STATUS_MAX, // Bounding value.
+ enum Status { // Used in HISTOGRAM_ENUMERATION.
+ SUCCESS, // Successfully received bytes from the server.
+ IP_STRING_PARSE_FAILED, // Parsing of IP string failed.
+ SOCKET_CREATE_FAILED, // Socket creation failed.
+ RESOLVE_FAILED, // Host resolution failed.
+ CONNECT_FAILED, // Connection to the server failed.
+ WRITE_FAILED, // Sending an echo message to the server failed.
+ READ_TIMED_OUT, // Reading the reply from the server timed out.
+ READ_FAILED, // Reading the reply from the server failed.
+ ZERO_LENGTH_ERROR, // Zero length message.
+ NO_CHECKSUM_ERROR, // Message doesn't have a checksum.
+ NO_KEY_ERROR, // Message doesn't have a key.
+ NO_PAYLOAD_SIZE_ERROR, // Message doesn't have a payload size.
+ NO_PAYLOAD_ERROR, // Message doesn't have a payload.
+ INVALID_KEY_ERROR, // Invalid key in the message.
+ TOO_SHORT_PAYLOAD, // Message is shorter than payload.
+ TOO_LONG_PAYLOAD, // Message is longer than payload.
+ INVALID_CHECKSUM, // Checksum verification failed.
+ PATTERN_CHANGED, // Pattern in payload has changed.
+ INVALID_PACKET_NUMBER, // Packet number didn't match.
+ TOO_MANY_PACKETS, // Received more packets than the packets sent.
+ PREVIOUS_PACKET_NUMBER, // Received a packet from an earlier test.
+ DUPLICATE_PACKET, // Received a duplicate packet.
+ SOME_PACKETS_NOT_VERIFIED, // Some packets have failed verification.
+ STATUS_MAX, // Bounding value.
};
// |ProtocolValue| enumerates different protocols that are being tested.
enum ProtocolValue {
- PROTOCOL_TCP,
PROTOCOL_UDP,
};
// |HistogramPortSelector| enumerates list of ports that are used for network
- // connectivity tests (either TCP or UDP).
+ // connectivity tests (for UDP). Currently we are testing port 6121 only.
enum HistogramPortSelector {
- PORT_53 = 0, // DNS
- PORT_80, // HTTP
- PORT_587, // SMTP Submission.
- PORT_6121, // SPDY
- PORT_8080, // High order webserver.
+ PORT_6121 = 0, // SPDY
HISTOGRAM_PORT_MAX,
};
+ // |TestType| specifies the |current_test_| test we are currently running or
+ // the |next_test_| test we need to run next.
+ enum TestType {
+ START_PACKET_TEST, // Initial packet loss test.
+ NON_PACED_PACKET_TEST, // Packet loss test with no pacing.
+ PACED_PACKET_TEST, // Packet loss test with pacing.
+ TEST_TYPE_MAX,
+ };
+
+ // |PacketStatus| collects the Status and RTT statistics for each packet.
+ struct PacketStatus {
+ base::TimeTicks start_time_;
+ base::TimeTicks end_time_;
+ };
+
+ // Constructs a NetworkStats object that collects metrics for network
+ // connectivity (for UDP).
+ NetworkStats();
+ // NetworkStats is deleted when Finish() is called.
+ ~NetworkStats();
+
// Starts the client, connecting to |server|.
// Client will send |bytes_to_send| bytes to |server|.
// When client has received all echoed bytes from the server, or
@@ -106,13 +125,22 @@
uint32 packets_to_send,
const net::CompletionCallback& callback);
- protected:
- // Constructs an NetworkStats object that collects metrics for network
- // connectivity (either TCP or UDP).
- NetworkStats();
- // NetworkStats is deleted when Finish() is called.
- virtual ~NetworkStats();
+ private:
+ friend class NetworkStatsTest;
+ // Allow tests to access our innards for testing purposes.
+ FRIEND_TEST_ALL_PREFIXES(NetworkStatsTest, GetHistogramNames);
+ FRIEND_TEST_ALL_PREFIXES(NetworkStatsTestUDP, VerifyBytesInvalidHeaders);
+ FRIEND_TEST_ALL_PREFIXES(NetworkStatsTestUDP, VerifyBytesInvalidChecksum);
+ FRIEND_TEST_ALL_PREFIXES(NetworkStatsTestUDP, VerifyBytesPreviousPacket);
+ FRIEND_TEST_ALL_PREFIXES(NetworkStatsTestUDP, VerifyBytesInvalidPacketNumber);
+ FRIEND_TEST_ALL_PREFIXES(NetworkStatsTestUDP, VerifyBytesPatternChanged);
+ FRIEND_TEST_ALL_PREFIXES(NetworkStatsTestUDP, VerifyBytes);
+
+ // Starts the test specified by the |next_test_|. It also resets all the book
+ // keeping data, before starting the new test.
+ void RestartPacketTest();
+
// Initializes |finished_callback_| and the number of bytes to send to the
// server. |finished_callback| is called when we are done with the test.
// |finished_callback| is mainly useful for unittests.
@@ -122,70 +150,39 @@
uint32 packets_to_send,
const net::CompletionCallback& finished_callback);
- // Called after host is resolved. UDPStatsClient and TCPStatsClient implement
- // this method. They create the socket and connect to the server.
- virtual bool DoConnect(int result) = 0;
+ // Resets all the counters and the collected stats.
+ void ResetData();
+ // Callback that is called when host resolution is completed.
+ void OnResolveComplete(int result);
+
+ // Called after host is resolved. Creates UDPClientSocket and connects to the
+ // server. If successfully connected, then calls ConnectComplete() to start
+ // the network connectivity tests. Returns |false| if there is any error.
+ bool DoConnect(int result);
+
// This method is called after socket connection is completed. It will start
// the process of sending packets to |server| by calling SendPacket(). Returns
// false if connection is not established (result is less than 0).
bool ConnectComplete(int result);
- // Collects network connectivity stats. This is called when all the data from
- // server is read or when there is a failure during connect/read/write.
- virtual void Finish(Status status, int result) {}
-
- // This method is called from Finish() and calls |finished_callback_| callback
- // to indicate that the test has finished.
- void DoFinishCallback(int result);
-
- // Verifies the data and calls Finish() if there is an error or if all bytes
- // are read. Returns true if Finish() is called otherwise returns false.
- virtual bool ReadComplete(int result);
-
- // Returns the number of bytes to be sent to the |server|.
- uint32 load_size() const { return load_size_; }
-
- // Helper methods to get and set |socket_|.
- net::Socket* socket() { return socket_.get(); }
- void set_socket(net::Socket* socket);
-
- // Returns |start_time_| (used by histograms).
- base::TimeTicks start_time() const { return start_time_; }
-
- // Returns |addresses_|.
- const net::AddressList& addresses() const { return addresses_; }
-
- // Returns packets_received_mask_ (used by unit tests).
- uint32 packets_received_mask() const { return packets_received_mask_; }
-
- // Collect the following network connectivity stats.
- // a) What percentage of users can get a message end-to-end to a TCP/UDP
- // server and if connectivity failed, at what stage (Connect or Write or Read)
- // did it fail?
- // b) What is RTT for the echo message.
- // c) Packet loss correlation and other network connectivity data by calling
- // RecordAcksReceivedHistograms() and RecordStatusAndRTTHistograms().
- void RecordHistograms(const ProtocolValue& protocol,
- const Status& status,
- int result);
-
- private:
- friend class NetworkStatsTest;
-
- // Allow tests to access our innards for testing purposes.
- FRIEND_TEST_ALL_PREFIXES(NetworkStatsTest, GetHistogramNames);
- FRIEND_TEST_ALL_PREFIXES(NetworkStatsTestTCP, VerifyBytes);
-
- // Callback that is called when host resolution is completed.
- void OnResolveComplete(int result);
-
// This method is called whenever we need to send a packet. It is called from
// either ConnectComplete or OnWriteComplete. It will send a packet, based on
// load_size_, to |server| by calling SendData(). If there are no more packets
// to send, it calls ReadData() to read/verify the data from the |server|.
void SendPacket();
+ // Sends the next packet by calling |SendPacket| after a delay. Delay time is
+ // calculated based on the remaining packets and the remaining time.
+ // For START_PACKET_TEST and NON_PACED_PACKET_TEST delay is zero. It also
+ // yields for packets received between sends.
+ void SendNextPacketAfterDelay();
+
+ // Verifies the data and calls Finish() if there is a significant network
+ // error or if all packets are sent. Returns true if Finish() is called
+ // otherwise returns false.
+ bool ReadComplete(int result);
+
// Callbacks when an internal IO is completed.
void OnReadComplete(int result);
void OnWriteComplete(int result);
@@ -208,8 +205,14 @@
// We set a timeout for responses from the echo servers.
void StartReadDataTimer(int milliseconds);
- void OnReadDataTimeout(); // Called when the ReadData Timer fires.
+ // Called when the ReadData Timer fires. |test_base_packet_number| specifies
+ // the |base_packet_number_| when we have started the timer. If we haven't
+ // received all the packets for the test (test took longer than 30 secs to
+ // run), then we call Finish() to finish processing. If we have already
+ // received all packets from the server, then this method is a no-op.
+ void OnReadDataTimeout(uint32 test_base_packet_number);
+
// Returns the checksum for the message.
uint32 GetChecksum(const char* message, uint32 message_length);
@@ -239,25 +242,66 @@
// if all the bytes are verified.
NetworkStats::Status VerifyBytes(const std::string& response);
+ // Collects network connectivity stats. This is called when all the data from
+ // server is read or when there is a failure during connect/read/write. It
+ // will either restart the second phase of the test, or it will self destruct
+ // at the end of this method.
+ void Finish(Status status, int result);
+
+ // This method is called from Finish() and calls |finished_callback_| callback
+ // to indicate that the test has finished.
+ void DoFinishCallback(int result);
+
+ // Collect the network connectivity stats by calling RecordRTTHistograms(),
+ // RecordAcksReceivedHistograms() and RecordPacketLossSeriesHistograms(). See
+ // below for details.
+ void RecordHistograms(const ProtocolValue& protocol,
+ const Status& status,
+ int result);
+
// Collect the following network connectivity stats when
// kMaximumSequentialPackets (21) packets are sent.
// a) Received the "echo response" for at least one packet.
// b) Received the "echo response" for the nth packet.
// c) Count the number of "echo responses" received for each of the initial
// sequences of packets 1...n.
- void RecordAcksReceivedHistograms(const char* load_size_string);
+ void RecordAcksReceivedHistograms(const std::string& load_size_string);
- // Collect the following network connectivity stats.
- // a) What percentage of users can get a message end-to-end to a TCP/UDP
- // server and if connectivity failed, at what stage (Connect or Write or Read)
- // did it fail?
- // b) What is RTT for the echo message.
- // c) Records if there is a probabalistic dependency in packet loss when
+ // Collect the following network connectivity stats for
+ // kMaximumCorrelationPackets (6) packets test.
+ // a) Success/failure of each packet, to estimate reachability for users.
+ // b) Records if there is a probabalistic dependency in packet loss when
// kMaximumCorrelationPackets packets are sent consecutively.
void RecordPacketLossSeriesHistograms(const ProtocolValue& protocol,
+ const std::string& load_size_string,
const Status& status,
- const char* load_size_string,
int result);
+
+ // Collects the RTT for the packet specified by the |index|.
+ void RecordRTTHistograms(const ProtocolValue& protocol,
+ const std::string& load_size_string,
+ uint32 index);
+
+ uint32 load_size() const { return load_size_; }
+
+ // Returns string representation of test_type_.
+ const char* TestName();
+
+ uint32 packet_number() const { return packet_number_; }
+ uint32 base_packet_number() const { return base_packet_number_; }
+ uint32 set_base_packet_number(uint32 packet_number) {
+ return base_packet_number_ = packet_number;
+ }
+
+ net::Socket* socket() { return socket_.get(); }
+ void set_socket(net::Socket* socket);
+
+ const net::AddressList& addresses() const { return addresses_; }
+
+ uint32 packets_received_mask() const { return packets_received_mask_; }
+
+ TestType next_test() const { return next_test_; }
+
// The socket handle for this session.
scoped_ptr<net::Socket> socket_;
@@ -272,9 +316,6 @@
uint32 bytes_to_read_;
uint32 bytes_to_send_;
- // The encoded message read from the server.
- std::string encoded_message_;
-
// |stream_| is used to generate data to be sent to the server and it is also
// used to verify the data received from the server.
net::TestDataStream stream_;
@@ -294,79 +335,35 @@
// round trip is finished).
net::CompletionCallback finished_callback_;
- // The time when the session was started.
- base::TimeTicks start_time_;
+ // Collects the Status and RTT for each packet.
+ std::vector<PacketStatus> packet_status_;
+ // The time when we have received 1st byte from the server.
+ base::TimeTicks packet_1st_byte_read_time_;
+
+ // The last time when we have received data from the server.
+ base::TimeTicks packet_last_byte_read_time_;
+
+ // This is the average time it took to receive a packet from the server.
+ base::TimeDelta average_time_;
+
// Data to track number of packets to send to the server and the packets we
// have received from the server.
- uint32 packets_to_send_;
- uint32 packets_sent_;
- uint32 base_packet_number_;
- uint32 packets_received_mask_;
+ uint32 packets_to_send_; // Numbers of packets that are to be sent.
+ uint32 packets_sent_; // Numbers of packets sent to the server.
+ uint32 packets_received_; // Number of packets successfully received.
+ uint32 packets_received_mask_; // Tracks the received status of each packet.
+ uint32 packet_number_; // The packet number being sent to the server.
+ uint32 base_packet_number_; // The packet number before the test.
+ bool sending_complete_; // Finished sending all packets.
+ TestType current_test_; // Current test that is running.
+ TestType next_test_; // Next test that is to be run.
+
// We use this factory to create timeout tasks for socket's ReadData.
base::WeakPtrFactory<NetworkStats> weak_factory_;
};
-class UDPStatsClient : public NetworkStats {
- public:
- // Constructs an UDPStatsClient object that collects metrics for UDP
- // connectivity.
- UDPStatsClient();
- // UDPStatsClient is deleted when Finish() is called.
- virtual ~UDPStatsClient();
-
- protected:
- // Allow tests to access our innards for testing purposes.
- friend class NetworkStatsTestUDP;
-
- // Called after host is resolved. Creates UDClientSocket and connects to the
- // server. If successfully connected, then calls ConnectComplete() to start
- // the echo protocol. Returns |false| if there is any error.
- virtual bool DoConnect(int result) OVERRIDE;
-
- // This method calls NetworkStats::ReadComplete() to verify the data and calls
- // Finish() if there is an error or if read callback didn't return any data
- // (|result| is less than or equal to 0).
- virtual bool ReadComplete(int result) OVERRIDE;
-
- // Collects stats for UDP connectivity. This is called when all the data from
- // server is read or when there is a failure during connect/read/write. This
- // object is deleted at the end of this method.
- virtual void Finish(Status status, int result) OVERRIDE;
-};
-
-class TCPStatsClient : public NetworkStats {
- public:
- // Constructs a TCPStatsClient object that collects metrics for TCP
- // connectivity.
- TCPStatsClient();
- // TCPStatsClient is deleted when Finish() is called.
- virtual ~TCPStatsClient();
-
- protected:
- // Allow tests to access our innards for testing purposes.
- friend class NetworkStatsTestTCP;
-
- // Called after host is resolved. Creates TCPClientSocket and connects to the
- // server.
- virtual bool DoConnect(int result) OVERRIDE;
-
- // This method calls NetworkStats::ReadComplete() to verify the data and calls
- // Finish() if there is an error (|result| is less than 0).
- virtual bool ReadComplete(int result) OVERRIDE;
-
- // Collects stats for TCP connectivity. This is called when all the data from
- // server is read or when there is a failure during connect/read/write. This
- // object is deleted at the end of this method.
- virtual void Finish(Status status, int result) OVERRIDE;
-
- private:
- // Callback that is called when connect is completed and calls
- // ConnectComplete() to start the echo protocol.
- void OnConnectComplete(int result);
-};
-
class ProxyDetector {
public:
// Used for the callback that is called from |OnResolveProxyComplete|.
@@ -410,17 +407,17 @@
bool has_pending_proxy_resolution_;
};
-// This collects the network connectivity stats for UDP and TCP for small
+// This collects the network connectivity stats for UDP protocol for small
// percentage of users who are participating in the experiment. All users must
// have enabled "UMA upload". This method gets called only if UMA upload to the
// server has succeeded.
void CollectNetworkStats(const std::string& network_stats_server_url,
IOThread* io_thread);
-// This starts a test randomly selected among "TCP test with small packet size",
-// "TCP test with large packet size", "UDP test with small packet size", "UDP
-// test with large packet size" and "UDP multi packet loss" tests to collect the
-// network connectivity stats.
+// This starts a test randomly selected among "6 packets correlation test for
+// 1200 bytes packet", "21 packets bursty test with 1200 bytes packet",
+// "21 packets bursty test with 500 bytes packet", and "21 packets bursty test
+// with 100 bytes packet" tests.
void StartNetworkStatsTest(net::HostResolver* host_resolver,
const net::HostPortPair& server_address,
NetworkStats::HistogramPortSelector histogram_port,
« no previous file with comments | « no previous file | chrome/browser/net/network_stats.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698