From 783d19a534bf7f245d5099717666c8f7a7953caa Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 19 Jan 2018 01:24:43 +0100 Subject: [PATCH 1/3] 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 fd049399aa4ed8495928e375466970d98cb42e17. Fixes: https://github.com/libuv/libuv/issues/1716 Fixes: https://github.com/nodejs/node/issues/18225 --- src/unix/stream.c | 6 ------ src/unix/tcp.c | 8 +++++--- test/test-list.h | 2 -- test/test-tcp-bind-error.c | 42 ------------------------------------------ 4 files changed, 5 insertions(+), 53 deletions(-) diff --git a/src/unix/stream.c b/src/unix/stream.c index bccfd20f..6fc0a01f 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -1411,9 +1411,6 @@ int uv_write2(uv_write_t* req, if (uv__stream_fd(stream) < 0) return -EBADF; - if (!(stream->flags & UV_STREAM_WRITABLE)) - return -EPIPE; - if (send_handle) { if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) return -EINVAL; @@ -1565,9 +1562,6 @@ int uv_read_start(uv_stream_t* stream, if (stream->flags & UV_CLOSING) return -EINVAL; - if (!(stream->flags & UV_STREAM_READABLE)) - return -ENOTCONN; - /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just * expresses the desired state of the user. */ diff --git a/src/unix/tcp.c b/src/unix/tcp.c index a4037851..c7c8d21c 100644 --- a/src/unix/tcp.c +++ b/src/unix/tcp.c @@ -158,7 +158,9 @@ int uv__tcp_bind(uv_tcp_t* tcp, if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) return -EINVAL; - err = maybe_new_socket(tcp, addr->sa_family, 0); + err = maybe_new_socket(tcp, + addr->sa_family, + UV_STREAM_READABLE | UV_STREAM_WRITABLE); if (err) return err; @@ -333,14 +335,14 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { if (single_accept) tcp->flags |= UV_TCP_SINGLE_ACCEPT; - flags = 0; + flags = UV_STREAM_READABLE; #if defined(__MVS__) /* 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 */ flags |= UV_HANDLE_BOUND; -#endif +#endif err = maybe_new_socket(tcp, AF_INET, flags); if (err) return err; diff --git a/test/test-list.h b/test/test-list.h index d23cf866..8e4f2025 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -94,7 +94,6 @@ TEST_DECLARE (tcp_bind_error_fault) TEST_DECLARE (tcp_bind_error_inval) TEST_DECLARE (tcp_bind_localhost_ok) TEST_DECLARE (tcp_bind_invalid_flags) -TEST_DECLARE (tcp_bind_writable_flags) TEST_DECLARE (tcp_listen_without_bind) TEST_DECLARE (tcp_connect_error_fault) TEST_DECLARE (tcp_connect_timeout) @@ -535,7 +534,6 @@ TASK_LIST_START TEST_ENTRY (tcp_bind_error_inval) TEST_ENTRY (tcp_bind_localhost_ok) TEST_ENTRY (tcp_bind_invalid_flags) - TEST_ENTRY (tcp_bind_writable_flags) TEST_ENTRY (tcp_listen_without_bind) TEST_ENTRY (tcp_connect_error_fault) TEST_ENTRY (tcp_connect_timeout) diff --git a/test/test-tcp-bind-error.c b/test/test-tcp-bind-error.c index 1456d081..10ed68e1 100644 --- a/test/test-tcp-bind-error.c +++ b/test/test-tcp-bind-error.c @@ -214,45 +214,3 @@ TEST_IMPL(tcp_listen_without_bind) { MAKE_VALGRIND_HAPPY(); return 0; } - - -TEST_IMPL(tcp_bind_writable_flags) { - struct sockaddr_in addr; - uv_tcp_t server; - uv_buf_t buf; - uv_write_t write_req; - uv_shutdown_t shutdown_req; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); - r = uv_tcp_init(uv_default_loop(), &server); - ASSERT(r == 0); - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - ASSERT(r == 0); - r = uv_listen((uv_stream_t*)&server, 128, NULL); - ASSERT(r == 0); - - ASSERT(0 == uv_is_writable((uv_stream_t*) &server)); - ASSERT(0 == uv_is_readable((uv_stream_t*) &server)); - - buf = uv_buf_init("PING", 4); - r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL); - ASSERT(r == UV_EPIPE); - r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL); -#ifdef _WIN32 - ASSERT(r == UV_EPIPE); -#else - ASSERT(r == UV_ENOTCONN); -#endif - r = uv_read_start((uv_stream_t*) &server, NULL, NULL); - ASSERT(r == UV_ENOTCONN); - - uv_close((uv_handle_t*)&server, close_cb); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - - ASSERT(close_cb_called == 1); - - MAKE_VALGRIND_HAPPY(); - return 0; -} -- 2.15.1