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

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 20 matching lines...) Expand all
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.
88 static const int32 kPorts[] = {53, 80, 587, 6121, 8080, 999999}; 84 static const int32 kPorts[] = {6121, 999999};
jar (doing other things) 2012/09/05 01:00:55 Is this a sentinel? If so, use a named constant to
ramant (doing other things) 2012/09/05 04:28:54 999999 is used by the unit tests. Added a comment
89
90 // The packet number that is to be sent to the server.
91 static uint32 g_packet_number_ = 0;
92 85
93 // Maximum number of packets that can be sent to the server for packet loss 86 // Maximum number of packets that can be sent to the server for packet loss
94 // correlation test. 87 // correlation test.
95 static const uint32 kMaximumCorrelationPackets = 6; 88 static const uint32 kMaximumCorrelationPackets = 6;
96 89
97 // Maximum number of packets that can be sent to the server. 90 // Maximum number of packets that can be sent to the server.
98 static const uint32 kMaximumSequentialPackets = 21; 91 static const uint32 kMaximumSequentialPackets = 21;
99 92
93 // This specifies the maximum message (payload) size.
94 static const uint32 kMaxMessage = kMaximumSequentialPackets * 2048;
95
100 // NetworkStats methods and members. 96 // NetworkStats methods and members.
101 NetworkStats::NetworkStats() 97 NetworkStats::NetworkStats()
102 : load_size_(0), 98 : read_buffer_(NULL),
99 write_buffer_(NULL),
100 load_size_(0),
103 bytes_to_read_(0), 101 bytes_to_read_(0),
104 bytes_to_send_(0), 102 bytes_to_send_(0),
105 has_proxy_server_(false), 103 has_proxy_server_(false),
106 packets_to_send_(0), 104 packets_to_send_(0),
107 packets_sent_(0), 105 packets_sent_(0),
106 packets_received_(0),
107 packets_received_mask_(0),
108 packet_number_(0),
108 base_packet_number_(0), 109 base_packet_number_(0),
109 packets_received_mask_(0), 110 sending_complete_(false),
111 current_test_(START_PACKET_TEST),
112 next_test_(TEST_TYPE_MAX),
110 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 113 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
111 } 114 }
112 115
113 NetworkStats::~NetworkStats() { 116 NetworkStats::~NetworkStats() {
114 socket_.reset(); 117 socket_.reset();
115 } 118 }
116 119
117 bool NetworkStats::Start(net::HostResolver* host_resolver, 120 bool NetworkStats::Start(net::HostResolver* host_resolver,
118 const net::HostPortPair& server_host_port_pair, 121 const net::HostPortPair& server_host_port_pair,
119 HistogramPortSelector histogram_port, 122 HistogramPortSelector histogram_port,
(...skipping 15 matching lines...) Expand all
135 int rv = host_resolver->Resolve( 138 int rv = host_resolver->Resolve(
136 request, &addresses_, 139 request, &addresses_,
137 base::Bind(&NetworkStats::OnResolveComplete, 140 base::Bind(&NetworkStats::OnResolveComplete,
138 base::Unretained(this)), 141 base::Unretained(this)),
139 NULL, net::BoundNetLog()); 142 NULL, net::BoundNetLog());
140 if (rv == net::ERR_IO_PENDING) 143 if (rv == net::ERR_IO_PENDING)
141 return true; 144 return true;
142 return DoConnect(rv); 145 return DoConnect(rv);
143 } 146 }
144 147
148 void NetworkStats::RestartPacketTest() {
149 ResetData();
150 current_test_ = next_test_;
151 next_test_ = TEST_TYPE_MAX;
152 if (!bytes_to_read_) {
153 read_buffer_ = NULL;
154 ReadData();
155 }
156 SendPacket();
157 }
158
145 void NetworkStats::Initialize( 159 void NetworkStats::Initialize(
146 uint32 bytes_to_send, 160 uint32 bytes_to_send,
147 HistogramPortSelector histogram_port, 161 HistogramPortSelector histogram_port,
148 bool has_proxy_server, 162 bool has_proxy_server,
149 uint32 packets_to_send, 163 uint32 packets_to_send,
150 const net::CompletionCallback& finished_callback) { 164 const net::CompletionCallback& finished_callback) {
151 DCHECK(bytes_to_send); // We should have data to send. 165 DCHECK(bytes_to_send); // We should have data to send.
152 DCHECK(packets_to_send); // We should send at least 1 packet. 166 DCHECK(packets_to_send); // We should send at least 1 packet.
153 DCHECK_LE(bytes_to_send, kLargeTestBytesToSend); 167 DCHECK_LE(bytes_to_send, kLargeTestBytesToSend);
168 DCHECK_LE(packets_to_send, 8 * sizeof(packets_received_mask_));
154 169
155 load_size_ = bytes_to_send; 170 load_size_ = bytes_to_send;
156 packets_to_send_ = packets_to_send; 171 packets_to_send_ = packets_to_send;
157
158 histogram_port_ = histogram_port; 172 histogram_port_ = histogram_port;
159 has_proxy_server_ = has_proxy_server; 173 has_proxy_server_ = has_proxy_server;
160 finished_callback_ = finished_callback; 174 finished_callback_ = finished_callback;
175 ResetData();
176 packet_number_ = base::RandInt(1 << 28, INT_MAX);
177 }
178
179 void NetworkStats::ResetData() {
180 write_buffer_ = NULL;
181 bytes_to_send_ = 0;
182 packet_status_.clear();
183 packet_status_.resize(packets_to_send_);
184 packets_sent_ = 0;
185 packets_received_ = 0;
186 packets_received_mask_ = 0;
187 sending_complete_ = false;
188 }
189
190 void NetworkStats::OnResolveComplete(int result) {
191 DoConnect(result);
192 }
193
194 bool NetworkStats::DoConnect(int result) {
195 if (result != net::OK) {
196 Finish(RESOLVE_FAILED, result);
197 return false;
198 }
199
200 net::UDPClientSocket* udp_socket =
201 new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND,
202 net::RandIntCallback(),
203 NULL,
204 net::NetLog::Source());
205 if (!udp_socket) {
206 Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT);
207 return false;
208 }
209 set_socket(udp_socket);
210
211 if (addresses().empty()) {
212 Finish(RESOLVE_FAILED, net::ERR_INVALID_ARGUMENT);
213 return false;
214 }
215
216 const net::IPEndPoint& endpoint = addresses().front();
217 int rv = udp_socket->Connect(endpoint);
218 if (rv < 0) {
219 Finish(CONNECT_FAILED, rv);
220 return false;
221 }
222
223 const int kSocketBufferSize = packets_to_send_ * 2048;
jar (doing other things) 2012/09/05 01:00:55 Perhaps we want this to be double the packets_to_s
ramant (doing other things) 2012/09/05 04:28:54 Done.
224 udp_socket->SetSendBufferSize(kSocketBufferSize);
225 udp_socket->SetReceiveBufferSize(kSocketBufferSize);
226 return ConnectComplete(rv);
161 } 227 }
162 228
163 bool NetworkStats::ConnectComplete(int result) { 229 bool NetworkStats::ConnectComplete(int result) {
164 if (result < 0) { 230 if (result < 0) {
165 Finish(CONNECT_FAILED, result); 231 Finish(CONNECT_FAILED, result);
166 return false; 232 return false;
167 } 233 }
168 234
169 base_packet_number_ = g_packet_number_; 235 ReadData();
170 start_time_ = base::TimeTicks::Now();
171 SendPacket(); 236 SendPacket();
172 return true; 237 return true;
173 } 238 }
174 239
175 void NetworkStats::DoFinishCallback(int result) { 240 void NetworkStats::SendPacket() {
176 if (!finished_callback_.is_null()) { 241 while (true) {
177 net::CompletionCallback callback = finished_callback_; 242 if (bytes_to_send_ == 0u) {
178 finished_callback_.Reset(); 243 if (packets_sent_ >= packets_to_send_) {
179 callback.Run(result); 244 // Timeout if we don't get response back from echo servers in 30 secs.
180 } 245 sending_complete_ = true;
246 const int kReadDataTimeoutMs = 30000;
247 StartReadDataTimer(kReadDataTimeoutMs);
248 break;
249 }
250
251 ++packet_number_;
252 if (packets_sent_ == 0)
253 base_packet_number_ = packet_number_;
254 bytes_to_send_ = SendingPacketSize();
255 SendNextPacketAfterDelay();
256 break;
257 }
258
259 int rv = SendData();
260 if (rv < 0) {
261 if (rv != net::ERR_IO_PENDING)
262 Finish(WRITE_FAILED, rv);
263 break;
264 }
265 DCHECK_EQ(bytes_to_send_, 0u);
266 };
181 } 267 }
182 268
183 void NetworkStats::set_socket(net::Socket* socket) { 269 void NetworkStats::SendNextPacketAfterDelay() {
184 DCHECK(socket); 270 if (current_test_ == PACED_PACKET_TEST) {
185 DCHECK(!socket_.get()); 271 MessageLoop::current()->PostDelayedTask(
186 socket_.reset(socket); 272 FROM_HERE,
273 base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr()),
274 average_time_);
275 return;
276 }
277
278 MessageLoop::current()->PostTask(
279 FROM_HERE,
280 base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr()));
187 } 281 }
188 282
189 bool NetworkStats::ReadComplete(int result) { 283 bool NetworkStats::ReadComplete(int result) {
190 DCHECK(socket_.get()); 284 DCHECK(socket_.get());
191 DCHECK_NE(net::ERR_IO_PENDING, result); 285 DCHECK_NE(net::ERR_IO_PENDING, result);
192 if (result < 0) { 286 if (result < 0) {
193 Finish(READ_FAILED, result); 287 Finish(READ_FAILED, result);
194 return true; 288 return true;
195 } 289 }
196 290
197 encoded_message_.append(read_buffer_->data(), result); 291 if (result > 0) {
292 std::string encoded_message;
293 encoded_message.append(read_buffer_->data(), result);
294 if (VerifyBytes(encoded_message) == SUCCESS) {
295 base::TimeTicks now = base::TimeTicks::Now();
296 if (packets_received_ == 0)
297 packet_1st_byte_read_time_ = now;
298 packet_last_byte_read_time_ = now;
299
300 DCHECK_GE(bytes_to_read_, static_cast<uint32>(result));
301 if (bytes_to_read_ >= static_cast<uint32>(result))
302 bytes_to_read_ -= result;
303 ++packets_received_;
304 }
305 }
198 306
199 read_buffer_ = NULL; 307 read_buffer_ = NULL;
200 bytes_to_read_ -= result;
201 308
202 // No more data to read. 309 // No more data to read.
203 if (!bytes_to_read_ || result == 0) { 310 if (!bytes_to_read_ || result == 0) {
311 if (!sending_complete_)
312 return false;
313
204 Status status = VerifyPackets(); 314 Status status = VerifyPackets();
205 if (status == SUCCESS) 315 if (status == SUCCESS)
206 Finish(status, net::OK); 316 Finish(status, net::OK);
207 else 317 else
208 Finish(status, net::ERR_INVALID_RESPONSE); 318 Finish(status, net::ERR_INVALID_RESPONSE);
209 return true; 319 return true;
210 } 320 }
211 return false; 321 return false;
212 } 322 }
213 323
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) { 324 void NetworkStats::OnReadComplete(int result) {
244 if (!ReadComplete(result)) { 325 if (!ReadComplete(result)) {
245 // Called ReadData() via PostDelayedTask() to avoid recursion. Added a delay 326 // 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 327 // 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 328 // the CPU too extensively (waiting for the time-out) in case of an infinite
248 // loop. 329 // loop.
249 MessageLoop::current()->PostDelayedTask( 330 MessageLoop::current()->PostDelayedTask(
250 FROM_HERE, 331 FROM_HERE,
251 base::Bind(&NetworkStats::ReadData, weak_factory_.GetWeakPtr()), 332 base::Bind(&NetworkStats::ReadData, weak_factory_.GetWeakPtr()),
252 base::TimeDelta::FromMilliseconds(1)); 333 base::TimeDelta::FromMilliseconds(1));
(...skipping 22 matching lines...) Expand all
275 356
276 MessageLoop::current()->PostTask( 357 MessageLoop::current()->PostTask(
277 FROM_HERE, 358 FROM_HERE,
278 base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr())); 359 base::Bind(&NetworkStats::SendPacket, weak_factory_.GetWeakPtr()));
279 } 360 }
280 361
281 void NetworkStats::ReadData() { 362 void NetworkStats::ReadData() {
282 int rv; 363 int rv;
283 do { 364 do {
284 if (!socket_.get()) 365 if (!socket_.get())
285 return; 366 break;
286 367
287 DCHECK(!read_buffer_.get()); 368 DCHECK(!read_buffer_.get());
288 369
289 // We release the read_buffer_ in the destructor if there is an error. 370 // We release the read_buffer_ in the destructor if there is an error.
290 read_buffer_ = new net::IOBuffer(kMaxMessage); 371 read_buffer_ = new net::IOBuffer(kMaxMessage);
291 372
292 rv = socket_->Read(read_buffer_, kMaxMessage, 373 rv = socket_->Read(read_buffer_, kMaxMessage,
293 base::Bind(&NetworkStats::OnReadComplete, 374 base::Bind(&NetworkStats::OnReadComplete,
294 base::Unretained(this))); 375 base::Unretained(this)));
295 if (rv == net::ERR_IO_PENDING) 376 if (rv == net::ERR_IO_PENDING)
296 return; 377 break;
378
297 // If we have read all the data then return. 379 // If we have read all the data then return.
298 if (ReadComplete(rv)) 380 if (ReadComplete(rv))
299 return; 381 break;
300 } while (rv > 0); 382 } while (rv > 0);
301 } 383 }
302 384
303 int NetworkStats::SendData() { 385 int NetworkStats::SendData() {
304 DCHECK(bytes_to_send_); // We should have data to send. 386 DCHECK(bytes_to_send_); // We should have data to send.
305 do { 387 do {
306 if (!write_buffer_.get()) { 388 if (!write_buffer_.get()) {
389 // Send a new packet.
307 scoped_refptr<net::IOBufferWithSize> buffer( 390 scoped_refptr<net::IOBufferWithSize> buffer(
308 new net::IOBufferWithSize(bytes_to_send_)); 391 new net::IOBufferWithSize(bytes_to_send_));
309 GetEchoRequest(buffer); 392 GetEchoRequest(buffer);
310 write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_); 393 write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_);
394
395 // As soon as we write, a read could happen. Thus update all the book
396 // keeping data.
397 bytes_to_read_ += ReceivingPacketSize();
398 ++packets_sent_;
399 if (packets_sent_ >= packets_to_send_)
400 sending_complete_ = true;
401
402 uint32 packet_index = packet_number_ - base_packet_number_;
403 DCHECK_GE(packet_index, 0u);
404 DCHECK_LT(packet_index, packet_status_.size());
405 packet_status_[packet_index].start_time_ = base::TimeTicks::Now();
311 } 406 }
312 407
313 if (!socket_.get()) 408 if (!socket_.get())
314 return net::ERR_UNEXPECTED; 409 return net::ERR_UNEXPECTED;
315 int rv = socket_->Write(write_buffer_, 410 int rv = socket_->Write(write_buffer_,
316 write_buffer_->BytesRemaining(), 411 write_buffer_->BytesRemaining(),
317 base::Bind(&NetworkStats::OnWriteComplete, 412 base::Bind(&NetworkStats::OnWriteComplete,
318 base::Unretained(this))); 413 base::Unretained(this)));
319 if (rv < 0) 414 if (rv < 0)
320 return rv; 415 return rv;
321 DidSendData(rv); 416 DidSendData(rv);
322 } while (bytes_to_send_); 417 } while (bytes_to_send_);
323 return net::OK; 418 return net::OK;
324 } 419 }
325 420
326 uint32 NetworkStats::SendingPacketSize() const { 421 uint32 NetworkStats::SendingPacketSize() const {
327 return kVersionLength + kChecksumLength + kPayloadSizeLength + load_size_; 422 return kVersionLength + kChecksumLength + kPayloadSizeLength + load_size_;
328 } 423 }
329 424
330 uint32 NetworkStats::ReceivingPacketSize() const { 425 uint32 NetworkStats::ReceivingPacketSize() const {
331 return kVersionLength + kChecksumLength + kPayloadSizeLength + kKeyLength + 426 return kVersionLength + kChecksumLength + kPayloadSizeLength + kKeyLength +
332 load_size_; 427 load_size_;
333 } 428 }
334 429
335 void NetworkStats::DidSendData(int bytes_sent) { 430 void NetworkStats::DidSendData(int bytes_sent) {
336 write_buffer_->DidConsume(bytes_sent); 431 write_buffer_->DidConsume(bytes_sent);
337 if (!write_buffer_->BytesRemaining()) 432 if (!write_buffer_->BytesRemaining())
338 write_buffer_ = NULL; 433 write_buffer_ = NULL;
339 bytes_to_send_ -= bytes_sent; 434 bytes_to_send_ -= bytes_sent;
340 if (bytes_to_send_ == 0)
341 ++packets_sent_;
342 } 435 }
343 436
344 void NetworkStats::StartReadDataTimer(int milliseconds) { 437 void NetworkStats::StartReadDataTimer(int milliseconds) {
345 MessageLoop::current()->PostDelayedTask( 438 MessageLoop::current()->PostDelayedTask(
346 FROM_HERE, 439 FROM_HERE,
347 base::Bind(&NetworkStats::OnReadDataTimeout, weak_factory_.GetWeakPtr()), 440 base::Bind(&NetworkStats::OnReadDataTimeout,
441 weak_factory_.GetWeakPtr(),
442 base_packet_number_),
348 base::TimeDelta::FromMilliseconds(milliseconds)); 443 base::TimeDelta::FromMilliseconds(milliseconds));
349 } 444 }
350 445
351 void NetworkStats::OnReadDataTimeout() { 446 void NetworkStats::OnReadDataTimeout(uint32 test_base_packet_number) {
447 if (test_base_packet_number != base_packet_number_)
448 return;
449
352 Status status = VerifyPackets(); 450 Status status = VerifyPackets();
353 if (status == SUCCESS) 451 if (status == SUCCESS)
354 Finish(status, net::OK); 452 Finish(status, net::OK);
355 else 453 else
356 Finish(READ_TIMED_OUT, net::ERR_INVALID_ARGUMENT); 454 Finish(READ_TIMED_OUT, net::ERR_INVALID_ARGUMENT);
357 } 455 }
358 456
359 uint32 NetworkStats::GetChecksum(const char* message, uint32 message_length) { 457 uint32 NetworkStats::GetChecksum(const char* message, uint32 message_length) {
360 // Calculate the <checksum> of the <message>. 458 // Calculate the <checksum> of the <message>.
361 uint32 sum = 0; 459 uint32 sum = 0;
(...skipping 26 matching lines...) Expand all
388 uint32 buffer_size = static_cast<uint32>(io_buffer->size()); 486 uint32 buffer_size = static_cast<uint32>(io_buffer->size());
389 487
390 // Copy the <version> into the io_buffer starting from the kVersionStart 488 // Copy the <version> into the io_buffer starting from the kVersionStart
391 // position. 489 // position.
392 std::string version = base::StringPrintf("%02d", kVersionNumber); 490 std::string version = base::StringPrintf("%02d", kVersionNumber);
393 DCHECK(kVersionLength == version.length()); 491 DCHECK(kVersionLength == version.length());
394 DCHECK_GE(buffer_size, kVersionStart + kVersionLength); 492 DCHECK_GE(buffer_size, kVersionStart + kVersionLength);
395 memcpy(buffer + kVersionStart, version.c_str(), kVersionLength); 493 memcpy(buffer + kVersionStart, version.c_str(), kVersionLength);
396 494
397 // Copy the packet_number into the payload. 495 // Copy the packet_number into the payload.
398 std::string packet_number = base::StringPrintf("%010d", g_packet_number_); 496 std::string packet_number = base::StringPrintf("%010d", packet_number_);
399 DCHECK(kPacketNumberLength == packet_number.length()); 497 DCHECK(kPacketNumberLength == packet_number.length());
400 DCHECK_GE(buffer_size, kPayloadStart + kPacketNumberLength); 498 DCHECK_GE(buffer_size, kPayloadStart + kPacketNumberLength);
401 memcpy(buffer + kPayloadStart, packet_number.c_str(), kPacketNumberLength); 499 memcpy(buffer + kPayloadStart, packet_number.c_str(), kPacketNumberLength);
402 500
403 // Get the <payload> from the |stream_| and copy it into io_buffer after 501 // Get the <payload> from the |stream_| and copy it into io_buffer after
404 // packet_number. 502 // packet_number.
405 stream_.Reset(); 503 stream_.Reset();
406 DCHECK_GE(buffer_size, kPayloadStart + load_size_); 504 DCHECK_GE(buffer_size, kPayloadStart + load_size_);
407 stream_.GetBytes(buffer + kPayloadStart + kPacketNumberLength, 505 stream_.GetBytes(buffer + kPayloadStart + kPacketNumberLength,
408 load_size_ - kPacketNumberLength); 506 load_size_ - kPacketNumberLength);
(...skipping 10 matching lines...) Expand all
419 517
420 // Copy the size of the <payload> into the io_buffer starting from the 518 // Copy the size of the <payload> into the io_buffer starting from the
421 // kPayloadSizeStart position. 519 // kPayloadSizeStart position.
422 std::string payload_size = base::StringPrintf("%07d", load_size_); 520 std::string payload_size = base::StringPrintf("%07d", load_size_);
423 DCHECK(kPayloadSizeLength == payload_size.length()); 521 DCHECK(kPayloadSizeLength == payload_size.length());
424 DCHECK_GE(buffer_size, kPayloadSizeStart + kPayloadSizeLength); 522 DCHECK_GE(buffer_size, kPayloadSizeStart + kPayloadSizeLength);
425 memcpy(buffer + kPayloadSizeStart, payload_size.c_str(), kPayloadSizeLength); 523 memcpy(buffer + kPayloadSizeStart, payload_size.c_str(), kPayloadSizeLength);
426 } 524 }
427 525
428 NetworkStats::Status NetworkStats::VerifyPackets() { 526 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; 527 Status status = SUCCESS;
433 for (uint32 i = 0; i < packets_to_send_; i++) { 528 uint32 successful_packets = 0;
434 if (message_length <= packet_start) { 529
435 status = ZERO_LENGTH_ERROR; 530 for (uint32 i = 0; i < packet_status_.size(); i++) {
436 break; 531 if (packets_received_mask_ & (1 << i))
532 ++successful_packets;
533 }
534
535 if (packets_received_ > packets_to_send_)
536 status = TOO_MANY_PACKETS;
537
538 if (packets_to_send_ > successful_packets)
539 status = SOME_PACKETS_NOT_VERIFIED;
540
541 if (current_test_ == START_PACKET_TEST &&
542 packets_to_send_ == kMaximumSequentialPackets &&
543 successful_packets > 1) {
544 base::TimeDelta total_time;
545 if (packet_last_byte_read_time_ > packet_1st_byte_read_time_) {
546 total_time =
547 packet_last_byte_read_time_ - packet_1st_byte_read_time_;
437 } 548 }
438 std::string response = 549 average_time_ = total_time / (successful_packets - 1);
439 encoded_message_.substr(packet_start, receiving_packet_size); 550 std::string load_size_string = base::StringPrintf("%dB", load_size_);
jar (doing other things) 2012/09/05 01:00:55 nit: We only use this on line 556, so we might as
ramant (doing other things) 2012/09/05 04:28:54 Done.
440 Status packet_status = VerifyBytes(response); 551 std::string histogram_name = base::StringPrintf(
441 if (packet_status != SUCCESS) 552 "NetConnectivity3.%s.Sent%02d.%d.%s.PacketDelay",
442 status = packet_status; 553 TestName(),
443 packet_start += receiving_packet_size; 554 kMaximumSequentialPackets,
555 kPorts[histogram_port_],
556 load_size_string.c_str());
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_ != kMaximumSequentialPackets) {
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 if (packets_to_send_ < 2 || protocol != PROTOCOL_UDP)
580 return; 781 return;
581 782
582 // Build "NetConnectivity2.Send6.SeriesAcked.<port>.<load_size>" histogram 783 const char* test_name = TestName();
784
785 // Build "NetConnectivity3.Send6.SeriesAcked.<port>.<load_size>" histogram
583 // name. Total number of histograms are 5*2. 786 // name. Total number of histograms are 5*2.
584 std::string series_acked_histogram_name = base::StringPrintf( 787 std::string series_acked_histogram_name = base::StringPrintf(
585 "NetConnectivity2.Send6.SeriesAcked.%d.%s", 788 "NetConnectivity3.%s.Send6.SeriesAcked.%d.%s",
789 test_name,
586 kPorts[histogram_port_], 790 kPorts[histogram_port_],
587 load_size_string); 791 load_size_string.c_str());
588 // Build "NetConnectivity2.Send6.PacketsSent.<port>.<load_size>" histogram 792 // Build "NetConnectivity3.Send6.PacketsSent.<port>.<load_size>" histogram
589 // name. Total number of histograms are 5*2. 793 // name. Total number of histograms are 5*2.
590 std::string packets_sent_histogram_name = base::StringPrintf( 794 std::string packets_sent_histogram_name = base::StringPrintf(
591 "NetConnectivity2.Send6.PacketsSent.%d.%s", 795 "NetConnectivity3.%s.Send6.PacketsSent.%d.%s",
796 test_name,
592 kPorts[histogram_port_], 797 kPorts[histogram_port_],
593 load_size_string); 798 load_size_string.c_str());
594 799
595 // If we are running without a proxy, we'll generate 2 distinct histograms in 800 // If we are running without a proxy, we'll generate 2 distinct histograms in
596 // each case, one will have the ".NoProxy" suffix. 801 // each case, one will have the ".NoProxy" suffix.
597 size_t histogram_count = has_proxy_server_ ? 1 : 2; 802 size_t histogram_count = has_proxy_server_ ? 1 : 2;
598 for (size_t i = 0; i < histogram_count; i++) { 803 for (size_t i = 0; i < histogram_count; i++) {
599 // For packet loss test, just record packet loss data. 804 // For packet loss test, just record packet loss data.
600 base::Histogram* series_acked_histogram = base::LinearHistogram::FactoryGet( 805 base::Histogram* series_acked_histogram = base::LinearHistogram::FactoryGet(
601 series_acked_histogram_name, 806 series_acked_histogram_name,
602 1, 807 1,
603 2 << kMaximumCorrelationPackets, 808 2 << kMaximumCorrelationPackets,
604 (2 << kMaximumCorrelationPackets) + 1, 809 (2 << kMaximumCorrelationPackets) + 1,
605 base::Histogram::kUmaTargetedHistogramFlag); 810 base::Histogram::kUmaTargetedHistogramFlag);
606 series_acked_histogram->Add(packets_received_mask_); 811 series_acked_histogram->Add(packets_received_mask_);
607 series_acked_histogram_name.append(".NoProxy"); 812 series_acked_histogram_name.append(".NoProxy");
608 813
609 base::Histogram* packets_sent_histogram = 814 base::Histogram* packets_sent_histogram =
610 base::Histogram::FactoryGet( 815 base::Histogram::FactoryGet(
611 packets_sent_histogram_name, 816 packets_sent_histogram_name,
612 1, kMaximumCorrelationPackets, kMaximumCorrelationPackets + 1, 817 1, kMaximumCorrelationPackets, kMaximumCorrelationPackets + 1,
613 base::Histogram::kUmaTargetedHistogramFlag); 818 base::Histogram::kUmaTargetedHistogramFlag);
614 packets_sent_histogram->Add(packets_sent_); 819 packets_sent_histogram->Add(packets_sent_);
615 packets_sent_histogram_name.append(".NoProxy"); 820 packets_sent_histogram_name.append(".NoProxy");
616 } 821 }
617 } 822 }
618 823
619 void NetworkStats::RecordHistograms(const ProtocolValue& protocol, 824 void NetworkStats::RecordRTTHistograms(const ProtocolValue& protocol,
620 const Status& status, 825 const std::string& load_size_string,
621 int result) { 826 uint32 index) {
622 // Build <load_size> string. 827 DCHECK_GE(index, 0u);
623 const char* kSmallLoadString = "100B"; 828 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 829
634 if (packets_to_send_ == kMaximumSequentialPackets) { 830 const char* test_name = TestName();
635 RecordAcksReceivedHistograms(load_size_string); 831 std::string rtt_histogram_name = base::StringPrintf(
636 return; 832 "NetConnectivity3.%s.Sent%02d.Success.RTT.Packet%02d.%d.%s",
637 } 833 test_name,
638 RecordPacketLossSeriesHistograms(protocol, status, load_size_string, result); 834 packets_to_send_,
835 index + 1,
836 kPorts[histogram_port_],
837 load_size_string.c_str());
838 base::Histogram* rtt_histogram = base::Histogram::FactoryTimeGet(
839 rtt_histogram_name,
840 base::TimeDelta::FromMilliseconds(10),
841 base::TimeDelta::FromSeconds(30), 50,
842 base::Histogram::kUmaTargetedHistogramFlag);
843 base::TimeDelta duration =
844 packet_status_[index].end_time_ - packet_status_[index].start_time_;
845 rtt_histogram->AddTime(duration);
639 } 846 }
640 847
641 // UDPStatsClient methods and members. 848 const char* NetworkStats::TestName() {
642 UDPStatsClient::UDPStatsClient() 849 switch (current_test_) {
643 : NetworkStats() { 850 case START_PACKET_TEST:
851 return "StartPacket";
852 case NON_PACED_PACKET_TEST:
853 return "NonPacedPacket";
854 case PACED_PACKET_TEST:
855 return "PacedPacket";
856 default:
857 NOTREACHED();
858 return "None";
859 }
644 } 860 }
645 861
646 UDPStatsClient::~UDPStatsClient() { 862 void NetworkStats::set_socket(net::Socket* socket) {
647 } 863 DCHECK(socket);
648 864 DCHECK(!socket_.get());
649 bool UDPStatsClient::DoConnect(int result) { 865 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 } 866 }
758 867
759 // ProxyDetector methods and members. 868 // ProxyDetector methods and members.
760 ProxyDetector::ProxyDetector(net::ProxyService* proxy_service, 869 ProxyDetector::ProxyDetector(net::ProxyService* proxy_service,
761 const net::HostPortPair& server_address, 870 const net::HostPortPair& server_address,
762 OnResolvedCallback callback) 871 OnResolvedCallback callback)
763 : proxy_service_(proxy_service), 872 : proxy_service_(proxy_service),
764 server_address_(server_address), 873 server_address_(server_address),
765 callback_(callback), 874 callback_(callback),
766 has_pending_proxy_resolution_(false) { 875 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 936 // Check that there is a network connection. We get called only if UMA upload
828 // to the server has succeeded. 937 // to the server has succeeded.
829 DCHECK(!net::NetworkChangeNotifier::IsOffline()); 938 DCHECK(!net::NetworkChangeNotifier::IsOffline());
830 939
831 CR_DEFINE_STATIC_LOCAL(scoped_refptr<base::FieldTrial>, trial, ()); 940 CR_DEFINE_STATIC_LOCAL(scoped_refptr<base::FieldTrial>, trial, ());
832 static bool collect_stats = false; 941 static bool collect_stats = false;
833 static NetworkStats::HistogramPortSelector histogram_port = 942 static NetworkStats::HistogramPortSelector histogram_port =
834 NetworkStats::PORT_6121; 943 NetworkStats::PORT_6121;
835 944
836 if (!trial.get()) { 945 if (!trial.get()) {
837 // Set up a field trial to collect network stats for UDP and TCP. 946 // Set up a field trial to collect network stats for UDP.
838 const base::FieldTrial::Probability kDivisor = 1000; 947 const base::FieldTrial::Probability kDivisor = 1000;
839 948
840 // Enable the connectivity testing for 0.5% of the users in stable channel. 949 // Enable the connectivity testing for 0.5% of the users in stable channel.
841 base::FieldTrial::Probability probability_per_group = 5; 950 base::FieldTrial::Probability probability_per_group = 5;
842 951
843 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 952 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
844 if (channel == chrome::VersionInfo::CHANNEL_CANARY) 953 if (channel == chrome::VersionInfo::CHANNEL_CANARY)
845 probability_per_group = kDivisor; 954 probability_per_group = kDivisor;
846 else if (channel == chrome::VersionInfo::CHANNEL_DEV) 955 else if (channel == chrome::VersionInfo::CHANNEL_DEV)
847 // Enable the connectivity testing for 10% of the users in dev channel. 956 // 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 1004
896 // static 1005 // static
897 void StartNetworkStatsTest(net::HostResolver* host_resolver, 1006 void StartNetworkStatsTest(net::HostResolver* host_resolver,
898 const net::HostPortPair& server_address, 1007 const net::HostPortPair& server_address,
899 NetworkStats::HistogramPortSelector histogram_port, 1008 NetworkStats::HistogramPortSelector histogram_port,
900 bool has_proxy_server) { 1009 bool has_proxy_server) {
901 int experiment_to_run = base::RandInt(1, 4); 1010 int experiment_to_run = base::RandInt(1, 4);
902 switch (experiment_to_run) { 1011 switch (experiment_to_run) {
903 case 1: 1012 case 1:
904 { 1013 {
905 UDPStatsClient* udp_stats_client = new UDPStatsClient(); 1014 NetworkStats* udp_stats_client = new NetworkStats();
906 udp_stats_client->Start( 1015 udp_stats_client->Start(
907 host_resolver, server_address, histogram_port, has_proxy_server, 1016 host_resolver, server_address, histogram_port, has_proxy_server,
908 kSmallTestBytesToSend, kMaximumCorrelationPackets, 1017 kLargeTestBytesToSend, kMaximumCorrelationPackets,
909 net::CompletionCallback()); 1018 net::CompletionCallback());
910 } 1019 }
911 break; 1020 break;
912 case 2: 1021 case 2:
913 { 1022 {
914 UDPStatsClient* udp_stats_client = new UDPStatsClient(); 1023 NetworkStats* udp_stats_client = new NetworkStats();
915 udp_stats_client->Start( 1024 udp_stats_client->Start(
916 host_resolver, server_address, histogram_port, has_proxy_server, 1025 host_resolver, server_address, histogram_port, has_proxy_server,
917 kSmallTestBytesToSend, kMaximumSequentialPackets, 1026 kSmallTestBytesToSend, kMaximumSequentialPackets,
918 net::CompletionCallback()); 1027 net::CompletionCallback());
919 } 1028 }
920 break; 1029 break;
921 case 3: 1030 case 3:
922 { 1031 {
923 UDPStatsClient* udp_stats_client = new UDPStatsClient(); 1032 NetworkStats* udp_stats_client = new NetworkStats();
924 udp_stats_client->Start( 1033 udp_stats_client->Start(
925 host_resolver, server_address, histogram_port, has_proxy_server, 1034 host_resolver, server_address, histogram_port, has_proxy_server,
926 kMediumTestBytesToSend, kMaximumSequentialPackets, 1035 kMediumTestBytesToSend, kMaximumSequentialPackets,
927 net::CompletionCallback()); 1036 net::CompletionCallback());
928 } 1037 }
929 break; 1038 break;
930 case 4: 1039 case 4:
931 { 1040 {
932 UDPStatsClient* udp_stats_client = new UDPStatsClient(); 1041 NetworkStats* udp_stats_client = new NetworkStats();
933 udp_stats_client->Start( 1042 udp_stats_client->Start(
934 host_resolver, server_address, histogram_port, has_proxy_server, 1043 host_resolver, server_address, histogram_port, has_proxy_server,
935 kLargeTestBytesToSend, kMaximumSequentialPackets, 1044 kLargeTestBytesToSend, kMaximumSequentialPackets,
936 net::CompletionCallback()); 1045 net::CompletionCallback());
937 } 1046 }
938 break; 1047 break;
939 } 1048 }
940 } 1049 }
941 1050
942 } // namespace chrome_browser_net 1051 } // 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