From 1d5b315f1773660689b5b55cc7081d7e999aa5ef Mon Sep 17 00:00:00 2001 From: "James F. Carter" Date: Wed, 10 Jan 2018 13:49:22 +0000 Subject: [PATCH 1/4] apply tcp keepalive to serving sockets --- src/common/sockutil.c | 28 ++++++++++++++++++++++++++++ src/common/sockutil.h | 15 +++++++++++++++ src/server/serve.c | 3 +++ src/server/serve.h | 3 +++ 4 files changed, 49 insertions(+) diff --git a/src/common/sockutil.c b/src/common/sockutil.c index a924026..23bb97c 100644 --- a/src/common/sockutil.c +++ b/src/common/sockutil.c @@ -68,6 +68,34 @@ int sock_set_reuseaddr( int fd, int optval ) return setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval) ); } +int sock_set_keepalive_params( int fd, int time, int intvl, int probes) +{ + return sock_set_keepalive(fd, 1) || + sock_set_tcp_keepidle(fd, time) || + sock_set_tcp_keepintvl(fd, intvl) || + sock_set_tcp_keepcnt(fd, probes); +} + +int sock_set_keepalive( int fd, int optval ) +{ + return setsockopt( fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval) ); +} + +int sock_set_tcp_keepidle( int fd, int optval ) +{ + return setsockopt( fd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, sizeof(optval) ); +} + +int sock_set_tcp_keepintvl( int fd, int optval ) +{ + return setsockopt( fd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, sizeof(optval) ); +} + +int sock_set_tcp_keepcnt( int fd, int optval ) +{ + return setsockopt( fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, sizeof(optval) ); +} + /* Set the tcp_nodelay option */ int sock_set_tcp_nodelay( int fd, int optval ) { diff --git a/src/common/sockutil.h b/src/common/sockutil.h index e79b566..94dbf85 100644 --- a/src/common/sockutil.h +++ b/src/common/sockutil.h @@ -14,9 +14,24 @@ size_t sockaddr_size(const struct sockaddr* sa); */ const char* sockaddr_address_string(const struct sockaddr* sa, char* dest, size_t len); +/* Configure TCP keepalive on a socket */ +int sock_set_keepalive_params( int fd, int time, int intvl, int probes); + +/* Set the SOL_KEEPALIVE otion */ +int sock_set_keepalive(int fd, int optval); + /* Set the SOL_REUSEADDR otion */ int sock_set_reuseaddr(int fd, int optval); +/* Set the tcp_keepidle option */ +int sock_set_tcp_keepidle(int fd, int optval); + +/* Set the tcp_keepintvl option */ +int sock_set_tcp_keepintvl(int fd, int optval); + +/* Set the tcp_keepcnt option */ +int sock_set_tcp_keepcnt(int fd, int optval); + /* Set the tcp_nodelay option */ int sock_set_tcp_nodelay(int fd, int optval); diff --git a/src/server/serve.c b/src/server/serve.c index de6b871..225e384 100644 --- a/src/server/serve.c +++ b/src/server/serve.c @@ -422,6 +422,9 @@ void accept_nbd_client( int slot; char s_client_address[64] = {0}; + FATAL_IF_NEGATIVE( sock_set_keepalive_params( client_fd, CLIENT_KEEPALIVE_TIME, CLIENT_KEEPALIVE_INTVL, CLIENT_KEEPALIVE_PROBES), + "Error setting keepalive parameters on client socket fd %d", client_fd ); + if ( !server_should_accept_client( params, client_address, s_client_address, 64 ) ) { FATAL_IF_NEGATIVE( close( client_fd ), diff --git a/src/server/serve.h b/src/server/serve.h index 5d04e14..1b697f2 100644 --- a/src/server/serve.h +++ b/src/server/serve.h @@ -21,6 +21,9 @@ struct client_tbl_entry { #define MAX_NBD_CLIENTS 16 +#define CLIENT_KEEPALIVE_TIME 30 +#define CLIENT_KEEPALIVE_INTVL 10 +#define CLIENT_KEEPALIVE_PROBES 3 struct server { /* The flexnbd wrapper this server is attached to */ struct flexnbd * flexnbd; From 0c668f17766608dca7f3e37919252899419bf612 Mon Sep 17 00:00:00 2001 From: "James F. Carter" Date: Wed, 10 Jan 2018 13:54:26 +0000 Subject: [PATCH 2/4] remember how || works in C --- src/common/sockutil.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/common/sockutil.c b/src/common/sockutil.c index 23bb97c..158e8cd 100644 --- a/src/common/sockutil.c +++ b/src/common/sockutil.c @@ -70,10 +70,13 @@ int sock_set_reuseaddr( int fd, int optval ) int sock_set_keepalive_params( int fd, int time, int intvl, int probes) { - return sock_set_keepalive(fd, 1) || + if (sock_set_keepalive(fd, 1) || sock_set_tcp_keepidle(fd, time) || sock_set_tcp_keepintvl(fd, intvl) || - sock_set_tcp_keepcnt(fd, probes); + sock_set_tcp_keepcnt(fd, probes)) { + return -1; + } + return 0; } int sock_set_keepalive( int fd, int optval ) From 884a7147448f734247e20792766dadaaebe98acc Mon Sep 17 00:00:00 2001 From: "James F. Carter" Date: Wed, 10 Jan 2018 13:55:05 +0000 Subject: [PATCH 3/4] whitespace fix --- src/common/sockutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/sockutil.c b/src/common/sockutil.c index 158e8cd..56d728f 100644 --- a/src/common/sockutil.c +++ b/src/common/sockutil.c @@ -74,7 +74,7 @@ int sock_set_keepalive_params( int fd, int time, int intvl, int probes) sock_set_tcp_keepidle(fd, time) || sock_set_tcp_keepintvl(fd, intvl) || sock_set_tcp_keepcnt(fd, probes)) { - return -1; + return -1; } return 0; } From d62b069ce4a3c162d20363fd123156c311aad4b7 Mon Sep 17 00:00:00 2001 From: "James F. Carter" Date: Wed, 10 Jan 2018 13:58:11 +0000 Subject: [PATCH 4/4] debian: update changelog --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index de8ee40..0403ca2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +flexnbd (0.1.8) UNRELEASED; urgency=medium + + * Set TCP keepalive on sockets so broken connections are reaped (#33, !33) + + -- James Carter Wed, 10 Jan 2018 13:57:10 +0000 + flexnbd (0.1.7) stable; urgency=medium * Return bytes_left in migration statistics.