diff --git a/ChangeLog.txt b/ChangeLog.txt index ac6d47f5..213073e4 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -3,6 +3,8 @@ Broker: - Fix possible crash when using pattern ACLs. - Fix problems parsing config strings with multiple leading spaces. Closes #462154. +- Websockets clients are now periodically disconnected if they have not + maintained their keepalive timer. Closes #461619. Client library: - Inflight limits should only apply to outgoing messages. Closes #461620. diff --git a/src/conf.c b/src/conf.c index 292a10fe..e85534b6 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1557,6 +1557,7 @@ int _config_read_file_core(struct mqtt3_config *config, bool reload, const char }else if(!strcmp(token, "websockets")){ #ifdef WITH_WEBSOCKETS cur_listener->protocol = mp_websockets; + config->have_websockets_listener = true; #else _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Websockets support not available."); return MOSQ_ERR_INVAL; diff --git a/src/loop.c b/src/loop.c index e937e937..81b5529a 100644 --- a/src/loop.c +++ b/src/loop.c @@ -59,6 +59,36 @@ extern int g_clients_expired; static void loop_handle_errors(struct mosquitto_db *db, struct pollfd *pollfds); static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pollfds); +#ifdef WITH_WEBSOCKETS +static void temp__expire_websockets_clients(struct mosquitto_db *db) +{ + struct mosquitto *context, *ctxt_tmp; + static time_t last_check = 0; + time_t now = mosquitto_time(); + char *id; + + if(now - last_check > 60){ + HASH_ITER(hh_id, db->contexts_by_id, context, ctxt_tmp){ + if(context->wsi && context->sock != INVALID_SOCKET){ + if(context->keepalive && now - context->last_msg_in > (time_t)(context->keepalive)*3/2){ + if(db->config->connection_messages == true){ + if(context->id){ + id = context->id; + }else{ + id = ""; + } + _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s has exceeded timeout, disconnecting.", id); + } + /* Client has exceeded keepalive*1.5 */ + do_disconnect(db, context); + } + } + } + last_check = mosquitto_time(); + } +} +#endif + int mosquitto_main_loop(struct mosquitto_db *db, int *listensock, int listensock_count, int listener_max) { #ifdef WITH_SYS_TREE @@ -344,6 +374,9 @@ int mosquitto_main_loop(struct mosquitto_db *db, int *listensock, int listensock libwebsocket_service(db->config->listeners[i].ws_context, 0); } } + if(db->config->have_websockets_listener){ + temp__expire_websockets_clients(db); + } #endif } diff --git a/src/mosquitto_broker.h b/src/mosquitto_broker.h index d1deb7d5..026fd47c 100644 --- a/src/mosquitto_broker.h +++ b/src/mosquitto_broker.h @@ -119,6 +119,7 @@ struct mqtt3_config { bool verbose; #ifdef WITH_WEBSOCKETS int websockets_log_level; + bool have_websockets_listener; #endif #ifdef WITH_BRIDGE struct _mqtt3_bridge *bridges;