| 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 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) { | 139 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) { |
| 140 #if defined(OS_LINUX) || defined(OS_ANDROID) | 140 #if defined(OS_LINUX) || defined(OS_ANDROID) |
| 141 base::PostTaskAndReplyWithResult( | 141 base::PostTaskAndReplyWithResult( |
| 142 base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(), | 142 base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(), |
| 143 FROM_HERE, | 143 FROM_HERE, |
| 144 base::Bind(SystemSupportsTCPFastOpen), | 144 base::Bind(SystemSupportsTCPFastOpen), |
| 145 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); | 145 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); |
| 146 #endif | 146 #endif |
| 147 } | 147 } |
| 148 | 148 |
| 149 TCPSocketPosix::TCPSocketPosix(NetLog* net_log, const NetLog::Source& source) | 149 TCPSocketPosix::TCPSocketPosix( |
| 150 : use_tcp_fastopen_(false), | 150 scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher, |
| 151 NetLog* net_log, |
| 152 const NetLog::Source& source) |
| 153 : socket_performance_watcher_(std::move(socket_performance_watcher)), |
| 154 use_tcp_fastopen_(false), |
| 151 tcp_fastopen_write_attempted_(false), | 155 tcp_fastopen_write_attempted_(false), |
| 152 tcp_fastopen_connected_(false), | 156 tcp_fastopen_connected_(false), |
| 153 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), | 157 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), |
| 154 logging_multiple_connect_attempts_(false), | 158 logging_multiple_connect_attempts_(false), |
| 155 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 159 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { |
| 156 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 160 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
| 157 source.ToEventParametersCallback()); | 161 source.ToEventParametersCallback()); |
| 158 } | 162 } |
| 159 | 163 |
| 160 TCPSocketPosix::~TCPSocketPosix() { | 164 TCPSocketPosix::~TCPSocketPosix() { |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 IPEndPoint* address) { | 521 IPEndPoint* address) { |
| 518 DCHECK(accept_socket_); | 522 DCHECK(accept_socket_); |
| 519 | 523 |
| 520 SockaddrStorage storage; | 524 SockaddrStorage storage; |
| 521 if (accept_socket_->GetPeerAddress(&storage) != OK || | 525 if (accept_socket_->GetPeerAddress(&storage) != OK || |
| 522 !address->FromSockAddr(storage.addr, storage.addr_len)) { | 526 !address->FromSockAddr(storage.addr, storage.addr_len)) { |
| 523 accept_socket_.reset(); | 527 accept_socket_.reset(); |
| 524 return ERR_ADDRESS_INVALID; | 528 return ERR_ADDRESS_INVALID; |
| 525 } | 529 } |
| 526 | 530 |
| 527 tcp_socket->reset(new TCPSocketPosix(net_log_.net_log(), net_log_.source())); | 531 tcp_socket->reset( |
| 532 new TCPSocketPosix(nullptr, net_log_.net_log(), net_log_.source())); |
| 528 (*tcp_socket)->socket_.reset(accept_socket_.release()); | 533 (*tcp_socket)->socket_.reset(accept_socket_.release()); |
| 529 return OK; | 534 return OK; |
| 530 } | 535 } |
| 531 | 536 |
| 532 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, | 537 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, |
| 533 int rv) const { | 538 int rv) const { |
| 534 DCHECK_NE(ERR_IO_PENDING, rv); | 539 DCHECK_NE(ERR_IO_PENDING, rv); |
| 540 NotifySocketPerformanceWatcher(); |
| 535 callback.Run(HandleConnectCompleted(rv)); | 541 callback.Run(HandleConnectCompleted(rv)); |
| 536 } | 542 } |
| 537 | 543 |
| 538 int TCPSocketPosix::HandleConnectCompleted(int rv) const { | 544 int TCPSocketPosix::HandleConnectCompleted(int rv) const { |
| 539 // Log the end of this attempt (and any OS error it threw). | 545 // Log the end of this attempt (and any OS error it threw). |
| 540 if (rv != OK) { | 546 if (rv != OK) { |
| 541 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 547 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 542 NetLog::IntCallback("os_error", errno)); | 548 NetLog::IntCallback("os_error", errno)); |
| 543 } else { | 549 } else { |
| 544 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); | 550 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 | 584 |
| 579 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 585 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, |
| 580 CreateNetLogSourceAddressCallback(storage.addr, | 586 CreateNetLogSourceAddressCallback(storage.addr, |
| 581 storage.addr_len)); | 587 storage.addr_len)); |
| 582 } | 588 } |
| 583 | 589 |
| 584 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, | 590 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, |
| 585 const CompletionCallback& callback, | 591 const CompletionCallback& callback, |
| 586 int rv) { | 592 int rv) { |
| 587 DCHECK_NE(ERR_IO_PENDING, rv); | 593 DCHECK_NE(ERR_IO_PENDING, rv); |
| 594 NotifySocketPerformanceWatcher(); |
| 588 callback.Run(HandleReadCompleted(buf.get(), rv)); | 595 callback.Run(HandleReadCompleted(buf.get(), rv)); |
| 589 } | 596 } |
| 590 | 597 |
| 591 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { | 598 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { |
| 592 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 599 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 593 // A TCP FastOpen connect-with-write was attempted. This read was a | 600 // A TCP FastOpen connect-with-write was attempted. This read was a |
| 594 // subsequent read, which either succeeded or failed. If the read | 601 // subsequent read, which either succeeded or failed. If the read |
| 595 // succeeded, the socket is considered connected via TCP FastOpen. | 602 // succeeded, the socket is considered connected via TCP FastOpen. |
| 596 // If the read failed, TCP FastOpen is (conservatively) turned off for all | 603 // If the read failed, TCP FastOpen is (conservatively) turned off for all |
| 597 // subsequent connections. TCP FastOpen status is recorded in both cases. | 604 // subsequent connections. TCP FastOpen status is recorded in both cases. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 615 buf->data()); | 622 buf->data()); |
| 616 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | 623 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); |
| 617 | 624 |
| 618 return rv; | 625 return rv; |
| 619 } | 626 } |
| 620 | 627 |
| 621 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, | 628 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, |
| 622 const CompletionCallback& callback, | 629 const CompletionCallback& callback, |
| 623 int rv) { | 630 int rv) { |
| 624 DCHECK_NE(ERR_IO_PENDING, rv); | 631 DCHECK_NE(ERR_IO_PENDING, rv); |
| 632 NotifySocketPerformanceWatcher(); |
| 625 callback.Run(HandleWriteCompleted(buf.get(), rv)); | 633 callback.Run(HandleWriteCompleted(buf.get(), rv)); |
| 626 } | 634 } |
| 627 | 635 |
| 628 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { | 636 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { |
| 629 if (rv < 0) { | 637 if (rv < 0) { |
| 630 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 638 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 631 // TCP FastOpen connect-with-write was attempted, and the write failed | 639 // TCP FastOpen connect-with-write was attempted, and the write failed |
| 632 // for unknown reasons. Record status and (conservatively) turn off | 640 // for unknown reasons. Record status and (conservatively) turn off |
| 633 // TCP FastOpen for all subsequent connections. | 641 // TCP FastOpen for all subsequent connections. |
| 634 // TODO (jri): This currently results in conservative behavior, where TCP | 642 // TODO (jri): This currently results in conservative behavior, where TCP |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 // turning off TCP FastOpen on more specific errors. | 710 // turning off TCP FastOpen on more specific errors. |
| 703 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; | 711 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; |
| 704 g_tcp_fastopen_has_failed = true; | 712 g_tcp_fastopen_has_failed = true; |
| 705 return rv; | 713 return rv; |
| 706 } | 714 } |
| 707 | 715 |
| 708 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; | 716 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; |
| 709 return socket_->WaitForWrite(buf, buf_len, callback); | 717 return socket_->WaitForWrite(buf, buf_len, callback); |
| 710 } | 718 } |
| 711 | 719 |
| 720 void TCPSocketPosix::NotifySocketPerformanceWatcher() const { |
| 721 #if defined(TCP_INFO) |
| 722 if (!socket_performance_watcher_) |
| 723 return; |
| 724 |
| 725 tcp_info info; |
| 726 bool getsockopt_success = GetTcpInfo(socket_->socket_fd(), &info); |
| 727 if (!getsockopt_success) |
| 728 return; |
| 729 |
| 730 if (info.tcpi_rtt > 0) { |
| 731 // Zero RTT value indicates that tcp_info struct was not properly populated. |
| 732 socket_performance_watcher_->OnUpdatedRTTAvailable( |
| 733 base::TimeDelta::FromMicroseconds(info.tcpi_rtt)); |
| 734 } |
| 735 #endif // defined(TCP_INFO) |
| 736 } |
| 737 |
| 712 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { | 738 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { |
| 713 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || | 739 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || |
| 714 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); | 740 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); |
| 715 | 741 |
| 716 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 742 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 717 // TCP FastOpen connect-with-write was attempted, and failed. | 743 // TCP FastOpen connect-with-write was attempted, and failed. |
| 718 tcp_fastopen_status_ = | 744 tcp_fastopen_status_ = |
| 719 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? | 745 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? |
| 720 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : | 746 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : |
| 721 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... |
| 763 if (info.tcpi_rtt > 0) { | 789 if (info.tcpi_rtt > 0) { |
| 764 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); | 790 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); |
| 765 return true; | 791 return true; |
| 766 } | 792 } |
| 767 } | 793 } |
| 768 #endif // defined(TCP_INFO) | 794 #endif // defined(TCP_INFO) |
| 769 return false; | 795 return false; |
| 770 } | 796 } |
| 771 | 797 |
| 772 } // namespace net | 798 } // namespace net |
| OLD | NEW |