unix: make uv_tcp_keepalive predictable

Current UNIX systems define various defaults for
TCP_KEEPINTVL and TCP_KEEPCNT, which makes the time
between TCP_KEEPIDLE delay is reached and timeout
effectively occurs unpredictable (Linux: /proc/sys
/net/ipv4/tcp_keepalive_intvl;tcp_keepalive_probes).

Do the following: set TCP_KEEPINTVL to 1 second (same
as Win32 default) and TCP_KEEPCNT to 10 times (same
as Win32 hardcoded value).

Fixes: https://github.com/libuv/libuv/issues/2664
PR-URL: https://github.com/libuv/libuv/pull/2669
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
Manuel BACHMANN 2020-02-04 10:59:38 +01:00 committed by Santiago Gimeno
parent fb5a35ee91
commit 21aff3b4c4
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE
2 changed files with 15 additions and 2 deletions

View File

@ -60,6 +60,11 @@ API
Enable / disable TCP keep-alive. `delay` is the initial delay in seconds,
ignored when `enable` is zero.
After `delay` has been reached, 10 successive probes, each spaced 1 second
from the previous one, will still happen. If the connection is still lost
at the end of this procedure, then the handle is destroyed with a
``UV_ETIMEDOUT`` error passed to the corresponding callback.
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
Enable / disable simultaneous asynchronous accept requests that are

View File

@ -379,8 +379,16 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
return UV__ERR(errno);
#ifdef TCP_KEEPIDLE
if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
return UV__ERR(errno);
if (on) {
int intvl = 1; /* 1 second; same as default on Win32 */
int cnt = 10; /* 10 retries; same as hardcoded on Win32 */
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
return UV__ERR(errno);
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
return UV__ERR(errno);
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
return UV__ERR(errno);
}
#endif
/* Solaris/SmartOS, if you don't support keep-alive,