Home | History | Annotate | Download | only in socket
      1 // Copyright (c) 2012 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/stream_listen_socket.h"
      6 
      7 #if defined(OS_WIN)
      8 // winsock2.h must be included first in order to ensure it is included before
      9 // windows.h.
     10 #include <winsock2.h>
     11 #elif defined(OS_POSIX)
     12 #include <arpa/inet.h>
     13 #include <errno.h>
     14 #include <netinet/in.h>
     15 #include <sys/socket.h>
     16 #include <sys/types.h>
     17 #include "net/base/net_errors.h"
     18 #endif
     19 
     20 #include "base/logging.h"
     21 #include "base/memory/ref_counted.h"
     22 #include "base/memory/scoped_ptr.h"
     23 #include "base/posix/eintr_wrapper.h"
     24 #include "base/sys_byteorder.h"
     25 #include "base/threading/platform_thread.h"
     26 #include "build/build_config.h"
     27 #include "net/base/ip_endpoint.h"
     28 #include "net/base/net_errors.h"
     29 #include "net/base/net_util.h"
     30 #include "net/socket/socket_descriptor.h"
     31 
     32 using std::string;
     33 
     34 #if defined(OS_WIN)
     35 typedef int socklen_t;
     36 #endif  // defined(OS_WIN)
     37 
     38 namespace net {
     39 
     40 namespace {
     41 
     42 const int kReadBufSize = 4096;
     43 
     44 }  // namespace
     45 
     46 #if defined(OS_WIN)
     47 const int StreamListenSocket::kSocketError = SOCKET_ERROR;
     48 #elif defined(OS_POSIX)
     49 const int StreamListenSocket::kSocketError = -1;
     50 #endif
     51 
     52 StreamListenSocket::StreamListenSocket(SocketDescriptor s,
     53                                        StreamListenSocket::Delegate* del)
     54     : socket_delegate_(del),
     55       socket_(s),
     56       reads_paused_(false),
     57       has_pending_reads_(false) {
     58 #if defined(OS_WIN)
     59   socket_event_ = WSACreateEvent();
     60   // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT.
     61   WatchSocket(NOT_WAITING);
     62 #elif defined(OS_POSIX)
     63   wait_state_ = NOT_WAITING;
     64 #endif
     65 }
     66 
     67 StreamListenSocket::~StreamListenSocket() {
     68   CloseSocket();
     69 #if defined(OS_WIN)
     70   if (socket_event_) {
     71     WSACloseEvent(socket_event_);
     72     socket_event_ = WSA_INVALID_EVENT;
     73   }
     74 #endif
     75 }
     76 
     77 void StreamListenSocket::Send(const char* bytes, int len,
     78                               bool append_linefeed) {
     79   SendInternal(bytes, len);
     80   if (append_linefeed)
     81     SendInternal("\r\n", 2);
     82 }
     83 
     84 void StreamListenSocket::Send(const string& str, bool append_linefeed) {
     85   Send(str.data(), static_cast<int>(str.length()), append_linefeed);
     86 }
     87 
     88 int StreamListenSocket::GetLocalAddress(IPEndPoint* address) {
     89   SockaddrStorage storage;
     90   if (getsockname(socket_, storage.addr, &storage.addr_len)) {
     91 #if defined(OS_WIN)
     92     int err = WSAGetLastError();
     93 #else
     94     int err = errno;
     95 #endif
     96     return MapSystemError(err);
     97   }
     98   if (!address->FromSockAddr(storage.addr, storage.addr_len))
     99     return ERR_ADDRESS_INVALID;
    100   return OK;
    101 }
    102 
    103 int StreamListenSocket::GetPeerAddress(IPEndPoint* address) {
    104   SockaddrStorage storage;
    105   if (getpeername(socket_, storage.addr, &storage.addr_len)) {
    106 #if defined(OS_WIN)
    107     int err = WSAGetLastError();
    108 #else
    109     int err = errno;
    110 #endif
    111     return MapSystemError(err);
    112   }
    113 
    114   if (!address->FromSockAddr(storage.addr, storage.addr_len))
    115     return ERR_ADDRESS_INVALID;
    116 
    117   return OK;
    118 }
    119 
    120 SocketDescriptor StreamListenSocket::AcceptSocket() {
    121   SocketDescriptor conn = HANDLE_EINTR(accept(socket_, NULL, NULL));
    122   if (conn == kInvalidSocket)
    123     LOG(ERROR) << "Error accepting connection.";
    124   else
    125     SetNonBlocking(conn);
    126   return conn;
    127 }
    128 
    129 void StreamListenSocket::SendInternal(const char* bytes, int len) {
    130   char* send_buf = const_cast<char *>(bytes);
    131   int len_left = len;
    132   while (true) {
    133     int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0));
    134     if (sent == len_left) {  // A shortcut to avoid extraneous checks.
    135       break;
    136     }
    137     if (sent == kSocketError) {
    138 #if defined(OS_WIN)
    139       if (WSAGetLastError() != WSAEWOULDBLOCK) {
    140         LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError();
    141 #elif defined(OS_POSIX)
    142       if (errno != EWOULDBLOCK && errno != EAGAIN) {
    143         LOG(ERROR) << "send failed: errno==" << errno;
    144 #endif
    145         break;
    146       }
    147       // Otherwise we would block, and now we have to wait for a retry.
    148       // Fall through to PlatformThread::YieldCurrentThread()
    149     } else {
    150       // sent != len_left according to the shortcut above.
    151       // Shift the buffer start and send the remainder after a short while.
    152       send_buf += sent;
    153       len_left -= sent;
    154     }
    155     base::PlatformThread::YieldCurrentThread();
    156   }
    157 }
    158 
    159 void StreamListenSocket::Listen() {
    160   int backlog = 10;  // TODO(erikkay): maybe don't allow any backlog?
    161   if (listen(socket_, backlog) == -1) {
    162     // TODO(erikkay): error handling.
    163     LOG(ERROR) << "Could not listen on socket.";
    164     return;
    165   }
    166 #if defined(OS_POSIX)
    167   WatchSocket(WAITING_ACCEPT);
    168 #endif
    169 }
    170 
    171 void StreamListenSocket::Read() {
    172   char buf[kReadBufSize + 1];  // +1 for null termination.
    173   int len;
    174   do {
    175     len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0));
    176     if (len == kSocketError) {
    177 #if defined(OS_WIN)
    178       int err = WSAGetLastError();
    179       if (err == WSAEWOULDBLOCK) {
    180 #elif defined(OS_POSIX)
    181       if (errno == EWOULDBLOCK || errno == EAGAIN) {
    182 #endif
    183         break;
    184       } else {
    185         // TODO(ibrar): some error handling required here.
    186         break;
    187       }
    188     } else if (len == 0) {
    189       // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need
    190       // to call it here.
    191 #if defined(OS_POSIX)
    192       Close();
    193 #endif
    194     } else {
    195       // TODO(ibrar): maybe change DidRead to take a length instead.
    196       DCHECK_GT(len, 0);
    197       DCHECK_LE(len, kReadBufSize);
    198       buf[len] = 0;  // Already create a buffer with +1 length.
    199       socket_delegate_->DidRead(this, buf, len);
    200     }
    201   } while (len == kReadBufSize);
    202 }
    203 
    204 void StreamListenSocket::Close() {
    205 #if defined(OS_POSIX)
    206   if (wait_state_ == NOT_WAITING)
    207     return;
    208   wait_state_ = NOT_WAITING;
    209 #endif
    210   UnwatchSocket();
    211   socket_delegate_->DidClose(this);
    212 }
    213 
    214 void StreamListenSocket::CloseSocket() {
    215   if (socket_ != kInvalidSocket) {
    216     UnwatchSocket();
    217 #if defined(OS_WIN)
    218     closesocket(socket_);
    219 #elif defined(OS_POSIX)
    220     close(socket_);
    221 #endif
    222   }
    223 }
    224 
    225 void StreamListenSocket::WatchSocket(WaitState state) {
    226 #if defined(OS_WIN)
    227   WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ);
    228   watcher_.StartWatching(socket_event_, this);
    229 #elif defined(OS_POSIX)
    230   // Implicitly calls StartWatchingFileDescriptor().
    231   base::MessageLoopForIO::current()->WatchFileDescriptor(
    232       socket_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
    233   wait_state_ = state;
    234 #endif
    235 }
    236 
    237 void StreamListenSocket::UnwatchSocket() {
    238 #if defined(OS_WIN)
    239   watcher_.StopWatching();
    240 #elif defined(OS_POSIX)
    241   watcher_.StopWatchingFileDescriptor();
    242 #endif
    243 }
    244 
    245 // TODO(ibrar): We can add these functions into OS dependent files.
    246 #if defined(OS_WIN)
    247 // MessageLoop watcher callback.
    248 void StreamListenSocket::OnObjectSignaled(HANDLE object) {
    249   WSANETWORKEVENTS ev;
    250   if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) {
    251     // TODO
    252     return;
    253   }
    254 
    255   // If both FD_CLOSE and FD_READ are set we only call Read().
    256   // This will cause OnObjectSignaled to be called immediately again
    257   // unless this socket is destroyed in Read().
    258   if ((ev.lNetworkEvents & (FD_CLOSE | FD_READ)) == FD_CLOSE) {
    259     Close();
    260     // Close might have deleted this object. We should return immediately.
    261     return;
    262   }
    263   // The object was reset by WSAEnumNetworkEvents.  Watch for the next signal.
    264   watcher_.StartWatching(object, this);
    265 
    266   if (ev.lNetworkEvents == 0) {
    267     // Occasionally the event is set even though there is no new data.
    268     // The net seems to think that this is ignorable.
    269     return;
    270   }
    271   if (ev.lNetworkEvents & FD_ACCEPT) {
    272     Accept();
    273   }
    274   if (ev.lNetworkEvents & FD_READ) {
    275     if (reads_paused_) {
    276       has_pending_reads_ = true;
    277     } else {
    278       Read();
    279       // Read might have deleted this object. We should return immediately.
    280     }
    281   }
    282 }
    283 #elif defined(OS_POSIX)
    284 void StreamListenSocket::OnFileCanReadWithoutBlocking(int fd) {
    285   switch (wait_state_) {
    286     case WAITING_ACCEPT:
    287       Accept();
    288       break;
    289     case WAITING_READ:
    290       if (reads_paused_) {
    291         has_pending_reads_ = true;
    292       } else {
    293         Read();
    294       }
    295       break;
    296     default:
    297       // Close() is called by Read() in the Linux case.
    298       NOTREACHED();
    299       break;
    300   }
    301 }
    302 
    303 void StreamListenSocket::OnFileCanWriteWithoutBlocking(int fd) {
    304   // MessagePumpLibevent callback, we don't listen for write events
    305   // so we shouldn't ever reach here.
    306   NOTREACHED();
    307 }
    308 
    309 #endif
    310 
    311 void StreamListenSocket::PauseReads() {
    312   DCHECK(!reads_paused_);
    313   reads_paused_ = true;
    314 }
    315 
    316 void StreamListenSocket::ResumeReads() {
    317   DCHECK(reads_paused_);
    318   reads_paused_ = false;
    319   if (has_pending_reads_) {
    320     has_pending_reads_ = false;
    321     Read();
    322   }
    323 }
    324 
    325 }  // namespace net
    326