Chromium Code Reviews| 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_(socket_performance_watcher.Pass()), | |
| 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 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 513 IPEndPoint* address) { | 517 IPEndPoint* address) { |
| 514 DCHECK(accept_socket_); | 518 DCHECK(accept_socket_); |
| 515 | 519 |
| 516 SockaddrStorage storage; | 520 SockaddrStorage storage; |
| 517 if (accept_socket_->GetPeerAddress(&storage) != OK || | 521 if (accept_socket_->GetPeerAddress(&storage) != OK || |
| 518 !address->FromSockAddr(storage.addr, storage.addr_len)) { | 522 !address->FromSockAddr(storage.addr, storage.addr_len)) { |
| 519 accept_socket_.reset(); | 523 accept_socket_.reset(); |
| 520 return ERR_ADDRESS_INVALID; | 524 return ERR_ADDRESS_INVALID; |
| 521 } | 525 } |
| 522 | 526 |
| 523 tcp_socket->reset(new TCPSocketPosix(net_log_.net_log(), net_log_.source())); | 527 tcp_socket->reset( |
| 528 new TCPSocketPosix(/*socket_performance_watcher_factory=*/nullptr, | |
| 529 net_log_.net_log(), net_log_.source())); | |
| 524 (*tcp_socket)->socket_.reset(accept_socket_.release()); | 530 (*tcp_socket)->socket_.reset(accept_socket_.release()); |
| 525 return OK; | 531 return OK; |
| 526 } | 532 } |
| 527 | 533 |
| 528 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, | 534 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, |
| 529 int rv) const { | 535 int rv) const { |
| 530 DCHECK_NE(ERR_IO_PENDING, rv); | 536 DCHECK_NE(ERR_IO_PENDING, rv); |
| 537 NotifySocketPerformanceWatcher(); | |
| 531 callback.Run(HandleConnectCompleted(rv)); | 538 callback.Run(HandleConnectCompleted(rv)); |
| 532 } | 539 } |
| 533 | 540 |
| 534 int TCPSocketPosix::HandleConnectCompleted(int rv) const { | 541 int TCPSocketPosix::HandleConnectCompleted(int rv) const { |
| 535 // Log the end of this attempt (and any OS error it threw). | 542 // Log the end of this attempt (and any OS error it threw). |
| 536 if (rv != OK) { | 543 if (rv != OK) { |
| 537 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 544 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 538 NetLog::IntegerCallback("os_error", errno)); | 545 NetLog::IntegerCallback("os_error", errno)); |
| 539 } else { | 546 } else { |
| 540 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); | 547 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 574 | 581 |
| 575 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 582 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, |
| 576 CreateNetLogSourceAddressCallback(storage.addr, | 583 CreateNetLogSourceAddressCallback(storage.addr, |
| 577 storage.addr_len)); | 584 storage.addr_len)); |
| 578 } | 585 } |
| 579 | 586 |
| 580 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, | 587 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, |
| 581 const CompletionCallback& callback, | 588 const CompletionCallback& callback, |
| 582 int rv) { | 589 int rv) { |
| 583 DCHECK_NE(ERR_IO_PENDING, rv); | 590 DCHECK_NE(ERR_IO_PENDING, rv); |
| 591 NotifySocketPerformanceWatcher(); | |
| 584 callback.Run(HandleReadCompleted(buf.get(), rv)); | 592 callback.Run(HandleReadCompleted(buf.get(), rv)); |
| 585 } | 593 } |
| 586 | 594 |
| 587 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { | 595 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { |
| 588 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 596 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 589 // A TCP FastOpen connect-with-write was attempted. This read was a | 597 // A TCP FastOpen connect-with-write was attempted. This read was a |
| 590 // subsequent read, which either succeeded or failed. If the read | 598 // subsequent read, which either succeeded or failed. If the read |
| 591 // succeeded, the socket is considered connected via TCP FastOpen. | 599 // succeeded, the socket is considered connected via TCP FastOpen. |
| 592 // If the read failed, TCP FastOpen is (conservatively) turned off for all | 600 // If the read failed, TCP FastOpen is (conservatively) turned off for all |
| 593 // subsequent connections. TCP FastOpen status is recorded in both cases. | 601 // subsequent connections. TCP FastOpen status is recorded in both cases. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 611 buf->data()); | 619 buf->data()); |
| 612 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | 620 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); |
| 613 | 621 |
| 614 return rv; | 622 return rv; |
| 615 } | 623 } |
| 616 | 624 |
| 617 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, | 625 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, |
| 618 const CompletionCallback& callback, | 626 const CompletionCallback& callback, |
| 619 int rv) { | 627 int rv) { |
| 620 DCHECK_NE(ERR_IO_PENDING, rv); | 628 DCHECK_NE(ERR_IO_PENDING, rv); |
| 629 NotifySocketPerformanceWatcher(); | |
| 621 callback.Run(HandleWriteCompleted(buf.get(), rv)); | 630 callback.Run(HandleWriteCompleted(buf.get(), rv)); |
| 622 } | 631 } |
| 623 | 632 |
| 624 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { | 633 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { |
| 625 if (rv < 0) { | 634 if (rv < 0) { |
| 626 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 635 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 627 // TCP FastOpen connect-with-write was attempted, and the write failed | 636 // TCP FastOpen connect-with-write was attempted, and the write failed |
| 628 // for unknown reasons. Record status and (conservatively) turn off | 637 // for unknown reasons. Record status and (conservatively) turn off |
| 629 // TCP FastOpen for all subsequent connections. | 638 // TCP FastOpen for all subsequent connections. |
| 630 // TODO (jri): This currently results in conservative behavior, where TCP | 639 // TODO (jri): This currently results in conservative behavior, where TCP |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 698 // turning off TCP FastOpen on more specific errors. | 707 // turning off TCP FastOpen on more specific errors. |
| 699 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; | 708 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; |
| 700 g_tcp_fastopen_has_failed = true; | 709 g_tcp_fastopen_has_failed = true; |
| 701 return rv; | 710 return rv; |
| 702 } | 711 } |
| 703 | 712 |
| 704 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; | 713 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; |
| 705 return socket_->WaitForWrite(buf, buf_len, callback); | 714 return socket_->WaitForWrite(buf, buf_len, callback); |
| 706 } | 715 } |
| 707 | 716 |
| 717 void TCPSocketPosix::NotifySocketPerformanceWatcher() const { | |
| 718 if (!socket_performance_watcher_) | |
|
Ryan Sleevi
2015/10/20 00:10:36
Is there a reason not to wrap the entire method bo
tbansal1
2016/02/05 19:44:15
Done, I did not think of the optimization.
| |
| 719 return; | |
| 720 | |
| 721 bool getsockopt_success = false; | |
|
Ryan Sleevi
2015/10/20 00:10:36
I'd expect this will result in a compiler warning
tbansal1
2016/02/05 19:44:15
Obsolete.
| |
| 722 #if defined(TCP_INFO) | |
| 723 tcp_info info; | |
| 724 getsockopt_success = GetTcpInfo(socket_->socket_fd(), &info); | |
| 725 if (!getsockopt_success) | |
| 726 return; | |
| 727 | |
| 728 socket_performance_watcher_->OnUpdatedRTTAvailable( | |
| 729 base::TimeDelta::FromMicroseconds(info.tcpi_rtt)); | |
| 730 #endif // defined(TCP_INFO) | |
| 731 } | |
| 732 | |
| 708 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { | 733 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { |
| 709 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || | 734 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || |
| 710 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); | 735 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); |
| 711 | 736 |
| 712 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 737 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 713 // TCP FastOpen connect-with-write was attempted, and failed. | 738 // TCP FastOpen connect-with-write was attempted, and failed. |
| 714 tcp_fastopen_status_ = | 739 tcp_fastopen_status_ = |
| 715 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? | 740 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? |
| 716 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : | 741 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : |
| 717 TCP_FASTOPEN_SLOW_CONNECT_READ_FAILED); | 742 TCP_FASTOPEN_SLOW_CONNECT_READ_FAILED); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 759 if (info.tcpi_rtt > 0) { | 784 if (info.tcpi_rtt > 0) { |
| 760 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); | 785 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); |
| 761 return true; | 786 return true; |
| 762 } | 787 } |
| 763 } | 788 } |
| 764 #endif // defined(TCP_INFO) | 789 #endif // defined(TCP_INFO) |
| 765 return false; | 790 return false; |
| 766 } | 791 } |
| 767 | 792 |
| 768 } // namespace net | 793 } // namespace net |
| OLD | NEW |