diff --git a/include/mosquitto_broker.h b/include/mosquitto_broker.h index e66cc9ed..63d7f658 100644 --- a/include/mosquitto_broker.h +++ b/include/mosquitto_broker.h @@ -56,6 +56,7 @@ enum mosquitto_plugin_event { MOSQ_EVT_MESSAGE = 7, MOSQ_EVT_PSK_KEY = 8, MOSQ_EVT_TICK = 9, + MOSQ_EVT_DISCONNECT = 10, }; /* Data for the MOSQ_EVT_RELOAD event */ @@ -152,6 +153,14 @@ struct mosquitto_evt_tick { void *future2[4]; }; +/* Data for the MOSQ_EVT_DISCONNECT event */ +struct mosquitto_evt_disconnect { + void *future; + struct mosquitto *client; + int reason; + void *future2[4]; +}; + /* Callback definition */ typedef int (*MOSQ_FUNC_generic_callback)(int, void *, void *); diff --git a/src/context.c b/src/context.c index addf418f..4159b531 100644 --- a/src/context.c +++ b/src/context.c @@ -202,6 +202,8 @@ void context__disconnect(struct mosquitto_db *db, struct mosquitto *context) return; } + plugin__handle_disconnect(db, context, -1); + net__socket_close(db, context); context__send_will(db, context); diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index d2c318c9..8d9f2cfe 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -227,15 +227,16 @@ struct mosquitto__callback{ }; struct plugin__callbacks{ - struct mosquitto__callback *reload; + struct mosquitto__callback *tick; struct mosquitto__callback *acl_check; struct mosquitto__callback *basic_auth; - struct mosquitto__callback *ext_auth_start; - struct mosquitto__callback *ext_auth_continue; struct mosquitto__callback *control; + struct mosquitto__callback *disconnect; + struct mosquitto__callback *ext_auth_continue; + struct mosquitto__callback *ext_auth_start; struct mosquitto__callback *message; - struct mosquitto__callback *tick; struct mosquitto__callback *psk_key; + struct mosquitto__callback *reload; }; struct mosquitto__security_options { @@ -802,6 +803,7 @@ void listeners__reload_all_certificates(struct mosquitto_db *db); * Plugin related functions * ============================================================ */ int plugin__load_v5(struct mosquitto__listener *listener, struct mosquitto__auth_plugin *plugin, struct mosquitto_opt *auth_options, int auth_option_count, void *lib); +void plugin__handle_disconnect(struct mosquitto_db *db, struct mosquitto *context, int reason); int plugin__handle_message(struct mosquitto_db *db, struct mosquitto *context, struct mosquitto_msg_store *stored); void LIB_ERROR(void); void plugin__handle_tick(struct mosquitto_db *db); diff --git a/src/plugin.c b/src/plugin.c index 9b127440..8b974668 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -101,6 +101,30 @@ int plugin__load_v5(struct mosquitto__listener *listener, struct mosquitto__auth } +void plugin__handle_disconnect(struct mosquitto_db *db, struct mosquitto *context, int reason) +{ + struct mosquitto_evt_disconnect event_data; + struct mosquitto__callback *cb_base; + struct mosquitto__security_options *opts; + + if(db->config->per_listener_settings){ + if(context->listener == NULL){ + return; + } + opts = &context->listener->security_options; + }else{ + opts = &db->config->security_options; + memset(&event_data, 0, sizeof(event_data)); + } + + event_data.client = context; + event_data.reason = reason; + DL_FOREACH(opts->plugin_callbacks.disconnect, cb_base){ + cb_base->cb(MOSQ_EVT_DISCONNECT, &event_data, cb_base->userdata); + } +} + + int plugin__handle_message(struct mosquitto_db *db, struct mosquitto *context, struct mosquitto_msg_store *stored) { struct mosquitto_evt_message event_data; @@ -223,6 +247,9 @@ int mosquitto_callback_register( case MOSQ_EVT_TICK: cb_base = &security_options->plugin_callbacks.tick; break; + case MOSQ_EVT_DISCONNECT: + cb_base = &security_options->plugin_callbacks.disconnect; + break; default: return MOSQ_ERR_NOT_SUPPORTED; break; @@ -290,6 +317,9 @@ int mosquitto_callback_unregister( case MOSQ_EVT_TICK: cb_base = &security_options->plugin_callbacks.tick; break; + case MOSQ_EVT_DISCONNECT: + cb_base = &security_options->plugin_callbacks.disconnect; + break; default: return MOSQ_ERR_INVAL; break;