@cryptotaxi247 / netdata-1 / commits / f28263326

Implements cloud initiated disconnect command (#11723)

Timotej S committed Nov 9, 2021 at 13:42 UTC f2826332672c2486c643ffcc5ecf67c647491cde
10 files changed +91 -5
CMakeLists.txt
+1
@@ -1135,6 +1135,7 @@ endfunction()
1135
1136 set(ACLK_NG_PROTO_DEFS
1137 aclk/aclk-schemas/proto/aclk/v1/lib.proto
1138 + aclk/aclk-schemas/proto/agent/v1/disconnect.proto
1139 aclk/aclk-schemas/proto/agent/v1/connection.proto
1140 aclk/aclk-schemas/proto/alarm/v1/config.proto
1141 aclk/aclk-schemas/proto/alarm/v1/stream.proto
Makefile.am
+7
@@ -680,6 +680,7 @@ ACLK_NG_FILES += \
680
681 ACLK_NG_PROTO_DEFINITIONS = \
682 aclk/aclk-schemas/proto/aclk/v1/lib.proto \
683 + aclk/aclk-schemas/proto/agent/v1/disconnect.proto \
684 aclk/aclk-schemas/proto/agent/v1/connection.proto \
685 aclk/aclk-schemas/proto/alarm/v1/config.proto \
686 aclk/aclk-schemas/proto/alarm/v1/stream.proto \
@@ -710,6 +711,8 @@ ACLK_NG_PROTO_BUILT_FILES = aclk/aclk-schemas/proto/agent/v1/connection.pb.cc \
711 aclk/aclk-schemas/proto/chart/v1/config.pb.h \
712 aclk/aclk-schemas/proto/aclk/v1/lib.pb.cc \
713 aclk/aclk-schemas/proto/aclk/v1/lib.pb.h \
714 + aclk/aclk-schemas/proto/agent/v1/disconnect.pb.cc \
715 + aclk/aclk-schemas/proto/agent/v1/disconnect.pb.h \
716 aclk/aclk-schemas/proto/alarm/v1/config.pb.cc \
717 aclk/aclk-schemas/proto/alarm/v1/config.pb.h \
718 aclk/aclk-schemas/proto/alarm/v1/stream.pb.cc \
@@ -754,6 +757,10 @@ aclk/aclk-schemas/proto/aclk/v1/lib.pb.cc \
757 aclk/aclk-schemas/proto/aclk/v1/lib.pb.h: aclk/aclk-schemas/proto/aclk/v1/lib.proto
758 $(PROTOC) -I=aclk/aclk-schemas --cpp_out=$(builddir)/aclk/aclk-schemas $^
759
760 +aclk/aclk-schemas/proto/agent/v1/disconnect.pb.cc \
761 +aclk/aclk-schemas/proto/agent/v1/disconnect.pb.h: aclk/aclk-schemas/proto/agent/v1/disconnect.proto
762 + $(PROTOC) -I=aclk/aclk-schemas --cpp_out=$(builddir)/aclk/aclk-schemas $^
763 +
764 aclk/aclk-schemas/proto/alarm/v1/config.pb.cc \
765 aclk/aclk-schemas/proto/alarm/v1/config.pb.h: aclk/aclk-schemas/proto/alarm/v1/config.proto
766 $(PROTOC) -I=aclk/aclk-schemas --cpp_out=$(builddir)/aclk/aclk-schemas $^
aclk/aclk-schemas
+1 -1
@@ -1 +1 @@
1 -Subproject commit ff110970c006170b01b51a15bf6cdc219ce1dcf5
1 +Subproject commit 72d0a600dccf965b939a1ae4f7818d0ac896842a
aclk/aclk.c
+14 -2
@@ -24,6 +24,7 @@
24 #define ACLK_STABLE_TIMEOUT 3 // Minimum delay to mark AGENT as stable
25
26 int aclk_pubacks_per_conn = 0; // How many PubAcks we got since MQTT conn est.
27 +int disconnect_req = 0;
28
29 int aclk_alert_reloaded = 1; //1 on startup, and again on health_reload
30
@@ -218,7 +219,7 @@ static void msg_callback(const char *topic, const void *msg, size_t msglen, int
219 error("Received message on unexpected topic %s", topic);
220
221 if (aclk_shared_state.mqtt_shutdown_msg_id > 0) {
221 - error("Link is shutting down. Ignoring message.");
222 + error("Link is shutting down. Ignoring incoming message.");
223 return;
224 }
225
@@ -234,7 +235,7 @@ static void msg_callback_new(const char *topic, const void *msg, size_t msglen,
235 debug(D_ACLK, "Got Message From Broker Topic \"%s\" QOS %d", topic, qos);
236
237 if (aclk_shared_state.mqtt_shutdown_msg_id > 0) {
237 - error("Link is shutting down. Ignoring message.");
238 + error("Link is shutting down. Ignoring incoming message.");
239 return;
240 }
241
@@ -293,6 +294,8 @@ static int read_query_thread_count()
294 return threads;
295 }
296
297 +void aclk_graceful_disconnect(mqtt_wss_client client);
298 +
299 /* Keeps connection alive and handles all network comms.
300 * Returns on error or when netdata is shutting down.
301 * @param client instance of mqtt_wss_client
@@ -310,6 +313,15 @@ static int handle_connection(mqtt_wss_client client)
313 return 1;
314 }
315
316 + if (disconnect_req) {
317 + disconnect_req = 0;
318 + aclk_graceful_disconnect(client);
319 + aclk_queue_unlock();
320 + aclk_shared_state.mqtt_shutdown_msg_id = -1;
321 + aclk_shared_state.mqtt_shutdown_msg_rcvd = 0;
322 + return 1;
323 + }
324 +
325 // mqtt_wss_service will return faster than in one second
326 // if there is enough work to do
327 time_t now = now_monotonic_sec();
aclk/aclk.h
+2
@@ -12,6 +12,8 @@
12
13 extern time_t aclk_block_until;
14
15 +extern int disconnect_req;
16 +
17 extern aclk_env_t *aclk_env;
18
19 void *aclk_main(void *ptr);
aclk/aclk_query_queue.c
+7
@@ -193,3 +193,10 @@ void aclk_queue_lock(void)
193 aclk_query_queue.block_push = 1;
194 ACLK_QUEUE_UNLOCK;
195 }
196 +
197 +void aclk_queue_unlock(void)
198 +{
199 + ACLK_QUEUE_LOCK;
200 + aclk_query_queue.block_push = 0;
201 + ACLK_QUEUE_UNLOCK;
202 +}
aclk/aclk_query_queue.h
+1
@@ -91,6 +91,7 @@ aclk_query_t aclk_queue_pop(void);
91 void aclk_queue_flush(void);
92
93 void aclk_queue_lock(void);
94 +void aclk_queue_unlock(void);
95
96 #define QUEUE_IF_PAYLOAD_PRESENT(query) \
97 if (likely(query->data.bin_payload.payload)) { \
aclk/aclk_rx_msgs.c
+18
@@ -416,6 +416,24 @@ void aclk_handle_new_cloud_msg(const char *message_type, const char *msg, size_t
416 destroy_send_alarm_snapshot(sas);
417 return;
418 }
419 + if (!strcmp(message_type, "DisconnectReq")) {
420 + struct disconnect_cmd *cmd = parse_disconnect_cmd(msg, msg_len);
421 + if (!cmd)
422 + return;
423 + if (cmd->permaban) {
424 + error ("Cloud Banned This Agent!");
425 + aclk_disable_runtime = 1;
426 + }
427 + info ("Cloud requested disconnect (EC=%u, \"%s\")", (unsigned int)cmd->error_code, cmd->error_description);
428 + if (cmd->reconnect_after_s > 0) {
429 + aclk_block_until = now_monotonic_sec() + cmd->reconnect_after_s;
430 + info ("Cloud asks not to reconnect for %u seconds. We shall honor that request", (unsigned int)cmd->reconnect_after_s);
431 + }
432 + disconnect_req = 1;
433 + freez(cmd->error_description);
434 + freez(cmd);
435 + return;
436 + }
437 error ("Unknown new cloud arch message type received \"%s\"", message_type);
438 }
439 #endif
aclk/schema-wrappers/connection.cc
+31 -2
@@ -1,6 +1,7 @@
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "proto/agent/v1/connection.pb.h"
4 +#include "proto/agent/v1/disconnect.pb.h"
5 #include "connection.h"
6
7 #include "schema_wrapper_utils.h"
@@ -8,15 +9,17 @@
9 #include <sys/time.h>
10 #include <stdlib.h>
11
12 +using namespace agent::v1;
13 +
14 char *generate_update_agent_connection(size_t *len, const update_agent_connection_t *data)
15 {
13 - agent::v1::UpdateAgentConnection connupd;
16 + UpdateAgentConnection connupd;
17
18 connupd.set_claim_id(data->claim_id);
19 connupd.set_reachable(data->reachable);
20 connupd.set_session_id(data->session_id);
21
19 - connupd.set_update_source((data->lwt) ? agent::v1::CONNECTION_UPDATE_SOURCE_LWT : agent::v1::CONNECTION_UPDATE_SOURCE_AGENT);
22 + connupd.set_update_source((data->lwt) ? CONNECTION_UPDATE_SOURCE_LWT : CONNECTION_UPDATE_SOURCE_AGENT);
23
24 struct timeval tv;
25 gettimeofday(&tv, NULL);
@@ -32,3 +35,29 @@ char *generate_update_agent_connection(size_t *len, const update_agent_connectio
35
36 return msg;
37 }
38 +
39 +struct disconnect_cmd *parse_disconnect_cmd(const char *data, size_t len) {
40 + DisconnectReq req;
41 + struct disconnect_cmd *res;
42 +
43 + if (!req.ParseFromArray(data, len))
44 + return NULL;
45 +
46 + res = (struct disconnect_cmd *)calloc(1, sizeof(struct disconnect_cmd));
47 +
48 + if (!res)
49 + return NULL;
50 +
51 + res->reconnect_after_s = req.reconnect_after_seconds();
52 + res->permaban = req.permaban();
53 + res->error_code = req.error_code();
54 + if (req.error_description().c_str()) {
55 + res->error_description = strdup(req.error_description().c_str());
56 + if (!res->error_description) {
57 + free(res);
58 + return NULL;
59 + }
60 + }
61 +
62 + return res;
63 +}
aclk/schema-wrappers/connection.h
+9
@@ -27,6 +27,15 @@ typedef struct {
27
28 char *generate_update_agent_connection(size_t *len, const update_agent_connection_t *data);
29
30 +struct disconnect_cmd {
31 + uint64_t reconnect_after_s;
32 + int permaban;
33 + uint32_t error_code;
34 + char *error_description;
35 +};
36 +
37 +struct disconnect_cmd *parse_disconnect_cmd(const char *data, size_t len);
38 +
39 #ifdef __cplusplus
40 }
41 #endif