| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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> |
| 11 #include <netinet/tcp.h> | 11 #include <netinet/tcp.h> |
| 12 #if defined(OS_POSIX) | 12 #if defined(OS_POSIX) |
| 13 #include <netinet/in.h> | 13 #include <netinet/in.h> |
| 14 #endif | 14 #endif |
| 15 | 15 |
| 16 #include "base/eintr_wrapper.h" | 16 #include "base/eintr_wrapper.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/message_loop.h" | 18 #include "base/message_loop.h" |
| 19 #include "base/metrics/stats_counters.h" | 19 #include "base/metrics/stats_counters.h" |
| 20 #include "base/string_util.h" | 20 #include "base/string_util.h" |
| 21 #include "net/base/connection_type_histograms.h" | 21 #include "net/base/connection_type_histograms.h" |
| 22 #include "net/base/io_buffer.h" | 22 #include "net/base/io_buffer.h" |
| 23 #include "net/base/ip_endpoint.h" | 23 #include "net/base/ip_endpoint.h" |
| 24 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
| 25 #include "net/base/net_log.h" | 25 #include "net/base/net_log.h" |
| 26 #include "net/base/net_util.h" | 26 #include "net/base/net_util.h" |
| 27 #include "net/base/network_change_notifier.h" | 27 #include "net/base/network_change_notifier.h" |
| 28 #include "net/socket/socket_error_params.h" | 28 #include "net/socket/socket_net_log_params.h" |
| 29 | 29 |
| 30 namespace net { | 30 namespace net { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 const int kInvalidSocket = -1; | 34 const int kInvalidSocket = -1; |
| 35 const int kTCPKeepAliveSeconds = 45; | 35 const int kTCPKeepAliveSeconds = 45; |
| 36 | 36 |
| 37 // SetTCPNoDelay turns on/off buffering in the kernel. By default, TCP sockets | 37 // SetTCPNoDelay turns on/off buffering in the kernel. By default, TCP sockets |
| 38 // will wait up to 200ms for more data to complete a packet before transmitting. | 38 // will wait up to 200ms for more data to complete a packet before transmitting. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 current_address_index_(-1), | 132 current_address_index_(-1), |
| 133 read_watcher_(this), | 133 read_watcher_(this), |
| 134 write_watcher_(this), | 134 write_watcher_(this), |
| 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) { | 141 num_bytes_read_(0) { |
| 142 scoped_refptr<NetLog::EventParameters> params; | 142 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
| 143 if (source.is_valid()) | 143 source.ToEventParametersCallback()); |
| 144 params = new NetLogSourceParameter("source_dependency", source); | |
| 145 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | |
| 146 | 144 |
| 147 if (is_tcp_fastopen_enabled()) | 145 if (is_tcp_fastopen_enabled()) |
| 148 use_tcp_fastopen_ = true; | 146 use_tcp_fastopen_ = true; |
| 149 } | 147 } |
| 150 | 148 |
| 151 TCPClientSocketLibevent::~TCPClientSocketLibevent() { | 149 TCPClientSocketLibevent::~TCPClientSocketLibevent() { |
| 152 Disconnect(); | 150 Disconnect(); |
| 153 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 151 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); |
| 154 } | 152 } |
| 155 | 153 |
| 156 int TCPClientSocketLibevent::AdoptSocket(int socket) { | 154 int TCPClientSocketLibevent::AdoptSocket(int socket) { |
| 157 DCHECK_EQ(socket_, kInvalidSocket); | 155 DCHECK_EQ(socket_, kInvalidSocket); |
| 158 | 156 |
| 159 int error = SetupSocket(socket); | 157 int error = SetupSocket(socket); |
| 160 if (error) | 158 if (error) |
| 161 return MapSystemError(error); | 159 return MapSystemError(error); |
| 162 | 160 |
| 163 socket_ = socket; | 161 socket_ = socket; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 DCHECK_EQ(0, connect_os_error_); | 261 DCHECK_EQ(0, connect_os_error_); |
| 264 | 262 |
| 265 const IPEndPoint& endpoint = addresses_[current_address_index_]; | 263 const IPEndPoint& endpoint = addresses_[current_address_index_]; |
| 266 | 264 |
| 267 if (previously_disconnected_) { | 265 if (previously_disconnected_) { |
| 268 use_history_.Reset(); | 266 use_history_.Reset(); |
| 269 previously_disconnected_ = false; | 267 previously_disconnected_ = false; |
| 270 } | 268 } |
| 271 | 269 |
| 272 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 270 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 273 make_scoped_refptr(new NetLogStringParameter( | 271 CreateNetLogIPEndPointCallback(&endpoint)); |
| 274 "address", | |
| 275 endpoint.ToString()))); | |
| 276 | 272 |
| 277 next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; | 273 next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; |
| 278 | 274 |
| 279 if (bound_socket_ != kInvalidSocket) { | 275 if (bound_socket_ != kInvalidSocket) { |
| 280 DCHECK(bind_address_.get()); | 276 DCHECK(bind_address_.get()); |
| 281 socket_ = bound_socket_; | 277 socket_ = bound_socket_; |
| 282 bound_socket_ = kInvalidSocket; | 278 bound_socket_ = kInvalidSocket; |
| 283 } else { | 279 } else { |
| 284 // Create a non-blocking socket. | 280 // Create a non-blocking socket. |
| 285 connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_); | 281 connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 return MapSystemError(connect_os_error_); | 323 return MapSystemError(connect_os_error_); |
| 328 } | 324 } |
| 329 | 325 |
| 330 return ERR_IO_PENDING; | 326 return ERR_IO_PENDING; |
| 331 } | 327 } |
| 332 | 328 |
| 333 int TCPClientSocketLibevent::DoConnectComplete(int result) { | 329 int TCPClientSocketLibevent::DoConnectComplete(int result) { |
| 334 // Log the end of this attempt (and any OS error it threw). | 330 // Log the end of this attempt (and any OS error it threw). |
| 335 int os_error = connect_os_error_; | 331 int os_error = connect_os_error_; |
| 336 connect_os_error_ = 0; | 332 connect_os_error_ = 0; |
| 337 scoped_refptr<NetLog::EventParameters> params; | 333 if (result != OK) { |
| 338 if (result != OK) | 334 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 339 params = new NetLogIntegerParameter("os_error", os_error); | 335 NetLog::IntegerCallback("os_error", os_error)); |
| 340 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); | 336 } else { |
| 337 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); |
| 338 } |
| 341 | 339 |
| 342 if (result == OK) { | 340 if (result == OK) { |
| 343 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; | 341 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; |
| 344 write_socket_watcher_.StopWatchingFileDescriptor(); | 342 write_socket_watcher_.StopWatchingFileDescriptor(); |
| 345 use_history_.set_was_ever_connected(); | 343 use_history_.set_was_ever_connected(); |
| 346 return OK; // Done! | 344 return OK; // Done! |
| 347 } | 345 } |
| 348 | 346 |
| 349 // Close whatever partially connected socket we currently have. | 347 // Close whatever partially connected socket we currently have. |
| 350 DoDisconnect(); | 348 DoDisconnect(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 num_bytes_read_ += static_cast<int64>(nread); | 444 num_bytes_read_ += static_cast<int64>(nread); |
| 447 if (nread > 0) | 445 if (nread > 0) |
| 448 use_history_.set_was_used_to_convey_data(); | 446 use_history_.set_was_used_to_convey_data(); |
| 449 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, | 447 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, |
| 450 buf->data()); | 448 buf->data()); |
| 451 return nread; | 449 return nread; |
| 452 } | 450 } |
| 453 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 451 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
| 454 int net_error = MapSystemError(errno); | 452 int net_error = MapSystemError(errno); |
| 455 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 453 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 456 make_scoped_refptr(new SocketErrorParams(net_error, errno))); | 454 CreateNetLogSocketErrorCallback(net_error, errno)); |
| 457 return net_error; | 455 return net_error; |
| 458 } | 456 } |
| 459 | 457 |
| 460 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 458 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 461 socket_, true, MessageLoopForIO::WATCH_READ, | 459 socket_, true, MessageLoopForIO::WATCH_READ, |
| 462 &read_socket_watcher_, &read_watcher_)) { | 460 &read_socket_watcher_, &read_watcher_)) { |
| 463 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; | 461 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; |
| 464 return MapSystemError(errno); | 462 return MapSystemError(errno); |
| 465 } | 463 } |
| 466 | 464 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 487 write_bytes.Add(nwrite); | 485 write_bytes.Add(nwrite); |
| 488 if (nwrite > 0) | 486 if (nwrite > 0) |
| 489 use_history_.set_was_used_to_convey_data(); | 487 use_history_.set_was_used_to_convey_data(); |
| 490 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, | 488 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, |
| 491 buf->data()); | 489 buf->data()); |
| 492 return nwrite; | 490 return nwrite; |
| 493 } | 491 } |
| 494 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 492 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
| 495 int net_error = MapSystemError(errno); | 493 int net_error = MapSystemError(errno); |
| 496 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 494 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
| 497 make_scoped_refptr(new SocketErrorParams(net_error, errno))); | 495 CreateNetLogSocketErrorCallback(net_error, errno)); |
| 498 return net_error; | 496 return net_error; |
| 499 } | 497 } |
| 500 | 498 |
| 501 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 499 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 502 socket_, true, MessageLoopForIO::WATCH_WRITE, | 500 socket_, true, MessageLoopForIO::WATCH_WRITE, |
| 503 &write_socket_watcher_, &write_watcher_)) { | 501 &write_socket_watcher_, &write_watcher_)) { |
| 504 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; | 502 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; |
| 505 return MapSystemError(errno); | 503 return MapSystemError(errno); |
| 506 } | 504 } |
| 507 | 505 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 | 589 |
| 592 SockaddrStorage storage; | 590 SockaddrStorage storage; |
| 593 int rv = getsockname(socket_, storage.addr, &storage.addr_len); | 591 int rv = getsockname(socket_, storage.addr, &storage.addr_len); |
| 594 if (rv != 0) { | 592 if (rv != 0) { |
| 595 PLOG(ERROR) << "getsockname() [rv: " << rv << "] error: "; | 593 PLOG(ERROR) << "getsockname() [rv: " << rv << "] error: "; |
| 596 NOTREACHED(); | 594 NOTREACHED(); |
| 597 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); | 595 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); |
| 598 return; | 596 return; |
| 599 } | 597 } |
| 600 | 598 |
| 601 const std::string source_address_str = | |
| 602 NetAddressToStringWithPort(storage.addr, storage.addr_len); | |
| 603 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 599 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, |
| 604 make_scoped_refptr(new NetLogStringParameter( | 600 CreateNetLogSourceAddressCallback(storage.addr, |
| 605 "source address", | 601 storage.addr_len)); |
| 606 source_address_str))); | |
| 607 } | 602 } |
| 608 | 603 |
| 609 void TCPClientSocketLibevent::DoReadCallback(int rv) { | 604 void TCPClientSocketLibevent::DoReadCallback(int rv) { |
| 610 DCHECK_NE(rv, ERR_IO_PENDING); | 605 DCHECK_NE(rv, ERR_IO_PENDING); |
| 611 DCHECK(!read_callback_.is_null()); | 606 DCHECK(!read_callback_.is_null()); |
| 612 | 607 |
| 613 // since Run may result in Read being called, clear read_callback_ up front. | 608 // since Run may result in Read being called, clear read_callback_ up front. |
| 614 CompletionCallback c = read_callback_; | 609 CompletionCallback c = read_callback_; |
| 615 read_callback_.Reset(); | 610 read_callback_.Reset(); |
| 616 c.Run(rv); | 611 c.Run(rv); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 read_bytes.Add(bytes_transferred); | 656 read_bytes.Add(bytes_transferred); |
| 662 num_bytes_read_ += static_cast<int64>(bytes_transferred); | 657 num_bytes_read_ += static_cast<int64>(bytes_transferred); |
| 663 if (bytes_transferred > 0) | 658 if (bytes_transferred > 0) |
| 664 use_history_.set_was_used_to_convey_data(); | 659 use_history_.set_was_used_to_convey_data(); |
| 665 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, | 660 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, |
| 666 read_buf_->data()); | 661 read_buf_->data()); |
| 667 } else { | 662 } else { |
| 668 result = MapSystemError(errno); | 663 result = MapSystemError(errno); |
| 669 if (result != ERR_IO_PENDING) { | 664 if (result != ERR_IO_PENDING) { |
| 670 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 665 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 671 make_scoped_refptr(new SocketErrorParams(result, errno))); | 666 CreateNetLogSocketErrorCallback(result, errno)); |
| 672 } | 667 } |
| 673 } | 668 } |
| 674 | 669 |
| 675 if (result != ERR_IO_PENDING) { | 670 if (result != ERR_IO_PENDING) { |
| 676 read_buf_ = NULL; | 671 read_buf_ = NULL; |
| 677 read_buf_len_ = 0; | 672 read_buf_len_ = 0; |
| 678 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 673 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
| 679 DCHECK(ok); | 674 DCHECK(ok); |
| 680 DoReadCallback(result); | 675 DoReadCallback(result); |
| 681 } | 676 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 692 base::StatsCounter write_bytes("tcp.write_bytes"); | 687 base::StatsCounter write_bytes("tcp.write_bytes"); |
| 693 write_bytes.Add(bytes_transferred); | 688 write_bytes.Add(bytes_transferred); |
| 694 if (bytes_transferred > 0) | 689 if (bytes_transferred > 0) |
| 695 use_history_.set_was_used_to_convey_data(); | 690 use_history_.set_was_used_to_convey_data(); |
| 696 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, result, | 691 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, result, |
| 697 write_buf_->data()); | 692 write_buf_->data()); |
| 698 } else { | 693 } else { |
| 699 result = MapSystemError(errno); | 694 result = MapSystemError(errno); |
| 700 if (result != ERR_IO_PENDING) { | 695 if (result != ERR_IO_PENDING) { |
| 701 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 696 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
| 702 make_scoped_refptr(new SocketErrorParams(result, errno))); | 697 CreateNetLogSocketErrorCallback(result, errno)); |
| 703 } | 698 } |
| 704 } | 699 } |
| 705 | 700 |
| 706 if (result != ERR_IO_PENDING) { | 701 if (result != ERR_IO_PENDING) { |
| 707 write_buf_ = NULL; | 702 write_buf_ = NULL; |
| 708 write_buf_len_ = 0; | 703 write_buf_len_ = 0; |
| 709 write_socket_watcher_.StopWatchingFileDescriptor(); | 704 write_socket_watcher_.StopWatchingFileDescriptor(); |
| 710 DoWriteCallback(result); | 705 DoWriteCallback(result); |
| 711 } | 706 } |
| 712 } | 707 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 | 756 |
| 762 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { | 757 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { |
| 763 return connect_time_micros_; | 758 return connect_time_micros_; |
| 764 } | 759 } |
| 765 | 760 |
| 766 NextProto TCPClientSocketLibevent::GetNegotiatedProtocol() const { | 761 NextProto TCPClientSocketLibevent::GetNegotiatedProtocol() const { |
| 767 return kProtoUnknown; | 762 return kProtoUnknown; |
| 768 } | 763 } |
| 769 | 764 |
| 770 } // namespace net | 765 } // namespace net |
| OLD | NEW |