aboutsummaryrefslogtreecommitdiff
path: root/src/unix
diff options
context:
space:
mode:
Diffstat (limited to 'src/unix')
-rw-r--r--src/unix/internal.h6
-rw-r--r--src/unix/stream.c2
-rw-r--r--src/unix/tcp.c47
3 files changed, 31 insertions, 24 deletions
diff --git a/src/unix/internal.h b/src/unix/internal.h
index a1d7d436..89b73e2b 100644
--- a/src/unix/internal.h
+++ b/src/unix/internal.h
@@ -299,7 +299,11 @@ int uv__slurp(const char* filename, char* buf, size_t len);
/* tcp */
int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
int uv__tcp_nodelay(int fd, int on);
-int uv__tcp_keepalive(int fd, int on, unsigned int delay);
+int uv__tcp_keepalive(int fd,
+ int on,
+ unsigned int idle,
+ unsigned int intvl,
+ unsigned int cnt);
/* tty */
void uv__tty_close(uv_tty_t* handle);
diff --git a/src/unix/stream.c b/src/unix/stream.c
index 18763b47..204f5a25 100644
--- a/src/unix/stream.c
+++ b/src/unix/stream.c
@@ -417,7 +417,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
/* TODO Use delay the user passed in. */
if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) &&
- uv__tcp_keepalive(fd, 1, 60)) {
+ uv__tcp_keepalive(fd, 1, 60, 1, 10)) {
return UV__ERR(errno);
}
}
diff --git a/src/unix/tcp.c b/src/unix/tcp.c
index 98970d75..b8800bdc 100644
--- a/src/unix/tcp.c
+++ b/src/unix/tcp.c
@@ -466,22 +466,18 @@ int uv__tcp_nodelay(int fd, int on) {
#else
#define UV_KEEPALIVE_FACTOR(x)
#endif
-int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
- int idle;
- int intvl;
- int cnt;
-
- (void) &idle;
- (void) &intvl;
- (void) &cnt;
-
+int uv__tcp_keepalive(int fd,
+ int on,
+ unsigned int idle,
+ unsigned int intvl,
+ unsigned int cnt) {
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
return UV__ERR(errno);
if (!on)
return 0;
- if (delay < 1)
+ if (idle < 1 || intvl < 1 || cnt < 1)
return UV_EINVAL;
#ifdef __sun
@@ -507,13 +503,16 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
* The TCP connection will be aborted after certain amount of probes, which is set by TCP_KEEPCNT, without receiving response.
*/
- idle = delay;
- /* Kernel expects at least 10 seconds. */
+ /* Kernel expects at least 10 seconds for TCP_KEEPIDLE and TCP_KEEPINTVL. */
if (idle < 10)
idle = 10;
- /* Kernel expects at most 10 days. */
+ if (intvl < 10)
+ intvl = 10;
+ /* Kernel expects at most 10 days for TCP_KEEPIDLE and TCP_KEEPINTVL. */
if (idle > 10*24*60*60)
idle = 10*24*60*60;
+ if (intvl > 10*24*60*60)
+ intvl = 10*24*60*60;
UV_KEEPALIVE_FACTOR(idle);
@@ -523,12 +522,10 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)))
return UV__ERR(errno);
- intvl = 10; /* required at least 10 seconds */
UV_KEEPALIVE_FACTOR(intvl);
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
return UV__ERR(errno);
- cnt = 1; /* 1 retry, ensure (TCP_KEEPINTVL * TCP_KEEPCNT) is 10 seconds */
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
return UV__ERR(errno);
#else
@@ -540,7 +537,7 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
/* Note that the consequent probes will not be sent at equal intervals on Solaris,
* but will be sent using the exponential backoff algorithm. */
- int time_to_abort = 10; /* 10 seconds */
+ unsigned int time_to_abort = intvl * cnt;
UV_KEEPALIVE_FACTOR(time_to_abort);
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, &time_to_abort, sizeof(time_to_abort)))
return UV__ERR(errno);
@@ -548,7 +545,6 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
#else /* !defined(__sun) */
- idle = delay;
UV_KEEPALIVE_FACTOR(idle);
#ifdef TCP_KEEPIDLE
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)))
@@ -560,14 +556,12 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
#endif
#ifdef TCP_KEEPINTVL
- intvl = 1; /* 1 second; same as default on Win32 */
UV_KEEPALIVE_FACTOR(intvl);
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
return UV__ERR(errno);
#endif
#ifdef TCP_KEEPCNT
- cnt = 10; /* 10 retries; same as hardcoded on Win32 */
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
return UV__ERR(errno);
#endif
@@ -595,11 +589,20 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
}
-int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
+int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int idle) {
+ return uv_tcp_keepalive_ex(handle, on, idle, 1, 10);
+}
+
+
+int uv_tcp_keepalive_ex(uv_tcp_t* handle,
+ int on,
+ unsigned int idle,
+ unsigned int intvl,
+ unsigned int cnt) {
int err;
if (uv__stream_fd(handle) != -1) {
- err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay);
+ err = uv__tcp_keepalive(uv__stream_fd(handle), on, idle, intvl, cnt);
if (err)
return err;
}
@@ -609,7 +612,7 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
else
handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
- /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
+ /* TODO Store idle if uv__stream_fd(handle) == -1 but don't want to enlarge
* uv_tcp_t with an int that's almost never used...
*/