Commit Graph

74 Commits

Author SHA1 Message Date
Ben Noordhuis
6c692ad1cb
unix: don't accept() connections in a loop (#3696)
After analysis of many real-world programs I've come to conclude that
accepting in a loop is nearly always suboptimal.

1. 99.9% of the time the second accept() call fails with EAGAIN, meaning
   there are no additional connections to accept. Not super expensive
   in isolation but it adds up.

2. When there are more connections to accept but the listen socket is
   shared between multiple processes (ex. the Node.js cluster module),
   libuv's greedy behavior necessitated the UV_TCP_SINGLE_ACCEPT hack
   to slow it down in order to give other processes a chance.

Accepting a single connection and relying on level-triggered polling to
get notified on the next incoming connection both simplifies the code
and optimizes for the common case.
2022-07-20 12:42:50 +02:00
Stacey Marshall
f5e4d85cd2
unix,tcp: allow EINVAL errno from setsockopt in uv_tcp_close_reset() (#3662)
Some setsockopt() implememantations may return with errno of EINVAL
when the socket has been shut down already, as documented in the
Open Group Specifications Issue 7, 2018.

When this happens, reset errno and continue to mark the socket closed
and handle any callback.
2022-07-11 12:29:25 -04:00
Samuel Cabrero
2108309302
unix,tcp: fix errno handling in uv__tcp_bind() (#3652)
The errno value is only meaningful if bind() fails and returns -1.

Some bind() implementations may return success but modify errno value
internally, like the socket_wrapper library used by the Samba testsuite.
2022-06-28 23:42:52 -04:00
Jameson Nash
d54c92e3e6
win: fix style nits [NFC] (#3474)
Internal functions usually have a uv__ prefix.
2022-02-15 10:13:24 -05:00
Jameson Nash
4ddc292774
stream: add uv_pipe and uv_socketpair to the API
Equivalents of `pipe` and `socketpair` for cross-platform use.

PR-URL: https://github.com/libuv/libuv/pull/2953
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
2020-11-09 21:50:09 -05:00
Ben Noordhuis
726af5ebc3 unix: report bind error in uv_tcp_connect()
Fix a bug where libuv forgets about EADDRINUSE errors reported earlier:
uv_tcp_bind() + uv_tcp_connect() seemingly succeed but the socket isn't
actually bound to the requested address.

This bug goes back to at least 2011 if indeed it ever worked at all.

PR-URL: https://github.com/libuv/libuv/pull/2218
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Jameson Nash <vtjnash@gmail.com>
2020-10-27 13:00:59 -04:00
Ben Noordhuis
c70dd705bc unix: use relaxed loads/stores for feature checks
Make ThreadSanitizer stop complaining about the static variables that
libuv uses to record the presence (or lack) of system calls and other
kernel features.

Fixes: https://github.com/libuv/libuv/issues/2884
PR-URL: https://github.com/libuv/libuv/pull/2886
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Jameson Nash <vtjnash@gmail.com>
2020-06-16 11:42:51 +02:00
Manuel BACHMANN
21aff3b4c4
unix: make uv_tcp_keepalive predictable
Current UNIX systems define various defaults for
TCP_KEEPINTVL and TCP_KEEPCNT, which makes the time
between TCP_KEEPIDLE delay is reached and timeout
effectively occurs unpredictable (Linux: /proc/sys
/net/ipv4/tcp_keepalive_intvl;tcp_keepalive_probes).

Do the following: set TCP_KEEPINTVL to 1 second (same
as Win32 default) and TCP_KEEPCNT to 10 times (same
as Win32 hardcoded value).

Fixes: https://github.com/libuv/libuv/issues/2664
PR-URL: https://github.com/libuv/libuv/pull/2669
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2020-02-07 22:52:45 +01:00
Santiago Gimeno
958e85fbd8
tcp: add uv_tcp_close_reset method
It resets a TCP connection by sending a RST packet. Due to some platform
inconsistencies, mixing of `uv_shutdown` and `uv_tcp_close_reset` calls
is not allowed.

Fixes: https://github.com/libuv/libuv/issues/1991
PR-URL: https://github.com/libuv/libuv/pull/2425
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
2019-08-19 23:41:15 +02:00
Santiago Gimeno
d16897c493
unix: refactor getsockname/getpeername methods
PR-URL: https://github.com/libuv/libuv/pull/1872
Backport-PR-URL: https://github.com/libuv/libuv/pull/2217
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
2019-03-16 12:05:23 -04:00
ptlomholt
110eb817bd
openbsd,tcp: special handling of EINVAL on connect
Map `EINVAL` to `ECONNREFUSED` and return error on the next tick.

Fixes: https://github.com/libuv/libuv/issues/2155
PR-URL: https://github.com/libuv/libuv/pull/2154
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2019-02-05 08:50:05 +01:00
Ben Noordhuis
619937c783 unix,win: merge handle flags
Some long overdue refactoring that unifies more of the UNIX and Windows
backends.

PR-URL: https://github.com/libuv/libuv/pull/1904
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2018-06-29 22:24:52 +02:00
Ben Noordhuis
2256be01b0 unix: catch some cases of watching fd twice
Libuv does not support multiple handles watching the same file
descriptor.  That condition is caught by an assert but it's detached
from the call site and therefore not always trivial to track down.

This commit turns cases where we can easily detect duplicates into
runtime `UV_EEXIST` errors.  More work is needed to catch _all_ cases.

Partially addresses https://github.com/libuv/libuv/issues/1172.

PR-URL: https://github.com/libuv/libuv/pull/1851
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
2018-05-30 13:24:19 +02:00
Alex Arslan
48b8c11876
tcp,openbsd: disable Unix TCP check for IPV6_ONLY
OpenBSD does not support setting IPV6_ONLY to anything but 1; OpenBSD
does not support IPv4-mapped IPv6 addresses.

Upstreamed from OpenBSD Ports Collection.

PR-URL: https://github.com/libuv/libuv/pull/1797
Reviewed-By: Aaron Bieber <deftly@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
2018-04-17 11:48:48 +02:00
Michael Kilburn
9ed3ed5fcb
unix: fix several instances of lost errno
This commit preserves errno properly in the following cases:

- new_socket() was previously discarding errno in some cases,
  and replacing it with the result of getsockname().
- uv__close() was not preserving errno when __MVS__ is defined.

Fixes: https://github.com/libuv/libuv/issues/1756
PR-URL: https://github.com/libuv/libuv/pull/1763
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
2018-03-03 11:03:41 -05:00
Jameson Nash
8f9ba2a597
Revert "Revert "unix,tcp: avoid marking server sockets connected""
This reverts commit 2098773243.

PR-URL: https://github.com/libuv/libuv/pull/1741
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
2018-02-25 18:45:05 +01:00
Mason X
89cbbc895b
include,src: introduce UV__ERR() macro
Using -errno, -E**, and -pthread_function() can be
error prone, and breaks compatibility with some operating
systems that already negate errno's (e.g. Haiku).

This commit adds a UV__ERR() macro that ensures libuv
errors are negative.

Fixes: https://github.com/libuv/help/issues/39
PR-URL: https://github.com/libuv/libuv/pull/1687
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2018-02-08 22:38:02 -05:00
Ben Noordhuis
2098773243 Revert "unix,tcp: avoid marking server sockets connected"
Reverted for breaking Node.js in rather spectacular fashion.

The bug is arguably on the Node.js side.  It looks like Node.js starts
reading before the socket is actually connected to something.
Until that is fixed downstream, let's revert the change.

This reverts commit fd049399aa.

Fixes: https://github.com/libuv/libuv/issues/1716
Fixes: https://github.com/nodejs/node/issues/18225
PR-URL: https://github.com/libuv/libuv/pull/1717
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2018-01-19 17:51:04 +01:00
Jameson Nash
fd049399aa
unix,tcp: avoid marking server sockets connected
It shouldn't be setting READABLE and WRITABLE on the socket server,
since they aren't, and this could confuse the client.

PR-URL: https://github.com/libuv/libuv/pull/1655
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
2017-12-20 22:17:52 +01:00
John Barboza
c5dd2d4218
unix: keep track of bound sockets sent via spawn
We use the UV_HANDLE_BOUND flag to mark a socket as bound to a
port. We need to do this for sockets that are sent from another
process as well as sockets that created by the process itself.
First check if the port number is non-zero. If yes then mark
it as bound.

PR-URL: https://github.com/libuv/libuv/pull/1348
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
2017-11-20 18:36:26 +01:00
John Barboza
f4ef897666 zos: track unbound handles and bind before listen
On zOS the listen call does not bind automatically if the socket
is unbound. Hence the manual binding to an arbitrary port is
required to be done manually.

PR-URL: https://github.com/libuv/libuv/pull/949
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2016-08-24 10:02:41 +01:00
John Barboza
1cff5b7557 zos: add support for new platform
- zos: disable test cases not applicable
- zos: build options
- zos: semaphore implementation
- zos: use compare and swap builtins
- zos: struct rusage not the same as other platforms
- zos: backlog<=0 produces undefined behaviour
    Will redefine backlog in the following way
    * if backlog == 0, set it to 1
    * if backlog < 0, set it to SOMAXCONN
- zos: define IMAXBEL as empty flag and implement uv__tty_make_raw
- zos: use udp multicast operations from aix
- zos: ESC in ebcdic
- zos: use LIBPATH for dynamic linker path
- zos: uv_udp_set_ttl only works for ipv6
- zos: increase pthread stack size by factor of 4
- zos: return ENODEV instead of ENXIO errors for setsockopt
- zos: use uv_cond_init the same way as aix
- test: enable oob test for zos
- zos: return EINVAL for zos error code EOPNOTSUPP

PR-URL: https://github.com/libuv/libuv/pull/937
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2016-08-19 01:34:29 +02:00
liuxiaobo
3a4f2d3155 unix: fix errno and retval conflict
We not only check the return value, but also check the errno != 0.
Because in rare cases connect() will return -1 but the errno
is 0 (for example, on Android 4.3, OnePlus phone A0001_12_150227)
and actually the tcp three-way handshake is completed.

PR-URL: https://github.com/libuv/libuv/pull/936
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Imran Iqbal <imran@imraniqbal.org>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2016-07-18 10:28:48 +01:00
Ben Noordhuis
375ba2d76d unix: use POLL{IN,OUT,etc} constants directly
Remove the UV__POLL defines and use POLL{IN,OUT,etc} directly.
On Linux, we lean on the fact that the POLL constants correspond
one-to-one to their EPOLL counterparts.

Fixes: https://github.com/libuv/libuv/issues/816
PR-URL: https://github.com/libuv/libuv/pull/817
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2016-04-11 10:51:13 +02:00
Saúl Ibarra Corretgé
d377435b5e unix: consolidate tcp and udp bind error
OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a socket created
with AF_INET to an AF_INET6 address or vice versa.

PR-URL: https://github.com/libuv/libuv/pull/407
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-06-28 11:53:52 +02:00
Saúl Ibarra Corretgé
f8f59824c4 unix, win: add ability to create tcp/udp sockets early
Introduce two new APIs:

int uv_tcp_init_ex(uv_loop_t*, uv_tcp_t* handle, int flags)
int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, int flags)

The lower 8 bits of the flags field are used for the socket domain.
AF_INET, AF_INET6 and AF_UNSPEC are supported. If AF_UNSPEC is specified
the socket is created lazily, just like uv_{tcp,udp}_init.

Some Windows notes:

getsockname fails with WSAEINVAL if the socket is not bound. This could
potentially be improved by detecting the socket family and filling
the sockaddr_in/6 struct manually.

bind returns WSAEFAULT if we try to bind a socket to the wrong family.
Unix returns EINVAL.

PR-URL: https://github.com/libuv/libuv/pull/400
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-06-19 09:37:19 +02:00
Ben Noordhuis
393c1c59a2 unix: set non-block mode in uv_{pipe,tcp,udp}_open
The contract specifies that the file descriptor should already be in
non-blocking mode before passing it to libuv.

However, node users don't really have an opportunity to do so, never
mind the fact that the call to uv_pipe_open() or uv_tcp_open() is an
implementation detail that most users won't be aware of.

Let's be nice and set the non-blocking flag explicitly.  It's a cheap
operation anyway.

Fixes: https://github.com/libuv/libuv/issues/124

PR: https://github.com/libuv/libuv/pull/134
Reviewed-by: Saúl Ibarra Corretgé <saghul@gmail.com>
2015-01-14 19:46:54 +01:00
Ben Noordhuis
ebc50aee1d Revert "unix: only set SO_REUSEADDR when bind() fails"
This reverts commit a9e95a33bc.

This seems to cause regressions in the test suite when IPv6 is disabled.

As optimizations go, it's a very minor one so let's not spend too much
effort trying to track down the cause of the regressions but revert the
change before it makes its way into a release.

PR-URL: https://github.com/libuv/libuv/pull/92
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2014-12-29 17:15:20 +01:00
Ben Noordhuis
a9e95a33bc unix: only set SO_REUSEADDR when bind() fails
Only call setsockopt() when the initial bind() fails with EADDRINUSE,
then retry.  Saves a system call in what is normally the common case.

PR-URL: https://github.com/libuv/libuv/pull/88
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
2014-12-27 18:41:15 +01:00
Saúl Ibarra Corretgé
9b4f2b84f1 unix, windows: validate flags on uv_udp|tcp_bind
fixes #1247
2014-04-22 22:57:01 +02:00
Chernyshev Viacheslav
886e2bcd55 unix, windows: pass const handle ptr to uv_tcp_get*name
uv_tcp_getsockname and uv_tcp_getpeername do not modify passed handle
pointer, so there is no need to keep this parameter non-const.
2014-04-18 12:07:38 +02:00
Saúl Ibarra Corretgé
7a4c42a054 unix: add UV_HANDLE_IPV6 flag to tcp and udp handles 2014-04-02 01:24:39 +02:00
Saúl Ibarra Corretgé
3901ec4976 unix: fix uv_tcp_nodelay return value in case of error
Fixes #1102
2014-02-10 09:00:46 +01:00
Fedor Indutny
8f15aae52f tcp: uv_tcp_dualstack()
Explicitly disable/enable dualstack depending on presence of flag set by
uv_tcp_dualstack() function.
2014-01-19 23:07:42 +00:00
Ben Noordhuis
359d667893 unix: sanity-check fds before closing
Ensure that close() system calls don't close stdio file descriptors
because that is almost never the intention.

This is also a partial workaround for a kernel bug that seems to affect
all Linux kernels when stdin is a pipe that gets closed: fd 0 keeps
signalling EPOLLHUP but a subsequent call to epoll_ctl(EPOLL_CTL_DEL)
fails with EBADF.  See joyent/node#6271 for details and a test case.
2013-10-01 03:55:54 +02:00
Ben Noordhuis
255671da74 include: uv_tcp_connect{6} now takes sockaddr_in*
Passing or returning structs as values makes life hard for people that
work with libuv through a foreign function interface. Switch to a
pointer-based approach.

Fixes #684.
2013-09-01 08:02:15 +02:00
Ben Noordhuis
daa229ace3 include: uv_tcp_bind{6} now takes sockaddr_in*
Passing or returning structs as values makes life hard for people that
work with libuv through a foreign function interface. Switch to a
pointer-based approach.

Fixes #684.
2013-09-01 08:02:13 +02:00
Ben Noordhuis
3ee4d3f183 unix, windows: return error codes directly
This commit changes the libuv API to return error codes directly rather
than storing them in a loop-global field.

A code snippet like this one:

    if (uv_foo(loop) < 0) {
      uv_err_t err = uv_last_error(loop);
      fprintf(stderr, "%s\n", uv_strerror(err));
    }

Should be rewritten like this:

    int err = uv_foo(loop);
    if (err < 0)
      fprintf(stderr, "%s\n", uv_strerror(err));

The rationale for this change is that it should make creating bindings
for other languages a lot easier: dealing with struct return values is
painful with most FFIs and often downright buggy.
2013-07-07 09:51:00 +02:00
Ben Noordhuis
5879c61394 unix: remove errno preserving code
Remove the errno preserving code. Libuv only implemented it in a
haphazard way and there seems to be a general consensus that no one
really cares anyway. Therefore, remove it.
2013-05-12 11:03:19 +02:00
Ben Noordhuis
0635e29714 unix, windows: remove ngx-queue.h
Avoids an extra #include in public headers and stops the ngx_queue_*
types and macros from leaking into user code.
2013-03-27 00:09:36 +01:00
Ben Noordhuis
905d56c140 unix: fix uv_tcp_simultaneous_accepts() logic
Inverts the meaning of the 'enable' argument. Before, it actually set
the UV_TCP_SINGLE_ACCEPT flag when enable=1. Now it clears it, which is
what uv-win does and what you would expect it to do.
2013-03-12 12:39:37 +01:00
Ben Noordhuis
dc559a5ce6 unix: disable relaxed accept() by default
Don't use the relaxed accept() algorithm introduced in be2a217 unless
explicitly requested. It causes a 50+% performance drop on some node.js
benchmarks:

  $ alias bench='out/Release/node benchmark/http_simple_auto.js \
    -c 10 -n 50000 bytes/1 2>&1 | grep Req'

  $ UV_TCP_SINGLE_ACCEPT=0 bench
  Requests per second:    12331.84 [#/sec] (mean)

  $ UV_TCP_SINGLE_ACCEPT=1 bench
  Requests per second:    3944.63 [#/sec] (mean)
2012-12-18 15:44:21 +01:00
Fedor Indutny
731adacad2 unix: use select() for specific fds on OS X
kqueue(2) on osx doesn't work (emits EINVAL error) with specific fds
(i.e. /dev/tty, /dev/null, etc). When given such descriptors - start
select(2) watcher thread that will emit io events.
2012-12-09 15:43:08 +01:00
Ben Noordhuis
a385ae4f59 unix: only set SO_REUSEADDR on tcp listen sockets
Avoid the extra syscall, it's a no-op for non-listening sockets.

At least, it should be - it remains to be investigated if a FreeBSD kernel bug
affects ephemeral port allocation inside connect(). See [1] for details.

[1] http://www.freebsd.org/cgi/query-pr.cgi?pr=174087
2012-12-09 14:34:33 +01:00
Ben Noordhuis
65bb6f068e unix: rename UV__IO_* constants 2012-11-16 17:33:29 +01:00
Ben Noordhuis
1282d64868 unix: remove dependency on libev 2012-11-16 17:33:25 +01:00
Ben Noordhuis
be2a2176ce unix: rethink relaxed accept() approach
Benchmarks demonstrated that the idle timer handle approach didn't balance the
load quite fair enough, the majority of new connections still ended up in one
or two processes.

The new approach voluntarily gives up a scheduler timeslice by calling
nanosleep() with a one nanosecond timeout.

Why not sched_yield()? Because on Linux (and this is probably true for other
Unices as well), sched_yield() only yields if there are other processes running
on the same CPU.

nanosleep() on the other hand always forces the process to sleep, which gives
other processes a chance to accept our pending connections.
2012-09-18 00:16:43 +02:00
Saúl Ibarra Corretgé
cc1c1912ca unix, windows: add uv_tcp_open and uv_udp_open 2012-09-17 18:09:51 +02:00
Bert Belder
27b11abcc0 unix: mark accept idle handle as internal 2012-09-08 17:52:57 +02:00
Ben Noordhuis
3bbe8f9754 Merge branch 'v0.8' 2012-09-04 01:23:18 +02:00