Merge commit 'pan/master' into not-linux
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Tue, 14 Oct 2008 22:28:35 +0000 (00:28 +0200)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Tue, 14 Oct 2008 22:28:35 +0000 (00:28 +0200)
Conflicts:
postlicyd/filter.c
postlicyd/main-postlicyd.c

Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
1  2 
mk/common.mk
postlicyd/Makefile
postlicyd/filter.c
postlicyd/main-postlicyd.c

diff --combined mk/common.mk
@@@ -1,8 -1,8 +1,8 @@@
  include ../mk/cflags.mk
  
  prefix ?= /usr/local
 -LDFLAGS += -Wl,--warn-common
 -CFLAGS  += --std=gnu99 -D_GNU_SOURCE -I../ -I../common
 +LDFLAGS += -L/opt/local/lib
 +CFLAGS  += --std=gnu99 -I../ -I../common -I/opt/local/include
  
  INSTALL_PROGS = $(addprefix install-,$(PROGRAMS))
  
@@@ -49,8 -49,8 +49,8 @@@ $(LIBS:=.a): $$(patsubst %.c,.%.o,$$($$
        $(RM) $@
        $(AR) rcs $@ $(filter %.o,$^)
  
--$(PROGRAMS) $(TESTS): $$(patsubst %.c,.%.o,$$($$@_SOURCES)) Makefile ../common.ld
 -      $(CC) -o $@ $(filter %.ld,$^) $(filter %.o,$^) $(LDFLAGS) $($@_LIBADD) $(filter %.a,$^)
++$(PROGRAMS) $(TESTS): $$(patsubst %.c,.%.o,$$($$@_SOURCES)) Makefile
 +      $(CC) -o $@ $(filter %.o,$^) $(LDFLAGS) $($@_LIBADD) $(filter %.a,$^)
  
  -include $(foreach p,$(PROGRAMS) $(TESTS),$(patsubst %.c,.%.dep,$(filter %.c,$($p_SOURCES))))
  
diff --combined postlicyd/Makefile
@@@ -40,10 -40,10 +40,10 @@@ TESTS     = tst-rbl tst-filters tst-gre
  
  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)
 +postlicyd_LIBADD  = $(UB_LIBS) $(TC_LIBS) -lev
  
  tst-rbl_SOURCES   = tst-rbl.c ../common/lib.a filter.c config.c query.c iplist.c $(GENERATED)
  
diff --combined postlicyd/filter.c
@@@ -50,6 -50,8 +50,8 @@@ static filter_async_handler_t       asy
  static const filter_hook_t default_hook = {
      .type      = 0,
      .value     = (char*)"DUNNO",
+     .counter   = -1,
+     .cost      = 0,
      .postfix   = true,
      .async     = false,
      .filter_id = 0
@@@ -58,6 -60,8 +60,8 @@@
  static const filter_hook_t async_hook = {
      .type      = 0,
      .value     = NULL,
+     .counter   = -1,
+     .cost      = 0,
      .postfix   = false,
      .async     = true,
      .filter_id = 0
@@@ -277,6 -281,6 +281,7 @@@ bool filter_add_hook(filter_t *filter, 
                       const char *value, int value_len)
  {
      filter_hook_t hook;
++    hook.filter_id = -1;
      hook.type  = hook_tokenize(name, name_len);
      if (hook.type == HTK_UNKNOWN) {
          err("unknown hook type %.*s", name_len, name);
              htokens[hook.type], ftokens[filter->type]);
          return false;
      }
-     hook.async     = false;
-     hook.filter_id = -1;
-     hook.value      = NULL;
+     hook.async   = false;
+     /* Value format is (counter:id:incr)?(postfix:reply|filter_name)
+      */
++    hook.value = NULL;
+     if (strncmp(value, "counter:", 8) == 0) {
+         char *end = NULL;
+         value += 8;
+         hook.counter = strtol(value, &end, 10);
+         if (end == value || *end != ':') {
+               err("hook %s, cannot read counter id", htokens[hook.type]);
+               return false;
+         } else if (hook.counter < 0 || hook.counter >= MAX_COUNTERS) {
+             err("hook %s, invalid counter id %d", htokens[hook.type], hook.counter);
+             return false;
+         }
+         value = end + 1;
+         hook.cost = strtol(value, &end, 10);
+         if (end == value || *end != ':') {
+             err("hook %s, cannot read counter increment", htokens[hook.type]);
+             return false;
+         } else if (hook.cost < 0) {
+             err("hook %s, invalid counter increment value %d", htokens[hook.type],
+                 hook.cost);
+             return false;
+         }
+         value = end + 1;
+     } else {
+         hook.counter = -1;
+         hook.cost    = 0;
+     }
      hook.postfix = (strncmp(value, "postfix:", 8) == 0);
      if (hook.postfix && query_format(NULL, 0, value + 8, NULL) == -1) {
          err("invalid formatted text \"%s\"", value + 8);
          return false;
      }
      hook.value = m_strdup(hook.postfix ? value + 8 : value);
 -    hook.filter_id = -1;
      array_add(filter->hooks, hook);
      return true;
  }
@@@ -320,6 -352,12 +353,12 @@@ void filter_context_wipe(filter_context
      }
  }
  
+ void filter_context_clean(filter_context_t *context)
+ {
+     p_clear(&context->counters, 1);
+     context->instance[0] = '\0';
+ }
  void filter_post_async_result(filter_context_t *context, filter_result_t result)
  {
      const filter_t *filter = context->current_filter;
@@@ -38,6 -38,7 +38,6 @@@
  
  #include "buffer.h"
  #include "common.h"
 -#include "epoll.h"
  #include "policy_tokens.h"
  #include "server.h"
  #include "config.h"
@@@ -51,9 -52,8 +51,9 @@@
  
  DECLARE_MAIN
  
 -static config_t *config = NULL;
 -
 +static config_t *config  = NULL;
 +static bool refresh      = false;
 +static PA(server_t) busy = ARRAY_INIT;
  
  static void *query_starter(server_t* server)
  {
@@@ -73,17 -73,12 +73,17 @@@ static void query_stopper(void *data
  
  static bool config_refresh(void *mconfig)
  {
 +    refresh = true;
      if (filter_running > 0) {
 -        sighup = true;
 -        sleep(1);
          return true;
      }
 -    return config_reload(mconfig);
 +    bool ret = config_reload(mconfig);
 +    foreach (server_t **server, busy) {
 +        server_ro(*server);
 +    }}
 +    array_len(busy) = 0;
 +    refresh = false;
 +    return ret;
  }
  
  static void policy_answer(server_t *pcy, const char *message)
      }
      buffer_addstr(&pcy->obuf, "\n\n");
      buffer_consume(&pcy->ibuf, query->eoq - pcy->ibuf.data);
 -    epoll_modify(pcy->fd, EPOLLIN | EPOLLOUT, pcy);
 +    server_rw(pcy);
  }
  
  static const filter_t *next_filter(server_t *pcy, const filter_t *filter,
                                     const query_t *query, const filter_hook_t *hook, bool *ok) {
+     if (hook != NULL) {
+         query_context_t *context = pcy->data;
+         if (hook->counter >= 0 && hook->counter < MAX_COUNTERS && hook->cost > 0) {
+             context->context.counters[hook->counter] += hook->cost;
+             debug("request client=%s, from=<%s>, to=<%s>: added %d to counter %d (now %u)",
+                   query->client_name,
+                   query->sender == NULL ? "undefined" : query->sender,
+                   query->recipient == NULL ? "undefined" : query->recipient,
+                   hook->cost, hook->counter, context->context.counters[hook->counter]);
+         }
+     }
      if (hook == NULL) {
          warn("request client=%s, from=<%s>, to=<%s>: aborted",
               query->client_name,
@@@ -180,8 -186,7 +191,8 @@@ static bool policy_process(server_t *pc
  
  static int policy_run(server_t *pcy, void* vconfig)
  {
 -    if (sighup) {
 +    if (refresh) {
 +        array_add(busy, pcy);
          return 0;
      }
  
      if (!query_parse(pcy->data, pcy->ibuf.data))
          return -1;
      query->eoq = eoq + strlen("\n\n");
 -    epoll_modify(pcy->fd, 0, pcy);
+     if (query->instance == NULL || strcmp(context->context.instance, query->instance) != 0) {
+         filter_context_clean(&context->context);
+         m_strcat(context->context.instance, 64, query->instance);
+     }
 +    server_none(pcy);
      return policy_process(pcy, mconfig) ? 0 : -1;
  }
  
@@@ -231,9 -240,6 +246,9 @@@ static void policy_async_handler(filter
      if (!ok) {
          server_release(server);
      }
 +    if (refresh && filter_running == 0) {
 +        config_refresh(config);
 +    }
  }
  
  static int postlicyd_init(void)
      filter_async_handler_register(policy_async_handler);
      return 0;
  }
 +
 +static void postlicyd_shutdown(void)
 +{
 +    array_deep_wipe(busy, server_delete);
 +}
  module_init(postlicyd_init);
 +module_exit(postlicyd_shutdown);
  
  int start_listener(int port)
  {