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 |