From: Florent Bruneau Date: Mon, 13 Oct 2008 19:59:15 +0000 (+0200) Subject: Add "counter" filter. X-Git-Url: http://git.madism.org/?a=commitdiff_plain;h=1377aa69575ab9a92b7edb7d9ae9cb2f3380cf01;p=apps%2Fpfixtools.git Add "counter" filter. Signed-off-by: Florent Bruneau --- diff --git a/postlicyd/Makefile b/postlicyd/Makefile index 104155c..659588a 100644 --- a/postlicyd/Makefile +++ b/postlicyd/Makefile @@ -40,7 +40,7 @@ TESTS = tst-rbl tst-filters tst-greylist UB_LIBS = -lunbound -FILTERS = iplist.c greylist.c strlist.c match.c +FILTERS = iplist.c greylist.c strlist.c match.c counters.c postlicyd_SOURCES = main-postlicyd.c ../common/lib.a filter.c config.c query.c $(FILTERS) $(GENERATED) postlicyd_LIBADD = $(UB_LIBS) $(TC_LIBS) diff --git a/postlicyd/counters.c b/postlicyd/counters.c new file mode 100644 index 0000000..477e6e1 --- /dev/null +++ b/postlicyd/counters.c @@ -0,0 +1,126 @@ +/******************************************************************************/ +/* pfixtools: a collection of postfix related tools */ +/* ~~~~~~~~~ */ +/* ________________________________________________________________________ */ +/* */ +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ +/* */ +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ +/* 3. The names of its contributors may not be used to endorse or promote */ +/* products derived from this software without specific prior written */ +/* permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND */ +/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */ +/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS */ +/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */ +/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ +/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ +/* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN */ +/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) */ +/* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF */ +/* THE POSSIBILITY OF SUCH DAMAGE. */ +/******************************************************************************/ + +/* + * Copyright © 2008 Florent Bruneau + */ + +#include "filter.h" +#include "config.h" +#include "query.h" + +typedef struct counter_config_t { + int counter; + uint32_t hard_threshold; + uint32_t soft_threshold; +} counter_config_t; + + +static counter_config_t *counter_config_new(void) +{ + return p_new(counter_config_t, 1); +} + +static void counter_config_delete(counter_config_t **config) +{ + if (*config) { + p_delete(config); + } +} + +static bool counter_filter_constructor(filter_t *filter) +{ + counter_config_t *config = counter_config_new(); + config->counter = -1; + +#define PARSE_CHECK(Expr, Str, ...) \ + if (!(Expr)) { \ + err(Str, ##__VA_ARGS__); \ + counter_config_delete(&config); \ + return false; \ + } + + foreach (filter_param_t *param, filter->params) { + switch (param->type) { + FILTER_PARAM_PARSE_INT(COUNTER, config->counter); + FILTER_PARAM_PARSE_INT(HARD_THRESHOLD, config->hard_threshold); + FILTER_PARAM_PARSE_INT(SOFT_THRESHOLD, config->soft_threshold); + default: break; + } + }} + + PARSE_CHECK(config->counter >= 0 && config->counter < MAX_COUNTERS, + "invalid counter number: %d", config->counter); + filter->data = config; + return true; +} + +static void counter_filter_destructor(filter_t *filter) +{ + counter_config_t *config = filter->data; + counter_config_delete(&config); + filter->data = config; +} + +static filter_result_t counter_filter(const filter_t *filter, const query_t *query, + filter_context_t *context) +{ + const counter_config_t *counter = filter->data; + const uint32_t val = context->counters[counter->counter]; + + if (val >= counter->hard_threshold) { + return HTK_HARD_MATCH; + } else if (val >= counter->soft_threshold) { + return HTK_SOFT_MATCH; + } else { + return HTK_FAIL; + } +} + +static int counter_init(void) +{ + filter_type_t type = filter_register("counter", counter_filter_constructor, + counter_filter_destructor, counter_filter, + NULL, NULL); + /* Hooks. + */ + (void)filter_hook_register(type, "fail"); + (void)filter_hook_register(type, "hard_match"); + (void)filter_hook_register(type, "soft_match"); + + /* Parameters. + */ + (void)filter_param_register(type, "counter"); + (void)filter_param_register(type, "hard_threshold"); + (void)filter_param_register(type, "soft_threshold"); + return 0; +} +module_init(counter_init);