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 "net/socket/tcp_client_socket.h" | 5 #include "net/socket/tcp_client_socket.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <netdb.h> | 9 #include <netdb.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 current_ai_(NULL), | 130 current_ai_(NULL), |
131 read_watcher_(this), | 131 read_watcher_(this), |
132 write_watcher_(this), | 132 write_watcher_(this), |
133 read_callback_(NULL), | 133 read_callback_(NULL), |
134 write_callback_(NULL), | 134 write_callback_(NULL), |
135 next_connect_state_(CONNECT_STATE_NONE), | 135 next_connect_state_(CONNECT_STATE_NONE), |
136 connect_os_error_(0), | 136 connect_os_error_(0), |
137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
138 previously_disconnected_(false), | 138 previously_disconnected_(false), |
139 use_tcp_fastopen_(false), | 139 use_tcp_fastopen_(false), |
140 tcp_fastopen_connected_(false) { | 140 tcp_fastopen_connected_(false), |
| 141 connect_start_time_(), |
| 142 connect_time_micros_(), |
| 143 num_bytes_read_(0) { |
141 scoped_refptr<NetLog::EventParameters> params; | 144 scoped_refptr<NetLog::EventParameters> params; |
142 if (source.is_valid()) | 145 if (source.is_valid()) |
143 params = new NetLogSourceParameter("source_dependency", source); | 146 params = new NetLogSourceParameter("source_dependency", source); |
144 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 147 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
145 | 148 |
146 if (is_tcp_fastopen_enabled()) | 149 if (is_tcp_fastopen_enabled()) |
147 use_tcp_fastopen_ = true; | 150 use_tcp_fastopen_ = true; |
148 } | 151 } |
149 | 152 |
150 TCPClientSocketLibevent::~TCPClientSocketLibevent() { | 153 TCPClientSocketLibevent::~TCPClientSocketLibevent() { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 size_t addr_len = sizeof(addr_storage); | 294 size_t addr_len = sizeof(addr_storage); |
292 if (!bind_address_->ToSockAddr(addr, &addr_len)) | 295 if (!bind_address_->ToSockAddr(addr, &addr_len)) |
293 return ERR_INVALID_ARGUMENT; | 296 return ERR_INVALID_ARGUMENT; |
294 if (HANDLE_EINTR(bind(socket_, addr, addr_len))) | 297 if (HANDLE_EINTR(bind(socket_, addr, addr_len))) |
295 return MapSystemError(errno); | 298 return MapSystemError(errno); |
296 } | 299 } |
297 } | 300 } |
298 | 301 |
299 // Connect the socket. | 302 // Connect the socket. |
300 if (!use_tcp_fastopen_) { | 303 if (!use_tcp_fastopen_) { |
| 304 connect_start_time_ = base::TimeTicks::Now(); |
301 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, | 305 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, |
302 static_cast<int>(current_ai_->ai_addrlen)))) { | 306 static_cast<int>(current_ai_->ai_addrlen)))) { |
303 // Connected without waiting! | 307 // Connected without waiting! |
304 return OK; | 308 return OK; |
305 } | 309 } |
306 } else { | 310 } else { |
307 // With TCP FastOpen, we pretend that the socket is connected. | 311 // With TCP FastOpen, we pretend that the socket is connected. |
308 DCHECK(!tcp_fastopen_connected_); | 312 DCHECK(!tcp_fastopen_connected_); |
309 return OK; | 313 return OK; |
310 } | 314 } |
(...skipping 21 matching lines...) Expand all Loading... |
332 int os_error = connect_os_error_; | 336 int os_error = connect_os_error_; |
333 connect_os_error_ = 0; | 337 connect_os_error_ = 0; |
334 scoped_refptr<NetLog::EventParameters> params; | 338 scoped_refptr<NetLog::EventParameters> params; |
335 if (result != OK) | 339 if (result != OK) |
336 params = new NetLogIntegerParameter("os_error", os_error); | 340 params = new NetLogIntegerParameter("os_error", os_error); |
337 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); | 341 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); |
338 | 342 |
339 write_socket_watcher_.StopWatchingFileDescriptor(); | 343 write_socket_watcher_.StopWatchingFileDescriptor(); |
340 | 344 |
341 if (result == OK) { | 345 if (result == OK) { |
| 346 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; |
342 use_history_.set_was_ever_connected(); | 347 use_history_.set_was_ever_connected(); |
343 return OK; // Done! | 348 return OK; // Done! |
344 } | 349 } |
345 | 350 |
346 // Close whatever partially connected socket we currently have. | 351 // Close whatever partially connected socket we currently have. |
347 DoDisconnect(); | 352 DoDisconnect(); |
348 | 353 |
349 // Try to fall back to the next address in the list. | 354 // Try to fall back to the next address in the list. |
350 if (current_ai_->ai_next) { | 355 if (current_ai_->ai_next) { |
351 next_connect_state_ = CONNECT_STATE_CONNECT; | 356 next_connect_state_ = CONNECT_STATE_CONNECT; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 DCHECK(!waiting_connect()); | 438 DCHECK(!waiting_connect()); |
434 DCHECK(!read_callback_); | 439 DCHECK(!read_callback_); |
435 // Synchronous operation not supported | 440 // Synchronous operation not supported |
436 DCHECK(callback); | 441 DCHECK(callback); |
437 DCHECK_GT(buf_len, 0); | 442 DCHECK_GT(buf_len, 0); |
438 | 443 |
439 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | 444 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
440 if (nread >= 0) { | 445 if (nread >= 0) { |
441 base::StatsCounter read_bytes("tcp.read_bytes"); | 446 base::StatsCounter read_bytes("tcp.read_bytes"); |
442 read_bytes.Add(nread); | 447 read_bytes.Add(nread); |
| 448 num_bytes_read_ += static_cast<int64>(nread); |
443 if (nread > 0) | 449 if (nread > 0) |
444 use_history_.set_was_used_to_convey_data(); | 450 use_history_.set_was_used_to_convey_data(); |
445 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, | 451 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, |
446 buf->data()); | 452 buf->data()); |
447 return nread; | 453 return nread; |
448 } | 454 } |
449 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 455 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
450 DVLOG(1) << "read failed, errno " << errno; | 456 DVLOG(1) << "read failed, errno " << errno; |
451 return MapSystemError(errno); | 457 return MapSystemError(errno); |
452 } | 458 } |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 void TCPClientSocketLibevent::DidCompleteRead() { | 633 void TCPClientSocketLibevent::DidCompleteRead() { |
628 int bytes_transferred; | 634 int bytes_transferred; |
629 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), | 635 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), |
630 read_buf_len_)); | 636 read_buf_len_)); |
631 | 637 |
632 int result; | 638 int result; |
633 if (bytes_transferred >= 0) { | 639 if (bytes_transferred >= 0) { |
634 result = bytes_transferred; | 640 result = bytes_transferred; |
635 base::StatsCounter read_bytes("tcp.read_bytes"); | 641 base::StatsCounter read_bytes("tcp.read_bytes"); |
636 read_bytes.Add(bytes_transferred); | 642 read_bytes.Add(bytes_transferred); |
| 643 num_bytes_read_ += static_cast<int64>(bytes_transferred); |
637 if (bytes_transferred > 0) | 644 if (bytes_transferred > 0) |
638 use_history_.set_was_used_to_convey_data(); | 645 use_history_.set_was_used_to_convey_data(); |
639 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, | 646 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, |
640 read_buf_->data()); | 647 read_buf_->data()); |
641 } else { | 648 } else { |
642 result = MapSystemError(errno); | 649 result = MapSystemError(errno); |
643 } | 650 } |
644 | 651 |
645 if (result != ERR_IO_PENDING) { | 652 if (result != ERR_IO_PENDING) { |
646 read_buf_ = NULL; | 653 read_buf_ = NULL; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 } | 723 } |
717 | 724 |
718 bool TCPClientSocketLibevent::WasEverUsed() const { | 725 bool TCPClientSocketLibevent::WasEverUsed() const { |
719 return use_history_.was_used_to_convey_data(); | 726 return use_history_.was_used_to_convey_data(); |
720 } | 727 } |
721 | 728 |
722 bool TCPClientSocketLibevent::UsingTCPFastOpen() const { | 729 bool TCPClientSocketLibevent::UsingTCPFastOpen() const { |
723 return use_tcp_fastopen_; | 730 return use_tcp_fastopen_; |
724 } | 731 } |
725 | 732 |
| 733 int64 TCPClientSocketLibevent::NumBytesRead() const { |
| 734 return num_bytes_read_; |
| 735 } |
| 736 |
| 737 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { |
| 738 return connect_time_micros_; |
| 739 } |
| 740 |
726 } // namespace net | 741 } // namespace net |
OLD | NEW |