Navigation Menu

Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Add interval and count to keep-alive #269

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/uv.h
Expand Up @@ -483,9 +483,11 @@ UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
/* Enable/disable TCP keep-alive. /* Enable/disable TCP keep-alive.
* *
* `ms` is the initial delay in seconds, ignored when `enable` is zero. * `ms` is the initial delay in seconds, ignored when `enable` is zero.
* interval is the keep-alive probe interval after the initial delay. Doesn't work in Windows
* count is the number of keep-alives that fail before thinking the socket is dead. Doesn't work in Windows
*/ */
UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, int enable, UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, int enable,
unsigned int delay); unsigned int delay, unsigned int interval, unsigned int count);


/* /*
* This setting applies to Windows only. * This setting applies to Windows only.
Expand Down
2 changes: 1 addition & 1 deletion src/unix/internal.h
Expand Up @@ -132,7 +132,7 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
/* tcp */ /* tcp */
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb); int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
int uv__tcp_nodelay(uv_tcp_t* handle, int enable); int uv__tcp_nodelay(uv_tcp_t* handle, int enable);
int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay); int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay, unsigned int interval, unsigned int count);


/* pipe */ /* pipe */
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
Expand Down
2 changes: 1 addition & 1 deletion src/unix/stream.c
Expand Up @@ -102,7 +102,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {


/* TODO Use delay the user passed in. */ /* TODO Use delay the user passed in. */
if ((stream->flags & UV_TCP_KEEPALIVE) && if ((stream->flags & UV_TCP_KEEPALIVE) &&
uv__tcp_keepalive((uv_tcp_t*)stream, 1, 60)) { uv__tcp_keepalive((uv_tcp_t*)stream, 1, 60, 60, 8)) {
return -1; return -1;
} }
} }
Expand Down
29 changes: 26 additions & 3 deletions src/unix/tcp.c
Expand Up @@ -255,7 +255,8 @@ int uv__tcp_nodelay(uv_tcp_t* handle, int enable) {
} }




int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay,
unsigned int interval, unsigned int count) {
if (setsockopt(handle->fd, if (setsockopt(handle->fd,
SOL_SOCKET, SOL_SOCKET,
SO_KEEPALIVE, SO_KEEPALIVE,
Expand Down Expand Up @@ -287,6 +288,28 @@ int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
} }
#endif #endif


#ifdef TCP_KEEPINTVL
if (enable && interval && setsockopt(handle->fd,
IPPROTO_TCP,
TCP_KEEPINTVL,
&interval,
sizeof interval) == -1) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
#endif

#ifdef TCP_KEEPCNT
if (enable && count && setsockopt(handle->fd,
IPPROTO_TCP,
TCP_KEEPCNT,
&count,
sizeof count) == -1) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
#endif

return 0; return 0;
} }


Expand All @@ -304,8 +327,8 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
} }




int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay, unsigned int interval, unsigned int count) {
if (handle->fd != -1 && uv__tcp_keepalive(handle, enable, delay)) if (handle->fd != -1 && uv__tcp_keepalive(handle, enable, delay, interval, count))
return -1; return -1;


if (enable) if (enable)
Expand Down
14 changes: 10 additions & 4 deletions src/win/tcp.c
Expand Up @@ -59,7 +59,8 @@ static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
} }




static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) { static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay,
unsigned int interval, unsigned int count) {
if (setsockopt(socket, if (setsockopt(socket,
SOL_SOCKET, SOL_SOCKET,
SO_KEEPALIVE, SO_KEEPALIVE,
Expand All @@ -78,6 +79,11 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign
return -1; return -1;
} }


/*
* interval and count cannot be applied without registry
* changes and system reboot
*/

return 0; return 0;
} }


Expand Down Expand Up @@ -132,7 +138,7 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,


/* TODO: Use stored delay. */ /* TODO: Use stored delay. */
if ((handle->flags & UV_HANDLE_TCP_KEEPALIVE) && if ((handle->flags & UV_HANDLE_TCP_KEEPALIVE) &&
uv__tcp_keepalive(handle, socket, 1, 60)) { uv__tcp_keepalive(handle, socket, 1, 60, 60, 8)) {
return -1; return -1;
} }


Expand Down Expand Up @@ -1058,9 +1064,9 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
} }




int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay, unsigned int interval, unsigned int count) {
if (handle->socket != INVALID_SOCKET && if (handle->socket != INVALID_SOCKET &&
uv__tcp_keepalive(handle, handle->socket, enable, delay)) { uv__tcp_keepalive(handle, handle->socket, enable, delay, interval, count)) {
return -1; return -1;
} }


Expand Down
2 changes: 1 addition & 1 deletion test/test-tcp-flags.c
Expand Up @@ -39,7 +39,7 @@ TEST_IMPL(tcp_flags) {
r = uv_tcp_nodelay(&handle, 1); r = uv_tcp_nodelay(&handle, 1);
ASSERT(r == 0); ASSERT(r == 0);


r = uv_tcp_keepalive(&handle, 1, 60); r = uv_tcp_keepalive(&handle, 1, 60, 60, 8);
ASSERT(r == 0); ASSERT(r == 0);


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