+static void strlist_filter_async(rbl_result_t *result, void *arg)
+{
+ filter_context_t *context = arg;
+ const filter_t *filter = context->current_filter;
+ const strlist_config_t *data = filter->data;
+ strlist_async_data_t *async = context->contexts[filter_type];
+
+ if (*result != RBL_ERROR) {
+ async->error = false;
+ }
+ --async->awaited;
+
+ debug("got asynchronous request result for filter %s, rbl %d, still awaiting %d answers",
+ filter->name, result - array_ptr(async->results, 0), async->awaited);
+
+ if (async->awaited == 0) {
+ filter_result_t res = HTK_FAIL;
+ if (async->error) {
+ res = HTK_ERROR;
+ } else {
+ uint32_t j = 0;
+#define DO_SUM(Field) \
+ if (data->match_ ## Field) { \
+ for (uint32_t i = 0 ; i < array_len(data->host_offsets) ; ++i) { \
+ int weight = array_elt(data->host_weights, i); \
+ \
+ switch (array_elt(async->results, j)) { \
+ case RBL_ASYNC: \
+ crit("no more awaited answer but result is ASYNC"); \
+ abort(); \
+ case RBL_FOUND: \
+ async->sum += weight; \
+ break; \
+ default: \
+ break; \
+ } \
+ ++j; \
+ } \
+ }
+ DO_SUM(helo);
+ DO_SUM(client);
+ DO_SUM(reverse);
+ DO_SUM(recipient);
+ DO_SUM(sender);
+#undef DO_SUM
+ debug("score is %d", async->sum);
+ if (async->sum >= (uint32_t)data->hard_threshold) {
+ res = HTK_HARD_MATCH;
+ } else if (async->sum >= (uint32_t)data->soft_threshold) {
+ res = HTK_SOFT_MATCH;
+ }
+ }
+ debug("answering to filter %s", filter->name);
+ filter_post_async_result(context, res);
+ }
+}
+
+
+static filter_result_t strlist_filter(const filter_t *filter, const query_t *query,
+ filter_context_t *context)