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/profiler/scoped_tracker.h" | |
17 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
18 #include "base/threading/worker_pool.h" | 19 #include "base/threading/worker_pool.h" |
19 #include "net/base/address_list.h" | 20 #include "net/base/address_list.h" |
20 #include "net/base/connection_type_histograms.h" | 21 #include "net/base/connection_type_histograms.h" |
21 #include "net/base/io_buffer.h" | 22 #include "net/base/io_buffer.h" |
22 #include "net/base/ip_endpoint.h" | 23 #include "net/base/ip_endpoint.h" |
23 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
24 #include "net/base/network_activity_monitor.h" | 25 #include "net/base/network_activity_monitor.h" |
25 #include "net/base/network_change_notifier.h" | 26 #include "net/base/network_change_notifier.h" |
26 #include "net/base/sockaddr_storage.h" | 27 #include "net/base/sockaddr_storage.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
129 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) { | 130 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) { |
130 #if defined(OS_LINUX) || defined(OS_ANDROID) | 131 #if defined(OS_LINUX) || defined(OS_ANDROID) |
131 base::PostTaskAndReplyWithResult( | 132 base::PostTaskAndReplyWithResult( |
132 base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(), | 133 base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(), |
133 FROM_HERE, | 134 FROM_HERE, |
134 base::Bind(SystemSupportsTCPFastOpen), | 135 base::Bind(SystemSupportsTCPFastOpen), |
135 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); | 136 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); |
136 #endif | 137 #endif |
137 } | 138 } |
138 | 139 |
139 TCPSocketPosix::TCPSocketPosix(NetLog* net_log, const NetLog::Source& source) | 140 TCPSocketPosix::TCPSocketPosix( |
140 : use_tcp_fastopen_(false), | 141 scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher, |
142 NetLog* net_log, | |
143 const NetLog::Source& source) | |
144 : socket_performance_watcher_(std::move(socket_performance_watcher)), | |
145 use_tcp_fastopen_(false), | |
141 tcp_fastopen_write_attempted_(false), | 146 tcp_fastopen_write_attempted_(false), |
142 tcp_fastopen_connected_(false), | 147 tcp_fastopen_connected_(false), |
143 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), | 148 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), |
144 logging_multiple_connect_attempts_(false), | 149 logging_multiple_connect_attempts_(false), |
145 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 150 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { |
146 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 151 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
147 source.ToEventParametersCallback()); | 152 source.ToEventParametersCallback()); |
148 } | 153 } |
149 | 154 |
150 TCPSocketPosix::~TCPSocketPosix() { | 155 TCPSocketPosix::~TCPSocketPosix() { |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 IPEndPoint* address) { | 512 IPEndPoint* address) { |
508 DCHECK(accept_socket_); | 513 DCHECK(accept_socket_); |
509 | 514 |
510 SockaddrStorage storage; | 515 SockaddrStorage storage; |
511 if (accept_socket_->GetPeerAddress(&storage) != OK || | 516 if (accept_socket_->GetPeerAddress(&storage) != OK || |
512 !address->FromSockAddr(storage.addr, storage.addr_len)) { | 517 !address->FromSockAddr(storage.addr, storage.addr_len)) { |
513 accept_socket_.reset(); | 518 accept_socket_.reset(); |
514 return ERR_ADDRESS_INVALID; | 519 return ERR_ADDRESS_INVALID; |
515 } | 520 } |
516 | 521 |
517 tcp_socket->reset(new TCPSocketPosix(net_log_.net_log(), net_log_.source())); | 522 tcp_socket->reset( |
523 new TCPSocketPosix(nullptr, net_log_.net_log(), net_log_.source())); | |
Wez
2016/03/04 18:50:26
IIUC this means that you can't associated a socket
tbansal1
2016/03/09 00:20:03
SocketPerformanceWatcher only expects RTT values f
| |
518 (*tcp_socket)->socket_.reset(accept_socket_.release()); | 524 (*tcp_socket)->socket_.reset(accept_socket_.release()); |
519 return OK; | 525 return OK; |
520 } | 526 } |
521 | 527 |
522 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, | 528 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, |
523 int rv) const { | 529 int rv) { |
524 DCHECK_NE(ERR_IO_PENDING, rv); | 530 DCHECK_NE(ERR_IO_PENDING, rv); |
531 NotifySocketPerformanceWatcher(); | |
525 callback.Run(HandleConnectCompleted(rv)); | 532 callback.Run(HandleConnectCompleted(rv)); |
526 } | 533 } |
527 | 534 |
528 int TCPSocketPosix::HandleConnectCompleted(int rv) const { | 535 int TCPSocketPosix::HandleConnectCompleted(int rv) const { |
529 // Log the end of this attempt (and any OS error it threw). | 536 // Log the end of this attempt (and any OS error it threw). |
530 if (rv != OK) { | 537 if (rv != OK) { |
531 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 538 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
532 NetLog::IntCallback("os_error", errno)); | 539 NetLog::IntCallback("os_error", errno)); |
533 } else { | 540 } else { |
534 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); | 541 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
568 | 575 |
569 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 576 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, |
570 CreateNetLogSourceAddressCallback(storage.addr, | 577 CreateNetLogSourceAddressCallback(storage.addr, |
571 storage.addr_len)); | 578 storage.addr_len)); |
572 } | 579 } |
573 | 580 |
574 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, | 581 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, |
575 const CompletionCallback& callback, | 582 const CompletionCallback& callback, |
576 int rv) { | 583 int rv) { |
577 DCHECK_NE(ERR_IO_PENDING, rv); | 584 DCHECK_NE(ERR_IO_PENDING, rv); |
585 NotifySocketPerformanceWatcher(); | |
578 callback.Run(HandleReadCompleted(buf.get(), rv)); | 586 callback.Run(HandleReadCompleted(buf.get(), rv)); |
579 } | 587 } |
580 | 588 |
581 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { | 589 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { |
582 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 590 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
583 // A TCP FastOpen connect-with-write was attempted. This read was a | 591 // A TCP FastOpen connect-with-write was attempted. This read was a |
584 // subsequent read, which either succeeded or failed. If the read | 592 // subsequent read, which either succeeded or failed. If the read |
585 // succeeded, the socket is considered connected via TCP FastOpen. | 593 // succeeded, the socket is considered connected via TCP FastOpen. |
586 // If the read failed, TCP FastOpen is (conservatively) turned off for all | 594 // If the read failed, TCP FastOpen is (conservatively) turned off for all |
587 // subsequent connections. TCP FastOpen status is recorded in both cases. | 595 // subsequent connections. TCP FastOpen status is recorded in both cases. |
(...skipping 17 matching lines...) Expand all Loading... | |
605 buf->data()); | 613 buf->data()); |
606 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | 614 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); |
607 | 615 |
608 return rv; | 616 return rv; |
609 } | 617 } |
610 | 618 |
611 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, | 619 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, |
612 const CompletionCallback& callback, | 620 const CompletionCallback& callback, |
613 int rv) { | 621 int rv) { |
614 DCHECK_NE(ERR_IO_PENDING, rv); | 622 DCHECK_NE(ERR_IO_PENDING, rv); |
623 NotifySocketPerformanceWatcher(); | |
615 callback.Run(HandleWriteCompleted(buf.get(), rv)); | 624 callback.Run(HandleWriteCompleted(buf.get(), rv)); |
616 } | 625 } |
617 | 626 |
618 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { | 627 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { |
619 if (rv < 0) { | 628 if (rv < 0) { |
620 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 629 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
621 // TCP FastOpen connect-with-write was attempted, and the write failed | 630 // TCP FastOpen connect-with-write was attempted, and the write failed |
622 // for unknown reasons. Record status and (conservatively) turn off | 631 // for unknown reasons. Record status and (conservatively) turn off |
623 // TCP FastOpen for all subsequent connections. | 632 // TCP FastOpen for all subsequent connections. |
624 // TODO (jri): This currently results in conservative behavior, where TCP | 633 // TODO (jri): This currently results in conservative behavior, where TCP |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 // turning off TCP FastOpen on more specific errors. | 701 // turning off TCP FastOpen on more specific errors. |
693 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; | 702 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; |
694 g_tcp_fastopen_has_failed = true; | 703 g_tcp_fastopen_has_failed = true; |
695 return rv; | 704 return rv; |
696 } | 705 } |
697 | 706 |
698 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; | 707 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; |
699 return socket_->WaitForWrite(buf, buf_len, callback); | 708 return socket_->WaitForWrite(buf, buf_len, callback); |
700 } | 709 } |
701 | 710 |
711 void TCPSocketPosix::NotifySocketPerformanceWatcher() { | |
712 #if defined(TCP_INFO) | |
713 // TODO(tbansal): Remove ScopedTracker once crbug.com/590254 is fixed. | |
714 tracked_objects::ScopedTracker tracking_profile( | |
715 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
716 "590254 TCPSocketPosix::NotifySocketPerformanceWatcher")); | |
717 | |
718 // Check if |socket_performance_watcher_| can be notified of a RTT value. | |
Wez
2016/03/04 18:50:26
nit: "can" -> "must" or reword to "...watcher_| is
tbansal1
2016/03/09 00:20:03
Done.
| |
719 if (!socket_performance_watcher_ || | |
720 !socket_performance_watcher_->ShouldNotifyUpdatedRTT()) { | |
721 return; | |
722 } | |
723 | |
724 tcp_info info; | |
725 if (!GetTcpInfo(socket_->socket_fd(), &info)) | |
726 return; | |
727 | |
728 // Only notify the SocketPerformanceWatcher if the RTT in |tcp_info| struct | |
729 // was populated. A value of 0 may be valid, but it is not reported to the | |
730 // SocketPerformanceWatcher in order to maintain high accuracy. | |
Wez
2016/03/04 18:50:26
nit: Not clear from the comment why omitting valid
tbansal1
2016/03/09 00:20:03
I expanded the comment to make it clearer.
| |
731 if (info.tcpi_rtt > 0) { | |
732 socket_performance_watcher_->OnUpdatedRTTAvailable( | |
733 base::TimeDelta::FromMicroseconds(info.tcpi_rtt)); | |
734 } | |
735 #endif // defined(TCP_INFO) | |
736 } | |
737 | |
702 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { | 738 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { |
703 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || | 739 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || |
704 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); | 740 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); |
705 | 741 |
706 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 742 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
707 // TCP FastOpen connect-with-write was attempted, and failed. | 743 // TCP FastOpen connect-with-write was attempted, and failed. |
708 tcp_fastopen_status_ = | 744 tcp_fastopen_status_ = |
709 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? | 745 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? |
710 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : | 746 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : |
711 TCP_FASTOPEN_SLOW_CONNECT_READ_FAILED); | 747 TCP_FASTOPEN_SLOW_CONNECT_READ_FAILED); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
753 if (info.tcpi_rtt > 0) { | 789 if (info.tcpi_rtt > 0) { |
754 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); | 790 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); |
755 return true; | 791 return true; |
756 } | 792 } |
757 } | 793 } |
758 #endif // defined(TCP_INFO) | 794 #endif // defined(TCP_INFO) |
759 return false; | 795 return false; |
760 } | 796 } |
761 | 797 |
762 } // namespace net | 798 } // namespace net |
OLD | NEW |