tcp,pipe: fail bind or listen after close (#3641)
Return `UV_EINVAL` in `bind` and `listen` when `handle` is `UV_HANDLE_CLOSING` or `UV_HANDLE_CLOSED`. Fixes: https://github.com/libuv/libuv/issues/3503
This commit is contained in:
parent
d938c104e1
commit
8bcd689c04
@ -51,7 +51,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
|||||||
/* Already bound? */
|
/* Already bound? */
|
||||||
if (uv__stream_fd(handle) >= 0)
|
if (uv__stream_fd(handle) >= 0)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
if (uv__is_closing(handle)) {
|
||||||
|
return UV_EINVAL;
|
||||||
|
}
|
||||||
/* Make a copy of the file name, it outlives this function's scope. */
|
/* Make a copy of the file name, it outlives this function's scope. */
|
||||||
pipe_fname = uv__strdup(name);
|
pipe_fname = uv__strdup(name);
|
||||||
if (pipe_fname == NULL)
|
if (pipe_fname == NULL)
|
||||||
|
|||||||
@ -641,7 +641,9 @@ done:
|
|||||||
|
|
||||||
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
||||||
int err;
|
int err;
|
||||||
|
if (uv__is_closing(stream)) {
|
||||||
|
return UV_EINVAL;
|
||||||
|
}
|
||||||
switch (stream->type) {
|
switch (stream->type) {
|
||||||
case UV_TCP:
|
case UV_TCP:
|
||||||
err = uv__tcp_listen((uv_tcp_t*)stream, backlog, cb);
|
err = uv__tcp_listen((uv_tcp_t*)stream, backlog, cb);
|
||||||
|
|||||||
@ -295,7 +295,9 @@ int uv_tcp_bind(uv_tcp_t* handle,
|
|||||||
|
|
||||||
if (handle->type != UV_TCP)
|
if (handle->type != UV_TCP)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
if (uv__is_closing(handle)) {
|
||||||
|
return UV_EINVAL;
|
||||||
|
}
|
||||||
if (addr->sa_family == AF_INET)
|
if (addr->sa_family == AF_INET)
|
||||||
addrlen = sizeof(struct sockaddr_in);
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
else if (addr->sa_family == AF_INET6)
|
else if (addr->sa_family == AF_INET6)
|
||||||
|
|||||||
@ -731,7 +731,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
|||||||
if (!name) {
|
if (!name) {
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
if (uv__is_closing(handle)) {
|
||||||
|
return UV_EINVAL;
|
||||||
|
}
|
||||||
if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
|
if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
|
||||||
handle->pipe.serv.pending_instances = default_pending_pipe_instances;
|
handle->pipe.serv.pending_instances = default_pending_pipe_instances;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,9 @@
|
|||||||
|
|
||||||
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
||||||
int err;
|
int err;
|
||||||
|
if (uv__is_closing(stream)) {
|
||||||
|
return UV_EINVAL;
|
||||||
|
}
|
||||||
err = ERROR_INVALID_PARAMETER;
|
err = ERROR_INVALID_PARAMETER;
|
||||||
switch (stream->type) {
|
switch (stream->type) {
|
||||||
case UV_TCP:
|
case UV_TCP:
|
||||||
|
|||||||
@ -122,6 +122,7 @@ TEST_DECLARE (tcp_bind_error_inval)
|
|||||||
TEST_DECLARE (tcp_bind_localhost_ok)
|
TEST_DECLARE (tcp_bind_localhost_ok)
|
||||||
TEST_DECLARE (tcp_bind_invalid_flags)
|
TEST_DECLARE (tcp_bind_invalid_flags)
|
||||||
TEST_DECLARE (tcp_bind_writable_flags)
|
TEST_DECLARE (tcp_bind_writable_flags)
|
||||||
|
TEST_DECLARE (tcp_bind_or_listen_error_after_close)
|
||||||
TEST_DECLARE (tcp_listen_without_bind)
|
TEST_DECLARE (tcp_listen_without_bind)
|
||||||
TEST_DECLARE (tcp_connect_error_fault)
|
TEST_DECLARE (tcp_connect_error_fault)
|
||||||
TEST_DECLARE (tcp_connect_timeout)
|
TEST_DECLARE (tcp_connect_timeout)
|
||||||
@ -192,6 +193,7 @@ TEST_DECLARE (pipe_bind_error_addrnotavail)
|
|||||||
TEST_DECLARE (pipe_bind_error_inval)
|
TEST_DECLARE (pipe_bind_error_inval)
|
||||||
TEST_DECLARE (pipe_connect_multiple)
|
TEST_DECLARE (pipe_connect_multiple)
|
||||||
TEST_DECLARE (pipe_listen_without_bind)
|
TEST_DECLARE (pipe_listen_without_bind)
|
||||||
|
TEST_DECLARE (pipe_bind_or_listen_error_after_close)
|
||||||
TEST_DECLARE (pipe_connect_bad_name)
|
TEST_DECLARE (pipe_connect_bad_name)
|
||||||
TEST_DECLARE (pipe_connect_to_file)
|
TEST_DECLARE (pipe_connect_to_file)
|
||||||
TEST_DECLARE (pipe_connect_on_prepare)
|
TEST_DECLARE (pipe_connect_on_prepare)
|
||||||
@ -697,6 +699,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (tcp_bind_localhost_ok)
|
TEST_ENTRY (tcp_bind_localhost_ok)
|
||||||
TEST_ENTRY (tcp_bind_invalid_flags)
|
TEST_ENTRY (tcp_bind_invalid_flags)
|
||||||
TEST_ENTRY (tcp_bind_writable_flags)
|
TEST_ENTRY (tcp_bind_writable_flags)
|
||||||
|
TEST_ENTRY (tcp_bind_or_listen_error_after_close)
|
||||||
TEST_ENTRY (tcp_listen_without_bind)
|
TEST_ENTRY (tcp_listen_without_bind)
|
||||||
TEST_ENTRY (tcp_connect_error_fault)
|
TEST_ENTRY (tcp_connect_error_fault)
|
||||||
TEST_ENTRY (tcp_connect_timeout)
|
TEST_ENTRY (tcp_connect_timeout)
|
||||||
@ -775,6 +778,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (pipe_bind_error_inval)
|
TEST_ENTRY (pipe_bind_error_inval)
|
||||||
TEST_ENTRY (pipe_connect_multiple)
|
TEST_ENTRY (pipe_connect_multiple)
|
||||||
TEST_ENTRY (pipe_listen_without_bind)
|
TEST_ENTRY (pipe_listen_without_bind)
|
||||||
|
TEST_ENTRY (pipe_bind_or_listen_error_after_close)
|
||||||
TEST_ENTRY (pipe_getsockname)
|
TEST_ENTRY (pipe_getsockname)
|
||||||
TEST_ENTRY (pipe_getsockname_abstract)
|
TEST_ENTRY (pipe_getsockname_abstract)
|
||||||
TEST_ENTRY (pipe_getsockname_blocking)
|
TEST_ENTRY (pipe_getsockname_blocking)
|
||||||
|
|||||||
@ -137,3 +137,19 @@ TEST_IMPL(pipe_listen_without_bind) {
|
|||||||
MAKE_VALGRIND_HAPPY();
|
MAKE_VALGRIND_HAPPY();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_IMPL(pipe_bind_or_listen_error_after_close) {
|
||||||
|
uv_pipe_t server;
|
||||||
|
|
||||||
|
ASSERT_EQ(uv_pipe_init(uv_default_loop(), &server, 0), 0);
|
||||||
|
uv_close((uv_handle_t*) &server, NULL);
|
||||||
|
|
||||||
|
ASSERT_EQ(uv_pipe_bind(&server, TEST_PIPENAME), UV_EINVAL);
|
||||||
|
|
||||||
|
ASSERT_EQ(uv_listen((uv_stream_t*) &server, SOMAXCONN, NULL), UV_EINVAL);
|
||||||
|
|
||||||
|
ASSERT_EQ(uv_run(uv_default_loop(), UV_RUN_DEFAULT), 0);
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -297,3 +297,21 @@ TEST_IMPL(tcp_bind_writable_flags) {
|
|||||||
MAKE_VALGRIND_HAPPY();
|
MAKE_VALGRIND_HAPPY();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_IMPL(tcp_bind_or_listen_error_after_close) {
|
||||||
|
uv_tcp_t tcp;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
addr.sin_port = htons(9999);
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
|
||||||
|
ASSERT_EQ(uv_tcp_init(uv_default_loop(), &tcp), 0);
|
||||||
|
uv_close((uv_handle_t*) &tcp, NULL);
|
||||||
|
ASSERT_EQ(uv_tcp_bind(&tcp, (struct sockaddr*) &addr, 0), UV_EINVAL);
|
||||||
|
ASSERT_EQ(uv_listen((uv_stream_t*) &tcp, 5, NULL), UV_EINVAL);
|
||||||
|
ASSERT_EQ(uv_run(uv_default_loop(), UV_RUN_DEFAULT), 0);
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user