Home | History | Annotate | Download | only in socket
      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