Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / net / socket / stream_listen_socket.cc
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 (ev.lNetworkEvents & FD_CLOSE) {
256     Close();
257     // Close might have deleted this object. We should return immediately.
258     return;
259   }
260
261   // The object was reset by WSAEnumNetworkEvents.  Watch for the next signal.
262   watcher_.StartWatching(object, this);
263
264   if (ev.lNetworkEvents == 0) {
265     // Occasionally the event is set even though there is no new data.
266     // The net seems to think that this is ignorable.
267     return;
268   }
269   if (ev.lNetworkEvents & FD_ACCEPT) {
270     Accept();
271   }
272   if (ev.lNetworkEvents & FD_READ) {
273     if (reads_paused_) {
274       has_pending_reads_ = true;
275     } else {
276       Read();
277       // Read() might call Close() internally and 'this' can be invalid here
278       return;
279     }
280   }
281 }
282 #elif defined(OS_POSIX)
283 void StreamListenSocket::OnFileCanReadWithoutBlocking(int fd) {
284   switch (wait_state_) {
285     case WAITING_ACCEPT:
286       Accept();
287       break;
288     case WAITING_READ:
289       if (reads_paused_) {
290         has_pending_reads_ = true;
291       } else {
292         Read();
293       }
294       break;
295     default:
296       // Close() is called by Read() in the Linux case.
297       NOTREACHED();
298       break;
299   }
300 }
301
302 void StreamListenSocket::OnFileCanWriteWithoutBlocking(int fd) {
303   // MessagePumpLibevent callback, we don't listen for write events
304   // so we shouldn't ever reach here.
305   NOTREACHED();
306 }
307
308 #endif
309
310 void StreamListenSocket::PauseReads() {
311   DCHECK(!reads_paused_);
312   reads_paused_ = true;
313 }
314
315 void StreamListenSocket::ResumeReads() {
316   DCHECK(reads_paused_);
317   reads_paused_ = false;
318   if (has_pending_reads_) {
319     has_pending_reads_ = false;
320     Read();
321   }
322 }
323
324 }  // namespace net