From 8efcac05e62e5873528f3f7fc12476213c425cf6 Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Sun, 8 Mar 2026 12:49:26 +0000 Subject: [PATCH 1/2] Fix MQTT client ID collision on ARM 32-bit userland with 64-bit kernel The MQTT client ID was generated using sprintf with %ld and time(nullptr). On platforms with 32-bit userland but 64-bit kernel (such as Raspberry Pi OS and some custom Alpine Linux builds), time_t is a 64-bit long long but %ld only reads 32 bits. Since the upper 32 bits of the current Unix timestamp are zero, this always produces "MMDVMHost.0", causing client ID collisions when multiple instances or restarts occur. Replace time()-based client IDs with PID-based IDs using getpid(), which is always a 32-bit value and unique per process. Platform-guarded for Windows (_getpid) and POSIX (getpid). --- MQTTConnection.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/MQTTConnection.cpp b/MQTTConnection.cpp index c4bb87d..df009ff 100644 --- a/MQTTConnection.cpp +++ b/MQTTConnection.cpp @@ -21,7 +21,12 @@ #include #include #include -#include + +#if defined(_WIN32) || defined(_WIN64) +#include +#else +#include +#endif CMQTTConnection::CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const bool authEnabled, const std::string& username, const std::string& password, const std::vector>& subs, unsigned int keepalive, MQTT_QOS qos) : @@ -53,7 +58,11 @@ CMQTTConnection::~CMQTTConnection() bool CMQTTConnection::open() { char name[50U]; - ::sprintf(name, "MMDVMHost.%ld", ::time(nullptr)); +#if defined(_WIN32) || defined(_WIN64) + ::sprintf(name, "MMDVMHost.%u", (unsigned)::_getpid()); +#else + ::sprintf(name, "MMDVMHost.%u", (unsigned)::getpid()); +#endif ::fprintf(stdout, "MMDVMHost (%s) connecting to MQTT as %s\n", m_name.c_str(), name); From 469306ff1f96bc2fa36e7b3f2a28651ca097cb14 Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Sun, 8 Mar 2026 14:16:34 +0000 Subject: [PATCH 2/2] Add mosquitto_loop_stop before mosquitto_destroy in close() The background network thread started by mosquitto_loop_start() was not being stopped before mosquitto_destroy(), which can cause a use-after-free if the thread is still running when the mosquitto structure is freed. --- MQTTConnection.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/MQTTConnection.cpp b/MQTTConnection.cpp index df009ff..a479a69 100644 --- a/MQTTConnection.cpp +++ b/MQTTConnection.cpp @@ -147,6 +147,7 @@ void CMQTTConnection::close() { if (m_mosq != nullptr) { ::mosquitto_disconnect(m_mosq); + ::mosquitto_loop_stop(m_mosq, true); ::mosquitto_destroy(m_mosq); m_mosq = nullptr; }