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