| 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.h" | 5 #include "net/socket/tcp_socket.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <netinet/tcp.h> | 8 #include <netinet/tcp.h> |
| 9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/posix/eintr_wrapper.h" | 16 #include "base/posix/eintr_wrapper.h" |
| 17 #include "base/task_runner_util.h" | 17 #include "base/task_runner_util.h" |
| 18 #include "base/threading/worker_pool.h" | 18 #include "base/threading/worker_pool.h" |
| 19 #include "base/time/default_tick_clock.h" | 19 #include "base/time/time.h" |
| 20 #include "net/base/address_list.h" | 20 #include "net/base/address_list.h" |
| 21 #include "net/base/io_buffer.h" | 21 #include "net/base/io_buffer.h" |
| 22 #include "net/base/ip_endpoint.h" | 22 #include "net/base/ip_endpoint.h" |
| 23 #include "net/base/net_errors.h" | 23 #include "net/base/net_errors.h" |
| 24 #include "net/base/network_activity_monitor.h" | 24 #include "net/base/network_activity_monitor.h" |
| 25 #include "net/base/network_change_notifier.h" | 25 #include "net/base/network_change_notifier.h" |
| 26 #include "net/base/sockaddr_storage.h" | 26 #include "net/base/sockaddr_storage.h" |
| 27 #include "net/log/net_log.h" | 27 #include "net/log/net_log.h" |
| 28 #include "net/log/net_log_event_type.h" | 28 #include "net/log/net_log_event_type.h" |
| 29 #include "net/log/net_log_source.h" | 29 #include "net/log/net_log_source.h" |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 base::Bind(SystemSupportsTCPFastOpen), | 138 base::Bind(SystemSupportsTCPFastOpen), |
| 139 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); | 139 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); |
| 140 #endif | 140 #endif |
| 141 } | 141 } |
| 142 | 142 |
| 143 TCPSocketPosix::TCPSocketPosix( | 143 TCPSocketPosix::TCPSocketPosix( |
| 144 std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher, | 144 std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher, |
| 145 NetLog* net_log, | 145 NetLog* net_log, |
| 146 const NetLogSource& source) | 146 const NetLogSource& source) |
| 147 : socket_performance_watcher_(std::move(socket_performance_watcher)), | 147 : socket_performance_watcher_(std::move(socket_performance_watcher)), |
| 148 tick_clock_(new base::DefaultTickClock()), | |
| 149 rtt_notifications_minimum_interval_(base::TimeDelta::FromSeconds(1)), | |
| 150 use_tcp_fastopen_(false), | 148 use_tcp_fastopen_(false), |
| 151 tcp_fastopen_write_attempted_(false), | 149 tcp_fastopen_write_attempted_(false), |
| 152 tcp_fastopen_connected_(false), | 150 tcp_fastopen_connected_(false), |
| 153 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), | 151 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), |
| 154 logging_multiple_connect_attempts_(false), | 152 logging_multiple_connect_attempts_(false), |
| 155 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)) { | 153 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)) { |
| 156 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, | 154 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, |
| 157 source.ToEventParametersCallback()); | 155 source.ToEventParametersCallback()); |
| 158 } | 156 } |
| 159 | 157 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 | 475 |
| 478 void TCPSocketPosix::EndLoggingMultipleConnectAttempts(int net_error) { | 476 void TCPSocketPosix::EndLoggingMultipleConnectAttempts(int net_error) { |
| 479 if (logging_multiple_connect_attempts_) { | 477 if (logging_multiple_connect_attempts_) { |
| 480 LogConnectEnd(net_error); | 478 LogConnectEnd(net_error); |
| 481 logging_multiple_connect_attempts_ = false; | 479 logging_multiple_connect_attempts_ = false; |
| 482 } else { | 480 } else { |
| 483 NOTREACHED(); | 481 NOTREACHED(); |
| 484 } | 482 } |
| 485 } | 483 } |
| 486 | 484 |
| 487 void TCPSocketPosix::SetTickClockForTesting( | |
| 488 std::unique_ptr<base::TickClock> tick_clock) { | |
| 489 tick_clock_ = std::move(tick_clock); | |
| 490 } | |
| 491 | |
| 492 void TCPSocketPosix::AcceptCompleted( | 485 void TCPSocketPosix::AcceptCompleted( |
| 493 std::unique_ptr<TCPSocketPosix>* tcp_socket, | 486 std::unique_ptr<TCPSocketPosix>* tcp_socket, |
| 494 IPEndPoint* address, | 487 IPEndPoint* address, |
| 495 const CompletionCallback& callback, | 488 const CompletionCallback& callback, |
| 496 int rv) { | 489 int rv) { |
| 497 DCHECK_NE(ERR_IO_PENDING, rv); | 490 DCHECK_NE(ERR_IO_PENDING, rv); |
| 498 callback.Run(HandleAcceptCompleted(tcp_socket, address, rv)); | 491 callback.Run(HandleAcceptCompleted(tcp_socket, address, rv)); |
| 499 } | 492 } |
| 500 | 493 |
| 501 int TCPSocketPosix::HandleAcceptCompleted( | 494 int TCPSocketPosix::HandleAcceptCompleted( |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 g_tcp_fastopen_has_failed = true; | 710 g_tcp_fastopen_has_failed = true; |
| 718 return rv; | 711 return rv; |
| 719 } | 712 } |
| 720 | 713 |
| 721 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; | 714 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; |
| 722 return socket_->WaitForWrite(buf, buf_len, callback); | 715 return socket_->WaitForWrite(buf, buf_len, callback); |
| 723 } | 716 } |
| 724 | 717 |
| 725 void TCPSocketPosix::NotifySocketPerformanceWatcher() { | 718 void TCPSocketPosix::NotifySocketPerformanceWatcher() { |
| 726 #if defined(TCP_INFO) | 719 #if defined(TCP_INFO) |
| 727 const base::TimeTicks now_ticks = tick_clock_->NowTicks(); | |
| 728 // Do not notify |socket_performance_watcher_| if the last notification was | |
| 729 // recent than |rtt_notifications_minimum_interval_| ago. This helps in | |
| 730 // reducing the overall overhead of the tcp_info syscalls. | |
| 731 if (now_ticks - last_rtt_notification_ < rtt_notifications_minimum_interval_) | |
| 732 return; | |
| 733 | |
| 734 // Check if |socket_performance_watcher_| is interested in receiving a RTT | 720 // Check if |socket_performance_watcher_| is interested in receiving a RTT |
| 735 // update notification. | 721 // update notification. |
| 736 if (!socket_performance_watcher_ || | 722 if (!socket_performance_watcher_ || |
| 737 !socket_performance_watcher_->ShouldNotifyUpdatedRTT()) { | 723 !socket_performance_watcher_->ShouldNotifyUpdatedRTT()) { |
| 738 return; | 724 return; |
| 739 } | 725 } |
| 740 | 726 |
| 741 tcp_info info; | 727 tcp_info info; |
| 742 if (!GetTcpInfo(socket_->socket_fd(), &info)) | 728 if (!GetTcpInfo(socket_->socket_fd(), &info)) |
| 743 return; | 729 return; |
| 744 | 730 |
| 745 // Only notify the |socket_performance_watcher_| if the RTT in |tcp_info| | 731 // Only notify the |socket_performance_watcher_| if the RTT in |tcp_info| |
| 746 // struct was populated. A value of 0 may be valid in certain cases | 732 // struct was populated. A value of 0 may be valid in certain cases |
| 747 // (on very fast networks), but it is discarded. This means that | 733 // (on very fast networks), but it is discarded. This means that |
| 748 // some of the RTT values may be missed, but the values that are kept are | 734 // some of the RTT values may be missed, but the values that are kept are |
| 749 // guaranteed to be correct. | 735 // guaranteed to be correct. |
| 750 if (info.tcpi_rtt == 0 && info.tcpi_rttvar == 0) | 736 if (info.tcpi_rtt == 0 && info.tcpi_rttvar == 0) |
| 751 return; | 737 return; |
| 752 | 738 |
| 753 socket_performance_watcher_->OnUpdatedRTTAvailable( | 739 socket_performance_watcher_->OnUpdatedRTTAvailable( |
| 754 base::TimeDelta::FromMicroseconds(info.tcpi_rtt)); | 740 base::TimeDelta::FromMicroseconds(info.tcpi_rtt)); |
| 755 last_rtt_notification_ = now_ticks; | |
| 756 #endif // defined(TCP_INFO) | 741 #endif // defined(TCP_INFO) |
| 757 } | 742 } |
| 758 | 743 |
| 759 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { | 744 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { |
| 760 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || | 745 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || |
| 761 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); | 746 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); |
| 762 | 747 |
| 763 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 748 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 764 // TCP FastOpen connect-with-write was attempted, and failed. | 749 // TCP FastOpen connect-with-write was attempted, and failed. |
| 765 tcp_fastopen_status_ = | 750 tcp_fastopen_status_ = |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 if (info.tcpi_rtt > 0) { | 795 if (info.tcpi_rtt > 0) { |
| 811 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); | 796 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); |
| 812 return true; | 797 return true; |
| 813 } | 798 } |
| 814 } | 799 } |
| 815 #endif // defined(TCP_INFO) | 800 #endif // defined(TCP_INFO) |
| 816 return false; | 801 return false; |
| 817 } | 802 } |
| 818 | 803 |
| 819 } // namespace net | 804 } // namespace net |
| OLD | NEW |