| 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 num_bytes_read_(0), |
| 142 connect_time_micros_(-1) { |
| 141 scoped_refptr<NetLog::EventParameters> params; | 143 scoped_refptr<NetLog::EventParameters> params; |
| 142 if (source.is_valid()) | 144 if (source.is_valid()) |
| 143 params = new NetLogSourceParameter("source_dependency", source); | 145 params = new NetLogSourceParameter("source_dependency", source); |
| 144 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 146 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
| 145 | 147 |
| 146 if (is_tcp_fastopen_enabled()) | 148 if (is_tcp_fastopen_enabled()) |
| 147 use_tcp_fastopen_ = true; | 149 use_tcp_fastopen_ = true; |
| 148 } | 150 } |
| 149 | 151 |
| 150 TCPClientSocketLibevent::~TCPClientSocketLibevent() { | 152 TCPClientSocketLibevent::~TCPClientSocketLibevent() { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 size_t addr_len = sizeof(addr_storage); | 293 size_t addr_len = sizeof(addr_storage); |
| 292 if (!bind_address_->ToSockAddr(addr, &addr_len)) | 294 if (!bind_address_->ToSockAddr(addr, &addr_len)) |
| 293 return ERR_INVALID_ARGUMENT; | 295 return ERR_INVALID_ARGUMENT; |
| 294 if (HANDLE_EINTR(bind(socket_, addr, addr_len))) | 296 if (HANDLE_EINTR(bind(socket_, addr, addr_len))) |
| 295 return MapSystemError(errno); | 297 return MapSystemError(errno); |
| 296 } | 298 } |
| 297 } | 299 } |
| 298 | 300 |
| 299 // Connect the socket. | 301 // Connect the socket. |
| 300 if (!use_tcp_fastopen_) { | 302 if (!use_tcp_fastopen_) { |
| 303 connect_start_time_ = base::TimeTicks::Now(); |
| 301 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, | 304 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, |
| 302 static_cast<int>(current_ai_->ai_addrlen)))) { | 305 static_cast<int>(current_ai_->ai_addrlen)))) { |
| 303 // Connected without waiting! | 306 // Connected without waiting! |
| 304 return OK; | 307 return OK; |
| 305 } | 308 } |
| 306 } else { | 309 } else { |
| 307 // With TCP FastOpen, we pretend that the socket is connected. | 310 // With TCP FastOpen, we pretend that the socket is connected. |
| 308 DCHECK(!tcp_fastopen_connected_); | 311 DCHECK(!tcp_fastopen_connected_); |
| 309 return OK; | 312 return OK; |
| 310 } | 313 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 332 int os_error = connect_os_error_; | 335 int os_error = connect_os_error_; |
| 333 connect_os_error_ = 0; | 336 connect_os_error_ = 0; |
| 334 scoped_refptr<NetLog::EventParameters> params; | 337 scoped_refptr<NetLog::EventParameters> params; |
| 335 if (result != OK) | 338 if (result != OK) |
| 336 params = new NetLogIntegerParameter("os_error", os_error); | 339 params = new NetLogIntegerParameter("os_error", os_error); |
| 337 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); | 340 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); |
| 338 | 341 |
| 339 write_socket_watcher_.StopWatchingFileDescriptor(); | 342 write_socket_watcher_.StopWatchingFileDescriptor(); |
| 340 | 343 |
| 341 if (result == OK) { | 344 if (result == OK) { |
| 345 connect_time_micros_ = (base::TimeTicks::Now() - |
| 346 connect_start_time_).ToInternalValue(); |
| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 DCHECK(!waiting_connect()); | 426 DCHECK(!waiting_connect()); |
| 422 DCHECK(!read_callback_); | 427 DCHECK(!read_callback_); |
| 423 // Synchronous operation not supported | 428 // Synchronous operation not supported |
| 424 DCHECK(callback); | 429 DCHECK(callback); |
| 425 DCHECK_GT(buf_len, 0); | 430 DCHECK_GT(buf_len, 0); |
| 426 | 431 |
| 427 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | 432 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
| 428 if (nread >= 0) { | 433 if (nread >= 0) { |
| 429 base::StatsCounter read_bytes("tcp.read_bytes"); | 434 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 430 read_bytes.Add(nread); | 435 read_bytes.Add(nread); |
| 436 num_bytes_read_ += static_cast<int64>(nread); |
| 431 if (nread > 0) | 437 if (nread > 0) |
| 432 use_history_.set_was_used_to_convey_data(); | 438 use_history_.set_was_used_to_convey_data(); |
| 433 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, | 439 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, |
| 434 buf->data()); | 440 buf->data()); |
| 435 return nread; | 441 return nread; |
| 436 } | 442 } |
| 437 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 443 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
| 438 DVLOG(1) << "read failed, errno " << errno; | 444 DVLOG(1) << "read failed, errno " << errno; |
| 439 return MapSystemError(errno); | 445 return MapSystemError(errno); |
| 440 } | 446 } |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 void TCPClientSocketLibevent::DidCompleteRead() { | 621 void TCPClientSocketLibevent::DidCompleteRead() { |
| 616 int bytes_transferred; | 622 int bytes_transferred; |
| 617 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), | 623 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), |
| 618 read_buf_len_)); | 624 read_buf_len_)); |
| 619 | 625 |
| 620 int result; | 626 int result; |
| 621 if (bytes_transferred >= 0) { | 627 if (bytes_transferred >= 0) { |
| 622 result = bytes_transferred; | 628 result = bytes_transferred; |
| 623 base::StatsCounter read_bytes("tcp.read_bytes"); | 629 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 624 read_bytes.Add(bytes_transferred); | 630 read_bytes.Add(bytes_transferred); |
| 631 num_bytes_read_ += static_cast<int64>(bytes_transferred); |
| 625 if (bytes_transferred > 0) | 632 if (bytes_transferred > 0) |
| 626 use_history_.set_was_used_to_convey_data(); | 633 use_history_.set_was_used_to_convey_data(); |
| 627 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, | 634 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, |
| 628 read_buf_->data()); | 635 read_buf_->data()); |
| 629 } else { | 636 } else { |
| 630 result = MapSystemError(errno); | 637 result = MapSystemError(errno); |
| 631 } | 638 } |
| 632 | 639 |
| 633 if (result != ERR_IO_PENDING) { | 640 if (result != ERR_IO_PENDING) { |
| 634 read_buf_ = NULL; | 641 read_buf_ = NULL; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 } | 711 } |
| 705 | 712 |
| 706 bool TCPClientSocketLibevent::WasEverUsed() const { | 713 bool TCPClientSocketLibevent::WasEverUsed() const { |
| 707 return use_history_.was_used_to_convey_data(); | 714 return use_history_.was_used_to_convey_data(); |
| 708 } | 715 } |
| 709 | 716 |
| 710 bool TCPClientSocketLibevent::UsingTCPFastOpen() const { | 717 bool TCPClientSocketLibevent::UsingTCPFastOpen() const { |
| 711 return use_tcp_fastopen_; | 718 return use_tcp_fastopen_; |
| 712 } | 719 } |
| 713 | 720 |
| 721 int64 TCPClientSocketLibevent::NumBytesRead() const { |
| 722 return num_bytes_read_; |
| 723 } |
| 724 |
| 725 int TCPClientSocketLibevent::GetConnectTimeMicros() const { |
| 726 return connect_time_micros_; |
| 727 } |
| 728 |
| 714 } // namespace net | 729 } // namespace net |
| OLD | NEW |