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 3 // found in the LICENSE file. 4 5 #include "net/socket/tcp_socket.h" 6 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <netdb.h> 10 #include <netinet/in.h> 11 #include <netinet/tcp.h> 12 #include <sys/socket.h> 13 14 #include "base/callback_helpers.h" 15 #include "base/logging.h" 16 #include "base/metrics/histogram.h" 17 #include "base/metrics/stats_counters.h" 18 #include "base/posix/eintr_wrapper.h" 19 #include "build/build_config.h" 20 #include "net/base/address_list.h" 21 #include "net/base/connection_type_histograms.h" 22 #include "net/base/io_buffer.h" 23 #include "net/base/ip_endpoint.h" 24 #include "net/base/net_errors.h" 25 #include "net/base/net_util.h" 26 #include "net/base/network_change_notifier.h" 27 #include "net/socket/socket_net_log_params.h" 28 29 // If we don't have a definition for TCPI_OPT_SYN_DATA, create one. 30 #ifndef TCPI_OPT_SYN_DATA 31 #define TCPI_OPT_SYN_DATA 32 32 #endif 33 34 namespace net { 35 36 namespace { 37 38 const int kTCPKeepAliveSeconds = 45; 39 40 // SetTCPNoDelay turns on/off buffering in the kernel. By default, TCP sockets 41 // will wait up to 200ms for more data to complete a packet before transmitting. 42 // After calling this function, the kernel will not wait. See TCP_NODELAY in 43 // `man 7 tcp`. 44 bool SetTCPNoDelay(int fd, bool no_delay) { 45 int on = no_delay ? 1 : 0; 46 int error = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); 47 return error == 0; 48 } 49 50 // SetTCPKeepAlive sets SO_KEEPALIVE. 51 bool SetTCPKeepAlive(int fd, bool enable, int delay) { 52 int on = enable ? 1 : 0; 53 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) { 54 PLOG(ERROR) << "Failed to set SO_KEEPALIVE on fd: " << fd; 55 return false; 56 } 57 #if defined(OS_LINUX) || defined(OS_ANDROID) 58 // Set seconds until first TCP keep alive. 59 if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) { 60 PLOG(ERROR) << "Failed to set TCP_KEEPIDLE on fd: " << fd; 61 return false; 62 } 63 // Set seconds between TCP keep alives. 64 if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &delay, sizeof(delay))) { 65 PLOG(ERROR) << "Failed to set TCP_KEEPINTVL on fd: " << fd; 66 return false; 67 } 68 #endif 69 return true; 70 } 71 72 int MapAcceptError(int os_error) { 73 switch (os_error) { 74 // If the client aborts the connection before the server calls accept, 75 // POSIX specifies accept should fail with ECONNABORTED. The server can 76 // ignore the error and just call accept again, so we map the error to 77 // ERR_IO_PENDING. See UNIX Network Programming, Vol. 1, 3rd Ed., Sec. 78 // 5.11, "Connection Abort before accept Returns". 79 case ECONNABORTED: 80 return ERR_IO_PENDING; 81 default: 82 return MapSystemError(os_error); 83 } 84 } 85 86 int MapConnectError(int os_error) { 87 switch (os_error) { 88 case EACCES: 89 return ERR_NETWORK_ACCESS_DENIED; 90 case ETIMEDOUT: 91 return ERR_CONNECTION_TIMED_OUT; 92 default: { 93 int net_error = MapSystemError(os_error); 94 if (net_error == ERR_FAILED) 95 return ERR_CONNECTION_FAILED; // More specific than ERR_FAILED. 96 97 // Give a more specific error when the user is offline. 98 if (net_error == ERR_ADDRESS_UNREACHABLE && 99 NetworkChangeNotifier::IsOffline()) { 100 return ERR_INTERNET_DISCONNECTED; 101 } 102 return net_error; 103 } 104 } 105 } 106 107 } // namespace 108 109 //----------------------------------------------------------------------------- 110 111 TCPSocketLibevent::Watcher::Watcher( 112 const base::Closure& read_ready_callback, 113 const base::Closure& write_ready_callback) 114 : read_ready_callback_(read_ready_callback), 115 write_ready_callback_(write_ready_callback) { 116 } 117 118 TCPSocketLibevent::Watcher::~Watcher() { 119 } 120 121 void TCPSocketLibevent::Watcher::OnFileCanReadWithoutBlocking(int /* fd */) { 122 if (!read_ready_callback_.is_null()) 123 read_ready_callback_.Run(); 124 else 125 NOTREACHED(); 126 } 127 128 void TCPSocketLibevent::Watcher::OnFileCanWriteWithoutBlocking(int /* fd */) { 129 if (!write_ready_callback_.is_null()) 130 write_ready_callback_.Run(); 131 else 132 NOTREACHED(); 133 } 134 135 TCPSocketLibevent::TCPSocketLibevent(NetLog* net_log, 136 const NetLog::Source& source) 137 : socket_(kInvalidSocket), 138 accept_watcher_(base::Bind(&TCPSocketLibevent::DidCompleteAccept, 139 base::Unretained(this)), 140 base::Closure()), 141 accept_socket_(NULL), 142 accept_address_(NULL), 143 read_watcher_(base::Bind(&TCPSocketLibevent::DidCompleteRead, 144 base::Unretained(this)), 145 base::Closure()), 146 write_watcher_(base::Closure(), 147 base::Bind(&TCPSocketLibevent::DidCompleteConnectOrWrite, 148 base::Unretained(this))), 149 read_buf_len_(0), 150 write_buf_len_(0), 151 use_tcp_fastopen_(IsTCPFastOpenEnabled()), 152 tcp_fastopen_connected_(false), 153 fast_open_status_(FAST_OPEN_STATUS_UNKNOWN), 154 waiting_connect_(false), 155 connect_os_error_(0), 156 logging_multiple_connect_attempts_(false), 157 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { 158 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 159 source.ToEventParametersCallback()); 160 } 161 162 TCPSocketLibevent::~TCPSocketLibevent() { 163 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); 164 if (tcp_fastopen_connected_) { 165 UMA_HISTOGRAM_ENUMERATION("Net.TcpFastOpenSocketConnection", 166 fast_open_status_, FAST_OPEN_MAX_VALUE); 167 } 168 Close(); 169 } 170 171 int TCPSocketLibevent::Open(AddressFamily family) { 172 DCHECK(CalledOnValidThread()); 173 DCHECK_EQ(socket_, kInvalidSocket); 174 175 socket_ = CreatePlatformSocket(ConvertAddressFamily(family), SOCK_STREAM, 176 IPPROTO_TCP); 177 if (socket_ < 0) { 178 PLOG(ERROR) << "CreatePlatformSocket() returned an error"; 179 return MapSystemError(errno); 180 } 181 182 if (SetNonBlocking(socket_)) { 183 int result = MapSystemError(errno); 184 Close(); 185 return result; 186 } 187 188 return OK; 189 } 190 191 int TCPSocketLibevent::AdoptConnectedSocket(int socket, 192 const IPEndPoint& peer_address) { 193 DCHECK(CalledOnValidThread()); 194 DCHECK_EQ(socket_, kInvalidSocket); 195 196 socket_ = socket; 197 198 if (SetNonBlocking(socket_)) { 199 int result = MapSystemError(errno); 200 Close(); 201 return result; 202 } 203 204 peer_address_.reset(new IPEndPoint(peer_address)); 205 206 return OK; 207 } 208 209 int TCPSocketLibevent::Bind(const IPEndPoint& address) { 210 DCHECK(CalledOnValidThread()); 211 DCHECK_NE(socket_, kInvalidSocket); 212 213 SockaddrStorage storage; 214 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 215 return ERR_ADDRESS_INVALID; 216 217 int result = bind(socket_, storage.addr, storage.addr_len); 218 if (result < 0) { 219 PLOG(ERROR) << "bind() returned an error"; 220 return MapSystemError(errno); 221 } 222 223 return OK; 224 } 225 226 int TCPSocketLibevent::Listen(int backlog) { 227 DCHECK(CalledOnValidThread()); 228 DCHECK_GT(backlog, 0); 229 DCHECK_NE(socket_, kInvalidSocket); 230 231 int result = listen(socket_, backlog); 232 if (result < 0) { 233 PLOG(ERROR) << "listen() returned an error"; 234 return MapSystemError(errno); 235 } 236 237 return OK; 238 } 239 240 int TCPSocketLibevent::Accept(scoped_ptr<TCPSocketLibevent>* socket, 241 IPEndPoint* address, 242 const CompletionCallback& callback) { 243 DCHECK(CalledOnValidThread()); 244 DCHECK(socket); 245 DCHECK(address); 246 DCHECK(!callback.is_null()); 247 DCHECK(accept_callback_.is_null()); 248 249 net_log_.BeginEvent(NetLog::TYPE_TCP_ACCEPT); 250 251 int result = AcceptInternal(socket, address); 252 253 if (result == ERR_IO_PENDING) { 254 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 255 socket_, true, base::MessageLoopForIO::WATCH_READ, 256 &accept_socket_watcher_, &accept_watcher_)) { 257 PLOG(ERROR) << "WatchFileDescriptor failed on read"; 258 return MapSystemError(errno); 259 } 260 261 accept_socket_ = socket; 262 accept_address_ = address; 263 accept_callback_ = callback; 264 } 265 266 return result; 267 } 268 269 int TCPSocketLibevent::Connect(const IPEndPoint& address, 270 const CompletionCallback& callback) { 271 DCHECK(CalledOnValidThread()); 272 DCHECK_NE(socket_, kInvalidSocket); 273 DCHECK(!waiting_connect_); 274 275 // |peer_address_| will be non-NULL if Connect() has been called. Unless 276 // Close() is called to reset the internal state, a second call to Connect() 277 // is not allowed. 278 // Please note that we don't allow a second Connect() even if the previous 279 // Connect() has failed. Connecting the same |socket_| again after a 280 // connection attempt failed results in unspecified behavior according to 281 // POSIX. 282 DCHECK(!peer_address_); 283 284 if (!logging_multiple_connect_attempts_) 285 LogConnectBegin(AddressList(address)); 286 287 peer_address_.reset(new IPEndPoint(address)); 288 289 int rv = DoConnect(); 290 if (rv == ERR_IO_PENDING) { 291 // Synchronous operation not supported. 292 DCHECK(!callback.is_null()); 293 write_callback_ = callback; 294 waiting_connect_ = true; 295 } else { 296 DoConnectComplete(rv); 297 } 298 299 return rv; 300 } 301 302 bool TCPSocketLibevent::IsConnected() const { 303 DCHECK(CalledOnValidThread()); 304 305 if (socket_ == kInvalidSocket || waiting_connect_) 306 return false; 307 308 if (use_tcp_fastopen_ && !tcp_fastopen_connected_ && peer_address_) { 309 // With TCP FastOpen, we pretend that the socket is connected. 310 // This allows GetPeerAddress() to return peer_address_. 311 return true; 312 } 313 314 // Check if connection is alive. 315 char c; 316 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); 317 if (rv == 0) 318 return false; 319 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) 320 return false; 321 322 return true; 323 } 324 325 bool TCPSocketLibevent::IsConnectedAndIdle() const { 326 DCHECK(CalledOnValidThread()); 327 328 if (socket_ == kInvalidSocket || waiting_connect_) 329 return false; 330 331 // TODO(wtc): should we also handle the TCP FastOpen case here, 332 // as we do in IsConnected()? 333 334 // Check if connection is alive and we haven't received any data 335 // unexpectedly. 336 char c; 337 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); 338 if (rv >= 0) 339 return false; 340 if (errno != EAGAIN && errno != EWOULDBLOCK) 341 return false; 342 343 return true; 344 } 345 346 int TCPSocketLibevent::Read(IOBuffer* buf, 347 int buf_len, 348 const CompletionCallback& callback) { 349 DCHECK(CalledOnValidThread()); 350 DCHECK_NE(kInvalidSocket, socket_); 351 DCHECK(!waiting_connect_); 352 DCHECK(read_callback_.is_null()); 353 // Synchronous operation not supported 354 DCHECK(!callback.is_null()); 355 DCHECK_GT(buf_len, 0); 356 357 int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len)); 358 if (nread >= 0) { 359 base::StatsCounter read_bytes("tcp.read_bytes"); 360 read_bytes.Add(nread); 361 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, nread, 362 buf->data()); 363 RecordFastOpenStatus(); 364 return nread; 365 } 366 if (errno != EAGAIN && errno != EWOULDBLOCK) { 367 int net_error = MapSystemError(errno); 368 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, 369 CreateNetLogSocketErrorCallback(net_error, errno)); 370 return net_error; 371 } 372 373 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 374 socket_, true, base::MessageLoopForIO::WATCH_READ, 375 &read_socket_watcher_, &read_watcher_)) { 376 DVLOG(1) << "WatchFileDescriptor failed on read, errno " << errno; 377 return MapSystemError(errno); 378 } 379 380 read_buf_ = buf; 381 read_buf_len_ = buf_len; 382 read_callback_ = callback; 383 return ERR_IO_PENDING; 384 } 385 386 int TCPSocketLibevent::Write(IOBuffer* buf, 387 int buf_len, 388 const CompletionCallback& callback) { 389 DCHECK(CalledOnValidThread()); 390 DCHECK_NE(kInvalidSocket, socket_); 391 DCHECK(!waiting_connect_); 392 DCHECK(write_callback_.is_null()); 393 // Synchronous operation not supported 394 DCHECK(!callback.is_null()); 395 DCHECK_GT(buf_len, 0); 396 397 int nwrite = InternalWrite(buf, buf_len); 398 if (nwrite >= 0) { 399 base::StatsCounter write_bytes("tcp.write_bytes"); 400 write_bytes.Add(nwrite); 401 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, nwrite, 402 buf->data()); 403 return nwrite; 404 } 405 if (errno != EAGAIN && errno != EWOULDBLOCK) { 406 int net_error = MapSystemError(errno); 407 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, 408 CreateNetLogSocketErrorCallback(net_error, errno)); 409 return net_error; 410 } 411 412 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 413 socket_, true, base::MessageLoopForIO::WATCH_WRITE, 414 &write_socket_watcher_, &write_watcher_)) { 415 DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno; 416 return MapSystemError(errno); 417 } 418 419 write_buf_ = buf; 420 write_buf_len_ = buf_len; 421 write_callback_ = callback; 422 return ERR_IO_PENDING; 423 } 424 425 int TCPSocketLibevent::GetLocalAddress(IPEndPoint* address) const { 426 DCHECK(CalledOnValidThread()); 427 DCHECK(address); 428 429 SockaddrStorage storage; 430 if (getsockname(socket_, storage.addr, &storage.addr_len) < 0) 431 return MapSystemError(errno); 432 if (!address->FromSockAddr(storage.addr, storage.addr_len)) 433 return ERR_ADDRESS_INVALID; 434 435 return OK; 436 } 437 438 int TCPSocketLibevent::GetPeerAddress(IPEndPoint* address) const { 439 DCHECK(CalledOnValidThread()); 440 DCHECK(address); 441 if (!IsConnected()) 442 return ERR_SOCKET_NOT_CONNECTED; 443 *address = *peer_address_; 444 return OK; 445 } 446 447 int TCPSocketLibevent::SetDefaultOptionsForServer() { 448 DCHECK(CalledOnValidThread()); 449 return SetAddressReuse(true); 450 } 451 452 void TCPSocketLibevent::SetDefaultOptionsForClient() { 453 DCHECK(CalledOnValidThread()); 454 455 // This mirrors the behaviour on Windows. See the comment in 456 // tcp_socket_win.cc after searching for "NODELAY". 457 SetTCPNoDelay(socket_, true); // If SetTCPNoDelay fails, we don't care. 458 SetTCPKeepAlive(socket_, true, kTCPKeepAliveSeconds); 459 } 460 461 int TCPSocketLibevent::SetAddressReuse(bool allow) { 462 DCHECK(CalledOnValidThread()); 463 464 // SO_REUSEADDR is useful for server sockets to bind to a recently unbound 465 // port. When a socket is closed, the end point changes its state to TIME_WAIT 466 // and wait for 2 MSL (maximum segment lifetime) to ensure the remote peer 467 // acknowledges its closure. For server sockets, it is usually safe to 468 // bind to a TIME_WAIT end point immediately, which is a widely adopted 469 // behavior. 470 // 471 // Note that on *nix, SO_REUSEADDR does not enable the TCP socket to bind to 472 // an end point that is already bound by another socket. To do that one must 473 // set SO_REUSEPORT instead. This option is not provided on Linux prior 474 // to 3.9. 475 // 476 // SO_REUSEPORT is provided in MacOS X and iOS. 477 int boolean_value = allow ? 1 : 0; 478 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &boolean_value, 479 sizeof(boolean_value)); 480 if (rv < 0) 481 return MapSystemError(errno); 482 return OK; 483 } 484 485 bool TCPSocketLibevent::SetReceiveBufferSize(int32 size) { 486 DCHECK(CalledOnValidThread()); 487 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 488 reinterpret_cast<const char*>(&size), 489 sizeof(size)); 490 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; 491 return rv == 0; 492 } 493 494 bool TCPSocketLibevent::SetSendBufferSize(int32 size) { 495 DCHECK(CalledOnValidThread()); 496 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 497 reinterpret_cast<const char*>(&size), 498 sizeof(size)); 499 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; 500 return rv == 0; 501 } 502 503 bool TCPSocketLibevent::SetKeepAlive(bool enable, int delay) { 504 DCHECK(CalledOnValidThread()); 505 return SetTCPKeepAlive(socket_, enable, delay); 506 } 507 508 bool TCPSocketLibevent::SetNoDelay(bool no_delay) { 509 DCHECK(CalledOnValidThread()); 510 return SetTCPNoDelay(socket_, no_delay); 511 } 512 513 void TCPSocketLibevent::Close() { 514 DCHECK(CalledOnValidThread()); 515 516 bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); 517 DCHECK(ok); 518 ok = read_socket_watcher_.StopWatchingFileDescriptor(); 519 DCHECK(ok); 520 ok = write_socket_watcher_.StopWatchingFileDescriptor(); 521 DCHECK(ok); 522 523 if (socket_ != kInvalidSocket) { 524 if (IGNORE_EINTR(close(socket_)) < 0) 525 PLOG(ERROR) << "close"; 526 socket_ = kInvalidSocket; 527 } 528 529 if (!accept_callback_.is_null()) { 530 accept_socket_ = NULL; 531 accept_address_ = NULL; 532 accept_callback_.Reset(); 533 } 534 535 if (!read_callback_.is_null()) { 536 read_buf_ = NULL; 537 read_buf_len_ = 0; 538 read_callback_.Reset(); 539 } 540 541 if (!write_callback_.is_null()) { 542 write_buf_ = NULL; 543 write_buf_len_ = 0; 544 write_callback_.Reset(); 545 } 546 547 tcp_fastopen_connected_ = false; 548 fast_open_status_ = FAST_OPEN_STATUS_UNKNOWN; 549 waiting_connect_ = false; 550 peer_address_.reset(); 551 connect_os_error_ = 0; 552 } 553 554 bool TCPSocketLibevent::UsingTCPFastOpen() const { 555 return use_tcp_fastopen_; 556 } 557 558 void TCPSocketLibevent::StartLoggingMultipleConnectAttempts( 559 const AddressList& addresses) { 560 if (!logging_multiple_connect_attempts_) { 561 logging_multiple_connect_attempts_ = true; 562 LogConnectBegin(addresses); 563 } else { 564 NOTREACHED(); 565 } 566 } 567 568 void TCPSocketLibevent::EndLoggingMultipleConnectAttempts(int net_error) { 569 if (logging_multiple_connect_attempts_) { 570 LogConnectEnd(net_error); 571 logging_multiple_connect_attempts_ = false; 572 } else { 573 NOTREACHED(); 574 } 575 } 576 577 int TCPSocketLibevent::AcceptInternal(scoped_ptr<TCPSocketLibevent>* socket, 578 IPEndPoint* address) { 579 SockaddrStorage storage; 580 int new_socket = HANDLE_EINTR(accept(socket_, 581 storage.addr, 582 &storage.addr_len)); 583 if (new_socket < 0) { 584 int net_error = MapAcceptError(errno); 585 if (net_error != ERR_IO_PENDING) 586 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, net_error); 587 return net_error; 588 } 589 590 IPEndPoint ip_end_point; 591 if (!ip_end_point.FromSockAddr(storage.addr, storage.addr_len)) { 592 NOTREACHED(); 593 if (IGNORE_EINTR(close(new_socket)) < 0) 594 PLOG(ERROR) << "close"; 595 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, 596 ERR_ADDRESS_INVALID); 597 return ERR_ADDRESS_INVALID; 598 } 599 scoped_ptr<TCPSocketLibevent> tcp_socket(new TCPSocketLibevent( 600 net_log_.net_log(), net_log_.source())); 601 int adopt_result = tcp_socket->AdoptConnectedSocket(new_socket, ip_end_point); 602 if (adopt_result != OK) { 603 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, adopt_result); 604 return adopt_result; 605 } 606 *socket = tcp_socket.Pass(); 607 *address = ip_end_point; 608 net_log_.EndEvent(NetLog::TYPE_TCP_ACCEPT, 609 CreateNetLogIPEndPointCallback(&ip_end_point)); 610 return OK; 611 } 612 613 int TCPSocketLibevent::DoConnect() { 614 DCHECK_EQ(0, connect_os_error_); 615 616 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, 617 CreateNetLogIPEndPointCallback(peer_address_.get())); 618 619 // Connect the socket. 620 if (!use_tcp_fastopen_) { 621 SockaddrStorage storage; 622 if (!peer_address_->ToSockAddr(storage.addr, &storage.addr_len)) 623 return ERR_INVALID_ARGUMENT; 624 625 if (!HANDLE_EINTR(connect(socket_, storage.addr, storage.addr_len))) { 626 // Connected without waiting! 627 return OK; 628 } 629 } else { 630 // With TCP FastOpen, we pretend that the socket is connected. 631 DCHECK(!tcp_fastopen_connected_); 632 return OK; 633 } 634 635 // Check if the connect() failed synchronously. 636 connect_os_error_ = errno; 637 if (connect_os_error_ != EINPROGRESS) 638 return MapConnectError(connect_os_error_); 639 640 // Otherwise the connect() is going to complete asynchronously, so watch 641 // for its completion. 642 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 643 socket_, true, base::MessageLoopForIO::WATCH_WRITE, 644 &write_socket_watcher_, &write_watcher_)) { 645 connect_os_error_ = errno; 646 DVLOG(1) << "WatchFileDescriptor failed: " << connect_os_error_; 647 return MapSystemError(connect_os_error_); 648 } 649 650 return ERR_IO_PENDING; 651 } 652 653 void TCPSocketLibevent::DoConnectComplete(int result) { 654 // Log the end of this attempt (and any OS error it threw). 655 int os_error = connect_os_error_; 656 connect_os_error_ = 0; 657 if (result != OK) { 658 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, 659 NetLog::IntegerCallback("os_error", os_error)); 660 } else { 661 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT); 662 } 663 664 if (!logging_multiple_connect_attempts_) 665 LogConnectEnd(result); 666 } 667 668 void TCPSocketLibevent::LogConnectBegin(const AddressList& addresses) { 669 base::StatsCounter connects("tcp.connect"); 670 connects.Increment(); 671 672 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT, 673 addresses.CreateNetLogCallback()); 674 } 675 676 void TCPSocketLibevent::LogConnectEnd(int net_error) { 677 if (net_error == OK) 678 UpdateConnectionTypeHistograms(CONNECTION_ANY); 679 680 if (net_error != OK) { 681 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); 682 return; 683 } 684 685 SockaddrStorage storage; 686 int rv = getsockname(socket_, storage.addr, &storage.addr_len); 687 if (rv != 0) { 688 PLOG(ERROR) << "getsockname() [rv: " << rv << "] error: "; 689 NOTREACHED(); 690 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); 691 return; 692 } 693 694 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, 695 CreateNetLogSourceAddressCallback(storage.addr, 696 storage.addr_len)); 697 } 698 699 void TCPSocketLibevent::DidCompleteRead() { 700 RecordFastOpenStatus(); 701 if (read_callback_.is_null()) 702 return; 703 704 int bytes_transferred; 705 bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(), 706 read_buf_len_)); 707 708 int result; 709 if (bytes_transferred >= 0) { 710 result = bytes_transferred; 711 base::StatsCounter read_bytes("tcp.read_bytes"); 712 read_bytes.Add(bytes_transferred); 713 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, result, 714 read_buf_->data()); 715 } else { 716 result = MapSystemError(errno); 717 if (result != ERR_IO_PENDING) { 718 net_log_.AddEvent(NetLog::TYPE_SOCKET_READ_ERROR, 719 CreateNetLogSocketErrorCallback(result, errno)); 720 } 721 } 722 723 if (result != ERR_IO_PENDING) { 724 read_buf_ = NULL; 725 read_buf_len_ = 0; 726 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); 727 DCHECK(ok); 728 base::ResetAndReturn(&read_callback_).Run(result); 729 } 730 } 731 732 void TCPSocketLibevent::DidCompleteWrite() { 733 if (write_callback_.is_null()) 734 return; 735 736 int bytes_transferred; 737 bytes_transferred = HANDLE_EINTR(write(socket_, write_buf_->data(), 738 write_buf_len_)); 739 740 int result; 741 if (bytes_transferred >= 0) { 742 result = bytes_transferred; 743 base::StatsCounter write_bytes("tcp.write_bytes"); 744 write_bytes.Add(bytes_transferred); 745 net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, result, 746 write_buf_->data()); 747 } else { 748 result = MapSystemError(errno); 749 if (result != ERR_IO_PENDING) { 750 net_log_.AddEvent(NetLog::TYPE_SOCKET_WRITE_ERROR, 751 CreateNetLogSocketErrorCallback(result, errno)); 752 } 753 } 754 755 if (result != ERR_IO_PENDING) { 756 write_buf_ = NULL; 757 write_buf_len_ = 0; 758 write_socket_watcher_.StopWatchingFileDescriptor(); 759 base::ResetAndReturn(&write_callback_).Run(result); 760 } 761 } 762 763 void TCPSocketLibevent::DidCompleteConnect() { 764 DCHECK(waiting_connect_); 765 766 // Get the error that connect() completed with. 767 int os_error = 0; 768 socklen_t len = sizeof(os_error); 769 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &os_error, &len) < 0) 770 os_error = errno; 771 772 int result = MapConnectError(os_error); 773 connect_os_error_ = os_error; 774 if (result != ERR_IO_PENDING) { 775 DoConnectComplete(result); 776 waiting_connect_ = false; 777 write_socket_watcher_.StopWatchingFileDescriptor(); 778 base::ResetAndReturn(&write_callback_).Run(result); 779 } 780 } 781 782 void TCPSocketLibevent::DidCompleteConnectOrWrite() { 783 if (waiting_connect_) 784 DidCompleteConnect(); 785 else 786 DidCompleteWrite(); 787 } 788 789 void TCPSocketLibevent::DidCompleteAccept() { 790 DCHECK(CalledOnValidThread()); 791 792 int result = AcceptInternal(accept_socket_, accept_address_); 793 if (result != ERR_IO_PENDING) { 794 accept_socket_ = NULL; 795 accept_address_ = NULL; 796 bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); 797 DCHECK(ok); 798 CompletionCallback callback = accept_callback_; 799 accept_callback_.Reset(); 800 callback.Run(result); 801 } 802 } 803 804 int TCPSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { 805 int nwrite; 806 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) { 807 SockaddrStorage storage; 808 if (!peer_address_->ToSockAddr(storage.addr, &storage.addr_len)) { 809 errno = EINVAL; 810 return -1; 811 } 812 813 int flags = 0x20000000; // Magic flag to enable TCP_FASTOPEN. 814 #if defined(OS_LINUX) 815 // sendto() will fail with EPIPE when the system doesn't support TCP Fast 816 // Open. Theoretically that shouldn't happen since the caller should check 817 // for system support on startup, but users may dynamically disable TCP Fast 818 // Open via sysctl. 819 flags |= MSG_NOSIGNAL; 820 #endif // defined(OS_LINUX) 821 nwrite = HANDLE_EINTR(sendto(socket_, 822 buf->data(), 823 buf_len, 824 flags, 825 storage.addr, 826 storage.addr_len)); 827 tcp_fastopen_connected_ = true; 828 829 if (nwrite < 0) { 830 DCHECK_NE(EPIPE, errno); 831 832 // If errno == EINPROGRESS, that means the kernel didn't have a cookie 833 // and would block. The kernel is internally doing a connect() though. 834 // Remap EINPROGRESS to EAGAIN so we treat this the same as our other 835 // asynchronous cases. Note that the user buffer has not been copied to 836 // kernel space. 837 if (errno == EINPROGRESS) { 838 errno = EAGAIN; 839 fast_open_status_ = FAST_OPEN_SLOW_CONNECT_RETURN; 840 } else { 841 fast_open_status_ = FAST_OPEN_ERROR; 842 } 843 } else { 844 fast_open_status_ = FAST_OPEN_FAST_CONNECT_RETURN; 845 } 846 } else { 847 nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len)); 848 } 849 return nwrite; 850 } 851 852 void TCPSocketLibevent::RecordFastOpenStatus() { 853 if (use_tcp_fastopen_ && 854 (fast_open_status_ == FAST_OPEN_FAST_CONNECT_RETURN || 855 fast_open_status_ == FAST_OPEN_SLOW_CONNECT_RETURN)) { 856 DCHECK_NE(FAST_OPEN_STATUS_UNKNOWN, fast_open_status_); 857 bool getsockopt_success(false); 858 bool server_acked_data(false); 859 #if defined(TCP_INFO) 860 // Probe to see the if the socket used TCP Fast Open. 861 tcp_info info; 862 socklen_t info_len = sizeof(tcp_info); 863 getsockopt_success = 864 getsockopt(socket_, IPPROTO_TCP, TCP_INFO, &info, &info_len) == 0 && 865 info_len == sizeof(tcp_info); 866 server_acked_data = getsockopt_success && 867 (info.tcpi_options & TCPI_OPT_SYN_DATA); 868 #endif 869 if (getsockopt_success) { 870 if (fast_open_status_ == FAST_OPEN_FAST_CONNECT_RETURN) { 871 fast_open_status_ = (server_acked_data ? FAST_OPEN_SYN_DATA_ACK : 872 FAST_OPEN_SYN_DATA_NACK); 873 } else { 874 fast_open_status_ = (server_acked_data ? FAST_OPEN_NO_SYN_DATA_ACK : 875 FAST_OPEN_NO_SYN_DATA_NACK); 876 } 877 } else { 878 fast_open_status_ = (fast_open_status_ == FAST_OPEN_FAST_CONNECT_RETURN ? 879 FAST_OPEN_SYN_DATA_FAILED : 880 FAST_OPEN_NO_SYN_DATA_FAILED); 881 } 882 } 883 } 884 885 } // namespace net 886