From 50a3567335861c7ec0a218e30d30275efc4d6518 Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Sun, 8 Mar 2026 12:51:36 +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 a client ID ending in .0, causing collisions when multiple instances or restarts occur. Replace time()-based client IDs with PID-based IDs using getpid(), which is always a portable 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 c102bf1..f1f6164 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) : m_host(host), @@ -52,7 +57,11 @@ CMQTTConnection::~CMQTTConnection() bool CMQTTConnection::open() { char name[50U]; - ::sprintf(name, "DMRGateway.%ld", ::time(nullptr)); +#if defined(_WIN32) || defined(_WIN64) + ::sprintf(name, "DMRGateway.%u", (unsigned)::_getpid()); +#else + ::sprintf(name, "DMRGateway.%u", (unsigned)::getpid()); +#endif ::fprintf(stdout, "DMRGateway (%s) connecting to MQTT as %s\n", m_name.c_str(), name);