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 |