From 2bfc7e7cc82d49c4b334733418cc9c1f39aae5ea Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 30 Sep 2021 12:42:13 +0100 Subject: [PATCH] Do plugin callback unregistering automatically. --- ChangeLog.txt | 3 + include/mosquitto_plugin.h | 3 + plugins/dynamic-security/plugin.c | 5 - .../add-properties/mosquitto_add_properties.c | 9 -- .../auth-by-ip/mosquitto_auth_by_ip.c | 9 -- .../mosquitto_client_properties.c | 9 -- .../mosquitto_connection_state.c | 10 -- .../delayed-auth/mosquitto_delayed_auth.c | 11 ++- .../force-retain/mosquitto_force_retain.c | 9 -- .../mosquitto_message_timestamp.c | 9 -- .../mosquitto_payload_modification.c | 9 -- .../mosquitto_print_ip_on_publish.c | 9 -- .../mosquitto_topic_modification.c | 9 -- src/control.c | 23 +++++ src/mosquitto_broker_internal.h | 13 +++ src/plugin.c | 97 +++++++++++++++++-- src/security.c | 65 +++++++------ 17 files changed, 174 insertions(+), 128 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 30b344bd..ecd9d167 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -67,6 +67,9 @@ Broker: - Improve idle performance. The broker now calculates when the next event of interest is, and uses that as the timeout for e.g. epoll_wait(). This can reduce the number of process wakeups by 100x on an idle broker. +- Plugins no longer need to define mosquitto_plugin_cleanup() if they do not + need to do any of their own cleanup. Callbacks will be unregistered + automatically. Client library: - Add MOSQ_OPT_DISABLE_SOCKETPAIR to allow the disabling of the socketpair diff --git a/include/mosquitto_plugin.h b/include/mosquitto_plugin.h index 447f4b89..fd984030 100644 --- a/include/mosquitto_plugin.h +++ b/include/mosquitto_plugin.h @@ -190,6 +190,9 @@ mosq_plugin_EXPORT int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, * Called when the broker is shutting down. This will only ever be called once * per plugin. * + * If you do not need to do any of your own cleanup, this function is not + * required. The broker will automatically unregister your callbacks. + * * Parameters: * * user_data - The pointer provided in . diff --git a/plugins/dynamic-security/plugin.c b/plugins/dynamic-security/plugin.c index aa1064a2..bffc38d6 100644 --- a/plugins/dynamic-security/plugin.c +++ b/plugins/dynamic-security/plugin.c @@ -506,11 +506,6 @@ int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *options, int UNUSED(options); UNUSED(option_count); - if(plg_id){ - mosquitto_callback_unregister(plg_id, MOSQ_EVT_CONTROL, dynsec_control_callback, "$CONTROL/dynamic-security/v1"); - mosquitto_callback_unregister(plg_id, MOSQ_EVT_BASIC_AUTH, dynsec_auth__basic_auth_callback, NULL); - mosquitto_callback_unregister(plg_id, MOSQ_EVT_ACL_CHECK, dynsec__acl_check_callback, NULL); - } dynsec_groups__cleanup(); dynsec_clients__cleanup(); dynsec_roles__cleanup(); diff --git a/plugins/examples/add-properties/mosquitto_add_properties.c b/plugins/examples/add-properties/mosquitto_add_properties.c index bfdd072f..faadc37e 100644 --- a/plugins/examples/add-properties/mosquitto_add_properties.c +++ b/plugins/examples/add-properties/mosquitto_add_properties.c @@ -101,12 +101,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s mosquitto_plugin_set_info(identifier, PLUGIN_NAME, PLUGIN_VERSION); return mosquitto_callback_register(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL, NULL); } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL); -} diff --git a/plugins/examples/auth-by-ip/mosquitto_auth_by_ip.c b/plugins/examples/auth-by-ip/mosquitto_auth_by_ip.c index 06f7901a..a4d4f114 100644 --- a/plugins/examples/auth-by-ip/mosquitto_auth_by_ip.c +++ b/plugins/examples/auth-by-ip/mosquitto_auth_by_ip.c @@ -76,12 +76,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s mosquitto_plugin_set_info(identifier, PLUGIN_NAME, PLUGIN_VERSION); return mosquitto_callback_register(mosq_pid, MOSQ_EVT_BASIC_AUTH, basic_auth_callback, NULL, NULL); } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_BASIC_AUTH, basic_auth_callback, NULL); -} diff --git a/plugins/examples/client-properties/mosquitto_client_properties.c b/plugins/examples/client-properties/mosquitto_client_properties.c index 22d46935..7eb1d03f 100644 --- a/plugins/examples/client-properties/mosquitto_client_properties.c +++ b/plugins/examples/client-properties/mosquitto_client_properties.c @@ -53,12 +53,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s mosquitto_plugin_set_info(identifier, PLUGIN_NAME, PLUGIN_VERSION); return mosquitto_callback_register(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL, NULL); } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL); -} diff --git a/plugins/examples/connection-state/mosquitto_connection_state.c b/plugins/examples/connection-state/mosquitto_connection_state.c index 80af0899..7ae1a664 100644 --- a/plugins/examples/connection-state/mosquitto_connection_state.c +++ b/plugins/examples/connection-state/mosquitto_connection_state.c @@ -115,13 +115,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s rc = mosquitto_callback_register(mosq_pid, MOSQ_EVT_DISCONNECT, disconnect_callback, NULL, NULL); return rc; } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_CONNECT, connect_callback, NULL); - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_DISCONNECT, disconnect_callback, NULL); -} diff --git a/plugins/examples/delayed-auth/mosquitto_delayed_auth.c b/plugins/examples/delayed-auth/mosquitto_delayed_auth.c index 6ccf7b4d..a83b7b48 100644 --- a/plugins/examples/delayed-auth/mosquitto_delayed_auth.c +++ b/plugins/examples/delayed-auth/mosquitto_delayed_auth.c @@ -162,12 +162,17 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) { + struct client_list *client, *client_tmp; + UNUSED(user_data); UNUSED(opts); UNUSED(opt_count); - mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_BASIC_AUTH, basic_auth_callback, NULL); - mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_TICK, tick_callback, NULL); + HASH_ITER(hh, clients, client, client_tmp){ + HASH_DELETE(hh, clients, client); + mosquitto_free(client->id); + mosquitto_free(client); + } - return 0; + return MOSQ_ERR_SUCCESS; } diff --git a/plugins/examples/force-retain/mosquitto_force_retain.c b/plugins/examples/force-retain/mosquitto_force_retain.c index 1dc2fdee..69ef11a9 100644 --- a/plugins/examples/force-retain/mosquitto_force_retain.c +++ b/plugins/examples/force-retain/mosquitto_force_retain.c @@ -68,12 +68,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s mosquitto_plugin_set_info(identifier, PLUGIN_NAME, PLUGIN_VERSION); return mosquitto_callback_register(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL, NULL); } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL); -} diff --git a/plugins/examples/message-timestamp/mosquitto_message_timestamp.c b/plugins/examples/message-timestamp/mosquitto_message_timestamp.c index d9e78cf8..eff314c5 100644 --- a/plugins/examples/message-timestamp/mosquitto_message_timestamp.c +++ b/plugins/examples/message-timestamp/mosquitto_message_timestamp.c @@ -72,12 +72,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s mosquitto_plugin_set_info(identifier, PLUGIN_NAME, PLUGIN_VERSION); return mosquitto_callback_register(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL, NULL); } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL); -} diff --git a/plugins/examples/payload-modification/mosquitto_payload_modification.c b/plugins/examples/payload-modification/mosquitto_payload_modification.c index 16bad2e7..bd2fcfd2 100644 --- a/plugins/examples/payload-modification/mosquitto_payload_modification.c +++ b/plugins/examples/payload-modification/mosquitto_payload_modification.c @@ -95,12 +95,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s mosquitto_plugin_set_info(identifier, PLUGIN_NAME, PLUGIN_VERSION); return mosquitto_callback_register(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL, NULL); } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL); -} diff --git a/plugins/examples/print-ip-on-publish/mosquitto_print_ip_on_publish.c b/plugins/examples/print-ip-on-publish/mosquitto_print_ip_on_publish.c index bb485f4a..0e7ed9c9 100644 --- a/plugins/examples/print-ip-on-publish/mosquitto_print_ip_on_publish.c +++ b/plugins/examples/print-ip-on-publish/mosquitto_print_ip_on_publish.c @@ -42,12 +42,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s mosquitto_plugin_set_info(identifier, PLUGIN_NAME, PLUGIN_VERSION); return mosquitto_callback_register(mosq_pid, MOSQ_EVT_MESSAGE, message_callback, NULL, NULL); } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, message_callback, NULL); -} diff --git a/plugins/examples/topic-modification/mosquitto_topic_modification.c b/plugins/examples/topic-modification/mosquitto_topic_modification.c index 45cd18d6..1ab2ed27 100644 --- a/plugins/examples/topic-modification/mosquitto_topic_modification.c +++ b/plugins/examples/topic-modification/mosquitto_topic_modification.c @@ -78,12 +78,3 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s mosq_pid = identifier; return mosquitto_callback_register(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL, NULL); } - -int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) -{ - UNUSED(user_data); - UNUSED(opts); - UNUSED(opt_count); - - return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, callback_message, NULL); -} diff --git a/src/control.c b/src/control.c index 3750dbd4..5caf6c41 100644 --- a/src/control.c +++ b/src/control.c @@ -167,3 +167,26 @@ int control__unregister_callback(mosquitto_plugin_id_t *identifier, MOSQ_FUNC_ge return MOSQ_ERR_NOT_SUPPORTED; #endif } + +/* Unregister all control callbacks for a single plugin */ +void control__unregister_all_callbacks(mosquitto_plugin_id_t *identifier) +{ + struct mosquitto__security_options *opts; + + struct mosquitto__callback *cb_found; + struct control_endpoint *ep, *ep_tmp; + + opts = &db.config->security_options; + + DL_FOREACH_SAFE(identifier->control_endpoints, ep, ep_tmp){ + HASH_FIND(hh, opts->plugin_callbacks.control, ep->topic, strlen(ep->topic), cb_found); + if(cb_found){ + HASH_DELETE(hh, opts->plugin_callbacks.control, cb_found); + mosquitto__free(cb_found->data); + mosquitto__free(cb_found); + } + + DL_DELETE(identifier->control_endpoints, ep); + mosquitto__free(ep); + } +} diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index 5bdfa783..b564a856 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -259,11 +259,22 @@ struct mosquitto__listener_sock{ struct mosquitto__listener *listener; }; + +/* Callbacks belonging to a specific plugin + * Doesn't include MOSQ_EVT_CONTROL events. + */ +struct plugin_own_callback{ + struct plugin_own_callback *next, *prev; + MOSQ_FUNC_generic_callback cb_func; + int event; +}; + typedef struct mosquitto_plugin_id_t{ struct mosquitto__listener *listener; char *plugin_name; char *plugin_version; struct control_endpoint *control_endpoints; + struct plugin_own_callback *own_callbacks; } mosquitto_plugin_id_t; struct mosquitto__config { @@ -752,6 +763,7 @@ void control__cleanup(void); #endif int control__register_callback(mosquitto_plugin_id_t *pid, MOSQ_FUNC_generic_callback cb_func, const char *topic, void *userdata); int control__unregister_callback(mosquitto_plugin_id_t *pid, MOSQ_FUNC_generic_callback cb_func, const char *topic); +void control__unregister_all_callbacks(mosquitto_plugin_id_t *identifier); /* ============================================================ @@ -816,6 +828,7 @@ void plugin__handle_disconnect(struct mosquitto *context, int reason); int plugin__handle_message(struct mosquitto *context, struct mosquitto_msg_store *stored); void LIB_ERROR(void); void plugin__handle_tick(void); +int plugin__callback_unregister_all(mosquitto_plugin_id_t *identifier); /* ============================================================ * Property related functions diff --git a/src/plugin.c b/src/plugin.c index be3ded0f..18830ca6 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -43,16 +43,25 @@ static bool check_callback_exists(struct mosquitto__callback *cb_base, MOSQ_FUNC } -static int remove_callback(struct mosquitto__callback **cb_base, MOSQ_FUNC_generic_callback cb_func) +static int remove_callback(mosquitto_plugin_id_t *identifier, int event, struct mosquitto__callback **cb_base, MOSQ_FUNC_generic_callback cb_func) { struct mosquitto__callback *tail, *tmp; + struct plugin_own_callback *own, *own_tmp; DL_FOREACH_SAFE(*cb_base, tail, tmp){ if(tail->cb == cb_func){ DL_DELETE(*cb_base, tail); mosquitto__free(tail); + break; + } + } + DL_FOREACH_SAFE(identifier->own_callbacks, own, own_tmp){ + if(own->cb_func == cb_func && own->event == event){ + DL_DELETE(identifier->own_callbacks, own); + mosquitto__free(own); return MOSQ_ERR_SUCCESS; } + mosquitto__free(own); } return MOSQ_ERR_NOT_FOUND; } @@ -70,13 +79,8 @@ int plugin__load_v5(struct mosquitto__listener *listener, struct mosquitto__auth LIB_CLOSE(lib); return MOSQ_ERR_UNKNOWN; } - if(!(plugin->plugin_cleanup_v5 = (FUNC_plugin_cleanup_v5)LIB_SYM(lib, "mosquitto_plugin_cleanup"))){ - log__printf(NULL, MOSQ_LOG_ERR, - "Error: Unable to load plugin function mosquitto_plugin_cleanup()."); - LIB_ERROR(); - LIB_CLOSE(lib); - return MOSQ_ERR_UNKNOWN; - } + /* Optional function */ + plugin->plugin_cleanup_v5 = (FUNC_plugin_cleanup_v5)LIB_SYM(lib, "mosquitto_plugin_cleanup"); pid = mosquitto__calloc(1, sizeof(mosquitto_plugin_id_t)); if(pid == NULL){ @@ -262,6 +266,7 @@ int mosquitto_callback_register( struct mosquitto__callback **cb_base = NULL, *cb_new; struct mosquitto__security_options *security_options; const char *event_name; + struct plugin_own_callback *own_callback; if(cb_func == NULL) return MOSQ_ERR_INVAL; @@ -328,6 +333,15 @@ int mosquitto_callback_register( if(cb_new == NULL){ return MOSQ_ERR_NOMEM; } + own_callback = mosquitto__calloc(1, sizeof(struct plugin_own_callback)); + if(own_callback == NULL){ + mosquitto__free(cb_new); + return MOSQ_ERR_NOMEM; + } + own_callback->event = event; + own_callback->cb_func = cb_func; + DL_APPEND(identifier->own_callbacks, own_callback); + DL_APPEND(*cb_base, cb_new); cb_new->cb = cb_func; cb_new->userdata = userdata; @@ -341,6 +355,71 @@ int mosquitto_callback_register( } +int plugin__callback_unregister_all(mosquitto_plugin_id_t *identifier) +{ + struct mosquitto__callback **cb_base = NULL; + struct mosquitto__security_options *security_options; + struct plugin_own_callback *own, *own_tmp; + + if(identifier == NULL){ + return MOSQ_ERR_INVAL; + } + + if(identifier->listener == NULL){ + security_options = &db.config->security_options; + }else{ + security_options = &identifier->listener->security_options; + } + + control__unregister_all_callbacks(identifier); + + DL_FOREACH_SAFE(identifier->own_callbacks, own, own_tmp){ + switch(own->event){ + case MOSQ_EVT_RELOAD: + cb_base = &security_options->plugin_callbacks.reload; + break; + case MOSQ_EVT_ACL_CHECK: + cb_base = &security_options->plugin_callbacks.acl_check; + break; + case MOSQ_EVT_BASIC_AUTH: + cb_base = &security_options->plugin_callbacks.basic_auth; + break; + case MOSQ_EVT_PSK_KEY: + cb_base = &security_options->plugin_callbacks.psk_key; + break; + case MOSQ_EVT_EXT_AUTH_START: + cb_base = &security_options->plugin_callbacks.ext_auth_start; + break; + case MOSQ_EVT_EXT_AUTH_CONTINUE: + cb_base = &security_options->plugin_callbacks.ext_auth_continue; + break; + case MOSQ_EVT_CONTROL: + cb_base = NULL; + break; + case MOSQ_EVT_MESSAGE: + cb_base = &security_options->plugin_callbacks.message; + break; + case MOSQ_EVT_TICK: + cb_base = &security_options->plugin_callbacks.tick; + break; + case MOSQ_EVT_DISCONNECT: + cb_base = &security_options->plugin_callbacks.disconnect; + break; + case MOSQ_EVT_CONNECT: + cb_base = &security_options->plugin_callbacks.connect; + break; + default: + cb_base = NULL; + break; + } + if(cb_base){ + remove_callback(identifier, own->event, cb_base, own->cb_func); + } + } + return MOSQ_ERR_SUCCESS; +} + + int mosquitto_callback_unregister( mosquitto_plugin_id_t *identifier, int event, @@ -398,7 +477,7 @@ int mosquitto_callback_unregister( break; } - return remove_callback(cb_base, cb_func); + return remove_callback(identifier, event, cb_base, cb_func); } void mosquitto_complete_basic_auth(const char *client_id, int result) diff --git a/src/security.c b/src/security.c index e4db8536..324861a2 100644 --- a/src/security.c +++ b/src/security.c @@ -406,46 +406,53 @@ static void security__module_cleanup_single(struct mosquitto__security_options * { int i; struct control_endpoint *ep, *tmp; + struct mosquitto__auth_plugin_config *conf; for(i=0; iauth_plugin_config_count; i++){ + conf = &opts->auth_plugin_configs[i]; + /* Run plugin cleanup function */ - if(opts->auth_plugin_configs[i].plugin.version == 5){ - opts->auth_plugin_configs[i].plugin.plugin_cleanup_v5( - opts->auth_plugin_configs[i].plugin.user_data, - opts->auth_plugin_configs[i].options, - opts->auth_plugin_configs[i].option_count); - mosquitto__free(opts->auth_plugin_configs[i].plugin.identifier->plugin_name); - mosquitto__free(opts->auth_plugin_configs[i].plugin.identifier->plugin_version); - DL_FOREACH_SAFE(opts->auth_plugin_configs[i].plugin.identifier->control_endpoints, ep, tmp){ - DL_DELETE(opts->auth_plugin_configs[i].plugin.identifier->control_endpoints, ep); + if(conf->plugin.version == 5){ + if(conf->plugin.plugin_cleanup_v5){ + conf->plugin.plugin_cleanup_v5( + conf->plugin.user_data, + conf->options, + conf->option_count); + } + + plugin__callback_unregister_all(conf->plugin.identifier); + mosquitto__free(conf->plugin.identifier->plugin_name); + mosquitto__free(conf->plugin.identifier->plugin_version); + DL_FOREACH_SAFE(conf->plugin.identifier->control_endpoints, ep, tmp){ + DL_DELETE(conf->plugin.identifier->control_endpoints, ep); mosquitto__free(ep); } - mosquitto__free(opts->auth_plugin_configs[i].plugin.identifier); - opts->auth_plugin_configs[i].plugin.identifier = NULL; + mosquitto__free(conf->plugin.identifier); + conf->plugin.identifier = NULL; - }else if(opts->auth_plugin_configs[i].plugin.version == 4){ - opts->auth_plugin_configs[i].plugin.plugin_cleanup_v4( - opts->auth_plugin_configs[i].plugin.user_data, - opts->auth_plugin_configs[i].options, - opts->auth_plugin_configs[i].option_count); + }else if(conf->plugin.version == 4){ + conf->plugin.plugin_cleanup_v4( + conf->plugin.user_data, + conf->options, + conf->option_count); - }else if(opts->auth_plugin_configs[i].plugin.version == 3){ - opts->auth_plugin_configs[i].plugin.plugin_cleanup_v3( - opts->auth_plugin_configs[i].plugin.user_data, - opts->auth_plugin_configs[i].options, - opts->auth_plugin_configs[i].option_count); + }else if(conf->plugin.version == 3){ + conf->plugin.plugin_cleanup_v3( + conf->plugin.user_data, + conf->options, + conf->option_count); - }else if(opts->auth_plugin_configs[i].plugin.version == 2){ - opts->auth_plugin_configs[i].plugin.plugin_cleanup_v2( - opts->auth_plugin_configs[i].plugin.user_data, - (struct mosquitto_auth_opt *)opts->auth_plugin_configs[i].options, - opts->auth_plugin_configs[i].option_count); + }else if(conf->plugin.version == 2){ + conf->plugin.plugin_cleanup_v2( + conf->plugin.user_data, + (struct mosquitto_auth_opt *)conf->options, + conf->option_count); } - if(opts->auth_plugin_configs[i].plugin.lib){ - LIB_CLOSE(opts->auth_plugin_configs[i].plugin.lib); + if(conf->plugin.lib){ + LIB_CLOSE(conf->plugin.lib); } - memset(&opts->auth_plugin_configs[i].plugin, 0, sizeof(struct mosquitto__auth_plugin)); + memset(&conf->plugin, 0, sizeof(struct mosquitto__auth_plugin)); } }