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

Side by Side Diff: chrome/browser/net/network_stats.cc

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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/net/network_stats.h ('k') | chrome/browser/net/network_stats_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/net/network_stats.h" 5 #include "chrome/browser/net/network_stats.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/metrics/field_trial.h" 10 #include "base/metrics/field_trial.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "base/stringprintf.h" 13 #include "base/stringprintf.h"
14 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "base/tuple.h" 16 #include "base/tuple.h"
17 #include "chrome/common/chrome_version_info.h" 17 #include "chrome/common/chrome_version_info.h"
18 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "googleurl/src/gurl.h" 19 #include "googleurl/src/gurl.h"
20 #include "net/base/net_errors.h" 20 #include "net/base/net_errors.h"
21 #include "net/base/net_util.h" 21 #include "net/base/net_util.h"
22 #include "net/base/network_change_notifier.h" 22 #include "net/base/network_change_notifier.h"
23 #include "net/base/test_completion_callback.h" 23 #include "net/base/test_completion_callback.h"
24 #include "net/proxy/proxy_service.h" 24 #include "net/proxy/proxy_service.h"
25 #include "net/socket/tcp_client_socket.h"
26 #include "net/udp/udp_client_socket.h" 25 #include "net/udp/udp_client_socket.h"
27 #include "net/udp/udp_server_socket.h" 26 #include "net/udp/udp_server_socket.h"
28 27
29 using content::BrowserThread; 28 using content::BrowserThread;
30 29
31 namespace chrome_browser_net { 30 namespace chrome_browser_net {
32 31
33 // This specifies the number of bytes to be sent to the TCP/UDP servers as part 32 // This specifies the number of bytes to be sent to the UDP echo servers as part
34 // of small packet size test. 33 // of small packet size test.
35 static const uint32 kSmallTestBytesToSend = 100; 34 static const uint32 kSmallTestBytesToSend = 100;
36 35
37 // This specifies the number of bytes to be sent to the TCP/UDP servers as part 36 // This specifies the number of bytes to be sent to the UDP echo servers as part
38 // of medium packet size test. 37 // of medium packet size test.
39 static const uint32 kMediumTestBytesToSend = 500; 38 static const uint32 kMediumTestBytesToSend = 500;
40 39
41 // This specifies the number of bytes to be sent to the TCP/UDP servers as part 40 // This specifies the number of bytes to be sent to the UDP echo servers as part
42 // of large packet size test. 41 // of large packet size test.
43 static const uint32 kLargeTestBytesToSend = 1200; 42 static const uint32 kLargeTestBytesToSend = 1200;
44 43
45 // This specifies the maximum message (payload) size.
46 static const uint32 kMaxMessage = 2048;
47
48 // This specifies starting position of the <version> and length of the 44 // This specifies starting position of the <version> and length of the
49 // <version> in "echo request" and "echo response". 45 // <version> in "echo request" and "echo response".
50 static const uint32 kVersionNumber = 1; 46 static const uint32 kVersionNumber = 1;
51 static const uint32 kVersionStart = 0; 47 static const uint32 kVersionStart = 0;
52 static const uint32 kVersionLength = 2; 48 static const uint32 kVersionLength = 2;
53 static const uint32 kVersionEnd = kVersionStart + kVersionLength; 49 static const uint32 kVersionEnd = kVersionStart + kVersionLength;
54 50
55 // This specifies the starting position of the <checksum> and length of the 51 // This specifies the starting position of the <checksum> and length of the
56 // <checksum> in "echo request" and "echo response". Maximum value for the 52 // <checksum> in "echo request" and "echo response". Maximum value for the
57 // <checksum> is less than (2 ** 31 - 1). 53 // <checksum> is less than (2 ** 31 - 1).
(...skipping 19 matching lines...) Expand all
77 // This specifies the starting position of the <payload> in "echo request". 73 // This specifies the starting position of the <payload> in "echo request".
78 static const uint32 kPayloadStart = kPayloadSizeEnd; 74 static const uint32 kPayloadStart = kPayloadSizeEnd;
79 75
80 // This specifies the length of the packet_number in the payload. 76 // This specifies the length of the packet_number in the payload.
81 static const uint32 kPacketNumberLength = 10; 77 static const uint32 kPacketNumberLength = 10;
82 78
83 // This specifies the starting position of the <encoded_payload> in 79 // This specifies the starting position of the <encoded_payload> in
84 // "echo response". 80 // "echo response".
85 static const uint32 kEncodedPayloadStart = kKeyEnd; 81 static const uint32 kEncodedPayloadStart = kKeyEnd;
86 82
87 // HistogramPortSelector and kPorts should be kept in sync. 83 // HistogramPortSelector and kPorts should be kept in sync. Port 999999 is
88 static const int32 kPorts[] = {53, 80, 587, 6121, 8080, 999999}; 84 // used by the unit tests.
89 85 static const int32 kPorts[] = {6121, 999999};
90 // The packet number that is to be sent to the server.
91 static uint32 g_packet_number_ = 0;
92 86
93 // Maximum number of packets that can be sent to the server for packet loss 87 // Maximum number of packets that can be sent to the server for packet loss
94 // correlation test. 88 // correlation test.
95 static const uint32 kMaximumCorrelationPackets = 6; 89 static const uint32 kMaximumCorrelationPackets = 6;
96 90
97 // Maximum number of packets that can be sent to the server. 91 // Maximum number of packets that can be sent to the server.
98 static const uint32 kMaximumSequentialPackets = 21; 92 static const uint32 kMaximumSequentialPackets = 21;
99 93
94 // This specifies the maximum message (payload) size.
95 static const uint32 kMaxMessage = kMaximumSequentialPackets * 2048;
96
100 // NetworkStats methods and members. 97 // NetworkStats methods and members.
101 NetworkStats::NetworkStats() 98 NetworkStats::NetworkStats()
102 : load_size_(0), 99 : read_buffer_(NULL),
100 write_buffer_(NULL),
101 load_size_(0),
103 bytes_to_read_(0), 102 bytes_to_read_(0),
104 bytes_to_send_(0), 103 bytes_to_send_(0),
105 has_proxy_server_(false), 104 has_proxy_server_(false),
106 packets_to_send_(0), 105 packets_to_send_(0),
107 packets_sent_(0), 106 packets_sent_(0),
107 packets_received_(0),
108 packets_received_mask_(0),
109 packet_number_(0),
108 base_packet_number_(0), 110 base_packet_number_(0),
109 packets_received_mask_(0), 111 sending_complete_(false),
112 current_test_(START_PACKET_TEST),
113 next_test_(TEST_TYPE_MAX),
110 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 114 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
111 } 115 }
112 116
113 NetworkStats::~NetworkStats() { 117 NetworkStats::~NetworkStats() {
114 socket_.reset(); 118 socket_.reset();
115 } 119 }
116 120
117 bool NetworkStats::Start(net::HostResolver* host_resolver, 121 bool NetworkStats::Start(net::HostResolver* host_resolver,
118 const net::HostPortPair& server_host_port_pair, 122 const net::HostPortPair& server_host_port_pair,
119 HistogramPortSelector histogram_port, 123 HistogramPortSelector histogram_port,
(...skipping 15 matching lines...) Expand all
135 int rv = host_resolver->Resolve( 139 int rv = host_resolver->Resolve(
136 request, &addresses_, 140 request, &addresses_,
137 base::Bind(&NetworkStats::OnResolveComplete, 141 base::Bind(&NetworkStats::OnResolveComplete,
138 base::Unretained(this)), 142 base::Unretained(this)),
139 NULL, net::BoundNetLog()); 143 NULL, net::BoundNetLog());
140 if (rv == net::ERR_IO_PENDING) 144 if (rv == net::ERR_IO_PENDING)
141 return true; 145 return true;
142 return DoConnect(rv); 146 return DoConnect(rv);
143 } 147 }
144 148
149 void NetworkStats::RestartPacketTest() {
150 ResetData();
151 current_test_ = next_test_;
152 next_test_ = TEST_TYPE_MAX;
153 if (!bytes_to_read_) {
154 read_buffer_ = NULL;
155 ReadData();
156 }
157 SendPacket();
158 }
159
145 void NetworkStats::Initialize( 160 void NetworkStats::Initialize(
146 uint32 bytes_to_send, 161 uint32 bytes_to_send,
147 HistogramPortSelector histogram_port, 162 HistogramPortSelector histogram_port,
148 bool has_proxy_server, 163 bool has_proxy_server,
149 uint32 packets_to_send, 164 uint32 packets_to_send,
150 const net::CompletionCallback& finished_callback) { 165 const net::CompletionCallback& finished_callback) {
151 DCHECK(bytes_to_send); // We should have data to send. 166 DCHECK(bytes_to_send); // We should have data to send.
152 DCHECK(packets_to_send); // We should send at least 1 packet. 167 DCHECK(packets_to_send); // We should send at least 1 packet.
153 DCHECK_LE(bytes_to_send, kLargeTestBytesToSend); 168 DCHECK_LE(bytes_to_send, kLargeTestBytesToSend);
169 DCHECK_LE(packets_to_send, 8 * sizeof(packets_received_mask_));
154 170
155 load_size_ = bytes_to_send; 171 load_size_ = bytes_to_send;
156 packets_to_send_ = packets_to_send; 172 packets_to_send_ = packets_to_send;
157
158 histogram_port_ = histogram_port; 173 histogram_port_ = histogram_port;
159 has_proxy_server_ = has_proxy_server; 174 has_proxy_server_ = has_proxy_server;
160 finished_callback_ = finished_callback; 175 finished_callback_ = finished_callback;
176 ResetData();
177 packet_number_ = base::RandInt(1 << 28, INT_MAX);
178 }
179
180 void NetworkStats::ResetData() {
181 write_buffer_ = NULL;
182 bytes_to_send_ = 0;
183 packet_status_.clear();
184 packet_status_.resize(packets_to_send_);
185 packets_sent_ = 0;
186 packets_received_ = 0;
187 packets_received_mask_ = 0;
188 sending_complete_ = false;
189 }
190
191 void NetworkStats::OnResolveComplete(int result) {
192 DoConnect(result);
193 }
194
195 bool NetworkStats::DoConnect(int result) {
196 if (result != net::OK) {
197 Finish(RESOLVE_FAILED, result);
198 return false;
199 }
200
201 net::UDPClientSocket* udp_socket =
202 new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND,
203 net::RandIntCallback(),
204 NULL,
205 net::NetLog::Source());
206 if (!udp_socket) {
207 Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT);
208 return false;
209 }
210 set_socket(udp_socket);
211
212 if (addresses().empty()) {
213 Finish(RESOLVE_FAILED, net::ERR_INVALID_ARGUMENT);
214 return false;
215 }
216
217 const net::IPEndPoint& endpoint = addresses().front();
218 int rv = udp_socket->Connect(endpoint);
219 if (rv < 0) {
220 Finish(CONNECT_FAILED, rv);
221 return false;
222 }
223
224 const int kSocketBufferSize = 2 * packets_to_send_ * 2048;
225 udp_socket->SetSendBufferSize(kSocketBufferSize);
226 udp_socket->SetReceiveBufferSize(kSocketBufferSize);
227 return ConnectComplete(rv);
161 } 228 }
162 229
163 bool NetworkStats::ConnectComplete(int result) { 230 bool NetworkStats::ConnectComplete(int result) {
164 if (result < 0) { 231 if (result < 0) {
165 Finish(CONNECT_FAILED, result); 232 Finish(CONNECT_FAILED, result);
166 return false; 233 return false;
167 } 234 }
168 235
169 base_packet_number_ = g_packet_number_; 236 ReadData();
170 start_time_ = base::TimeTicks::Now();
171 SendPacket(); 237 SendPacket();
172 return true; 238 return true;
173 } 239 }
174 240
175 void NetworkStats::DoFinishCallback(int result) { 241 void NetworkStats::SendPacket() {
176 if (!finished_callback_.is_null()) { 242 while (true) {
177 net::CompletionCallback callback = finished_callback_; 243 if (bytes_to_send_ == 0u) {
178 finished_callback_.Reset(); 244 if (packets_sent_ >= packets_to_send_) {
179 callback.Run(result); 245 // Timeout if we don't get response back from echo servers in 30 secs.
180 } 246 sending_complete_ = true;
247 const int kReadDataTimeoutMs = 30000;
248 StartReadDataTimer(kReadDataTimeoutMs);
249 break;
250 }
251
252 ++packet_number_;
253 if (packets_sent_ == 0)
254 base_packet_number_ = packet_number_;
255 bytes_to_send_ = SendingPacketSize();
256 SendNextPacketAfterDelay();
257 break;
258 }
259
260 int rv = SendData();
261 if (rv < 0) {
262 if (rv != net::ERR_IO_PENDING)
263 Finish(WRITE_FAILED, rv);
264 break;
265 }
266 DCHECK_EQ(bytes_to_send_, 0u);
267 };
181 } 268 }
182 269
183 void NetworkStats::set_socket(net::Socket* socket) { 270 void NetworkStats::SendNextPacketAfterDelay() {
184 DCHECK(socket); 271 if (current_test_ == PACED_PACKET_TEST) {
185 DCHECK(!socket_.get()); 272 MessageLoop::current()->PostDelayedTask(
186 socket_.reset(socket); 273 FROM_HERE,
274 base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr()),
275 average_time_);
276 return;
277 }
278
279 MessageLoop::current()->PostTask(
280 FROM_HERE,
281 base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr()));
187 } 282 }
188 283
189 bool NetworkStats::ReadComplete(int result) { 284 bool NetworkStats::ReadComplete(int result) {
190 DCHECK(socket_.get()); 285 DCHECK(socket_.get());
191 DCHECK_NE(net::ERR_IO_PENDING, result); 286 DCHECK_NE(net::ERR_IO_PENDING, result);
192 if (result < 0) { 287 if (result < 0) {
193 Finish(READ_FAILED, result); 288 Finish(READ_FAILED, result);
194 return true; 289 return true;
195 } 290 }
196 291
197 encoded_message_.append(read_buffer_->data(), result); 292 if (result > 0) {
293 std::string encoded_message;
294 encoded_message.append(read_buffer_->data(), result);
295 if (VerifyBytes(encoded_message) == SUCCESS) {
296 base::TimeTicks now = base::TimeTicks::Now();
297 if (packets_received_ == 0)
298 packet_1st_byte_read_time_ = now;
299 packet_last_byte_read_time_ = now;
300
301 DCHECK_GE(bytes_to_read_, static_cast<uint32>(result));
302 if (bytes_to_read_ >= static_cast<uint32>(result))
303 bytes_to_read_ -= result;
304 ++packets_received_;
305 }
306 }
198 307
199 read_buffer_ = NULL; 308 read_buffer_ = NULL;
200 bytes_to_read_ -= result;
201 309
202 // No more data to read. 310 // No more data to read.
203 if (!bytes_to_read_ || result == 0) { 311 if (!bytes_to_read_ || result == 0) {
312 if (!sending_complete_)
313 return false;
314
204 Status status = VerifyPackets(); 315 Status status = VerifyPackets();
205 if (status == SUCCESS) 316 if (status == SUCCESS)
206 Finish(status, net::OK); 317 Finish(status, net::OK);
207 else 318 else
208 Finish(status, net::ERR_INVALID_RESPONSE); 319 Finish(status, net::ERR_INVALID_RESPONSE);
209 return true; 320 return true;
210 } 321 }
211 return false; 322 return false;
212 } 323 }
213 324
214 void NetworkStats::OnResolveComplete(int result) {
215 DoConnect(result);
216 }
217
218 void NetworkStats::SendPacket() {
219 DCHECK_EQ(bytes_to_send_, 0u);
220 uint32 sending_packet_size = SendingPacketSize();
221
222 while (packets_to_send_ > packets_sent_) {
223 ++g_packet_number_;
224
225 bytes_to_send_ = sending_packet_size;
226 int rv = SendData();
227 if (rv < 0) {
228 if (rv != net::ERR_IO_PENDING)
229 Finish(WRITE_FAILED, rv);
230 return;
231 }
232 DCHECK_EQ(bytes_to_send_, 0u);
233 }
234
235 // Timeout if we don't get response back from echo servers in 60 secs.
236 const int kReadDataTimeoutMs = 60000;
237 StartReadDataTimer(kReadDataTimeoutMs);
238
239 bytes_to_read_ = packets_sent_ * ReceivingPacketSize();
240 ReadData();
241 }
242
243 void NetworkStats::OnReadComplete(int result) { 325 void NetworkStats::OnReadComplete(int result) {
244 if (!ReadComplete(result)) { 326 if (!ReadComplete(result)) {
245 // Called ReadData() via PostDelayedTask() to avoid recursion. Added a delay 327 // Called ReadData() via PostDelayedTask() to avoid recursion. Added a delay
246 // of 1ms so that the time-out will fire before we have time to really hog 328 // of 1ms so that the time-out will fire before we have time to really hog
247 // the CPU too extensively (waiting for the time-out) in case of an infinite 329 // the CPU too extensively (waiting for the time-out) in case of an infinite
248 // loop. 330 // loop.
249 MessageLoop::current()->PostDelayedTask( 331 MessageLoop::current()->PostDelayedTask(
250 FROM_HERE, 332 FROM_HERE,
251 base::Bind(&NetworkStats::ReadData, weak_factory_.GetWeakPtr()), 333 base::Bind(&NetworkStats::ReadData, weak_factory_.GetWeakPtr()),
252 base::TimeDelta::FromMilliseconds(1)); 334 base::TimeDelta::FromMilliseconds(1));
(...skipping 22 matching lines...) Expand all
275 357
276 MessageLoop::current()->PostTask( 358 MessageLoop::current()->PostTask(
277 FROM_HERE, 359 FROM_HERE,
278 base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr())); 360 base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr()));
279 } 361 }
280 362
281 void NetworkStats::ReadData() { 363 void NetworkStats::ReadData() {
282 int rv; 364 int rv;
283 do { 365 do {
284 if (!socket_.get()) 366 if (!socket_.get())
285 return; 367 break;
286 368
287 DCHECK(!read_buffer_.get()); 369 DCHECK(!read_buffer_.get());
288 370
289 // We release the read_buffer_ in the destructor if there is an error. 371 // We release the read_buffer_ in the destructor if there is an error.
290 read_buffer_ = new net::IOBuffer(kMaxMessage); 372 read_buffer_ = new net::IOBuffer(kMaxMessage);
291 373
292 rv = socket_->Read(read_buffer_, kMaxMessage, 374 rv = socket_->Read(read_buffer_, kMaxMessage,
293 base::Bind(&NetworkStats::OnReadComplete, 375 base::Bind(&NetworkStats::OnReadComplete,
294 base::Unretained(this))); 376 base::Unretained(this)));
295 if (rv == net::ERR_IO_PENDING) 377 if (rv == net::ERR_IO_PENDING)
296 return; 378 break;
379
297 // If we have read all the data then return. 380 // If we have read all the data then return.
298 if (ReadComplete(rv)) 381 if (ReadComplete(rv))
299 return; 382 break;
300 } while (rv > 0); 383 } while (rv > 0);
301 } 384 }
302 385
303 int NetworkStats::SendData() { 386 int NetworkStats::SendData() {
304 DCHECK(bytes_to_send_); // We should have data to send. 387 DCHECK(bytes_to_send_); // We should have data to send.
305 do { 388 do {
306 if (!write_buffer_.get()) { 389 if (!write_buffer_.get()) {
390 // Send a new packet.
307 scoped_refptr<net::IOBufferWithSize> buffer( 391 scoped_refptr<net::IOBufferWithSize> buffer(
308 new net::IOBufferWithSize(bytes_to_send_)); 392 new net::IOBufferWithSize(bytes_to_send_));
309 GetEchoRequest(buffer); 393 GetEchoRequest(buffer);
310 write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_); 394 write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_);
395
396 // As soon as we write, a read could happen. Thus update all the book
397 // keeping data.
398 bytes_to_read_ += ReceivingPacketSize();
399 ++packets_sent_;
400 if (packets_sent_ >= packets_to_send_)
401 sending_complete_ = true;
402
403 uint32 packet_index = packet_number_ - base_packet_number_;
404 DCHECK_GE(packet_index, 0u);
405 DCHECK_LT(packet_index, packet_status_.size());
406 packet_status_[packet_index].start_time_ = base::TimeTicks::Now();
311 } 407 }
312 408
313 if (!socket_.get()) 409 if (!socket_.get())
314 return net::ERR_UNEXPECTED; 410 return net::ERR_UNEXPECTED;
315 int rv = socket_->Write(write_buffer_, 411 int rv = socket_->Write(write_buffer_,
316 write_buffer_->BytesRemaining(), 412 write_buffer_->BytesRemaining(),
317 base::Bind(&NetworkStats::OnWriteComplete, 413 base::Bind(&NetworkStats::OnWriteComplete,
318 base::Unretained(this))); 414 base::Unretained(this)));
319 if (rv < 0) 415 if (rv < 0)
320 return rv; 416 return rv;
321 DidSendData(rv); 417 DidSendData(rv);
322 } while (bytes_to_send_); 418 } while (bytes_to_send_);
323 return net::OK; 419 return net::OK;
324 } 420 }
325 421
326 uint32 NetworkStats::SendingPacketSize() const { 422 uint32 NetworkStats::SendingPacketSize() const {
327 return kVersionLength + kChecksumLength + kPayloadSizeLength + load_size_; 423 return kVersionLength + kChecksumLength + kPayloadSizeLength + load_size_;
328 } 424 }
329 425
330 uint32 NetworkStats::ReceivingPacketSize() const { 426 uint32 NetworkStats::ReceivingPacketSize() const {
331 return kVersionLength + kChecksumLength + kPayloadSizeLength + kKeyLength + 427 return kVersionLength + kChecksumLength + kPayloadSizeLength + kKeyLength +
332 load_size_; 428 load_size_;
333 } 429 }
334 430
335 void NetworkStats::DidSendData(int bytes_sent) { 431 void NetworkStats::DidSendData(int bytes_sent) {
336 write_buffer_->DidConsume(bytes_sent); 432 write_buffer_->DidConsume(bytes_sent);
337 if (!write_buffer_->BytesRemaining()) 433 if (!write_buffer_->BytesRemaining())
338 write_buffer_ = NULL; 434 write_buffer_ = NULL;
339 bytes_to_send_ -= bytes_sent; 435 bytes_to_send_ -= bytes_sent;
340 if (bytes_to_send_ == 0)
341 ++packets_sent_;
342 } 436 }
343 437
344 void NetworkStats::StartReadDataTimer(int milliseconds) { 438 void NetworkStats::StartReadDataTimer(int milliseconds) {
345 MessageLoop::current()->PostDelayedTask( 439 MessageLoop::current()->PostDelayedTask(
346 FROM_HERE, 440 FROM_HERE,
347 base::Bind(&NetworkStats::OnReadDataTimeout, weak_factory_.GetWeakPtr()), 441 base::Bind(&NetworkStats::OnReadDataTimeout,
442 weak_factory_.GetWeakPtr(),
443 base_packet_number_),
348 base::TimeDelta::FromMilliseconds(milliseconds)); 444 base::TimeDelta::FromMilliseconds(milliseconds));
349 } 445 }
350 446
351 void NetworkStats::OnReadDataTimeout() { 447 void NetworkStats::OnReadDataTimeout(uint32 test_base_packet_number) {
448 if (test_base_packet_number != base_packet_number_)
449 return;
450
352 Status status = VerifyPackets(); 451 Status status = VerifyPackets();
353 if (status == SUCCESS) 452 if (status == SUCCESS)
354 Finish(status, net::OK); 453 Finish(status, net::OK);
355 else 454 else
356 Finish(READ_TIMED_OUT, net::ERR_INVALID_ARGUMENT); 455 Finish(READ_TIMED_OUT, net::ERR_INVALID_ARGUMENT);
357 } 456 }
358 457
359 uint32 NetworkStats::GetChecksum(const char* message, uint32 message_length) { 458 uint32 NetworkStats::GetChecksum(const char* message, uint32 message_length) {
360 // Calculate the <checksum> of the <message>. 459 // Calculate the <checksum> of the <message>.
361 uint32 sum = 0; 460 uint32 sum = 0;
(...skipping 26 matching lines...) Expand all
388 uint32 buffer_size = static_cast<uint32>(io_buffer->size()); 487 uint32 buffer_size = static_cast<uint32>(io_buffer->size());
389 488
390 // Copy the <version> into the io_buffer starting from the kVersionStart 489 // Copy the <version> into the io_buffer starting from the kVersionStart
391 // position. 490 // position.
392 std::string version = base::StringPrintf("%02d", kVersionNumber); 491 std::string version = base::StringPrintf("%02d", kVersionNumber);
393 DCHECK(kVersionLength == version.length()); 492 DCHECK(kVersionLength == version.length());
394 DCHECK_GE(buffer_size, kVersionStart + kVersionLength); 493 DCHECK_GE(buffer_size, kVersionStart + kVersionLength);
395 memcpy(buffer + kVersionStart, version.c_str(), kVersionLength); 494 memcpy(buffer + kVersionStart, version.c_str(), kVersionLength);
396 495
397 // Copy the packet_number into the payload. 496 // Copy the packet_number into the payload.
398 std::string packet_number = base::StringPrintf("%010d", g_packet_number_); 497 std::string packet_number = base::StringPrintf("%010d", packet_number_);
399 DCHECK(kPacketNumberLength == packet_number.length()); 498 DCHECK(kPacketNumberLength == packet_number.length());
400 DCHECK_GE(buffer_size, kPayloadStart + kPacketNumberLength); 499 DCHECK_GE(buffer_size, kPayloadStart + kPacketNumberLength);
401 memcpy(buffer + kPayloadStart, packet_number.c_str(), kPacketNumberLength); 500 memcpy(buffer + kPayloadStart, packet_number.c_str(), kPacketNumberLength);
402 501
403 // Get the <payload> from the |stream_| and copy it into io_buffer after 502 // Get the <payload> from the |stream_| and copy it into io_buffer after
404 // packet_number. 503 // packet_number.
405 stream_.Reset(); 504 stream_.Reset();
406 DCHECK_GE(buffer_size, kPayloadStart + load_size_); 505 DCHECK_GE(buffer_size, kPayloadStart + load_size_);
407 stream_.GetBytes(buffer + kPayloadStart + kPacketNumberLength, 506 stream_.GetBytes(buffer + kPayloadStart + kPacketNumberLength,
408 load_size_ - kPacketNumberLength); 507 load_size_ - kPacketNumberLength);
(...skipping 10 matching lines...) Expand all
419 518
420 // Copy the size of the <payload> into the io_buffer starting from the 519 // Copy the size of the <payload> into the io_buffer starting from the
421 // kPayloadSizeStart position. 520 // kPayloadSizeStart position.
422 std::string payload_size = base::StringPrintf("%07d", load_size_); 521 std::string payload_size = base::StringPrintf("%07d", load_size_);
423 DCHECK(kPayloadSizeLength == payload_size.length()); 522 DCHECK(kPayloadSizeLength == payload_size.length());
424 DCHECK_GE(buffer_size, kPayloadSizeStart + kPayloadSizeLength); 523 DCHECK_GE(buffer_size, kPayloadSizeStart + kPayloadSizeLength);
425 memcpy(buffer + kPayloadSizeStart, payload_size.c_str(), kPayloadSizeLength); 524 memcpy(buffer + kPayloadSizeStart, payload_size.c_str(), kPayloadSizeLength);
426 } 525 }
427 526
428 NetworkStats::Status NetworkStats::VerifyPackets() { 527 NetworkStats::Status NetworkStats::VerifyPackets() {
429 uint32 packet_start = 0;
430 size_t message_length = encoded_message_.length();
431 uint32 receiving_packet_size = ReceivingPacketSize();
432 Status status = SUCCESS; 528 Status status = SUCCESS;
433 for (uint32 i = 0; i < packets_to_send_; i++) { 529 uint32 successful_packets = 0;
434 if (message_length <= packet_start) { 530
435 status = ZERO_LENGTH_ERROR; 531 for (uint32 i = 0; i < packet_status_.size(); i++) {
436 break; 532 if (packets_received_mask_ & (1 << i))
533 ++successful_packets;
534 }
535
536 if (packets_received_ > packets_to_send_)
537 status = TOO_MANY_PACKETS;
538
539 if (packets_to_send_ > successful_packets)
540 status = SOME_PACKETS_NOT_VERIFIED;
541
542 if (current_test_ == START_PACKET_TEST &&
543 packets_to_send_ == kMaximumSequentialPackets &&
544 successful_packets > 1) {
545 base::TimeDelta total_time;
546 if (packet_last_byte_read_time_ > packet_1st_byte_read_time_) {
547 total_time =
548 packet_last_byte_read_time_ - packet_1st_byte_read_time_;
437 } 549 }
438 std::string response = 550 average_time_ = total_time / (successful_packets - 1);
439 encoded_message_.substr(packet_start, receiving_packet_size); 551 std::string histogram_name = base::StringPrintf(
440 Status packet_status = VerifyBytes(response); 552 "NetConnectivity3.%s.Sent%02d.%d.%dB.PacketDelay",
441 if (packet_status != SUCCESS) 553 TestName(),
442 status = packet_status; 554 kMaximumSequentialPackets,
443 packet_start += receiving_packet_size; 555 kPorts[histogram_port_],
556 load_size_);
557 base::Histogram* histogram = base::Histogram::FactoryTimeGet(
558 histogram_name, base::TimeDelta::FromMilliseconds(1),
559 base::TimeDelta::FromSeconds(30), 50,
560 base::Histogram::kUmaTargetedHistogramFlag);
561 histogram->AddTime(total_time);
562
563 int experiment_to_run = base::RandInt(1, 2);
564 if (experiment_to_run == 1)
565 next_test_ = NON_PACED_PACKET_TEST;
566 else
567 next_test_ = PACED_PACKET_TEST;
444 } 568 }
445 if (message_length > packet_start) 569
446 status = TOO_MANY_PACKETS;
447 return status; 570 return status;
448 } 571 }
449 572
450 NetworkStats::Status NetworkStats::VerifyBytes(const std::string& response) { 573 NetworkStats::Status NetworkStats::VerifyBytes(const std::string& response) {
451 // If the "echo response" doesn't have enough bytes, then return false. 574 // If the "echo response" doesn't have enough bytes, then return false.
452 if (response.length() <= kVersionStart) 575 if (response.length() <= kVersionStart)
453 return ZERO_LENGTH_ERROR; 576 return ZERO_LENGTH_ERROR;
454 if (response.length() <= kChecksumStart) 577 if (response.length() <= kChecksumStart)
455 return NO_CHECKSUM_ERROR; 578 return NO_CHECKSUM_ERROR;
456 if (response.length() <= kPayloadSizeStart) 579 if (response.length() <= kPayloadSizeStart)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 response.substr(kChecksumStart, kChecksumLength); 612 response.substr(kChecksumStart, kChecksumLength);
490 const char* checksum = checksum_string.c_str(); 613 const char* checksum = checksum_string.c_str();
491 uint32 checksum_value = atoi(checksum); 614 uint32 checksum_value = atoi(checksum);
492 if (checksum_value != sum) 615 if (checksum_value != sum)
493 return INVALID_CHECKSUM; 616 return INVALID_CHECKSUM;
494 617
495 // Verify the packet_number. 618 // Verify the packet_number.
496 char packet_number_data[kPacketNumberLength + 1]; 619 char packet_number_data[kPacketNumberLength + 1];
497 memset(packet_number_data, 0, kPacketNumberLength + 1); 620 memset(packet_number_data, 0, kPacketNumberLength + 1);
498 memcpy(packet_number_data, decoded_data, kPacketNumberLength); 621 memcpy(packet_number_data, decoded_data, kPacketNumberLength);
499 uint32 packet_number = atoi(packet_number_data); 622 uint32 packet_number_received = atoi(packet_number_data);
500 uint32 packet_index = packet_number - base_packet_number_; 623 if (packet_number_received < base_packet_number_)
501 if (packet_index > packets_to_send_) 624 return PREVIOUS_PACKET_NUMBER;
625 uint32 packet_index = packet_number_received - base_packet_number_;
626 if (packet_index >= packets_to_send_)
502 return INVALID_PACKET_NUMBER; 627 return INVALID_PACKET_NUMBER;
503 628
504 stream_.Reset(); 629 stream_.Reset();
505 if (!stream_.VerifyBytes(&decoded_data[kPacketNumberLength], 630 if (!stream_.VerifyBytes(&decoded_data[kPacketNumberLength],
506 message_length - kPacketNumberLength)) { 631 message_length - kPacketNumberLength)) {
507 return PATTERN_CHANGED; 632 return PATTERN_CHANGED;
508 } 633 }
509 634
510 packets_received_mask_ |= 1 << (packet_index - 1); 635 if (packets_received_mask_ & (1 << packet_index))
636 return DUPLICATE_PACKET;
637
638 packets_received_mask_ |= 1 << packet_index;
639 DCHECK_GE(packet_index, 0u);
640 DCHECK_LT(packet_index, packet_status_.size());
641 packet_status_[packet_index].end_time_ = base::TimeTicks::Now();
511 return SUCCESS; 642 return SUCCESS;
512 } 643 }
513 644
514 void NetworkStats::RecordAcksReceivedHistograms(const char* load_size_string) { 645 void NetworkStats::Finish(Status status, int result) {
646 // Set the base_packet_number_ for the start of next test. Changing the
647 // |base_packet_number_| indicates to OnReadDataTimeout that the Finish has
648 // already been called for the test and that it doesn't need to call Finish
649 // again.
650 base_packet_number_ = packet_number_ + 1;
651 RecordHistograms(PROTOCOL_UDP, status, result);
652
653 if (next_test() == NON_PACED_PACKET_TEST ||
654 next_test() == PACED_PACKET_TEST) {
655 MessageLoop::current()->PostTask(
656 FROM_HERE,
657 base::Bind(&NetworkStats::RestartPacketTest,
658 weak_factory_.GetWeakPtr()));
659 return;
660 }
661
662 DoFinishCallback(result);
663
664 // Close the socket so that there are no more IO operations.
665 net::UDPClientSocket* udp_socket =
666 static_cast<net::UDPClientSocket*>(socket());
667 if (udp_socket)
668 udp_socket->Close();
669
670 delete this;
671 }
672
673 void NetworkStats::DoFinishCallback(int result) {
674 if (!finished_callback_.is_null()) {
675 net::CompletionCallback callback = finished_callback_;
676 finished_callback_.Reset();
677 callback.Run(result);
678 }
679 }
680
681 void NetworkStats::RecordHistograms(const ProtocolValue& protocol,
682 const Status& status,
683 int result) {
684 if (packets_to_send_ != kMaximumSequentialPackets &&
685 packets_to_send_ != kMaximumCorrelationPackets) {
686 return;
687 }
688
689 std::string load_size_string = base::StringPrintf("%dB", load_size_);
690
691 if (packets_to_send_ == kMaximumCorrelationPackets) {
692 RecordPacketLossSeriesHistograms(
693 protocol, load_size_string, status, result);
694 return;
695 }
696
697 for (uint32 i = 0; i < 3; i++)
698 RecordRTTHistograms(protocol, load_size_string, i);
699
700 RecordRTTHistograms(protocol, load_size_string, 9);
701 RecordRTTHistograms(protocol, load_size_string, 19);
702
703 RecordAcksReceivedHistograms(load_size_string);
704 }
705
706 void NetworkStats::RecordAcksReceivedHistograms(
707 const std::string& load_size_string) {
708 DCHECK_EQ(packets_to_send_, kMaximumSequentialPackets);
709
710 const char* test_name = TestName();
515 bool received_atleast_one_packet = packets_received_mask_ > 0; 711 bool received_atleast_one_packet = packets_received_mask_ > 0;
712
516 std::string histogram_name = base::StringPrintf( 713 std::string histogram_name = base::StringPrintf(
517 "NetConnectivity2.Sent%d.GotAnAck.%d.%s", 714 "NetConnectivity3.%s.Sent%02d.GotAnAck.%d.%s",
715 test_name,
518 kMaximumSequentialPackets, 716 kMaximumSequentialPackets,
519 kPorts[histogram_port_], 717 kPorts[histogram_port_],
520 load_size_string); 718 load_size_string.c_str());
521 base::Histogram* got_an_ack_histogram = base::BooleanHistogram::FactoryGet( 719 base::Histogram* got_an_ack_histogram = base::BooleanHistogram::FactoryGet(
522 histogram_name, base::Histogram::kUmaTargetedHistogramFlag); 720 histogram_name, base::Histogram::kUmaTargetedHistogramFlag);
523 got_an_ack_histogram->AddBoolean(received_atleast_one_packet); 721 got_an_ack_histogram->AddBoolean(received_atleast_one_packet);
524 722
525 histogram_name = base::StringPrintf( 723 histogram_name = base::StringPrintf(
526 "NetConnectivity2.Sent%d.PacketsSent.%d.%s", 724 "NetConnectivity3.%s.Sent%02d.PacketsSent.%d.%s",
725 test_name,
527 kMaximumSequentialPackets, 726 kMaximumSequentialPackets,
528 kPorts[histogram_port_], 727 kPorts[histogram_port_],
529 load_size_string); 728 load_size_string.c_str());
530 base::Histogram* packets_sent_histogram = 729 base::Histogram* packets_sent_histogram =
531 base::Histogram::FactoryGet( 730 base::Histogram::FactoryGet(
532 histogram_name, 731 histogram_name,
533 1, kMaximumSequentialPackets, kMaximumSequentialPackets + 1, 732 1, kMaximumSequentialPackets, kMaximumSequentialPackets + 1,
534 base::Histogram::kUmaTargetedHistogramFlag); 733 base::Histogram::kUmaTargetedHistogramFlag);
535 packets_sent_histogram->Add(packets_sent_); 734 packets_sent_histogram->Add(packets_sent_);
536 735
537 if (!received_atleast_one_packet || packets_sent_ != packets_to_send_) 736 if (!received_atleast_one_packet || packets_sent_ != packets_to_send_)
538 return; 737 return;
539 738
540 histogram_name = base::StringPrintf( 739 histogram_name = base::StringPrintf(
541 "NetConnectivity2.Sent%d.AckReceivedForNthPacket.%d.%s", 740 "NetConnectivity3.%s.Sent%02d.AckReceivedForNthPacket.%02d.%s",
741 test_name,
542 kMaximumSequentialPackets, 742 kMaximumSequentialPackets,
543 kPorts[histogram_port_], 743 kPorts[histogram_port_],
544 load_size_string); 744 load_size_string.c_str());
545 base::Histogram* ack_received_for_nth_packet_histogram = 745 base::Histogram* ack_received_for_nth_packet_histogram =
546 base::Histogram::FactoryGet( 746 base::Histogram::FactoryGet(
547 histogram_name, 747 histogram_name,
548 1, kMaximumSequentialPackets, kMaximumSequentialPackets + 1, 748 1, kMaximumSequentialPackets + 1, kMaximumSequentialPackets + 2,
549 base::Histogram::kUmaTargetedHistogramFlag); 749 base::Histogram::kUmaTargetedHistogramFlag);
550 750
551 int count = 0; 751 int count = 0;
552 for (size_t j = 0; j < packets_to_send_; j++) { 752 for (size_t j = 0; j < packets_to_send_; j++) {
553 int packet_number = j + 1; 753 int packet_number = j + 1;
554 if (packets_received_mask_ & (1 << j)) { 754 if (packets_received_mask_ & (1 << j)) {
555 ack_received_for_nth_packet_histogram->Add(packet_number); 755 ack_received_for_nth_packet_histogram->Add(packet_number);
556 count++; 756 count++;
557 } 757 }
558 if (packet_number < 2) 758 if (packet_number < 2)
559 continue; 759 continue;
560 histogram_name = base::StringPrintf( 760 histogram_name = base::StringPrintf(
561 "NetConnectivity2.Sent%d.AcksReceivedFromFirst%dPackets.%d.%s", 761 "NetConnectivity3.%s.Sent%02d.AcksReceivedFromFirst%02dPackets.%d.%s",
762 test_name,
562 kMaximumSequentialPackets, 763 kMaximumSequentialPackets,
563 packet_number, 764 packet_number,
564 kPorts[histogram_port_], 765 kPorts[histogram_port_],
565 load_size_string); 766 load_size_string.c_str());
566 base::Histogram* acks_received_count_histogram = 767 base::Histogram* acks_received_count_histogram =
567 base::Histogram::FactoryGet( 768 base::Histogram::FactoryGet(
568 histogram_name, 1, packet_number, packet_number + 1, 769 histogram_name, 1, packet_number, packet_number + 1,
569 base::Histogram::kUmaTargetedHistogramFlag); 770 base::Histogram::kUmaTargetedHistogramFlag);
570 acks_received_count_histogram->Add(count); 771 acks_received_count_histogram->Add(count);
571 } 772 }
572 } 773 }
573 774
574 void NetworkStats::RecordPacketLossSeriesHistograms( 775 void NetworkStats::RecordPacketLossSeriesHistograms(
575 const ProtocolValue& protocol, 776 const ProtocolValue& protocol,
777 const std::string& load_size_string,
576 const Status& status, 778 const Status& status,
577 const char* load_size_string,
578 int result) { 779 int result) {
579 if (packets_to_send_ < 2 || protocol != PROTOCOL_UDP) 780 DCHECK_EQ(packets_to_send_, kMaximumCorrelationPackets);
580 return;
581 781
582 // Build "NetConnectivity2.Send6.SeriesAcked.<port>.<load_size>" histogram 782 const char* test_name = TestName();
783
784 // Build "NetConnectivity3.Send6.SeriesAcked.<port>.<load_size>" histogram
583 // name. Total number of histograms are 5*2. 785 // name. Total number of histograms are 5*2.
584 std::string series_acked_histogram_name = base::StringPrintf( 786 std::string series_acked_histogram_name = base::StringPrintf(
585 "NetConnectivity2.Send6.SeriesAcked.%d.%s", 787 "NetConnectivity3.%s.Send6.SeriesAcked.%d.%s",
788 test_name,
586 kPorts[histogram_port_], 789 kPorts[histogram_port_],
587 load_size_string); 790 load_size_string.c_str());
588 // Build "NetConnectivity2.Send6.PacketsSent.<port>.<load_size>" histogram 791 // Build "NetConnectivity3.Send6.PacketsSent.<port>.<load_size>" histogram
589 // name. Total number of histograms are 5*2. 792 // name. Total number of histograms are 5*2.
590 std::string packets_sent_histogram_name = base::StringPrintf( 793 std::string packets_sent_histogram_name = base::StringPrintf(
591 "NetConnectivity2.Send6.PacketsSent.%d.%s", 794 "NetConnectivity3.%s.Send6.PacketsSent.%d.%s",
795 test_name,
592 kPorts[histogram_port_], 796 kPorts[histogram_port_],
593 load_size_string); 797 load_size_string.c_str());
594 798
595 // If we are running without a proxy, we'll generate 2 distinct histograms in 799 // If we are running without a proxy, we'll generate 2 distinct histograms in
596 // each case, one will have the ".NoProxy" suffix. 800 // each case, one will have the ".NoProxy" suffix.
597 size_t histogram_count = has_proxy_server_ ? 1 : 2; 801 size_t histogram_count = has_proxy_server_ ? 1 : 2;
598 for (size_t i = 0; i < histogram_count; i++) { 802 for (size_t i = 0; i < histogram_count; i++) {
599 // For packet loss test, just record packet loss data. 803 // For packet loss test, just record packet loss data.
600 base::Histogram* series_acked_histogram = base::LinearHistogram::FactoryGet( 804 base::Histogram* series_acked_histogram = base::LinearHistogram::FactoryGet(
601 series_acked_histogram_name, 805 series_acked_histogram_name,
602 1, 806 1,
603 2 << kMaximumCorrelationPackets, 807 2 << kMaximumCorrelationPackets,
604 (2 << kMaximumCorrelationPackets) + 1, 808 (2 << kMaximumCorrelationPackets) + 1,
605 base::Histogram::kUmaTargetedHistogramFlag); 809 base::Histogram::kUmaTargetedHistogramFlag);
606 series_acked_histogram->Add(packets_received_mask_); 810 series_acked_histogram->Add(packets_received_mask_);
607 series_acked_histogram_name.append(".NoProxy"); 811 series_acked_histogram_name.append(".NoProxy");
608 812
609 base::Histogram* packets_sent_histogram = 813 base::Histogram* packets_sent_histogram =
610 base::Histogram::FactoryGet( 814 base::Histogram::FactoryGet(
611 packets_sent_histogram_name, 815 packets_sent_histogram_name,
612 1, kMaximumCorrelationPackets, kMaximumCorrelationPackets + 1, 816 1, kMaximumCorrelationPackets, kMaximumCorrelationPackets + 1,
613 base::Histogram::kUmaTargetedHistogramFlag); 817 base::Histogram::kUmaTargetedHistogramFlag);
614 packets_sent_histogram->Add(packets_sent_); 818 packets_sent_histogram->Add(packets_sent_);
615 packets_sent_histogram_name.append(".NoProxy"); 819 packets_sent_histogram_name.append(".NoProxy");
616 } 820 }
617 } 821 }
618 822
619 void NetworkStats::RecordHistograms(const ProtocolValue& protocol, 823 void NetworkStats::RecordRTTHistograms(const ProtocolValue& protocol,
620 const Status& status, 824 const std::string& load_size_string,
621 int result) { 825 uint32 index) {
622 // Build <load_size> string. 826 DCHECK_GE(index, 0u);
623 const char* kSmallLoadString = "100B"; 827 DCHECK_LT(index, packet_status_.size());
624 const char* kMediumLoadString = "500B";
625 const char* kLargeLoadString = "1K";
626 const char* load_size_string;
627 if (load_size_ == kSmallTestBytesToSend)
628 load_size_string = kSmallLoadString;
629 else if (load_size_ == kMediumTestBytesToSend)
630 load_size_string = kMediumLoadString;
631 else
632 load_size_string = kLargeLoadString;
633 828
634 if (packets_to_send_ == kMaximumSequentialPackets) { 829 const char* test_name = TestName();
635 RecordAcksReceivedHistograms(load_size_string); 830 std::string rtt_histogram_name = base::StringPrintf(
636 return; 831 "NetConnectivity3.%s.Sent%02d.Success.RTT.Packet%02d.%d.%s",
637 } 832 test_name,
638 RecordPacketLossSeriesHistograms(protocol, status, load_size_string, result); 833 packets_to_send_,
834 index + 1,
835 kPorts[histogram_port_],
836 load_size_string.c_str());
837 base::Histogram* rtt_histogram = base::Histogram::FactoryTimeGet(
838 rtt_histogram_name,
839 base::TimeDelta::FromMilliseconds(10),
840 base::TimeDelta::FromSeconds(30), 50,
841 base::Histogram::kUmaTargetedHistogramFlag);
842 base::TimeDelta duration =
843 packet_status_[index].end_time_ - packet_status_[index].start_time_;
844 rtt_histogram->AddTime(duration);
639 } 845 }
640 846
641 // UDPStatsClient methods and members. 847 const char* NetworkStats::TestName() {
642 UDPStatsClient::UDPStatsClient() 848 switch (current_test_) {
643 : NetworkStats() { 849 case START_PACKET_TEST:
850 return "StartPacket";
851 case NON_PACED_PACKET_TEST:
852 return "NonPacedPacket";
853 case PACED_PACKET_TEST:
854 return "PacedPacket";
855 default:
856 NOTREACHED();
857 return "None";
858 }
644 } 859 }
645 860
646 UDPStatsClient::~UDPStatsClient() { 861 void NetworkStats::set_socket(net::Socket* socket) {
647 } 862 DCHECK(socket);
648 863 DCHECK(!socket_.get());
649 bool UDPStatsClient::DoConnect(int result) { 864 socket_.reset(socket);
650 if (result != net::OK) {
651 Finish(RESOLVE_FAILED, result);
652 return false;
653 }
654
655 net::UDPClientSocket* udp_socket =
656 new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND,
657 net::RandIntCallback(),
658 NULL,
659 net::NetLog::Source());
660 if (!udp_socket) {
661 Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT);
662 return false;
663 }
664 set_socket(udp_socket);
665
666 if (addresses().empty()) {
667 Finish(RESOLVE_FAILED, net::ERR_INVALID_ARGUMENT);
668 return false;
669 }
670
671 const net::IPEndPoint& endpoint = addresses().front();
672 int rv = udp_socket->Connect(endpoint);
673 if (rv < 0) {
674 Finish(CONNECT_FAILED, rv);
675 return false;
676 }
677 return NetworkStats::ConnectComplete(rv);
678 }
679
680 bool UDPStatsClient::ReadComplete(int result) {
681 DCHECK_NE(net::ERR_IO_PENDING, result);
682 if (result <= 0) {
683 Finish(READ_FAILED, result);
684 return true;
685 }
686 return NetworkStats::ReadComplete(result);
687 }
688
689 void UDPStatsClient::Finish(Status status, int result) {
690 RecordHistograms(PROTOCOL_UDP, status, result);
691
692 DoFinishCallback(result);
693
694 // Close the socket so that there are no more IO operations.
695 net::UDPClientSocket* udp_socket =
696 static_cast<net::UDPClientSocket*>(socket());
697 if (udp_socket)
698 udp_socket->Close();
699
700 delete this;
701 }
702
703 // TCPStatsClient methods and members.
704 TCPStatsClient::TCPStatsClient() {
705 }
706
707 TCPStatsClient::~TCPStatsClient() {
708 }
709
710 bool TCPStatsClient::DoConnect(int result) {
711 if (result != net::OK) {
712 Finish(RESOLVE_FAILED, result);
713 return false;
714 }
715
716 net::TCPClientSocket* tcp_socket =
717 new net::TCPClientSocket(addresses(), NULL, net::NetLog::Source());
718 if (!tcp_socket) {
719 Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT);
720 return false;
721 }
722 set_socket(tcp_socket);
723
724 int rv = tcp_socket->Connect(base::Bind(&TCPStatsClient::OnConnectComplete,
725 base::Unretained(this)));
726 if (rv == net::ERR_IO_PENDING)
727 return true;
728
729 return NetworkStats::ConnectComplete(rv);
730 }
731
732 void TCPStatsClient::OnConnectComplete(int result) {
733 NetworkStats::ConnectComplete(result);
734 }
735
736 bool TCPStatsClient::ReadComplete(int result) {
737 DCHECK_NE(net::ERR_IO_PENDING, result);
738 if (result < 0) {
739 Finish(READ_FAILED, result);
740 return true;
741 }
742 return NetworkStats::ReadComplete(result);
743 }
744
745 void TCPStatsClient::Finish(Status status, int result) {
746 RecordHistograms(PROTOCOL_TCP, status, result);
747
748 DoFinishCallback(result);
749
750 // Disconnect the socket so that there are no more IO operations.
751 net::TCPClientSocket* tcp_socket =
752 static_cast<net::TCPClientSocket*>(socket());
753 if (tcp_socket)
754 tcp_socket->Disconnect();
755
756 delete this;
757 } 865 }
758 866
759 // ProxyDetector methods and members. 867 // ProxyDetector methods and members.
760 ProxyDetector::ProxyDetector(net::ProxyService* proxy_service, 868 ProxyDetector::ProxyDetector(net::ProxyService* proxy_service,
761 const net::HostPortPair& server_address, 869 const net::HostPortPair& server_address,
762 OnResolvedCallback callback) 870 OnResolvedCallback callback)
763 : proxy_service_(proxy_service), 871 : proxy_service_(proxy_service),
764 server_address_(server_address), 872 server_address_(server_address),
765 callback_(callback), 873 callback_(callback),
766 has_pending_proxy_resolution_(false) { 874 has_pending_proxy_resolution_(false) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 // Check that there is a network connection. We get called only if UMA upload 935 // Check that there is a network connection. We get called only if UMA upload
828 // to the server has succeeded. 936 // to the server has succeeded.
829 DCHECK(!net::NetworkChangeNotifier::IsOffline()); 937 DCHECK(!net::NetworkChangeNotifier::IsOffline());
830 938
831 CR_DEFINE_STATIC_LOCAL(scoped_refptr<base::FieldTrial>, trial, ()); 939 CR_DEFINE_STATIC_LOCAL(scoped_refptr<base::FieldTrial>, trial, ());
832 static bool collect_stats = false; 940 static bool collect_stats = false;
833 static NetworkStats::HistogramPortSelector histogram_port = 941 static NetworkStats::HistogramPortSelector histogram_port =
834 NetworkStats::PORT_6121; 942 NetworkStats::PORT_6121;
835 943
836 if (!trial.get()) { 944 if (!trial.get()) {
837 // Set up a field trial to collect network stats for UDP and TCP. 945 // Set up a field trial to collect network stats for UDP.
838 const base::FieldTrial::Probability kDivisor = 1000; 946 const base::FieldTrial::Probability kDivisor = 1000;
839 947
840 // Enable the connectivity testing for 0.5% of the users in stable channel. 948 // Enable the connectivity testing for 0.5% of the users in stable channel.
841 base::FieldTrial::Probability probability_per_group = 5; 949 base::FieldTrial::Probability probability_per_group = 5;
842 950
843 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 951 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
844 if (channel == chrome::VersionInfo::CHANNEL_CANARY) 952 if (channel == chrome::VersionInfo::CHANNEL_CANARY)
845 probability_per_group = kDivisor; 953 probability_per_group = kDivisor;
846 else if (channel == chrome::VersionInfo::CHANNEL_DEV) 954 else if (channel == chrome::VersionInfo::CHANNEL_DEV)
847 // Enable the connectivity testing for 10% of the users in dev channel. 955 // Enable the connectivity testing for 10% of the users in dev channel.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 1003
896 // static 1004 // static
897 void StartNetworkStatsTest(net::HostResolver* host_resolver, 1005 void StartNetworkStatsTest(net::HostResolver* host_resolver,
898 const net::HostPortPair& server_address, 1006 const net::HostPortPair& server_address,
899 NetworkStats::HistogramPortSelector histogram_port, 1007 NetworkStats::HistogramPortSelector histogram_port,
900 bool has_proxy_server) { 1008 bool has_proxy_server) {
901 int experiment_to_run = base::RandInt(1, 4); 1009 int experiment_to_run = base::RandInt(1, 4);
902 switch (experiment_to_run) { 1010 switch (experiment_to_run) {
903 case 1: 1011 case 1:
904 { 1012 {
905 UDPStatsClient* udp_stats_client = new UDPStatsClient(); 1013 NetworkStats* udp_stats_client = new NetworkStats();
906 udp_stats_client->Start( 1014 udp_stats_client->Start(
907 host_resolver, server_address, histogram_port, has_proxy_server, 1015 host_resolver, server_address, histogram_port, has_proxy_server,
908 kSmallTestBytesToSend, kMaximumCorrelationPackets, 1016 kLargeTestBytesToSend, kMaximumCorrelationPackets,
909 net::CompletionCallback()); 1017 net::CompletionCallback());
910 } 1018 }
911 break; 1019 break;
912 case 2: 1020 case 2:
913 { 1021 {
914 UDPStatsClient* udp_stats_client = new UDPStatsClient(); 1022 NetworkStats* udp_stats_client = new NetworkStats();
915 udp_stats_client->Start( 1023 udp_stats_client->Start(
916 host_resolver, server_address, histogram_port, has_proxy_server, 1024 host_resolver, server_address, histogram_port, has_proxy_server,
917 kSmallTestBytesToSend, kMaximumSequentialPackets, 1025 kSmallTestBytesToSend, kMaximumSequentialPackets,
918 net::CompletionCallback()); 1026 net::CompletionCallback());
919 } 1027 }
920 break; 1028 break;
921 case 3: 1029 case 3:
922 { 1030 {
923 UDPStatsClient* udp_stats_client = new UDPStatsClient(); 1031 NetworkStats* udp_stats_client = new NetworkStats();
924 udp_stats_client->Start( 1032 udp_stats_client->Start(
925 host_resolver, server_address, histogram_port, has_proxy_server, 1033 host_resolver, server_address, histogram_port, has_proxy_server,
926 kMediumTestBytesToSend, kMaximumSequentialPackets, 1034 kMediumTestBytesToSend, kMaximumSequentialPackets,
927 net::CompletionCallback()); 1035 net::CompletionCallback());
928 } 1036 }
929 break; 1037 break;
930 case 4: 1038 case 4:
931 { 1039 {
932 UDPStatsClient* udp_stats_client = new UDPStatsClient(); 1040 NetworkStats* udp_stats_client = new NetworkStats();
933 udp_stats_client->Start( 1041 udp_stats_client->Start(
934 host_resolver, server_address, histogram_port, has_proxy_server, 1042 host_resolver, server_address, histogram_port, has_proxy_server,
935 kLargeTestBytesToSend, kMaximumSequentialPackets, 1043 kLargeTestBytesToSend, kMaximumSequentialPackets,
936 net::CompletionCallback()); 1044 net::CompletionCallback());
937 } 1045 }
938 break; 1046 break;
939 } 1047 }
940 } 1048 }
941 1049
942 } // namespace chrome_browser_net 1050 } // namespace chrome_browser_net
OLDNEW
« no previous file with comments | « chrome/browser/net/network_stats.h ('k') | chrome/browser/net/network_stats_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698