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

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: More plumbing 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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698