Skip to content

Commit

Permalink
unix,win: error on zero delay tcp keepalive
Browse files Browse the repository at this point in the history
Closes: libuv#4350
Closes: libuv#3487
  • Loading branch information
saghul authored Mar 22, 2024
1 parent f55628e commit 6adeeac
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 8 deletions.
4 changes: 4 additions & 0 deletions docs/src/tcp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ API
at the end of this procedure, then the handle is destroyed with a
``UV_ETIMEDOUT`` error passed to the corresponding callback.
If `delay` is less than 1 then ``UV_EINVAL`` is returned.
.. versionchanged:: 1.49.0 If `delay` is less than 1 then ``UV_EINVAL``` is returned.
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
Enable / disable simultaneous asynchronous accept requests that are
Expand Down
4 changes: 2 additions & 2 deletions src/unix/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,8 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
if (!on)
return 0;

if (delay == 0)
return -1;
if (delay < 1)
return UV_EINVAL;

#ifdef __sun
/* The implementation of TCP keep-alive on Solaris/SmartOS is a bit unusual
Expand Down
16 changes: 11 additions & 5 deletions src/win/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,17 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign
return WSAGetLastError();
}

if (enable && setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPALIVE,
(const char*)&delay,
sizeof delay) == -1) {
if (!enable)
return 0;

if (delay < 1)
return UV_EINVAL;

if (setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPALIVE,
(const char*)&delay,
sizeof delay) == -1) {
return WSAGetLastError();
}

Expand Down
9 changes: 8 additions & 1 deletion test/test-tcp-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ TEST_IMPL(tcp_flags) {

loop = uv_default_loop();

r = uv_tcp_init(loop, &handle);
/* Use _ex to make sure the socket is created. */
r = uv_tcp_init_ex(loop, &handle, AF_INET);
ASSERT_OK(r);

r = uv_tcp_nodelay(&handle, 1);
Expand All @@ -42,6 +43,12 @@ TEST_IMPL(tcp_flags) {
r = uv_tcp_keepalive(&handle, 1, 60);
ASSERT_OK(r);

r = uv_tcp_keepalive(&handle, 0, 0);
ASSERT_OK(r);

r = uv_tcp_keepalive(&handle, 1, 0);
ASSERT_EQ(r, UV_EINVAL);

uv_close((uv_handle_t*)&handle, NULL);

r = uv_run(loop, UV_RUN_DEFAULT);
Expand Down

0 comments on commit 6adeeac

Please sign in to comment.