| 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_win.h" | 5 #include "net/socket/tcp_client_socket_win.h" |
| 6 | 6 |
| 7 #include <mstcpip.h> | 7 #include <mstcpip.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 11 #include "base/metrics/stats_counters.h" | 11 #include "base/metrics/stats_counters.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/win/object_watcher.h" | 13 #include "base/win/object_watcher.h" |
| 14 #include "base/win/windows_version.h" | 14 #include "base/win/windows_version.h" |
| 15 #include "net/base/connection_type_histograms.h" | 15 #include "net/base/connection_type_histograms.h" |
| 16 #include "net/base/io_buffer.h" | 16 #include "net/base/io_buffer.h" |
| 17 #include "net/base/ip_endpoint.h" | 17 #include "net/base/ip_endpoint.h" |
| 18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 19 #include "net/base/net_log.h" | 19 #include "net/base/net_log.h" |
| 20 #include "net/base/net_util.h" | 20 #include "net/base/net_util.h" |
| 21 #include "net/base/network_change_notifier.h" | 21 #include "net/base/network_change_notifier.h" |
| 22 #include "net/base/winsock_init.h" | 22 #include "net/base/winsock_init.h" |
| 23 #include "net/base/winsock_util.h" | 23 #include "net/base/winsock_util.h" |
| 24 #include "net/socket/socket_error_params.h" | 24 #include "net/socket/socket_net_log_params.h" |
| 25 | 25 |
| 26 namespace net { | 26 namespace net { |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 const int kTCPKeepAliveSeconds = 45; | 30 const int kTCPKeepAliveSeconds = 45; |
| 31 | 31 |
| 32 bool SetSocketReceiveBufferSize(SOCKET socket, int32 size) { | 32 bool SetSocketReceiveBufferSize(SOCKET socket, int32 size) { |
| 33 int rv = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, | 33 int rv = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, |
| 34 reinterpret_cast<const char*>(&size), sizeof(size)); | 34 reinterpret_cast<const char*>(&size), sizeof(size)); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 bound_socket_(INVALID_SOCKET), | 328 bound_socket_(INVALID_SOCKET), |
| 329 addresses_(addresses), | 329 addresses_(addresses), |
| 330 current_address_index_(-1), | 330 current_address_index_(-1), |
| 331 waiting_read_(false), | 331 waiting_read_(false), |
| 332 waiting_write_(false), | 332 waiting_write_(false), |
| 333 next_connect_state_(CONNECT_STATE_NONE), | 333 next_connect_state_(CONNECT_STATE_NONE), |
| 334 connect_os_error_(0), | 334 connect_os_error_(0), |
| 335 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 335 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
| 336 previously_disconnected_(false), | 336 previously_disconnected_(false), |
| 337 num_bytes_read_(0) { | 337 num_bytes_read_(0) { |
| 338 scoped_refptr<NetLog::EventParameters> params; | 338 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
| 339 if (source.is_valid()) | 339 source.ToEventParametersCallback()); |
| 340 params = new NetLogSourceParameter("source_dependency", source); | |
| 341 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | |
| 342 EnsureWinsockInit(); | 340 EnsureWinsockInit(); |
| 343 } | 341 } |
| 344 | 342 |
| 345 TCPClientSocketWin::~TCPClientSocketWin() { | 343 TCPClientSocketWin::~TCPClientSocketWin() { |
| 346 Disconnect(); | 344 Disconnect(); |
| 347 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 345 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); |
| 348 } | 346 } |
| 349 | 347 |
| 350 int TCPClientSocketWin::AdoptSocket(SOCKET socket) { | 348 int TCPClientSocketWin::AdoptSocket(SOCKET socket) { |
| 351 DCHECK_EQ(socket_, INVALID_SOCKET); | 349 DCHECK_EQ(socket_, INVALID_SOCKET); |
| 352 | 350 |
| 353 int error = SetupSocket(socket); | 351 int error = SetupSocket(socket); |
| 354 if (error) | 352 if (error) |
| 355 return MapSystemError(error); | 353 return MapSystemError(error); |
| 356 | 354 |
| 357 socket_ = socket; | 355 socket_ = socket; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 DCHECK_EQ(0, connect_os_error_); | 454 DCHECK_EQ(0, connect_os_error_); |
| 457 | 455 |
| 458 const IPEndPoint& endpoint = addresses_[current_address_index_]; | 456 const IPEndPoint& endpoint = addresses_[current_address_index_]; |
| 459 | 457 |
| 460 if (previously_disconnected_) { | 458 if (previously_disconnected_) { |
| 461 use_history_.Reset(); | 459 use_history_.Reset(); |
| 462 previously_disconnected_ = false; | 460 previously_disconnected_ = false; |
| 463 } | 461 } |
| 464 | 462 |
| 465 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 463 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 466 new NetLogStringParameter("address", | 464 CreateNetLogIPEndPointCallback(&endpoint)); |
| 467 endpoint.ToString())); | |
| 468 | 465 |
| 469 next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; | 466 next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; |
| 470 | 467 |
| 471 if (bound_socket_ != INVALID_SOCKET) { | 468 if (bound_socket_ != INVALID_SOCKET) { |
| 472 DCHECK(bind_address_.get()); | 469 DCHECK(bind_address_.get()); |
| 473 socket_ = bound_socket_; | 470 socket_ = bound_socket_; |
| 474 bound_socket_ = INVALID_SOCKET; | 471 bound_socket_ = INVALID_SOCKET; |
| 475 } else { | 472 } else { |
| 476 connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_); | 473 connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_); |
| 477 if (connect_os_error_ != 0) | 474 if (connect_os_error_ != 0) |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 } | 518 } |
| 522 | 519 |
| 523 core_->WatchForRead(); | 520 core_->WatchForRead(); |
| 524 return ERR_IO_PENDING; | 521 return ERR_IO_PENDING; |
| 525 } | 522 } |
| 526 | 523 |
| 527 int TCPClientSocketWin::DoConnectComplete(int result) { | 524 int TCPClientSocketWin::DoConnectComplete(int result) { |
| 528 // Log the end of this attempt (and any OS error it threw). | 525 // Log the end of this attempt (and any OS error it threw). |
| 529 int os_error = connect_os_error_; | 526 int os_error = connect_os_error_; |
| 530 connect_os_error_ = 0; | 527 connect_os_error_ = 0; |
| 531 scoped_refptr<NetLog::EventParameters> params; | 528 if (result != OK) { |
| 532 if (result != OK) | 529 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 533 params = new NetLogIntegerParameter("os_error", os_error); | 530 NetLog::IntegerCallback("os_error", os_error)); |
| 534 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); | 531 } else { |
| 532 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); |
| 533 } |
| 535 | 534 |
| 536 if (result == OK) { | 535 if (result == OK) { |
| 537 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; | 536 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; |
| 538 use_history_.set_was_ever_connected(); | 537 use_history_.set_was_ever_connected(); |
| 539 return OK; // Done! | 538 return OK; // Done! |
| 540 } | 539 } |
| 541 | 540 |
| 542 // Close whatever partially connected socket we currently have. | 541 // Close whatever partially connected socket we currently have. |
| 543 DoDisconnect(); | 542 DoDisconnect(); |
| 544 | 543 |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 use_history_.set_was_used_to_convey_data(); | 716 use_history_.set_was_used_to_convey_data(); |
| 718 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, | 717 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, |
| 719 core_->read_buffer_.buf); | 718 core_->read_buffer_.buf); |
| 720 return static_cast<int>(num); | 719 return static_cast<int>(num); |
| 721 } | 720 } |
| 722 } else { | 721 } else { |
| 723 int os_error = WSAGetLastError(); | 722 int os_error = WSAGetLastError(); |
| 724 if (os_error != WSA_IO_PENDING) { | 723 if (os_error != WSA_IO_PENDING) { |
| 725 int net_error = MapSystemError(os_error); | 724 int net_error = MapSystemError(os_error); |
| 726 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 725 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 727 make_scoped_refptr(new SocketErrorParams(net_error, os_error))); | 726 CreateNetLogSocketErrorCallback(net_error, os_error)); |
| 728 return net_error; | 727 return net_error; |
| 729 } | 728 } |
| 730 } | 729 } |
| 731 core_->WatchForRead(); | 730 core_->WatchForRead(); |
| 732 waiting_read_ = true; | 731 waiting_read_ = true; |
| 733 read_callback_ = callback; | 732 read_callback_ = callback; |
| 734 core_->read_iobuffer_ = buf; | 733 core_->read_iobuffer_ = buf; |
| 735 return ERR_IO_PENDING; | 734 return ERR_IO_PENDING; |
| 736 } | 735 } |
| 737 | 736 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 use_history_.set_was_used_to_convey_data(); | 772 use_history_.set_was_used_to_convey_data(); |
| 774 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, rv, | 773 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, rv, |
| 775 core_->write_buffer_.buf); | 774 core_->write_buffer_.buf); |
| 776 return rv; | 775 return rv; |
| 777 } | 776 } |
| 778 } else { | 777 } else { |
| 779 int os_error = WSAGetLastError(); | 778 int os_error = WSAGetLastError(); |
| 780 if (os_error != WSA_IO_PENDING) { | 779 if (os_error != WSA_IO_PENDING) { |
| 781 int net_error = MapSystemError(os_error); | 780 int net_error = MapSystemError(os_error); |
| 782 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 781 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
| 783 make_scoped_refptr(new SocketErrorParams(net_error, os_error))); | 782 CreateNetLogSocketErrorCallback(net_error, os_error)); |
| 784 return net_error; | 783 return net_error; |
| 785 } | 784 } |
| 786 } | 785 } |
| 787 core_->WatchForWrite(); | 786 core_->WatchForWrite(); |
| 788 waiting_write_ = true; | 787 waiting_write_ = true; |
| 789 write_callback_ = callback; | 788 write_callback_ = callback; |
| 790 core_->write_iobuffer_ = buf; | 789 core_->write_iobuffer_ = buf; |
| 791 return ERR_IO_PENDING; | 790 return ERR_IO_PENDING; |
| 792 } | 791 } |
| 793 | 792 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 823 int rv = getsockname( | 822 int rv = getsockname( |
| 824 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); | 823 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); |
| 825 if (rv != 0) { | 824 if (rv != 0) { |
| 826 LOG(ERROR) << "getsockname() [rv: " << rv | 825 LOG(ERROR) << "getsockname() [rv: " << rv |
| 827 << "] error: " << WSAGetLastError(); | 826 << "] error: " << WSAGetLastError(); |
| 828 NOTREACHED(); | 827 NOTREACHED(); |
| 829 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); | 828 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); |
| 830 return; | 829 return; |
| 831 } | 830 } |
| 832 | 831 |
| 833 const std::string source_address_str = | 832 net_log_.EndEvent( |
| 834 NetAddressToStringWithPort( | 833 NetLog::TYPE_TCP_CONNECT, |
| 834 CreateNetLogSourceAddressCallback( |
| 835 reinterpret_cast<const struct sockaddr*>(&source_address), | 835 reinterpret_cast<const struct sockaddr*>(&source_address), |
| 836 sizeof(source_address)); | 836 sizeof(source_address))); |
| 837 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | |
| 838 make_scoped_refptr(new NetLogStringParameter( | |
| 839 "source_address", | |
| 840 source_address_str))); | |
| 841 } | 837 } |
| 842 | 838 |
| 843 void TCPClientSocketWin::DoReadCallback(int rv) { | 839 void TCPClientSocketWin::DoReadCallback(int rv) { |
| 844 DCHECK_NE(rv, ERR_IO_PENDING); | 840 DCHECK_NE(rv, ERR_IO_PENDING); |
| 845 DCHECK(!read_callback_.is_null()); | 841 DCHECK(!read_callback_.is_null()); |
| 846 | 842 |
| 847 // Since Run may result in Read being called, clear read_callback_ up front. | 843 // Since Run may result in Read being called, clear read_callback_ up front. |
| 848 CompletionCallback c = read_callback_; | 844 CompletionCallback c = read_callback_; |
| 849 read_callback_.Reset(); | 845 read_callback_.Reset(); |
| 850 c.Run(rv); | 846 c.Run(rv); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 num_bytes_read_ += num_bytes; | 899 num_bytes_read_ += num_bytes; |
| 904 if (num_bytes > 0) | 900 if (num_bytes > 0) |
| 905 use_history_.set_was_used_to_convey_data(); | 901 use_history_.set_was_used_to_convey_data(); |
| 906 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 902 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
| 907 num_bytes, core_->read_buffer_.buf); | 903 num_bytes, core_->read_buffer_.buf); |
| 908 rv = static_cast<int>(num_bytes); | 904 rv = static_cast<int>(num_bytes); |
| 909 } else { | 905 } else { |
| 910 int os_error = WSAGetLastError(); | 906 int os_error = WSAGetLastError(); |
| 911 rv = MapSystemError(os_error); | 907 rv = MapSystemError(os_error); |
| 912 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 908 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 913 make_scoped_refptr(new SocketErrorParams(rv, os_error))); | 909 CreateNetLogSocketErrorCallback(rv, os_error)); |
| 914 } | 910 } |
| 915 DoReadCallback(rv); | 911 DoReadCallback(rv); |
| 916 } | 912 } |
| 917 | 913 |
| 918 void TCPClientSocketWin::DidCompleteWrite() { | 914 void TCPClientSocketWin::DidCompleteWrite() { |
| 919 DCHECK(waiting_write_); | 915 DCHECK(waiting_write_); |
| 920 | 916 |
| 921 DWORD num_bytes, flags; | 917 DWORD num_bytes, flags; |
| 922 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 918 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
| 923 &num_bytes, FALSE, &flags); | 919 &num_bytes, FALSE, &flags); |
| 924 WSAResetEvent(core_->write_overlapped_.hEvent); | 920 WSAResetEvent(core_->write_overlapped_.hEvent); |
| 925 waiting_write_ = false; | 921 waiting_write_ = false; |
| 926 int rv; | 922 int rv; |
| 927 if (!ok) { | 923 if (!ok) { |
| 928 int os_error = WSAGetLastError(); | 924 int os_error = WSAGetLastError(); |
| 929 rv = MapSystemError(os_error); | 925 rv = MapSystemError(os_error); |
| 930 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 926 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
| 931 make_scoped_refptr(new SocketErrorParams(rv, os_error))); | 927 CreateNetLogSocketErrorCallback(rv, os_error)); |
| 932 } else { | 928 } else { |
| 933 rv = static_cast<int>(num_bytes); | 929 rv = static_cast<int>(num_bytes); |
| 934 if (rv > core_->write_buffer_length_ || rv < 0) { | 930 if (rv > core_->write_buffer_length_ || rv < 0) { |
| 935 // It seems that some winsock interceptors report that more was written | 931 // It seems that some winsock interceptors report that more was written |
| 936 // than was available. Treat this as an error. http://crbug.com/27870 | 932 // than was available. Treat this as an error. http://crbug.com/27870 |
| 937 LOG(ERROR) << "Detected broken LSP: Asked to write " | 933 LOG(ERROR) << "Detected broken LSP: Asked to write " |
| 938 << core_->write_buffer_length_ << " bytes, but " << rv | 934 << core_->write_buffer_length_ << " bytes, but " << rv |
| 939 << " bytes reported."; | 935 << " bytes reported."; |
| 940 rv = ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; | 936 rv = ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; |
| 941 } else { | 937 } else { |
| 942 base::StatsCounter write_bytes("tcp.write_bytes"); | 938 base::StatsCounter write_bytes("tcp.write_bytes"); |
| 943 write_bytes.Add(num_bytes); | 939 write_bytes.Add(num_bytes); |
| 944 if (num_bytes > 0) | 940 if (num_bytes > 0) |
| 945 use_history_.set_was_used_to_convey_data(); | 941 use_history_.set_was_used_to_convey_data(); |
| 946 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, | 942 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, |
| 947 core_->write_buffer_.buf); | 943 core_->write_buffer_.buf); |
| 948 } | 944 } |
| 949 } | 945 } |
| 950 core_->write_iobuffer_ = NULL; | 946 core_->write_iobuffer_ = NULL; |
| 951 DoWriteCallback(rv); | 947 DoWriteCallback(rv); |
| 952 } | 948 } |
| 953 | 949 |
| 954 } // namespace net | 950 } // namespace net |
| OLD | NEW |