diff options
-rw-r--r-- | examples/sudo_logsrvd.conf | 3 | ||||
-rw-r--r-- | logsrvd/logsrvd.c | 12 | ||||
-rw-r--r-- | logsrvd/logsrvd.h | 1 | ||||
-rw-r--r-- | logsrvd/logsrvd_conf.c | 21 |
4 files changed, 37 insertions, 0 deletions
diff --git a/examples/sudo_logsrvd.conf b/examples/sudo_logsrvd.conf index 7fd4306c8..fdc643525 100644 --- a/examples/sudo_logsrvd.conf +++ b/examples/sudo_logsrvd.conf @@ -21,6 +21,9 @@ # respond. A value of 0 will disable the timeout. The default value is 30. #timeout = 30 +# If set, SO_KEEPALIVE socket option is set on the connected socket. +#tcp_keepalive = true + # If set, secure connections with TLS 1.2 or 1.3. # By default, server connections are not encrypted. #tls = true diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c index d88f3c9b1..01296ff87 100644 --- a/logsrvd/logsrvd.c +++ b/logsrvd/logsrvd.c @@ -20,6 +20,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <netinet/tcp.h> #include <arpa/inet.h> #include <errno.h> @@ -1508,6 +1509,17 @@ listener_cb(int fd, int what, void *v) } /* TODO: pause accepting on ENFILE and EMFILE */ } + + /* set keepalive socket option on socket returned by accept */ + if (logsrvd_conf_tcp_keepalive()) { + int keepalive = 1; + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepalive, + sizeof(keepalive)) == -1) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, + "unable to set SO_KEEPALIVE option"); + } + } + debug_return; } diff --git a/logsrvd/logsrvd.h b/logsrvd/logsrvd.h index 1e081e025..ef5ab687d 100644 --- a/logsrvd/logsrvd.h +++ b/logsrvd/logsrvd.h @@ -176,6 +176,7 @@ bool logsrvd_conf_read(const char *path); const char *logsrvd_conf_iolog_dir(void); const char *logsrvd_conf_iolog_file(void); struct listen_address_list *logsrvd_conf_listen_address(void); +bool logsrvd_conf_tcp_keepalive(void); struct timespec *logsrvd_conf_get_sock_timeout(void); #if defined(HAVE_OPENSSL) bool logsrvd_conf_get_tls_opt(void); diff --git a/logsrvd/logsrvd_conf.c b/logsrvd/logsrvd_conf.c index fb1056d3e..e9fb12618 100644 --- a/logsrvd/logsrvd_conf.c +++ b/logsrvd/logsrvd_conf.c @@ -74,6 +74,7 @@ static struct logsrvd_config { struct logsrvd_config_server { struct listen_address_list addresses; struct timespec timeout; + bool tcp_keepalive; #if defined(HAVE_OPENSSL) bool tls; struct logsrvd_tls_config tls_config; @@ -134,6 +135,11 @@ logsrvd_conf_listen_address(void) return &logsrvd_config->server.addresses; } +bool +logsrvd_conf_tcp_keepalive(void) +{ + return logsrvd_config->server.tcp_keepalive; +} struct timespec * logsrvd_conf_get_sock_timeout(void) { @@ -415,6 +421,19 @@ cb_timeout(struct logsrvd_config *config, const char *str) debug_return_bool(true); } +static bool +cb_keepalive(struct logsrvd_config *config, const char *str) +{ + int val; + debug_decl(cb_keepalive, SUDO_DEBUG_UTIL); + + if ((val = sudo_strtobool(str)) == -1) + debug_return_bool(false); + + config->server.tcp_keepalive = val; + debug_return_bool(true); +} + #if defined(HAVE_OPENSSL) static bool cb_tls_opt(struct logsrvd_config *config, const char *str) @@ -677,6 +696,7 @@ cb_logfile_time_format(struct logsrvd_config *config, const char *str) static struct logsrvd_config_entry server_conf_entries[] = { { "listen_address", cb_listen_address }, { "timeout", cb_timeout }, + { "tcp_keepalive", cb_keepalive }, #if defined(HAVE_OPENSSL) { "tls", cb_tls_opt }, { "tls_key", cb_tls_key }, @@ -857,6 +877,7 @@ logsrvd_conf_alloc(void) /* Server defaults */ TAILQ_INIT(&config->server.addresses); config->server.timeout.tv_sec = DEFAULT_SOCKET_TIMEOUT_SEC; + config->server.tcp_keepalive = true; #if defined(HAVE_OPENSSL) config->server.tls_config.cacert_path = strdup(DEFAULT_CA_CERT_PATH); |