OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/callback_old.h" | 7 #include "base/callback_old.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/task.h" | 12 #include "base/task.h" |
13 #include "base/threading/platform_thread.h" | 13 #include "base/threading/platform_thread.h" |
14 #include "base/time.h" | 14 #include "base/time.h" |
15 #include "base/tuple.h" | 15 #include "base/tuple.h" |
16 #include "content/browser/browser_thread.h" | 16 #include "content/browser/browser_thread.h" |
17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
18 #include "net/base/net_util.h" | 18 #include "net/base/net_util.h" |
19 #include "net/base/network_change_notifier.h" | 19 #include "net/base/network_change_notifier.h" |
20 #include "net/base/sys_addrinfo.h" | 20 #include "net/base/sys_addrinfo.h" |
21 #include "net/base/test_completion_callback.h" | 21 #include "net/base/test_completion_callback.h" |
22 #include "net/socket/tcp_client_socket.h" | 22 #include "net/socket/tcp_client_socket.h" |
23 #include "net/udp/udp_client_socket.h" | 23 #include "net/udp/udp_client_socket.h" |
24 #include "net/udp/udp_server_socket.h" | 24 #include "net/udp/udp_server_socket.h" |
25 | 25 |
26 namespace chrome_browser_net { | 26 namespace chrome_browser_net { |
27 | 27 |
28 // This specifies the number of bytes to be sent to the TCP/UDP servers as part | 28 // This specifies the number of bytes to be sent to the TCP/UDP servers as part |
29 // of small packet size test. | 29 // of small packet size test. |
30 static const int kSmallTestBytesToSend = 100; | 30 static const uint32 kSmallTestBytesToSend = 100; |
31 | 31 |
32 // 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 TCP/UDP servers as part |
33 // of large packet size test. | 33 // of large packet size test. |
34 static const int kLargeTestBytesToSend = 1200; | 34 static const uint32 kLargeTestBytesToSend = 1200; |
| 35 |
| 36 // This specifies the maximum message (payload) size. |
| 37 static const uint32 kMaxMessage = 2048; |
| 38 |
| 39 // This specifies starting position of the <version> and length of the |
| 40 // <version> in "echo request" and "echo response". |
| 41 static const uint32 kVersionNumber = 1; |
| 42 static const uint32 kVersionStart = 0; |
| 43 static const uint32 kVersionLength = 2; |
| 44 static const uint32 kVersionEnd = kVersionStart + kVersionLength; |
| 45 |
| 46 // This specifies the starting position of the <checksum> and length of the |
| 47 // <checksum> in "echo request" and "echo response". Maximum value for the |
| 48 // <checksum> is less than (2 ** 31 - 1). |
| 49 static const uint32 kChecksumStart = kVersionEnd; |
| 50 static const uint32 kChecksumLength = 10; |
| 51 static const uint32 kChecksumEnd = kChecksumStart + kChecksumLength; |
| 52 |
| 53 // This specifies the starting position of the <payload_size> and length of the |
| 54 // <payload_size> in "echo request" and "echo response". Maximum number of bytes |
| 55 // that can be sent in the <payload> is 9,999,999. |
| 56 static const uint32 kPayloadSizeStart = kChecksumEnd; |
| 57 static const uint32 kPayloadSizeLength = 7; |
| 58 static const uint32 kPayloadSizeEnd = kPayloadSizeStart + kPayloadSizeLength; |
| 59 |
| 60 // This specifies the starting position of the <key> and length of the <key> in |
| 61 // "echo response". |
| 62 static const uint32 kKeyStart = kPayloadSizeEnd; |
| 63 static const uint32 kKeyLength = 6; |
| 64 static const uint32 kKeyEnd = kKeyStart + kKeyLength; |
| 65 static const int32 kKeyMinValue = 0; |
| 66 static const int32 kKeyMaxValue = 999999; |
| 67 |
| 68 // This specifies the starting position of the <payload> in "echo request". |
| 69 static const uint32 kPayloadStart = kPayloadSizeEnd; |
| 70 |
| 71 // This specifies the starting position of the <encoded_payload> and length of |
| 72 // the <encoded_payload> in "echo response". |
| 73 static const uint32 kEncodedPayloadStart = kKeyEnd; |
35 | 74 |
36 // NetworkStats methods and members. | 75 // NetworkStats methods and members. |
37 NetworkStats::NetworkStats() | 76 NetworkStats::NetworkStats() |
38 : bytes_to_read_(0), | 77 : load_size_(0), |
| 78 bytes_to_read_(0), |
39 bytes_to_send_(0), | 79 bytes_to_send_(0), |
| 80 encoded_message_(""), |
40 ALLOW_THIS_IN_INITIALIZER_LIST( | 81 ALLOW_THIS_IN_INITIALIZER_LIST( |
41 read_callback_(this, &NetworkStats::OnReadComplete)), | 82 read_callback_(this, &NetworkStats::OnReadComplete)), |
42 ALLOW_THIS_IN_INITIALIZER_LIST( | 83 ALLOW_THIS_IN_INITIALIZER_LIST( |
43 write_callback_(this, &NetworkStats::OnWriteComplete)), | 84 write_callback_(this, &NetworkStats::OnWriteComplete)), |
44 finished_callback_(NULL), | 85 finished_callback_(NULL), |
45 start_time_(base::TimeTicks::Now()) { | 86 start_time_(base::TimeTicks::Now()), |
| 87 ALLOW_THIS_IN_INITIALIZER_LIST(timers_factory_(this)) { |
46 } | 88 } |
47 | 89 |
48 NetworkStats::~NetworkStats() { | 90 NetworkStats::~NetworkStats() { |
49 socket_.reset(); | 91 socket_.reset(); |
50 } | 92 } |
51 | 93 |
52 void NetworkStats::Initialize(int bytes_to_send, | 94 void NetworkStats::Initialize(uint32 bytes_to_send, |
53 net::CompletionCallback* finished_callback) { | 95 net::CompletionCallback* finished_callback) { |
54 DCHECK(bytes_to_send); // We should have data to send. | 96 DCHECK(bytes_to_send); // We should have data to send. |
55 | 97 |
56 load_size_ = bytes_to_send; | 98 load_size_ = bytes_to_send; |
57 bytes_to_send_ = bytes_to_send; | 99 bytes_to_send_ = kVersionLength + kChecksumLength + kPayloadSizeLength + |
58 bytes_to_read_ = bytes_to_send; | 100 load_size_; |
| 101 bytes_to_read_ = kVersionLength + kChecksumLength + kPayloadSizeLength + |
| 102 kKeyLength + load_size_; |
59 finished_callback_ = finished_callback; | 103 finished_callback_ = finished_callback; |
60 } | 104 } |
61 | 105 |
62 bool NetworkStats::DoStart(int result) { | 106 bool NetworkStats::DoStart(int result) { |
63 if (result < 0) { | 107 if (result < 0) { |
64 Finish(CONNECT_FAILED, result); | 108 Finish(CONNECT_FAILED, result); |
65 return false; | 109 return false; |
66 } | 110 } |
67 | 111 |
68 DCHECK(bytes_to_send_); // We should have data to send. | 112 DCHECK(bytes_to_send_); // We should have data to send. |
69 | 113 |
70 start_time_ = base::TimeTicks::Now(); | 114 start_time_ = base::TimeTicks::Now(); |
71 | 115 |
72 int rv = SendData(); | 116 int rv = SendData(); |
73 if (rv < 0) { | 117 if (rv < 0) { |
74 if (rv != net::ERR_IO_PENDING) { | 118 if (rv != net::ERR_IO_PENDING) { |
75 Finish(WRITE_FAILED, rv); | 119 Finish(WRITE_FAILED, rv); |
76 return false; | 120 return false; |
77 } | 121 } |
78 } | 122 } |
79 | 123 |
80 stream_.Reset(); | 124 stream_.Reset(); |
| 125 |
| 126 // Timeout if we don't get response back from echo servers in 60 secs. |
| 127 const int kReadDataTimeoutMs = 60000; |
| 128 StartReadDataTimer(kReadDataTimeoutMs); |
| 129 |
81 ReadData(); | 130 ReadData(); |
82 | 131 |
83 return true; | 132 return true; |
84 } | 133 } |
85 | 134 |
86 void NetworkStats::DoFinishCallback(int result) { | 135 void NetworkStats::DoFinishCallback(int result) { |
87 if (finished_callback_ != NULL) { | 136 if (finished_callback_ != NULL) { |
88 net::CompletionCallback* callback = finished_callback_; | 137 net::CompletionCallback* callback = finished_callback_; |
89 finished_callback_ = NULL; | 138 finished_callback_ = NULL; |
90 callback->Run(result); | 139 callback->Run(result); |
91 } | 140 } |
92 } | 141 } |
93 | 142 |
94 void NetworkStats::set_socket(net::Socket* socket) { | 143 void NetworkStats::set_socket(net::Socket* socket) { |
95 DCHECK(socket); | 144 DCHECK(socket); |
96 DCHECK(!socket_.get()); | 145 DCHECK(!socket_.get()); |
97 socket_.reset(socket); | 146 socket_.reset(socket); |
98 } | 147 } |
99 | 148 |
100 bool NetworkStats::ReadComplete(int result) { | 149 bool NetworkStats::ReadComplete(int result) { |
101 DCHECK(socket_.get()); | 150 DCHECK(socket_.get()); |
102 DCHECK_NE(net::ERR_IO_PENDING, result); | 151 DCHECK_NE(net::ERR_IO_PENDING, result); |
103 if (result < 0) { | 152 if (result < 0) { |
104 Finish(READ_FAILED, result); | 153 Finish(READ_FAILED, result); |
105 return true; | 154 return true; |
106 } | 155 } |
107 | 156 |
108 if (!stream_.VerifyBytes(read_buffer_->data(), result)) { | 157 encoded_message_.append(read_buffer_->data(), result); |
109 Finish(READ_VERIFY_FAILED, net::ERR_INVALID_RESPONSE); | |
110 return true; | |
111 } | |
112 | 158 |
113 read_buffer_ = NULL; | 159 read_buffer_ = NULL; |
114 bytes_to_read_ -= result; | 160 bytes_to_read_ -= result; |
115 | 161 |
116 // No more data to read. | 162 // No more data to read. |
117 if (!bytes_to_read_) { | 163 if (!bytes_to_read_ || result == 0) { |
118 Finish(SUCCESS, net::OK); | 164 if (VerifyBytes()) |
| 165 Finish(SUCCESS, net::OK); |
| 166 else |
| 167 Finish(READ_VERIFY_FAILED, net::ERR_INVALID_RESPONSE); |
119 return true; | 168 return true; |
120 } | 169 } |
121 ReadData(); | |
122 return false; | 170 return false; |
123 } | 171 } |
124 | 172 |
125 void NetworkStats::OnReadComplete(int result) { | 173 void NetworkStats::OnReadComplete(int result) { |
126 ReadComplete(result); | 174 if (!ReadComplete(result)) { |
| 175 // Called ReadData() via PostDelayedTask() to avoid recursion. Added a delay |
| 176 // of 1ms so that the time-out will fire before we have time to really hog |
| 177 // the CPU too extensively (waiting for the time-out) in case of an infinite |
| 178 // loop. |
| 179 const int kReadDataDelayMs = 1; |
| 180 MessageLoop::current()->PostDelayedTask( |
| 181 FROM_HERE, |
| 182 timers_factory_.NewRunnableMethod(&NetworkStats::ReadData), |
| 183 kReadDataDelayMs); |
| 184 } |
127 } | 185 } |
128 | 186 |
129 void NetworkStats::OnWriteComplete(int result) { | 187 void NetworkStats::OnWriteComplete(int result) { |
130 DCHECK(socket_.get()); | 188 DCHECK(socket_.get()); |
131 DCHECK_NE(net::ERR_IO_PENDING, result); | 189 DCHECK_NE(net::ERR_IO_PENDING, result); |
132 if (result < 0) { | 190 if (result < 0) { |
133 Finish(WRITE_FAILED, result); | 191 Finish(WRITE_FAILED, result); |
134 return; | 192 return; |
135 } | 193 } |
136 | 194 |
137 write_buffer_->DidConsume(result); | 195 write_buffer_->DidConsume(result); |
138 bytes_to_send_ -= result; | 196 bytes_to_send_ -= result; |
139 if (!write_buffer_->BytesRemaining()) | 197 if (!write_buffer_->BytesRemaining()) |
140 write_buffer_ = NULL; | 198 write_buffer_ = NULL; |
141 | 199 |
142 if (bytes_to_send_) { | 200 if (bytes_to_send_) { |
143 int rv = SendData(); | 201 int rv = SendData(); |
144 if (rv < 0) { | 202 if (rv < 0) { |
145 if (rv != net::ERR_IO_PENDING) { | 203 if (rv != net::ERR_IO_PENDING) { |
146 Finish(WRITE_FAILED, rv); | 204 Finish(WRITE_FAILED, rv); |
147 return; | 205 return; |
148 } | 206 } |
149 } | 207 } |
150 } | 208 } |
151 } | 209 } |
152 | 210 |
153 void NetworkStats::ReadData() { | 211 void NetworkStats::ReadData() { |
154 DCHECK(!read_buffer_.get()); | |
155 int kMaxMessage = 2048; | |
156 | |
157 // We release the read_buffer_ in the destructor if there is an error. | |
158 read_buffer_ = new net::IOBuffer(kMaxMessage); | |
159 | |
160 int rv; | 212 int rv; |
161 do { | 213 do { |
162 DCHECK(socket_.get()); | 214 if (!socket_.get()) |
| 215 return; |
| 216 |
| 217 DCHECK(!read_buffer_.get()); |
| 218 |
| 219 // We release the read_buffer_ in the destructor if there is an error. |
| 220 read_buffer_ = new net::IOBuffer(kMaxMessage); |
| 221 |
163 rv = socket_->Read(read_buffer_, kMaxMessage, &read_callback_); | 222 rv = socket_->Read(read_buffer_, kMaxMessage, &read_callback_); |
164 if (rv == net::ERR_IO_PENDING) | 223 if (rv == net::ERR_IO_PENDING) |
165 return; | 224 return; |
166 if (ReadComplete(rv)) // Complete the read manually. | 225 // If we have read all the data then return. |
| 226 if (ReadComplete(rv)) |
167 return; | 227 return; |
168 } while (rv > 0); | 228 } while (rv > 0); |
169 } | 229 } |
170 | 230 |
171 int NetworkStats::SendData() { | 231 int NetworkStats::SendData() { |
172 DCHECK(bytes_to_send_); // We should have data to send. | 232 DCHECK(bytes_to_send_); // We should have data to send. |
173 do { | 233 do { |
174 if (!write_buffer_.get()) { | 234 if (!write_buffer_.get()) { |
175 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(bytes_to_send_)); | 235 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(bytes_to_send_)); |
176 stream_.GetBytes(buffer->data(), bytes_to_send_); | 236 GetEchoRequest(buffer); |
177 write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_); | 237 write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_); |
178 } | 238 } |
179 | 239 |
180 DCHECK(socket_.get()); | 240 if (!socket_.get()) |
| 241 return net::ERR_UNEXPECTED; |
181 int rv = socket_->Write(write_buffer_, | 242 int rv = socket_->Write(write_buffer_, |
182 write_buffer_->BytesRemaining(), | 243 write_buffer_->BytesRemaining(), |
183 &write_callback_); | 244 &write_callback_); |
184 if (rv < 0) | 245 if (rv < 0) |
185 return rv; | 246 return rv; |
186 write_buffer_->DidConsume(rv); | 247 write_buffer_->DidConsume(rv); |
187 bytes_to_send_ -= rv; | 248 bytes_to_send_ -= rv; |
188 if (!write_buffer_->BytesRemaining()) | 249 if (!write_buffer_->BytesRemaining()) |
189 write_buffer_ = NULL; | 250 write_buffer_ = NULL; |
190 } while (bytes_to_send_); | 251 } while (bytes_to_send_); |
191 return net::OK; | 252 return net::OK; |
192 } | 253 } |
193 | 254 |
| 255 void NetworkStats::StartReadDataTimer(int milliseconds) { |
| 256 MessageLoop::current()->PostDelayedTask( |
| 257 FROM_HERE, |
| 258 timers_factory_.NewRunnableMethod(&NetworkStats::OnReadDataTimeout), |
| 259 milliseconds); |
| 260 } |
| 261 |
| 262 void NetworkStats::OnReadDataTimeout() { |
| 263 Finish(READ_TIMED_OUT, net::ERR_INVALID_ARGUMENT); |
| 264 } |
| 265 |
| 266 void NetworkStats::GetEchoRequest(net::IOBuffer* io_buffer) { |
| 267 // Copy the <version> into the io_buffer starting from the kVersionStart |
| 268 // position. |
| 269 std::string version = base::StringPrintf("%02d", kVersionNumber); |
| 270 char* buffer = io_buffer->data() + kVersionStart; |
| 271 DCHECK(kVersionLength == version.length()); |
| 272 memcpy(buffer, version.c_str(), kVersionLength); |
| 273 |
| 274 // Get the <payload> from the |stream_| and copy it into io_buffer starting |
| 275 // from the kPayloadStart position. |
| 276 buffer = io_buffer->data() + kPayloadStart; |
| 277 stream_.GetBytes(buffer, load_size_); |
| 278 |
| 279 // Calculate the <checksum> of the <payload>. |
| 280 uint32 sum = 0; |
| 281 for (uint32 i = 0; i < load_size_; ++i) |
| 282 sum += buffer[i]; |
| 283 |
| 284 // Copy the <checksum> into the io_buffer starting from the kChecksumStart |
| 285 // position. |
| 286 std::string checksum = base::StringPrintf("%010d", sum); |
| 287 buffer = io_buffer->data() + kChecksumStart; |
| 288 DCHECK(kChecksumLength == checksum.length()); |
| 289 memcpy(buffer, checksum.c_str(), kChecksumLength); |
| 290 |
| 291 // Copy the size of the <payload> into the io_buffer starting from the |
| 292 // kPayloadSizeStart position. |
| 293 buffer = io_buffer->data() + kPayloadSizeStart; |
| 294 std::string payload_size = base::StringPrintf("%07d", load_size_); |
| 295 DCHECK(kPayloadSizeLength == payload_size.length()); |
| 296 memcpy(buffer, payload_size.c_str(), kPayloadSizeLength); |
| 297 } |
| 298 |
| 299 bool NetworkStats::VerifyBytes() { |
| 300 // If the "echo response" doesn't have enough bytes, then return false. |
| 301 if (encoded_message_.length() < kEncodedPayloadStart) |
| 302 return false; |
| 303 |
| 304 // Extract the |key| from the "echo response". |
| 305 std::string key_string = encoded_message_.substr(kKeyStart, kKeyLength); |
| 306 const char* key = key_string.c_str(); |
| 307 int key_value = atoi(key); |
| 308 if (key_value < kKeyMinValue || key_value > kKeyMaxValue) |
| 309 return false; |
| 310 |
| 311 std::string encoded_payload = |
| 312 encoded_message_.substr(kEncodedPayloadStart); |
| 313 const char* encoded_data = encoded_payload.c_str(); |
| 314 uint32 message_length = encoded_payload.length(); |
| 315 message_length = std::min(message_length, kMaxMessage); |
| 316 // We should get back all the data we had sent. |
| 317 if (message_length != load_size_) |
| 318 return false; |
| 319 |
| 320 // Decrypt the data by looping through the |encoded_data| and XOR each byte |
| 321 // with the |key| to get the decoded byte. Append the decoded byte to the |
| 322 // |decoded_data|. |
| 323 char decoded_data[kMaxMessage + 1]; |
| 324 for (uint32 data_index = 0, key_index = 0; |
| 325 data_index < message_length; |
| 326 ++data_index) { |
| 327 char encoded_byte = encoded_data[data_index]; |
| 328 char key_byte = key[key_index]; |
| 329 char decoded_byte = encoded_byte ^ key_byte; |
| 330 decoded_data[data_index] = decoded_byte; |
| 331 key_index = (key_index + 1) % kKeyLength; |
| 332 } |
| 333 |
| 334 return stream_.VerifyBytes(decoded_data, message_length); |
| 335 } |
| 336 |
194 // UDPStatsClient methods and members. | 337 // UDPStatsClient methods and members. |
195 UDPStatsClient::UDPStatsClient() | 338 UDPStatsClient::UDPStatsClient() |
196 : NetworkStats() { | 339 : NetworkStats() { |
197 } | 340 } |
198 | 341 |
199 UDPStatsClient::~UDPStatsClient() { | 342 UDPStatsClient::~UDPStatsClient() { |
200 } | 343 } |
201 | 344 |
202 bool UDPStatsClient::Start(const std::string& ip_str, | 345 bool UDPStatsClient::Start(const std::string& ip_str, |
203 int port, | 346 int port, |
204 int bytes_to_send, | 347 uint32 bytes_to_send, |
205 net::CompletionCallback* finished_callback) { | 348 net::CompletionCallback* finished_callback) { |
206 DCHECK(port); | 349 DCHECK(port); |
207 DCHECK(bytes_to_send); // We should have data to send. | 350 DCHECK(bytes_to_send); // We should have data to send. |
208 | 351 |
209 Initialize(bytes_to_send, finished_callback); | 352 Initialize(bytes_to_send, finished_callback); |
210 | 353 |
211 net::IPAddressNumber ip_number; | 354 net::IPAddressNumber ip_number; |
212 if (!net::ParseIPLiteralToNumber(ip_str, &ip_number)) { | 355 if (!net::ParseIPLiteralToNumber(ip_str, &ip_number)) { |
213 Finish(IP_STRING_PARSE_FAILED, net::ERR_INVALID_ARGUMENT); | 356 Finish(IP_STRING_PARSE_FAILED, net::ERR_INVALID_ARGUMENT); |
214 return false; | 357 return false; |
215 } | 358 } |
216 net::IPEndPoint server_address = net::IPEndPoint(ip_number, port); | 359 net::IPEndPoint server_address = net::IPEndPoint(ip_number, port); |
217 | 360 |
218 net::UDPClientSocket* udp_socket = | 361 net::UDPClientSocket* udp_socket = |
219 new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND, | 362 new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND, |
220 net::RandIntCallback(), | 363 net::RandIntCallback(), |
221 NULL, | 364 NULL, |
222 net::NetLog::Source()); | 365 net::NetLog::Source()); |
223 DCHECK(udp_socket); | 366 if (!udp_socket) { |
| 367 Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT); |
| 368 return false; |
| 369 } |
224 set_socket(udp_socket); | 370 set_socket(udp_socket); |
225 | 371 |
226 int rv = udp_socket->Connect(server_address); | 372 int rv = udp_socket->Connect(server_address); |
227 return DoStart(rv); | 373 return DoStart(rv); |
228 } | 374 } |
229 | 375 |
| 376 bool UDPStatsClient::ReadComplete(int result) { |
| 377 DCHECK_NE(net::ERR_IO_PENDING, result); |
| 378 if (result <= 0) { |
| 379 Finish(READ_FAILED, result); |
| 380 return true; |
| 381 } |
| 382 return NetworkStats::ReadComplete(result); |
| 383 } |
| 384 |
230 void UDPStatsClient::Finish(Status status, int result) { | 385 void UDPStatsClient::Finish(Status status, int result) { |
231 base::TimeDelta duration = base::TimeTicks::Now() - start_time(); | 386 base::TimeDelta duration = base::TimeTicks::Now() - start_time(); |
232 if (load_size() == kSmallTestBytesToSend) { | 387 if (load_size() == kSmallTestBytesToSend) { |
233 if (result == net::OK) | 388 if (result == net::OK) |
234 UMA_HISTOGRAM_TIMES("NetConnectivity.UDP.Success.100B.RTT", duration); | 389 UMA_HISTOGRAM_TIMES("NetConnectivity.UDP.Success.100B.RTT", duration); |
235 else | 390 else |
236 UMA_HISTOGRAM_TIMES("NetConnectivity.UDP.Fail.100B.RTT", duration); | 391 UMA_HISTOGRAM_TIMES("NetConnectivity.UDP.Fail.100B.RTT", duration); |
237 | 392 |
238 UMA_HISTOGRAM_ENUMERATION( | 393 UMA_HISTOGRAM_ENUMERATION( |
239 "NetConnectivity.UDP.Status.100B", status, STATUS_MAX); | 394 "NetConnectivity.UDP.Status.100B", status, STATUS_MAX); |
(...skipping 25 matching lines...) Expand all Loading... |
265 resolve_callback_(this, &TCPStatsClient::OnResolveComplete)), | 420 resolve_callback_(this, &TCPStatsClient::OnResolveComplete)), |
266 ALLOW_THIS_IN_INITIALIZER_LIST( | 421 ALLOW_THIS_IN_INITIALIZER_LIST( |
267 connect_callback_(this, &TCPStatsClient::OnConnectComplete)) { | 422 connect_callback_(this, &TCPStatsClient::OnConnectComplete)) { |
268 } | 423 } |
269 | 424 |
270 TCPStatsClient::~TCPStatsClient() { | 425 TCPStatsClient::~TCPStatsClient() { |
271 } | 426 } |
272 | 427 |
273 bool TCPStatsClient::Start(net::HostResolver* host_resolver, | 428 bool TCPStatsClient::Start(net::HostResolver* host_resolver, |
274 const net::HostPortPair& server_host_port_pair, | 429 const net::HostPortPair& server_host_port_pair, |
275 int bytes_to_send, | 430 uint32 bytes_to_send, |
276 net::CompletionCallback* finished_callback) { | 431 net::CompletionCallback* finished_callback) { |
277 DCHECK(bytes_to_send); // We should have data to send. | 432 DCHECK(bytes_to_send); // We should have data to send. |
278 | 433 |
279 Initialize(bytes_to_send, finished_callback); | 434 Initialize(bytes_to_send, finished_callback); |
280 | 435 |
281 net::HostResolver::RequestInfo request(server_host_port_pair); | 436 net::HostResolver::RequestInfo request(server_host_port_pair); |
282 int rv = host_resolver->Resolve(request, | 437 int rv = host_resolver->Resolve(request, |
283 &addresses_, | 438 &addresses_, |
284 &resolve_callback_, | 439 &resolve_callback_, |
285 NULL, | 440 NULL, |
286 net::BoundNetLog()); | 441 net::BoundNetLog()); |
287 if (rv == net::ERR_IO_PENDING) | 442 if (rv == net::ERR_IO_PENDING) |
288 return true; | 443 return true; |
289 return DoConnect(rv); | 444 return DoConnect(rv); |
290 } | 445 } |
291 | 446 |
292 void TCPStatsClient::OnResolveComplete(int result) { | 447 void TCPStatsClient::OnResolveComplete(int result) { |
293 DoConnect(result); | 448 DoConnect(result); |
294 } | 449 } |
295 | 450 |
296 bool TCPStatsClient::DoConnect(int result) { | 451 bool TCPStatsClient::DoConnect(int result) { |
297 if (result != net::OK) { | 452 if (result != net::OK) { |
298 Finish(RESOLVE_FAILED, result); | 453 Finish(RESOLVE_FAILED, result); |
299 return false; | 454 return false; |
300 } | 455 } |
301 | 456 |
302 net::TCPClientSocket* tcp_socket = | 457 net::TCPClientSocket* tcp_socket = |
303 new net::TCPClientSocket(addresses_, NULL, net::NetLog::Source()); | 458 new net::TCPClientSocket(addresses_, NULL, net::NetLog::Source()); |
304 DCHECK(tcp_socket); | 459 if (!tcp_socket) { |
| 460 Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT); |
| 461 return false; |
| 462 } |
305 set_socket(tcp_socket); | 463 set_socket(tcp_socket); |
306 | 464 |
307 int rv = tcp_socket->Connect(&connect_callback_); | 465 int rv = tcp_socket->Connect(&connect_callback_); |
308 if (rv == net::ERR_IO_PENDING) | 466 if (rv == net::ERR_IO_PENDING) |
309 return true; | 467 return true; |
310 | 468 |
311 return DoStart(rv); | 469 return DoStart(rv); |
312 } | 470 } |
313 | 471 |
314 void TCPStatsClient::OnConnectComplete(int result) { | 472 void TCPStatsClient::OnConnectComplete(int result) { |
315 DoStart(result); | 473 DoStart(result); |
316 } | 474 } |
317 | 475 |
| 476 bool TCPStatsClient::ReadComplete(int result) { |
| 477 DCHECK_NE(net::ERR_IO_PENDING, result); |
| 478 if (result < 0) { |
| 479 Finish(READ_FAILED, result); |
| 480 return true; |
| 481 } |
| 482 return NetworkStats::ReadComplete(result); |
| 483 } |
| 484 |
318 void TCPStatsClient::Finish(Status status, int result) { | 485 void TCPStatsClient::Finish(Status status, int result) { |
319 base::TimeDelta duration = base::TimeTicks::Now() - start_time(); | 486 base::TimeDelta duration = base::TimeTicks::Now() - start_time(); |
320 if (load_size() == kSmallTestBytesToSend) { | 487 if (load_size() == kSmallTestBytesToSend) { |
321 if (result == net::OK) | 488 if (result == net::OK) |
322 UMA_HISTOGRAM_TIMES("NetConnectivity.TCP.Success.100B.RTT", duration); | 489 UMA_HISTOGRAM_TIMES("NetConnectivity.TCP.Success.100B.RTT", duration); |
323 else | 490 else |
324 UMA_HISTOGRAM_TIMES("NetConnectivity.TCP.Fail.100B.RTT", duration); | 491 UMA_HISTOGRAM_TIMES("NetConnectivity.TCP.Fail.100B.RTT", duration); |
325 | 492 |
326 UMA_HISTOGRAM_ENUMERATION( | 493 UMA_HISTOGRAM_ENUMERATION( |
327 "NetConnectivity.TCP.Status.100B", status, STATUS_MAX); | 494 "NetConnectivity.TCP.Status.100B", status, STATUS_MAX); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 TCPStatsClient* small_tcp_client = new TCPStatsClient(); | 591 TCPStatsClient* small_tcp_client = new TCPStatsClient(); |
425 small_tcp_client->Start(host_resolver, server_address, kSmallTestBytesToSend, | 592 small_tcp_client->Start(host_resolver, server_address, kSmallTestBytesToSend, |
426 NULL); | 593 NULL); |
427 | 594 |
428 TCPStatsClient* large_tcp_client = new TCPStatsClient(); | 595 TCPStatsClient* large_tcp_client = new TCPStatsClient(); |
429 large_tcp_client->Start(host_resolver, server_address, kLargeTestBytesToSend, | 596 large_tcp_client->Start(host_resolver, server_address, kLargeTestBytesToSend, |
430 NULL); | 597 NULL); |
431 } | 598 } |
432 | 599 |
433 } // namespace chrome_browser_net | 600 } // namespace chrome_browser_net |
OLD | NEW |