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_ = |
58 bytes_to_read_ = bytes_to_send; | 100 kVersionLength + kChecksumLength + kPayloadSizeLength + load_size_; |
101 bytes_to_read_ = | |
102 kVersionLength + kChecksumLength + kPayloadSizeLength + kKeyLength + | |
jar (doing other things)
2011/08/15 19:33:50
style nit: (personal?): suggest not wrapping until
ramant (doing other things)
2011/08/16 00:00:03
Done.
| |
103 load_size_; | |
59 finished_callback_ = finished_callback; | 104 finished_callback_ = finished_callback; |
60 } | 105 } |
61 | 106 |
62 bool NetworkStats::DoStart(int result) { | 107 bool NetworkStats::DoStart(int result) { |
63 if (result < 0) { | 108 if (result < 0) { |
64 Finish(CONNECT_FAILED, result); | 109 Finish(CONNECT_FAILED, result); |
65 return false; | 110 return false; |
66 } | 111 } |
67 | 112 |
68 DCHECK(bytes_to_send_); // We should have data to send. | 113 DCHECK(bytes_to_send_); // We should have data to send. |
69 | 114 |
70 start_time_ = base::TimeTicks::Now(); | 115 start_time_ = base::TimeTicks::Now(); |
71 | 116 |
72 int rv = SendData(); | 117 int rv = SendData(); |
73 if (rv < 0) { | 118 if (rv < 0) { |
74 if (rv != net::ERR_IO_PENDING) { | 119 if (rv != net::ERR_IO_PENDING) { |
75 Finish(WRITE_FAILED, rv); | 120 Finish(WRITE_FAILED, rv); |
76 return false; | 121 return false; |
77 } | 122 } |
78 } | 123 } |
79 | 124 |
80 stream_.Reset(); | 125 stream_.Reset(); |
126 | |
127 // Timeout if we don't get response back from echo servers in 60 secs. | |
128 const int kReadDataTimeoutMs = 60000; | |
129 StartReadDataTimer(kReadDataTimeoutMs); | |
130 | |
81 ReadData(); | 131 ReadData(); |
82 | 132 |
83 return true; | 133 return true; |
84 } | 134 } |
85 | 135 |
86 void NetworkStats::DoFinishCallback(int result) { | 136 void NetworkStats::DoFinishCallback(int result) { |
87 if (finished_callback_ != NULL) { | 137 if (finished_callback_ != NULL) { |
88 net::CompletionCallback* callback = finished_callback_; | 138 net::CompletionCallback* callback = finished_callback_; |
89 finished_callback_ = NULL; | 139 finished_callback_ = NULL; |
90 callback->Run(result); | 140 callback->Run(result); |
91 } | 141 } |
92 } | 142 } |
93 | 143 |
94 void NetworkStats::set_socket(net::Socket* socket) { | 144 void NetworkStats::set_socket(net::Socket* socket) { |
95 DCHECK(socket); | 145 DCHECK(socket); |
96 DCHECK(!socket_.get()); | 146 DCHECK(!socket_.get()); |
97 socket_.reset(socket); | 147 socket_.reset(socket); |
98 } | 148 } |
99 | 149 |
100 bool NetworkStats::ReadComplete(int result) { | 150 bool NetworkStats::ReadComplete(int result) { |
101 DCHECK(socket_.get()); | 151 DCHECK(socket_.get()); |
102 DCHECK_NE(net::ERR_IO_PENDING, result); | 152 DCHECK_NE(net::ERR_IO_PENDING, result); |
103 if (result < 0) { | 153 if (result < 0) { |
104 Finish(READ_FAILED, result); | 154 Finish(READ_FAILED, result); |
105 return true; | 155 return true; |
106 } | 156 } |
107 | 157 |
108 if (!stream_.VerifyBytes(read_buffer_->data(), result)) { | 158 encoded_message_.append(read_buffer_->data(), result); |
109 Finish(READ_VERIFY_FAILED, net::ERR_INVALID_RESPONSE); | |
110 return true; | |
111 } | |
112 | 159 |
113 read_buffer_ = NULL; | 160 read_buffer_ = NULL; |
114 bytes_to_read_ -= result; | 161 bytes_to_read_ -= result; |
115 | 162 |
116 // No more data to read. | 163 // No more data to read. |
117 if (!bytes_to_read_) { | 164 if (!bytes_to_read_ || result == 0) { |
118 Finish(SUCCESS, net::OK); | 165 if (VerifyBytes()) |
166 Finish(SUCCESS, net::OK); | |
167 else | |
168 Finish(READ_VERIFY_FAILED, net::ERR_INVALID_RESPONSE); | |
119 return true; | 169 return true; |
120 } | 170 } |
121 ReadData(); | |
122 return false; | 171 return false; |
123 } | 172 } |
124 | 173 |
125 void NetworkStats::OnReadComplete(int result) { | 174 void NetworkStats::OnReadComplete(int result) { |
126 ReadComplete(result); | 175 if (!ReadComplete(result)) { |
176 MessageLoop::current()->PostTask( | |
jar (doing other things)
2011/08/15 19:33:50
This deserves some comment. You mentioned that yo
ramant (doing other things)
2011/08/16 00:00:03
Done.
| |
177 FROM_HERE, | |
178 timers_factory_.NewRunnableMethod(&NetworkStats::ReadData)); | |
179 } | |
127 } | 180 } |
128 | 181 |
129 void NetworkStats::OnWriteComplete(int result) { | 182 void NetworkStats::OnWriteComplete(int result) { |
130 DCHECK(socket_.get()); | 183 DCHECK(socket_.get()); |
131 DCHECK_NE(net::ERR_IO_PENDING, result); | 184 DCHECK_NE(net::ERR_IO_PENDING, result); |
132 if (result < 0) { | 185 if (result < 0) { |
133 Finish(WRITE_FAILED, result); | 186 Finish(WRITE_FAILED, result); |
134 return; | 187 return; |
135 } | 188 } |
136 | 189 |
137 write_buffer_->DidConsume(result); | 190 write_buffer_->DidConsume(result); |
138 bytes_to_send_ -= result; | 191 bytes_to_send_ -= result; |
139 if (!write_buffer_->BytesRemaining()) | 192 if (!write_buffer_->BytesRemaining()) |
140 write_buffer_ = NULL; | 193 write_buffer_ = NULL; |
141 | 194 |
142 if (bytes_to_send_) { | 195 if (bytes_to_send_) { |
143 int rv = SendData(); | 196 int rv = SendData(); |
144 if (rv < 0) { | 197 if (rv < 0) { |
145 if (rv != net::ERR_IO_PENDING) { | 198 if (rv != net::ERR_IO_PENDING) { |
146 Finish(WRITE_FAILED, rv); | 199 Finish(WRITE_FAILED, rv); |
147 return; | 200 return; |
148 } | 201 } |
149 } | 202 } |
150 } | 203 } |
151 } | 204 } |
152 | 205 |
153 void NetworkStats::ReadData() { | 206 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; | 207 int rv; |
161 do { | 208 do { |
162 DCHECK(socket_.get()); | 209 if (!socket_.get()) |
210 return; | |
211 | |
212 DCHECK(!read_buffer_.get()); | |
213 | |
214 // We release the read_buffer_ in the destructor if there is an error. | |
215 read_buffer_ = new net::IOBuffer(kMaxMessage); | |
216 | |
163 rv = socket_->Read(read_buffer_, kMaxMessage, &read_callback_); | 217 rv = socket_->Read(read_buffer_, kMaxMessage, &read_callback_); |
164 if (rv == net::ERR_IO_PENDING) | 218 if (rv == net::ERR_IO_PENDING) |
165 return; | 219 return; |
166 if (ReadComplete(rv)) // Complete the read manually. | 220 // If we have read all the data then return. |
221 if (ReadComplete(rv)) | |
167 return; | 222 return; |
168 } while (rv > 0); | 223 } while (rv > 0); |
169 } | 224 } |
170 | 225 |
171 int NetworkStats::SendData() { | 226 int NetworkStats::SendData() { |
172 DCHECK(bytes_to_send_); // We should have data to send. | 227 DCHECK(bytes_to_send_); // We should have data to send. |
173 do { | 228 do { |
174 if (!write_buffer_.get()) { | 229 if (!write_buffer_.get()) { |
175 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(bytes_to_send_)); | 230 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(bytes_to_send_)); |
176 stream_.GetBytes(buffer->data(), bytes_to_send_); | 231 GetEchoRequest(buffer); |
177 write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_); | 232 write_buffer_ = new net::DrainableIOBuffer(buffer, bytes_to_send_); |
178 } | 233 } |
179 | 234 |
180 DCHECK(socket_.get()); | 235 if (!socket_.get()) |
236 return net::ERR_UNEXPECTED; | |
181 int rv = socket_->Write(write_buffer_, | 237 int rv = socket_->Write(write_buffer_, |
182 write_buffer_->BytesRemaining(), | 238 write_buffer_->BytesRemaining(), |
183 &write_callback_); | 239 &write_callback_); |
184 if (rv < 0) | 240 if (rv < 0) |
185 return rv; | 241 return rv; |
186 write_buffer_->DidConsume(rv); | 242 write_buffer_->DidConsume(rv); |
187 bytes_to_send_ -= rv; | 243 bytes_to_send_ -= rv; |
188 if (!write_buffer_->BytesRemaining()) | 244 if (!write_buffer_->BytesRemaining()) |
189 write_buffer_ = NULL; | 245 write_buffer_ = NULL; |
190 } while (bytes_to_send_); | 246 } while (bytes_to_send_); |
191 return net::OK; | 247 return net::OK; |
192 } | 248 } |
193 | 249 |
250 void NetworkStats::StartReadDataTimer(int milliseconds) { | |
251 MessageLoop::current()->PostDelayedTask( | |
252 FROM_HERE, | |
253 timers_factory_.NewRunnableMethod(&NetworkStats::OnReadDataTimeout), | |
254 milliseconds); | |
255 } | |
256 | |
257 void NetworkStats::OnReadDataTimeout() { | |
258 Finish(READ_FAILED, net::ERR_INVALID_ARGUMENT); | |
jar (doing other things)
2011/08/15 19:33:50
Is there any better error code to supply here?
ramant (doing other things)
2011/08/16 00:00:03
Done.
| |
259 } | |
260 | |
261 void NetworkStats::GetEchoRequest(net::IOBuffer* io_buffer) { | |
262 // Copy the <version> into the io_buffer starting from the kVersionStart | |
263 // position. | |
264 std::string version = base::StringPrintf("%02d", kVersionNumber); | |
265 char* buffer = io_buffer->data() + kVersionStart; | |
266 DCHECK(kVersionLength == version.length()); | |
267 memcpy(buffer, version.c_str(), kVersionLength); | |
268 | |
269 // Get the <payload> from the |stream_| and copy it into io_buffer starting | |
270 // from the kPayloadStart position. | |
271 buffer = io_buffer->data() + kPayloadStart; | |
272 stream_.GetBytes(buffer, load_size_); | |
273 | |
274 // Calculate the <checksum> of the <payload>. | |
275 uint32 sum = 0; | |
276 for (uint32 i = 0; i < load_size_; ++i) | |
277 sum += buffer[i]; | |
278 | |
279 // Copy the <checksum> into the io_buffer starting from the kChecksumStart | |
280 // position. | |
281 std::string checksum = base::StringPrintf("%010d", sum); | |
282 buffer = io_buffer->data() + kChecksumStart; | |
283 DCHECK(kChecksumLength == checksum.length()); | |
284 memcpy(buffer, checksum.c_str(), kChecksumLength); | |
285 | |
286 // Copy the size of the <payload> into the io_buffer starting from the | |
287 // kPayloadSizeStart position. | |
288 buffer = io_buffer->data() + kPayloadSizeStart; | |
289 std::string payload_size = base::StringPrintf("%07d", load_size_); | |
290 DCHECK(kPayloadSizeLength == payload_size.length()); | |
291 memcpy(buffer, payload_size.c_str(), kPayloadSizeLength); | |
292 } | |
293 | |
294 bool NetworkStats::VerifyBytes() { | |
295 // If the "echo response" doesn't have enough bytes, then return false. | |
296 if (encoded_message_.length() < kEncodedPayloadStart) | |
297 return false; | |
298 | |
299 // Extract the |key| from the "echo response". | |
300 std::string key_string = encoded_message_.substr(kKeyStart, kKeyLength); | |
301 const char* key = key_string.c_str(); | |
302 int key_value = atoi(key); | |
303 if (key_value < kKeyMinValue || key_value > kKeyMaxValue) | |
304 return false; | |
305 | |
306 std::string encoded_payload = | |
307 encoded_message_.substr(kEncodedPayloadStart); | |
308 const char* encoded_data = encoded_payload.c_str(); | |
309 uint32 message_length = encoded_payload.length(); | |
310 message_length = std::min(message_length, kMaxMessage); | |
311 // We should get back all the data we had sent. | |
312 if (message_length != load_size_) | |
313 return false; | |
314 | |
315 // Decrypt the data by looping through the |encoded_data| and XOR each byte | |
316 // with the |key| to get the decoded byte. Append the decoded byte to the | |
317 // |decoded_data|. | |
318 char decoded_data[kMaxMessage + 1]; | |
319 for (uint32 data_index = 0, key_index = 0; | |
320 data_index < message_length; | |
321 ++data_index) { | |
322 char encoded_byte = encoded_data[data_index]; | |
323 char key_byte = key[key_index]; | |
324 char decoded_byte = encoded_byte ^ key_byte; | |
325 decoded_data[data_index] = decoded_byte; | |
326 key_index = (key_index + 1) % kKeyLength; | |
327 } | |
328 | |
329 return stream_.VerifyBytes(decoded_data, message_length); | |
330 } | |
331 | |
194 // UDPStatsClient methods and members. | 332 // UDPStatsClient methods and members. |
195 UDPStatsClient::UDPStatsClient() | 333 UDPStatsClient::UDPStatsClient() |
196 : NetworkStats() { | 334 : NetworkStats() { |
197 } | 335 } |
198 | 336 |
199 UDPStatsClient::~UDPStatsClient() { | 337 UDPStatsClient::~UDPStatsClient() { |
200 } | 338 } |
201 | 339 |
202 bool UDPStatsClient::Start(const std::string& ip_str, | 340 bool UDPStatsClient::Start(const std::string& ip_str, |
203 int port, | 341 int port, |
204 int bytes_to_send, | 342 uint32 bytes_to_send, |
205 net::CompletionCallback* finished_callback) { | 343 net::CompletionCallback* finished_callback) { |
206 DCHECK(port); | 344 DCHECK(port); |
207 DCHECK(bytes_to_send); // We should have data to send. | 345 DCHECK(bytes_to_send); // We should have data to send. |
208 | 346 |
209 Initialize(bytes_to_send, finished_callback); | 347 Initialize(bytes_to_send, finished_callback); |
210 | 348 |
211 net::IPAddressNumber ip_number; | 349 net::IPAddressNumber ip_number; |
212 if (!net::ParseIPLiteralToNumber(ip_str, &ip_number)) { | 350 if (!net::ParseIPLiteralToNumber(ip_str, &ip_number)) { |
213 Finish(IP_STRING_PARSE_FAILED, net::ERR_INVALID_ARGUMENT); | 351 Finish(IP_STRING_PARSE_FAILED, net::ERR_INVALID_ARGUMENT); |
214 return false; | 352 return false; |
215 } | 353 } |
216 net::IPEndPoint server_address = net::IPEndPoint(ip_number, port); | 354 net::IPEndPoint server_address = net::IPEndPoint(ip_number, port); |
217 | 355 |
218 net::UDPClientSocket* udp_socket = | 356 net::UDPClientSocket* udp_socket = |
219 new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND, | 357 new net::UDPClientSocket(net::DatagramSocket::DEFAULT_BIND, |
220 net::RandIntCallback(), | 358 net::RandIntCallback(), |
221 NULL, | 359 NULL, |
222 net::NetLog::Source()); | 360 net::NetLog::Source()); |
223 DCHECK(udp_socket); | 361 if (!udp_socket) { |
362 Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT); | |
363 return false; | |
364 } | |
224 set_socket(udp_socket); | 365 set_socket(udp_socket); |
225 | 366 |
226 int rv = udp_socket->Connect(server_address); | 367 int rv = udp_socket->Connect(server_address); |
227 return DoStart(rv); | 368 return DoStart(rv); |
228 } | 369 } |
229 | 370 |
371 bool UDPStatsClient::ReadComplete(int result) { | |
372 DCHECK_NE(net::ERR_IO_PENDING, result); | |
373 if (result <= 0) { | |
374 Finish(READ_FAILED, result); | |
375 return true; | |
376 } | |
377 return NetworkStats::ReadComplete(result); | |
378 } | |
379 | |
230 void UDPStatsClient::Finish(Status status, int result) { | 380 void UDPStatsClient::Finish(Status status, int result) { |
231 base::TimeDelta duration = base::TimeTicks::Now() - start_time(); | 381 base::TimeDelta duration = base::TimeTicks::Now() - start_time(); |
232 if (load_size() == kSmallTestBytesToSend) { | 382 if (load_size() == kSmallTestBytesToSend) { |
233 if (result == net::OK) | 383 if (result == net::OK) |
234 UMA_HISTOGRAM_TIMES("NetConnectivity.UDP.Success.100B.RTT", duration); | 384 UMA_HISTOGRAM_TIMES("NetConnectivity.UDP.Success.100B.RTT", duration); |
235 else | 385 else |
236 UMA_HISTOGRAM_TIMES("NetConnectivity.UDP.Fail.100B.RTT", duration); | 386 UMA_HISTOGRAM_TIMES("NetConnectivity.UDP.Fail.100B.RTT", duration); |
237 | 387 |
238 UMA_HISTOGRAM_ENUMERATION( | 388 UMA_HISTOGRAM_ENUMERATION( |
239 "NetConnectivity.UDP.Status.100B", status, STATUS_MAX); | 389 "NetConnectivity.UDP.Status.100B", status, STATUS_MAX); |
(...skipping 25 matching lines...) Expand all Loading... | |
265 resolve_callback_(this, &TCPStatsClient::OnResolveComplete)), | 415 resolve_callback_(this, &TCPStatsClient::OnResolveComplete)), |
266 ALLOW_THIS_IN_INITIALIZER_LIST( | 416 ALLOW_THIS_IN_INITIALIZER_LIST( |
267 connect_callback_(this, &TCPStatsClient::OnConnectComplete)) { | 417 connect_callback_(this, &TCPStatsClient::OnConnectComplete)) { |
268 } | 418 } |
269 | 419 |
270 TCPStatsClient::~TCPStatsClient() { | 420 TCPStatsClient::~TCPStatsClient() { |
271 } | 421 } |
272 | 422 |
273 bool TCPStatsClient::Start(net::HostResolver* host_resolver, | 423 bool TCPStatsClient::Start(net::HostResolver* host_resolver, |
274 const net::HostPortPair& server_host_port_pair, | 424 const net::HostPortPair& server_host_port_pair, |
275 int bytes_to_send, | 425 uint32 bytes_to_send, |
276 net::CompletionCallback* finished_callback) { | 426 net::CompletionCallback* finished_callback) { |
277 DCHECK(bytes_to_send); // We should have data to send. | 427 DCHECK(bytes_to_send); // We should have data to send. |
278 | 428 |
279 Initialize(bytes_to_send, finished_callback); | 429 Initialize(bytes_to_send, finished_callback); |
280 | 430 |
281 net::HostResolver::RequestInfo request(server_host_port_pair); | 431 net::HostResolver::RequestInfo request(server_host_port_pair); |
282 int rv = host_resolver->Resolve(request, | 432 int rv = host_resolver->Resolve(request, |
283 &addresses_, | 433 &addresses_, |
284 &resolve_callback_, | 434 &resolve_callback_, |
285 NULL, | 435 NULL, |
286 net::BoundNetLog()); | 436 net::BoundNetLog()); |
287 if (rv == net::ERR_IO_PENDING) | 437 if (rv == net::ERR_IO_PENDING) |
288 return true; | 438 return true; |
289 return DoConnect(rv); | 439 return DoConnect(rv); |
290 } | 440 } |
291 | 441 |
292 void TCPStatsClient::OnResolveComplete(int result) { | 442 void TCPStatsClient::OnResolveComplete(int result) { |
293 DoConnect(result); | 443 DoConnect(result); |
294 } | 444 } |
295 | 445 |
296 bool TCPStatsClient::DoConnect(int result) { | 446 bool TCPStatsClient::DoConnect(int result) { |
297 if (result != net::OK) { | 447 if (result != net::OK) { |
298 Finish(RESOLVE_FAILED, result); | 448 Finish(RESOLVE_FAILED, result); |
299 return false; | 449 return false; |
300 } | 450 } |
301 | 451 |
302 net::TCPClientSocket* tcp_socket = | 452 net::TCPClientSocket* tcp_socket = |
303 new net::TCPClientSocket(addresses_, NULL, net::NetLog::Source()); | 453 new net::TCPClientSocket(addresses_, NULL, net::NetLog::Source()); |
304 DCHECK(tcp_socket); | 454 if (!tcp_socket) { |
455 Finish(SOCKET_CREATE_FAILED, net::ERR_INVALID_ARGUMENT); | |
456 return false; | |
457 } | |
305 set_socket(tcp_socket); | 458 set_socket(tcp_socket); |
306 | 459 |
307 int rv = tcp_socket->Connect(&connect_callback_); | 460 int rv = tcp_socket->Connect(&connect_callback_); |
308 if (rv == net::ERR_IO_PENDING) | 461 if (rv == net::ERR_IO_PENDING) |
309 return true; | 462 return true; |
310 | 463 |
311 return DoStart(rv); | 464 return DoStart(rv); |
312 } | 465 } |
313 | 466 |
314 void TCPStatsClient::OnConnectComplete(int result) { | 467 void TCPStatsClient::OnConnectComplete(int result) { |
315 DoStart(result); | 468 DoStart(result); |
316 } | 469 } |
317 | 470 |
471 bool TCPStatsClient::ReadComplete(int result) { | |
472 DCHECK_NE(net::ERR_IO_PENDING, result); | |
473 if (result < 0) { | |
474 Finish(READ_FAILED, result); | |
475 return true; | |
476 } | |
477 return NetworkStats::ReadComplete(result); | |
478 } | |
479 | |
318 void TCPStatsClient::Finish(Status status, int result) { | 480 void TCPStatsClient::Finish(Status status, int result) { |
319 base::TimeDelta duration = base::TimeTicks::Now() - start_time(); | 481 base::TimeDelta duration = base::TimeTicks::Now() - start_time(); |
320 if (load_size() == kSmallTestBytesToSend) { | 482 if (load_size() == kSmallTestBytesToSend) { |
321 if (result == net::OK) | 483 if (result == net::OK) |
322 UMA_HISTOGRAM_TIMES("NetConnectivity.TCP.Success.100B.RTT", duration); | 484 UMA_HISTOGRAM_TIMES("NetConnectivity.TCP.Success.100B.RTT", duration); |
323 else | 485 else |
324 UMA_HISTOGRAM_TIMES("NetConnectivity.TCP.Fail.100B.RTT", duration); | 486 UMA_HISTOGRAM_TIMES("NetConnectivity.TCP.Fail.100B.RTT", duration); |
325 | 487 |
326 UMA_HISTOGRAM_ENUMERATION( | 488 UMA_HISTOGRAM_ENUMERATION( |
327 "NetConnectivity.TCP.Status.100B", status, STATUS_MAX); | 489 "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(); | 586 TCPStatsClient* small_tcp_client = new TCPStatsClient(); |
425 small_tcp_client->Start(host_resolver, server_address, kSmallTestBytesToSend, | 587 small_tcp_client->Start(host_resolver, server_address, kSmallTestBytesToSend, |
426 NULL); | 588 NULL); |
427 | 589 |
428 TCPStatsClient* large_tcp_client = new TCPStatsClient(); | 590 TCPStatsClient* large_tcp_client = new TCPStatsClient(); |
429 large_tcp_client->Start(host_resolver, server_address, kLargeTestBytesToSend, | 591 large_tcp_client->Start(host_resolver, server_address, kLargeTestBytesToSend, |
430 NULL); | 592 NULL); |
431 } | 593 } |
432 | 594 |
433 } // namespace chrome_browser_net | 595 } // namespace chrome_browser_net |
OLD | NEW |