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( |
580 CreateNetLogSourceAddressCallback(storage.addr, | 582 NetLogEventType::TCP_CONNECT, |
581 storage.addr_len)); | 583 CreateNetLogSourceAddressCallback(storage.addr, 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 } |
590 | 592 |
591 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { | 593 int TCPSocketPosix::HandleReadCompleted(IOBuffer* buf, int rv) { |
592 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { | 594 if (tcp_fastopen_write_attempted_ && !tcp_fastopen_connected_) { |
593 // A TCP FastOpen connect-with-write was attempted. This read was a | 595 // A TCP FastOpen connect-with-write was attempted. This read was a |
594 // subsequent read, which either succeeded or failed. If the read | 596 // subsequent read, which either succeeded or failed. If the read |
595 // succeeded, the socket is considered connected via TCP FastOpen. | 597 // succeeded, the socket is considered connected via TCP FastOpen. |
596 // If the read failed, TCP FastOpen is (conservatively) turned off for all | 598 // If the read failed, TCP FastOpen is (conservatively) turned off for all |
597 // subsequent connections. TCP FastOpen status is recorded in both cases. | 599 // subsequent connections. TCP FastOpen status is recorded in both cases. |
598 // TODO (jri): This currently results in conservative behavior, where TCP | 600 // TODO (jri): This currently results in conservative behavior, where TCP |
599 // FastOpen is turned off on _any_ error. Implement optimizations, | 601 // FastOpen is turned off on _any_ error. Implement optimizations, |
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 |