OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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> |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 current_ai_(NULL), | 135 current_ai_(NULL), |
136 read_watcher_(this), | 136 read_watcher_(this), |
137 write_watcher_(this), | 137 write_watcher_(this), |
138 read_callback_(NULL), | 138 read_callback_(NULL), |
139 write_callback_(NULL), | 139 write_callback_(NULL), |
140 next_connect_state_(CONNECT_STATE_NONE), | 140 next_connect_state_(CONNECT_STATE_NONE), |
141 connect_os_error_(0), | 141 connect_os_error_(0), |
142 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 142 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
143 previously_disconnected_(false), | 143 previously_disconnected_(false), |
144 use_tcp_fastopen_(false), | 144 use_tcp_fastopen_(false), |
145 tcp_fastopen_connected_(false) { | 145 tcp_fastopen_connected_(false), |
| 146 num_bytes_read_(0), |
| 147 connect_time_micros_(-1) { |
146 scoped_refptr<NetLog::EventParameters> params; | 148 scoped_refptr<NetLog::EventParameters> params; |
147 if (source.is_valid()) | 149 if (source.is_valid()) |
148 params = new NetLogSourceParameter("source_dependency", source); | 150 params = new NetLogSourceParameter("source_dependency", source); |
149 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 151 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
150 | 152 |
151 if (is_tcp_fastopen_enabled()) | 153 if (is_tcp_fastopen_enabled()) |
152 use_tcp_fastopen_ = true; | 154 use_tcp_fastopen_ = true; |
153 } | 155 } |
154 | 156 |
155 TCPClientSocketLibevent::~TCPClientSocketLibevent() { | 157 TCPClientSocketLibevent::~TCPClientSocketLibevent() { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 size_t addr_len = sizeof(addr_storage); | 298 size_t addr_len = sizeof(addr_storage); |
297 if (!bind_address_->ToSockAddr(addr, &addr_len)) | 299 if (!bind_address_->ToSockAddr(addr, &addr_len)) |
298 return ERR_INVALID_ARGUMENT; | 300 return ERR_INVALID_ARGUMENT; |
299 if (HANDLE_EINTR(bind(socket_, addr, addr_len))) | 301 if (HANDLE_EINTR(bind(socket_, addr, addr_len))) |
300 return MapSystemError(errno); | 302 return MapSystemError(errno); |
301 } | 303 } |
302 } | 304 } |
303 | 305 |
304 // Connect the socket. | 306 // Connect the socket. |
305 if (!use_tcp_fastopen_) { | 307 if (!use_tcp_fastopen_) { |
| 308 connect_start_time_ = base::TimeTicks::Now(); |
306 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, | 309 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, |
307 static_cast<int>(current_ai_->ai_addrlen)))) { | 310 static_cast<int>(current_ai_->ai_addrlen)))) { |
308 // Connected without waiting! | 311 // Connected without waiting! |
309 return OK; | 312 return OK; |
310 } | 313 } |
311 } else { | 314 } else { |
312 // With TCP FastOpen, we pretend that the socket is connected. | 315 // With TCP FastOpen, we pretend that the socket is connected. |
313 DCHECK(!tcp_fastopen_connected_); | 316 DCHECK(!tcp_fastopen_connected_); |
314 return OK; | 317 return OK; |
315 } | 318 } |
(...skipping 21 matching lines...) Expand all Loading... |
337 int os_error = connect_os_error_; | 340 int os_error = connect_os_error_; |
338 connect_os_error_ = 0; | 341 connect_os_error_ = 0; |
339 scoped_refptr<NetLog::EventParameters> params; | 342 scoped_refptr<NetLog::EventParameters> params; |
340 if (result != OK) | 343 if (result != OK) |
341 params = new NetLogIntegerParameter("os_error", os_error); | 344 params = new NetLogIntegerParameter("os_error", os_error); |
342 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); | 345 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, params); |
343 | 346 |
344 write_socket_watcher_.StopWatchingFileDescriptor(); | 347 write_socket_watcher_.StopWatchingFileDescriptor(); |
345 | 348 |
346 if (result == OK) { | 349 if (result == OK) { |
| 350 connect_time_micros_ = (base::TimeTicks::Now() - |
| 351 connect_start_time_).ToInternalValue(); |
347 use_history_.set_was_ever_connected(); | 352 use_history_.set_was_ever_connected(); |
348 return OK; // Done! | 353 return OK; // Done! |
349 } | 354 } |
350 | 355 |
351 // Close whatever partially connected socket we currently have. | 356 // Close whatever partially connected socket we currently have. |
352 DoDisconnect(); | 357 DoDisconnect(); |
353 | 358 |
354 // Try to fall back to the next address in the list. | 359 // Try to fall back to the next address in the list. |
355 if (current_ai_->ai_next) { | 360 if (current_ai_->ai_next) { |
356 next_connect_state_ = CONNECT_STATE_CONNECT; | 361 next_connect_state_ = CONNECT_STATE_CONNECT; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 CompletionCallback* callback) { | 428 CompletionCallback* callback) { |
424 DCHECK(CalledOnValidThread()); | 429 DCHECK(CalledOnValidThread()); |
425 DCHECK_NE(kInvalidSocket, socket_); | 430 DCHECK_NE(kInvalidSocket, socket_); |
426 DCHECK(!waiting_connect()); | 431 DCHECK(!waiting_connect()); |
427 DCHECK(!read_callback_); | 432 DCHECK(!read_callback_); |
428 // Synchronous operation not supported | 433 // Synchronous operation not supported |
429 DCHECK(callback); | 434 DCHECK(callback); |
430 DCHECK_GT(buf_len, 0); | 435 DCHECK_GT(buf_len, 0); |
431 | 436 |
432 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | 437 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
| 438 LOG(ERROR) << "this = " << (int*) this << "\tnread = " << nread; |
433 if (nread >= 0) { | 439 if (nread >= 0) { |
434 base::StatsCounter read_bytes("tcp.read_bytes"); | 440 base::StatsCounter read_bytes("tcp.read_bytes"); |
435 read_bytes.Add(nread); | 441 read_bytes.Add(nread); |
| 442 num_bytes_read_ += static_cast<int64>(nread); |
| 443 LOG(ERROR) << "this = " << (int*) this << "\tRead " << nread; |
436 if (nread > 0) | 444 if (nread > 0) |
437 use_history_.set_was_used_to_convey_data(); | 445 use_history_.set_was_used_to_convey_data(); |
438 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, | 446 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, |
439 buf->data()); | 447 buf->data()); |
440 return nread; | 448 return nread; |
441 } | 449 } |
442 if (errno != EAGAIN && errno != EWOULDBLOCK) { | 450 if (errno != EAGAIN && errno != EWOULDBLOCK) { |
443 DVLOG(1) << "read failed, errno " << errno; | 451 DVLOG(1) << "read failed, errno " << errno; |
444 return MapSystemError(errno); | 452 return MapSystemError(errno); |
445 } | 453 } |
446 | 454 |
447 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 455 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
448 socket_, true, MessageLoopForIO::WATCH_READ, | 456 socket_, true, MessageLoopForIO::WATCH_READ, |
449 &read_socket_watcher_, &read_watcher_)) { | 457 &read_socket_watcher_, &read_watcher_)) { |
450 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; | 458 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; |
451 return MapSystemError(errno); | 459 return MapSystemError(errno); |
452 } | 460 } |
453 | 461 |
| 462 LOG(ERROR) << "this = " << (int*) this << "\tread_buf_len_ = " << read_buf_len
_; |
454 read_buf_ = buf; | 463 read_buf_ = buf; |
455 read_buf_len_ = buf_len; | 464 read_buf_len_ = buf_len; |
456 read_callback_ = callback; | 465 read_callback_ = callback; |
457 return ERR_IO_PENDING; | 466 return ERR_IO_PENDING; |
458 } | 467 } |
459 | 468 |
460 int TCPClientSocketLibevent::Write(IOBuffer* buf, | 469 int TCPClientSocketLibevent::Write(IOBuffer* buf, |
461 int buf_len, | 470 int buf_len, |
462 CompletionCallback* callback) { | 471 CompletionCallback* callback) { |
463 DCHECK(CalledOnValidThread()); | 472 DCHECK(CalledOnValidThread()); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 void TCPClientSocketLibevent::DidCompleteRead() { | 629 void TCPClientSocketLibevent::DidCompleteRead() { |
621 int bytes_transferred; | 630 int bytes_transferred; |
622 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), | 631 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), |
623 read_buf_len_)); | 632 read_buf_len_)); |
624 | 633 |
625 int result; | 634 int result; |
626 if (bytes_transferred >= 0) { | 635 if (bytes_transferred >= 0) { |
627 result = bytes_transferred; | 636 result = bytes_transferred; |
628 base::StatsCounter read_bytes("tcp.read_bytes"); | 637 base::StatsCounter read_bytes("tcp.read_bytes"); |
629 read_bytes.Add(bytes_transferred); | 638 read_bytes.Add(bytes_transferred); |
| 639 num_bytes_read_ += static_cast<int64>(bytes_transferred); |
| 640 LOG(ERROR) << "this = " << (int*) this << "\tRead " << bytes_transferred; |
630 if (bytes_transferred > 0) | 641 if (bytes_transferred > 0) |
631 use_history_.set_was_used_to_convey_data(); | 642 use_history_.set_was_used_to_convey_data(); |
632 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, | 643 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, |
633 read_buf_->data()); | 644 read_buf_->data()); |
634 } else { | 645 } else { |
635 result = MapSystemError(errno); | 646 result = MapSystemError(errno); |
636 } | 647 } |
637 | 648 |
638 if (result != ERR_IO_PENDING) { | 649 if (result != ERR_IO_PENDING) { |
639 read_buf_ = NULL; | 650 read_buf_ = NULL; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 | 721 |
711 bool TCPClientSocketLibevent::WasEverUsed() const { | 722 bool TCPClientSocketLibevent::WasEverUsed() const { |
712 return use_history_.was_used_to_convey_data(); | 723 return use_history_.was_used_to_convey_data(); |
713 } | 724 } |
714 | 725 |
715 bool TCPClientSocketLibevent::UsingTCPFastOpen() const { | 726 bool TCPClientSocketLibevent::UsingTCPFastOpen() const { |
716 return use_tcp_fastopen_; | 727 return use_tcp_fastopen_; |
717 } | 728 } |
718 | 729 |
719 } // namespace net | 730 } // namespace net |
OLD | NEW |