| 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 |