Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [mosquitto-dev] [PATCH] Add option to use tcp keepalive

So, what's wrong with just turning down your mqtt keepalive?  

TCP Keepalive shorter than MQTT keepalive -> never going to have
mqtt keeaplive timeouts. why bother? TCP keepalive longer than
MQTT keepalive -> never going to have tcp keepalive timeouts, why
bother?

MQTT keepalives are two bytes. Yes, this is bigger than a tcp
keepalive, but it covers more than a tcp keepalive does too. TCP
keepalive only tells you that the tcp connection is (probably)
still ok, not whether there's still a functional client at the
remote end.

I'm not sure I see any real motivation for this, and certainly
not something that's going to be platform specific!

Sincerely,
Karl Palsson


Raphael Lisicki <rlisicki@xxxxxxxxxxxxx> wrote:
> 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

Attachment: signature.html
Description: OpenPGP Digital Signature


Back to the top