@cryptotaxi247 / netdata-1 / commits / 59119aae4

Fix MQTT packet ACK (#21416)

invalidate sending_frag when marking messages for garbage collection

Stelios Fragkakis committed Dec 8, 2025 at 22:23 UTC 59119aae4b0983c4acf3f212da8c1f2104f5474b
1 file changed +23
src/aclk/mqtt_websockets/mqtt_ng.c
+23
@@ -1177,6 +1177,20 @@ static void mark_message_for_gc(struct buffer_fragment *frag)
1177 }
1178 }
1179
1180 +// Check if sending_frag points to any fragment in the message starting at msg_head
1181 +static bool sending_frag_in_message(struct transaction_buffer *buf, struct buffer_fragment *msg_head)
1182 +{
1183 + struct buffer_fragment *frag = msg_head;
1184 + while (frag) {
1185 + if (buf->sending_frag == frag)
1186 + return true;
1187 + if (frag->flags & BUFFER_FRAG_MQTT_PACKET_TAIL)
1188 + return false;
1189 + frag = frag->next;
1190 + }
1191 + return false;
1192 +}
1193 +
1194 static int mark_packet_acked(struct mqtt_ng_client *client, uint16_t packet_id)
1195 {
1196 size_t reclaimable = 0;
@@ -1196,6 +1210,12 @@ static int mark_packet_acked(struct mqtt_ng_client *client, uint16_t packet_id)
1210 usec_t latency = now_monotonic_usec() - frag->sent_monotonic_ut;
1211 pulse_aclk_sent_message_acked(latency, frag->len);
1212 __atomic_store_n(&publish_latency, latency, __ATOMIC_RELEASE);
1213 +
1214 + // Invalidate sending_frag if it points to any fragment in this message
1215 + // since mark_message_for_gc will free the data
1216 + if (sending_frag_in_message(&client->main_buffer, frag))
1217 + client->main_buffer.sending_frag = NULL;
1218 +
1219 mark_message_for_gc(frag);
1220
1221 size_t used = BUFFER_BYTES_USED(&client->main_buffer.hdr_buffer);
@@ -2096,6 +2116,9 @@ int handle_incoming_traffic(struct mqtt_ng_client *client)
2116 worker_is_busy(WORKER_ACLK_CPT_CONNACK);
2117
2118 LOCK_HDR_BUFFER(&client->main_buffer);
2119 + // Invalidate sending_frag if it points to any fragment in the CONNECT message
2120 + if (sending_frag_in_message(&client->main_buffer, client->connect_msg))
2121 + client->main_buffer.sending_frag = NULL;
2122 mark_message_for_gc(client->connect_msg);
2123 UNLOCK_HDR_BUFFER(&client->main_buffer);
2124