net: mqtt: Reset client state before notifying MQTT_EVT_DISCONNECT
MQTT client state is protected using mutex. That mutex however is temporarily unlocked when calling event callbacks. This means that in client_disconnect() transport can already be disconnected, but without marking it as such in client->internal.state. When mutex is unlocked in event_notify() function, then there are two possible paths of failure: 1) First possibility is when RX and TX are called from two separate threads, so that the other thread gets resumed and functions like verify_tx_state() (e.g. in mqtt_publish()) allow to continue communication over disconnected medium. 2) Another possibility is that user calls mqtt_abort() or mqtt_disconnect() in event handler. In both cases MQTT library tries to send or receive data, possibly followed by second close() of underlying file descriptor. Prevent using disconnected transport by clearing MQTT client state right after calling mqtt_transport_disconnect(), without releasing mutex, even for a while. Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
This commit is contained in:
parent
5fd53dcd8a
commit
9a791dd6bb
|
@ -56,6 +56,9 @@ static void client_disconnect(struct mqtt_client *client, int result,
|
|||
MQTT_ERR("Failed to disconnect transport!");
|
||||
}
|
||||
|
||||
/* Reset internal state. */
|
||||
client_reset(client);
|
||||
|
||||
if (notify) {
|
||||
struct mqtt_evt evt = {
|
||||
.type = MQTT_EVT_DISCONNECT,
|
||||
|
@ -65,9 +68,6 @@ static void client_disconnect(struct mqtt_client *client, int result,
|
|||
/* Notify application. */
|
||||
event_notify(client, &evt);
|
||||
}
|
||||
|
||||
/* Reset internal state. */
|
||||
client_reset(client);
|
||||
}
|
||||
|
||||
static int client_connect(struct mqtt_client *client)
|
||||
|
|
Loading…
Reference in a new issue