| 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 |