Rizin
unix-like reverse engineering framework and cli tools
tcp.c
Go to the documentation of this file.
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 
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 
38  if (err < 0)
39  return err;
40  sockfd = err;
41 
43  if (err) {
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)) {
54  return UV__ERR(errno);
55  }
56 
57  if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) {
59  return UV__ERR(errno);
60  }
61  }
62 
63  return 0;
64 }
65 
66 
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 
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 
144  return uv_tcp_init_ex(loop, tcp, AF_UNSPEC);
145 }
146 
147 
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 
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 
218  addr->sa_family,
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 
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 
278  sock,
280 }
281 
282 
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 
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 
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 
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 
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  */
354 #endif
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 
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 
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 
411  int err;
412 
413  if (uv__stream_fd(handle) != -1) {
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 
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) {
433  if (err)
434  return err;
435  }
436 
437  if (on)
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 
451  if (enable)
453  else
455  return 0;
456 }
457 
458 
461 }
ut16 val
Definition: armass64_const.h:6
static bool err
Definition: armass.c:435
static mcore_handle handle
Definition: asm_mcore.c:8
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd domain
Definition: sflib.h:79
#define UV__ERR(x)
Definition: errno.h:29
return memset(p, 0, total)
static const void static count static fd struct stat static buf struct pollfd unsigned static timeout void static offset void static length char static len const struct iovec static count unsigned long static filedes static sched_yield static flags static oldfd static pause unsigned static seconds static protocol struct sockaddr addrlen
Definition: sflib.h:75
assert(limit<=UINT32_MAX/2)
#define QUEUE_INIT(q)
Definition: queue.h:45
#define QUEUE_REMOVE(q)
Definition: queue.h:101
static struct sockaddr static addrlen listen
Definition: sfsocketcall.h:116
static sockfd
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
static bind
Definition: sfsocketcall.h:114
#define SO_KEEPALIVE
Definition: sftypes.h:437
#define EINVAL
Definition: sftypes.h:132
#define EINTR
Definition: sftypes.h:114
#define EOPNOTSUPP
Definition: sftypes.h:155
#define EAFNOSUPPORT
Definition: sftypes.h:157
#define SO_LINGER
Definition: sftypes.h:441
#define SO_REUSEADDR
Definition: sftypes.h:430
#define EADDRINUSE
Definition: sftypes.h:158
#define EINPROGRESS
Definition: sftypes.h:175
unsigned int socklen_t
Definition: sftypes.h:219
@ SOCK_STREAM
Definition: sftypes.h:224
#define SOL_SOCKET
Definition: sftypes.h:427
#define AF_INET
Definition: sftypes.h:287
#define AF_INET6
Definition: sftypes.h:295
#define ECONNREFUSED
Definition: sftypes.h:171
#define AF_UNSPEC
Definition: sftypes.h:283
Definition: z80asm.h:102
Definition: uv.h:1780
Definition: uv.h:547
char * getenv()
uv_loop_t * loop
Definition: main.c:7
void uv__io_start(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: core.c:882
int uv__fd_exists(uv_loop_t *loop, int fd)
Definition: core.c:965
int uv__getsockpeername(const uv_handle_t *handle, uv__peersockfunc func, struct sockaddr *name, int *namelen)
Definition: core.c:1490
int uv__socket(int domain, int type, int protocol)
Definition: core.c:436
void uv__io_feed(uv_loop_t *loop, uv__io_t *w)
Definition: core.c:952
int uv__close(int fd)
Definition: core.c:569
int uv__stream_open(uv_stream_t *, int fd, int flags)
Definition: stream.c:406
void uv__server_io(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: stream.c:528
#define uv__stream_fd(handle)
Definition: internal.h:282
#define uv__nonblock
Definition: internal.h:170
void uv__stream_close(uv_stream_t *handle)
Definition: stream.c:1633
void uv__stream_init(uv_loop_t *loop, uv_stream_t *stream, uv_handle_type type)
Definition: stream.c:85
static int maybe_new_socket(uv_tcp_t *handle, int domain, unsigned long flags)
Definition: tcp.c:67
int uv__tcp_keepalive(int fd, int on, unsigned int delay)
Definition: tcp.c:380
int uv__tcp_connect(uv_connect_t *req, uv_tcp_t *handle, const struct sockaddr *addr, unsigned int addrlen, uv_connect_cb cb)
Definition: tcp.c:204
int uv__tcp_bind(uv_tcp_t *tcp, const struct sockaddr *addr, unsigned int addrlen, unsigned int flags)
Definition: tcp.c:148
int uv_tcp_init(uv_loop_t *loop, uv_tcp_t *tcp)
Definition: tcp.c:143
int uv_tcp_close_reset(uv_tcp_t *handle, uv_close_cb close_cb)
Definition: tcp.c:311
static int new_socket(uv_tcp_t *handle, int domain, unsigned long flags)
Definition: tcp.c:31
int uv_tcp_listen(uv_tcp_t *tcp, int backlog, uv_connection_cb cb)
Definition: tcp.c:328
int uv_tcp_nodelay(uv_tcp_t *handle, int on)
Definition: tcp.c:410
int uv_tcp_open(uv_tcp_t *handle, uv_os_sock_t sock)
Definition: tcp.c:267
int uv_tcp_getpeername(const uv_tcp_t *handle, struct sockaddr *name, int *namelen)
Definition: tcp.c:297
int uv_tcp_simultaneous_accepts(uv_tcp_t *handle, int enable)
Definition: tcp.c:450
int uv_tcp_init_ex(uv_loop_t *loop, uv_tcp_t *tcp, unsigned int flags)
Definition: tcp.c:114
int uv_tcp_keepalive(uv_tcp_t *handle, int on, unsigned int delay)
Definition: tcp.c:428
void uv__tcp_close(uv_tcp_t *handle)
Definition: tcp.c:459
int uv__tcp_nodelay(int fd, int on)
Definition: tcp.c:373
int uv_tcp_getsockname(const uv_tcp_t *handle, struct sockaddr *name, int *namelen)
Definition: tcp.c:283
int uv_os_sock_t
Definition: unix.h:129
@ UV_HANDLE_TCP_KEEPALIVE
Definition: uv-common.h:106
@ UV_HANDLE_IPV6
Definition: uv-common.h:102
@ UV_HANDLE_TCP_NODELAY
Definition: uv-common.h:105
@ UV_HANDLE_TCP_SINGLE_ACCEPT
Definition: uv-common.h:107
@ UV_HANDLE_SHUTTING
Definition: uv-common.h:84
@ UV_HANDLE_WRITABLE
Definition: uv-common.h:93
@ UV_HANDLE_BOUND
Definition: uv-common.h:91
@ UV_HANDLE_READABLE
Definition: uv-common.h:92
#define uv__load_relaxed(p)
Definition: uv-common.h:67
#define uv__store_relaxed(p, v)
Definition: uv-common.h:68
#define uv__req_init(loop, req, typ)
Definition: uv-common.h:329
void(* uv_connection_cb)(uv_stream_t *server, int status)
Definition: uv.h:318
@ UV_TCP_IPV6ONLY
Definition: uv.h:564
UV_EXTERN void uv_close(uv_handle_t *handle, uv_close_cb close_cb)
Definition: core.c:108
void(* uv_connect_cb)(uv_connect_t *req, int status)
Definition: uv.h:316
void(* uv_close_cb)(uv_handle_t *handle)
Definition: uv.h:319
#define IPV6_V6ONLY
Definition: winsock.h:46
#define TCP_KEEPALIVE
Definition: winsock.h:42
static const z80_opcode fd[]
Definition: z80_tab.h:997
static const char * cb[]
Definition: z80_tab.h:176
static int addr
Definition: z80asm.c:58