diff --git a/ChangeLog.txt b/ChangeLog.txt index 7173262b..5c43be75 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -37,6 +37,9 @@ Broker: - Return protocol error if a client attemps to subscribe to a shared subscription and also sets no-local. - Log protocol version and ciphers that a client negotiates when connecting. +- Registration of the MOSQ_EVT_CONTROL plugin event is now handled globally + across the broker, so only a single plugin can register for a given $CONTROL + topic. Client library: - Add MOSQ_OPT_DISABLE_SOCKETPAIR to allow the disabling of the socketpair diff --git a/src/control.c b/src/control.c index 9cef197c..4daaaae5 100644 --- a/src/control.c +++ b/src/control.c @@ -36,12 +36,15 @@ int control__process(struct mosquitto *context, struct mosquitto_msg_store *stor mosquitto_property *properties = NULL; int rc = MOSQ_ERR_SUCCESS; - if(db.config->per_listener_settings){ + /* Check global plugins and non-per-listener settings first */ + opts = &db.config->security_options; + HASH_FIND(hh, opts->plugin_callbacks.control, stored->topic, strlen(stored->topic), cb_found); + + /* If not found, check for per-listener plugins. */ + if(cb_found == NULL && db.config->per_listener_settings){ opts = &context->listener->security_options; - }else{ - opts = &db.config->security_options; + HASH_FIND(hh, opts->plugin_callbacks.control, stored->topic, strlen(stored->topic), cb_found); } - HASH_FIND(hh, opts->plugin_callbacks.control, stored->topic, strlen(stored->topic), cb_found); if(cb_found){ memset(&event_data, 0, sizeof(event_data)); event_data.client = context; @@ -75,9 +78,10 @@ int control__process(struct mosquitto *context, struct mosquitto_msg_store *stor } #endif -int control__register_callback(struct mosquitto__security_options *opts, MOSQ_FUNC_generic_callback cb_func, const char *topic, void *userdata) +int control__register_callback(MOSQ_FUNC_generic_callback cb_func, const char *topic, void *userdata) { #ifdef WITH_CONTROL + struct mosquitto__security_options *opts; struct mosquitto__callback *cb_found, *cb_new; size_t topic_len; @@ -88,6 +92,8 @@ int control__register_callback(struct mosquitto__security_options *opts, MOSQ_FU return MOSQ_ERR_INVAL; } + opts = &db.config->security_options; + HASH_FIND(hh, opts->plugin_callbacks.control, topic, topic_len, cb_found); if(cb_found){ return MOSQ_ERR_ALREADY_EXISTS; @@ -112,9 +118,11 @@ int control__register_callback(struct mosquitto__security_options *opts, MOSQ_FU #endif } -int control__unregister_callback(struct mosquitto__security_options *opts, MOSQ_FUNC_generic_callback cb_func, const char *topic) +int control__unregister_callback(MOSQ_FUNC_generic_callback cb_func, const char *topic) { #ifdef WITH_CONTROL + struct mosquitto__security_options *opts; + struct mosquitto__callback *cb_found; size_t topic_len; @@ -123,6 +131,8 @@ int control__unregister_callback(struct mosquitto__security_options *opts, MOSQ_ if(topic_len == 0 || topic_len > 65535) return MOSQ_ERR_INVAL; if(strncmp(topic, "$CONTROL/", strlen("$CONTROL/"))) return MOSQ_ERR_INVAL; + opts = &db.config->security_options; + HASH_FIND(hh, opts->plugin_callbacks.control, topic, topic_len, cb_found); if(cb_found && cb_found->cb == cb_func){ HASH_DELETE(hh, opts->plugin_callbacks.control, cb_found); diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index bb8d53f5..86388b9e 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -723,8 +723,8 @@ int connect__on_authorised(struct mosquitto *context, void *auth_data_out, uint1 int control__process(struct mosquitto *context, struct mosquitto_msg_store *stored); void control__cleanup(void); #endif -int control__register_callback(struct mosquitto__security_options *opts, MOSQ_FUNC_generic_callback cb_func, const char *topic, void *userdata); -int control__unregister_callback(struct mosquitto__security_options *opts, MOSQ_FUNC_generic_callback cb_func, const char *topic); +int control__register_callback(MOSQ_FUNC_generic_callback cb_func, const char *topic, void *userdata); +int control__unregister_callback(MOSQ_FUNC_generic_callback cb_func, const char *topic); /* ============================================================ diff --git a/src/plugin.c b/src/plugin.c index 9a8adce3..b44c235a 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -267,7 +267,7 @@ int mosquitto_callback_register( cb_base = &security_options->plugin_callbacks.ext_auth_continue; break; case MOSQ_EVT_CONTROL: - return control__register_callback(security_options, cb_func, event_data, userdata); + return control__register_callback(cb_func, event_data, userdata); break; case MOSQ_EVT_MESSAGE: cb_base = &security_options->plugin_callbacks.message; @@ -340,7 +340,7 @@ int mosquitto_callback_unregister( cb_base = &security_options->plugin_callbacks.ext_auth_continue; break; case MOSQ_EVT_CONTROL: - return control__unregister_callback(security_options, cb_func, event_data); + return control__unregister_callback(cb_func, event_data); break; case MOSQ_EVT_MESSAGE: cb_base = &security_options->plugin_callbacks.message;