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 |
| 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" |
| 20 #include "base/time/default_tick_clock.h" | |
| 19 #include "net/base/address_list.h" | 21 #include "net/base/address_list.h" |
| 20 #include "net/base/connection_type_histograms.h" | 22 #include "net/base/connection_type_histograms.h" |
| 21 #include "net/base/io_buffer.h" | 23 #include "net/base/io_buffer.h" |
| 22 #include "net/base/ip_endpoint.h" | 24 #include "net/base/ip_endpoint.h" |
| 23 #include "net/base/net_errors.h" | 25 #include "net/base/net_errors.h" |
| 24 #include "net/base/network_activity_monitor.h" | 26 #include "net/base/network_activity_monitor.h" |
| 25 #include "net/base/network_change_notifier.h" | 27 #include "net/base/network_change_notifier.h" |
| 26 #include "net/base/sockaddr_storage.h" | 28 #include "net/base/sockaddr_storage.h" |
| 27 #include "net/socket/socket_net_log_params.h" | 29 #include "net/socket/socket_net_log_params.h" |
| 28 #include "net/socket/socket_posix.h" | 30 #include "net/socket/socket_posix.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) { | 131 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) { |
| 130 #if defined(OS_LINUX) || defined(OS_ANDROID) | 132 #if defined(OS_LINUX) || defined(OS_ANDROID) |
| 131 base::PostTaskAndReplyWithResult( | 133 base::PostTaskAndReplyWithResult( |
| 132 base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(), | 134 base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(), |
| 133 FROM_HERE, | 135 FROM_HERE, |
| 134 base::Bind(SystemSupportsTCPFastOpen), | 136 base::Bind(SystemSupportsTCPFastOpen), |
| 135 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); | 137 base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); |
| 136 #endif | 138 #endif |
| 137 } | 139 } |
| 138 | 140 |
| 139 TCPSocketPosix::TCPSocketPosix(NetLog* net_log, const NetLog::Source& source) | 141 TCPSocketPosix::TCPSocketPosix( |
| 140 : use_tcp_fastopen_(false), | 142 scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher, |
| 143 NetLog* net_log, | |
| 144 const NetLog::Source& source) | |
| 145 : rtt_notifications_minimum_interval_(base::TimeDelta::FromSeconds(1)), | |
| 146 socket_performance_watcher_(std::move(socket_performance_watcher)), | |
| 147 tick_clock_(new base::DefaultTickClock()), | |
| 148 use_tcp_fastopen_(false), | |
| 141 tcp_fastopen_write_attempted_(false), | 149 tcp_fastopen_write_attempted_(false), |
| 142 tcp_fastopen_connected_(false), | 150 tcp_fastopen_connected_(false), |
| 143 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), | 151 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), |
| 144 logging_multiple_connect_attempts_(false), | 152 logging_multiple_connect_attempts_(false), |
| 145 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 153 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { |
| 146 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 154 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
| 147 source.ToEventParametersCallback()); | 155 source.ToEventParametersCallback()); |
| 148 } | 156 } |
| 149 | 157 |
| 150 TCPSocketPosix::~TCPSocketPosix() { | 158 TCPSocketPosix::~TCPSocketPosix() { |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 | 475 |
| 468 void TCPSocketPosix::EndLoggingMultipleConnectAttempts(int net_error) { | 476 void TCPSocketPosix::EndLoggingMultipleConnectAttempts(int net_error) { |
| 469 if (logging_multiple_connect_attempts_) { | 477 if (logging_multiple_connect_attempts_) { |
| 470 LogConnectEnd(net_error); | 478 LogConnectEnd(net_error); |
| 471 logging_multiple_connect_attempts_ = false; | 479 logging_multiple_connect_attempts_ = false; |
| 472 } else { | 480 } else { |
| 473 NOTREACHED(); | 481 NOTREACHED(); |
| 474 } | 482 } |
| 475 } | 483 } |
| 476 | 484 |
| 485 void TCPSocketPosix::SetTickClockForTesting( | |
| 486 scoped_ptr<base::TickClock> tick_clock) { | |
| 487 tick_clock_.swap(tick_clock); | |
|
Ryan Sleevi
2016/04/11 22:06:56
I believe this should be
tick_clock_.swap(std::mo
tbansal1
2016/04/12 16:14:33
This gave compilation error:
error: non-const lval
| |
| 488 } | |
| 489 | |
| 477 void TCPSocketPosix::AcceptCompleted(scoped_ptr<TCPSocketPosix>* tcp_socket, | 490 void TCPSocketPosix::AcceptCompleted(scoped_ptr<TCPSocketPosix>* tcp_socket, |
| 478 IPEndPoint* address, | 491 IPEndPoint* address, |
| 479 const CompletionCallback& callback, | 492 const CompletionCallback& callback, |
| 480 int rv) { | 493 int rv) { |
| 481 DCHECK_NE(ERR_IO_PENDING, rv); | 494 DCHECK_NE(ERR_IO_PENDING, rv); |
| 482 callback.Run(HandleAcceptCompleted(tcp_socket, address, rv)); | 495 callback.Run(HandleAcceptCompleted(tcp_socket, address, rv)); |
| 483 } | 496 } |
| 484 | 497 |
| 485 int TCPSocketPosix::HandleAcceptCompleted( | 498 int TCPSocketPosix::HandleAcceptCompleted( |
| 486 scoped_ptr<TCPSocketPosix>* tcp_socket, | 499 scoped_ptr<TCPSocketPosix>* tcp_socket, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 503 IPEndPoint* address) { | 516 IPEndPoint* address) { |
| 504 DCHECK(accept_socket_); | 517 DCHECK(accept_socket_); |
| 505 | 518 |
| 506 SockaddrStorage storage; | 519 SockaddrStorage storage; |
| 507 if (accept_socket_->GetPeerAddress(&storage) != OK || | 520 if (accept_socket_->GetPeerAddress(&storage) != OK || |
| 508 !address->FromSockAddr(storage.addr, storage.addr_len)) { | 521 !address->FromSockAddr(storage.addr, storage.addr_len)) { |
| 509 accept_socket_.reset(); | 522 accept_socket_.reset(); |
| 510 return ERR_ADDRESS_INVALID; | 523 return ERR_ADDRESS_INVALID; |
| 511 } | 524 } |
| 512 | 525 |
| 513 tcp_socket->reset(new TCPSocketPosix(net_log_.net_log(), net_log_.source())); | 526 tcp_socket->reset( |
| 527 new TCPSocketPosix(nullptr, net_log_.net_log(), net_log_.source())); | |
| 514 (*tcp_socket)->socket_.reset(accept_socket_.release()); | 528 (*tcp_socket)->socket_.reset(accept_socket_.release()); |
| 515 return OK; | 529 return OK; |
| 516 } | 530 } |
| 517 | 531 |
| 518 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, | 532 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, |
| 519 int rv) const { | 533 int rv) { |
| 520 DCHECK_NE(ERR_IO_PENDING, rv); | 534 DCHECK_NE(ERR_IO_PENDING, rv); |
| 521 callback.Run(HandleConnectCompleted(rv)); | 535 callback.Run(HandleConnectCompleted(rv)); |
| 522 } | 536 } |
| 523 | 537 |
| 524 int TCPSocketPosix::HandleConnectCompleted(int rv) const { | 538 int TCPSocketPosix::HandleConnectCompleted(int rv) { |
| 525 // Log the end of this attempt (and any OS error it threw). | 539 // Log the end of this attempt (and any OS error it threw). |
| 526 if (rv != OK) { | 540 if (rv != OK) { |
| 527 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 541 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
| 528 NetLog::IntCallback("os_error", errno)); | 542 NetLog::IntCallback("os_error", errno)); |
| 529 } else { | 543 } else { |
| 530 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); | 544 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); |
| 545 NotifySocketPerformanceWatcher(); | |
| 531 } | 546 } |
| 532 | 547 |
| 533 // Give a more specific error when the user is offline. | 548 // Give a more specific error when the user is offline. |
| 534 if (rv == ERR_ADDRESS_UNREACHABLE && NetworkChangeNotifier::IsOffline()) | 549 if (rv == ERR_ADDRESS_UNREACHABLE && NetworkChangeNotifier::IsOffline()) |
| 535 rv = ERR_INTERNET_DISCONNECTED; | 550 rv = ERR_INTERNET_DISCONNECTED; |
| 536 | 551 |
| 537 if (!logging_multiple_connect_attempts_) | 552 if (!logging_multiple_connect_attempts_) |
| 538 LogConnectEnd(rv); | 553 LogConnectEnd(rv); |
| 539 | 554 |
| 540 return rv; | 555 return rv; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 590 else | 605 else |
| 591 g_tcp_fastopen_has_failed = true; | 606 g_tcp_fastopen_has_failed = true; |
| 592 UpdateTCPFastOpenStatusAfterRead(); | 607 UpdateTCPFastOpenStatusAfterRead(); |
| 593 } | 608 } |
| 594 | 609 |
| 595 if (rv < 0) { | 610 if (rv < 0) { |
| 596 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 611 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
| 597 CreateNetLogSocketErrorCallback(rv, errno)); | 612 CreateNetLogSocketErrorCallback(rv, errno)); |
| 598 return rv; | 613 return rv; |
| 599 } | 614 } |
| 615 NotifySocketPerformanceWatcher(); | |
| 616 | |
| 600 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, | 617 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, |
| 601 buf->data()); | 618 buf->data()); |
| 602 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | 619 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); |
| 603 | 620 |
| 604 return rv; | 621 return rv; |
| 605 } | 622 } |
| 606 | 623 |
| 607 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, | 624 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, |
| 608 const CompletionCallback& callback, | 625 const CompletionCallback& callback, |
| 609 int rv) { | 626 int rv) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 621 // FastOpen is turned off on _any_ error. Implement optimizations, | 638 // FastOpen is turned off on _any_ error. Implement optimizations, |
| 622 // such as turning off TCP FastOpen on more specific errors, and | 639 // such as turning off TCP FastOpen on more specific errors, and |
| 623 // re-attempting TCP FastOpen after a certain amount of time has passed. | 640 // re-attempting TCP FastOpen after a certain amount of time has passed. |
| 624 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; | 641 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; |
| 625 g_tcp_fastopen_has_failed = true; | 642 g_tcp_fastopen_has_failed = true; |
| 626 } | 643 } |
| 627 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 644 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
| 628 CreateNetLogSocketErrorCallback(rv, errno)); | 645 CreateNetLogSocketErrorCallback(rv, errno)); |
| 629 return rv; | 646 return rv; |
| 630 } | 647 } |
| 648 NotifySocketPerformanceWatcher(); | |
| 649 | |
| 631 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, rv, | 650 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, rv, |
| 632 buf->data()); | 651 buf->data()); |
| 633 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv); | 652 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv); |
| 634 return rv; | 653 return rv; |
| 635 } | 654 } |
| 636 | 655 |
| 637 int TCPSocketPosix::TcpFastOpenWrite(IOBuffer* buf, | 656 int TCPSocketPosix::TcpFastOpenWrite(IOBuffer* buf, |
| 638 int buf_len, | 657 int buf_len, |
| 639 const CompletionCallback& callback) { | 658 const CompletionCallback& callback) { |
| 640 SockaddrStorage storage; | 659 SockaddrStorage storage; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 688 // turning off TCP FastOpen on more specific errors. | 707 // turning off TCP FastOpen on more specific errors. |
| 689 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; | 708 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; |
| 690 g_tcp_fastopen_has_failed = true; | 709 g_tcp_fastopen_has_failed = true; |
| 691 return rv; | 710 return rv; |
| 692 } | 711 } |
| 693 | 712 |
| 694 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; | 713 tcp_fastopen_status_ = TCP_FASTOPEN_SLOW_CONNECT_RETURN; |
| 695 return socket_->WaitForWrite(buf, buf_len, callback); | 714 return socket_->WaitForWrite(buf, buf_len, callback); |
| 696 } | 715 } |
| 697 | 716 |
| 717 void TCPSocketPosix::NotifySocketPerformanceWatcher() { | |
| 718 #if defined(TCP_INFO) | |
| 719 // TODO(tbansal): Remove ScopedTracker once crbug.com/590254 is fixed. | |
| 720 tracked_objects::ScopedTracker tracking_profile( | |
| 721 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 722 "590254 TCPSocketPosix::NotifySocketPerformanceWatcher")); | |
| 723 | |
| 724 const base::TimeTicks now_ticks = tick_clock_->NowTicks(); | |
| 725 // Do not notify |socket_performance_watcher_| if the last notification was | |
| 726 // recent than |rtt_notifications_minimum_interval_| ago. This helps in | |
| 727 // reducing the overall overhead of the tcp_info syscalls. | |
| 728 if (now_ticks - last_rtt_notification_ < rtt_notifications_minimum_interval_) | |
| 729 return; | |
| 730 | |
| 731 // Check if |socket_performance_watcher_| is interested in receiving a RTT | |
| 732 // update notification. | |
| 733 if (!socket_performance_watcher_ || | |
| 734 !socket_performance_watcher_->ShouldNotifyUpdatedRTT()) { | |
| 735 return; | |
| 736 } | |
| 737 | |
| 738 tcp_info info; | |
| 739 if (!GetTcpInfo(socket_->socket_fd(), &info)) | |
| 740 return; | |
| 741 | |
| 742 // Only notify the |socket_performance_watcher_| if the RTT in |tcp_info| | |
| 743 // struct was populated. A value of 0 may be valid in certain cases | |
| 744 // (on very fast networks), but it is discarded. This means that | |
| 745 // some of the RTT values may be missed, but the values that are kept are | |
| 746 // guaranteed to be correct. | |
| 747 if (info.tcpi_rtt == 0 && info.tcpi_rttvar == 0) | |
| 748 return; | |
| 749 | |
| 750 socket_performance_watcher_->OnUpdatedRTTAvailable( | |
| 751 base::TimeDelta::FromMicroseconds(info.tcpi_rtt)); | |
| 752 last_rtt_notification_ = now_ticks; | |
| 753 #endif // defined(TCP_INFO) | |
| 754 } | |
| 755 | |
| 698 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { | 756 void TCPSocketPosix::UpdateTCPFastOpenStatusAfterRead() { |
| 699 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || | 757 DCHECK(tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN || |
| 700 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); | 758 tcp_fastopen_status_ == TCP_FASTOPEN_SLOW_CONNECT_RETURN); |
| 701 | 759 |
| 702 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 760 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 703 // TCP FastOpen connect-with-write was attempted, and failed. | 761 // TCP FastOpen connect-with-write was attempted, and failed. |
| 704 tcp_fastopen_status_ = | 762 tcp_fastopen_status_ = |
| 705 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? | 763 (tcp_fastopen_status_ == TCP_FASTOPEN_FAST_CONNECT_RETURN ? |
| 706 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : | 764 TCP_FASTOPEN_FAST_CONNECT_READ_FAILED : |
| 707 TCP_FASTOPEN_SLOW_CONNECT_READ_FAILED); | 765 TCP_FASTOPEN_SLOW_CONNECT_READ_FAILED); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 749 if (info.tcpi_rtt > 0) { | 807 if (info.tcpi_rtt > 0) { |
| 750 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); | 808 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); |
| 751 return true; | 809 return true; |
| 752 } | 810 } |
| 753 } | 811 } |
| 754 #endif // defined(TCP_INFO) | 812 #endif // defined(TCP_INFO) |
| 755 return false; | 813 return false; |
| 756 } | 814 } |
| 757 | 815 |
| 758 } // namespace net | 816 } // namespace net |
| OLD | NEW |