Fix packet timeout handling (#20766)
Fix packet timeout handling in MQTT client
Stelios Fragkakis committed
Aug 6, 2025 at 08:05 UTC
d78d68f9b47d68406d132ee9993ec8ae13bc8bb2
1 file changed
+8
-6
src/aclk/mqtt_websockets/mqtt_ng.c
+8
-6
@@ -802,18 +802,20 @@ static void remove_packet_from_timeout_monitor_list(struct mqtt_ng_client *clien
802
spinlock_unlock(&client->pending_packets.spinlock);
803
}
804
805
+#define PACKET_TIMEOUT_EPOCH (1704067200L) // Jan 1, 2024 00:00:00 UTC
806
+
807
static void add_packet_to_timeout_monitor_list(struct mqtt_ng_client *client, uint16_t packet_id)
808
{
809
spinlock_lock(&client->pending_packets.spinlock);
810
time_t now = now_realtime_sec();
811
// Add it to the JudyL array
810
- time_t *Pvalue = (time_t *) JudyLIns(&client->pending_packets.JudyL, (Word_t) packet_id, PJE0);
812
+ uint32_t *Pvalue = (uint32_t *) JudyLIns(&client->pending_packets.JudyL, (Word_t) packet_id, PJE0);
813
if (!Pvalue || Pvalue == PJERR) {
814
nd_log(NDLS_DAEMON, NDLP_ERR, "Error inserting packet_id (%" PRIu16 ") into JudyL array.", packet_id);
815
spinlock_unlock(&client->pending_packets.spinlock);
816
return;
817
}
816
- *Pvalue = now + PACKET_ACK_TIMEOUT_SECS;
818
+ *Pvalue = (uint32_t) ((now - PACKET_TIMEOUT_EPOCH) + PACKET_ACK_TIMEOUT_SECS);
819
spinlock_unlock(&client->pending_packets.spinlock);
820
}
821
@@ -1189,12 +1191,12 @@ static void check_packet_monitor_list_for_timeouts(struct mqtt_ng_client *client
1191
{
1192
spinlock_lock(&client->pending_packets.spinlock);
1193
bool first_then_next = true;
1192
- time_t *Pvalue;
1194
+ uint32_t *Pvalue;
1195
Word_t packet_id = 0;
1196
time_t now = now_realtime_sec();
1195
- while ((Pvalue = (time_t *) JudyLFirstThenNext(client->pending_packets.JudyL, &packet_id, &first_then_next))) {
1196
- time_t expire_time = *Pvalue;
1197
- if (now >= expire_time) {
1197
+ while ((Pvalue = (uint32_t *) JudyLFirstThenNext(client->pending_packets.JudyL, &packet_id, &first_then_next))) {
1198
+ uint32_t expire_time_delta = *Pvalue;
1199
+ if (now >= (PACKET_TIMEOUT_EPOCH + expire_time_delta)) {
1200
spinlock_unlock(&client->pending_packets.spinlock);
1201
(void) mark_packet_acked(client, (uint16_t) packet_id);
1202
spinlock_lock(&client->pending_packets.spinlock);