| 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/profiler/scoped_tracker.h" |
| 18 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
| 19 #include "base/threading/worker_pool.h" | 19 #include "base/threading/worker_pool.h" |
| 20 #include "base/time/default_tick_clock.h" | 20 #include "base/time/default_tick_clock.h" |
| 21 #include "net/base/address_list.h" | 21 #include "net/base/address_list.h" |
| 22 #include "net/base/io_buffer.h" | 22 #include "net/base/io_buffer.h" |
| 23 #include "net/base/ip_endpoint.h" | 23 #include "net/base/ip_endpoint.h" |
| 24 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
| 25 #include "net/base/network_activity_monitor.h" | 25 #include "net/base/network_activity_monitor.h" |
| 26 #include "net/base/network_change_notifier.h" | 26 #include "net/base/network_change_notifier.h" |
| 27 #include "net/base/sockaddr_storage.h" | 27 #include "net/base/sockaddr_storage.h" |
| 28 #include "net/log/net_log_event_type.h" |
| 29 #include "net/log/net_log_source_type.h" |
| 28 #include "net/socket/socket_net_log_params.h" | 30 #include "net/socket/socket_net_log_params.h" |
| 29 #include "net/socket/socket_posix.h" | 31 #include "net/socket/socket_posix.h" |
| 30 | 32 |
| 31 // If we don't have a definition for TCPI_OPT_SYN_DATA, create one. | 33 // If we don't have a definition for TCPI_OPT_SYN_DATA, create one. |
| 32 #ifndef TCPI_OPT_SYN_DATA | 34 #ifndef TCPI_OPT_SYN_DATA |
| 33 #define TCPI_OPT_SYN_DATA 32 | 35 #define TCPI_OPT_SYN_DATA 32 |
| 34 #endif | 36 #endif |
| 35 | 37 |
| 36 namespace net { | 38 namespace net { |
| 37 | 39 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 NetLog* net_log, | 144 NetLog* net_log, |
| 143 const NetLog::Source& source) | 145 const NetLog::Source& source) |
| 144 : socket_performance_watcher_(std::move(socket_performance_watcher)), | 146 : socket_performance_watcher_(std::move(socket_performance_watcher)), |
| 145 tick_clock_(new base::DefaultTickClock()), | 147 tick_clock_(new base::DefaultTickClock()), |
| 146 rtt_notifications_minimum_interval_(base::TimeDelta::FromSeconds(1)), | 148 rtt_notifications_minimum_interval_(base::TimeDelta::FromSeconds(1)), |
| 147 use_tcp_fastopen_(false), | 149 use_tcp_fastopen_(false), |
| 148 tcp_fastopen_write_attempted_(false), | 150 tcp_fastopen_write_attempted_(false), |
| 149 tcp_fastopen_connected_(false), | 151 tcp_fastopen_connected_(false), |
| 150 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), | 152 tcp_fastopen_status_(TCP_FASTOPEN_STATUS_UNKNOWN), |
| 151 logging_multiple_connect_attempts_(false), | 153 logging_multiple_connect_attempts_(false), |
| 152 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 154 net_log_(BoundNetLog::Make(net_log, NetLogSourceType::SOCKET)) { |
| 153 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 155 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, |
| 154 source.ToEventParametersCallback()); | 156 source.ToEventParametersCallback()); |
| 155 } | 157 } |
| 156 | 158 |
| 157 TCPSocketPosix::~TCPSocketPosix() { | 159 TCPSocketPosix::~TCPSocketPosix() { |
| 158 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); | 160 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); |
| 159 Close(); | 161 Close(); |
| 160 } | 162 } |
| 161 | 163 |
| 162 int TCPSocketPosix::Open(AddressFamily family) { | 164 int TCPSocketPosix::Open(AddressFamily family) { |
| 163 DCHECK(!socket_); | 165 DCHECK(!socket_); |
| 164 socket_.reset(new SocketPosix); | 166 socket_.reset(new SocketPosix); |
| 165 int rv = socket_->Open(ConvertAddressFamily(family)); | 167 int rv = socket_->Open(ConvertAddressFamily(family)); |
| 166 if (rv != OK) | 168 if (rv != OK) |
| 167 socket_.reset(); | 169 socket_.reset(); |
| 168 return rv; | 170 return rv; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 } | 204 } |
| 203 | 205 |
| 204 int TCPSocketPosix::Accept(std::unique_ptr<TCPSocketPosix>* tcp_socket, | 206 int TCPSocketPosix::Accept(std::unique_ptr<TCPSocketPosix>* tcp_socket, |
| 205 IPEndPoint* address, | 207 IPEndPoint* address, |
| 206 const CompletionCallback& callback) { | 208 const CompletionCallback& callback) { |
| 207 DCHECK(tcp_socket); | 209 DCHECK(tcp_socket); |
| 208 DCHECK(!callback.is_null()); | 210 DCHECK(!callback.is_null()); |
| 209 DCHECK(socket_); | 211 DCHECK(socket_); |
| 210 DCHECK(!accept_socket_); | 212 DCHECK(!accept_socket_); |
| 211 | 213 |
| 212 net_log_.BeginEvent(NetLog::TYPE_TCP_ACCEPT); | 214 net_log_.BeginEvent(NetLogEventType::TCP_ACCEPT); |
| 213 | 215 |
| 214 int rv = socket_->Accept( | 216 int rv = socket_->Accept( |
| 215 &accept_socket_, | 217 &accept_socket_, |
| 216 base::Bind(&TCPSocketPosix::AcceptCompleted, base::Unretained(this), | 218 base::Bind(&TCPSocketPosix::AcceptCompleted, base::Unretained(this), |
| 217 tcp_socket, address, callback)); | 219 tcp_socket, address, callback)); |
| 218 if (rv != ERR_IO_PENDING) | 220 if (rv != ERR_IO_PENDING) |
| 219 rv = HandleAcceptCompleted(tcp_socket, address, rv); | 221 rv = HandleAcceptCompleted(tcp_socket, address, rv); |
| 220 return rv; | 222 return rv; |
| 221 } | 223 } |
| 222 | 224 |
| 223 int TCPSocketPosix::Connect(const IPEndPoint& address, | 225 int TCPSocketPosix::Connect(const IPEndPoint& address, |
| 224 const CompletionCallback& callback) { | 226 const CompletionCallback& callback) { |
| 225 DCHECK(socket_); | 227 DCHECK(socket_); |
| 226 | 228 |
| 227 if (!logging_multiple_connect_attempts_) | 229 if (!logging_multiple_connect_attempts_) |
| 228 LogConnectBegin(AddressList(address)); | 230 LogConnectBegin(AddressList(address)); |
| 229 | 231 |
| 230 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 232 net_log_.BeginEvent(NetLogEventType::TCP_CONNECT_ATTEMPT, |
| 231 CreateNetLogIPEndPointCallback(&address)); | 233 CreateNetLogIPEndPointCallback(&address)); |
| 232 | 234 |
| 233 SockaddrStorage storage; | 235 SockaddrStorage storage; |
| 234 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) | 236 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
| 235 return ERR_ADDRESS_INVALID; | 237 return ERR_ADDRESS_INVALID; |
| 236 | 238 |
| 237 if (use_tcp_fastopen_) { | 239 if (use_tcp_fastopen_) { |
| 238 // With TCP FastOpen, we pretend that the socket is connected. | 240 // With TCP FastOpen, we pretend that the socket is connected. |
| 239 DCHECK(!tcp_fastopen_write_attempted_); | 241 DCHECK(!tcp_fastopen_write_attempted_); |
| 240 socket_->SetPeerAddress(storage); | 242 socket_->SetPeerAddress(storage); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 } | 498 } |
| 497 | 499 |
| 498 int TCPSocketPosix::HandleAcceptCompleted( | 500 int TCPSocketPosix::HandleAcceptCompleted( |
| 499 std::unique_ptr<TCPSocketPosix>* tcp_socket, | 501 std::unique_ptr<TCPSocketPosix>* tcp_socket, |
| 500 IPEndPoint* address, | 502 IPEndPoint* address, |
| 501 int rv) { | 503 int rv) { |
| 502 if (rv == OK) | 504 if (rv == OK) |
| 503 rv = BuildTcpSocketPosix(tcp_socket, address); | 505 rv = BuildTcpSocketPosix(tcp_socket, address); |
| 504 | 506 |
| 505 if (rv == OK) { | 507 if (rv == OK) { |
| 506 net_log_.EndEvent(NetLog::TYPE_TCP_ACCEPT, | 508 net_log_.EndEvent(NetLogEventType::TCP_ACCEPT, |
| 507 CreateNetLogIPEndPointCallback(address)); | 509 CreateNetLogIPEndPointCallback(address)); |
| 508 } else { | 510 } else { |
| 509 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, rv); | 511 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_ACCEPT, rv); |
| 510 } | 512 } |
| 511 | 513 |
| 512 return rv; | 514 return rv; |
| 513 } | 515 } |
| 514 | 516 |
| 515 int TCPSocketPosix::BuildTcpSocketPosix( | 517 int TCPSocketPosix::BuildTcpSocketPosix( |
| 516 std::unique_ptr<TCPSocketPosix>* tcp_socket, | 518 std::unique_ptr<TCPSocketPosix>* tcp_socket, |
| 517 IPEndPoint* address) { | 519 IPEndPoint* address) { |
| 518 DCHECK(accept_socket_); | 520 DCHECK(accept_socket_); |
| 519 | 521 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 532 | 534 |
| 533 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, | 535 void TCPSocketPosix::ConnectCompleted(const CompletionCallback& callback, |
| 534 int rv) { | 536 int rv) { |
| 535 DCHECK_NE(ERR_IO_PENDING, rv); | 537 DCHECK_NE(ERR_IO_PENDING, rv); |
| 536 callback.Run(HandleConnectCompleted(rv)); | 538 callback.Run(HandleConnectCompleted(rv)); |
| 537 } | 539 } |
| 538 | 540 |
| 539 int TCPSocketPosix::HandleConnectCompleted(int rv) { | 541 int TCPSocketPosix::HandleConnectCompleted(int rv) { |
| 540 // 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). |
| 541 if (rv != OK) { | 543 if (rv != OK) { |
| 542 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 544 net_log_.EndEvent(NetLogEventType::TCP_CONNECT_ATTEMPT, |
| 543 NetLog::IntCallback("os_error", errno)); | 545 NetLog::IntCallback("os_error", errno)); |
| 544 } else { | 546 } else { |
| 545 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); | 547 net_log_.EndEvent(NetLogEventType::TCP_CONNECT_ATTEMPT); |
| 546 NotifySocketPerformanceWatcher(); | 548 NotifySocketPerformanceWatcher(); |
| 547 } | 549 } |
| 548 | 550 |
| 549 // Give a more specific error when the user is offline. | 551 // Give a more specific error when the user is offline. |
| 550 if (rv == ERR_ADDRESS_UNREACHABLE && NetworkChangeNotifier::IsOffline()) | 552 if (rv == ERR_ADDRESS_UNREACHABLE && NetworkChangeNotifier::IsOffline()) |
| 551 rv = ERR_INTERNET_DISCONNECTED; | 553 rv = ERR_INTERNET_DISCONNECTED; |
| 552 | 554 |
| 553 if (!logging_multiple_connect_attempts_) | 555 if (!logging_multiple_connect_attempts_) |
| 554 LogConnectEnd(rv); | 556 LogConnectEnd(rv); |
| 555 | 557 |
| 556 return rv; | 558 return rv; |
| 557 } | 559 } |
| 558 | 560 |
| 559 void TCPSocketPosix::LogConnectBegin(const AddressList& addresses) const { | 561 void TCPSocketPosix::LogConnectBegin(const AddressList& addresses) const { |
| 560 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, | 562 net_log_.BeginEvent(NetLogEventType::TCP_CONNECT, |
| 561 addresses.CreateNetLogCallback()); | 563 addresses.CreateNetLogCallback()); |
| 562 } | 564 } |
| 563 | 565 |
| 564 void TCPSocketPosix::LogConnectEnd(int net_error) const { | 566 void TCPSocketPosix::LogConnectEnd(int net_error) const { |
| 565 if (net_error != OK) { | 567 if (net_error != OK) { |
| 566 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); | 568 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, net_error); |
| 567 return; | 569 return; |
| 568 } | 570 } |
| 569 | 571 |
| 570 SockaddrStorage storage; | 572 SockaddrStorage storage; |
| 571 int rv = socket_->GetLocalAddress(&storage); | 573 int rv = socket_->GetLocalAddress(&storage); |
| 572 if (rv != OK) { | 574 if (rv != OK) { |
| 573 PLOG(ERROR) << "GetLocalAddress() [rv: " << rv << "] error: "; | 575 PLOG(ERROR) << "GetLocalAddress() [rv: " << rv << "] error: "; |
| 574 NOTREACHED(); | 576 NOTREACHED(); |
| 575 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); | 577 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, rv); |
| 576 return; | 578 return; |
| 577 } | 579 } |
| 578 | 580 |
| 579 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 581 net_log_.EndEvent(NetLogEventType::TCP_CONNECT, |
| 580 CreateNetLogSourceAddressCallback(storage.addr, | 582 CreateNetLogSourceAddressCallback(storage.addr, |
| 581 storage.addr_len)); | 583 storage.addr_len)); |
| 582 } | 584 } |
| 583 | 585 |
| 584 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, | 586 void TCPSocketPosix::ReadCompleted(const scoped_refptr<IOBuffer>& buf, |
| 585 const CompletionCallback& callback, | 587 const CompletionCallback& callback, |
| 586 int rv) { | 588 int rv) { |
| 587 DCHECK_NE(ERR_IO_PENDING, rv); | 589 DCHECK_NE(ERR_IO_PENDING, rv); |
| 588 callback.Run(HandleReadCompleted(buf.get(), rv)); | 590 callback.Run(HandleReadCompleted(buf.get(), rv)); |
| 589 } | 591 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 600 // such as turning off TCP FastOpen on more specific errors, and | 602 // such as turning off TCP FastOpen on more specific errors, and |
| 601 // re-attempting TCP FastOpen after a certain amount of time has passed. | 603 // re-attempting TCP FastOpen after a certain amount of time has passed. |
| 602 if (rv >= 0) | 604 if (rv >= 0) |
| 603 tcp_fastopen_connected_ = true; | 605 tcp_fastopen_connected_ = true; |
| 604 else | 606 else |
| 605 g_tcp_fastopen_has_failed = true; | 607 g_tcp_fastopen_has_failed = true; |
| 606 UpdateTCPFastOpenStatusAfterRead(); | 608 UpdateTCPFastOpenStatusAfterRead(); |
| 607 } | 609 } |
| 608 | 610 |
| 609 if (rv < 0) { | 611 if (rv < 0) { |
| 610 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 612 net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR, |
| 611 CreateNetLogSocketErrorCallback(rv, errno)); | 613 CreateNetLogSocketErrorCallback(rv, errno)); |
| 612 return rv; | 614 return rv; |
| 613 } | 615 } |
| 614 | 616 |
| 615 // Notify the watcher only if at least 1 byte was read. | 617 // Notify the watcher only if at least 1 byte was read. |
| 616 if (rv > 0) | 618 if (rv > 0) |
| 617 NotifySocketPerformanceWatcher(); | 619 NotifySocketPerformanceWatcher(); |
| 618 | 620 |
| 619 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv, | 621 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_RECEIVED, rv, |
| 620 buf->data()); | 622 buf->data()); |
| 621 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | 623 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); |
| 622 | 624 |
| 623 return rv; | 625 return rv; |
| 624 } | 626 } |
| 625 | 627 |
| 626 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, | 628 void TCPSocketPosix::WriteCompleted(const scoped_refptr<IOBuffer>& buf, |
| 627 const CompletionCallback& callback, | 629 const CompletionCallback& callback, |
| 628 int rv) { | 630 int rv) { |
| 629 DCHECK_NE(ERR_IO_PENDING, rv); | 631 DCHECK_NE(ERR_IO_PENDING, rv); |
| 630 callback.Run(HandleWriteCompleted(buf.get(), rv)); | 632 callback.Run(HandleWriteCompleted(buf.get(), rv)); |
| 631 } | 633 } |
| 632 | 634 |
| 633 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { | 635 int TCPSocketPosix::HandleWriteCompleted(IOBuffer* buf, int rv) { |
| 634 if (rv < 0) { | 636 if (rv < 0) { |
| 635 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 637 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
| 636 // TCP FastOpen connect-with-write was attempted, and the write failed | 638 // TCP FastOpen connect-with-write was attempted, and the write failed |
| 637 // for unknown reasons. Record status and (conservatively) turn off | 639 // for unknown reasons. Record status and (conservatively) turn off |
| 638 // TCP FastOpen for all subsequent connections. | 640 // TCP FastOpen for all subsequent connections. |
| 639 // TODO (jri): This currently results in conservative behavior, where TCP | 641 // TODO (jri): This currently results in conservative behavior, where TCP |
| 640 // FastOpen is turned off on _any_ error. Implement optimizations, | 642 // FastOpen is turned off on _any_ error. Implement optimizations, |
| 641 // such as turning off TCP FastOpen on more specific errors, and | 643 // such as turning off TCP FastOpen on more specific errors, and |
| 642 // re-attempting TCP FastOpen after a certain amount of time has passed. | 644 // re-attempting TCP FastOpen after a certain amount of time has passed. |
| 643 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; | 645 tcp_fastopen_status_ = TCP_FASTOPEN_ERROR; |
| 644 g_tcp_fastopen_has_failed = true; | 646 g_tcp_fastopen_has_failed = true; |
| 645 } | 647 } |
| 646 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 648 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, |
| 647 CreateNetLogSocketErrorCallback(rv, errno)); | 649 CreateNetLogSocketErrorCallback(rv, errno)); |
| 648 return rv; | 650 return rv; |
| 649 } | 651 } |
| 650 | 652 |
| 651 // Notify the watcher only if at least 1 byte was written. | 653 // Notify the watcher only if at least 1 byte was written. |
| 652 if (rv > 0) | 654 if (rv > 0) |
| 653 NotifySocketPerformanceWatcher(); | 655 NotifySocketPerformanceWatcher(); |
| 654 | 656 |
| 655 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, rv, | 657 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_SENT, rv, |
| 656 buf->data()); | 658 buf->data()); |
| 657 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv); | 659 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv); |
| 658 return rv; | 660 return rv; |
| 659 } | 661 } |
| 660 | 662 |
| 661 int TCPSocketPosix::TcpFastOpenWrite(IOBuffer* buf, | 663 int TCPSocketPosix::TcpFastOpenWrite(IOBuffer* buf, |
| 662 int buf_len, | 664 int buf_len, |
| 663 const CompletionCallback& callback) { | 665 const CompletionCallback& callback) { |
| 664 SockaddrStorage storage; | 666 SockaddrStorage storage; |
| 665 int rv = socket_->GetPeerAddress(&storage); | 667 int rv = socket_->GetPeerAddress(&storage); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 if (info.tcpi_rtt > 0) { | 814 if (info.tcpi_rtt > 0) { |
| 813 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); | 815 *out_rtt = base::TimeDelta::FromMicroseconds(info.tcpi_rtt); |
| 814 return true; | 816 return true; |
| 815 } | 817 } |
| 816 } | 818 } |
| 817 #endif // defined(TCP_INFO) | 819 #endif // defined(TCP_INFO) |
| 818 return false; | 820 return false; |
| 819 } | 821 } |
| 820 | 822 |
| 821 } // namespace net | 823 } // namespace net |
| OLD | NEW |