blob: e99bab16c7c93b457e1b121c654c5d70456a6290 [file] [log] [blame]
Miroslav Zagorac70230c62020-12-09 16:54:31 +01001/***
2 * Copyright 2020 HAProxy Technologies
3 *
4 * This file is part of the HAProxy OpenTracing filter.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20#include "include.h"
21
22
23#ifdef DEBUG_OT
24
25/***
26 * NAME
27 * flt_ot_vars_scope_dump -
28 *
29 * ARGUMENTS
30 * vars -
31 * scope -
32 *
33 * DESCRIPTION
Miroslav Zagoracb51e94b2022-03-01 19:18:34 +010034 * Function prints the contents of all variables defined for a particular
35 * scope.
Miroslav Zagorac70230c62020-12-09 16:54:31 +010036 *
37 * RETURN VALUE
38 * This function does not return a value.
39 */
40static void flt_ot_vars_scope_dump(struct vars *vars, const char *scope)
41{
42 const struct var *var;
43
44 if (vars == NULL)
45 return;
46
Miroslav Zagorac6163e032022-02-23 18:15:56 +010047 vars_rdlock(vars);
Miroslav Zagorac70230c62020-12-09 16:54:31 +010048 list_for_each_entry(var, &(vars->head), l)
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +010049 FLT_OT_DBG(2, "'%s.%016" PRIx64 "' -> '%.*s'", scope, var->name_hash, (int)b_data(&(var->data.u.str)), b_orig(&(var->data.u.str)));
Miroslav Zagorac6163e032022-02-23 18:15:56 +010050 vars_rdunlock(vars);
Miroslav Zagorac70230c62020-12-09 16:54:31 +010051}
52
53
54/***
55 * NAME
56 * flt_ot_vars_dump -
57 *
58 * ARGUMENTS
59 * s -
60 *
61 * DESCRIPTION
Miroslav Zagoracb51e94b2022-03-01 19:18:34 +010062 * Function prints the contents of all variables grouped by individual
63 * scope.
Miroslav Zagorac70230c62020-12-09 16:54:31 +010064 *
65 * RETURN VALUE
66 * This function does not return a value.
67 */
68void flt_ot_vars_dump(struct stream *s)
69{
70 FLT_OT_FUNC("%p", s);
71
72 /*
73 * It would be nice if we could use the get_vars() function from HAProxy
74 * source here to get the value of the 'vars' pointer, but it is defined
75 * as 'static inline', so unfortunately none of this is possible.
76 */
Willy Tarreaucfc4f242021-05-08 11:41:28 +020077 flt_ot_vars_scope_dump(&(proc_vars), "PROC");
Miroslav Zagorac70230c62020-12-09 16:54:31 +010078 flt_ot_vars_scope_dump(&(s->sess->vars), "SESS");
79 flt_ot_vars_scope_dump(&(s->vars_txn), "TXN");
80 flt_ot_vars_scope_dump(&(s->vars_reqres), "REQ/RES");
81
82 FLT_OT_RETURN();
83}
84
85#endif /* DEBUG_OT */
86
87
88/***
89 * NAME
Miroslav Zagorac854efef2022-03-01 18:41:36 +010090 * flt_ot_smp_init -
91 *
92 * ARGUMENTS
93 * s -
94 * smp -
95 * opt -
96 * type -
97 * data -
98 *
99 * DESCRIPTION
100 * The function initializes the value of the 'smp' structure. If the 'data'
101 * argument is set, then the 'sample_data' member of the 'smp' structure is
102 * also initialized.
103 *
104 * RETURN VALUE
105 * This function does not return a value.
106 */
107static inline void flt_ot_smp_init(struct stream *s, struct sample *smp, uint opt, int type, const char *data)
108{
109 (void)memset(smp, 0, sizeof(*smp));
110 (void)smp_set_owner(smp, s->be, s->sess, s, opt | SMP_OPT_FINAL);
111
112 if (data != NULL) {
113 smp->data.type = type;
114
115 chunk_initstr(&(smp->data.u.str), data);
116 }
117}
118
119
120/***
121 * NAME
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100122 * flt_ot_smp_add -
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100123 *
124 * ARGUMENTS
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100125 * data -
126 * blk -
127 * len -
128 * err -
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100129 *
130 * DESCRIPTION
131 * -
132 *
133 * RETURN VALUE
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100134 * -
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100135 */
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100136static int flt_ot_smp_add(struct sample_data *data, const char *name, size_t len, char **err)
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100137{
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100138 bool flag_alloc = 0;
139 int retval = FLT_OT_RET_ERROR;
140
141 FLT_OT_FUNC("%p, \"%.*s\", %zu, %p:%p", data, (int)len, name, len, FLT_OT_DPTR_ARGS(err));
142
143 FLT_OT_DBG_BUF(2, &(data->u.str));
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100144
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100145 if (b_orig(&(data->u.str)) == NULL) {
146 data->type = SMP_T_BIN;
147 chunk_init(&(data->u.str), FLT_OT_MALLOC(global.tune.bufsize), global.tune.bufsize);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100148
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100149 flag_alloc = (b_orig(&(data->u.str)) != NULL);
150 }
151
152 if (b_orig(&(data->u.str)) == NULL) {
153 FLT_OT_ERR("failed to add ctx '%.*s', not enough memory", (int)len, name);
154 }
155 else if (len > ((UINT64_C(1) << ((sizeof(FLT_OT_VAR_CTX_SIZE) << 3) - 1)) - 1)) {
156 FLT_OT_ERR("failed to add ctx '%.*s', too long name", (int)len, name);
157 }
158 else if ((len + sizeof(FLT_OT_VAR_CTX_SIZE)) > b_room(&(data->u.str))) {
159 FLT_OT_ERR("failed to add ctx '%.*s', too many names", (int)len, name);
160 }
161 else {
162 retval = b_data(&(data->u.str));
163
164 b_putchr(&(data->u.str), len);
165 (void)__b_putblk(&(data->u.str), name, len);
166
167 FLT_OT_DBG_BUF(2, &(data->u.str));
168 }
169
170 if ((retval == FLT_OT_RET_ERROR) && flag_alloc)
171 FLT_OT_FREE(b_orig(&(data->u.str)));
172
173 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100174}
175
176
177/***
178 * NAME
179 * flt_ot_normalize_name -
180 *
181 * ARGUMENTS
182 * var_name -
183 * size -
184 * len -
185 * name -
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100186 * flag_cpy -
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100187 * err -
188 *
189 * DESCRIPTION
190 * -
191 *
192 * RETURN VALUE
193 * -
194 */
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100195static int flt_ot_normalize_name(char *var_name, size_t size, int *len, const char *name, bool flag_cpy, char **err)
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100196{
197 int retval = 0;
198
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100199 FLT_OT_FUNC("%p, %zu, %p, \"%s\", %hhu, %p:%p", var_name, size, len, name, flag_cpy, FLT_OT_DPTR_ARGS(err));
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100200
201 if (!FLT_OT_STR_ISVALID(name))
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100202 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100203
204 /*
205 * In case the name of the variable consists of several elements,
206 * the character '.' is added between them.
207 */
208 if ((*len == 0) || (var_name[*len - 1] == '.'))
209 /* Do nothing. */;
210 else if (*len < (size - 1))
211 var_name[(*len)++] = '.';
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100212 else {
213 FLT_OT_ERR("failed to normalize variable name, buffer too small");
214
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100215 retval = -1;
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100216 }
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100217
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100218 if (flag_cpy) {
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100219 /* Copy variable name without modification. */
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100220 retval = strlen(name);
221 if ((*len + retval + 1) > size) {
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100222 FLT_OT_ERR("failed to normalize variable name, buffer too small");
223
224 retval = -1;
225 } else {
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100226 (void)memcpy(var_name + *len, name, retval + 1);
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100227
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100228 *len += retval;
229 }
230 } else {
231 /*
232 * HAProxy does not allow the use of variable names containing '-'
233 * or ' '. This of course applies to HTTP header names as well.
234 * Also, here the capital letters are converted to lowercase.
235 */
236 while (retval != -1)
237 if (*len >= (size - 1)) {
238 FLT_OT_ERR("failed to normalize variable name, buffer too small");
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100239
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100240 retval = -1;
241 } else {
242 uint8_t ch = name[retval];
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100243
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100244 if (ch == '\0')
245 break;
246 else if (ch == '-')
247 ch = FLT_OT_VAR_CHAR_DASH;
248 else if (ch == ' ')
249 ch = FLT_OT_VAR_CHAR_SPACE;
250 else if (isupper(ch))
251 ch = ist_lc[ch];
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100252
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100253 var_name[(*len)++] = ch;
254 retval++;
255 }
256
257 var_name[*len] = '\0';
258 }
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100259
260 FLT_OT_DBG(3, "var_name: \"%s\" %d/%d", var_name, retval, *len);
261
262 if (retval == -1)
263 *len = retval;
264
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100265 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100266}
267
268
269/***
270 * NAME
271 * flt_ot_var_name -
272 *
273 * ARGUMENTS
274 * scope -
275 * prefix -
276 * name -
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100277 * flag_cpy -
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100278 * var_name -
279 * size -
280 * err -
281 *
282 * DESCRIPTION
Miroslav Zagoracb51e94b2022-03-01 19:18:34 +0100283 * The function initializes the value of the 'smp' structure. If the 'data'
284 * argument is set, then the 'sample_data' member of the 'smp' structure is
285 * also initialized.
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100286 *
287 * RETURN VALUE
288 * -
289 */
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100290static int flt_ot_var_name(const char *scope, const char *prefix, const char *name, bool flag_cpy, char *var_name, size_t size, char **err)
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100291{
292 int retval = 0;
293
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100294 FLT_OT_FUNC("\"%s\", \"%s\", \"%s\", %hhu, %p, %zu, %p:%p", scope, prefix, name, flag_cpy, var_name, size, FLT_OT_DPTR_ARGS(err));
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100295
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100296 if (flt_ot_normalize_name(var_name, size, &retval, scope, 0, err) >= 0)
297 if (flt_ot_normalize_name(var_name, size, &retval, prefix, 0, err) >= 0)
298 (void)flt_ot_normalize_name(var_name, size, &retval, name, flag_cpy, err);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100299
300 if (retval == -1)
301 FLT_OT_ERR("failed to construct variable name '%s.%s.%s'", scope, prefix, name);
302
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100303 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100304}
305
306
307/***
308 * NAME
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100309 * flt_ot_ctx_loop -
310 *
311 * ARGUMENTS
312 * smp -
313 * scope -
314 * prefix -
315 * err -
316 * func -
317 * ptr -
318 *
319 * DESCRIPTION
320 * -
321 *
322 * RETURN VALUE
323 * -
324 */
325static int flt_ot_ctx_loop(struct sample *smp, const char *scope, const char *prefix, char **err, flt_ot_ctx_loop_cb func, void *ptr)
326{
327 FLT_OT_VAR_CTX_SIZE var_ctx_size;
328 char var_name[BUFSIZ], var_ctx[BUFSIZ];
329 int i, var_name_len, var_ctx_len, rc, n = 1, retval = 0;
330
331 FLT_OT_FUNC("%p, \"%s\", \"%s\", %p:%p, %p, %p", smp, scope, prefix, FLT_OT_DPTR_ARGS(err), func, ptr);
332
333 /*
334 * The variable in which we will save the name of the OpenTracing
335 * context variable.
336 */
337 var_name_len = flt_ot_var_name(scope, prefix, NULL, 0, var_name, sizeof(var_name), err);
338 if (var_name_len == -1)
339 FLT_OT_RETURN_INT(FLT_OT_RET_ERROR);
340
341 /*
342 * Here we will try to find all the previously recorded variables from
343 * the currently set OpenTracing context. If we find the required
344 * variable and it is marked as deleted, we will mark it as active.
345 * If we do not find it, then it is added to the end of the previously
346 * saved names.
347 */
348 if (vars_get_by_name(var_name, var_name_len, smp, NULL) == 0) {
349 FLT_OT_DBG(2, "ctx '%s' no variable found", var_name);
350 }
351 else if (smp->data.type != SMP_T_BIN) {
352 FLT_OT_ERR("ctx '%s' invalid data type %d", var_name, smp->data.type);
353
354 retval = FLT_OT_RET_ERROR;
355 }
356 else {
357 FLT_OT_DBG_BUF(2, &(smp->data.u.str));
358
359 for (i = 0; i < b_data(&(smp->data.u.str)); i += sizeof(var_ctx_size) + var_ctx_len, n++) {
360 var_ctx_size = *((typeof(var_ctx_size) *)(b_orig(&(smp->data.u.str)) + i));
361 var_ctx_len = abs(var_ctx_size);
362
363 if ((i + sizeof(var_ctx_size) + var_ctx_len) > b_data(&(smp->data.u.str))) {
364 FLT_OT_ERR("ctx '%s' invalid data size", var_name);
365
366 retval = FLT_OT_RET_ERROR;
367
368 break;
369 }
370
371 (void)memcpy(var_ctx, b_orig(&(smp->data.u.str)) + i + sizeof(var_ctx_size), var_ctx_len);
372 var_ctx[var_ctx_len] = '\0';
373
374 rc = func(smp, i, scope, prefix, var_ctx, var_ctx_size, err, ptr);
375 if (rc == FLT_OT_RET_ERROR) {
376 retval = FLT_OT_RET_ERROR;
377
378 break;
379 }
380 else if (rc > 0) {
381 retval = n;
382
383 break;
384 }
385 }
386 }
387
388 FLT_OT_RETURN_INT(retval);
389}
390
391
392/***
393 * NAME
394 * flt_ot_ctx_set_cb -
395 *
396 * ARGUMENTS
397 * smp -
398 * idx -
399 * scope -
400 * prefix -
401 * name -
402 * name_len -
403 * err -
404 * ptr -
405 *
406 * DESCRIPTION
407 * -
408 *
409 * RETURN VALUE
410 * -
411 */
412static int flt_ot_ctx_set_cb(struct sample *smp, size_t idx, const char *scope, const char *prefix, const char *name, FLT_OT_VAR_CTX_SIZE name_len, char **err, void *ptr)
413{
414 struct flt_ot_ctx *ctx = ptr;
415 int retval = 0;
416
417 FLT_OT_FUNC("%p, %zu, \"%s\", \"%s\", \"%s\", %hhd, %p:%p, %p", smp, idx, scope, prefix, name, name_len, FLT_OT_DPTR_ARGS(err), ptr);
418
419 if ((name_len == ctx->value_len) && (strncmp(name, ctx->value, name_len) == 0)) {
420 FLT_OT_DBG(2, "ctx '%s' found\n", name);
421
422 retval = 1;
423 }
424
425 FLT_OT_RETURN_INT(retval);
426}
427
428
429/***
430 * NAME
431 * flt_ot_ctx_set -
432 *
433 * ARGUMENTS
434 * s -
435 * scope -
436 * prefix -
437 * name -
438 * opt -
439 * err -
440 *
441 * DESCRIPTION
442 * -
443 *
444 * RETURN VALUE
445 * -
446 */
447static int flt_ot_ctx_set(struct stream *s, const char *scope, const char *prefix, const char *name, uint opt, char **err)
448{
449 struct flt_ot_ctx ctx;
450 struct sample smp_ctx;
451 char var_name[BUFSIZ];
452 bool flag_alloc = 0;
453 int rc, var_name_len, retval = FLT_OT_RET_ERROR;
454
455 FLT_OT_FUNC("%p, \"%s\", \"%s\", \"%s\", %u, %p:%p", s, scope, prefix, name, opt, FLT_OT_DPTR_ARGS(err));
456
457 /*
458 * The variable in which we will save the name of the OpenTracing
459 * context variable.
460 */
461 var_name_len = flt_ot_var_name(scope, prefix, NULL, 0, var_name, sizeof(var_name), err);
462 if (var_name_len == -1)
463 FLT_OT_RETURN_INT(retval);
464
465 /* Normalized name of the OpenTracing context variable. */
466 ctx.value_len = flt_ot_var_name(name, NULL, NULL, 0, ctx.value, sizeof(ctx.value), err);
467 if (ctx.value_len == -1)
468 FLT_OT_RETURN_INT(retval);
469
470 flt_ot_smp_init(s, &smp_ctx, opt, 0, NULL);
471
472 retval = flt_ot_ctx_loop(&smp_ctx, scope, prefix, err, flt_ot_ctx_set_cb, &ctx);
473 if (retval == 0) {
474 rc = flt_ot_smp_add(&(smp_ctx.data), ctx.value, ctx.value_len, err);
475 if (rc == FLT_OT_RET_ERROR)
476 retval = FLT_OT_RET_ERROR;
477
478 flag_alloc = (rc == 0);
479 }
480
481 if (retval == FLT_OT_RET_ERROR) {
482 /* Do nothing. */
483 }
484 else if (retval > 0) {
485 FLT_OT_DBG(2, "ctx '%s' data found", ctx.value);
486 }
487 else if (vars_set_by_name_ifexist(var_name, var_name_len, &smp_ctx) == 0) {
488 FLT_OT_ERR("failed to set ctx '%s'", var_name);
489
490 retval = FLT_OT_RET_ERROR;
491 }
492 else {
493 FLT_OT_DBG(2, "ctx '%s' -> '%.*s' set", var_name, (int)b_data(&(smp_ctx.data.u.str)), b_orig(&(smp_ctx.data.u.str)));
494
495 retval = b_data(&(smp_ctx.data.u.str));
496 }
497
498 if (flag_alloc)
499 FLT_OT_FREE(b_orig(&(smp_ctx.data.u.str)));
500
501 FLT_OT_RETURN_INT(retval);
502}
503
504
505/***
506 * NAME
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100507 * flt_ot_var_register -
508 *
509 * ARGUMENTS
510 * scope -
511 * prefix -
512 * name -
513 * err -
514 *
515 * DESCRIPTION
516 * -
517 *
518 * RETURN VALUE
519 * -
520 */
521int flt_ot_var_register(const char *scope, const char *prefix, const char *name, char **err)
522{
523 struct arg arg;
524 char var_name[BUFSIZ];
Miroslav Zagoracaec19a72022-03-01 18:44:36 +0100525 int retval = -1, var_name_len;
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100526
527 FLT_OT_FUNC("\"%s\", \"%s\", \"%s\", %p:%p", scope, prefix, name, FLT_OT_DPTR_ARGS(err));
528
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100529 var_name_len = flt_ot_var_name(scope, prefix, name, 0, var_name, sizeof(var_name), err);
Miroslav Zagoracaec19a72022-03-01 18:44:36 +0100530 if (var_name_len == -1)
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100531 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100532
533 /* Set <size> to 0 to not release var_name memory in vars_check_arg(). */
534 (void)memset(&arg, 0, sizeof(arg));
535 arg.type = ARGT_STR;
536 arg.data.str.area = var_name;
Miroslav Zagoracaec19a72022-03-01 18:44:36 +0100537 arg.data.str.data = var_name_len;
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100538
539 if (vars_check_arg(&arg, err) == 0) {
540 FLT_OT_ERR_APPEND("failed to register variable '%s': %s", var_name, *err);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100541 } else {
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100542 FLT_OT_DBG(2, "variable '%s' registered", var_name);
Miroslav Zagoracaec19a72022-03-01 18:44:36 +0100543
544 retval = var_name_len;
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100545 }
546
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100547 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100548}
549
550
551/***
552 * NAME
553 * flt_ot_var_set -
554 *
555 * ARGUMENTS
556 * s -
557 * scope -
558 * prefix -
559 * name -
560 * value -
561 * opt -
562 * err -
563 *
564 * DESCRIPTION
565 * -
566 *
567 * RETURN VALUE
568 * -
569 */
570int flt_ot_var_set(struct stream *s, const char *scope, const char *prefix, const char *name, const char *value, uint opt, char **err)
571{
572 struct sample smp;
573 char var_name[BUFSIZ];
Miroslav Zagoracaec19a72022-03-01 18:44:36 +0100574 int retval = -1, var_name_len;
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100575
576 FLT_OT_FUNC("%p, \"%s\", \"%s\", \"%s\", \"%s\", %u, %p:%p", s, scope, prefix, name, value, opt, FLT_OT_DPTR_ARGS(err));
577
Miroslav Zagoracb536cec2022-03-02 00:15:23 +0100578 var_name_len = flt_ot_var_name(scope, prefix, name, 0, var_name, sizeof(var_name), err);
Miroslav Zagoracaec19a72022-03-01 18:44:36 +0100579 if (var_name_len == -1)
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100580 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100581
Miroslav Zagorac854efef2022-03-01 18:41:36 +0100582 flt_ot_smp_init(s, &smp, opt, SMP_T_STR, value);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100583
Miroslav Zagoracaec19a72022-03-01 18:44:36 +0100584 if (vars_set_by_name_ifexist(var_name, var_name_len, &smp) == 0) {
Miroslav Zagorac728627f2022-03-01 18:42:54 +0100585 FLT_OT_ERR("failed to set variable '%s'", var_name);
Miroslav Zagorac728627f2022-03-01 18:42:54 +0100586 } else {
587 FLT_OT_DBG(2, "variable '%s' set", var_name);
Miroslav Zagoracaec19a72022-03-01 18:44:36 +0100588
589 retval = var_name_len;
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100590
591 if (strcmp(scope, FLT_OT_VARS_SCOPE) == 0)
592 retval = flt_ot_ctx_set(s, scope, prefix, name, opt, err);
593 }
594
595 FLT_OT_RETURN_INT(retval);
596}
597
598
599/***
600 * NAME
601 * flt_ot_vars_unset_cb -
602 *
603 * ARGUMENTS
604 * smp -
605 * idx -
606 * scope -
607 * prefix -
608 * name -
609 * name_len -
610 * err -
611 * ptr -
612 *
613 * DESCRIPTION
614 * -
615 *
616 * RETURN VALUE
617 * -
618 */
619static int flt_ot_vars_unset_cb(struct sample *smp, size_t idx, const char *scope, const char *prefix, const char *name, FLT_OT_VAR_CTX_SIZE name_len, char **err, void *ptr)
620{
621 struct sample smp_ctx;
622 char var_ctx[BUFSIZ];
623 int var_ctx_len, retval = FLT_OT_RET_ERROR;
624
625 FLT_OT_FUNC("%p, %zu, \"%s\", \"%s\", \"%s\", %hhd, %p:%p, %p", smp, idx, scope, prefix, name, name_len, FLT_OT_DPTR_ARGS(err), ptr);
626
627 var_ctx_len = flt_ot_var_name(scope, prefix, name, 1, var_ctx, sizeof(var_ctx), err);
628 if (var_ctx_len == -1) {
629 FLT_OT_ERR("ctx '%s' invalid", name);
630
631 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac728627f2022-03-01 18:42:54 +0100632 }
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100633
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100634 flt_ot_smp_init(smp->strm, &smp_ctx, smp->opt, 0, NULL);
635
636 if (vars_unset_by_name_ifexist(var_ctx, var_ctx_len, &smp_ctx) == 0) {
637 FLT_OT_ERR("ctx '%s' no variable found", var_ctx);
638 } else {
639 FLT_OT_DBG(2, "ctx '%s' unset", var_ctx);
640
641 retval = 0;
642 }
643
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100644 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100645}
646
647
648/***
649 * NAME
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100650 * flt_ot_vars_unset -
651 *
652 * ARGUMENTS
653 * s -
654 * scope -
655 * prefix -
656 * opt -
657 * err -
658 *
659 * DESCRIPTION
660 * -
661 *
662 * RETURN VALUE
663 * -
664 */
665int flt_ot_vars_unset(struct stream *s, const char *scope, const char *prefix, uint opt, char **err)
666{
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100667 struct sample smp_ctx;
668 char var_name[BUFSIZ];
669 int var_name_len, retval;
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100670
671 FLT_OT_FUNC("%p, \"%s\", \"%s\", %u, %p:%p", s, scope, prefix, opt, FLT_OT_DPTR_ARGS(err));
672
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100673 flt_ot_smp_init(s, &smp_ctx, opt, 0, NULL);
674
675 retval = flt_ot_ctx_loop(&smp_ctx, scope, prefix, err, flt_ot_vars_unset_cb, NULL);
676 if (retval != FLT_OT_RET_ERROR) {
677 /*
678 * After all ctx variables have been unset, the variable used
679 * to store their names should also be unset.
680 */
681 var_name_len = flt_ot_var_name(scope, prefix, NULL, 0, var_name, sizeof(var_name), err);
682 if (var_name_len == -1)
683 FLT_OT_RETURN_INT(FLT_OT_RET_ERROR);
684
685 flt_ot_smp_init(s, &smp_ctx, opt, 0, NULL);
686
687 if (vars_unset_by_name_ifexist(var_name, var_name_len, &smp_ctx) == 0) {
688 FLT_OT_DBG(2, "variable '%s' not found", var_name);
689 } else {
690 FLT_OT_DBG(2, "variable '%s' unset", var_name);
691
692 retval = 1;
693 }
694 }
695
696 FLT_OT_RETURN_INT(retval);
697}
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100698
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100699
700/***
701 * NAME
702 * flt_ot_vars_get_cb -
703 *
704 * ARGUMENTS
705 * smp -
706 * idx -
707 * scope -
708 * prefix -
709 * name -
710 * name_len -
711 * err -
712 * ptr -
713 *
714 * DESCRIPTION
715 * -
716 *
717 * RETURN VALUE
718 * -
719 */
720static int flt_ot_vars_get_cb(struct sample *smp, size_t idx, const char *scope, const char *prefix, const char *name, FLT_OT_VAR_CTX_SIZE name_len, char **err, void *ptr)
721{
722 struct otc_text_map **map = ptr;
723 struct sample smp_ctx;
724 char var_ctx[BUFSIZ], ot_var_name[BUFSIZ], ch;
725 int var_ctx_len, ot_var_name_len, retval = FLT_OT_RET_ERROR;
726
727 FLT_OT_FUNC("%p, %zu, \"%s\", \"%s\", \"%s\", %hhd, %p:%p, %p", smp, idx, scope, prefix, name, name_len, FLT_OT_DPTR_ARGS(err), ptr);
728
729 var_ctx_len = flt_ot_var_name(scope, prefix, name, 1, var_ctx, sizeof(var_ctx), err);
730 if (var_ctx_len == -1) {
731 FLT_OT_ERR("ctx '%s' invalid", name);
732
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100733 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100734 }
735
736 flt_ot_smp_init(smp->strm, &smp_ctx, smp->opt, 0, NULL);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100737
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100738 if (vars_get_by_name(var_ctx, var_ctx_len, &smp_ctx, NULL) != 0) {
739 FLT_OT_DBG(2, "'%s' -> '%.*s'", var_ctx, (int)b_data(&(smp_ctx.data.u.str)), b_orig(&(smp_ctx.data.u.str)));
740
741 if (*map == NULL) {
742 *map = otc_text_map_new(NULL, 8);
743 if (*map == NULL) {
744 FLT_OT_ERR("failed to create map data");
745
746 FLT_OT_RETURN_INT(FLT_OT_RET_ERROR);
747 }
748 }
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100749
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100750 /*
751 * Eh, because the use of some characters is not allowed
752 * in the variable name, the conversion of the replaced
753 * characters to the original is performed here.
754 */
755 for (ot_var_name_len = 0; (ch = name[ot_var_name_len]) != '\0'; ot_var_name_len++)
756 if (ot_var_name_len >= (FLT_OT_TABLESIZE(ot_var_name) - 1)) {
757 FLT_OT_ERR("failed to reverse variable name, buffer too small");
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100758
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100759 otc_text_map_destroy(map, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100760
761 break;
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100762 } else {
763 ot_var_name[ot_var_name_len] = (ch == FLT_OT_VAR_CHAR_DASH) ? '-' : ((ch == FLT_OT_VAR_CHAR_SPACE) ? ' ' : ch);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100764 }
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100765 ot_var_name[ot_var_name_len] = '\0';
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100766
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100767 if (*map == NULL) {
768 retval = FLT_OT_RET_ERROR;
769 }
770 else if (otc_text_map_add(*map, ot_var_name, ot_var_name_len, b_orig(&(smp_ctx.data.u.str)), b_data(&(smp_ctx.data.u.str)), OTC_TEXT_MAP_DUP_KEY | OTC_TEXT_MAP_DUP_VALUE) == -1) {
771 FLT_OT_ERR("failed to add map data");
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100772
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100773 otc_text_map_destroy(map, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100774
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100775 retval = FLT_OT_RET_ERROR;
776 }
777 else {
778 retval = 0;
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100779 }
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100780 } else {
781 FLT_OT_DBG(2, "ctx '%s' no variable found", var_ctx);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100782 }
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100783
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100784 FLT_OT_RETURN_INT(retval);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100785}
786
787
788/***
789 * NAME
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100790 * flt_ot_vars_get -
791 *
792 * ARGUMENTS
793 * s -
794 * scope -
795 * prefix -
796 * opt -
797 * err -
798 *
799 * DESCRIPTION
800 * -
801 *
802 * RETURN VALUE
803 * -
804 */
805struct otc_text_map *flt_ot_vars_get(struct stream *s, const char *scope, const char *prefix, uint opt, char **err)
806{
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100807 struct sample smp_ctx;
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100808 struct otc_text_map *retptr = NULL;
809
810 FLT_OT_FUNC("%p, \"%s\", \"%s\", %u, %p:%p", s, scope, prefix, opt, FLT_OT_DPTR_ARGS(err));
811
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100812 flt_ot_smp_init(s, &smp_ctx, opt, 0, NULL);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100813
Miroslav Zagorac52c2ec32022-03-10 00:03:24 +0100814 (void)flt_ot_ctx_loop(&smp_ctx, scope, prefix, err, flt_ot_vars_get_cb, &retptr);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100815
816 ot_text_map_show(retptr);
817
818 if ((retptr != NULL) && (retptr->count == 0)) {
819 FLT_OT_DBG(2, "WARNING: no variables found");
820
821 otc_text_map_destroy(&retptr, OTC_TEXT_MAP_FREE_KEY | OTC_TEXT_MAP_FREE_VALUE);
822 }
823
Miroslav Zagoracca09e012022-03-04 09:56:00 +0100824 FLT_OT_RETURN_PTR(retptr);
Miroslav Zagorac70230c62020-12-09 16:54:31 +0100825}
826
827/*
828 * Local variables:
829 * c-indent-level: 8
830 * c-basic-offset: 8
831 * End:
832 *
833 * vi: noexpandtab shiftwidth=8 tabstop=8
834 */