Show Pages in chrome://md-settings
[chromium-blink-merge.git] / net / socket / stream_listen_socket.cc
blobfd164a556d5b3f0235794e4e939be61f4cd7459d
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"
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
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"
32 using std::string;
34 #if defined(OS_WIN)
35 typedef int socklen_t;
36 #endif // defined(OS_WIN)
38 namespace net {
40 namespace {
42 const int kReadBufSize = 4096;
44 } // namespace
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
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
67 StreamListenSocket::~StreamListenSocket() {
68 CloseSocket();
69 #if defined(OS_WIN)
70 if (socket_event_) {
71 WSACloseEvent(socket_event_);
72 socket_event_ = WSA_INVALID_EVENT;
74 #endif
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);
84 void StreamListenSocket::Send(const string& str, bool append_linefeed) {
85 Send(str.data(), static_cast<int>(str.length()), append_linefeed);
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);
98 if (!address->FromSockAddr(storage.addr, storage.addr_len))
99 return ERR_ADDRESS_INVALID;
100 return OK;
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);
114 if (!address->FromSockAddr(storage.addr, storage.addr_len))
115 return ERR_ADDRESS_INVALID;
117 return OK;
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;
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;
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;
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;
155 base::PlatformThread::YieldCurrentThread();
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;
166 #if defined(OS_POSIX)
167 WatchSocket(WAITING_ACCEPT);
168 #endif
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;
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);
201 } while (len == kReadBufSize);
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);
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
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
237 void StreamListenSocket::UnwatchSocket() {
238 #if defined(OS_WIN)
239 watcher_.StopWatching();
240 #elif defined(OS_POSIX)
241 watcher_.StopWatchingFileDescriptor();
242 #endif
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;
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;
263 // The object was reset by WSAEnumNetworkEvents. Watch for the next signal.
264 watcher_.StartWatching(object, this);
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;
271 if (ev.lNetworkEvents & FD_ACCEPT) {
272 Accept();
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.
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();
295 break;
296 default:
297 // Close() is called by Read() in the Linux case.
298 NOTREACHED();
299 break;
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();
309 #endif
311 void StreamListenSocket::PauseReads() {
312 DCHECK(!reads_paused_);
313 reads_paused_ = true;
316 void StreamListenSocket::ResumeReads() {
317 DCHECK(reads_paused_);
318 reads_paused_ = false;
319 if (has_pending_reads_) {
320 has_pending_reads_ = false;
321 Read();
325 } // namespace net