master
c 187 lines 6.63 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "stream.h"
4 #include "stream-receiver-internals.h"
5 #include "stream-sender-internals.h"
6
7 static STREAM_CAPABILITIES globally_disabled_capabilities = STREAM_CAP_ALWAYS_DISABLED;
8
9 static struct {
10 STREAM_CAPABILITIES cap;
11 const char *str;
12 } capability_names[] = {
13 // DO NOT CHANGE NAMES
14 // THEY ARE USED BY STREAM_PATH, SO CONNECTING OF DIFFERENT NODES WILL BREAK
15
16 {STREAM_CAP_V1, "V1" },
17 {STREAM_CAP_V2, "V2" },
18 {STREAM_CAP_VN, "VN" },
19 {STREAM_CAP_VCAPS, "VCAPS" },
20 {STREAM_CAP_HLABELS, "HLABELS" },
21 {STREAM_CAP_CLAIM, "CLAIM" },
22 {STREAM_CAP_CLABELS, "CLABELS" },
23 {STREAM_CAP_LZ4, "LZ4" },
24 {STREAM_CAP_FUNCTIONS, "FUNCTIONS" },
25 {STREAM_CAP_REPLICATION, "REPLICATION" },
26 {STREAM_CAP_BINARY, "BINARY" },
27 {STREAM_CAP_INTERPOLATED, "INTERPOLATED" },
28 {STREAM_CAP_IEEE754, "IEEE754" },
29 {STREAM_CAP_DATA_WITH_ML, "ML"}, // do not remove this - stream_path fails to parse old nodes
30 {STREAM_CAP_ML_MODELS, "MLMODELS" },
31 {STREAM_CAP_DYNCFG, "DYNCFG" },
32 {STREAM_CAP_SLOTS, "SLOTS" },
33 {STREAM_CAP_ZSTD, "ZSTD" },
34 {STREAM_CAP_GZIP, "GZIP" },
35 {STREAM_CAP_BROTLI, "BROTLI" },
36 {STREAM_CAP_PROGRESS, "PROGRESS" },
37 {STREAM_CAP_NODE_ID, "NODEID" },
38 {STREAM_CAP_PATHS, "PATHS" },
39 {STREAM_CAP_FLOAT_BASELINE, "FLOATBASELINE" },
40
41 // terminator
42 {0 , NULL },
43 };
44
45 STREAM_CAPABILITIES stream_capabilities_parse_one(const char *str) {
46 if (!str || !*str)
47 return STREAM_CAP_NONE;
48
49 for (size_t i = 0; capability_names[i].str; i++) {
50 if (strcmp(capability_names[i].str, str) == 0)
51 return capability_names[i].cap;
52 }
53
54 return STREAM_CAP_NONE;
55 }
56
57 void stream_capabilities_to_string(BUFFER *wb, STREAM_CAPABILITIES caps) {
58 for(size_t i = 0; capability_names[i].str ; i++) {
59 if(caps & capability_names[i].cap) {
60 buffer_strcat(wb, capability_names[i].str);
61 buffer_strcat(wb, " ");
62 }
63 }
64 }
65
66 void stream_capabilities_to_json_array(BUFFER *wb, STREAM_CAPABILITIES caps, const char *key) {
67 if(key)
68 buffer_json_member_add_array(wb, key);
69 else
70 buffer_json_add_array_item_array(wb);
71
72 for(size_t i = 0; capability_names[i].str ; i++) {
73 if(caps & capability_names[i].cap)
74 buffer_json_add_array_item_string(wb, capability_names[i].str);
75 }
76
77 buffer_json_array_close(wb);
78 }
79
80 void log_receiver_capabilities(struct receiver_state *rpt) {
81 BUFFER *wb = buffer_create(100, NULL);
82 stream_capabilities_to_string(wb, rpt->capabilities);
83
84 nd_log_daemon(NDLP_INFO, "STREAM RCV '%s' [from [%s]:%s]: established link with negotiated capabilities: %s",
85 rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port, buffer_tostring(wb));
86
87 buffer_free(wb);
88 }
89
90 void log_sender_capabilities(struct sender_state *s) {
91 BUFFER *wb = buffer_create(100, NULL);
92 stream_capabilities_to_string(wb, s->capabilities);
93
94 nd_log_daemon(NDLP_INFO, "STREAM SND '%s' [to %s]: established link with negotiated capabilities: %s",
95 rrdhost_hostname(s->host), s->remote_ip, buffer_tostring(wb));
96
97 buffer_free(wb);
98 }
99
100 STREAM_CAPABILITIES stream_our_capabilities(RRDHOST *host, bool sender) {
101 STREAM_CAPABILITIES disabled_capabilities = globally_disabled_capabilities;
102
103 if(host && sender) {
104 // we have DATA_WITH_ML capability
105 // we should remove the DATA_WITH_ML capability if our database does not have anomaly info
106 // this can happen under these conditions: 1. we don't run ML, and 2. we don't receive ML
107 rrdhost_receiver_lock(host);
108
109 if (!ml_host_running(host) && !stream_has_capability(host->receiver, STREAM_CAP_ML_MODELS))
110 disabled_capabilities |= STREAM_CAP_ML_MODELS;
111
112 rrdhost_receiver_unlock(host);
113
114 if(host->sender)
115 disabled_capabilities |= host->sender->disabled_capabilities;
116 }
117
118 // if(sender) {
119 // if(nd_profile.stream_sender_compression == ND_COMPRESSION_FASTEST)
120 // // lz4 or nothing
121 // disabled_capabilities |= (STREAM_CAP_COMPRESSIONS_AVAILABLE & ~(STREAM_CAP_LZ4_AVAILABLE));
122 // }
123
124 return (STREAM_CAP_V1 |
125 STREAM_CAP_V2 |
126 STREAM_CAP_VN |
127 STREAM_CAP_VCAPS |
128 STREAM_CAP_HLABELS |
129 STREAM_CAP_CLAIM |
130 STREAM_CAP_CLABELS |
131 STREAM_CAP_FUNCTIONS |
132 STREAM_CAP_REPLICATION |
133 STREAM_CAP_BINARY |
134 STREAM_CAP_INTERPOLATED |
135 STREAM_CAP_SLOTS |
136 STREAM_CAP_PROGRESS |
137 STREAM_CAP_COMPRESSIONS_AVAILABLE |
138 STREAM_CAP_DYNCFG |
139 STREAM_CAP_NODE_ID |
140 STREAM_CAP_PATHS |
141 STREAM_CAP_IEEE754 |
142 STREAM_CAP_ML_MODELS |
143 STREAM_CAP_FLOAT_BASELINE |
144 0) & ~disabled_capabilities;
145 }
146
147 STREAM_CAPABILITIES convert_stream_version_to_capabilities(int32_t version, RRDHOST *host, bool sender) {
148 STREAM_CAPABILITIES caps = 0;
149
150 if(version <= 1) caps = STREAM_CAP_V1;
151 else if(version < STREAM_OLD_VERSION_CLAIM) caps = STREAM_CAP_V2 | STREAM_CAP_HLABELS;
152 else if(version <= STREAM_OLD_VERSION_CLAIM) caps = STREAM_CAP_VN | STREAM_CAP_HLABELS | STREAM_CAP_CLAIM;
153 else if(version <= STREAM_OLD_VERSION_CLABELS) caps = STREAM_CAP_VN | STREAM_CAP_HLABELS | STREAM_CAP_CLAIM | STREAM_CAP_CLABELS;
154 else if(version <= STREAM_OLD_VERSION_LZ4) caps = STREAM_CAP_VN | STREAM_CAP_HLABELS | STREAM_CAP_CLAIM | STREAM_CAP_CLABELS | STREAM_CAP_LZ4_AVAILABLE;
155 else caps = version;
156
157 if(caps & STREAM_CAP_VCAPS)
158 caps &= ~(STREAM_CAP_V1|STREAM_CAP_V2|STREAM_CAP_VN);
159
160 if(caps & STREAM_CAP_VN)
161 caps &= ~(STREAM_CAP_V1|STREAM_CAP_V2);
162
163 if(caps & STREAM_CAP_V2)
164 caps &= ~(STREAM_CAP_V1);
165
166 STREAM_CAPABILITIES common_caps = caps & stream_our_capabilities(host, sender);
167
168 if(!(common_caps & STREAM_CAP_INTERPOLATED))
169 // DATA WITH ML requires INTERPOLATED
170 common_caps &= ~(STREAM_CAP_ML_MODELS);
171
172 return common_caps;
173 }
174
175 int32_t stream_capabilities_to_vn(uint32_t caps) {
176 if(caps & STREAM_CAP_LZ4) return STREAM_OLD_VERSION_LZ4;
177 if(caps & STREAM_CAP_CLABELS) return STREAM_OLD_VERSION_CLABELS;
178 return STREAM_OLD_VERSION_CLAIM; // if(caps & STREAM_CAP_CLAIM)
179 }
180
181 void check_local_streaming_capabilities(void) {
182 ieee754_doubles = is_system_ieee754_double();
183 if(!ieee754_doubles)
184 globally_disabled_capabilities |= STREAM_CAP_IEEE754;
185 else
186 globally_disabled_capabilities &= ~STREAM_CAP_IEEE754;
187 }