From: Christopher Faulet Date: Fri, 3 Apr 2020 13:24:06 +0000 (+0200) Subject: MINOR: checks: Support custom functions to eval a tcp-check expect rules X-Git-Tag: v2.2-dev7~129 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9e6ed1598e281c08d1ec92a996d4e5b18e6cb1e8;p=thirdparty%2Fhaproxy.git MINOR: checks: Support custom functions to eval a tcp-check expect rules It is now possible to set a custom function to evaluate a tcp-check expect rule. It is an internal and not documentd option because the right pointer of function must be set and it is not possible to express it in the configuration. It will be used to convert some protocol healthchecks to tcp-checks. Custom functions must have the following signature: enum tcpcheck_eval_ret (*custom)(struct check *, struct tcpcheck_rule *, int); --- diff --git a/include/types/checks.h b/include/types/checks.h index 220563345c..30f7d75fb0 100644 --- a/include/types/checks.h +++ b/include/types/checks.h @@ -253,11 +253,12 @@ enum tcpcheck_eval_ret { }; enum tcpcheck_expect_type { - TCPCHK_EXPECT_UNDEF = 0, /* Match is not used. */ - TCPCHK_EXPECT_STRING, /* Matches a string. */ - TCPCHK_EXPECT_REGEX, /* Matches a regular pattern. */ + TCPCHK_EXPECT_UNDEF = 0, /* Match is not used. */ + TCPCHK_EXPECT_STRING, /* Matches a string. */ + TCPCHK_EXPECT_REGEX, /* Matches a regular pattern. */ TCPCHK_EXPECT_REGEX_BINARY, /* Matches a regular pattern on a hex-encoded text. */ - TCPCHK_EXPECT_BINARY, /* Matches a binary sequence. */ + TCPCHK_EXPECT_BINARY, /* Matches a binary sequence. */ + TCPCHK_EXPECT_CUSTOM, /* Execute a custom function. */ }; struct tcpcheck_expect { @@ -265,6 +266,9 @@ struct tcpcheck_expect { union { char *string; /* Matching a literal string / binary anywhere in the response. */ struct my_regex *regex; /* Matching a regex pattern. */ + + /* custom function to eval epxect rule */ + enum tcpcheck_eval_ret (*custom)(struct check *, struct tcpcheck_rule *, int); }; struct tcpcheck_rule *head; /* first expect of a chain. */ int length; /* Size in bytes of the pattern referenced by string / binary. */ diff --git a/src/checks.c b/src/checks.c index 6a28b543c5..c6bced88a6 100644 --- a/src/checks.c +++ b/src/checks.c @@ -664,6 +664,9 @@ static void chk_report_conn_err(struct check *check, int errno_bck, int expired) case TCPCHK_EXPECT_REGEX_BINARY: chunk_appendf(chk, " (expect binary regex)"); break; + case TCPCHK_EXPECT_CUSTOM: + chunk_appendf(chk, " (expect custom function)"); + break; case TCPCHK_EXPECT_UNDEF: chunk_appendf(chk, " (undefined expect!)"); break; @@ -2803,6 +2806,9 @@ static void tcpcheck_onerror_message(struct buffer *msg, struct check *check, st } } break; + case TCPCHK_EXPECT_CUSTOM: + chunk_appendf(msg, " (custom function) at step %d", tcpcheck_get_step_id(check, rule)); + break; case TCPCHK_EXPECT_UNDEF: /* Should never happen. */ return; @@ -3193,6 +3199,10 @@ static enum tcpcheck_eval_ret tcpcheck_eval_expect(struct check *check, struct t else match = regex_exec2(expect->regex, b_head(&trash), MIN(b_data(&trash), b_size(&trash)-1)); break; + case TCPCHK_EXPECT_CUSTOM: + if (expect->custom) + ret = expect->custom(check, rule, last_read); + goto out; case TCPCHK_EXPECT_UNDEF: /* Should never happen. */ ret = TCPCHK_EVAL_STOP; @@ -3540,6 +3550,7 @@ static void free_tcpcheck(struct tcpcheck_rule *rule, int in_pool) case TCPCHK_EXPECT_REGEX_BINARY: regex_free(rule->expect.regex); break; + case TCPCHK_EXPECT_CUSTOM: case TCPCHK_EXPECT_UNDEF: break; } @@ -4676,8 +4687,8 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str int inverse = 0, with_capture = 0; str = on_success_msg = on_error_msg = comment = pattern = NULL; - if (!*(args[cur_arg+1]) || !*(args[cur_arg+2])) { - memprintf(errmsg, "expects a pattern (type+string) as arguments"); + if (!*(args[cur_arg+1])) { + memprintf(errmsg, "expects at least a matching pattern as arguments"); goto error; } @@ -4730,6 +4741,17 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str cur_arg++; pattern = args[cur_arg]; } + else if (strcmp(args[cur_arg], "custom") == 0) { + if (in_pattern) { + memprintf(errmsg, "[!] not supported with '%s'", args[cur_arg]); + goto error; + } + if (type != TCPCHK_EXPECT_UNDEF) { + memprintf(errmsg, "only on pattern expected"); + goto error; + } + type = TCPCHK_EXPECT_CUSTOM; + } else if (strcmp(args[cur_arg], "comment") == 0) { if (in_pattern) { memprintf(errmsg, "[!] not supported with '%s'", args[cur_arg]); @@ -4941,6 +4963,9 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str if (!chk->expect.regex) goto error; break; + case TCPCHK_EXPECT_CUSTOM: + chk->expect.custom = NULL; /* Must be defined by the caller ! */ + break; case TCPCHK_EXPECT_UNDEF: free(chk); memprintf(errmsg, "pattern not found");