1 // Copyright (c) 2010 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 "build/build_config.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 <errno.h> 13 #include <netinet/in.h> 14 #include <sys/socket.h> 15 #include <arpa/inet.h> 16 #include "net/base/net_errors.h" 17 #if defined(USE_SYSTEM_LIBEVENT) 18 #include <event.h> 19 #else 20 #include "third_party/libevent/event.h" 21 #endif 22 #endif 23 24 #include "base/eintr_wrapper.h" 25 #include "base/threading/platform_thread.h" 26 #include "net/base/net_util.h" 27 #include "net/base/listen_socket.h" 28 29 #if defined(OS_WIN) 30 typedef int socklen_t; 31 #endif // defined(OS_WIN) 32 33 namespace { 34 35 const int kReadBufSize = 4096; 36 37 } // namespace 38 39 #if defined(OS_WIN) 40 const SOCKET ListenSocket::kInvalidSocket = INVALID_SOCKET; 41 const int ListenSocket::kSocketError = SOCKET_ERROR; 42 #elif defined(OS_POSIX) 43 const SOCKET ListenSocket::kInvalidSocket = -1; 44 const int ListenSocket::kSocketError = -1; 45 #endif 46 47 ListenSocket* ListenSocket::Listen(std::string ip, int port, 48 ListenSocketDelegate* del) { 49 SOCKET s = Listen(ip, port); 50 if (s == kInvalidSocket) { 51 // TODO(erikkay): error handling 52 } else { 53 ListenSocket* sock = new ListenSocket(s, del); 54 sock->Listen(); 55 return sock; 56 } 57 return NULL; 58 } 59 60 void ListenSocket::Send(const char* bytes, int len, bool append_linefeed) { 61 SendInternal(bytes, len); 62 if (append_linefeed) { 63 SendInternal("\r\n", 2); 64 } 65 } 66 67 void ListenSocket::Send(const std::string& str, bool append_linefeed) { 68 Send(str.data(), static_cast<int>(str.length()), append_linefeed); 69 } 70 71 void ListenSocket::PauseReads() { 72 DCHECK(!reads_paused_); 73 reads_paused_ = true; 74 } 75 76 void ListenSocket::ResumeReads() { 77 DCHECK(reads_paused_); 78 reads_paused_ = false; 79 if (has_pending_reads_) { 80 has_pending_reads_ = false; 81 Read(); 82 } 83 } 84 85 ListenSocket::ListenSocket(SOCKET s, ListenSocketDelegate *del) 86 : socket_(s), 87 socket_delegate_(del), 88 reads_paused_(false), 89 has_pending_reads_(false) { 90 #if defined(OS_WIN) 91 socket_event_ = WSACreateEvent(); 92 // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT 93 WatchSocket(NOT_WAITING); 94 #endif 95 } 96 97 ListenSocket::~ListenSocket() { 98 #if defined(OS_WIN) 99 if (socket_event_) { 100 WSACloseEvent(socket_event_); 101 socket_event_ = WSA_INVALID_EVENT; 102 } 103 #endif 104 CloseSocket(socket_); 105 } 106 107 SOCKET ListenSocket::Listen(std::string ip, int port) { 108 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 109 if (s != kInvalidSocket) { 110 #if defined(OS_POSIX) 111 // Allow rapid reuse. 112 static const int kOn = 1; 113 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn)); 114 #endif 115 sockaddr_in addr; 116 memset(&addr, 0, sizeof(addr)); 117 addr.sin_family = AF_INET; 118 addr.sin_addr.s_addr = inet_addr(ip.c_str()); 119 addr.sin_port = htons(port); 120 if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) { 121 #if defined(OS_WIN) 122 closesocket(s); 123 #elif defined(OS_POSIX) 124 close(s); 125 #endif 126 s = kInvalidSocket; 127 } 128 } 129 return s; 130 } 131 132 SOCKET ListenSocket::Accept(SOCKET s) { 133 sockaddr_in from; 134 socklen_t from_len = sizeof(from); 135 SOCKET conn = 136 HANDLE_EINTR(accept(s, reinterpret_cast<sockaddr*>(&from), &from_len)); 137 if (conn != kInvalidSocket) { 138 net::SetNonBlocking(conn); 139 } 140 return conn; 141 } 142 143 void ListenSocket::SendInternal(const char* bytes, int len) { 144 char* send_buf = const_cast<char *>(bytes); 145 int len_left = len; 146 while (true) { 147 int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); 148 if (sent == len_left) { // A shortcut to avoid extraneous checks. 149 break; 150 } 151 if (sent == kSocketError) { 152 #if defined(OS_WIN) 153 if (WSAGetLastError() != WSAEWOULDBLOCK) { 154 LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError(); 155 #elif defined(OS_POSIX) 156 if (errno != EWOULDBLOCK && errno != EAGAIN) { 157 LOG(ERROR) << "send failed: errno==" << errno; 158 #endif 159 break; 160 } 161 // Otherwise we would block, and now we have to wait for a retry. 162 // Fall through to PlatformThread::YieldCurrentThread() 163 } else { 164 // sent != len_left according to the shortcut above. 165 // Shift the buffer start and send the remainder after a short while. 166 send_buf += sent; 167 len_left -= sent; 168 } 169 base::PlatformThread::YieldCurrentThread(); 170 } 171 } 172 173 void ListenSocket::Listen() { 174 int backlog = 10; // TODO(erikkay): maybe don't allow any backlog? 175 listen(socket_, backlog); 176 // TODO(erikkay): error handling 177 #if defined(OS_POSIX) 178 WatchSocket(WAITING_ACCEPT); 179 #endif 180 } 181 182 void ListenSocket::Accept() { 183 SOCKET conn = Accept(socket_); 184 if (conn != kInvalidSocket) { 185 scoped_refptr<ListenSocket> sock( 186 new ListenSocket(conn, socket_delegate_)); 187 // it's up to the delegate to AddRef if it wants to keep it around 188 #if defined(OS_POSIX) 189 sock->WatchSocket(WAITING_READ); 190 #endif 191 socket_delegate_->DidAccept(this, sock); 192 } else { 193 // TODO(ibrar): some error handling required here 194 } 195 } 196 197 void ListenSocket::Read() { 198 char buf[kReadBufSize + 1]; // +1 for null termination 199 int len; 200 do { 201 len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0)); 202 if (len == kSocketError) { 203 #if defined(OS_WIN) 204 int err = WSAGetLastError(); 205 if (err == WSAEWOULDBLOCK) { 206 #elif defined(OS_POSIX) 207 if (errno == EWOULDBLOCK || errno == EAGAIN) { 208 #endif 209 break; 210 } else { 211 // TODO(ibrar): some error handling required here 212 break; 213 } 214 } else if (len == 0) { 215 // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need 216 // to call it here. 217 #if defined(OS_POSIX) 218 Close(); 219 #endif 220 } else { 221 // TODO(ibrar): maybe change DidRead to take a length instead 222 DCHECK(len > 0 && len <= kReadBufSize); 223 buf[len] = 0; // already create a buffer with +1 length 224 socket_delegate_->DidRead(this, buf, len); 225 } 226 } while (len == kReadBufSize); 227 } 228 229 void ListenSocket::Close() { 230 #if defined(OS_POSIX) 231 if (wait_state_ == WAITING_CLOSE) 232 return; 233 wait_state_ = WAITING_CLOSE; 234 #endif 235 socket_delegate_->DidClose(this); 236 } 237 238 void ListenSocket::CloseSocket(SOCKET s) { 239 if (s && s != kInvalidSocket) { 240 UnwatchSocket(); 241 #if defined(OS_WIN) 242 closesocket(s); 243 #elif defined(OS_POSIX) 244 close(s); 245 #endif 246 } 247 } 248 249 void ListenSocket::WatchSocket(WaitState state) { 250 #if defined(OS_WIN) 251 WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ); 252 watcher_.StartWatching(socket_event_, this); 253 #elif defined(OS_POSIX) 254 // Implicitly calls StartWatchingFileDescriptor(). 255 MessageLoopForIO::current()->WatchFileDescriptor( 256 socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); 257 wait_state_ = state; 258 #endif 259 } 260 261 void ListenSocket::UnwatchSocket() { 262 #if defined(OS_WIN) 263 watcher_.StopWatching(); 264 #elif defined(OS_POSIX) 265 watcher_.StopWatchingFileDescriptor(); 266 #endif 267 } 268 269 // TODO(ibrar): We can add these functions into OS dependent files 270 #if defined(OS_WIN) 271 // MessageLoop watcher callback 272 void ListenSocket::OnObjectSignaled(HANDLE object) { 273 WSANETWORKEVENTS ev; 274 if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) { 275 // TODO 276 return; 277 } 278 279 // The object was reset by WSAEnumNetworkEvents. Watch for the next signal. 280 watcher_.StartWatching(object, this); 281 282 if (ev.lNetworkEvents == 0) { 283 // Occasionally the event is set even though there is no new data. 284 // The net seems to think that this is ignorable. 285 return; 286 } 287 if (ev.lNetworkEvents & FD_ACCEPT) { 288 Accept(); 289 } 290 if (ev.lNetworkEvents & FD_READ) { 291 if (reads_paused_) { 292 has_pending_reads_ = true; 293 } else { 294 Read(); 295 } 296 } 297 if (ev.lNetworkEvents & FD_CLOSE) { 298 Close(); 299 } 300 } 301 #elif defined(OS_POSIX) 302 void ListenSocket::OnFileCanReadWithoutBlocking(int fd) { 303 if (wait_state_ == WAITING_ACCEPT) { 304 Accept(); 305 } 306 if (wait_state_ == WAITING_READ) { 307 if (reads_paused_) { 308 has_pending_reads_ = true; 309 } else { 310 Read(); 311 } 312 } 313 if (wait_state_ == WAITING_CLOSE) { 314 // Close() is called by Read() in the Linux case. 315 // TODO(erikkay): this seems to get hit multiple times after the close 316 } 317 } 318 319 void ListenSocket::OnFileCanWriteWithoutBlocking(int fd) { 320 // MessagePumpLibevent callback, we don't listen for write events 321 // so we shouldn't ever reach here. 322 NOTREACHED(); 323 } 324 325 #endif 326