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