From 8efcac05e62e5873528f3f7fc12476213c425cf6 Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Sun, 8 Mar 2026 12:49:26 +0000 Subject: [PATCH] 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);