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
32using std::string;
33
34#if defined(OS_WIN)
35typedef int socklen_t;
36#endif  // defined(OS_WIN)
37
38namespace net {
39
40namespace {
41
42const int kReadBufSize = 4096;
43
44}  // namespace
45
46#if defined(OS_WIN)
47const int StreamListenSocket::kSocketError = SOCKET_ERROR;
48#elif defined(OS_POSIX)
49const int StreamListenSocket::kSocketError = -1;
50#endif
51
52StreamListenSocket::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
67StreamListenSocket::~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
77void 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
84void StreamListenSocket::Send(const string& str, bool append_linefeed) {
85  Send(str.data(), static_cast<int>(str.length()), append_linefeed);
86}
87
88int 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
103int 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
120SocketDescriptor 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
129void 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
159void 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
171void 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
204void 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
214void 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
225void 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
237void 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.
248void 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)
284void 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
303void 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
311void StreamListenSocket::PauseReads() {
312  DCHECK(!reads_paused_);
313  reads_paused_ = true;
314}
315
316void 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