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