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_FAILED; 100 return OK; 101 } 102 103 SocketDescriptor StreamListenSocket::AcceptSocket() { 104 SocketDescriptor conn = HANDLE_EINTR(accept(socket_, NULL, NULL)); 105 if (conn == kInvalidSocket) 106 LOG(ERROR) << "Error accepting connection."; 107 else 108 SetNonBlocking(conn); 109 return conn; 110 } 111 112 void StreamListenSocket::SendInternal(const char* bytes, int len) { 113 char* send_buf = const_cast<char *>(bytes); 114 int len_left = len; 115 while (true) { 116 int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); 117 if (sent == len_left) { // A shortcut to avoid extraneous checks. 118 break; 119 } 120 if (sent == kSocketError) { 121 #if defined(OS_WIN) 122 if (WSAGetLastError() != WSAEWOULDBLOCK) { 123 LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError(); 124 #elif defined(OS_POSIX) 125 if (errno != EWOULDBLOCK && errno != EAGAIN) { 126 LOG(ERROR) << "send failed: errno==" << errno; 127 #endif 128 break; 129 } 130 // Otherwise we would block, and now we have to wait for a retry. 131 // Fall through to PlatformThread::YieldCurrentThread() 132 } else { 133 // sent != len_left according to the shortcut above. 134 // Shift the buffer start and send the remainder after a short while. 135 send_buf += sent; 136 len_left -= sent; 137 } 138 base::PlatformThread::YieldCurrentThread(); 139 } 140 } 141 142 void StreamListenSocket::Listen() { 143 int backlog = 10; // TODO(erikkay): maybe don't allow any backlog? 144 if (listen(socket_, backlog) == -1) { 145 // TODO(erikkay): error handling. 146 LOG(ERROR) << "Could not listen on socket."; 147 return; 148 } 149 #if defined(OS_POSIX) 150 WatchSocket(WAITING_ACCEPT); 151 #endif 152 } 153 154 void StreamListenSocket::Read() { 155 char buf[kReadBufSize + 1]; // +1 for null termination. 156 int len; 157 do { 158 len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0)); 159 if (len == kSocketError) { 160 #if defined(OS_WIN) 161 int err = WSAGetLastError(); 162 if (err == WSAEWOULDBLOCK) { 163 #elif defined(OS_POSIX) 164 if (errno == EWOULDBLOCK || errno == EAGAIN) { 165 #endif 166 break; 167 } else { 168 // TODO(ibrar): some error handling required here. 169 break; 170 } 171 } else if (len == 0) { 172 // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need 173 // to call it here. 174 #if defined(OS_POSIX) 175 Close(); 176 #endif 177 } else { 178 // TODO(ibrar): maybe change DidRead to take a length instead. 179 DCHECK_GT(len, 0); 180 DCHECK_LE(len, kReadBufSize); 181 buf[len] = 0; // Already create a buffer with +1 length. 182 socket_delegate_->DidRead(this, buf, len); 183 } 184 } while (len == kReadBufSize); 185 } 186 187 void StreamListenSocket::Close() { 188 #if defined(OS_POSIX) 189 if (wait_state_ == NOT_WAITING) 190 return; 191 wait_state_ = NOT_WAITING; 192 #endif 193 UnwatchSocket(); 194 socket_delegate_->DidClose(this); 195 } 196 197 void StreamListenSocket::CloseSocket() { 198 if (socket_ != kInvalidSocket) { 199 UnwatchSocket(); 200 #if defined(OS_WIN) 201 closesocket(socket_); 202 #elif defined(OS_POSIX) 203 close(socket_); 204 #endif 205 } 206 } 207 208 void StreamListenSocket::WatchSocket(WaitState state) { 209 #if defined(OS_WIN) 210 WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ); 211 watcher_.StartWatching(socket_event_, this); 212 #elif defined(OS_POSIX) 213 // Implicitly calls StartWatchingFileDescriptor(). 214 base::MessageLoopForIO::current()->WatchFileDescriptor( 215 socket_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this); 216 wait_state_ = state; 217 #endif 218 } 219 220 void StreamListenSocket::UnwatchSocket() { 221 #if defined(OS_WIN) 222 watcher_.StopWatching(); 223 #elif defined(OS_POSIX) 224 watcher_.StopWatchingFileDescriptor(); 225 #endif 226 } 227 228 // TODO(ibrar): We can add these functions into OS dependent files. 229 #if defined(OS_WIN) 230 // MessageLoop watcher callback. 231 void StreamListenSocket::OnObjectSignaled(HANDLE object) { 232 WSANETWORKEVENTS ev; 233 if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) { 234 // TODO 235 return; 236 } 237 238 if (ev.lNetworkEvents & FD_CLOSE) { 239 Close(); 240 // Close might have deleted this object. We should return immediately. 241 return; 242 } 243 244 // The object was reset by WSAEnumNetworkEvents. Watch for the next signal. 245 watcher_.StartWatching(object, this); 246 247 if (ev.lNetworkEvents == 0) { 248 // Occasionally the event is set even though there is no new data. 249 // The net seems to think that this is ignorable. 250 return; 251 } 252 if (ev.lNetworkEvents & FD_ACCEPT) { 253 Accept(); 254 } 255 if (ev.lNetworkEvents & FD_READ) { 256 if (reads_paused_) { 257 has_pending_reads_ = true; 258 } else { 259 Read(); 260 // Read() might call Close() internally and 'this' can be invalid here 261 return; 262 } 263 } 264 } 265 #elif defined(OS_POSIX) 266 void StreamListenSocket::OnFileCanReadWithoutBlocking(int fd) { 267 switch (wait_state_) { 268 case WAITING_ACCEPT: 269 Accept(); 270 break; 271 case WAITING_READ: 272 if (reads_paused_) { 273 has_pending_reads_ = true; 274 } else { 275 Read(); 276 } 277 break; 278 default: 279 // Close() is called by Read() in the Linux case. 280 NOTREACHED(); 281 break; 282 } 283 } 284 285 void StreamListenSocket::OnFileCanWriteWithoutBlocking(int fd) { 286 // MessagePumpLibevent callback, we don't listen for write events 287 // so we shouldn't ever reach here. 288 NOTREACHED(); 289 } 290 291 #endif 292 293 void StreamListenSocket::PauseReads() { 294 DCHECK(!reads_paused_); 295 reads_paused_ = true; 296 } 297 298 void StreamListenSocket::ResumeReads() { 299 DCHECK(reads_paused_); 300 reads_paused_ = false; 301 if (has_pending_reads_) { 302 has_pending_reads_ = false; 303 Read(); 304 } 305 } 306 307 } // namespace net 308