Re: [PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-13 Thread Miroslav Zagorac

Hello Tim,

On 09/11/2021 12:09 AM, Tim Düsterhus wrote:

The programming style in OT is not what I'm used to, but if I understand
it correctly then maybe istmatchi() is what you are searching for (it
matches prefixes which should be what you are doing manually)?



yes, this function could be used instead of strncasecmp().  However, it
doesn't seem optimized to me and is certainly faster than strncasecmp()
for simple cases for strings where the difference is right at the
beginning.  Already after comparing strings longer than 4 characters
(and the first 4 are the same), the function is slower than
strncasecmp() and the duration of the function increases rapidly while
the processing time of the function strncasecmp() is quite stable).

I’m not writing this to start some deeper discussion, this is purely
informative.  :)

Best regards,

--
Miroslav Zagorac
Senior Developer



Re: [PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-12 Thread Miroslav Zagorac

Hello Willy,

On 09/12/2021 08:11 AM, Willy Tarreau wrote:

thanks for working on fixing this, it's now merged. I've added a
tiny change to make sure that text_map is always initialized in
flt_ot_scope_run() because that made clang rightfully upset,
re-enabled OT in the CI since it's now OK.


Right, it's necessary, I overlooked it and the gcc didn't object.

Thanks.

--
Zaga

What can change the nature of a man?



Re: [PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-12 Thread Willy Tarreau
Hi guys,

thanks for working on fixing this, it's now merged. I've added a
tiny change to make sure that text_map is always initialized in
flt_ot_scope_run() because that made clang rightfully upset,
re-enabled OT in the CI since it's now OK.

Cheers,
Willy



Re: [PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-10 Thread Tim Düsterhus

Miroslav,

On 9/10/21 11:52 PM, Miroslav Zagorac wrote:

Hello Tim,

On 09/10/2021 10:55 PM, Tim Düsterhus wrote:

If it's not a NULL pointer then it must be a valid pointer. I don't
quite understand why you would need to replace this by an empty constant
string then? Is this about a missing NUL terminator? Otherwise a valid
pointer with .len == 0 would be equivalent to "".



No, v.ptr is not a null pointer and points to the wrong location, v.len
is equal to 0.

For example I added to the source two calls to the printf () function,
one before the htx_get_blk_value() function call and the other after:

-
printf(">>> n = { %p '%s' %zu }, v = { %p '%s' %zu }\n", n.ptr, n.ptr,
n.len, v.ptr, v.ptr, v.len);

v = htx_get_blk_value(htx, blk);

printf(">>> v = { %p '%s' %zu }\n", v.ptr, v.ptr, v.len);
-

I intentionally did not write the string format as '%.*s' so that the
contents can be seen.  These two headers are treated here:

1, 'ot-ctx-uberctx-haproxy_id: '
2. 'ot-ctx-uber-trace-id: 3c4069d777e89019:3c4069d777e89019:0:1'

, and this is the result:

1st header:
  >>> n = { 0x56079098bec1
'ot-ctx-uberctx-haproxy_idot-ctx-uber-trace-id3c4069d777e89019:3c4069d777e89019:0:1'
25 }, v = { (nil) '(null)' 0 }
  >>> v = { 0x56079098beda
'ot-ctx-uber-trace-id3c4069d777e89019:3c4069d777e89019:0:1' 0 }

As can be seen from the example, v.ptr = 0x56079098beda, v.len = 0.


This looks correct to me. The value points to the location right behind 
the name of the header and has length 0. The header is empty, thus the 
'v' is empty as well, as indicated by v.len == 0. Thus accessing any 
byte of this zero-size "buffer" is effectively undefined behavior.



2nd header:
  >>> n = { 0x56079098beda
'ot-ctx-uber-trace-id3c4069d777e89019:3c4069d777e89019:0:1' 20 }, v = {
(nil) '(null)' 0 }
  >>> v = { 0x56079098beee '3c4069d777e89019:3c4069d777e89019:0:1' 37 }


This also looks correct to me.


Maybe I use htx_get_blk_name()/htx_get_blk_value() in this function in
an inappropriate way, so I get such a result.


Unrelated to that: Having worked quite a bit with the ist API I would
generally recommend using the helper functions in ist.h (possibly adding
new ones if they are helpful) instead of directly touching the struct.
It makes refactoring much easier, because it's easy to find the function
calls vs. accessing struct members which might be available on different
structs.

As an example in flt_ot_http_headers_get you could use an ist for prefix
and then simply use isteqi() instead of strncasecmp().


The functions strncasecmp() and isteqi() are not compatible, because
isteqi() requires that the lengths of the strings being compared are
equal, whereas in this function that is not the case.  In addition, the
prefix and len should be put in the ist structure and n.len reduced to
the size of len, this is an unnecessary complication.


You are right of course. For some reason I thought you wanted to compare 
for equality and used the 'n' variant because they strings are not NUL 
terminated.


The programming style in OT is not what I'm used to, but if I understand 
it correctly then maybe istmatchi() is what you are searching for (it 
matches prefixes which should be what you are doing manually)?


Best regards
Tim Düsterhus



Re: [PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-10 Thread Miroslav Zagorac

Hello Tim,

On 09/10/2021 10:55 PM, Tim Düsterhus wrote:

If it's not a NULL pointer then it must be a valid pointer. I don't
quite understand why you would need to replace this by an empty constant
string then? Is this about a missing NUL terminator? Otherwise a valid
pointer with .len == 0 would be equivalent to "".



No, v.ptr is not a null pointer and points to the wrong location, v.len
is equal to 0.

For example I added to the source two calls to the printf () function,
one before the htx_get_blk_value() function call and the other after:

-
printf(">>> n = { %p '%s' %zu }, v = { %p '%s' %zu }\n", n.ptr, n.ptr, 
n.len, v.ptr, v.ptr, v.len);


v = htx_get_blk_value(htx, blk);

printf(">>> v = { %p '%s' %zu }\n", v.ptr, v.ptr, v.len);
-

I intentionally did not write the string format as '%.*s' so that the
contents can be seen.  These two headers are treated here:

1, 'ot-ctx-uberctx-haproxy_id: '
2. 'ot-ctx-uber-trace-id: 3c4069d777e89019:3c4069d777e89019:0:1'

, and this is the result:

1st header:
>>> n = { 0x56079098bec1 
'ot-ctx-uberctx-haproxy_idot-ctx-uber-trace-id3c4069d777e89019:3c4069d777e89019:0:1' 
25 }, v = { (nil) '(null)' 0 }
>>> v = { 0x56079098beda 
'ot-ctx-uber-trace-id3c4069d777e89019:3c4069d777e89019:0:1' 0 }


As can be seen from the example, v.ptr = 0x56079098beda, v.len = 0.

2nd header:
>>> n = { 0x56079098beda 
'ot-ctx-uber-trace-id3c4069d777e89019:3c4069d777e89019:0:1' 20 }, v = { 
(nil) '(null)' 0 }

>>> v = { 0x56079098beee '3c4069d777e89019:3c4069d777e89019:0:1' 37 }

Maybe I use htx_get_blk_name()/htx_get_blk_value() in this function in
an inappropriate way, so I get such a result.


Unrelated to that: Having worked quite a bit with the ist API I would
generally recommend using the helper functions in ist.h (possibly adding
new ones if they are helpful) instead of directly touching the struct.
It makes refactoring much easier, because it's easy to find the function
calls vs. accessing struct members which might be available on different
structs.

As an example in flt_ot_http_headers_get you could use an ist for prefix
and then simply use isteqi() instead of strncasecmp().


The functions strncasecmp() and isteqi() are not compatible, because
isteqi() requires that the lengths of the strings being compared are
equal, whereas in this function that is not the case.  In addition, the
prefix and len should be put in the ist structure and n.len reduced to
the size of len, this is an unnecessary complication.



 > Of course, it could look like this:
 >
 > if (v.len == 0)
 > v.ptr = "" /* or v = ist("") */;
 >

In your example I would prefer v = ist("") over v.ptr = "" and leave the
heavy lifting up to the compiler for that reason.



Ok, I will use ist("").

Best regards,

--
Zaga

What can change the nature of a man?



Re: [PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-10 Thread Tim Düsterhus

Miroslav,

On 9/10/21 8:08 PM, Miroslav Zagorac wrote:

the problem is that in this case after calling the function
htx_get_blk_value(), v.ptr is not a NULL pointer but v.len is equal
to 0, if the http header has no value.



If it's not a NULL pointer then it must be a valid pointer. I don't 
quite understand why you would need to replace this by an empty constant 
string then? Is this about a missing NUL terminator? Otherwise a valid 
pointer with .len == 0 would be equivalent to "".


-

Unrelated to that: Having worked quite a bit with the ist API I would 
generally recommend using the helper functions in ist.h (possibly adding 
new ones if they are helpful) instead of directly touching the struct. 
It makes refactoring much easier, because it's easy to find the function 
calls vs. accessing struct members which might be available on different 
structs.


As an example in flt_ot_http_headers_get you could use an ist for prefix 
and then simply use isteqi() instead of strncasecmp().


> Of course, it could look like this:
>
> if (v.len == 0)
>  v.ptr = "" /* or v = ist("") */;
>

In your example I would prefer v = ist("") over v.ptr = "" and leave the 
heavy lifting up to the compiler for that reason.


Best regards
Tim Düsterhus



Re: [PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-10 Thread Miroslav Zagorac

On 09/10/2021 07:18 PM, Tim Düsterhus wrote:

Patch 2 looks odd to me. Is the issue that .ptr is equal to NULL and
*that* is causing issues? Then I recommend the following instead:

if (!isttest(v))
v = ist("");

this is much cleaner, because it does not attempt to cram so much logic
into that single huge line.

In any case if the issue is a NULL then you must test for that NULL
instead of testing the length.


Hello Tim,

the problem is that in this case after calling the function
htx_get_blk_value(), v.ptr is not a NULL pointer but v.len is equal
to 0, if the http header has no value.

Of course, it could look like this:

if (v.len == 0)
   v.ptr = "" /* or v = ist("") */;


Best regards,

--
Zaga

What can change the nature of a man?



Re: [PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-10 Thread Tim Düsterhus

Miroslav,

On 9/10/21 12:31 PM, Miroslav Zagorac wrote:

I am sending 4 patches that revert to the opentracing filter function,
with the possibility of using haproxy variables to transfer the
opentracing context excluded.


Patch 2 looks odd to me. Is the issue that .ptr is equal to NULL and 
*that* is causing issues? Then I recommend the following instead:


if (!isttest(v))
  v = ist("");

this is much cleaner, because it does not attempt to cram so much logic 
into that single huge line.


In any case if the issue is a NULL then you must test for that NULL 
instead of testing the length.


Best regards
Tim Düsterhus



[PATCH] BUILD: opentracing: excluded use of haproxy variables for, OpenTracing context

2021-09-10 Thread Miroslav Zagorac

Hello all,

I am sending 4 patches that revert to the opentracing filter function, 
with the possibility of using haproxy variables to transfer the 
opentracing context excluded.


Work with haproxy variables will be functional in the foreseeable 
future, when the necessary changes are made in the source of the 
opentracing filter.


For a more detailed explanation of the changes you can see the 
description of the attached patches.



Source build with OpenTracing filter support on github can be enabled.


Willy, thank you for your understanding and patience.

--
Zaga

What can change the nature of a man?
>From 77fb9a98a82c72bd0696412e5d04425d2431a951 Mon Sep 17 00:00:00 2001
From: Miroslav Zagorac 
Date: Wed, 8 Sep 2021 20:56:05 +0200
Subject: [PATCH 1/4] BUILD: opentracing: exclude the use of haproxy variables
 for the OpenTracing context

Due to a recent change in the handling of haproxy variables, their use for
OpenTracing context transfer has been excluded from the compilation process.

The use of variables can be re-enabled if the newly defined variable
OT_USE_VARS is set to 1 when calling the 'make' utility.  However,
this should not be used for now as the compilation will end in error.

This change prevents the use of haproxy variables to convey the OpenTracing
context.  This means that the 'use-vars' parameter cannot be used in the
OpenTracing filter configuration for 'inject' and 'extract' operations.

An example configuration that uses this feature is in the test/ctx
directory, while the script to run that test is test/run-ctx.sh.

Then, the 'sess.ot.uuid' variable is no longer set when initializing the
OpenTracing session.  This means that this variable can still be used in
the OpenTracing configuration, but its contents will be empty.
---
 Makefile   |  1 +
 addons/ot/Makefile |  8 +++-
 addons/ot/include/filter.h |  2 +-
 addons/ot/include/parser.h | 19 +--
 addons/ot/src/event.c  |  6 ++
 addons/ot/src/filter.c |  2 ++
 addons/ot/src/parser.c |  4 
 addons/ot/src/scope.c  | 12 ++--
 8 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index d0a7862b6..38412275c 100644
--- a/Makefile
+++ b/Makefile
@@ -107,6 +107,7 @@
 #   OT_INC : force the include path to libopentracing-c-wrapper
 #   OT_LIB : force the lib path to libopentracing-c-wrapper
 #   OT_RUNPATH : add RUNPATH for libopentracing-c-wrapper to haproxy executable
+#   OT_USE_VARS: allows the use of variables for the OpenTracing context
 #   IGNOREGIT  : ignore GIT commit versions if set.
 #   VERSION: force haproxy version reporting.
 #   SUBVERS: add a sub-version (eg: platform, model, ...).
diff --git a/addons/ot/Makefile b/addons/ot/Makefile
index ef48ce49d..0cc8c6aad 100644
--- a/addons/ot/Makefile
+++ b/addons/ot/Makefile
@@ -3,6 +3,7 @@
 # OT_INC : force the include path to libopentracing-c-wrapper
 # OT_LIB : force the lib path to libopentracing-c-wrapper
 # OT_RUNPATH : add libopentracing-c-wrapper RUNPATH to haproxy executable
+# OT_USE_VARS : allows the use of variables for the OpenTracing context
 
 OT_DEFINE=
 OT_CFLAGS=
@@ -61,8 +62,13 @@ OPTIONS_OBJS += \
 	addons/ot/src/parser.o  \
 	addons/ot/src/pool.o\
 	addons/ot/src/scope.o   \
-	addons/ot/src/util.o\
+	addons/ot/src/util.o
+
+ifneq ($(OT_USE_VARS),)
+OT_DEFINE = -DUSE_OT_VARS
+OPTIONS_OBJS += \
 	addons/ot/src/vars.o
+endif
 
 OPTIONS_CFLAGS  += $(OT_CFLAGS) -Iaddons/ot/include
 OPTIONS_LDFLAGS += $(OT_LDFLAGS)
diff --git a/addons/ot/include/filter.h b/addons/ot/include/filter.h
index 0b36354e5..c97a0cc59 100644
--- a/addons/ot/include/filter.h
+++ b/addons/ot/include/filter.h
@@ -22,7 +22,7 @@
 
 #define FLT_OT_FMT_NAME   "'" FLT_OT_OPT_NAME "' : "
 #define FLT_OT_FMT_TYPE   "'filter' : "
-#define FTL_OT_VAR_UUID   "sess", "ot", "uuid"
+#define FLT_OT_VAR_UUID   "sess", "ot", "uuid"
 #define FLT_OT_ALERT(f, ...)  ha_alert(FLT_OT_FMT_TYPE FLT_OT_FMT_NAME f "\n", ##__VA_ARGS__)
 
 #define FLT_OT_CONDITION_IF   "if"
diff --git a/addons/ot/include/parser.h b/addons/ot/include/parser.h
index 75a39cc0c..96939916d 100644
--- a/addons/ot/include/parser.h
+++ b/addons/ot/include/parser.h
@@ -65,14 +65,29 @@
 	FLT_OT_PARSE_GROUP_DEF(ID, 0, 1, 2, 2, "ot-group", " ") \
 	FLT_OT_PARSE_GROUP_DEF(SCOPES, 0, 0, 2, 0, "scopes",   "  ...")
 
+#ifdef USE_OT_VARS
+#  define FLT_OT_PARSE_SCOPE_INJECT_HELP"  [use-vars] [use-headers]"
+#  define FLT_OT_PARSE_SCOPE_EXTRACT_HELP   "  [use-vars | use-headers]"
+#else
+#  define FLT_OT_PARSE_SCOPE_INJECT_HELP"  [use-headers]"
+#  define FLT_OT_PARSE_SCOPE_EXTRACT_HELP   "  [use-headers]"
+#endif
+
+/*
+ * In case the possibility of working with OpenTracing context via HAProxyu
+ * variables is not used, args_max member of the structure flt_ot_parse_data
+ * should be reduced for 'inject'