| 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 TCPClientSocketLibevent::TCPClientSocketLibevent( | 123 TCPClientSocketLibevent::TCPClientSocketLibevent( |
| 124 const AddressList& addresses, | 124 const AddressList& addresses, |
| 125 net::NetLog* net_log, | 125 net::NetLog* net_log, |
| 126 const net::NetLog::Source& source) | 126 const net::NetLog::Source& source) |
| 127 : socket_(kInvalidSocket), | 127 : socket_(kInvalidSocket), |
| 128 bound_socket_(kInvalidSocket), | 128 bound_socket_(kInvalidSocket), |
| 129 addresses_(addresses), | 129 addresses_(addresses), |
| 130 current_ai_(NULL), | 130 current_ai_(NULL), |
| 131 read_watcher_(this), | 131 read_watcher_(this), |
| 132 write_watcher_(this), | 132 write_watcher_(this), |
| 133 old_read_callback_(NULL), | |
| 134 old_write_callback_(NULL), | |
| 135 next_connect_state_(CONNECT_STATE_NONE), | 133 next_connect_state_(CONNECT_STATE_NONE), |
| 136 connect_os_error_(0), | 134 connect_os_error_(0), |
| 137 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | 135 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), |
| 138 previously_disconnected_(false), | 136 previously_disconnected_(false), |
| 139 use_tcp_fastopen_(false), | 137 use_tcp_fastopen_(false), |
| 140 tcp_fastopen_connected_(false), | 138 tcp_fastopen_connected_(false), |
| 141 num_bytes_read_(0) { | 139 num_bytes_read_(0) { |
| 142 scoped_refptr<NetLog::EventParameters> params; | 140 scoped_refptr<NetLog::EventParameters> params; |
| 143 if (source.is_valid()) | 141 if (source.is_valid()) |
| 144 params = new NetLogSourceParameter("source_dependency", source); | 142 params = new NetLogSourceParameter("source_dependency", source); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 PLOG(ERROR) << "close"; | 193 PLOG(ERROR) << "close"; |
| 196 bound_socket_ = kInvalidSocket; | 194 bound_socket_ = kInvalidSocket; |
| 197 return MapSystemError(error); | 195 return MapSystemError(error); |
| 198 } | 196 } |
| 199 | 197 |
| 200 bind_address_.reset(new IPEndPoint(address)); | 198 bind_address_.reset(new IPEndPoint(address)); |
| 201 | 199 |
| 202 return 0; | 200 return 0; |
| 203 } | 201 } |
| 204 | 202 |
| 205 int TCPClientSocketLibevent::Connect(OldCompletionCallback* callback) { | |
| 206 DCHECK(CalledOnValidThread()); | |
| 207 | |
| 208 // If already connected, then just return OK. | |
| 209 if (socket_ != kInvalidSocket) | |
| 210 return OK; | |
| 211 | |
| 212 base::StatsCounter connects("tcp.connect"); | |
| 213 connects.Increment(); | |
| 214 | |
| 215 DCHECK(!waiting_connect()); | |
| 216 | |
| 217 net_log_.BeginEvent( | |
| 218 NetLog::TYPE_TCP_CONNECT, | |
| 219 make_scoped_refptr(new AddressListNetLogParam(addresses_))); | |
| 220 | |
| 221 // We will try to connect to each address in addresses_. Start with the | |
| 222 // first one in the list. | |
| 223 next_connect_state_ = CONNECT_STATE_CONNECT; | |
| 224 current_ai_ = addresses_.head(); | |
| 225 | |
| 226 int rv = DoConnectLoop(OK); | |
| 227 if (rv == ERR_IO_PENDING) { | |
| 228 // Synchronous operation not supported. | |
| 229 DCHECK(callback); | |
| 230 old_write_callback_ = callback; | |
| 231 } else { | |
| 232 LogConnectCompletion(rv); | |
| 233 } | |
| 234 | |
| 235 return rv; | |
| 236 } | |
| 237 int TCPClientSocketLibevent::Connect(const CompletionCallback& callback) { | 203 int TCPClientSocketLibevent::Connect(const CompletionCallback& callback) { |
| 238 DCHECK(CalledOnValidThread()); | 204 DCHECK(CalledOnValidThread()); |
| 239 | 205 |
| 240 // If already connected, then just return OK. | 206 // If already connected, then just return OK. |
| 241 if (socket_ != kInvalidSocket) | 207 if (socket_ != kInvalidSocket) |
| 242 return OK; | 208 return OK; |
| 243 | 209 |
| 244 base::StatsCounter connects("tcp.connect"); | 210 base::StatsCounter connects("tcp.connect"); |
| 245 connects.Increment(); | 211 connects.Increment(); |
| 246 | 212 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 if (rv >= 0) | 420 if (rv >= 0) |
| 455 return false; | 421 return false; |
| 456 if (errno != EAGAIN && errno != EWOULDBLOCK) | 422 if (errno != EAGAIN && errno != EWOULDBLOCK) |
| 457 return false; | 423 return false; |
| 458 | 424 |
| 459 return true; | 425 return true; |
| 460 } | 426 } |
| 461 | 427 |
| 462 int TCPClientSocketLibevent::Read(IOBuffer* buf, | 428 int TCPClientSocketLibevent::Read(IOBuffer* buf, |
| 463 int buf_len, | 429 int buf_len, |
| 464 OldCompletionCallback* callback) { | |
| 465 DCHECK(CalledOnValidThread()); | |
| 466 DCHECK_NE(kInvalidSocket, socket_); | |
| 467 DCHECK(!waiting_connect()); | |
| 468 DCHECK(!old_read_callback_ && read_callback_.is_null()); | |
| 469 // Synchronous operation not supported | |
| 470 DCHECK(callback); | |
| 471 DCHECK_GT(buf_len, 0); | |
| 472 | |
| 473 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | |
| 474 if (nread >= 0) { | |
| 475 base::StatsCounter read_bytes("tcp.read_bytes"); | |
| 476 read_bytes.Add(nread); | |
| 477 num_bytes_read_ += static_cast<int64>(nread); | |
| 478 if (nread > 0) | |
| 479 use_history_.set_was_used_to_convey_data(); | |
| 480 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, | |
| 481 buf->data()); | |
| 482 return nread; | |
| 483 } | |
| 484 if (errno != EAGAIN && errno != EWOULDBLOCK) { | |
| 485 DVLOG(1) << "read failed, errno " << errno; | |
| 486 return MapSystemError(errno); | |
| 487 } | |
| 488 | |
| 489 if (!MessageLoopForIO::current()->WatchFileDescriptor( | |
| 490 socket_, true, MessageLoopForIO::WATCH_READ, | |
| 491 &read_socket_watcher_, &read_watcher_)) { | |
| 492 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; | |
| 493 return MapSystemError(errno); | |
| 494 } | |
| 495 | |
| 496 read_buf_ = buf; | |
| 497 read_buf_len_ = buf_len; | |
| 498 old_read_callback_ = callback; | |
| 499 return ERR_IO_PENDING; | |
| 500 } | |
| 501 int TCPClientSocketLibevent::Read(IOBuffer* buf, | |
| 502 int buf_len, | |
| 503 const CompletionCallback& callback) { | 430 const CompletionCallback& callback) { |
| 504 DCHECK(CalledOnValidThread()); | 431 DCHECK(CalledOnValidThread()); |
| 505 DCHECK_NE(kInvalidSocket, socket_); | 432 DCHECK_NE(kInvalidSocket, socket_); |
| 506 DCHECK(!waiting_connect()); | 433 DCHECK(!waiting_connect()); |
| 507 DCHECK(!old_read_callback_ && read_callback_.is_null()); | 434 DCHECK(read_callback_.is_null()); |
| 508 // Synchronous operation not supported | 435 // Synchronous operation not supported |
| 509 DCHECK(!callback.is_null()); | 436 DCHECK(!callback.is_null()); |
| 510 DCHECK_GT(buf_len, 0); | 437 DCHECK_GT(buf_len, 0); |
| 511 | 438 |
| 512 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); | 439 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); |
| 513 if (nread >= 0) { | 440 if (nread >= 0) { |
| 514 base::StatsCounter read_bytes("tcp.read_bytes"); | 441 base::StatsCounter read_bytes("tcp.read_bytes"); |
| 515 read_bytes.Add(nread); | 442 read_bytes.Add(nread); |
| 516 num_bytes_read_ += static_cast<int64>(nread); | 443 num_bytes_read_ += static_cast<int64>(nread); |
| 517 if (nread > 0) | 444 if (nread > 0) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 533 } | 460 } |
| 534 | 461 |
| 535 read_buf_ = buf; | 462 read_buf_ = buf; |
| 536 read_buf_len_ = buf_len; | 463 read_buf_len_ = buf_len; |
| 537 read_callback_ = callback; | 464 read_callback_ = callback; |
| 538 return ERR_IO_PENDING; | 465 return ERR_IO_PENDING; |
| 539 } | 466 } |
| 540 | 467 |
| 541 int TCPClientSocketLibevent::Write(IOBuffer* buf, | 468 int TCPClientSocketLibevent::Write(IOBuffer* buf, |
| 542 int buf_len, | 469 int buf_len, |
| 543 OldCompletionCallback* callback) { | 470 const CompletionCallback& callback) { |
| 544 DCHECK(CalledOnValidThread()); | 471 DCHECK(CalledOnValidThread()); |
| 545 DCHECK_NE(kInvalidSocket, socket_); | 472 DCHECK_NE(kInvalidSocket, socket_); |
| 546 DCHECK(!waiting_connect()); | 473 DCHECK(!waiting_connect()); |
| 547 DCHECK(!old_write_callback_ && write_callback_.is_null()); | 474 DCHECK(write_callback_.is_null()); |
| 548 // Synchronous operation not supported | 475 // Synchronous operation not supported |
| 549 DCHECK(callback); | 476 DCHECK(!callback.is_null()); |
| 550 DCHECK_GT(buf_len, 0); | 477 DCHECK_GT(buf_len, 0); |
| 551 | 478 |
| 552 int nwrite = InternalWrite(buf, buf_len); | 479 int nwrite = InternalWrite(buf, buf_len); |
| 553 if (nwrite >= 0) { | 480 if (nwrite >= 0) { |
| 554 base::StatsCounter write_bytes("tcp.write_bytes"); | 481 base::StatsCounter write_bytes("tcp.write_bytes"); |
| 555 write_bytes.Add(nwrite); | 482 write_bytes.Add(nwrite); |
| 556 if (nwrite > 0) | 483 if (nwrite > 0) |
| 557 use_history_.set_was_used_to_convey_data(); | 484 use_history_.set_was_used_to_convey_data(); |
| 558 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, | 485 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, |
| 559 buf->data()); | 486 buf->data()); |
| 560 return nwrite; | 487 return nwrite; |
| 561 } | 488 } |
| 562 if (errno != EAGAIN && errno != EWOULDBLOCK) | 489 if (errno != EAGAIN && errno != EWOULDBLOCK) |
| 563 return MapSystemError(errno); | 490 return MapSystemError(errno); |
| 564 | 491 |
| 565 if (!MessageLoopForIO::current()->WatchFileDescriptor( | 492 if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| 566 socket_, true, MessageLoopForIO::WATCH_WRITE, | 493 socket_, true, MessageLoopForIO::WATCH_WRITE, |
| 567 &write_socket_watcher_, &write_watcher_)) { | 494 &write_socket_watcher_, &write_watcher_)) { |
| 568 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; | 495 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; |
| 569 return MapSystemError(errno); | 496 return MapSystemError(errno); |
| 570 } | 497 } |
| 571 | 498 |
| 572 write_buf_ = buf; | 499 write_buf_ = buf; |
| 573 write_buf_len_ = buf_len; | 500 write_buf_len_ = buf_len; |
| 574 old_write_callback_ = callback; | 501 write_callback_ = callback; |
| 575 return ERR_IO_PENDING; | 502 return ERR_IO_PENDING; |
| 576 } | 503 } |
| 577 | 504 |
| 578 int TCPClientSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { | 505 int TCPClientSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { |
| 579 int nwrite; | 506 int nwrite; |
| 580 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) { | 507 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) { |
| 581 // We have a limited amount of data to send in the SYN packet. | 508 // We have a limited amount of data to send in the SYN packet. |
| 582 int kMaxFastOpenSendLength = 1420; | 509 int kMaxFastOpenSendLength = 1420; |
| 583 | 510 |
| 584 buf_len = std::min(kMaxFastOpenSendLength, buf_len); | 511 buf_len = std::min(kMaxFastOpenSendLength, buf_len); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 reinterpret_cast<const struct sockaddr*>(&source_address), | 577 reinterpret_cast<const struct sockaddr*>(&source_address), |
| 651 sizeof(source_address)); | 578 sizeof(source_address)); |
| 652 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, | 579 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, |
| 653 make_scoped_refptr(new NetLogStringParameter( | 580 make_scoped_refptr(new NetLogStringParameter( |
| 654 "source address", | 581 "source address", |
| 655 source_address_str))); | 582 source_address_str))); |
| 656 } | 583 } |
| 657 | 584 |
| 658 void TCPClientSocketLibevent::DoReadCallback(int rv) { | 585 void TCPClientSocketLibevent::DoReadCallback(int rv) { |
| 659 DCHECK_NE(rv, ERR_IO_PENDING); | 586 DCHECK_NE(rv, ERR_IO_PENDING); |
| 660 DCHECK(old_read_callback_ || !read_callback_.is_null()); | 587 DCHECK(!read_callback_.is_null()); |
| 661 | 588 |
| 662 // since Run may result in Read being called, clear read_callback_ up front. | 589 // since Run may result in Read being called, clear read_callback_ up front. |
| 663 if (old_read_callback_) { | 590 CompletionCallback c = read_callback_; |
| 664 OldCompletionCallback* c = old_read_callback_; | 591 read_callback_.Reset(); |
| 665 old_read_callback_ = NULL; | 592 c.Run(rv); |
| 666 c->Run(rv); | |
| 667 } else { | |
| 668 CompletionCallback c = read_callback_; | |
| 669 read_callback_.Reset(); | |
| 670 c.Run(rv); | |
| 671 } | |
| 672 } | 593 } |
| 673 | 594 |
| 674 void TCPClientSocketLibevent::DoWriteCallback(int rv) { | 595 void TCPClientSocketLibevent::DoWriteCallback(int rv) { |
| 675 DCHECK_NE(rv, ERR_IO_PENDING); | 596 DCHECK_NE(rv, ERR_IO_PENDING); |
| 676 DCHECK(old_write_callback_ || !write_callback_.is_null()); | 597 DCHECK(!write_callback_.is_null()); |
| 677 | 598 |
| 678 // since Run may result in Write being called, clear write_callback_ up front. | 599 // since Run may result in Write being called, clear write_callback_ up front. |
| 679 if (old_write_callback_) { | 600 CompletionCallback c = write_callback_; |
| 680 OldCompletionCallback* c = old_write_callback_; | 601 write_callback_.Reset(); |
| 681 old_write_callback_ = NULL; | 602 c.Run(rv); |
| 682 c->Run(rv); | |
| 683 } else { | |
| 684 CompletionCallback c = write_callback_; | |
| 685 write_callback_.Reset(); | |
| 686 c.Run(rv); | |
| 687 } | |
| 688 } | 603 } |
| 689 | 604 |
| 690 void TCPClientSocketLibevent::DidCompleteConnect() { | 605 void TCPClientSocketLibevent::DidCompleteConnect() { |
| 691 DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE); | 606 DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE); |
| 692 | 607 |
| 693 // Get the error that connect() completed with. | 608 // Get the error that connect() completed with. |
| 694 int os_error = 0; | 609 int os_error = 0; |
| 695 socklen_t len = sizeof(os_error); | 610 socklen_t len = sizeof(os_error); |
| 696 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &os_error, &len) < 0) | 611 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &os_error, &len) < 0) |
| 697 os_error = errno; | 612 os_error = errno; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 | 727 |
| 813 int64 TCPClientSocketLibevent::NumBytesRead() const { | 728 int64 TCPClientSocketLibevent::NumBytesRead() const { |
| 814 return num_bytes_read_; | 729 return num_bytes_read_; |
| 815 } | 730 } |
| 816 | 731 |
| 817 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { | 732 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { |
| 818 return connect_time_micros_; | 733 return connect_time_micros_; |
| 819 } | 734 } |
| 820 | 735 |
| 821 } // namespace net | 736 } // namespace net |
| OLD | NEW |