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.
5 #include "net/socket/stream_listen_socket.h"
8 // winsock2.h must be included first in order to ensure it is included before
11 #elif defined(OS_POSIX)
12 #include <arpa/inet.h>
14 #include <netinet/in.h>
15 #include <sys/socket.h>
16 #include <sys/types.h>
17 #include "net/base/net_errors.h"
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"
34 typedef int socklen_t
;
35 #endif // defined(OS_WIN)
41 const int kReadBufSize
= 4096;
46 const SocketDescriptor
StreamListenSocket::kInvalidSocket
= INVALID_SOCKET
;
47 const int StreamListenSocket::kSocketError
= SOCKET_ERROR
;
48 #elif defined(OS_POSIX)
49 const SocketDescriptor
StreamListenSocket::kInvalidSocket
= -1;
50 const int StreamListenSocket::kSocketError
= -1;
53 StreamListenSocket::StreamListenSocket(SocketDescriptor s
,
54 StreamListenSocket::Delegate
* del
)
55 : socket_delegate_(del
),
58 has_pending_reads_(false) {
60 socket_event_
= WSACreateEvent();
61 // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT.
62 WatchSocket(NOT_WAITING
);
63 #elif defined(OS_POSIX)
64 wait_state_
= NOT_WAITING
;
68 StreamListenSocket::~StreamListenSocket() {
71 WSACloseEvent(socket_event_
);
72 socket_event_
= WSA_INVALID_EVENT
;
78 void StreamListenSocket::Send(const char* bytes
, int len
,
79 bool append_linefeed
) {
80 SendInternal(bytes
, len
);
82 SendInternal("\r\n", 2);
85 void StreamListenSocket::Send(const string
& str
, bool append_linefeed
) {
86 Send(str
.data(), static_cast<int>(str
.length()), append_linefeed
);
89 int StreamListenSocket::GetLocalAddress(IPEndPoint
* address
) {
90 SockaddrStorage storage
;
91 if (getsockname(socket_
, storage
.addr
, &storage
.addr_len
)) {
93 int err
= WSAGetLastError();
97 return MapSystemError(err
);
99 if (!address
->FromSockAddr(storage
.addr
, storage
.addr_len
))
104 SocketDescriptor
StreamListenSocket::AcceptSocket() {
105 SocketDescriptor conn
= HANDLE_EINTR(accept(socket_
, NULL
, NULL
));
106 if (conn
== kInvalidSocket
)
107 LOG(ERROR
) << "Error accepting connection.";
109 SetNonBlocking(conn
);
113 void StreamListenSocket::SendInternal(const char* bytes
, int len
) {
114 char* send_buf
= const_cast<char *>(bytes
);
117 int sent
= HANDLE_EINTR(send(socket_
, send_buf
, len_left
, 0));
118 if (sent
== len_left
) { // A shortcut to avoid extraneous checks.
121 if (sent
== kSocketError
) {
123 if (WSAGetLastError() != WSAEWOULDBLOCK
) {
124 LOG(ERROR
) << "send failed: WSAGetLastError()==" << WSAGetLastError();
125 #elif defined(OS_POSIX)
126 if (errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
) {
127 LOG(ERROR
) << "send failed: errno==" << errno
;
131 // Otherwise we would block, and now we have to wait for a retry.
132 // Fall through to PlatformThread::YieldCurrentThread()
134 // sent != len_left according to the shortcut above.
135 // Shift the buffer start and send the remainder after a short while.
139 base::PlatformThread::YieldCurrentThread();
143 void StreamListenSocket::Listen() {
144 int backlog
= 10; // TODO(erikkay): maybe don't allow any backlog?
145 if (listen(socket_
, backlog
) == -1) {
146 // TODO(erikkay): error handling.
147 LOG(ERROR
) << "Could not listen on socket.";
150 #if defined(OS_POSIX)
151 WatchSocket(WAITING_ACCEPT
);
155 void StreamListenSocket::Read() {
156 char buf
[kReadBufSize
+ 1]; // +1 for null termination.
159 len
= HANDLE_EINTR(recv(socket_
, buf
, kReadBufSize
, 0));
160 if (len
== kSocketError
) {
162 int err
= WSAGetLastError();
163 if (err
== WSAEWOULDBLOCK
) {
164 #elif defined(OS_POSIX)
165 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
) {
169 // TODO(ibrar): some error handling required here.
172 } else if (len
== 0) {
173 // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need
175 #if defined(OS_POSIX)
179 // TODO(ibrar): maybe change DidRead to take a length instead.
181 DCHECK_LE(len
, kReadBufSize
);
182 buf
[len
] = 0; // Already create a buffer with +1 length.
183 socket_delegate_
->DidRead(this, buf
, len
);
185 } while (len
== kReadBufSize
);
188 void StreamListenSocket::Close() {
189 #if defined(OS_POSIX)
190 if (wait_state_
== NOT_WAITING
)
192 wait_state_
= NOT_WAITING
;
195 socket_delegate_
->DidClose(this);
198 void StreamListenSocket::CloseSocket(SocketDescriptor s
) {
199 if (s
&& s
!= kInvalidSocket
) {
203 #elif defined(OS_POSIX)
209 void StreamListenSocket::WatchSocket(WaitState state
) {
211 WSAEventSelect(socket_
, socket_event_
, FD_ACCEPT
| FD_CLOSE
| FD_READ
);
212 watcher_
.StartWatching(socket_event_
, this);
213 #elif defined(OS_POSIX)
214 // Implicitly calls StartWatchingFileDescriptor().
215 MessageLoopForIO::current()->WatchFileDescriptor(
216 socket_
, true, MessageLoopForIO::WATCH_READ
, &watcher_
, this);
221 void StreamListenSocket::UnwatchSocket() {
223 watcher_
.StopWatching();
224 #elif defined(OS_POSIX)
225 watcher_
.StopWatchingFileDescriptor();
229 // TODO(ibrar): We can add these functions into OS dependent files.
231 // MessageLoop watcher callback.
232 void StreamListenSocket::OnObjectSignaled(HANDLE object
) {
234 if (kSocketError
== WSAEnumNetworkEvents(socket_
, socket_event_
, &ev
)) {
239 // The object was reset by WSAEnumNetworkEvents. Watch for the next signal.
240 watcher_
.StartWatching(object
, this);
242 if (ev
.lNetworkEvents
== 0) {
243 // Occasionally the event is set even though there is no new data.
244 // The net seems to think that this is ignorable.
247 if (ev
.lNetworkEvents
& FD_ACCEPT
) {
250 if (ev
.lNetworkEvents
& FD_READ
) {
252 has_pending_reads_
= true;
257 if (ev
.lNetworkEvents
& FD_CLOSE
) {
261 #elif defined(OS_POSIX)
262 void StreamListenSocket::OnFileCanReadWithoutBlocking(int fd
) {
263 switch (wait_state_
) {
269 has_pending_reads_
= true;
275 // Close() is called by Read() in the Linux case.
281 void StreamListenSocket::OnFileCanWriteWithoutBlocking(int fd
) {
282 // MessagePumpLibevent callback, we don't listen for write events
283 // so we shouldn't ever reach here.
289 void StreamListenSocket::PauseReads() {
290 DCHECK(!reads_paused_
);
291 reads_paused_
= true;
294 void StreamListenSocket::ResumeReads() {
295 DCHECK(reads_paused_
);
296 reads_paused_
= false;
297 if (has_pending_reads_
) {
298 has_pending_reads_
= false;