This commit adds new configuration options to use TCP
keepalives. They can be useful when using a
bandwidth-constrained connection. The broker can realize
earlier that a client has disconnected before the next MQTT
ping takes place
---
config.mk | 7 +++++++
mosquitto.conf | 9 +++++++++
src/conf.c | 30 ++++++++++++++++++++++++++++++
src/mosquitto_broker_internal.h | 6 ++++++
src/net.c | 25 +++++++++++++++++++++++++
5 files changed, 77 insertions(+)
diff --git a/config.mk b/config.mk
index 0185027..297abfa 100644
--- a/config.mk
+++ b/config.mk
@@ -92,6 +92,9 @@ WITH_STATIC_LIBRARIES:=no
# Build with epoll support.
WITH_EPOLL:=yes
+# Build with support for TCP keepalives. Requires Linux
+WITH_TCPKEEPALIVE:=yes
+
# =============================================================================
# End of user configuration
# =============================================================================
@@ -255,6 +258,10 @@ ifeq ($(WITH_EC),yes)
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_EC
endif
+ifeq ($(WITH_TCPKEEPALIVE),yes)
+ BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_TCPKEEPALIVE
+endif
+
ifeq ($(WITH_ADNS),yes)
BROKER_LIBS:=$(BROKER_LIBS) -lanl
BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_ADNS
diff --git a/mosquitto.conf b/mosquitto.conf
index b383c0a..31cf71a 100644
--- a/mosquitto.conf
+++ b/mosquitto.conf
@@ -136,6 +136,15 @@
# of packets being sent.
#set_tcp_nodelay false
+# Additionally use TCP keepalive as a lower-overhead way to check if a session
+# is still alive. Might allow to set a bigger ping rate.
+# The properties are directly passed to setsockopt.
+# See http://man7.org/linux/man-pages/man7/tcp.7.html for explanation
+#use_tcp_keepalive true
+#tcp_keepcnt 5
+#tcp_keepidle 900
+#tcp_keepintvl 180
+
# =================================================================
# Default listener
# =================================================================
diff --git a/src/conf.c b/src/conf.c
index 44207d4..3b8aa7e 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -251,6 +251,12 @@ void config__init(struct mosquitto__config *config)
config->auth_plugins = NULL;
config->verbose = false;
config->message_size_limit = 0;
+#ifdef WITH_TCPKEEPALIVE
+ config->use_tcp_keepalive = false;
+ config->tcp_keepcnt = 5;
+ config->tcp_keepidle = 900;
+ config->tcp_keepintvl = 180;
+#endif
}
void config__cleanup(struct mosquitto__config *config)
@@ -1854,6 +1860,30 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, const
|| !strcmp(token, "max_log_entries")
|| !strcmp(token, "trace_output")){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Unsupported rsmb configuration option \"%s\".", token);
+ }else if(!strcmp(token, "use_tcp_keepalive")){
+#ifdef WITH_TCPKEEPALIVE
+ if(conf__parse_bool(&token, "use_tcp_keepalive", &config->use_tcp_keepalive, saveptr)) return MOSQ_ERR_INVAL;
+#else
+ log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TCPKEEPALIVE support not available.");
+#endif
+ }else if(!strcmp(token, "tcp_keepcnt")){
+#ifdef WITH_TCPKEEPALIVE
+ if(conf__parse_int(&token, "tcp_keepcnt", &config->tcp_keepcnt, saveptr)) return MOSQ_ERR_INVAL;
+#else
+ log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TCPKEEPALIVE support not available.");
+#endif
+ }else if(!strcmp(token, "tcp_keepidle")){
+#ifdef WITH_TCPKEEPALIVE
+ if(conf__parse_int(&token, "tcp_keepidle", &config->tcp_keepidle, saveptr)) return MOSQ_ERR_INVAL;
+#else
+ log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TCPKEEPALIVE support not available.");
+#endif
+ }else if(!strcmp(token, "tcp_keepintvl")){
+#ifdef WITH_TCPKEEPALIVE
+ if(conf__parse_int(&token, "tcp_keepintvl", &config->tcp_keepintvl, saveptr)) return MOSQ_ERR_INVAL;
+#else
+ log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TCPKEEPALIVE support not available.");
+#endif
}else{
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unknown configuration variable \"%s\".", token);
return MOSQ_ERR_INVAL;
diff --git a/src/mosquitto_broker_internal.h
b/src/mosquitto_broker_internal.h index 92fac93..85b9cbf 100644
--- a/src/mosquitto_broker_internal.h
+++ b/src/mosquitto_broker_internal.h
@@ -223,6 +223,12 @@ struct mosquitto__config {
struct mosquitto__bridge *bridges;
int bridge_count;
#endif
+#ifdef WITH_TCPKEEPALIVE
+ bool use_tcp_keepalive;
+ int tcp_keepcnt;
+ int tcp_keepidle;
+ int tcp_keepintvl;
+#endif
struct mosquitto__auth_plugin_config *auth_plugins;
int auth_plugin_count;
};
diff --git a/src/net.c b/src/net.c
index a0f90b8..ae9c5bc 100644
--- a/src/net.c
+++ b/src/net.c
@@ -27,6 +27,11 @@ Contributors:
#include <ws2tcpip.h>
#endif
+#ifdef WITH_TCPKEEPALIVE
+# include <sys/socket.h>
+# include <netinet/tcp.h>
+#endif
+
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@@ -127,6 +132,26 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock)
setsockopt(new_sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
}
+#ifdef WITH_TCPKEEPALIVE
+ if (db->config->use_tcp_keepalive){
+ int optval = 1;
+ if (setsockopt(new_sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) {
+ log__printf(NULL, MOSQ_LOG_WARNING, "TCP keepalive could not be enabled");
+ }
+ else {
+ int keepcnt = db->config->tcp_keepcnt;
+ int keepidle = db->config->tcp_keepidle;
+ int keepintvl = db->config->tcp_keepintvl;
+
+ setsockopt(new_sock, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt));
+ setsockopt(new_sock, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle));
+ setsockopt(new_sock, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, sizeof(keepintvl));
+
+ log__printf(NULL, MOSQ_LOG_DEBUG, "TCP keepalive enabled with %d, %d, %d", keepcnt, keepidle, keepintvl);
+ }
+ }
+#endif
+
new_context = context__init(db, new_sock);
if(!new_context){
COMPAT_CLOSE(new_sock);
--
2.7.4
_______________________________________________
mosquitto-dev mailing list
mosquitto-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or
unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/mosquitto-dev
_______________________________________________
mosquitto-dev mailing list
mosquitto-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/mosquitto-dev