From: Florent Bruneau Date: Mon, 15 Sep 2008 12:22:10 +0000 (+0200) Subject: Tokenize hook names. X-Git-Url: http://git.madism.org/?p=apps%2Fpfixtools.git;a=commitdiff_plain;h=d8b00b7c6eb72ef123eeb85016649742932c38d9 Tokenize hook names. Signed-off-by: Florent Bruneau --- diff --git a/postlicyd/Makefile b/postlicyd/Makefile index e4eb9ab..3d49ba2 100644 --- a/postlicyd/Makefile +++ b/postlicyd/Makefile @@ -32,7 +32,9 @@ include ../mk/tc.mk PROGRAMS = postlicyd -GENERATED = policy_tokens.h policy_tokens.c filter_tokens.h filter_tokens.c +GENERATED = policy_tokens.h policy_tokens.c \ + filter_tokens.h filter_tokens.c \ + hook_tokens.h hook_tokens.c TESTS = test-rbl postlicyd_SOURCES = main-postlicyd.c ../common/lib.a filter.c config.c greylist.c rbl.c $(GENERATED) diff --git a/postlicyd/filter.c b/postlicyd/filter.c index deb3190..e5b8f35 100644 --- a/postlicyd/filter.c +++ b/postlicyd/filter.c @@ -40,18 +40,34 @@ static filter_runner_t runners[FTK_count]; static filter_constructor_t constructors[FTK_count]; static filter_destructor_t destructors[FTK_count]; +static bool hooks[FTK_count][HTK_count]; -void filter_register(const char *type, filter_constructor_t constructor, - filter_destructor_t destructor, filter_runner_t runner) +filter_type_t filter_register(const char *type, filter_constructor_t constructor, + filter_destructor_t destructor, filter_runner_t runner) { filter_token tok = filter_tokenize(type, m_strlen(type)); - assert(tok != FTK_UNKNOWN && "Unknown filter type"); + CHECK_FILTER(tok); syslog(LOG_INFO, "filter type %s registered", type); runners[tok] = runner; constructors[tok] = constructor; destructors[tok] = destructor; + return tok; +} + +filter_result_t filter_hook_register(filter_type_t filter, + const char *name) +{ + filter_result_t tok = hook_tokenize(name, m_strlen(name)); + CHECK_FILTER(filter); + CHECK_HOOK(tok); + + syslog(LOG_INFO, "hook %s registered for filter type %s", name, + ftokens[filter]); + + hooks[filter][tok] = true; + return tok; } bool filter_build(filter_t *filter) @@ -64,7 +80,7 @@ bool filter_build(filter_t *filter) # define QSORT_TYPE filter_hook_t # define QSORT_BASE filter->hooks.data # define QSORT_NELT filter->hooks.len -# define QSORT_LT(a,b) strcmp(a->name, b->name) < 0 +# define QSORT_LT(a,b) a->type < b->type # include "qsort.c" } filter_constructor_t constructor = constructors[filter->type]; @@ -82,7 +98,7 @@ bool filter_update_references(filter_t *filter, A(filter_t) *filter_list) hook->filter_id = filter_find_with_name(filter_list, hook->value); if (hook->filter_id == -1) { syslog(LOG_ERR, "invalid filter name %s for hook %s", - hook->value, hook->name); + hook->value, htokens[hook->type]); return false; } p_delete(&hook->value); @@ -134,7 +150,16 @@ bool filter_add_hook(filter_t *filter, const char *name, ssize_t name_len, const char *value, ssize_t value_len) { filter_hook_t hook; - hook.name = m_strdup(name); + hook.type = hook_tokenize(name, name_len); + if (hook.type == HTK_UNKNOWN) { + syslog(LOG_ERR, "unknown hook type %.*s", name_len, name); + return false; + } + if (!hooks[filter->type][hook.type]) { + syslog(LOG_ERR, "hook %s is valid for filter %s", + htokens[hook.type], ftokens[filter->type]); + return false; + } hook.postfix = (strncmp(value, "postfix:", 8) == 0); hook.value = m_strdup(hook.postfix ? value + 8 : value); hook.filter_id = -1; diff --git a/postlicyd/filter.h b/postlicyd/filter.h index db8e457..986e6cf 100644 --- a/postlicyd/filter.h +++ b/postlicyd/filter.h @@ -38,13 +38,15 @@ #include "common.h" #include "filter_tokens.h" +#include "hook_tokens.h" #include "query.h" #include "array.h" typedef filter_token filter_type_t; +typedef hook_token filter_result_t; typedef struct filter_hook_t { - char *name; + filter_result_t type; char *value; bool postfix; @@ -70,16 +72,24 @@ typedef struct filter_t { ARRAY(filter_t) #define FILTER_INIT { NULL, FTK_UNKNOWN, ARRAY_INIT, NULL, ARRAY_INIT } +#define CHECK_FILTER(Filter) \ + assert(Filter != FTK_UNKNOWN && Filter != FTK_count \ + && "Unknown filter type") +#define CHECK_HOOK(Hook) \ + assert(Hook != HTK_UNKNOWN && Hook != HTK_count \ + && "Unknown hook") -typedef const char *filter_result_t; typedef filter_result_t (*filter_runner_t)(const filter_t *filter, const query_t *query); typedef bool (*filter_constructor_t)(filter_t *filter); typedef void (*filter_destructor_t)(filter_t *filter); __attribute__((nonnull(1,4))) -void filter_register(const char *type, filter_constructor_t constructor, - filter_destructor_t destructor, filter_runner_t runner); +filter_type_t filter_register(const char *type, filter_constructor_t constructor, + filter_destructor_t destructor, filter_runner_t runner); + +__attribute__((nonnull(2))) +filter_result_t filter_hook_register(filter_type_t filter, const char *name); __attribute__((nonnull(1))) static inline void filter_init(filter_t *filter) @@ -132,7 +142,6 @@ bool filter_update_references(filter_t *filter, A(filter_t) *array); __attribute__((nonnull(1))) static inline void filter_hook_wipe(filter_hook_t *hook) { - p_delete(&hook->name); p_delete(&hook->value); } diff --git a/postlicyd/hook_tokens.sh b/postlicyd/hook_tokens.sh new file mode 100755 index 0000000..82871a5 --- /dev/null +++ b/postlicyd/hook_tokens.sh @@ -0,0 +1,123 @@ +#! /bin/sh -e + +die() { + echo "$@" 1>&2 + exit 2 +} + +do_hdr() { + cat <//g' +%{ +`do_hdr` + +#include "str.h" +#include "`echo "${this%.sh}"`.h" + +static const struct tok * +tokenize_aux(const char *str, unsigned int len); + +%} +struct tok { const char *name; int val; }; +%% +`grep_self "$0" | do_tokens` +%% + +const char *htokens[HTK_count] = { +`grep_self "$0" | sed -e 's/.*/ "&",/'` +}; + +hook_token hook_tokenize(const char *s, ssize_t len) +{ + if (len < 0) + len = m_strlen(s); + + if (len) { + const struct tok *res = tokenize_aux(s, len); + return res ? res->val : HTK_UNKNOWN; + } else { + return HTK_UNKNOWN; + } +} +EOF +} + +grep_self() { + grep 'filter_hook_register(.*, *"' *.c | sed 's/.*filter_hook_register(.*, *"\(.*\)" *).*/\1/' | sort | uniq +} + +trap "rm -f $1" 1 2 3 15 +rm -f $1 +case "$1" in + *.h) do_h > $1;; + *.c) do_c > $1;; + *) die "you must ask for the 'h' or 'c' generation";; +esac +chmod -w $1 + +exit 0 diff --git a/postlicyd/rbl.c b/postlicyd/rbl.c index 3ded455..5267bf6 100644 --- a/postlicyd/rbl.c +++ b/postlicyd/rbl.c @@ -355,7 +355,7 @@ static filter_result_t rbl_filter(const filter_t *filter, const query_t *query) if (parse_ipv4(query->client_address, &end, &ip) != 0) { syslog(LOG_WARNING, "invalid client address: %s, expected ipv4", query->client_address); - return "error"; + return HTK_ERROR; } for (int i = 0 ; i < data->rbls.len ; ++i) { const rbldb_t *rbl = array_elt(data->rbls, i); @@ -365,18 +365,22 @@ static filter_result_t rbl_filter(const filter_t *filter, const query_t *query) } } if (sum > data->hard_threshold) { - return "hard_match"; + return HTK_HARD_MATCH; } else if (sum > data->soft_threshold) { - return "soft_match"; + return HTK_SOFT_MATCH; } else { - return "fail"; + return HTK_FAIL; } } static int rbl_init(void) { - filter_register("rbl", rbl_filter_constructor, rbl_filter_destructor, - rbl_filter); + filter_type_t type = filter_register("rbl", rbl_filter_constructor, + rbl_filter_destructor, rbl_filter); + (void)filter_hook_register(type, "error"); + (void)filter_hook_register(type, "fail"); + (void)filter_hook_register(type, "hard_match"); + (void)filter_hook_register(type, "soft_match"); return 0; } module_init(rbl_init);