OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_socket_win.h" | 5 #include "net/socket/tcp_socket_win.h" |
6 | 6 |
7 #include <mstcpip.h> | 7 #include <mstcpip.h> |
8 | 8 |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "net/socket/socket_descriptor.h" | 22 #include "net/socket/socket_descriptor.h" |
23 #include "net/socket/socket_net_log_params.h" | 23 #include "net/socket/socket_net_log_params.h" |
24 | 24 |
25 namespace net { | 25 namespace net { |
26 | 26 |
27 namespace { | 27 namespace { |
28 | 28 |
29 const int kTCPKeepAliveSeconds = 45; | 29 const int kTCPKeepAliveSeconds = 45; |
30 | 30 |
31 int SetSocketReceiveBufferSize(SOCKET socket, int32 size) { | 31 int SetSocketReceiveBufferSize(SOCKET socket, int32 size) { |
32 int rv = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, | 32 int rv = setsockopt(socket, |
33 reinterpret_cast<const char*>(&size), sizeof(size)); | 33 SOL_SOCKET, |
| 34 SO_RCVBUF, |
| 35 reinterpret_cast<const char*>(&size), |
| 36 sizeof(size)); |
34 int net_error = (rv == 0) ? OK : MapSystemError(WSAGetLastError()); | 37 int net_error = (rv == 0) ? OK : MapSystemError(WSAGetLastError()); |
35 DCHECK(!rv) << "Could not set socket receive buffer size: " << net_error; | 38 DCHECK(!rv) << "Could not set socket receive buffer size: " << net_error; |
36 return net_error; | 39 return net_error; |
37 } | 40 } |
38 | 41 |
39 int SetSocketSendBufferSize(SOCKET socket, int32 size) { | 42 int SetSocketSendBufferSize(SOCKET socket, int32 size) { |
40 int rv = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, | 43 int rv = setsockopt(socket, |
41 reinterpret_cast<const char*>(&size), sizeof(size)); | 44 SOL_SOCKET, |
| 45 SO_SNDBUF, |
| 46 reinterpret_cast<const char*>(&size), |
| 47 sizeof(size)); |
42 int net_error = (rv == 0) ? OK : MapSystemError(WSAGetLastError()); | 48 int net_error = (rv == 0) ? OK : MapSystemError(WSAGetLastError()); |
43 DCHECK(!rv) << "Could not set socket send buffer size: " << net_error; | 49 DCHECK(!rv) << "Could not set socket send buffer size: " << net_error; |
44 return net_error; | 50 return net_error; |
45 } | 51 } |
46 | 52 |
47 // Disable Nagle. | 53 // Disable Nagle. |
48 // The Nagle implementation on windows is governed by RFC 896. The idea | 54 // The Nagle implementation on windows is governed by RFC 896. The idea |
49 // behind Nagle is to reduce small packets on the network. When Nagle is | 55 // behind Nagle is to reduce small packets on the network. When Nagle is |
50 // enabled, if a partial packet has been sent, the TCP stack will disallow | 56 // enabled, if a partial packet has been sent, the TCP stack will disallow |
51 // further *partial* packets until an ACK has been received from the other | 57 // further *partial* packets until an ACK has been received from the other |
52 // side. Good applications should always strive to send as much data as | 58 // side. Good applications should always strive to send as much data as |
53 // possible and avoid partial-packet sends. However, in most real world | 59 // possible and avoid partial-packet sends. However, in most real world |
54 // applications, there are edge cases where this does not happen, and two | 60 // applications, there are edge cases where this does not happen, and two |
55 // partial packets may be sent back to back. For a browser, it is NEVER | 61 // partial packets may be sent back to back. For a browser, it is NEVER |
56 // a benefit to delay for an RTT before the second packet is sent. | 62 // a benefit to delay for an RTT before the second packet is sent. |
57 // | 63 // |
58 // As a practical example in Chromium today, consider the case of a small | 64 // As a practical example in Chromium today, consider the case of a small |
59 // POST. I have verified this: | 65 // POST. I have verified this: |
60 // Client writes 649 bytes of header (partial packet #1) | 66 // Client writes 649 bytes of header (partial packet #1) |
61 // Client writes 50 bytes of POST data (partial packet #2) | 67 // Client writes 50 bytes of POST data (partial packet #2) |
62 // In the above example, with Nagle, a RTT delay is inserted between these | 68 // In the above example, with Nagle, a RTT delay is inserted between these |
63 // two sends due to nagle. RTTs can easily be 100ms or more. The best | 69 // two sends due to nagle. RTTs can easily be 100ms or more. The best |
64 // fix is to make sure that for POSTing data, we write as much data as | 70 // fix is to make sure that for POSTing data, we write as much data as |
65 // possible and minimize partial packets. We will fix that. But disabling | 71 // possible and minimize partial packets. We will fix that. But disabling |
66 // Nagle also ensure we don't run into this delay in other edge cases. | 72 // Nagle also ensure we don't run into this delay in other edge cases. |
67 // See also: | 73 // See also: |
68 // http://technet.microsoft.com/en-us/library/bb726981.aspx | 74 // http://technet.microsoft.com/en-us/library/bb726981.aspx |
69 bool DisableNagle(SOCKET socket, bool disable) { | 75 bool DisableNagle(SOCKET socket, bool disable) { |
70 BOOL val = disable ? TRUE : FALSE; | 76 BOOL val = disable ? TRUE : FALSE; |
71 int rv = setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, | 77 int rv = setsockopt(socket, |
| 78 IPPROTO_TCP, |
| 79 TCP_NODELAY, |
72 reinterpret_cast<const char*>(&val), | 80 reinterpret_cast<const char*>(&val), |
73 sizeof(val)); | 81 sizeof(val)); |
74 DCHECK(!rv) << "Could not disable nagle"; | 82 DCHECK(!rv) << "Could not disable nagle"; |
75 return rv == 0; | 83 return rv == 0; |
76 } | 84 } |
77 | 85 |
78 // Enable TCP Keep-Alive to prevent NAT routers from timing out TCP | 86 // Enable TCP Keep-Alive to prevent NAT routers from timing out TCP |
79 // connections. See http://crbug.com/27400 for details. | 87 // connections. See http://crbug.com/27400 for details. |
80 bool SetTCPKeepAlive(SOCKET socket, BOOL enable, int delay_secs) { | 88 bool SetTCPKeepAlive(SOCKET socket, BOOL enable, int delay_secs) { |
81 int delay = delay_secs * 1000; | 89 int delay = delay_secs * 1000; |
82 struct tcp_keepalive keepalive_vals = { | 90 struct tcp_keepalive keepalive_vals = { |
83 enable ? 1 : 0, // TCP keep-alive on. | 91 enable ? 1 : 0, // TCP keep-alive on. |
84 delay, // Delay seconds before sending first TCP keep-alive packet. | 92 delay, // Delay seconds before sending first TCP keep-alive packet. |
85 delay, // Delay seconds between sending TCP keep-alive packets. | 93 delay, // Delay seconds between sending TCP keep-alive packets. |
86 }; | 94 }; |
87 DWORD bytes_returned = 0xABAB; | 95 DWORD bytes_returned = 0xABAB; |
88 int rv = WSAIoctl(socket, SIO_KEEPALIVE_VALS, &keepalive_vals, | 96 int rv = WSAIoctl(socket, |
89 sizeof(keepalive_vals), NULL, 0, | 97 SIO_KEEPALIVE_VALS, |
90 &bytes_returned, NULL, NULL); | 98 &keepalive_vals, |
| 99 sizeof(keepalive_vals), |
| 100 NULL, |
| 101 0, |
| 102 &bytes_returned, |
| 103 NULL, |
| 104 NULL); |
91 DCHECK(!rv) << "Could not enable TCP Keep-Alive for socket: " << socket | 105 DCHECK(!rv) << "Could not enable TCP Keep-Alive for socket: " << socket |
92 << " [error: " << WSAGetLastError() << "]."; | 106 << " [error: " << WSAGetLastError() << "]."; |
93 | 107 |
94 // Disregard any failure in disabling nagle or enabling TCP Keep-Alive. | 108 // Disregard any failure in disabling nagle or enabling TCP Keep-Alive. |
95 return rv == 0; | 109 return rv == 0; |
96 } | 110 } |
97 | 111 |
98 int MapConnectError(int os_error) { | 112 int MapConnectError(int os_error) { |
99 switch (os_error) { | 113 switch (os_error) { |
100 // connect fails with WSAEACCES when Windows Firewall blocks the | 114 // connect fails with WSAEACCES when Windows Firewall blocks the |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 if (core_->socket_) { | 256 if (core_->socket_) { |
243 if (core_->socket_->waiting_connect_) | 257 if (core_->socket_->waiting_connect_) |
244 core_->socket_->DidCompleteConnect(); | 258 core_->socket_->DidCompleteConnect(); |
245 else | 259 else |
246 core_->socket_->DidSignalRead(); | 260 core_->socket_->DidSignalRead(); |
247 } | 261 } |
248 | 262 |
249 core_->Release(); | 263 core_->Release(); |
250 } | 264 } |
251 | 265 |
252 void TCPSocketWin::Core::WriteDelegate::OnObjectSignaled( | 266 void TCPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) { |
253 HANDLE object) { | |
254 DCHECK_EQ(object, core_->write_overlapped_.hEvent); | 267 DCHECK_EQ(object, core_->write_overlapped_.hEvent); |
255 if (core_->socket_) | 268 if (core_->socket_) |
256 core_->socket_->DidCompleteWrite(); | 269 core_->socket_->DidCompleteWrite(); |
257 | 270 |
258 core_->Release(); | 271 core_->Release(); |
259 } | 272 } |
260 | 273 |
261 //----------------------------------------------------------------------------- | 274 //----------------------------------------------------------------------------- |
262 | 275 |
263 TCPSocketWin::TCPSocketWin(net::NetLog* net_log, | 276 TCPSocketWin::TCPSocketWin(net::NetLog* net_log, |
(...skipping 15 matching lines...) Expand all Loading... |
279 | 292 |
280 TCPSocketWin::~TCPSocketWin() { | 293 TCPSocketWin::~TCPSocketWin() { |
281 Close(); | 294 Close(); |
282 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); | 295 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); |
283 } | 296 } |
284 | 297 |
285 int TCPSocketWin::Open(AddressFamily family) { | 298 int TCPSocketWin::Open(AddressFamily family) { |
286 DCHECK(CalledOnValidThread()); | 299 DCHECK(CalledOnValidThread()); |
287 DCHECK_EQ(socket_, INVALID_SOCKET); | 300 DCHECK_EQ(socket_, INVALID_SOCKET); |
288 | 301 |
289 socket_ = CreatePlatformSocket(ConvertAddressFamily(family), SOCK_STREAM, | 302 socket_ = CreatePlatformSocket( |
290 IPPROTO_TCP); | 303 ConvertAddressFamily(family), SOCK_STREAM, IPPROTO_TCP); |
291 if (socket_ == INVALID_SOCKET) { | 304 if (socket_ == INVALID_SOCKET) { |
292 PLOG(ERROR) << "CreatePlatformSocket() returned an error"; | 305 PLOG(ERROR) << "CreatePlatformSocket() returned an error"; |
293 return MapSystemError(WSAGetLastError()); | 306 return MapSystemError(WSAGetLastError()); |
294 } | 307 } |
295 | 308 |
296 if (SetNonBlocking(socket_)) { | 309 if (SetNonBlocking(socket_)) { |
297 int result = MapSystemError(WSAGetLastError()); | 310 int result = MapSystemError(WSAGetLastError()); |
298 Close(); | 311 Close(); |
299 return result; | 312 return result; |
300 } | 313 } |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 base::StatsCounter writes("tcp.writes"); | 517 base::StatsCounter writes("tcp.writes"); |
505 writes.Increment(); | 518 writes.Increment(); |
506 | 519 |
507 WSABUF write_buffer; | 520 WSABUF write_buffer; |
508 write_buffer.len = buf_len; | 521 write_buffer.len = buf_len; |
509 write_buffer.buf = buf->data(); | 522 write_buffer.buf = buf->data(); |
510 | 523 |
511 // TODO(wtc): Remove the assertion after enough testing. | 524 // TODO(wtc): Remove the assertion after enough testing. |
512 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 525 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
513 DWORD num; | 526 DWORD num; |
514 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, | 527 int rv = WSASend( |
515 &core_->write_overlapped_, NULL); | 528 socket_, &write_buffer, 1, &num, 0, &core_->write_overlapped_, NULL); |
516 if (rv == 0) { | 529 if (rv == 0) { |
517 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 530 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
518 rv = static_cast<int>(num); | 531 rv = static_cast<int>(num); |
519 if (rv > buf_len || rv < 0) { | 532 if (rv > buf_len || rv < 0) { |
520 // It seems that some winsock interceptors report that more was written | 533 // It seems that some winsock interceptors report that more was written |
521 // than was available. Treat this as an error. http://crbug.com/27870 | 534 // than was available. Treat this as an error. http://crbug.com/27870 |
522 LOG(ERROR) << "Detected broken LSP: Asked to write " << buf_len | 535 LOG(ERROR) << "Detected broken LSP: Asked to write " << buf_len |
523 << " bytes, but " << rv << " bytes reported."; | 536 << " bytes, but " << rv << " bytes reported."; |
524 return ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; | 537 return ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; |
525 } | 538 } |
526 base::StatsCounter write_bytes("tcp.write_bytes"); | 539 base::StatsCounter write_bytes("tcp.write_bytes"); |
527 write_bytes.Add(rv); | 540 write_bytes.Add(rv); |
528 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, rv, | 541 net_log_.AddByteTransferEvent( |
529 buf->data()); | 542 NetLog::TYPE_SOCKET_BYTES_SENT, rv, buf->data()); |
530 return rv; | 543 return rv; |
531 } | 544 } |
532 } else { | 545 } else { |
533 int os_error = WSAGetLastError(); | 546 int os_error = WSAGetLastError(); |
534 if (os_error != WSA_IO_PENDING) { | 547 if (os_error != WSA_IO_PENDING) { |
535 int net_error = MapSystemError(os_error); | 548 int net_error = MapSystemError(os_error); |
536 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 549 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
537 CreateNetLogSocketErrorCallback(net_error, os_error)); | 550 CreateNetLogSocketErrorCallback(net_error, os_error)); |
538 return net_error; | 551 return net_error; |
539 } | 552 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 // | 617 // |
605 // Unlike on *nix, on Windows a TCP server socket can always bind to an end | 618 // Unlike on *nix, on Windows a TCP server socket can always bind to an end |
606 // point in TIME_WAIT state without setting SO_REUSEADDR, therefore it is not | 619 // point in TIME_WAIT state without setting SO_REUSEADDR, therefore it is not |
607 // needed here. | 620 // needed here. |
608 // | 621 // |
609 // SO_EXCLUSIVEADDRUSE will prevent a TCP client socket from binding to an end | 622 // SO_EXCLUSIVEADDRUSE will prevent a TCP client socket from binding to an end |
610 // point in TIME_WAIT status. It does not have this effect for a TCP server | 623 // point in TIME_WAIT status. It does not have this effect for a TCP server |
611 // socket. | 624 // socket. |
612 | 625 |
613 BOOL true_value = 1; | 626 BOOL true_value = 1; |
614 int rv = setsockopt(socket_, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, | 627 int rv = setsockopt(socket_, |
| 628 SOL_SOCKET, |
| 629 SO_EXCLUSIVEADDRUSE, |
615 reinterpret_cast<const char*>(&true_value), | 630 reinterpret_cast<const char*>(&true_value), |
616 sizeof(true_value)); | 631 sizeof(true_value)); |
617 if (rv < 0) | 632 if (rv < 0) |
618 return MapSystemError(errno); | 633 return MapSystemError(errno); |
619 return OK; | 634 return OK; |
620 } | 635 } |
621 | 636 |
622 int TCPSocketWin::SetReceiveBufferSize(int32 size) { | 637 int TCPSocketWin::SetReceiveBufferSize(int32 size) { |
623 DCHECK(CalledOnValidThread()); | 638 DCHECK(CalledOnValidThread()); |
624 return SetSocketReceiveBufferSize(socket_, size); | 639 return SetSocketReceiveBufferSize(socket_, size); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 | 743 |
729 IPEndPoint ip_end_point; | 744 IPEndPoint ip_end_point; |
730 if (!ip_end_point.FromSockAddr(storage.addr, storage.addr_len)) { | 745 if (!ip_end_point.FromSockAddr(storage.addr, storage.addr_len)) { |
731 NOTREACHED(); | 746 NOTREACHED(); |
732 if (closesocket(new_socket) < 0) | 747 if (closesocket(new_socket) < 0) |
733 PLOG(ERROR) << "closesocket"; | 748 PLOG(ERROR) << "closesocket"; |
734 int net_error = ERR_ADDRESS_INVALID; | 749 int net_error = ERR_ADDRESS_INVALID; |
735 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, net_error); | 750 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, net_error); |
736 return net_error; | 751 return net_error; |
737 } | 752 } |
738 scoped_ptr<TCPSocketWin> tcp_socket(new TCPSocketWin( | 753 scoped_ptr<TCPSocketWin> tcp_socket( |
739 net_log_.net_log(), net_log_.source())); | 754 new TCPSocketWin(net_log_.net_log(), net_log_.source())); |
740 int adopt_result = tcp_socket->AdoptConnectedSocket(new_socket, ip_end_point); | 755 int adopt_result = tcp_socket->AdoptConnectedSocket(new_socket, ip_end_point); |
741 if (adopt_result != OK) { | 756 if (adopt_result != OK) { |
742 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, adopt_result); | 757 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, adopt_result); |
743 return adopt_result; | 758 return adopt_result; |
744 } | 759 } |
745 *socket = tcp_socket.Pass(); | 760 *socket = tcp_socket.Pass(); |
746 *address = ip_end_point; | 761 *address = ip_end_point; |
747 net_log_.EndEvent(NetLog::TYPE_TCP_ACCEPT, | 762 net_log_.EndEvent(NetLog::TYPE_TCP_ACCEPT, |
748 CreateNetLogIPEndPointCallback(&ip_end_point)); | 763 CreateNetLogIPEndPointCallback(&ip_end_point)); |
749 return OK; | 764 return OK; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 return; | 878 return; |
864 } | 879 } |
865 | 880 |
866 net_log_.EndEvent( | 881 net_log_.EndEvent( |
867 NetLog::TYPE_TCP_CONNECT, | 882 NetLog::TYPE_TCP_CONNECT, |
868 CreateNetLogSourceAddressCallback( | 883 CreateNetLogSourceAddressCallback( |
869 reinterpret_cast<const struct sockaddr*>(&source_address), | 884 reinterpret_cast<const struct sockaddr*>(&source_address), |
870 sizeof(source_address))); | 885 sizeof(source_address))); |
871 } | 886 } |
872 | 887 |
873 int TCPSocketWin::DoRead(IOBuffer* buf, int buf_len, | 888 int TCPSocketWin::DoRead(IOBuffer* buf, |
| 889 int buf_len, |
874 const CompletionCallback& callback) { | 890 const CompletionCallback& callback) { |
875 if (!core_->non_blocking_reads_initialized_) { | 891 if (!core_->non_blocking_reads_initialized_) { |
876 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, | 892 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_READ | FD_CLOSE); |
877 FD_READ | FD_CLOSE); | |
878 core_->non_blocking_reads_initialized_ = true; | 893 core_->non_blocking_reads_initialized_ = true; |
879 } | 894 } |
880 int rv = recv(socket_, buf->data(), buf_len, 0); | 895 int rv = recv(socket_, buf->data(), buf_len, 0); |
881 if (rv == SOCKET_ERROR) { | 896 if (rv == SOCKET_ERROR) { |
882 int os_error = WSAGetLastError(); | 897 int os_error = WSAGetLastError(); |
883 if (os_error != WSAEWOULDBLOCK) { | 898 if (os_error != WSAEWOULDBLOCK) { |
884 int net_error = MapSystemError(os_error); | 899 int net_error = MapSystemError(os_error); |
885 net_log_.AddEvent( | 900 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
886 NetLog::TYPE_SOCKET_READ_ERROR, | 901 CreateNetLogSocketErrorCallback(net_error, os_error)); |
887 CreateNetLogSocketErrorCallback(net_error, os_error)); | |
888 return net_error; | 902 return net_error; |
889 } | 903 } |
890 } else { | 904 } else { |
891 base::StatsCounter read_bytes("tcp.read_bytes"); | 905 base::StatsCounter read_bytes("tcp.read_bytes"); |
892 if (rv > 0) | 906 if (rv > 0) |
893 read_bytes.Add(rv); | 907 read_bytes.Add(rv); |
894 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, | 908 net_log_.AddByteTransferEvent( |
895 buf->data()); | 909 NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, buf->data()); |
896 return rv; | 910 return rv; |
897 } | 911 } |
898 | 912 |
899 waiting_read_ = true; | 913 waiting_read_ = true; |
900 read_callback_ = callback; | 914 read_callback_ = callback; |
901 core_->read_iobuffer_ = buf; | 915 core_->read_iobuffer_ = buf; |
902 core_->read_buffer_length_ = buf_len; | 916 core_->read_buffer_length_ = buf_len; |
903 core_->WatchForRead(); | 917 core_->WatchForRead(); |
904 return ERR_IO_PENDING; | 918 return ERR_IO_PENDING; |
905 } | 919 } |
906 | 920 |
907 void TCPSocketWin::DidCompleteConnect() { | 921 void TCPSocketWin::DidCompleteConnect() { |
908 DCHECK(waiting_connect_); | 922 DCHECK(waiting_connect_); |
909 DCHECK(!read_callback_.is_null()); | 923 DCHECK(!read_callback_.is_null()); |
910 int result; | 924 int result; |
911 | 925 |
912 WSANETWORKEVENTS events; | 926 WSANETWORKEVENTS events; |
913 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | 927 int rv = |
914 &events); | 928 WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, &events); |
915 int os_error = 0; | 929 int os_error = 0; |
916 if (rv == SOCKET_ERROR) { | 930 if (rv == SOCKET_ERROR) { |
917 NOTREACHED(); | 931 NOTREACHED(); |
918 os_error = WSAGetLastError(); | 932 os_error = WSAGetLastError(); |
919 result = MapSystemError(os_error); | 933 result = MapSystemError(os_error); |
920 } else if (events.lNetworkEvents & FD_CONNECT) { | 934 } else if (events.lNetworkEvents & FD_CONNECT) { |
921 os_error = events.iErrorCode[FD_CONNECT_BIT]; | 935 os_error = events.iErrorCode[FD_CONNECT_BIT]; |
922 result = MapConnectError(os_error); | 936 result = MapConnectError(os_error); |
923 } else { | 937 } else { |
924 NOTREACHED(); | 938 NOTREACHED(); |
925 result = ERR_UNEXPECTED; | 939 result = ERR_UNEXPECTED; |
926 } | 940 } |
927 | 941 |
928 connect_os_error_ = os_error; | 942 connect_os_error_ = os_error; |
929 DoConnectComplete(result); | 943 DoConnectComplete(result); |
930 waiting_connect_ = false; | 944 waiting_connect_ = false; |
931 | 945 |
932 DCHECK_NE(result, ERR_IO_PENDING); | 946 DCHECK_NE(result, ERR_IO_PENDING); |
933 base::ResetAndReturn(&read_callback_).Run(result); | 947 base::ResetAndReturn(&read_callback_).Run(result); |
934 } | 948 } |
935 | 949 |
936 void TCPSocketWin::DidCompleteWrite() { | 950 void TCPSocketWin::DidCompleteWrite() { |
937 DCHECK(waiting_write_); | 951 DCHECK(waiting_write_); |
938 DCHECK(!write_callback_.is_null()); | 952 DCHECK(!write_callback_.is_null()); |
939 | 953 |
940 DWORD num_bytes, flags; | 954 DWORD num_bytes, flags; |
941 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 955 BOOL ok = WSAGetOverlappedResult( |
942 &num_bytes, FALSE, &flags); | 956 socket_, &core_->write_overlapped_, &num_bytes, FALSE, &flags); |
943 WSAResetEvent(core_->write_overlapped_.hEvent); | 957 WSAResetEvent(core_->write_overlapped_.hEvent); |
944 waiting_write_ = false; | 958 waiting_write_ = false; |
945 int rv; | 959 int rv; |
946 if (!ok) { | 960 if (!ok) { |
947 int os_error = WSAGetLastError(); | 961 int os_error = WSAGetLastError(); |
948 rv = MapSystemError(os_error); | 962 rv = MapSystemError(os_error); |
949 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 963 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
950 CreateNetLogSocketErrorCallback(rv, os_error)); | 964 CreateNetLogSocketErrorCallback(rv, os_error)); |
951 } else { | 965 } else { |
952 rv = static_cast<int>(num_bytes); | 966 rv = static_cast<int>(num_bytes); |
953 if (rv > core_->write_buffer_length_ || rv < 0) { | 967 if (rv > core_->write_buffer_length_ || rv < 0) { |
954 // It seems that some winsock interceptors report that more was written | 968 // It seems that some winsock interceptors report that more was written |
955 // than was available. Treat this as an error. http://crbug.com/27870 | 969 // than was available. Treat this as an error. http://crbug.com/27870 |
956 LOG(ERROR) << "Detected broken LSP: Asked to write " | 970 LOG(ERROR) << "Detected broken LSP: Asked to write " |
957 << core_->write_buffer_length_ << " bytes, but " << rv | 971 << core_->write_buffer_length_ << " bytes, but " << rv |
958 << " bytes reported."; | 972 << " bytes reported."; |
959 rv = ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; | 973 rv = ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; |
960 } else { | 974 } else { |
961 base::StatsCounter write_bytes("tcp.write_bytes"); | 975 base::StatsCounter write_bytes("tcp.write_bytes"); |
962 write_bytes.Add(num_bytes); | 976 write_bytes.Add(num_bytes); |
963 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes, | 977 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, |
| 978 num_bytes, |
964 core_->write_iobuffer_->data()); | 979 core_->write_iobuffer_->data()); |
965 } | 980 } |
966 } | 981 } |
967 | 982 |
968 core_->write_iobuffer_ = NULL; | 983 core_->write_iobuffer_ = NULL; |
969 | 984 |
970 DCHECK_NE(rv, ERR_IO_PENDING); | 985 DCHECK_NE(rv, ERR_IO_PENDING); |
971 base::ResetAndReturn(&write_callback_).Run(rv); | 986 base::ResetAndReturn(&write_callback_).Run(rv); |
972 } | 987 } |
973 | 988 |
974 void TCPSocketWin::DidSignalRead() { | 989 void TCPSocketWin::DidSignalRead() { |
975 DCHECK(waiting_read_); | 990 DCHECK(waiting_read_); |
976 DCHECK(!read_callback_.is_null()); | 991 DCHECK(!read_callback_.is_null()); |
977 | 992 |
978 int os_error = 0; | 993 int os_error = 0; |
979 WSANETWORKEVENTS network_events; | 994 WSANETWORKEVENTS network_events; |
980 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | 995 int rv = WSAEnumNetworkEvents( |
981 &network_events); | 996 socket_, core_->read_overlapped_.hEvent, &network_events); |
982 if (rv == SOCKET_ERROR) { | 997 if (rv == SOCKET_ERROR) { |
983 os_error = WSAGetLastError(); | 998 os_error = WSAGetLastError(); |
984 rv = MapSystemError(os_error); | 999 rv = MapSystemError(os_error); |
985 } else if (network_events.lNetworkEvents) { | 1000 } else if (network_events.lNetworkEvents) { |
986 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); | 1001 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); |
987 // If network_events.lNetworkEvents is FD_CLOSE and | 1002 // If network_events.lNetworkEvents is FD_CLOSE and |
988 // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful | 1003 // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful |
989 // connection closure. It is tempting to directly set rv to 0 in | 1004 // connection closure. It is tempting to directly set rv to 0 in |
990 // this case, but the MSDN pages for WSAEventSelect and | 1005 // this case, but the MSDN pages for WSAEventSelect and |
991 // WSAAsyncSelect recommend we still call DoRead(): | 1006 // WSAAsyncSelect recommend we still call DoRead(): |
992 // FD_CLOSE should only be posted after all data is read from a | 1007 // FD_CLOSE should only be posted after all data is read from a |
993 // socket, but an application should check for remaining data upon | 1008 // socket, but an application should check for remaining data upon |
994 // receipt of FD_CLOSE to avoid any possibility of losing data. | 1009 // receipt of FD_CLOSE to avoid any possibility of losing data. |
995 // | 1010 // |
996 // If network_events.iErrorCode[FD_READ_BIT] or | 1011 // If network_events.iErrorCode[FD_READ_BIT] or |
997 // network_events.iErrorCode[FD_CLOSE_BIT] is nonzero, still call | 1012 // network_events.iErrorCode[FD_CLOSE_BIT] is nonzero, still call |
998 // DoRead() because recv() reports a more accurate error code | 1013 // DoRead() because recv() reports a more accurate error code |
999 // (WSAECONNRESET vs. WSAECONNABORTED) when the connection was | 1014 // (WSAECONNRESET vs. WSAECONNABORTED) when the connection was |
1000 // reset. | 1015 // reset. |
1001 rv = DoRead(core_->read_iobuffer_, core_->read_buffer_length_, | 1016 rv = DoRead( |
1002 read_callback_); | 1017 core_->read_iobuffer_, core_->read_buffer_length_, read_callback_); |
1003 if (rv == ERR_IO_PENDING) | 1018 if (rv == ERR_IO_PENDING) |
1004 return; | 1019 return; |
1005 } else { | 1020 } else { |
1006 // This may happen because Read() may succeed synchronously and | 1021 // This may happen because Read() may succeed synchronously and |
1007 // consume all the received data without resetting the event object. | 1022 // consume all the received data without resetting the event object. |
1008 core_->WatchForRead(); | 1023 core_->WatchForRead(); |
1009 return; | 1024 return; |
1010 } | 1025 } |
1011 | 1026 |
1012 waiting_read_ = false; | 1027 waiting_read_ = false; |
1013 core_->read_iobuffer_ = NULL; | 1028 core_->read_iobuffer_ = NULL; |
1014 core_->read_buffer_length_ = 0; | 1029 core_->read_buffer_length_ = 0; |
1015 | 1030 |
1016 DCHECK_NE(rv, ERR_IO_PENDING); | 1031 DCHECK_NE(rv, ERR_IO_PENDING); |
1017 base::ResetAndReturn(&read_callback_).Run(rv); | 1032 base::ResetAndReturn(&read_callback_).Run(rv); |
1018 } | 1033 } |
1019 | 1034 |
1020 } // namespace net | 1035 } // namespace net |
1021 | |
OLD | NEW |