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