| 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" |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 const net::NetLog::Source& source) | 336 const net::NetLog::Source& source) |
| 337 : socket_(INVALID_SOCKET), | 337 : socket_(INVALID_SOCKET), |
| 338 bound_socket_(INVALID_SOCKET), | 338 bound_socket_(INVALID_SOCKET), |
| 339 addresses_(addresses), | 339 addresses_(addresses), |
| 340 current_address_index_(-1), | 340 current_address_index_(-1), |
| 341 waiting_read_(false), | 341 waiting_read_(false), |
| 342 waiting_write_(false), | 342 waiting_write_(false), |
| 343 next_connect_state_(CONNECT_STATE_NONE), | 343 next_connect_state_(CONNECT_STATE_NONE), |
| 344 connect_os_error_(0), | 344 connect_os_error_(0), |
| 345 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 345 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
| 346 previously_disconnected_(false), | 346 previously_disconnected_(false) { |
| 347 num_bytes_read_(0) { | |
| 348 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 347 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
| 349 source.ToEventParametersCallback()); | 348 source.ToEventParametersCallback()); |
| 350 EnsureWinsockInit(); | 349 EnsureWinsockInit(); |
| 351 } | 350 } |
| 352 | 351 |
| 353 TCPClientSocketWin::~TCPClientSocketWin() { | 352 TCPClientSocketWin::~TCPClientSocketWin() { |
| 354 Disconnect(); | 353 Disconnect(); |
| 355 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); | 354 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); |
| 356 } | 355 } |
| 357 | 356 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 | 493 |
| 495 DCHECK(!core_); | 494 DCHECK(!core_); |
| 496 core_ = new Core(this); | 495 core_ = new Core(this); |
| 497 // WSAEventSelect sets the socket to non-blocking mode as a side effect. | 496 // WSAEventSelect sets the socket to non-blocking mode as a side effect. |
| 498 // Our connect() and recv() calls require that the socket be non-blocking. | 497 // Our connect() and recv() calls require that the socket be non-blocking. |
| 499 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); | 498 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); |
| 500 | 499 |
| 501 SockaddrStorage storage; | 500 SockaddrStorage storage; |
| 502 if (!endpoint.ToSockAddr(storage.addr, &storage.addr_len)) | 501 if (!endpoint.ToSockAddr(storage.addr, &storage.addr_len)) |
| 503 return ERR_INVALID_ARGUMENT; | 502 return ERR_INVALID_ARGUMENT; |
| 504 connect_start_time_ = base::TimeTicks::Now(); | |
| 505 if (!connect(socket_, storage.addr, storage.addr_len)) { | 503 if (!connect(socket_, storage.addr, storage.addr_len)) { |
| 506 // Connected without waiting! | 504 // Connected without waiting! |
| 507 // | 505 // |
| 508 // The MSDN page for connect says: | 506 // The MSDN page for connect says: |
| 509 // With a nonblocking socket, the connection attempt cannot be completed | 507 // With a nonblocking socket, the connection attempt cannot be completed |
| 510 // immediately. In this case, connect will return SOCKET_ERROR, and | 508 // immediately. In this case, connect will return SOCKET_ERROR, and |
| 511 // WSAGetLastError will return WSAEWOULDBLOCK. | 509 // WSAGetLastError will return WSAEWOULDBLOCK. |
| 512 // which implies that for a nonblocking socket, connect never returns 0. | 510 // which implies that for a nonblocking socket, connect never returns 0. |
| 513 // It's not documented whether the event object will be signaled or not | 511 // It's not documented whether the event object will be signaled or not |
| 514 // if connect does return 0. So the code below is essentially dead code | 512 // if connect does return 0. So the code below is essentially dead code |
| (...skipping 20 matching lines...) Expand all Loading... |
| 535 int os_error = connect_os_error_; | 533 int os_error = connect_os_error_; |
| 536 connect_os_error_ = 0; | 534 connect_os_error_ = 0; |
| 537 if (result != OK) { | 535 if (result != OK) { |
| 538 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 536 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 539 NetLog::IntegerCallback("os_error", os_error)); | 537 NetLog::IntegerCallback("os_error", os_error)); |
| 540 } else { | 538 } else { |
| 541 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); | 539 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); |
| 542 } | 540 } |
| 543 | 541 |
| 544 if (result == OK) { | 542 if (result == OK) { |
| 545 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; | |
| 546 use_history_.set_was_ever_connected(); | 543 use_history_.set_was_ever_connected(); |
| 547 return OK; // Done! | 544 return OK; // Done! |
| 548 } | 545 } |
| 549 | 546 |
| 550 // Close whatever partially connected socket we currently have. | 547 // Close whatever partially connected socket we currently have. |
| 551 DoDisconnect(); | 548 DoDisconnect(); |
| 552 | 549 |
| 553 // Try to fall back to the next address in the list. | 550 // Try to fall back to the next address in the list. |
| 554 if (current_address_index_ + 1 < static_cast<int>(addresses_.size())) { | 551 if (current_address_index_ + 1 < static_cast<int>(addresses_.size())) { |
| 555 next_connect_state_ = CONNECT_STATE_CONNECT; | 552 next_connect_state_ = CONNECT_STATE_CONNECT; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 | 683 |
| 687 bool TCPClientSocketWin::WasEverUsed() const { | 684 bool TCPClientSocketWin::WasEverUsed() const { |
| 688 return use_history_.was_used_to_convey_data(); | 685 return use_history_.was_used_to_convey_data(); |
| 689 } | 686 } |
| 690 | 687 |
| 691 bool TCPClientSocketWin::UsingTCPFastOpen() const { | 688 bool TCPClientSocketWin::UsingTCPFastOpen() const { |
| 692 // Not supported on windows. | 689 // Not supported on windows. |
| 693 return false; | 690 return false; |
| 694 } | 691 } |
| 695 | 692 |
| 696 int64 TCPClientSocketWin::NumBytesRead() const { | |
| 697 return num_bytes_read_; | |
| 698 } | |
| 699 | |
| 700 base::TimeDelta TCPClientSocketWin::GetConnectTimeMicros() const { | |
| 701 return connect_time_micros_; | |
| 702 } | |
| 703 | |
| 704 bool TCPClientSocketWin::WasNpnNegotiated() const { | 693 bool TCPClientSocketWin::WasNpnNegotiated() const { |
| 705 return false; | 694 return false; |
| 706 } | 695 } |
| 707 | 696 |
| 708 NextProto TCPClientSocketWin::GetNegotiatedProtocol() const { | 697 NextProto TCPClientSocketWin::GetNegotiatedProtocol() const { |
| 709 return kProtoUnknown; | 698 return kProtoUnknown; |
| 710 } | 699 } |
| 711 | 700 |
| 712 bool TCPClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { | 701 bool TCPClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { |
| 713 return false; | 702 return false; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 int net_error = MapSystemError(os_error); | 836 int net_error = MapSystemError(os_error); |
| 848 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 837 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 849 CreateNetLogSocketErrorCallback(net_error, os_error)); | 838 CreateNetLogSocketErrorCallback(net_error, os_error)); |
| 850 return net_error; | 839 return net_error; |
| 851 } | 840 } |
| 852 } else { | 841 } else { |
| 853 base::StatsCounter read_bytes("tcp.read_bytes"); | 842 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 854 if (rv > 0) { | 843 if (rv > 0) { |
| 855 use_history_.set_was_used_to_convey_data(); | 844 use_history_.set_was_used_to_convey_data(); |
| 856 read_bytes.Add(rv); | 845 read_bytes.Add(rv); |
| 857 num_bytes_read_ += rv; | |
| 858 } | 846 } |
| 859 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, | 847 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, |
| 860 buf->data()); | 848 buf->data()); |
| 861 return rv; | 849 return rv; |
| 862 } | 850 } |
| 863 } else { | 851 } else { |
| 864 buf_len = core_->ThrottleReadSize(buf_len); | 852 buf_len = core_->ThrottleReadSize(buf_len); |
| 865 | 853 |
| 866 WSABUF read_buffer; | 854 WSABUF read_buffer; |
| 867 read_buffer.len = buf_len; | 855 read_buffer.len = buf_len; |
| 868 read_buffer.buf = buf->data(); | 856 read_buffer.buf = buf->data(); |
| 869 | 857 |
| 870 // TODO(wtc): Remove the assertion after enough testing. | 858 // TODO(wtc): Remove the assertion after enough testing. |
| 871 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | 859 AssertEventNotSignaled(core_->read_overlapped_.hEvent); |
| 872 DWORD num; | 860 DWORD num; |
| 873 DWORD flags = 0; | 861 DWORD flags = 0; |
| 874 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags, | 862 int rv = WSARecv(socket_, &read_buffer, 1, &num, &flags, |
| 875 &core_->read_overlapped_, NULL); | 863 &core_->read_overlapped_, NULL); |
| 876 if (rv == 0) { | 864 if (rv == 0) { |
| 877 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | 865 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
| 878 base::StatsCounter read_bytes("tcp.read_bytes"); | 866 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 879 if (num > 0) { | 867 if (num > 0) { |
| 880 use_history_.set_was_used_to_convey_data(); | 868 use_history_.set_was_used_to_convey_data(); |
| 881 read_bytes.Add(num); | 869 read_bytes.Add(num); |
| 882 num_bytes_read_ += num; | |
| 883 } | 870 } |
| 884 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, | 871 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, num, |
| 885 buf->data()); | 872 buf->data()); |
| 886 return static_cast<int>(num); | 873 return static_cast<int>(num); |
| 887 } | 874 } |
| 888 } else { | 875 } else { |
| 889 int os_error = WSAGetLastError(); | 876 int os_error = WSAGetLastError(); |
| 890 if (os_error != WSA_IO_PENDING) { | 877 if (os_error != WSA_IO_PENDING) { |
| 891 int net_error = MapSystemError(os_error); | 878 int net_error = MapSystemError(os_error); |
| 892 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 879 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 void TCPClientSocketWin::DidCompleteRead() { | 942 void TCPClientSocketWin::DidCompleteRead() { |
| 956 DCHECK(waiting_read_); | 943 DCHECK(waiting_read_); |
| 957 DWORD num_bytes, flags; | 944 DWORD num_bytes, flags; |
| 958 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, | 945 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, |
| 959 &num_bytes, FALSE, &flags); | 946 &num_bytes, FALSE, &flags); |
| 960 waiting_read_ = false; | 947 waiting_read_ = false; |
| 961 int rv; | 948 int rv; |
| 962 if (ok) { | 949 if (ok) { |
| 963 base::StatsCounter read_bytes("tcp.read_bytes"); | 950 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 964 read_bytes.Add(num_bytes); | 951 read_bytes.Add(num_bytes); |
| 965 num_bytes_read_ += num_bytes; | |
| 966 if (num_bytes > 0) | 952 if (num_bytes > 0) |
| 967 use_history_.set_was_used_to_convey_data(); | 953 use_history_.set_was_used_to_convey_data(); |
| 968 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, | 954 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, |
| 969 num_bytes, core_->read_iobuffer_->data()); | 955 num_bytes, core_->read_iobuffer_->data()); |
| 970 rv = static_cast<int>(num_bytes); | 956 rv = static_cast<int>(num_bytes); |
| 971 } else { | 957 } else { |
| 972 int os_error = WSAGetLastError(); | 958 int os_error = WSAGetLastError(); |
| 973 rv = MapSystemError(os_error); | 959 rv = MapSystemError(os_error); |
| 974 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 960 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 975 CreateNetLogSocketErrorCallback(rv, os_error)); | 961 CreateNetLogSocketErrorCallback(rv, os_error)); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 core_->WatchForRead(); | 1037 core_->WatchForRead(); |
| 1052 return; | 1038 return; |
| 1053 } | 1039 } |
| 1054 waiting_read_ = false; | 1040 waiting_read_ = false; |
| 1055 core_->read_iobuffer_ = NULL; | 1041 core_->read_iobuffer_ = NULL; |
| 1056 core_->read_buffer_length_ = 0; | 1042 core_->read_buffer_length_ = 0; |
| 1057 DoReadCallback(rv); | 1043 DoReadCallback(rv); |
| 1058 } | 1044 } |
| 1059 | 1045 |
| 1060 } // namespace net | 1046 } // namespace net |
| OLD | NEW |