diff --git a/doc/configuration.txt b/doc/configuration.txt index 2c4e24cca..b253ca92f 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -87,7 +87,8 @@ Summary 7.3.4. Fetching samples at Layer 5 7.3.5. Fetching samples from buffer contents (Layer 6) 7.3.6. Fetching HTTP samples (Layer 7) -7.3.7. Fetching samples for developers +7.3.7. Fetching health-check samples +7.3.8. Fetching samples for developers 7.4. Pre-defined ACLs 8. Logging @@ -17164,7 +17165,25 @@ url32+src : binary the source address family. This can be used to track per-IP, per-URL counters. -7.3.7. Fetching samples for developers +7.3.7. Fetching health-check samples +------------------------------------- + +This set of sample fetch methods may be called from an health-check execution +context. It was introduced in the version 2.2. The following sample fetches are +placed in the dedicated scope "check". Other sample fetches may also be called +when an health-check is performed if it makes sense and if the sample fetch was +adapted to be called in this context. + +check.payload(,) : binary + This extracts a binary block of bytes and starting at byte + in the check input buffer. As a special case, if the argument is + zero, then the whole buffer from to the end is extracted. This can + be called from a tcp-check expect rule, or eventually from a set-var rule + after an expect rule and before a send rule (check input buffer is filled on + tcp-check expect rules and reset on tcp-check send rules). + + +7.3.8. Fetching samples for developers --------------------------------------- This set of sample fetch methods is reserved to developers and must never be diff --git a/src/checks.c b/src/checks.c index a603728f5..3606aa083 100644 --- a/src/checks.c +++ b/src/checks.c @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -4122,6 +4123,44 @@ REGISTER_SERVER_DEINIT(deinit_srv_check); REGISTER_SERVER_DEINIT(deinit_srv_agent_check); REGISTER_POST_DEINIT(deinit_tcpchecks); +/* extracts check payload at a fixed position and length */ +static int +smp_fetch_chk_payload(const struct arg *arg_p, struct sample *smp, const char *kw, void *private) +{ + unsigned int buf_offset = ((arg_p[0].type == ARGT_SINT) ? arg_p[0].data.sint : 0); + unsigned int buf_size = ((arg_p[1].type == ARGT_SINT) ? arg_p[1].data.sint : 0); + struct server *srv = (smp->sess ? objt_server(smp->sess->origin) : NULL); + struct buffer *buf; + + if (!srv || !srv->do_check) + return 0; + + buf = &srv->check.bi; + if (buf_offset > b_data(buf)) + goto no_match; + if (buf_offset + buf_size > b_data(buf)) + buf_size = 0; + + /* init chunk as read only */ + smp->data.type = SMP_T_STR; + smp->flags = SMP_F_VOLATILE | SMP_F_CONST; + chunk_initlen(&smp->data.u.str, b_head(buf) + buf_offset, 0, (buf_size ? buf_size : (b_data(buf) - buf_offset))); + + return 1; + + no_match: + smp->flags = 0; + return 0; +} + +static struct sample_fetch_kw_list smp_kws = {ILH, { + { "check.payload", smp_fetch_chk_payload, ARG2(0,SINT,SINT), NULL, SMP_T_STR, SMP_USE_INTRN }, + { /* END */ }, +}}; + +INITCALL1(STG_REGISTER, sample_register_fetches, &smp_kws); + + struct action_kw_list tcp_check_keywords = { .list = LIST_HEAD_INIT(tcp_check_keywords.list), };