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 |