From 7d56221d5797d3c73448d35eeafa801590eacabf Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 25 Nov 2016 16:10:05 +0100 Subject: [PATCH] REORG: stkctr: move all the stick counters processing to stick-tables.c Historically we used to have the stick counters processing put into session.c which became stream.c. But a big part of it is now in stick-table.c (eg: converters) but despite this we still have all the sample fetch functions in stream.c These parts do not depend on the stream anymore, so let's move the remaining chunks to stick-table.c and have cleaner files. What remains in stream.c is everything needed to attach/detach trackers to the stream and to update the counters while the stream is being processed. --- include/proto/stick_table.h | 2 + include/proto/stream.h | 2 - src/stick_table.c | 823 ++++++++++++++++++++++++++++++++++++ src/stream.c | 822 ----------------------------------- 4 files changed, 825 insertions(+), 824 deletions(-) diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h index 941e2ff72..a5fd4000c 100644 --- a/include/proto/stick_table.h +++ b/include/proto/stick_table.h @@ -54,6 +54,8 @@ struct stktable_key *smp_to_stkey(struct sample *smp, struct stktable *t); struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px, struct session *sess, struct stream *strm, unsigned int opt, struct sample_expr *expr, struct sample *smp); +struct stkctr *smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw); +struct stkctr *smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw); int stktable_compatible_sample(struct sample_expr *expr, unsigned long table_type); int stktable_register_data_store(int idx, const char *name, int std_type, int arg_type); int stktable_get_data_type(char *name); diff --git a/include/proto/stream.h b/include/proto/stream.h index 02ac0f8fc..db239566a 100644 --- a/include/proto/stream.h +++ b/include/proto/stream.h @@ -48,8 +48,6 @@ void stream_process_counters(struct stream *s); void sess_change_server(struct stream *sess, struct server *newsrv); struct task *process_stream(struct task *t); void default_srv_error(struct stream *s, struct stream_interface *si); -struct stkctr *smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw); -struct stkctr *smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw); int parse_track_counters(char **args, int *arg, int section_type, struct proxy *curpx, struct track_ctr_prm *prm, diff --git a/src/stick_table.c b/src/stick_table.c index 383ec00e2..909b8c55a 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1520,6 +1521,710 @@ static enum act_parse_ret parse_set_gpt0(const char **args, int *arg, struct pro return ACT_RET_PRS_OK; } +/* set temp integer to the number of used entries in the table pointed to by expr. + * Accepts exactly 1 argument of type table. + */ +static int +smp_fetch_table_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = args->data.prx->table.current; + return 1; +} + +/* set temp integer to the number of free entries in the table pointed to by expr. + * Accepts exactly 1 argument of type table. + */ +static int +smp_fetch_table_avl(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct proxy *px; + + px = args->data.prx; + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = px->table.size - px->table.current; + return 1; +} + +/* Returns a pointer to a stkctr depending on the fetch keyword name. + * It is designed to be called as sc[0-9]_* sc_* or src_* exclusively. + * sc[0-9]_* will return a pointer to the respective field in the + * stream . sc_* requires an UINT argument specifying the stick + * counter number. src_* will fill a locally allocated structure with + * the table and entry corresponding to what is specified with src_*. + * NULL may be returned if the designated stkctr is not tracked. For + * the sc_* and sc[0-9]_* forms, an optional table argument may be + * passed. When present, the currently tracked key is then looked up + * in the specified table instead of the current table. The purpose is + * to be able to convery multiple values per key (eg: have gpc0 from + * multiple tables). is allowed to be NULL, in which case only + * the session will be consulted. + */ +struct stkctr * +smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw) +{ + static struct stkctr stkctr; + struct stkctr *stkptr; + struct stksess *stksess; + unsigned int num = kw[2] - '0'; + int arg = 0; + + if (num == '_' - '0') { + /* sc_* variant, args[0] = ctr# (mandatory) */ + num = args[arg++].data.sint; + if (num >= MAX_SESS_STKCTR) + return NULL; + } + else if (num > 9) { /* src_* variant, args[0] = table */ + struct stktable_key *key; + struct connection *conn = objt_conn(sess->origin); + struct sample smp; + + if (!conn) + return NULL; + + /* Fetch source adress in a sample. */ + smp.px = NULL; + smp.sess = sess; + smp.strm = strm; + if (!smp_fetch_src(NULL, &smp, NULL, NULL)) + return NULL; + + /* Converts into key. */ + key = smp_to_stkey(&smp, &args->data.prx->table); + if (!key) + return NULL; + + stkctr.table = &args->data.prx->table; + stkctr_set_entry(&stkctr, stktable_lookup_key(stkctr.table, key)); + return &stkctr; + } + + /* Here, contains the counter number from 0 to 9 for + * the sc[0-9]_ form, or even higher using sc_(num) if needed. + * args[arg] is the first optional argument. We first lookup the + * ctr form the stream, then from the session if it was not there. + */ + + if (strm) + stkptr = &strm->stkctr[num]; + if (!strm || !stkctr_entry(stkptr)) { + stkptr = &sess->stkctr[num]; + if (!stkctr_entry(stkptr)) + return NULL; + } + + stksess = stkctr_entry(stkptr); + if (!stksess) + return NULL; + + if (unlikely(args[arg].type == ARGT_TAB)) { + /* an alternate table was specified, let's look up the same key there */ + stkctr.table = &args[arg].data.prx->table; + stkctr_set_entry(&stkctr, stktable_lookup(stkctr.table, stksess)); + return &stkctr; + } + return stkptr; +} + +/* same as smp_fetch_sc_stkctr() but dedicated to src_* and can create + * the entry if it doesn't exist yet. This is needed for a few fetch + * functions which need to create an entry, such as src_inc_gpc* and + * src_clr_gpc*. + */ +struct stkctr * +smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw) +{ + static struct stkctr stkctr; + struct stktable_key *key; + struct connection *conn = objt_conn(sess->origin); + struct sample smp; + + if (strncmp(kw, "src_", 4) != 0) + return NULL; + + if (!conn) + return NULL; + + /* Fetch source adress in a sample. */ + smp.px = NULL; + smp.sess = sess; + smp.strm = strm; + if (!smp_fetch_src(NULL, &smp, NULL, NULL)) + return NULL; + + /* Converts into key. */ + key = smp_to_stkey(&smp, &args->data.prx->table); + if (!key) + return NULL; + + stkctr.table = &args->data.prx->table; + stkctr_set_entry(&stkctr, stktable_update_key(stkctr.table, key)); + return &stkctr; +} + +/* set return a boolean indicating if the requested stream counter is + * currently being tracked or not. + * Supports being called as "sc[0-9]_tracked" only. + */ +static int +smp_fetch_sc_tracked(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_BOOL; + smp->data.u.sint = !!smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + return 1; +} + +/* set to the General Purpose Flag 0 value from the stream's tracked + * frontend counters or from the src. + * Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpt0" only. Value + * zero is returned if the key is new. + */ +static int +smp_fetch_sc_get_gpt0(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT0); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, gpt0); + } + return 1; +} + +/* set to the General Purpose Counter 0 value from the stream's tracked + * frontend counters or from the src. + * Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpc0" only. Value + * zero is returned if the key is new. + */ +static int +smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, gpc0); + } + return 1; +} + +/* set to the General Purpose Counter 0's event rate from the stream's + * tracked frontend counters or from the src. + * Supports being called as "sc[0-9]_gpc0_rate" or "src_gpc0_rate" only. + * Value zero is returned if the key is new. + */ +static int +smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0_RATE); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate), + stkctr->table->data_arg[STKTABLE_DT_GPC0_RATE].u); + } + return 1; +} + +/* Increment the General Purpose Counter 0 value from the stream's tracked + * frontend counters and return it into temp integer. + * Supports being called as "sc[0-9]_inc_gpc0" or "src_inc_gpc0" only. + */ +static int +smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + + if (stkctr_entry(stkctr) == NULL) + stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw); + + if (stkctr && stkctr_entry(stkctr)) { + void *ptr1,*ptr2; + + /* First, update gpc0_rate if it's tracked. Second, update its + * gpc0 if tracked. Returns gpc0's value otherwise the curr_ctr. + */ + ptr1 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0_RATE); + if (ptr1) { + update_freq_ctr_period(&stktable_data_cast(ptr1, gpc0_rate), + stkctr->table->data_arg[STKTABLE_DT_GPC0_RATE].u, 1); + smp->data.u.sint = (&stktable_data_cast(ptr1, gpc0_rate))->curr_ctr; + } + + ptr2 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); + if (ptr2) + smp->data.u.sint = ++stktable_data_cast(ptr2, gpc0); + + /* If data was modified, we need to touch to re-schedule sync */ + if (ptr1 || ptr2) + stktable_touch(stkctr->table, stkctr_entry(stkctr), 1); + } + return 1; +} + +/* Clear the General Purpose Counter 0 value from the stream's tracked + * frontend counters and return its previous value into temp integer. + * Supports being called as "sc[0-9]_clr_gpc0" or "src_clr_gpc0" only. + */ +static int +smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + + if (stkctr_entry(stkctr) == NULL) + stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw); + + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, gpc0); + stktable_data_cast(ptr, gpc0) = 0; + /* If data was modified, we need to touch to re-schedule sync */ + stktable_touch(stkctr->table, stkctr_entry(stkctr), 1); + } + return 1; +} + +/* set to the cumulated number of connections from the stream's tracked + * frontend counters. Supports being called as "sc[0-9]_conn_cnt" or + * "src_conn_cnt" only. + */ +static int +smp_fetch_sc_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CNT); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, conn_cnt); + } + return 1; +} + +/* set to the connection rate from the stream's tracked frontend + * counters. Supports being called as "sc[0-9]_conn_rate" or "src_conn_rate" + * only. + */ +static int +smp_fetch_sc_conn_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_RATE); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate), + stkctr->table->data_arg[STKTABLE_DT_CONN_RATE].u); + } + return 1; +} + +/* set temp integer to the number of connections from the stream's source address + * in the table pointed to by expr, after updating it. + * Accepts exactly 1 argument of type table. + */ +static int +smp_fetch_src_updt_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct connection *conn = objt_conn(smp->sess->origin); + struct stksess *ts; + struct stktable_key *key; + void *ptr; + struct proxy *px; + + if (!conn) + return 0; + + /* Fetch source adress in a sample. */ + if (!smp_fetch_src(NULL, smp, NULL, NULL)) + return 0; + + /* Converts into key. */ + key = smp_to_stkey(smp, &args->data.prx->table); + if (!key) + return 0; + + px = args->data.prx; + + if ((ts = stktable_update_key(&px->table, key)) == NULL) + /* entry does not exist and could not be created */ + return 0; + + ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CNT); + if (!ptr) + return 0; /* parameter not stored in this table */ + + smp->data.type = SMP_T_SINT; + smp->data.u.sint = ++stktable_data_cast(ptr, conn_cnt); + /* Touch was previously performed by stktable_update_key */ + smp->flags = SMP_F_VOL_TEST; + return 1; +} + +/* set to the number of concurrent connections from the stream's tracked + * frontend counters. Supports being called as "sc[0-9]_conn_cur" or + * "src_conn_cur" only. + */ +static int +smp_fetch_sc_conn_cur(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CUR); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, conn_cur); + } + return 1; +} + +/* set to the cumulated number of streams from the stream's tracked + * frontend counters. Supports being called as "sc[0-9]_sess_cnt" or + * "src_sess_cnt" only. + */ +static int +smp_fetch_sc_sess_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_CNT); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, sess_cnt); + } + return 1; +} + +/* set to the stream rate from the stream's tracked frontend counters. + * Supports being called as "sc[0-9]_sess_rate" or "src_sess_rate" only. + */ +static int +smp_fetch_sc_sess_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_RATE); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, sess_rate), + stkctr->table->data_arg[STKTABLE_DT_SESS_RATE].u); + } + return 1; +} + +/* set to the cumulated number of HTTP requests from the stream's tracked + * frontend counters. Supports being called as "sc[0-9]_http_req_cnt" or + * "src_http_req_cnt" only. + */ +static int +smp_fetch_sc_http_req_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, http_req_cnt); + } + return 1; +} + +/* set to the HTTP request rate from the stream's tracked frontend + * counters. Supports being called as "sc[0-9]_http_req_rate" or + * "src_http_req_rate" only. + */ +static int +smp_fetch_sc_http_req_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate), + stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u); + } + return 1; +} + +/* set to the cumulated number of HTTP requests errors from the stream's + * tracked frontend counters. Supports being called as "sc[0-9]_http_err_cnt" or + * "src_http_err_cnt" only. + */ +static int +smp_fetch_sc_http_err_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_CNT); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, http_err_cnt); + } + return 1; +} + +/* set to the HTTP request error rate from the stream's tracked frontend + * counters. Supports being called as "sc[0-9]_http_err_rate" or + * "src_http_err_rate" only. + */ +static int +smp_fetch_sc_http_err_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_RATE); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate), + stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u); + } + return 1; +} + +/* set to the number of kbytes received from clients, as found in the + * stream's tracked frontend counters. Supports being called as + * "sc[0-9]_kbytes_in" or "src_kbytes_in" only. + */ +static int +smp_fetch_sc_kbytes_in(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_CNT); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, bytes_in_cnt) >> 10; + } + return 1; +} + +/* set to the data rate received from clients in bytes/s, as found + * in the stream's tracked frontend counters. Supports being called as + * "sc[0-9]_bytes_in_rate" or "src_bytes_in_rate" only. + */ +static int +smp_fetch_sc_bytes_in_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_RATE); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate), + stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u); + } + return 1; +} + +/* set to the number of kbytes sent to clients, as found in the + * stream's tracked frontend counters. Supports being called as + * "sc[0-9]_kbytes_out" or "src_kbytes_out" only. + */ +static int +smp_fetch_sc_kbytes_out(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_CNT); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = stktable_data_cast(ptr, bytes_out_cnt) >> 10; + } + return 1; +} + +/* set to the data rate sent to clients in bytes/s, as found in the + * stream's tracked frontend counters. Supports being called as + * "sc[0-9]_bytes_out_rate" or "src_bytes_out_rate" only. + */ +static int +smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_RATE); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate), + stkctr->table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u); + } + return 1; +} + +/* set to the number of active trackers on the SC entry in the stream's + * tracked frontend counters. Supports being called as "sc[0-9]_trackers" only. + */ +static int +smp_fetch_sc_trackers(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); + if (!stkctr) + return 0; + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = stkctr_entry(stkctr) ? stkctr_entry(stkctr)->ref_cnt : 0; + return 1; +} + /* The functions below are used to manipulate table contents from the CLI. * There are 3 main actions, "clear", "set" and "show". The code is shared @@ -2117,6 +2822,123 @@ static struct action_kw_list http_res_kws = { { }, { { /* END */ } }}; +///* Note: must not be declared as its list will be overwritten. +// * Please take care of keeping this list alphabetically sorted. +// */ +//static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, { +// { "table_avl", smp_fetch_table_avl, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, +// { "table_cnt", smp_fetch_table_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, +// { /* END */ }, +//}}; +/* Note: must not be declared as its list will be overwritten. + * Please take care of keeping this list alphabetically sorted. + */ +static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, { + { "sc_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_conn_cnt", smp_fetch_sc_conn_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_conn_cur", smp_fetch_sc_conn_cur, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_conn_rate", smp_fetch_sc_conn_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_get_gpt0", smp_fetch_sc_get_gpt0, ARG2(1,SINT,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, + { "sc_get_gpc0", smp_fetch_sc_get_gpc0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_http_err_rate", smp_fetch_sc_http_err_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_http_req_rate", smp_fetch_sc_http_req_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_kbytes_in", smp_fetch_sc_kbytes_in, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "sc_kbytes_out", smp_fetch_sc_kbytes_out, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "sc_sess_cnt", smp_fetch_sc_sess_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_sess_rate", smp_fetch_sc_sess_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc_tracked", smp_fetch_sc_tracked, ARG2(1,SINT,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, + { "sc_trackers", smp_fetch_sc_trackers, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_conn_cur", smp_fetch_sc_conn_cur, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_conn_rate", smp_fetch_sc_conn_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, + { "sc0_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_kbytes_in", smp_fetch_sc_kbytes_in, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "sc0_kbytes_out", smp_fetch_sc_kbytes_out, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "sc0_sess_cnt", smp_fetch_sc_sess_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_sess_rate", smp_fetch_sc_sess_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc0_tracked", smp_fetch_sc_tracked, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, + { "sc0_trackers", smp_fetch_sc_trackers, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_conn_cur", smp_fetch_sc_conn_cur, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_conn_rate", smp_fetch_sc_conn_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, + { "sc1_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_kbytes_in", smp_fetch_sc_kbytes_in, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "sc1_kbytes_out", smp_fetch_sc_kbytes_out, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "sc1_sess_cnt", smp_fetch_sc_sess_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_sess_rate", smp_fetch_sc_sess_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc1_tracked", smp_fetch_sc_tracked, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, + { "sc1_trackers", smp_fetch_sc_trackers, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_conn_cur", smp_fetch_sc_conn_cur, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_conn_rate", smp_fetch_sc_conn_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, + { "sc2_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_kbytes_in", smp_fetch_sc_kbytes_in, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "sc2_kbytes_out", smp_fetch_sc_kbytes_out, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "sc2_sess_cnt", smp_fetch_sc_sess_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_sess_rate", smp_fetch_sc_sess_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "sc2_tracked", smp_fetch_sc_tracked, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, + { "sc2_trackers", smp_fetch_sc_trackers, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "src_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_conn_cur", smp_fetch_sc_conn_cur, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_conn_rate", smp_fetch_sc_conn_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(1,TAB), NULL, SMP_T_BOOL, SMP_USE_L4CLI, }, + { "src_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_kbytes_in", smp_fetch_sc_kbytes_in, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_kbytes_out", smp_fetch_sc_kbytes_out, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_sess_cnt", smp_fetch_sc_sess_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_sess_rate", smp_fetch_sc_sess_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "src_updt_conn_cnt", smp_fetch_src_updt_conn_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, + { "table_avl", smp_fetch_table_avl, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { "table_cnt", smp_fetch_table_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, + { /* END */ }, +}}; + + /* Note: must not be declared as its list will be overwritten */ static struct sample_conv_kw_list sample_conv_kws = {ILH, { { "in_table", sample_conv_in_table, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_BOOL }, @@ -2153,6 +2975,7 @@ static void __stick_table_init(void) http_res_keywords_register(&http_res_kws); /* register sample fetch and format conversion keywords */ + sample_register_fetches(&smp_fetch_keywords); sample_register_convs(&sample_conv_kws); cli_register_kw(&cli_kws); } diff --git a/src/stream.c b/src/stream.c index 0f8483416..b333dec62 100644 --- a/src/stream.c +++ b/src/stream.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -2611,710 +2610,6 @@ void stream_shutdown(struct stream *stream, int why) /* All supported ACL keywords must be declared here. */ /************************************************************************/ -/* Returns a pointer to a stkctr depending on the fetch keyword name. - * It is designed to be called as sc[0-9]_* sc_* or src_* exclusively. - * sc[0-9]_* will return a pointer to the respective field in the - * stream . sc_* requires an UINT argument specifying the stick - * counter number. src_* will fill a locally allocated structure with - * the table and entry corresponding to what is specified with src_*. - * NULL may be returned if the designated stkctr is not tracked. For - * the sc_* and sc[0-9]_* forms, an optional table argument may be - * passed. When present, the currently tracked key is then looked up - * in the specified table instead of the current table. The purpose is - * to be able to convery multiple values per key (eg: have gpc0 from - * multiple tables). is allowed to be NULL, in which case only - * the session will be consulted. - */ -struct stkctr * -smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw) -{ - static struct stkctr stkctr; - struct stkctr *stkptr; - struct stksess *stksess; - unsigned int num = kw[2] - '0'; - int arg = 0; - - if (num == '_' - '0') { - /* sc_* variant, args[0] = ctr# (mandatory) */ - num = args[arg++].data.sint; - if (num >= MAX_SESS_STKCTR) - return NULL; - } - else if (num > 9) { /* src_* variant, args[0] = table */ - struct stktable_key *key; - struct connection *conn = objt_conn(sess->origin); - struct sample smp; - - if (!conn) - return NULL; - - /* Fetch source adress in a sample. */ - smp.px = NULL; - smp.sess = sess; - smp.strm = strm; - if (!smp_fetch_src(NULL, &smp, NULL, NULL)) - return NULL; - - /* Converts into key. */ - key = smp_to_stkey(&smp, &args->data.prx->table); - if (!key) - return NULL; - - stkctr.table = &args->data.prx->table; - stkctr_set_entry(&stkctr, stktable_lookup_key(stkctr.table, key)); - return &stkctr; - } - - /* Here, contains the counter number from 0 to 9 for - * the sc[0-9]_ form, or even higher using sc_(num) if needed. - * args[arg] is the first optional argument. We first lookup the - * ctr form the stream, then from the session if it was not there. - */ - - if (strm) - stkptr = &strm->stkctr[num]; - if (!strm || !stkctr_entry(stkptr)) { - stkptr = &sess->stkctr[num]; - if (!stkctr_entry(stkptr)) - return NULL; - } - - stksess = stkctr_entry(stkptr); - if (!stksess) - return NULL; - - if (unlikely(args[arg].type == ARGT_TAB)) { - /* an alternate table was specified, let's look up the same key there */ - stkctr.table = &args[arg].data.prx->table; - stkctr_set_entry(&stkctr, stktable_lookup(stkctr.table, stksess)); - return &stkctr; - } - return stkptr; -} - -/* same as smp_fetch_sc_stkctr() but dedicated to src_* and can create - * the entry if it doesn't exist yet. This is needed for a few fetch - * functions which need to create an entry, such as src_inc_gpc* and - * src_clr_gpc*. - */ -struct stkctr * -smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw) -{ - static struct stkctr stkctr; - struct stktable_key *key; - struct connection *conn = objt_conn(sess->origin); - struct sample smp; - - if (strncmp(kw, "src_", 4) != 0) - return NULL; - - if (!conn) - return NULL; - - /* Fetch source adress in a sample. */ - smp.px = NULL; - smp.sess = sess; - smp.strm = strm; - if (!smp_fetch_src(NULL, &smp, NULL, NULL)) - return NULL; - - /* Converts into key. */ - key = smp_to_stkey(&smp, &args->data.prx->table); - if (!key) - return NULL; - - stkctr.table = &args->data.prx->table; - stkctr_set_entry(&stkctr, stktable_update_key(stkctr.table, key)); - return &stkctr; -} - -/* set return a boolean indicating if the requested stream counter is - * currently being tracked or not. - * Supports being called as "sc[0-9]_tracked" only. - */ -static int -smp_fetch_sc_tracked(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_BOOL; - smp->data.u.sint = !!smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - return 1; -} - -/* set to the General Purpose Flag 0 value from the stream's tracked - * frontend counters or from the src. - * Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpt0" only. Value - * zero is returned if the key is new. - */ -static int -smp_fetch_sc_get_gpt0(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT0); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, gpt0); - } - return 1; -} - -/* set to the General Purpose Counter 0 value from the stream's tracked - * frontend counters or from the src. - * Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpc0" only. Value - * zero is returned if the key is new. - */ -static int -smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, gpc0); - } - return 1; -} - -/* set to the General Purpose Counter 0's event rate from the stream's - * tracked frontend counters or from the src. - * Supports being called as "sc[0-9]_gpc0_rate" or "src_gpc0_rate" only. - * Value zero is returned if the key is new. - */ -static int -smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0_RATE); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate), - stkctr->table->data_arg[STKTABLE_DT_GPC0_RATE].u); - } - return 1; -} - -/* Increment the General Purpose Counter 0 value from the stream's tracked - * frontend counters and return it into temp integer. - * Supports being called as "sc[0-9]_inc_gpc0" or "src_inc_gpc0" only. - */ -static int -smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - - if (stkctr_entry(stkctr) == NULL) - stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw); - - if (stkctr && stkctr_entry(stkctr)) { - void *ptr1,*ptr2; - - /* First, update gpc0_rate if it's tracked. Second, update its - * gpc0 if tracked. Returns gpc0's value otherwise the curr_ctr. - */ - ptr1 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0_RATE); - if (ptr1) { - update_freq_ctr_period(&stktable_data_cast(ptr1, gpc0_rate), - stkctr->table->data_arg[STKTABLE_DT_GPC0_RATE].u, 1); - smp->data.u.sint = (&stktable_data_cast(ptr1, gpc0_rate))->curr_ctr; - } - - ptr2 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); - if (ptr2) - smp->data.u.sint = ++stktable_data_cast(ptr2, gpc0); - - /* If data was modified, we need to touch to re-schedule sync */ - if (ptr1 || ptr2) - stktable_touch(stkctr->table, stkctr_entry(stkctr), 1); - } - return 1; -} - -/* Clear the General Purpose Counter 0 value from the stream's tracked - * frontend counters and return its previous value into temp integer. - * Supports being called as "sc[0-9]_clr_gpc0" or "src_clr_gpc0" only. - */ -static int -smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - - if (stkctr_entry(stkctr) == NULL) - stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw); - - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, gpc0); - stktable_data_cast(ptr, gpc0) = 0; - /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch(stkctr->table, stkctr_entry(stkctr), 1); - } - return 1; -} - -/* set to the cumulated number of connections from the stream's tracked - * frontend counters. Supports being called as "sc[0-9]_conn_cnt" or - * "src_conn_cnt" only. - */ -static int -smp_fetch_sc_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CNT); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, conn_cnt); - } - return 1; -} - -/* set to the connection rate from the stream's tracked frontend - * counters. Supports being called as "sc[0-9]_conn_rate" or "src_conn_rate" - * only. - */ -static int -smp_fetch_sc_conn_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_RATE); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate), - stkctr->table->data_arg[STKTABLE_DT_CONN_RATE].u); - } - return 1; -} - -/* set temp integer to the number of connections from the stream's source address - * in the table pointed to by expr, after updating it. - * Accepts exactly 1 argument of type table. - */ -static int -smp_fetch_src_updt_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct connection *conn = objt_conn(smp->sess->origin); - struct stksess *ts; - struct stktable_key *key; - void *ptr; - struct proxy *px; - - if (!conn) - return 0; - - /* Fetch source adress in a sample. */ - if (!smp_fetch_src(NULL, smp, NULL, NULL)) - return 0; - - /* Converts into key. */ - key = smp_to_stkey(smp, &args->data.prx->table); - if (!key) - return 0; - - px = args->data.prx; - - if ((ts = stktable_update_key(&px->table, key)) == NULL) - /* entry does not exist and could not be created */ - return 0; - - ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CNT); - if (!ptr) - return 0; /* parameter not stored in this table */ - - smp->data.type = SMP_T_SINT; - smp->data.u.sint = ++stktable_data_cast(ptr, conn_cnt); - /* Touch was previously performed by stktable_update_key */ - smp->flags = SMP_F_VOL_TEST; - return 1; -} - -/* set to the number of concurrent connections from the stream's tracked - * frontend counters. Supports being called as "sc[0-9]_conn_cur" or - * "src_conn_cur" only. - */ -static int -smp_fetch_sc_conn_cur(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CUR); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, conn_cur); - } - return 1; -} - -/* set to the cumulated number of streams from the stream's tracked - * frontend counters. Supports being called as "sc[0-9]_sess_cnt" or - * "src_sess_cnt" only. - */ -static int -smp_fetch_sc_sess_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_CNT); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, sess_cnt); - } - return 1; -} - -/* set to the stream rate from the stream's tracked frontend counters. - * Supports being called as "sc[0-9]_sess_rate" or "src_sess_rate" only. - */ -static int -smp_fetch_sc_sess_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_RATE); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, sess_rate), - stkctr->table->data_arg[STKTABLE_DT_SESS_RATE].u); - } - return 1; -} - -/* set to the cumulated number of HTTP requests from the stream's tracked - * frontend counters. Supports being called as "sc[0-9]_http_req_cnt" or - * "src_http_req_cnt" only. - */ -static int -smp_fetch_sc_http_req_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, http_req_cnt); - } - return 1; -} - -/* set to the HTTP request rate from the stream's tracked frontend - * counters. Supports being called as "sc[0-9]_http_req_rate" or - * "src_http_req_rate" only. - */ -static int -smp_fetch_sc_http_req_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate), - stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u); - } - return 1; -} - -/* set to the cumulated number of HTTP requests errors from the stream's - * tracked frontend counters. Supports being called as "sc[0-9]_http_err_cnt" or - * "src_http_err_cnt" only. - */ -static int -smp_fetch_sc_http_err_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_CNT); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, http_err_cnt); - } - return 1; -} - -/* set to the HTTP request error rate from the stream's tracked frontend - * counters. Supports being called as "sc[0-9]_http_err_rate" or - * "src_http_err_rate" only. - */ -static int -smp_fetch_sc_http_err_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_RATE); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate), - stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u); - } - return 1; -} - -/* set to the number of kbytes received from clients, as found in the - * stream's tracked frontend counters. Supports being called as - * "sc[0-9]_kbytes_in" or "src_kbytes_in" only. - */ -static int -smp_fetch_sc_kbytes_in(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_CNT); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, bytes_in_cnt) >> 10; - } - return 1; -} - -/* set to the data rate received from clients in bytes/s, as found - * in the stream's tracked frontend counters. Supports being called as - * "sc[0-9]_bytes_in_rate" or "src_bytes_in_rate" only. - */ -static int -smp_fetch_sc_bytes_in_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_RATE); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate), - stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u); - } - return 1; -} - -/* set to the number of kbytes sent to clients, as found in the - * stream's tracked frontend counters. Supports being called as - * "sc[0-9]_kbytes_out" or "src_kbytes_out" only. - */ -static int -smp_fetch_sc_kbytes_out(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_CNT); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = stktable_data_cast(ptr, bytes_out_cnt) >> 10; - } - return 1; -} - -/* set to the data rate sent to clients in bytes/s, as found in the - * stream's tracked frontend counters. Supports being called as - * "sc[0-9]_bytes_out_rate" or "src_bytes_out_rate" only. - */ -static int -smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_RATE); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate), - stkctr->table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u); - } - return 1; -} - -/* set to the number of active trackers on the SC entry in the stream's - * tracked frontend counters. Supports being called as "sc[0-9]_trackers" only. - */ -static int -smp_fetch_sc_trackers(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw); - if (!stkctr) - return 0; - - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = stkctr_entry(stkctr) ? stkctr_entry(stkctr)->ref_cnt : 0; - return 1; -} - -/* set temp integer to the number of used entries in the table pointed to by expr. - * Accepts exactly 1 argument of type table. - */ -static int -smp_fetch_table_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = args->data.prx->table.current; - return 1; -} - -/* set temp integer to the number of free entries in the table pointed to by expr. - * Accepts exactly 1 argument of type table. - */ -static int -smp_fetch_table_avl(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - struct proxy *px; - - px = args->data.prx; - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = px->table.size - px->table.current; - return 1; -} - /* 0=OK, <0=Alert, >0=Warning */ static enum act_parse_ret stream_parse_use_service(const char **args, int *cur_arg, struct proxy *px, struct act_rule *rule, @@ -3986,126 +3281,9 @@ static struct action_kw_list stream_http_keywords = { ILH, { { /* END */ } }}; -/* Note: must not be declared as its list will be overwritten. - * Please take care of keeping this list alphabetically sorted. - */ -static struct acl_kw_list acl_kws = {ILH, { - { /* END */ }, -}}; - -/* Note: must not be declared as its list will be overwritten. - * Please take care of keeping this list alphabetically sorted. - */ -static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, { - { "sc_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_conn_cnt", smp_fetch_sc_conn_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_conn_cur", smp_fetch_sc_conn_cur, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_conn_rate", smp_fetch_sc_conn_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_get_gpt0", smp_fetch_sc_get_gpt0, ARG2(1,SINT,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, - { "sc_get_gpc0", smp_fetch_sc_get_gpc0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_http_err_rate", smp_fetch_sc_http_err_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_http_req_rate", smp_fetch_sc_http_req_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_kbytes_in", smp_fetch_sc_kbytes_in, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "sc_kbytes_out", smp_fetch_sc_kbytes_out, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "sc_sess_cnt", smp_fetch_sc_sess_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_sess_rate", smp_fetch_sc_sess_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc_tracked", smp_fetch_sc_tracked, ARG2(1,SINT,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, - { "sc_trackers", smp_fetch_sc_trackers, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_conn_cur", smp_fetch_sc_conn_cur, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_conn_rate", smp_fetch_sc_conn_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, - { "sc0_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_kbytes_in", smp_fetch_sc_kbytes_in, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "sc0_kbytes_out", smp_fetch_sc_kbytes_out, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "sc0_sess_cnt", smp_fetch_sc_sess_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_sess_rate", smp_fetch_sc_sess_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc0_tracked", smp_fetch_sc_tracked, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, - { "sc0_trackers", smp_fetch_sc_trackers, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_conn_cur", smp_fetch_sc_conn_cur, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_conn_rate", smp_fetch_sc_conn_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, - { "sc1_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_kbytes_in", smp_fetch_sc_kbytes_in, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "sc1_kbytes_out", smp_fetch_sc_kbytes_out, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "sc1_sess_cnt", smp_fetch_sc_sess_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_sess_rate", smp_fetch_sc_sess_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc1_tracked", smp_fetch_sc_tracked, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, - { "sc1_trackers", smp_fetch_sc_trackers, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_conn_cur", smp_fetch_sc_conn_cur, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_conn_rate", smp_fetch_sc_conn_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, - { "sc2_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_kbytes_in", smp_fetch_sc_kbytes_in, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "sc2_kbytes_out", smp_fetch_sc_kbytes_out, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "sc2_sess_cnt", smp_fetch_sc_sess_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_sess_rate", smp_fetch_sc_sess_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "sc2_tracked", smp_fetch_sc_tracked, ARG1(0,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, }, - { "sc2_trackers", smp_fetch_sc_trackers, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "src_bytes_in_rate", smp_fetch_sc_bytes_in_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_clr_gpc0", smp_fetch_sc_clr_gpc0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_conn_cur", smp_fetch_sc_conn_cur, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_conn_rate", smp_fetch_sc_conn_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(1,TAB), NULL, SMP_T_BOOL, SMP_USE_L4CLI, }, - { "src_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_gpc0_rate", smp_fetch_sc_gpc0_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_kbytes_in", smp_fetch_sc_kbytes_in, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_kbytes_out", smp_fetch_sc_kbytes_out, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_sess_cnt", smp_fetch_sc_sess_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_sess_rate", smp_fetch_sc_sess_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "src_updt_conn_cnt", smp_fetch_src_updt_conn_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, }, - { "table_avl", smp_fetch_table_avl, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { "table_cnt", smp_fetch_table_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, }, - { /* END */ }, -}}; - __attribute__((constructor)) static void __stream_init(void) { - sample_register_fetches(&smp_fetch_keywords); - acl_register_keywords(&acl_kws); tcp_req_cont_keywords_register(&stream_tcp_keywords); http_req_keywords_register(&stream_http_keywords); cli_register_kw(&cli_kws);