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
new_socket(uv_tcp_t * handle,int domain,unsigned long flags)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
maybe_new_socket(uv_tcp_t * handle,int domain,unsigned long flags)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
uv_tcp_init_ex(uv_loop_t * loop,uv_tcp_t * tcp,unsigned int flags)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
uv_tcp_init(uv_loop_t * loop,uv_tcp_t * tcp)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
uv__tcp_bind(uv_tcp_t * tcp,const struct sockaddr * addr,unsigned int addrlen,unsigned int flags)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 err = bind(tcp->io_watcher.fd, addr, addrlen);
188 if (err == -1 && errno != EADDRINUSE) {
189 if (errno == EAFNOSUPPORT)
190 /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
191 * socket created with AF_INET to an AF_INET6 address or vice versa. */
192 return UV_EINVAL;
193 return UV__ERR(errno);
194 }
195 tcp->delayed_error = (err == -1) ? UV__ERR(errno) : 0;
196
197 tcp->flags |= UV_HANDLE_BOUND;
198 if (addr->sa_family == AF_INET6)
199 tcp->flags |= UV_HANDLE_IPV6;
200
201 return 0;
202 }
203
204
uv__tcp_connect(uv_connect_t * req,uv_tcp_t * handle,const struct sockaddr * addr,unsigned int addrlen,uv_connect_cb cb)205 int uv__tcp_connect(uv_connect_t* req,
206 uv_tcp_t* handle,
207 const struct sockaddr* addr,
208 unsigned int addrlen,
209 uv_connect_cb cb) {
210 int err;
211 int r;
212
213 assert(handle->type == UV_TCP);
214
215 if (handle->connect_req != NULL)
216 return UV_EALREADY; /* FIXME(bnoordhuis) UV_EINVAL or maybe UV_EBUSY. */
217
218 if (handle->delayed_error != 0)
219 goto out;
220
221 err = maybe_new_socket(handle,
222 addr->sa_family,
223 UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
224 if (err)
225 return err;
226
227 do {
228 errno = 0;
229 r = connect(uv__stream_fd(handle), addr, addrlen);
230 } while (r == -1 && errno == EINTR);
231
232 /* We not only check the return value, but also check the errno != 0.
233 * Because in rare cases connect() will return -1 but the errno
234 * is 0 (for example, on Android 4.3, OnePlus phone A0001_12_150227)
235 * and actually the tcp three-way handshake is completed.
236 */
237 if (r == -1 && errno != 0) {
238 if (errno == EINPROGRESS)
239 ; /* not an error */
240 else if (errno == ECONNREFUSED
241 #if defined(__OpenBSD__)
242 || errno == EINVAL
243 #endif
244 )
245 /* If we get ECONNREFUSED (Solaris) or EINVAL (OpenBSD) wait until the
246 * next tick to report the error. Solaris and OpenBSD wants to report
247 * immediately -- other unixes want to wait.
248 */
249 handle->delayed_error = UV__ERR(ECONNREFUSED);
250 else
251 return UV__ERR(errno);
252 }
253
254 out:
255
256 uv__req_init(handle->loop, req, UV_CONNECT);
257 req->cb = cb;
258 req->handle = (uv_stream_t*) handle;
259 QUEUE_INIT(&req->queue);
260 handle->connect_req = req;
261
262 uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
263
264 if (handle->delayed_error)
265 uv__io_feed(handle->loop, &handle->io_watcher);
266
267 return 0;
268 }
269
270
uv_tcp_open(uv_tcp_t * handle,uv_os_sock_t sock)271 int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
272 int err;
273
274 if (uv__fd_exists(handle->loop, sock))
275 return UV_EEXIST;
276
277 err = uv__nonblock(sock, 1);
278 if (err)
279 return err;
280
281 return uv__stream_open((uv_stream_t*)handle,
282 sock,
283 UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
284 }
285
286
uv_tcp_getsockname(const uv_tcp_t * handle,struct sockaddr * name,int * namelen)287 int uv_tcp_getsockname(const uv_tcp_t* handle,
288 struct sockaddr* name,
289 int* namelen) {
290
291 if (handle->delayed_error)
292 return handle->delayed_error;
293
294 return uv__getsockpeername((const uv_handle_t*) handle,
295 getsockname,
296 name,
297 namelen);
298 }
299
300
uv_tcp_getpeername(const uv_tcp_t * handle,struct sockaddr * name,int * namelen)301 int uv_tcp_getpeername(const uv_tcp_t* handle,
302 struct sockaddr* name,
303 int* namelen) {
304
305 if (handle->delayed_error)
306 return handle->delayed_error;
307
308 return uv__getsockpeername((const uv_handle_t*) handle,
309 getpeername,
310 name,
311 namelen);
312 }
313
314
uv_tcp_close_reset(uv_tcp_t * handle,uv_close_cb close_cb)315 int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) {
316 int fd;
317 struct linger l = { 1, 0 };
318
319 /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */
320 if (handle->flags & UV_HANDLE_SHUTTING)
321 return UV_EINVAL;
322
323 fd = uv__stream_fd(handle);
324 if (0 != setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l))) {
325 if (errno == EINVAL) {
326 /* Open Group Specifications Issue 7, 2018 edition states that
327 * EINVAL may mean the socket has been shut down already.
328 * Behavior observed on Solaris, illumos and macOS. */
329 errno = 0;
330 } else {
331 return UV__ERR(errno);
332 }
333 }
334
335 uv_close((uv_handle_t*) handle, close_cb);
336 return 0;
337 }
338
339
uv__tcp_listen(uv_tcp_t * tcp,int backlog,uv_connection_cb cb)340 int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
341 static int single_accept_cached = -1;
342 unsigned long flags;
343 int single_accept;
344 int err;
345
346 if (tcp->delayed_error)
347 return tcp->delayed_error;
348
349 single_accept = uv__load_relaxed(&single_accept_cached);
350 if (single_accept == -1) {
351 const char* val = getenv("UV_TCP_SINGLE_ACCEPT");
352 single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */
353 uv__store_relaxed(&single_accept_cached, single_accept);
354 }
355
356 if (single_accept)
357 tcp->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
358
359 flags = 0;
360 #if defined(__MVS__)
361 /* on zOS the listen call does not bind automatically
362 if the socket is unbound. Hence the manual binding to
363 an arbitrary port is required to be done manually
364 */
365 flags |= UV_HANDLE_BOUND;
366 #endif
367 err = maybe_new_socket(tcp, AF_INET, flags);
368 if (err)
369 return err;
370
371 if (listen(tcp->io_watcher.fd, backlog))
372 return UV__ERR(errno);
373
374 tcp->connection_cb = cb;
375 tcp->flags |= UV_HANDLE_BOUND;
376
377 /* Start listening for connections. */
378 tcp->io_watcher.cb = uv__server_io;
379 uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
380
381 return 0;
382 }
383
384
uv__tcp_nodelay(int fd,int on)385 int uv__tcp_nodelay(int fd, int on) {
386 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)))
387 return UV__ERR(errno);
388 return 0;
389 }
390
391
uv__tcp_keepalive(int fd,int on,unsigned int delay)392 int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
393 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
394 return UV__ERR(errno);
395
396 #ifdef TCP_KEEPIDLE
397 if (on) {
398 int intvl = 1; /* 1 second; same as default on Win32 */
399 int cnt = 10; /* 10 retries; same as hardcoded on Win32 */
400 if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
401 return UV__ERR(errno);
402 if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
403 return UV__ERR(errno);
404 if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
405 return UV__ERR(errno);
406 }
407 #endif
408
409 /* Solaris/SmartOS, if you don't support keep-alive,
410 * then don't advertise it in your system headers...
411 */
412 /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */
413 #if defined(TCP_KEEPALIVE) && !defined(__sun)
414 if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
415 return UV__ERR(errno);
416 #endif
417
418 return 0;
419 }
420
421
uv_tcp_nodelay(uv_tcp_t * handle,int on)422 int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
423 int err;
424
425 if (uv__stream_fd(handle) != -1) {
426 err = uv__tcp_nodelay(uv__stream_fd(handle), on);
427 if (err)
428 return err;
429 }
430
431 if (on)
432 handle->flags |= UV_HANDLE_TCP_NODELAY;
433 else
434 handle->flags &= ~UV_HANDLE_TCP_NODELAY;
435
436 return 0;
437 }
438
439
uv_tcp_keepalive(uv_tcp_t * handle,int on,unsigned int delay)440 int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
441 int err;
442
443 if (uv__stream_fd(handle) != -1) {
444 err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay);
445 if (err)
446 return err;
447 }
448
449 if (on)
450 handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
451 else
452 handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
453
454 /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
455 * uv_tcp_t with an int that's almost never used...
456 */
457
458 return 0;
459 }
460
461
uv_tcp_simultaneous_accepts(uv_tcp_t * handle,int enable)462 int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
463 if (enable)
464 handle->flags &= ~UV_HANDLE_TCP_SINGLE_ACCEPT;
465 else
466 handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
467 return 0;
468 }
469
470
uv__tcp_close(uv_tcp_t * handle)471 void uv__tcp_close(uv_tcp_t* handle) {
472 uv__stream_close((uv_stream_t*)handle);
473 }
474
475
uv_socketpair(int type,int protocol,uv_os_sock_t fds[2],int flags0,int flags1)476 int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) {
477 uv_os_sock_t temp[2];
478 int err;
479 #if defined(__FreeBSD__) || defined(__linux__)
480 int flags;
481
482 flags = type | SOCK_CLOEXEC;
483 if ((flags0 & UV_NONBLOCK_PIPE) && (flags1 & UV_NONBLOCK_PIPE))
484 flags |= SOCK_NONBLOCK;
485
486 if (socketpair(AF_UNIX, flags, protocol, temp))
487 return UV__ERR(errno);
488
489 if (flags & UV_FS_O_NONBLOCK) {
490 fds[0] = temp[0];
491 fds[1] = temp[1];
492 return 0;
493 }
494 #else
495 if (socketpair(AF_UNIX, type, protocol, temp))
496 return UV__ERR(errno);
497
498 if ((err = uv__cloexec(temp[0], 1)))
499 goto fail;
500 if ((err = uv__cloexec(temp[1], 1)))
501 goto fail;
502 #endif
503
504 if (flags0 & UV_NONBLOCK_PIPE)
505 if ((err = uv__nonblock(temp[0], 1)))
506 goto fail;
507 if (flags1 & UV_NONBLOCK_PIPE)
508 if ((err = uv__nonblock(temp[1], 1)))
509 goto fail;
510
511 fds[0] = temp[0];
512 fds[1] = temp[1];
513 return 0;
514
515 fail:
516 uv__close(temp[0]);
517 uv__close(temp[1]);
518 return err;
519 }
520