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 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
267int 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
283int 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
297int 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
311int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
312 static int single_accept = -1;
313 unsigned long flags;
314 int err;
315
316 if (tcp->delayed_error)
317 return tcp->delayed_error;
318
319 if (single_accept == -1) {
320 const char* val = getenv("UV_TCP_SINGLE_ACCEPT");
321 single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */
322 }
323
324 if (single_accept)
325 tcp->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
326
327 flags = 0;
328#if defined(__MVS__)
329 /* on zOS the listen call does not bind automatically
330 if the socket is unbound. Hence the manual binding to
331 an arbitrary port is required to be done manually
332 */
333 flags |= UV_HANDLE_BOUND;
334#endif
335 err = maybe_new_socket(tcp, AF_INET, flags);
336 if (err)
337 return err;
338
339 if (listen(tcp->io_watcher.fd, backlog))
340 return UV__ERR(errno);
341
342 tcp->connection_cb = cb;
343 tcp->flags |= UV_HANDLE_BOUND;
344
345 /* Start listening for connections. */
346 tcp->io_watcher.cb = uv__server_io;
347 uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
348
349 return 0;
350}
351
352
353int uv__tcp_nodelay(int fd, int on) {
354 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)))
355 return UV__ERR(errno);
356 return 0;
357}
358
359
360int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
361 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
362 return UV__ERR(errno);
363
364#ifdef TCP_KEEPIDLE
365 if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
366 return UV__ERR(errno);
367#endif
368
369 /* Solaris/SmartOS, if you don't support keep-alive,
370 * then don't advertise it in your system headers...
371 */
372 /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */
373#if defined(TCP_KEEPALIVE) && !defined(__sun)
374 if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
375 return UV__ERR(errno);
376#endif
377
378 return 0;
379}
380
381
382int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
383 int err;
384
385 if (uv__stream_fd(handle) != -1) {
386 err = uv__tcp_nodelay(uv__stream_fd(handle), on);
387 if (err)
388 return err;
389 }
390
391 if (on)
392 handle->flags |= UV_HANDLE_TCP_NODELAY;
393 else
394 handle->flags &= ~UV_HANDLE_TCP_NODELAY;
395
396 return 0;
397}
398
399
400int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
401 int err;
402
403 if (uv__stream_fd(handle) != -1) {
404 err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay);
405 if (err)
406 return err;
407 }
408
409 if (on)
410 handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
411 else
412 handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
413
414 /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
415 * uv_tcp_t with an int that's almost never used...
416 */
417
418 return 0;
419}
420
421
422int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
423 if (enable)
424 handle->flags &= ~UV_HANDLE_TCP_SINGLE_ACCEPT;
425 else
426 handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
427 return 0;
428}
429
430
431void uv__tcp_close(uv_tcp_t* handle) {
432 uv__stream_close((uv_stream_t*)handle);
433}
434