From a385ae4f59aeb10b24e60c3d6880a38a645635bd Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 9 Dec 2012 13:21:20 +0100 Subject: [PATCH] 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 --- src/unix/stream.c | 8 -------- src/unix/tcp.c | 28 ++++++++++------------------ 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/unix/stream.c b/src/unix/stream.c index 6af6020a..4e65173a 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -101,18 +101,10 @@ void uv__stream_init(uv_loop_t* loop, int uv__stream_open(uv_stream_t* stream, int fd, int flags) { - socklen_t yes; - assert(fd >= 0); stream->flags |= flags; if (stream->type == UV_TCP) { - /* Reuse the port address if applicable. */ - yes = 1; - - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) - return uv__set_sys_error(stream->loop, errno); - if ((stream->flags & UV_TCP_NODELAY) && uv__tcp_nodelay(fd, 1)) return uv__set_sys_error(stream->loop, errno); diff --git a/src/unix/tcp.c b/src/unix/tcp.c index 7c86e708..2c7b155d 100644 --- a/src/unix/tcp.c +++ b/src/unix/tcp.c @@ -58,29 +58,21 @@ static int uv__bind(uv_tcp_t* tcp, int domain, struct sockaddr* addr, int addrsize) { - int saved_errno; - int status; - - saved_errno = errno; - status = -1; + int on; if (maybe_new_socket(tcp, domain, UV_STREAM_READABLE|UV_STREAM_WRITABLE)) return -1; - tcp->delayed_error = 0; - if (bind(tcp->io_watcher.fd, addr, addrsize) == -1) { - if (errno == EADDRINUSE) { - tcp->delayed_error = errno; - } else { - uv__set_sys_error(tcp->loop, errno); - goto out; - } - } - status = 0; + on = 1; + if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) + return uv__set_sys_error(tcp->loop, errno); -out: - errno = saved_errno; - return status; + errno = 0; + if (bind(tcp->io_watcher.fd, addr, addrsize) && errno != EADDRINUSE) + return uv__set_sys_error(tcp->loop, errno); + + tcp->delayed_error = errno; + return 0; }