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
31static 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
67static 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
114int 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
143int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
144 return uv_tcp_init_ex(loop, tcp, AF_UNSPEC);
145}
146
147
148int 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
204int 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
253out:
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
270int 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
286int 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
300int 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
314int 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
331int 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
376int 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
383int 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
413int 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
431int 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
453int 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
462void uv__tcp_close(uv_tcp_t* handle) {
463 uv__stream_close((uv_stream_t*)handle);
464}
465
466
467int 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
506fail:
507 uv__close(temp[0]);
508 uv__close(temp[1]);
509 return err;
510}
511