diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml
index a6bf0c99..fa9d1e86 100644
--- a/man/mosquitto.conf.5.xml
+++ b/man/mosquitto.conf.5.xml
@@ -628,6 +628,16 @@
Reloaded on reload signal.
+
+ [ true | false ]
+
+ If set to false, then retained messages are not
+ supported. Clients that send a message with the retain
+ bit will be disconnected if this option is set to
+ false. Defaults to true.
+ Reloaded on reload signal.
+
+
[ true | false ]
diff --git a/mosquitto.conf b/mosquitto.conf
index 96450050..fa332a24 100644
--- a/mosquitto.conf
+++ b/mosquitto.conf
@@ -149,6 +149,12 @@
#per_listener_settings false
+# Set to false to disable retained message support. If a client publishes a
+# message with the retain bit set, it will be disconnected if this is set to
+# false.
+#retain_available true
+
+
# =================================================================
# Default listener
# =================================================================
diff --git a/src/conf.c b/src/conf.c
index 6b6f2434..20609e07 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -219,6 +219,7 @@ static void config__init_reload(struct mosquitto_db *db, struct mosquitto__confi
config->persistence_file = NULL;
config->persistent_client_expiration = 0;
config->queue_qos0_messages = false;
+ config->retain_available = true;
config->set_tcp_nodelay = false;
config->sys_interval = 10;
config->upgrade_outgoing_qos = false;
@@ -1729,6 +1730,8 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available.");
#endif
+ }else if(!strcmp(token, "retain_available")){
+ if(conf__parse_bool(&token, token, &config->retain_available, saveptr)) return MOSQ_ERR_INVAL;
}else if(!strcmp(token, "retry_interval")){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: The retry_interval option is no longer available.");
}else if(!strcmp(token, "round_robin")){
diff --git a/src/database.c b/src/database.c
index 3de57289..eb5547f7 100644
--- a/src/database.c
+++ b/src/database.c
@@ -575,6 +575,10 @@ int db__messages_easy_queue(struct mosquitto_db *db, struct mosquitto *context,
topic_heap = mosquitto__strdup(topic);
if(!topic_heap) return MOSQ_ERR_INVAL;
+ if(db->config->retain_available == false){
+ retain = 0;
+ }
+
if(UHPA_ALLOC(payload_uhpa, payloadlen) == 0){
mosquitto__free(topic_heap);
return MOSQ_ERR_NOMEM;
diff --git a/src/handle_connect.c b/src/handle_connect.c
index a109187e..0e87303b 100644
--- a/src/handle_connect.c
+++ b/src/handle_connect.c
@@ -236,6 +236,14 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context)
password_flag = connect_flags & 0x40;
username_flag = connect_flags & 0x80;
+ if(will && will_retain && db->config->retain_available == false){
+ if(protocol_version == mosq_p_mqtt5){
+ send__connack(db, context, 0, MQTT_RC_RETAIN_NOT_SUPPORTED);
+ }
+ rc = 1;
+ goto handle_connect_error;
+ }
+
if(packet__read_uint16(&context->in_packet, &(context->keepalive))){
rc = 1;
goto handle_connect_error;
diff --git a/src/handle_publish.c b/src/handle_publish.c
index 31b1df5b..8cb11449 100644
--- a/src/handle_publish.c
+++ b/src/handle_publish.c
@@ -68,6 +68,13 @@ int handle__publish(struct mosquitto_db *db, struct mosquitto *context)
}
retain = (header & 0x01);
+ if(retain && db->config->retain_available == false){
+ if(context->protocol == mosq_p_mqtt5){
+ send__disconnect(context, MQTT_RC_RETAIN_NOT_SUPPORTED, NULL);
+ }
+ return 1;
+ }
+
if(packet__read_string(&context->in_packet, &topic, &slen)) return 1;
if(!slen){
/* Invalid publish topic, disconnect client. */
diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h
index 7351e0d8..694bd649 100644
--- a/src/mosquitto_broker_internal.h
+++ b/src/mosquitto_broker_internal.h
@@ -268,6 +268,7 @@ struct mosquitto__config {
char *pid_file;
bool queue_qos0_messages;
bool per_listener_settings;
+ bool retain_available;
bool set_tcp_nodelay;
int sys_interval;
bool upgrade_outgoing_qos;
diff --git a/src/send_connack.c b/src/send_connack.c
index c674548e..629dca64 100644
--- a/src/send_connack.c
+++ b/src/send_connack.c
@@ -44,6 +44,13 @@ int send__connack(struct mosquitto_db *db, struct mosquitto *context, int ack, i
packet->command = CMD_CONNACK;
packet->remaining_length = 2;
if(context->protocol == mosq_p_mqtt5){
+ if(reason_code < 128 && db->config->retain_available == false){
+ rc = mosquitto_property_add_byte(&properties, MQTT_PROP_RETAIN_AVAILABLE, 0);
+ if(rc){
+ mosquitto__free(packet);
+ return rc;
+ }
+ }
proplen = property__get_length_all(properties);
varbytes = packet__varint_bytes(proplen);
packet->remaining_length += proplen + varbytes;