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 |