diff --git a/ChangeLog.txt b/ChangeLog.txt index d150fc12..4c1480c8 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -15,6 +15,9 @@ Broker: property just before they were expired. Closes #1464. - Fix TLS Websockets clients not receiving messages after taking over a previous connection. Closes #1489. +- Fix MQTT 3.1.1 clients using clean session false, or MQTT 5.0 clients using + session-expiry-interval set to infinity never expiring, even when the global + `persistent_client_expiration` option was set. Closes #1494. Client library: - Fix publish properties not being passed to on_message_v5 callback for QoS 2 diff --git a/src/context.c b/src/context.c index 35e57310..9483ef0c 100644 --- a/src/context.c +++ b/src/context.c @@ -230,7 +230,7 @@ void context__disconnect(struct mosquitto_db *db, struct mosquitto *context) context__send_will(db, context); if(context->session_expiry_interval == 0){ - + /* Client session is due to be expired now */ #ifdef WITH_BRIDGE if(!context->bridge) #endif diff --git a/src/session_expiry.c b/src/session_expiry.c index e720b703..5732c106 100644 --- a/src/session_expiry.c +++ b/src/session_expiry.c @@ -38,17 +38,32 @@ int session_expiry__add(struct mosquitto_db *db, struct mosquitto *context) { struct session_expiry_list *item; + if(db->config->persistent_client_expiration == 0){ + if(context->session_expiry_interval == UINT32_MAX){ + /* There isn't a global expiry set, and the client has asked to + * never expire, so we don't add it to the list. */ + return MOSQ_ERR_SUCCESS; + } + } + item = mosquitto__calloc(1, sizeof(struct session_expiry_list)); if(!item) return MOSQ_ERR_NOMEM; item->context = context; item->context->session_expiry_time = time(NULL); - if(db->config->persistent_client_expiration == 0 || - db->config->persistent_client_expiration < item->context->session_expiry_interval){ + if(db->config->persistent_client_expiration == 0){ + /* No global expiry, so use the client expiration interval */ item->context->session_expiry_time += item->context->session_expiry_interval; }else{ - item->context->session_expiry_time += db->config->persistent_client_expiration; + /* We have a global expiry interval */ + if(db->config->persistent_client_expiration < item->context->session_expiry_interval){ + /* The client expiry is longer than the global expiry, so use the global */ + item->context->session_expiry_time += db->config->persistent_client_expiration; + }else{ + /* The global expiry is longer than the client expiry, so use the client */ + item->context->session_expiry_time += item->context->session_expiry_interval; + } } context->expiry_list_item = item; @@ -95,8 +110,7 @@ void session_expiry__check(struct mosquitto_db *db, time_t now) last_check = now; DL_FOREACH_SAFE(expiry_list, item, tmp){ - if(item->context->session_expiry_interval != UINT32_MAX - && item->context->session_expiry_time < now){ + if(item->context->session_expiry_time < now){ context = item->context; session_expiry__remove(context);