OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_client_socket.h" | 5 #include "net/socket/tcp_client_socket.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <netdb.h> | 9 #include <netdb.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
11 #include <netinet/tcp.h> | 11 #include <netinet/tcp.h> |
12 #if defined(OS_POSIX) | 12 #if defined(OS_POSIX) |
13 #include <netinet/in.h> | 13 #include <netinet/in.h> |
14 #endif | 14 #endif |
15 | 15 |
16 #include "base/eintr_wrapper.h" | 16 #include "base/eintr_wrapper.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/message_loop.h" | 18 #include "base/message_loop.h" |
19 #include "base/metrics/stats_counters.h" | 19 #include "base/metrics/stats_counters.h" |
20 #include "base/string_util.h" | 20 #include "base/string_util.h" |
21 #include "net/base/connection_type_histograms.h" | 21 #include "net/base/connection_type_histograms.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/net_log.h" | 25 #include "net/base/net_log.h" |
26 #include "net/base/net_util.h" | 26 #include "net/base/net_util.h" |
27 #include "net/base/network_change_notifier.h" | 27 #include "net/base/network_change_notifier.h" |
28 #include "net/socket/socket_error_params.h" | 28 #include "net/socket/socket_net_log_params.h" |
29 | 29 |
30 namespace net { | 30 namespace net { |
31 | 31 |
32 namespace { | 32 namespace { |
33 | 33 |
34 const int kInvalidSocket = -1; | 34 const int kInvalidSocket = -1; |
35 const int kTCPKeepAliveSeconds = 45; | 35 const int kTCPKeepAliveSeconds = 45; |
36 | 36 |
37 // SetTCPNoDelay turns on/off buffering in the kernel. By default, TCP sockets | 37 // SetTCPNoDelay turns on/off buffering in the kernel. By default, TCP sockets |
38 // will wait up to 200ms for more data to complete a packet before transmitting. | 38 // will wait up to 200ms for more data to complete a packet before transmitting. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 current_address_index_(-1), | 132 current_address_index_(-1), |
133 read_watcher_(this), | 133 read_watcher_(this), |
134 write_watcher_(this), | 134 write_watcher_(this), |
135 next_connect_state_(CONNECT_STATE_NONE), | 135 next_connect_state_(CONNECT_STATE_NONE), |
136 connect_os_error_(0), | 136 connect_os_error_(0), |
137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
138 previously_disconnected_(false), | 138 previously_disconnected_(false), |
139 use_tcp_fastopen_(false), | 139 use_tcp_fastopen_(false), |
140 tcp_fastopen_connected_(false), | 140 tcp_fastopen_connected_(false), |
141 num_bytes_read_(0) { | 141 num_bytes_read_(0) { |
142 scoped_refptr<NetLog::EventParameters> params; | 142 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
143 if (source.is_valid()) | 143 source.ToEventParametersCallback()); |
144 params = new NetLogSourceParameter("source_dependency", source); | |
145 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | |
146 | 144 |
147 if (is_tcp_fastopen_enabled()) | 145 if (is_tcp_fastopen_enabled()) |
148 use_tcp_fastopen_ = true; | 146 use_tcp_fastopen_ = true; |
149 } | 147 } |
150 | 148 |
151 TCPClientSocketLibevent::~TCPClientSocketLibevent() { | 149 TCPClientSocketLibevent::~TCPClientSocketLibevent() { |
152 Disconnect(); | 150 Disconnect(); |
153 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 151 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); |
154 } | 152 } |
155 | 153 |
156 int TCPClientSocketLibevent::AdoptSocket(int socket) { | 154 int TCPClientSocketLibevent::AdoptSocket(int socket) { |
157 DCHECK_EQ(socket_, kInvalidSocket); | 155 DCHECK_EQ(socket_, kInvalidSocket); |
158 | 156 |
159 int error = SetupSocket(socket); | 157 int error = SetupSocket(socket); |
160 if (error) | 158 if (error) |
161 return MapSystemError(error); | 159 return MapSystemError(error); |
162 | 160 |
163 socket_ = socket; | 161 socket_ = socket; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 DCHECK_EQ(0, connect_os_error_); | 261 DCHECK_EQ(0, connect_os_error_); |
264 | 262 |
265 const IPEndPoint& endpoint = addresses_[current_address_index_]; | 263 const IPEndPoint& endpoint = addresses_[current_address_index_]; |
266 | 264 |
267 if (previously_disconnected_) { | 265 if (previously_disconnected_) { |
268 use_history_.Reset(); | 266 use_history_.Reset(); |
269 previously_disconnected_ = false; | 267 previously_disconnected_ = false; |
270 } | 268 } |
271 | 269 |
272 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, | 270 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
273 make_scoped_refptr(new NetLogStringParameter( | 271 CreateNetLogIPEndPointCallback(&endpoint)); |
274 "address", | |
275 endpoint.ToString()))); | |
276 | 272 |
277 next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; | 273 next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; |
278 | 274 |
279 if (bound_socket_ != kInvalidSocket) { | 275 if (bound_socket_ != kInvalidSocket) { |
280 DCHECK(bind_address_.get()); | 276 DCHECK(bind_address_.get()); |
281 socket_ = bound_socket_; | 277 socket_ = bound_socket_; |
282 bound_socket_ = kInvalidSocket; | 278 bound_socket_ = kInvalidSocket; |
283 } else { | 279 } else { |
284 // Create a non-blocking socket. | 280 // Create a non-blocking socket. |
285 connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_); | 281 connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 return MapSystemError(connect_os_error_); | 323 return MapSystemError(connect_os_error_); |
328 } | 324 } |
329 | 325 |
330 return ERR_IO_PENDING; | 326 return ERR_IO_PENDING; |
331 } | 327 } |
332 | 328 |
333 int TCPClientSocketLibevent::DoConnectComplete(int result) { | 329 int TCPClientSocketLibevent::DoConnectComplete(int result) { |
334 // Log the end of this attempt (and any OS error it threw). | 330 // Log the end of this attempt (and any OS error it threw). |
335 int os_error = connect_os_error_; | 331 int os_error = connect_os_error_; |
336 connect_os_error_ = 0; | 332 connect_os_error_ = 0; |
337 scoped_refptr<NetLog::EventParameters> params; | 333 if (result != OK) { |
338 if (result != OK) | 334 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, |
339 params = new NetLogIntegerParameter("os_error", os_error); | 335 NetLog::IntegerCallback("os_error", os_error)); |
340 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); | 336 } else { |
| 337 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); |
| 338 } |
341 | 339 |
342 if (result == OK) { | 340 if (result == OK) { |
343 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; | 341 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; |
344 write_socket_watcher_.StopWatchingFileDescriptor(); | 342 write_socket_watcher_.StopWatchingFileDescriptor(); |
345 use_history_.set_was_ever_connected(); | 343 use_history_.set_was_ever_connected(); |
346 return OK; // Done! | 344 return OK; // Done! |
347 } | 345 } |
348 | 346 |
349 // Close whatever partially connected socket we currently have. | 347 // Close whatever partially connected socket we currently have. |
350 DoDisconnect(); | 348 DoDisconnect(); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 num_bytes_read_ += static_cast<int64>(nread); | 444 num_bytes_read_ += static_cast<int64>(nread); |
447 if (nread > 0) | 445 if (nread > 0) |
448 use_history_.set_was_used_to_convey_data(); | 446 use_history_.set_was_used_to_convey_data(); |
449 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, | 447 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, |
450 buf->data()); | 448 buf->data()); |
451 return nread; | 449 return nread; |
452 } | 450 } |
453 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 451 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
454 int net_error = MapSystemError(errno); | 452 int net_error = MapSystemError(errno); |
455 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 453 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
456 make_scoped_refptr(new SocketErrorParams(net_error, errno))); | 454 CreateNetLogSocketErrorCallback(net_error, errno)); |
457 return net_error; | 455 return net_error; |
458 } | 456 } |
459 | 457 |
460 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 458 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
461 socket_, true, MessageLoopForIO::WATCH_READ, | 459 socket_, true, MessageLoopForIO::WATCH_READ, |
462 &read_socket_watcher_, &read_watcher_)) { | 460 &read_socket_watcher_, &read_watcher_)) { |
463 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; | 461 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; |
464 return MapSystemError(errno); | 462 return MapSystemError(errno); |
465 } | 463 } |
466 | 464 |
(...skipping 20 matching lines...) Expand all Loading... |
487 write_bytes.Add(nwrite); | 485 write_bytes.Add(nwrite); |
488 if (nwrite > 0) | 486 if (nwrite > 0) |
489 use_history_.set_was_used_to_convey_data(); | 487 use_history_.set_was_used_to_convey_data(); |
490 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, | 488 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, |
491 buf->data()); | 489 buf->data()); |
492 return nwrite; | 490 return nwrite; |
493 } | 491 } |
494 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 492 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
495 int net_error = MapSystemError(errno); | 493 int net_error = MapSystemError(errno); |
496 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 494 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
497 make_scoped_refptr(new SocketErrorParams(net_error, errno))); | 495 CreateNetLogSocketErrorCallback(net_error, errno)); |
498 return net_error; | 496 return net_error; |
499 } | 497 } |
500 | 498 |
501 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 499 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
502 socket_, true, MessageLoopForIO::WATCH_WRITE, | 500 socket_, true, MessageLoopForIO::WATCH_WRITE, |
503 &write_socket_watcher_, &write_watcher_)) { | 501 &write_socket_watcher_, &write_watcher_)) { |
504 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; | 502 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; |
505 return MapSystemError(errno); | 503 return MapSystemError(errno); |
506 } | 504 } |
507 | 505 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 | 589 |
592 SockaddrStorage storage; | 590 SockaddrStorage storage; |
593 int rv = getsockname(socket_, storage.addr, &storage.addr_len); | 591 int rv = getsockname(socket_, storage.addr, &storage.addr_len); |
594 if (rv != 0) { | 592 if (rv != 0) { |
595 PLOG(ERROR) << "getsockname() [rv: " << rv << "] error: "; | 593 PLOG(ERROR) << "getsockname() [rv: " << rv << "] error: "; |
596 NOTREACHED(); | 594 NOTREACHED(); |
597 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); | 595 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); |
598 return; | 596 return; |
599 } | 597 } |
600 | 598 |
601 const std::string source_address_str = | |
602 NetAddressToStringWithPort(storage.addr, storage.addr_len); | |
603 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 599 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, |
604 make_scoped_refptr(new NetLogStringParameter( | 600 CreateNetLogSourceAddressCallback(storage.addr, |
605 "source address", | 601 storage.addr_len)); |
606 source_address_str))); | |
607 } | 602 } |
608 | 603 |
609 void TCPClientSocketLibevent::DoReadCallback(int rv) { | 604 void TCPClientSocketLibevent::DoReadCallback(int rv) { |
610 DCHECK_NE(rv, ERR_IO_PENDING); | 605 DCHECK_NE(rv, ERR_IO_PENDING); |
611 DCHECK(!read_callback_.is_null()); | 606 DCHECK(!read_callback_.is_null()); |
612 | 607 |
613 // since Run may result in Read being called, clear read_callback_ up front. | 608 // since Run may result in Read being called, clear read_callback_ up front. |
614 CompletionCallback c = read_callback_; | 609 CompletionCallback c = read_callback_; |
615 read_callback_.Reset(); | 610 read_callback_.Reset(); |
616 c.Run(rv); | 611 c.Run(rv); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 read_bytes.Add(bytes_transferred); | 656 read_bytes.Add(bytes_transferred); |
662 num_bytes_read_ += static_cast<int64>(bytes_transferred); | 657 num_bytes_read_ += static_cast<int64>(bytes_transferred); |
663 if (bytes_transferred > 0) | 658 if (bytes_transferred > 0) |
664 use_history_.set_was_used_to_convey_data(); | 659 use_history_.set_was_used_to_convey_data(); |
665 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, | 660 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, |
666 read_buf_->data()); | 661 read_buf_->data()); |
667 } else { | 662 } else { |
668 result = MapSystemError(errno); | 663 result = MapSystemError(errno); |
669 if (result != ERR_IO_PENDING) { | 664 if (result != ERR_IO_PENDING) { |
670 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, | 665 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, |
671 make_scoped_refptr(new SocketErrorParams(result, errno))); | 666 CreateNetLogSocketErrorCallback(result, errno)); |
672 } | 667 } |
673 } | 668 } |
674 | 669 |
675 if (result != ERR_IO_PENDING) { | 670 if (result != ERR_IO_PENDING) { |
676 read_buf_ = NULL; | 671 read_buf_ = NULL; |
677 read_buf_len_ = 0; | 672 read_buf_len_ = 0; |
678 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 673 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
679 DCHECK(ok); | 674 DCHECK(ok); |
680 DoReadCallback(result); | 675 DoReadCallback(result); |
681 } | 676 } |
(...skipping 10 matching lines...) Expand all Loading... |
692 base::StatsCounter write_bytes("tcp.write_bytes"); | 687 base::StatsCounter write_bytes("tcp.write_bytes"); |
693 write_bytes.Add(bytes_transferred); | 688 write_bytes.Add(bytes_transferred); |
694 if (bytes_transferred > 0) | 689 if (bytes_transferred > 0) |
695 use_history_.set_was_used_to_convey_data(); | 690 use_history_.set_was_used_to_convey_data(); |
696 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, result, | 691 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, result, |
697 write_buf_->data()); | 692 write_buf_->data()); |
698 } else { | 693 } else { |
699 result = MapSystemError(errno); | 694 result = MapSystemError(errno); |
700 if (result != ERR_IO_PENDING) { | 695 if (result != ERR_IO_PENDING) { |
701 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, | 696 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, |
702 make_scoped_refptr(new SocketErrorParams(result, errno))); | 697 CreateNetLogSocketErrorCallback(result, errno)); |
703 } | 698 } |
704 } | 699 } |
705 | 700 |
706 if (result != ERR_IO_PENDING) { | 701 if (result != ERR_IO_PENDING) { |
707 write_buf_ = NULL; | 702 write_buf_ = NULL; |
708 write_buf_len_ = 0; | 703 write_buf_len_ = 0; |
709 write_socket_watcher_.StopWatchingFileDescriptor(); | 704 write_socket_watcher_.StopWatchingFileDescriptor(); |
710 DoWriteCallback(result); | 705 DoWriteCallback(result); |
711 } | 706 } |
712 } | 707 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 | 756 |
762 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { | 757 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { |
763 return connect_time_micros_; | 758 return connect_time_micros_; |
764 } | 759 } |
765 | 760 |
766 NextProto TCPClientSocketLibevent::GetNegotiatedProtocol() const { | 761 NextProto TCPClientSocketLibevent::GetNegotiatedProtocol() const { |
767 return kProtoUnknown; | 762 return kProtoUnknown; |
768 } | 763 } |
769 | 764 |
770 } // namespace net | 765 } // namespace net |
OLD | NEW |