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   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 
uv__tcp_connect(uv_connect_t * req,uv_tcp_t * handle,const struct sockaddr * addr,unsigned int addrlen,uv_connect_cb cb)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   err = maybe_new_socket(handle,
218                          addr->sa_family,
219                          UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
220   if (err)
221     return err;
222 
223   handle->delayed_error = 0;
224 
225   do {
226     errno = 0;
227     r = connect(uv__stream_fd(handle), addr, addrlen);
228   } while (r == -1 && errno == EINTR);
229 
230   /* We not only check the return value, but also check the errno != 0.
231    * Because in rare cases connect() will return -1 but the errno
232    * is 0 (for example, on Android 4.3, OnePlus phone A0001_12_150227)
233    * and actually the tcp three-way handshake is completed.
234    */
235   if (r == -1 && errno != 0) {
236     if (errno == EINPROGRESS)
237       ; /* not an error */
238     else if (errno == ECONNREFUSED
239 #if defined(__OpenBSD__)
240       || errno == EINVAL
241 #endif
242       )
243     /* If we get ECONNREFUSED (Solaris) or EINVAL (OpenBSD) wait until the
244      * next tick to report the error. Solaris and OpenBSD wants to report
245      * immediately -- other unixes want to wait.
246      */
247       handle->delayed_error = UV__ERR(ECONNREFUSED);
248     else
249       return UV__ERR(errno);
250   }
251 
252   uv__req_init(handle->loop, req, UV_CONNECT);
253   req->cb = cb;
254   req->handle = (uv_stream_t*) handle;
255   QUEUE_INIT(&req->queue);
256   handle->connect_req = req;
257 
258   uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
259 
260   if (handle->delayed_error)
261     uv__io_feed(handle->loop, &handle->io_watcher);
262 
263   return 0;
264 }
265 
266 
uv_tcp_open(uv_tcp_t * handle,uv_os_sock_t sock)267 int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
268   int err;
269 
270   if (uv__fd_exists(handle->loop, sock))
271     return UV_EEXIST;
272 
273   err = uv__nonblock(sock, 1);
274   if (err)
275     return err;
276 
277   return uv__stream_open((uv_stream_t*)handle,
278                          sock,
279                          UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
280 }
281 
282 
uv_tcp_getsockname(const uv_tcp_t * handle,struct sockaddr * name,int * namelen)283 int uv_tcp_getsockname(const uv_tcp_t* handle,
284                        struct sockaddr* name,
285                        int* namelen) {
286 
287   if (handle->delayed_error)
288     return handle->delayed_error;
289 
290   return uv__getsockpeername((const uv_handle_t*) handle,
291                              getsockname,
292                              name,
293                              namelen);
294 }
295 
296 
uv_tcp_getpeername(const uv_tcp_t * handle,struct sockaddr * name,int * namelen)297 int uv_tcp_getpeername(const uv_tcp_t* handle,
298                        struct sockaddr* name,
299                        int* namelen) {
300 
301   if (handle->delayed_error)
302     return handle->delayed_error;
303 
304   return uv__getsockpeername((const uv_handle_t*) handle,
305                              getpeername,
306                              name,
307                              namelen);
308 }
309 
310 
uv_tcp_close_reset(uv_tcp_t * handle,uv_close_cb close_cb)311 int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) {
312   int fd;
313   struct linger l = { 1, 0 };
314 
315   /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */
316   if (handle->flags & UV_HANDLE_SHUTTING)
317     return UV_EINVAL;
318 
319   fd = uv__stream_fd(handle);
320   if (0 != setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)))
321     return UV__ERR(errno);
322 
323   uv_close((uv_handle_t*) handle, close_cb);
324   return 0;
325 }
326 
327 
uv_tcp_listen(uv_tcp_t * tcp,int backlog,uv_connection_cb cb)328 int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
329   static int single_accept_cached = -1;
330   unsigned long flags;
331   int single_accept;
332   int err;
333 
334   if (tcp->delayed_error)
335     return tcp->delayed_error;
336 
337   single_accept = uv__load_relaxed(&single_accept_cached);
338   if (single_accept == -1) {
339     const char* val = getenv("UV_TCP_SINGLE_ACCEPT");
340     single_accept = (val != NULL && atoi(val) != 0);  /* Off by default. */
341     uv__store_relaxed(&single_accept_cached, single_accept);
342   }
343 
344   if (single_accept)
345     tcp->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
346 
347   flags = 0;
348 #if defined(__MVS__)
349   /* on zOS the listen call does not bind automatically
350      if the socket is unbound. Hence the manual binding to
351      an arbitrary port is required to be done manually
352   */
353   flags |= UV_HANDLE_BOUND;
354 #endif
355   err = maybe_new_socket(tcp, AF_INET, flags);
356   if (err)
357     return err;
358 
359   if (listen(tcp->io_watcher.fd, backlog))
360     return UV__ERR(errno);
361 
362   tcp->connection_cb = cb;
363   tcp->flags |= UV_HANDLE_BOUND;
364 
365   /* Start listening for connections. */
366   tcp->io_watcher.cb = uv__server_io;
367   uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
368 
369   return 0;
370 }
371 
372 
uv__tcp_nodelay(int fd,int on)373 int uv__tcp_nodelay(int fd, int on) {
374   if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)))
375     return UV__ERR(errno);
376   return 0;
377 }
378 
379 
uv__tcp_keepalive(int fd,int on,unsigned int delay)380 int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
381   if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
382     return UV__ERR(errno);
383 
384 #ifdef TCP_KEEPIDLE
385   if (on) {
386     int intvl = 1;  /*  1 second; same as default on Win32 */
387     int cnt = 10;  /* 10 retries; same as hardcoded on Win32 */
388     if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
389       return UV__ERR(errno);
390     if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
391       return UV__ERR(errno);
392     if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
393       return UV__ERR(errno);
394   }
395 #endif
396 
397   /* Solaris/SmartOS, if you don't support keep-alive,
398    * then don't advertise it in your system headers...
399    */
400   /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */
401 #if defined(TCP_KEEPALIVE) && !defined(__sun)
402   if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
403     return UV__ERR(errno);
404 #endif
405 
406   return 0;
407 }
408 
409 
uv_tcp_nodelay(uv_tcp_t * handle,int on)410 int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
411   int err;
412 
413   if (uv__stream_fd(handle) != -1) {
414     err = uv__tcp_nodelay(uv__stream_fd(handle), on);
415     if (err)
416       return err;
417   }
418 
419   if (on)
420     handle->flags |= UV_HANDLE_TCP_NODELAY;
421   else
422     handle->flags &= ~UV_HANDLE_TCP_NODELAY;
423 
424   return 0;
425 }
426 
427 
uv_tcp_keepalive(uv_tcp_t * handle,int on,unsigned int delay)428 int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
429   int err;
430 
431   if (uv__stream_fd(handle) != -1) {
432     err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay);
433     if (err)
434       return err;
435   }
436 
437   if (on)
438     handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
439   else
440     handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
441 
442   /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
443    *      uv_tcp_t with an int that's almost never used...
444    */
445 
446   return 0;
447 }
448 
449 
uv_tcp_simultaneous_accepts(uv_tcp_t * handle,int enable)450 int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
451   if (enable)
452     handle->flags &= ~UV_HANDLE_TCP_SINGLE_ACCEPT;
453   else
454     handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
455   return 0;
456 }
457 
458 
uv__tcp_close(uv_tcp_t * handle)459 void uv__tcp_close(uv_tcp_t* handle) {
460   uv__stream_close((uv_stream_t*)handle);
461 }
462