1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. |
2 | * |
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
4 | * of this software and associated documentation files (the "Software"), to |
5 | * deal in the Software without restriction, including without limitation the |
6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
7 | * sell copies of the Software, and to permit persons to whom the Software is |
8 | * furnished to do so, subject to the following conditions: |
9 | * |
10 | * The above copyright notice and this permission notice shall be included in |
11 | * all copies or substantial portions of the Software. |
12 | * |
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
19 | * IN THE SOFTWARE. |
20 | */ |
21 | |
22 | #include "uv.h" |
23 | #include "internal.h" |
24 | |
25 | #include <stdlib.h> |
26 | #include <unistd.h> |
27 | #include <assert.h> |
28 | #include <errno.h> |
29 | |
30 | |
31 | static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { |
32 | struct sockaddr_storage saddr; |
33 | socklen_t slen; |
34 | int sockfd; |
35 | int err; |
36 | |
37 | err = uv__socket(domain, SOCK_STREAM, 0); |
38 | if (err < 0) |
39 | return err; |
40 | sockfd = err; |
41 | |
42 | err = uv__stream_open((uv_stream_t*) handle, sockfd, flags); |
43 | if (err) { |
44 | uv__close(sockfd); |
45 | return err; |
46 | } |
47 | |
48 | if (flags & UV_HANDLE_BOUND) { |
49 | /* Bind this new socket to an arbitrary port */ |
50 | slen = sizeof(saddr); |
51 | memset(&saddr, 0, sizeof(saddr)); |
52 | if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) { |
53 | uv__close(sockfd); |
54 | return UV__ERR(errno); |
55 | } |
56 | |
57 | if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) { |
58 | uv__close(sockfd); |
59 | return UV__ERR(errno); |
60 | } |
61 | } |
62 | |
63 | return 0; |
64 | } |
65 | |
66 | |
67 | static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { |
68 | struct sockaddr_storage saddr; |
69 | socklen_t slen; |
70 | |
71 | if (domain == AF_UNSPEC) { |
72 | handle->flags |= flags; |
73 | return 0; |
74 | } |
75 | |
76 | if (uv__stream_fd(handle) != -1) { |
77 | |
78 | if (flags & UV_HANDLE_BOUND) { |
79 | |
80 | if (handle->flags & UV_HANDLE_BOUND) { |
81 | /* It is already bound to a port. */ |
82 | handle->flags |= flags; |
83 | return 0; |
84 | } |
85 | |
86 | /* Query to see if tcp socket is bound. */ |
87 | slen = sizeof(saddr); |
88 | memset(&saddr, 0, sizeof(saddr)); |
89 | if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) |
90 | return UV__ERR(errno); |
91 | |
92 | if ((saddr.ss_family == AF_INET6 && |
93 | ((struct sockaddr_in6*) &saddr)->sin6_port != 0) || |
94 | (saddr.ss_family == AF_INET && |
95 | ((struct sockaddr_in*) &saddr)->sin_port != 0)) { |
96 | /* Handle is already bound to a port. */ |
97 | handle->flags |= flags; |
98 | return 0; |
99 | } |
100 | |
101 | /* Bind to arbitrary port */ |
102 | if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) |
103 | return UV__ERR(errno); |
104 | } |
105 | |
106 | handle->flags |= flags; |
107 | return 0; |
108 | } |
109 | |
110 | return new_socket(handle, domain, flags); |
111 | } |
112 | |
113 | |
114 | int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* tcp, unsigned int flags) { |
115 | int domain; |
116 | |
117 | /* Use the lower 8 bits for the domain */ |
118 | domain = flags & 0xFF; |
119 | if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) |
120 | return UV_EINVAL; |
121 | |
122 | if (flags & ~0xFF) |
123 | return UV_EINVAL; |
124 | |
125 | uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP); |
126 | |
127 | /* If anything fails beyond this point we need to remove the handle from |
128 | * the handle queue, since it was added by uv__handle_init in uv_stream_init. |
129 | */ |
130 | |
131 | if (domain != AF_UNSPEC) { |
132 | int err = maybe_new_socket(tcp, domain, 0); |
133 | if (err) { |
134 | QUEUE_REMOVE(&tcp->handle_queue); |
135 | return err; |
136 | } |
137 | } |
138 | |
139 | return 0; |
140 | } |
141 | |
142 | |
143 | int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) { |
144 | return uv_tcp_init_ex(loop, tcp, AF_UNSPEC); |
145 | } |
146 | |
147 | |
148 | int uv__tcp_bind(uv_tcp_t* tcp, |
149 | const struct sockaddr* addr, |
150 | unsigned int addrlen, |
151 | unsigned int flags) { |
152 | int err; |
153 | int on; |
154 | |
155 | /* Cannot set IPv6-only mode on non-IPv6 socket. */ |
156 | if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) |
157 | return UV_EINVAL; |
158 | |
159 | err = maybe_new_socket(tcp, addr->sa_family, 0); |
160 | if (err) |
161 | return err; |
162 | |
163 | on = 1; |
164 | if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) |
165 | return UV__ERR(errno); |
166 | |
167 | #ifndef __OpenBSD__ |
168 | #ifdef IPV6_V6ONLY |
169 | if (addr->sa_family == AF_INET6) { |
170 | on = (flags & UV_TCP_IPV6ONLY) != 0; |
171 | if (setsockopt(tcp->io_watcher.fd, |
172 | IPPROTO_IPV6, |
173 | IPV6_V6ONLY, |
174 | &on, |
175 | sizeof on) == -1) { |
176 | #if defined(__MVS__) |
177 | if (errno == EOPNOTSUPP) |
178 | return UV_EINVAL; |
179 | #endif |
180 | return UV__ERR(errno); |
181 | } |
182 | } |
183 | #endif |
184 | #endif |
185 | |
186 | errno = 0; |
187 | if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE) { |
188 | if (errno == EAFNOSUPPORT) |
189 | /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a |
190 | * socket created with AF_INET to an AF_INET6 address or vice versa. */ |
191 | return UV_EINVAL; |
192 | return UV__ERR(errno); |
193 | } |
194 | tcp->delayed_error = UV__ERR(errno); |
195 | |
196 | tcp->flags |= UV_HANDLE_BOUND; |
197 | if (addr->sa_family == AF_INET6) |
198 | tcp->flags |= UV_HANDLE_IPV6; |
199 | |
200 | return 0; |
201 | } |
202 | |
203 | |
204 | int uv__tcp_connect(uv_connect_t* req, |
205 | uv_tcp_t* handle, |
206 | const struct sockaddr* addr, |
207 | unsigned int addrlen, |
208 | uv_connect_cb cb) { |
209 | int err; |
210 | int r; |
211 | |
212 | assert(handle->type == UV_TCP); |
213 | |
214 | if (handle->connect_req != NULL) |
215 | return UV_EALREADY; /* FIXME(bnoordhuis) UV_EINVAL or maybe UV_EBUSY. */ |
216 | |
217 | if (handle->delayed_error != 0) |
218 | goto out; |
219 | |
220 | err = maybe_new_socket(handle, |
221 | addr->sa_family, |
222 | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); |
223 | if (err) |
224 | return err; |
225 | |
226 | do { |
227 | errno = 0; |
228 | r = connect(uv__stream_fd(handle), addr, addrlen); |
229 | } while (r == -1 && errno == EINTR); |
230 | |
231 | /* We not only check the return value, but also check the errno != 0. |
232 | * Because in rare cases connect() will return -1 but the errno |
233 | * is 0 (for example, on Android 4.3, OnePlus phone A0001_12_150227) |
234 | * and actually the tcp three-way handshake is completed. |
235 | */ |
236 | if (r == -1 && errno != 0) { |
237 | if (errno == EINPROGRESS) |
238 | ; /* not an error */ |
239 | else if (errno == ECONNREFUSED |
240 | #if defined(__OpenBSD__) |
241 | || errno == EINVAL |
242 | #endif |
243 | ) |
244 | /* If we get ECONNREFUSED (Solaris) or EINVAL (OpenBSD) wait until the |
245 | * next tick to report the error. Solaris and OpenBSD wants to report |
246 | * immediately -- other unixes want to wait. |
247 | */ |
248 | handle->delayed_error = UV__ERR(ECONNREFUSED); |
249 | else |
250 | return UV__ERR(errno); |
251 | } |
252 | |
253 | out: |
254 | |
255 | uv__req_init(handle->loop, req, UV_CONNECT); |
256 | req->cb = cb; |
257 | req->handle = (uv_stream_t*) handle; |
258 | QUEUE_INIT(&req->queue); |
259 | handle->connect_req = req; |
260 | |
261 | uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); |
262 | |
263 | if (handle->delayed_error) |
264 | uv__io_feed(handle->loop, &handle->io_watcher); |
265 | |
266 | return 0; |
267 | } |
268 | |
269 | |
270 | int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { |
271 | int err; |
272 | |
273 | if (uv__fd_exists(handle->loop, sock)) |
274 | return UV_EEXIST; |
275 | |
276 | err = uv__nonblock(sock, 1); |
277 | if (err) |
278 | return err; |
279 | |
280 | return uv__stream_open((uv_stream_t*)handle, |
281 | sock, |
282 | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); |
283 | } |
284 | |
285 | |
286 | int uv_tcp_getsockname(const uv_tcp_t* handle, |
287 | struct sockaddr* name, |
288 | int* namelen) { |
289 | |
290 | if (handle->delayed_error) |
291 | return handle->delayed_error; |
292 | |
293 | return uv__getsockpeername((const uv_handle_t*) handle, |
294 | getsockname, |
295 | name, |
296 | namelen); |
297 | } |
298 | |
299 | |
300 | int uv_tcp_getpeername(const uv_tcp_t* handle, |
301 | struct sockaddr* name, |
302 | int* namelen) { |
303 | |
304 | if (handle->delayed_error) |
305 | return handle->delayed_error; |
306 | |
307 | return uv__getsockpeername((const uv_handle_t*) handle, |
308 | getpeername, |
309 | name, |
310 | namelen); |
311 | } |
312 | |
313 | |
314 | int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) { |
315 | int fd; |
316 | struct linger l = { 1, 0 }; |
317 | |
318 | /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */ |
319 | if (handle->flags & UV_HANDLE_SHUTTING) |
320 | return UV_EINVAL; |
321 | |
322 | fd = uv__stream_fd(handle); |
323 | if (0 != setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l))) |
324 | return UV__ERR(errno); |
325 | |
326 | uv_close((uv_handle_t*) handle, close_cb); |
327 | return 0; |
328 | } |
329 | |
330 | |
331 | int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { |
332 | static int single_accept_cached = -1; |
333 | unsigned long flags; |
334 | int single_accept; |
335 | int err; |
336 | |
337 | if (tcp->delayed_error) |
338 | return tcp->delayed_error; |
339 | |
340 | single_accept = uv__load_relaxed(&single_accept_cached); |
341 | if (single_accept == -1) { |
342 | const char* val = getenv("UV_TCP_SINGLE_ACCEPT" ); |
343 | single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */ |
344 | uv__store_relaxed(&single_accept_cached, single_accept); |
345 | } |
346 | |
347 | if (single_accept) |
348 | tcp->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; |
349 | |
350 | flags = 0; |
351 | #if defined(__MVS__) |
352 | /* on zOS the listen call does not bind automatically |
353 | if the socket is unbound. Hence the manual binding to |
354 | an arbitrary port is required to be done manually |
355 | */ |
356 | flags |= UV_HANDLE_BOUND; |
357 | #endif |
358 | err = maybe_new_socket(tcp, AF_INET, flags); |
359 | if (err) |
360 | return err; |
361 | |
362 | if (listen(tcp->io_watcher.fd, backlog)) |
363 | return UV__ERR(errno); |
364 | |
365 | tcp->connection_cb = cb; |
366 | tcp->flags |= UV_HANDLE_BOUND; |
367 | |
368 | /* Start listening for connections. */ |
369 | tcp->io_watcher.cb = uv__server_io; |
370 | uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN); |
371 | |
372 | return 0; |
373 | } |
374 | |
375 | |
376 | int uv__tcp_nodelay(int fd, int on) { |
377 | if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on))) |
378 | return UV__ERR(errno); |
379 | return 0; |
380 | } |
381 | |
382 | |
383 | int uv__tcp_keepalive(int fd, int on, unsigned int delay) { |
384 | if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) |
385 | return UV__ERR(errno); |
386 | |
387 | #ifdef TCP_KEEPIDLE |
388 | if (on) { |
389 | int intvl = 1; /* 1 second; same as default on Win32 */ |
390 | int cnt = 10; /* 10 retries; same as hardcoded on Win32 */ |
391 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) |
392 | return UV__ERR(errno); |
393 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) |
394 | return UV__ERR(errno); |
395 | if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt))) |
396 | return UV__ERR(errno); |
397 | } |
398 | #endif |
399 | |
400 | /* Solaris/SmartOS, if you don't support keep-alive, |
401 | * then don't advertise it in your system headers... |
402 | */ |
403 | /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */ |
404 | #if defined(TCP_KEEPALIVE) && !defined(__sun) |
405 | if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay))) |
406 | return UV__ERR(errno); |
407 | #endif |
408 | |
409 | return 0; |
410 | } |
411 | |
412 | |
413 | int uv_tcp_nodelay(uv_tcp_t* handle, int on) { |
414 | int err; |
415 | |
416 | if (uv__stream_fd(handle) != -1) { |
417 | err = uv__tcp_nodelay(uv__stream_fd(handle), on); |
418 | if (err) |
419 | return err; |
420 | } |
421 | |
422 | if (on) |
423 | handle->flags |= UV_HANDLE_TCP_NODELAY; |
424 | else |
425 | handle->flags &= ~UV_HANDLE_TCP_NODELAY; |
426 | |
427 | return 0; |
428 | } |
429 | |
430 | |
431 | int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) { |
432 | int err; |
433 | |
434 | if (uv__stream_fd(handle) != -1) { |
435 | err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay); |
436 | if (err) |
437 | return err; |
438 | } |
439 | |
440 | if (on) |
441 | handle->flags |= UV_HANDLE_TCP_KEEPALIVE; |
442 | else |
443 | handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; |
444 | |
445 | /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge |
446 | * uv_tcp_t with an int that's almost never used... |
447 | */ |
448 | |
449 | return 0; |
450 | } |
451 | |
452 | |
453 | int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { |
454 | if (enable) |
455 | handle->flags &= ~UV_HANDLE_TCP_SINGLE_ACCEPT; |
456 | else |
457 | handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; |
458 | return 0; |
459 | } |
460 | |
461 | |
462 | void uv__tcp_close(uv_tcp_t* handle) { |
463 | uv__stream_close((uv_stream_t*)handle); |
464 | } |
465 | |
466 | |
467 | int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) { |
468 | uv_os_sock_t temp[2]; |
469 | int err; |
470 | #if defined(__FreeBSD__) || defined(__linux__) |
471 | int flags; |
472 | |
473 | flags = type | SOCK_CLOEXEC; |
474 | if ((flags0 & UV_NONBLOCK_PIPE) && (flags1 & UV_NONBLOCK_PIPE)) |
475 | flags |= SOCK_NONBLOCK; |
476 | |
477 | if (socketpair(AF_UNIX, flags, protocol, temp)) |
478 | return UV__ERR(errno); |
479 | |
480 | if (flags & UV_FS_O_NONBLOCK) { |
481 | fds[0] = temp[0]; |
482 | fds[1] = temp[1]; |
483 | return 0; |
484 | } |
485 | #else |
486 | if (socketpair(AF_UNIX, type, protocol, temp)) |
487 | return UV__ERR(errno); |
488 | |
489 | if ((err = uv__cloexec(temp[0], 1))) |
490 | goto fail; |
491 | if ((err = uv__cloexec(temp[1], 1))) |
492 | goto fail; |
493 | #endif |
494 | |
495 | if (flags0 & UV_NONBLOCK_PIPE) |
496 | if ((err = uv__nonblock(temp[0], 1))) |
497 | goto fail; |
498 | if (flags1 & UV_NONBLOCK_PIPE) |
499 | if ((err = uv__nonblock(temp[1], 1))) |
500 | goto fail; |
501 | |
502 | fds[0] = temp[0]; |
503 | fds[1] = temp[1]; |
504 | return 0; |
505 | |
506 | fail: |
507 | uv__close(temp[0]); |
508 | uv__close(temp[1]); |
509 | return err; |
510 | } |
511 | |