Add mosquitto_kick_client_by_clientid()
and mosquitto_kick_client_by_username()
These can be used by plugins to disconnect clients.
This commit is contained in:
parent
3f1515e337
commit
f0862e26ec
@ -18,6 +18,8 @@ Broker:
|
||||
plugins to determine which version of MQTT a client has connected with.
|
||||
- Send DISCONNECT with `malformed-packet` reason code on invalid PUBLISH,
|
||||
SUBSCRIBE, and UNSUBSCRIBE packets.
|
||||
- Add `mosquitto_kick_client_by_clientid()` and `mosquitto_kick_client_by_username()`
|
||||
functions, which can be used by plugins to disconnect clients.
|
||||
|
||||
Client library:
|
||||
- Client no longer generates random client ids for v3.1.1 clients, these are
|
||||
|
@ -101,6 +101,7 @@ enum mosq_err_t {
|
||||
MOSQ_ERR_TIMEOUT = 27,
|
||||
MOSQ_ERR_RETAIN_NOT_SUPPORTED = 28,
|
||||
MOSQ_ERR_TOPIC_ALIAS_INVALID = 29,
|
||||
MOSQ_ERR_ADMINISTRATIVE_ACTION = 30,
|
||||
};
|
||||
|
||||
/* Option values */
|
||||
|
@ -9,6 +9,8 @@ _mosquitto_client_protocol
|
||||
_mosquitto_client_protocol_version
|
||||
_mosquitto_client_sub_count
|
||||
_mosquitto_client_username
|
||||
_mosquitto_kick_client_by_clientid
|
||||
_mosquitto_kick_client_by_username
|
||||
_mosquitto_log_printf
|
||||
_mosquitto_property_add_binary
|
||||
_mosquitto_property_add_byte
|
||||
|
@ -10,6 +10,8 @@
|
||||
mosquitto_client_protocol_version;
|
||||
mosquitto_client_sub_count;
|
||||
mosquitto_client_username;
|
||||
mosquitto_kick_client_by_clientid;
|
||||
mosquitto_kick_client_by_username;
|
||||
mosquitto_log_printf;
|
||||
mosquitto_plugin_publish;
|
||||
mosquitto_property_add_binary;
|
||||
|
@ -300,12 +300,19 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context, int reaso
|
||||
case MOSQ_ERR_KEEPALIVE:
|
||||
log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s has exceeded timeout, disconnecting.", id);
|
||||
break;
|
||||
case MOSQ_ERR_ADMINISTRATIVE_ACTION:
|
||||
log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s been disconnected by administrative action.", id);
|
||||
break;
|
||||
default:
|
||||
log__printf(NULL, MOSQ_LOG_NOTICE, "Socket error on client %s, disconnecting.", id);
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", id);
|
||||
if(reason == MOSQ_ERR_ADMINISTRATIVE_ACTION){
|
||||
log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s been disconnected by administrative action.", id);
|
||||
}else{
|
||||
log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
mux__delete(db, context);
|
||||
|
@ -179,6 +179,46 @@ const char *mosquitto_client_username(const struct mosquitto *client);
|
||||
int mosquitto_set_username(struct mosquitto *client, const char *username);
|
||||
|
||||
|
||||
/* =========================================================================
|
||||
*
|
||||
* Client control
|
||||
*
|
||||
* ========================================================================= */
|
||||
|
||||
/* Function: mosquitto_kick_client_by_clientid
|
||||
*
|
||||
* Forcefully disconnect a client from the broker.
|
||||
*
|
||||
* If clientid != NULL, then the client with the matching client id is
|
||||
* disconnected from the broker.
|
||||
* If clientid == NULL, then all clients are disconnected from the broker.
|
||||
*
|
||||
* If with_will == true, then if the client has a Last Will and Testament
|
||||
* defined then this will be sent. If false, the LWT will not be sent.
|
||||
*/
|
||||
int mosquitto_kick_client_by_clientid(const char *clientid, bool with_will);
|
||||
|
||||
/* Function: mosquitto_kick_client_by_username
|
||||
*
|
||||
* Forcefully disconnect a client from the broker.
|
||||
*
|
||||
* If username != NULL, then all clients with a matching username are kicked
|
||||
* from the broker.
|
||||
* If username == NULL, then all clients that do not have a username are
|
||||
* kicked.
|
||||
*
|
||||
* If with_will == true, then if the client has a Last Will and Testament
|
||||
* defined then this will be sent. If false, the LWT will not be sent.
|
||||
*/
|
||||
int mosquitto_kick_client_by_username(const char *username, bool with_will);
|
||||
|
||||
|
||||
/* =========================================================================
|
||||
*
|
||||
* Publishing functions
|
||||
*
|
||||
* ========================================================================= */
|
||||
|
||||
/* Function: mosquitto_broker_publish
|
||||
*
|
||||
* Publish a message from within a plugin.
|
||||
|
59
src/plugin.c
59
src/plugin.c
@ -20,6 +20,9 @@ Contributors:
|
||||
#include "mosquitto_internal.h"
|
||||
#include "mosquitto_broker.h"
|
||||
#include "memory_mosq.h"
|
||||
#include "mqtt_protocol.h"
|
||||
#include "send_mosq.h"
|
||||
#include "util_mosq.h"
|
||||
#include "utlist.h"
|
||||
|
||||
#ifdef WITH_TLS
|
||||
@ -230,3 +233,59 @@ int mosquitto_set_username(struct mosquitto *client, const char *username)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void disconnect_client(struct mosquitto_db *db, struct mosquitto *context, bool with_will)
|
||||
{
|
||||
if(context->protocol == mosq_p_mqtt5){
|
||||
send__disconnect(context, MQTT_RC_ADMINISTRATIVE_ACTION, NULL);
|
||||
}
|
||||
if(with_will == false){
|
||||
mosquitto__set_state(context, mosq_cs_disconnecting);
|
||||
}
|
||||
do_disconnect(db, context, MOSQ_ERR_ADMINISTRATIVE_ACTION);
|
||||
}
|
||||
|
||||
int mosquitto_kick_client_by_clientid(const char *clientid, bool with_will)
|
||||
{
|
||||
struct mosquitto_db *db;
|
||||
struct mosquitto *ctxt, *ctxt_tmp;
|
||||
|
||||
db = mosquitto__get_db();
|
||||
if(clientid == NULL){
|
||||
HASH_ITER(hh_sock, db->contexts_by_sock, ctxt, ctxt_tmp){
|
||||
disconnect_client(db, ctxt, with_will);
|
||||
}
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
HASH_FIND(hh_id, db->contexts_by_id, clientid, strlen(clientid), ctxt);
|
||||
if(ctxt){
|
||||
disconnect_client(db, ctxt, with_will);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return MOSQ_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mosquitto_kick_client_by_username(const char *username, bool with_will)
|
||||
{
|
||||
struct mosquitto_db *db;
|
||||
struct mosquitto *ctxt, *ctxt_tmp;
|
||||
|
||||
db = mosquitto__get_db();
|
||||
|
||||
if(username == NULL){
|
||||
HASH_ITER(hh_sock, db->contexts_by_sock, ctxt, ctxt_tmp){
|
||||
if(ctxt->username == NULL){
|
||||
disconnect_client(db, ctxt, with_will);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
HASH_ITER(hh_sock, db->contexts_by_sock, ctxt, ctxt_tmp){
|
||||
if(ctxt->username != NULL && !strcmp(ctxt->username, username)){
|
||||
disconnect_client(db, ctxt, with_will);
|
||||
}
|
||||
}
|
||||
}
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user