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

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: Rebased, addressed sleevi comments Created 4 years, 9 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 IPEndPoint* address) { 508 IPEndPoint* address) {
504 DCHECK(accept_socket_); 509 DCHECK(accept_socket_);
505 510
506 SockaddrStorage storage; 511 SockaddrStorage storage;
507 if (accept_socket_->GetPeerAddress(&storage) != OK || 512 if (accept_socket_->GetPeerAddress(&storage) != OK ||
508 !address->FromSockAddr(storage.addr, storage.addr_len)) { 513 !address->FromSockAddr(storage.addr, storage.addr_len)) {
509 accept_socket_.reset(); 514 accept_socket_.reset();
510 return ERR_ADDRESS_INVALID; 515 return ERR_ADDRESS_INVALID;
511 } 516 }
512 517
513 tcp_socket->reset(new TCPSocketPosix(net_log_.net_log(), net_log_.source())); 518 tcp_socket->reset(
519 new TCPSocketPosix(nullptr, net_log_.net_log(), net_log_.source()));
514 (*tcp_socket)->socket_.reset(accept_socket_.release()); 520 (*tcp_socket)->socket_.reset(accept_socket_.release());
515 return OK; 521 return OK;
516 } 522 }
517 523
518 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, 524 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback,
519 int rv) const { 525 int rv) {
520 DCHECK_NE(ERR_IO_PENDING, rv); 526 DCHECK_NE(ERR_IO_PENDING, rv);
527 NotifySocketPerformanceWatcher();
521 callback.Run(HandleConnectCompleted(rv)); 528 callback.Run(HandleConnectCompleted(rv));
522 } 529 }
523 530
524 int TCPSocketPosix::HandleConnectCompleted(int rv) const { 531 int TCPSocketPosix::HandleConnectCompleted(int rv) const {
525 // Log the end of this attempt (and any OS error it threw). 532 // Log the end of this attempt (and any OS error it threw).
526 if (rv != OK) { 533 if (rv != OK) {
527 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, 534 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT,
528 NetLog::IntCallback("os_error", errno)); 535 NetLog::IntCallback("os_error", errno));
529 } else { 536 } else {
530 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); 537 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 571
565 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, 572 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT,
566 CreateNetLogSourceAddressCallback(storage.addr, 573 CreateNetLogSourceAddressCallback(storage.addr,
567 storage.addr_len)); 574 storage.addr_len));
568 } 575 }
569 576
570 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, 577 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf,
571 const CompletionCallback& callback, 578 const CompletionCallback& callback,
572 int rv) { 579 int rv) {
573 DCHECK_NE(ERR_IO_PENDING, rv); 580 DCHECK_NE(ERR_IO_PENDING, rv);
581 NotifySocketPerformanceWatcher();
574 callback.Run(HandleReadCompleted(buf.get(), rv)); 582 callback.Run(HandleReadCompleted(buf.get(), rv));
575 } 583 }
576 584
577 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { 585 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) {
578 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { 586 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) {
579 // A TCP FastOpen connect-with-write was attempted. This read was a 587 // A TCP FastOpen connect-with-write was attempted. This read was a
580 // subsequent read, which either succeeded or failed. If the read 588 // subsequent read, which either succeeded or failed. If the read
581 // succeeded, the socket is considered connected via TCP FastOpen. 589 // succeeded, the socket is considered connected via TCP FastOpen.
582 // If the read failed, TCP FastOpen is (conservatively) turned off for all 590 // If the read failed, TCP FastOpen is (conservatively) turned off for all
583 // subsequent connections. TCP FastOpen status is recorded in both cases. 591 // subsequent connections. TCP FastOpen status is recorded in both cases.
(...skipping 17 matching lines...) Expand all
601 buf->data()); 609 buf->data());
602 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); 610 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv);
603 611
604 return rv; 612 return rv;
605 } 613 }
606 614
607 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, 615 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf,
608 const CompletionCallback& callback, 616 const CompletionCallback& callback,
609 int rv) { 617 int rv) {
610 DCHECK_NE(ERR_IO_PENDING, rv); 618 DCHECK_NE(ERR_IO_PENDING, rv);
619 NotifySocketPerformanceWatcher();
611 callback.Run(HandleWriteCompleted(buf.get(), rv)); 620 callback.Run(HandleWriteCompleted(buf.get(), rv));
612 } 621 }
613 622
614 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { 623 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) {
615 if (rv < 0) { 624 if (rv < 0) {
616 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { 625 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) {
617 // TCP FastOpen connect-with-write was attempted, and the write failed 626 // TCP FastOpen connect-with-write was attempted, and the write failed
618 // for unknown reasons. Record status and (conservatively) turn off 627 // for unknown reasons. Record status and (conservatively) turn off
619 // TCP FastOpen for all subsequent connections. 628 // TCP FastOpen for all subsequent connections.
620 // TODO (jri): This currently results in conservative behavior, where TCP 629 // TODO (jri): This currently results in conservative behavior, where TCP
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 // turning off TCP FastOpen on more specific errors. 697 // turning off TCP FastOpen on more specific errors.
689 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; 698 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR;
690 g_tcp_fastopen_has_failed = true; 699 g_tcp_fastopen_has_failed = true;
691 return rv; 700 return rv;
692 } 701 }
693 702
694 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; 703 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN;
695 return socket_->WaitForWrite(buf, buf_len, callback); 704 return socket_->WaitForWrite(buf, buf_len, callback);
696 } 705 }
697 706
707 void TCPSocketPosix::NotifySocketPerformanceWatcher() {
708 #if defined(TCP_INFO)
709 // TODO(tbansal): Remove ScopedTracker once crbug.com/590254 is fixed.
710 tracked_objects::ScopedTracker tracking_profile(
711 FROM_HERE_WITH_EXPLICIT_FUNCTION(
712 "590254 TCPSocketPosix::NotifySocketPerformanceWatcher"));
713
714 // Check if |socket_performance_watcher_| is interested in receiving a RTT
715 // update notification.
716 if (!socket_performance_watcher_ ||
717 !socket_performance_watcher_->ShouldNotifyUpdatedRTT()) {
718 return;
719 }
720
721 tcp_info info;
722 if (!GetTcpInfo(socket_->socket_fd(), &info))
723 return;
724
725 // Only notify the |socket_performance_watcher_| if the RTT in |tcp_info|
726 // struct was populated. A value of 0 may be valid in certain cases
727 // (on very fast networks), but it is discarded. This means that
728 // some of the RTT values may be missed, but the values that are kept are
729 // guaranteed to be correct.
730 if (info.tcpi_rtt == 0 && info.tcpi_rttvar == 0)
731 return;
732
733 socket_performance_watcher_->OnUpdatedRTTAvailable(
734 base::TimeDelta::FromMicroseconds(info.tcpi_rtt));
735 #endif // defined(TCP_INFO)
736 }
737
698 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { 738 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() {
699 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || 739 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ||
700 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); 740 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN);
701 741
702 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { 742 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) {
703 // TCP FastOpen connect-with-write was attempted, and failed. 743 // TCP FastOpen connect-with-write was attempted, and failed.
704 tcp_fastopen_status_ = 744 tcp_fastopen_status_ =
705 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? 745 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ?
706 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : 746 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED :
707 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
749 if (info.tcpi_rtt > 0) { 789 if (info.tcpi_rtt > 0) {
750 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); 790 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt);
751 return true; 791 return true;
752 } 792 }
753 } 793 }
754 #endif // defined(TCP_INFO) 794 #endif // defined(TCP_INFO)
755 return false; 795 return false;
756 } 796 }
757 797
758 } // namespace net 798 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698