Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: net/socket/tcp_socket_posix.cc

Issue 1376473003: Notify NQE of TCP RTT values (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed rsleevi comments, using ScopedTracker, added tests for SPW Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) { 140 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) {
140 #if defined(OS_LINUX) || defined(OS_ANDROID) 141 #if defined(OS_LINUX) || defined(OS_ANDROID)
141 base::PostTaskAndReplyWithResult( 142 base::PostTaskAndReplyWithResult(
142 base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(), 143 base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(),
143 FROM_HERE, 144 FROM_HERE,
144 base::Bind(SystemSupportsTCPFastOpen), 145 base::Bind(SystemSupportsTCPFastOpen),
145 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); 146 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled));
146 #endif 147 #endif
147 } 148 }
148 149
149 TCPSocketPosix::TCPSocketPosix(NetLog* net_log, const NetLog::Source& source) 150 TCPSocketPosix::TCPSocketPosix(
150 : use_tcp_fastopen_(false), 151 scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher,
152 NetLog* net_log,
153 const NetLog::Source& source)
154 : socket_performance_watcher_(std::move(socket_performance_watcher)),
155 use_tcp_fastopen_(false),
151 tcp_fastopen_write_attempted_(false), 156 tcp_fastopen_write_attempted_(false),
152 tcp_fastopen_connected_(false), 157 tcp_fastopen_connected_(false),
153 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), 158 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN),
154 logging_multiple_connect_attempts_(false), 159 logging_multiple_connect_attempts_(false),
155 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { 160 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {
156 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 161 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
157 source.ToEventParametersCallback()); 162 source.ToEventParametersCallback());
158 } 163 }
159 164
160 TCPSocketPosix::~TCPSocketPosix() { 165 TCPSocketPosix::~TCPSocketPosix() {
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 IPEndPoint* address) { 522 IPEndPoint* address) {
518 DCHECK(accept_socket_); 523 DCHECK(accept_socket_);
519 524
520 SockaddrStorage storage; 525 SockaddrStorage storage;
521 if (accept_socket_->GetPeerAddress(&storage) != OK || 526 if (accept_socket_->GetPeerAddress(&storage) != OK ||
522 !address->FromSockAddr(storage.addr, storage.addr_len)) { 527 !address->FromSockAddr(storage.addr, storage.addr_len)) {
523 accept_socket_.reset(); 528 accept_socket_.reset();
524 return ERR_ADDRESS_INVALID; 529 return ERR_ADDRESS_INVALID;
525 } 530 }
526 531
527 tcp_socket->reset(new TCPSocketPosix(net_log_.net_log(), net_log_.source())); 532 tcp_socket->reset(
533 new TCPSocketPosix(nullptr, net_log_.net_log(), net_log_.source()));
528 (*tcp_socket)->socket_.reset(accept_socket_.release()); 534 (*tcp_socket)->socket_.reset(accept_socket_.release());
529 return OK; 535 return OK;
530 } 536 }
531 537
532 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, 538 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback,
533 int rv) const { 539 int rv) {
534 DCHECK_NE(ERR_IO_PENDING, rv); 540 DCHECK_NE(ERR_IO_PENDING, rv);
541 NotifySocketPerformanceWatcher();
535 callback.Run(HandleConnectCompleted(rv)); 542 callback.Run(HandleConnectCompleted(rv));
536 } 543 }
537 544
538 int TCPSocketPosix::HandleConnectCompleted(int rv) const { 545 int TCPSocketPosix::HandleConnectCompleted(int rv) const {
539 // Log the end of this attempt (and any OS error it threw). 546 // Log the end of this attempt (and any OS error it threw).
540 if (rv != OK) { 547 if (rv != OK) {
541 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, 548 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT,
542 NetLog::IntCallback("os_error", errno)); 549 NetLog::IntCallback("os_error", errno));
543 } else { 550 } else {
544 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); 551 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 585
579 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, 586 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT,
580 CreateNetLogSourceAddressCallback(storage.addr, 587 CreateNetLogSourceAddressCallback(storage.addr,
581 storage.addr_len)); 588 storage.addr_len));
582 } 589 }
583 590
584 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, 591 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf,
585 const CompletionCallback& callback, 592 const CompletionCallback& callback,
586 int rv) { 593 int rv) {
587 DCHECK_NE(ERR_IO_PENDING, rv); 594 DCHECK_NE(ERR_IO_PENDING, rv);
595 NotifySocketPerformanceWatcher();
588 callback.Run(HandleReadCompleted(buf.get(), rv)); 596 callback.Run(HandleReadCompleted(buf.get(), rv));
589 } 597 }
590 598
591 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { 599 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) {
592 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { 600 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) {
593 // A TCP FastOpen connect-with-write was attempted. This read was a 601 // A TCP FastOpen connect-with-write was attempted. This read was a
594 // subsequent read, which either succeeded or failed. If the read 602 // subsequent read, which either succeeded or failed. If the read
595 // succeeded, the socket is considered connected via TCP FastOpen. 603 // succeeded, the socket is considered connected via TCP FastOpen.
596 // If the read failed, TCP FastOpen is (conservatively) turned off for all 604 // If the read failed, TCP FastOpen is (conservatively) turned off for all
597 // subsequent connections. TCP FastOpen status is recorded in both cases. 605 // subsequent connections. TCP FastOpen status is recorded in both cases.
(...skipping 17 matching lines...) Expand all
615 buf->data()); 623 buf->data());
616 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); 624 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv);
617 625
618 return rv; 626 return rv;
619 } 627 }
620 628
621 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, 629 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf,
622 const CompletionCallback& callback, 630 const CompletionCallback& callback,
623 int rv) { 631 int rv) {
624 DCHECK_NE(ERR_IO_PENDING, rv); 632 DCHECK_NE(ERR_IO_PENDING, rv);
633 NotifySocketPerformanceWatcher();
625 callback.Run(HandleWriteCompleted(buf.get(), rv)); 634 callback.Run(HandleWriteCompleted(buf.get(), rv));
626 } 635 }
627 636
628 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { 637 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) {
629 if (rv < 0) { 638 if (rv < 0) {
630 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { 639 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) {
631 // TCP FastOpen connect-with-write was attempted, and the write failed 640 // TCP FastOpen connect-with-write was attempted, and the write failed
632 // for unknown reasons. Record status and (conservatively) turn off 641 // for unknown reasons. Record status and (conservatively) turn off
633 // TCP FastOpen for all subsequent connections. 642 // TCP FastOpen for all subsequent connections.
634 // TODO (jri): This currently results in conservative behavior, where TCP 643 // TODO (jri): This currently results in conservative behavior, where TCP
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 // turning off TCP FastOpen on more specific errors. 711 // turning off TCP FastOpen on more specific errors.
703 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; 712 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR;
704 g_tcp_fastopen_has_failed = true; 713 g_tcp_fastopen_has_failed = true;
705 return rv; 714 return rv;
706 } 715 }
707 716
708 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; 717 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN;
709 return socket_->WaitForWrite(buf, buf_len, callback); 718 return socket_->WaitForWrite(buf, buf_len, callback);
710 } 719 }
711 720
721 void TCPSocketPosix::NotifySocketPerformanceWatcher() {
722 #if defined(TCP_INFO)
723 // Check if |socket_performance_watcher_| can be notified of a RTT value.
724 if (!socket_performance_watcher_ ||
725 !socket_performance_watcher_->CanNotifyRTT()) {
726 return;
727 }
728
729 // TODO(tbansal): Remove ScopedTracker once crbug.com/590254 is fixed.
730 tracked_objects::ScopedTracker tracking_profile(
731 FROM_HERE_WITH_EXPLICIT_FUNCTION(
732 "590254 TCPSocketPosix::NotifySocketPerformanceWatcher"));
733
734 tcp_info info;
735 if (!GetTcpInfo(socket_->socket_fd(), &info))
736 return;
737
738 // Only notify the SocketPerformanceWatcher if the RTT in |tcp_info| struct
739 // was populated. A value of 0 may be valid, but it is not reported to the
740 // SocketPerformanceWatcher in order to maintain high accuracy.
741 if (info.tcpi_rtt > 0) {
742 socket_performance_watcher_->OnUpdatedRTTAvailable(
743 base::TimeDelta::FromMicroseconds(info.tcpi_rtt));
744 }
745 #endif // defined(TCP_INFO)
746 }
747
712 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { 748 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() {
713 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || 749 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ||
714 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); 750 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN);
715 751
716 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { 752 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) {
717 // TCP FastOpen connect-with-write was attempted, and failed. 753 // TCP FastOpen connect-with-write was attempted, and failed.
718 tcp_fastopen_status_ = 754 tcp_fastopen_status_ =
719 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? 755 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ?
720 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : 756 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED :
721 TCP_FASTOPEN_SLOW_CONNECT_READ_FAILED); 757 TCP_FASTOPEN_SLOW_CONNECT_READ_FAILED);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 if (info.tcpi_rtt > 0) { 799 if (info.tcpi_rtt > 0) {
764 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); 800 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt);
765 return true; 801 return true;
766 } 802 }
767 } 803 }
768 #endif // defined(TCP_INFO) 804 #endif // defined(TCP_INFO)
769 return false; 805 return false;
770 } 806 }
771 807
772 } // namespace net 808 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698