]> source.dussan.org Git - rspamd.git/commitdiff
* Add strict priority rules
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 18 Mar 2011 14:20:35 +0000 (17:20 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 18 Mar 2011 14:20:35 +0000 (17:20 +0300)
* Improve and fix multimap module
* Add rspamd_config object to stage of early configure of rspamd

CMakeLists.txt
src/cfg_xml.c
src/lua/lua_common.h
src/lua/lua_config.c
src/plugins/lua/multimap.lua
src/symbols_cache.c
src/symbols_cache.h

index d7384cdef13a1bd0ddd8d525c67f4f5a9780ed85..79ca615fc42c06fc0a1f83ca759aa264909f629c 100644 (file)
@@ -797,9 +797,7 @@ FOREACH(LUA_PLUGIN ${LUA_PLUGINS})
        IF(NOT IS_DIRECTORY ${DESTDIR}/${ETC_PREFIX}/rspamd/plugins/lua/${_rp})
                INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${DESTDIR}/${ETC_PREFIX}/rspamd/plugins/lua/${_rp})")
        ENDIF(NOT IS_DIRECTORY ${DESTDIR}/${ETC_PREFIX}/rspamd/plugins/lua/${_rp})
-       IF(NOT EXISTS ${DESTDIR}/${ETC_PREFIX}/rspamd/plugins/${_rp}/${LUA_PLUGIN})
-               INSTALL(FILES "src/plugins/lua/${LUA_PLUGIN}" DESTINATION etc/rspamd/plugins/lua/${_rp})
-       ENDIF(NOT EXISTS ${DESTDIR}/${ETC_PREFIX}/rspamd/plugins/${_rp}/${LUA_PLUGIN})
+       INSTALL(FILES "src/plugins/lua/${LUA_PLUGIN}" DESTINATION etc/rspamd/plugins/lua/${_rp})
 ENDFOREACH(LUA_PLUGIN)
 
 # Lua config
index 06cdab069c08e0785cb076627c2181b4071e0b1a..2bc83e10943ee55cf3d506fe69631dbab36d68f7 100644 (file)
@@ -974,6 +974,7 @@ handle_lua (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable
 {
        gchar                        *val, *cur_dir, *lua_dir, *lua_file, *tmp1, *tmp2;
        lua_State                    *L = cfg->lua_state;
+       struct config_file           **pcfg;
 
        /* First check for global variable 'config' */
        lua_getglobal (L, "config");
@@ -993,6 +994,13 @@ handle_lua (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable
                lua_newtable (L);
                lua_setglobal (L, "composites");
        }
+       lua_getglobal (L, "rspamd_config");
+       if (lua_isnil (L, -1)) {
+               pcfg = lua_newuserdata (L, sizeof (struct config_file *));
+               lua_setclass (L, "rspamd{config}", -1);
+               *pcfg = cfg;
+               lua_setglobal (L, "rspamd_config");
+       }
        /* Now config tables can be used for configuring rspamd */
        /* First check "src" attribute */
        if (attrs != NULL && (val = g_hash_table_lookup (attrs, "src")) != NULL) {
index 9b0c356f335899aae07522d7e274ce23b0fff7a4..47d6956b0630d51d259145eade4a18acc43b1da5 100644 (file)
@@ -16,7 +16,7 @@
 
 extern const luaL_reg null_reg[];
 
-#define RSPAMD_LUA_API_VERSION 3
+#define RSPAMD_LUA_API_VERSION 4
 
 /* Common utility functions */
 void lua_newclass (lua_State *L, const gchar *classname, const struct luaL_reg *func);
index 62ea849f5255f504a0daa90ff93025885d93aa82..d69036e093c36c743ff99d7109e46df03cbc2289 100644 (file)
@@ -42,6 +42,7 @@ LUA_FUNCTION_DEF (config, get_classifier);
 LUA_FUNCTION_DEF (config, register_symbol);
 LUA_FUNCTION_DEF (config, register_virtual_symbol);
 LUA_FUNCTION_DEF (config, register_callback_symbol);
+LUA_FUNCTION_DEF (config, register_callback_symbol_priority);
 LUA_FUNCTION_DEF (config, register_post_filter);
 LUA_FUNCTION_DEF (config, register_module_option);
 LUA_FUNCTION_DEF (config, get_api_version);
@@ -56,6 +57,7 @@ static const struct luaL_reg    configlib_m[] = {
        LUA_INTERFACE_DEF (config, register_symbol),
        LUA_INTERFACE_DEF (config, register_virtual_symbol),
        LUA_INTERFACE_DEF (config, register_callback_symbol),
+       LUA_INTERFACE_DEF (config, register_callback_symbol_priority),
        LUA_INTERFACE_DEF (config, register_module_option),
        LUA_INTERFACE_DEF (config, register_post_filter),
        LUA_INTERFACE_DEF (config, get_api_version),
@@ -573,6 +575,32 @@ lua_config_register_callback_symbol (lua_State * L)
        return 1;
 }
 
+static gint
+lua_config_register_callback_symbol_priority (lua_State * L)
+{
+       struct config_file             *cfg = lua_check_config (L);
+       const gchar                     *name, *callback;
+       double                          weight;
+       gint                            priority;
+       struct lua_callback_data       *cd;
+
+       if (cfg) {
+               name = memory_pool_strdup (cfg->cfg_pool, luaL_checkstring (L, 2));
+               weight = luaL_checknumber (L, 3);
+               priority = luaL_checknumber (L, 4);
+               callback = luaL_checkstring (L, 5);
+
+               if (name) {
+                       cd = g_malloc (sizeof (struct lua_callback_data));
+                       cd->name = g_strdup (callback);
+                       cd->L = L;
+                       register_callback_symbol_priority (&cfg->cache, name, weight, priority, lua_metric_symbol_callback, cd);
+               }
+       }
+       return 1;
+}
+
+
 /* Radix and hash table functions */
 static gint
 lua_radix_get_key (lua_State * L)
index 023801e459592c267d1ea87abb813902b59c8412..98ebeb35361d67005c53c439444e682f45f7ee44 100644 (file)
@@ -285,6 +285,7 @@ local function add_multimap_rule(params)
                newrule['hash'] = cdb.create(newrule['map'])
                if newrule['hash'] then
                        table.insert(rules, newrule)
+                       return newrule
                else
                        rspamd_logger.warn('Cannot add rule: map doesn\'t exists: ' .. newrule['map'])
                end
@@ -294,6 +295,7 @@ local function add_multimap_rule(params)
                        newrule['ips'] = rspamd_config:add_radix_map (newrule['map'])
                        if newrule['ips'] then
                                table.insert(rules, newrule)
+                               return newrule
                        else
                                rspamd_logger.warn('Cannot add rule: map doesn\'t exists: ' .. newrule['map'])
                        end
@@ -301,6 +303,7 @@ local function add_multimap_rule(params)
                        newrule['hash'] = rspamd_config:add_hash_map (newrule['map'])
                        if newrule['hash'] then
                                table.insert(rules, newrule)
+                               return newrule
                        else
                                rspamd_logger.warn('Cannot add rule: map doesn\'t exists: ' .. newrule['map'])
                        end
@@ -308,14 +311,16 @@ local function add_multimap_rule(params)
                        newrule['hash'] = rspamd_cdb.create(newrule['map'])
                        if newrule['hash'] then
                                table.insert(rules, newrule)
+                               return newrule
                        else
                                rspamd_logger.warn('Cannot add rule: map doesn\'t exists: ' .. newrule['map'])
                        end
                else
                        table.insert(rules, newrule)
+                       return newrule
                end
        end
-       return newrule
+       return nil
 end
 
 -- Registration
@@ -358,7 +363,11 @@ end
 if table.maxn(rules) > 0 then
        -- add fake symbol to check all maps inside a single callback
        if type(rspamd_config.get_api_version) ~= 'nil' then
-               rspamd_config:register_callback_symbol('MULTIMAP', 1.0, 'check_multimap')
+               if rspamd_config.get_api_version() >= 4 then
+                       rspamd_config:register_callback_symbol_priority('MULTIMAP', 1.0, -1, 'check_multimap')
+               else
+                       rspamd_config:register_callback_symbol('MULTIMAP', 1.0, 'check_multimap')
+               end
        else
                rspamd_config:register_symbol('MULTIMAP', 1.0, 'check_multimap')
        end
index ca76ffe86085e439b95eda3a342b9d0277daf3a1..e6bd9a2ced52a60ebf19d9bdabc8250f4173aab3 100644 (file)
@@ -60,12 +60,19 @@ cache_logic_cmp (const void *p1, const void *p2)
        double                          w1, w2;
        double                          f1 = 0, f2 = 0;
 
-       if (total_frequency > 0) {
-               f1 = ((double)i1->s->frequency * nsymbols) / (double)total_frequency;
-               f2 = ((double)i2->s->frequency * nsymbols) / (double)total_frequency;
+       if (i1->priority == 0 && i2->priority == 0) {
+               if (total_frequency > 0) {
+                       f1 = ((double)i1->s->frequency * nsymbols) / (double)total_frequency;
+                       f2 = ((double)i2->s->frequency * nsymbols) / (double)total_frequency;
+               }
+               w1 = abs (i1->s->weight) * WEIGHT_MULT + f1 * FREQUENCY_MULT + i1->s->avg_time * TIME_MULT;
+               w2 = abs (i2->s->weight) * WEIGHT_MULT + f2 * FREQUENCY_MULT + i2->s->avg_time * TIME_MULT;
+       }
+       else {
+               /* Strict sorting */
+               w1 = abs (i1->priority);
+               w2 = abs (i2->priority);
        }
-       w1 = abs (i1->s->weight) * WEIGHT_MULT + f1 * FREQUENCY_MULT + i1->s->avg_time * TIME_MULT;
-       w2 = abs (i2->s->weight) * WEIGHT_MULT + f2 * FREQUENCY_MULT + i2->s->avg_time * TIME_MULT;
 
        return (gint)w2 - w1;
 }
@@ -250,7 +257,7 @@ enum rspamd_symbol_type {
 };
 
 static void
-register_symbol_common (struct symbols_cache **cache, const gchar *name, double weight,
+register_symbol_common (struct symbols_cache **cache, const gchar *name, double weight, gint priority,
                symbol_func_t func, gpointer user_data, enum rspamd_symbol_type type)
 {
        struct cache_item              *item = NULL;
@@ -269,6 +276,7 @@ register_symbol_common (struct symbols_cache **cache, const gchar *name, double
        rspamd_strlcpy (item->s->symbol, name, sizeof (item->s->symbol));
        item->func = func;
        item->user_data = user_data;
+       item->priority = priority;
 
        switch (type) {
        case SYMBOL_TYPE_NORMAL:
@@ -289,11 +297,23 @@ register_symbol_common (struct symbols_cache **cache, const gchar *name, double
                item->s->weight = weight;
        }
 
-       if (item->s->weight > 0) {
-               target = &(*cache)->static_items;
+       /* If we have undefined priority determine list according to weight */
+       if (priority == 0) {
+               if (item->s->weight > 0) {
+                       target = &(*cache)->static_items;
+               }
+               else {
+                       target = &(*cache)->negative_items;
+               }
        }
        else {
-               target = &(*cache)->negative_items;
+               /* Items with more priority are called before items with less priority */
+               if (priority < 0) {
+                       target = &(*cache)->negative_items;
+               }
+               else {
+                       target = &(*cache)->static_items;
+               }
        }
 
        pcache->used_items++;
@@ -307,20 +327,27 @@ void
 register_symbol (struct symbols_cache **cache, const gchar *name, double weight,
                symbol_func_t func, gpointer user_data)
 {
-       register_symbol_common (cache, name, weight, func, user_data, SYMBOL_TYPE_NORMAL);
+       register_symbol_common (cache, name, weight, 0, func, user_data, SYMBOL_TYPE_NORMAL);
 }
 
 void
 register_virtual_symbol (struct symbols_cache **cache, const gchar *name, double weight)
 {
-       register_symbol_common (cache, name, weight, NULL, NULL, SYMBOL_TYPE_VIRTUAL);
+       register_symbol_common (cache, name, weight, 0, NULL, NULL, SYMBOL_TYPE_VIRTUAL);
 }
 
 void
 register_callback_symbol (struct symbols_cache **cache, const gchar *name, double weight,
                symbol_func_t func, gpointer user_data)
 {
-       register_symbol_common (cache, name, weight, func, user_data, SYMBOL_TYPE_CALLBACK);
+       register_symbol_common (cache, name, weight, 0, func, user_data, SYMBOL_TYPE_CALLBACK);
+}
+
+void
+register_callback_symbol_priority (struct symbols_cache **cache, const gchar *name, double weight, gint priority,
+               symbol_func_t func, gpointer user_data)
+{
+       register_symbol_common (cache, name, weight, priority, func, user_data, SYMBOL_TYPE_CALLBACK);
 }
 
 void
@@ -355,6 +382,7 @@ register_dynamic_symbol (memory_pool_t *dynamic_pool, struct symbols_cache **cac
                item->s->weight = weight;
        }
        item->is_dynamic = TRUE;
+       item->priority = 0;
 
        pcache->used_items++;
        msg_debug ("used items: %d, added symbol: %s", (*cache)->used_items, name);
index 2fe03d32a758a5d225d1f26c53478f8ce892633a..6d41f7d7fd24839ec75b7667ed6315360d2edf57 100644 (file)
@@ -40,6 +40,9 @@ struct cache_item {
        /* Flags of virtual symbols */
        gboolean is_virtual;
        gboolean is_callback;
+
+       /* Priority */
+       gint priority;
 };
 
 
@@ -80,6 +83,7 @@ gboolean init_symbols_cache (memory_pool_t *pool, struct symbols_cache *cache, s
  */
 void register_symbol (struct symbols_cache **cache, const gchar *name, double weight, symbol_func_t func, gpointer user_data);
 
+
 /**
  * Register virtual symbol
  * @param name name of symbol
@@ -94,6 +98,14 @@ void register_virtual_symbol (struct symbols_cache **cache, const gchar *name, d
  */
 void register_callback_symbol (struct symbols_cache **cache, const gchar *name, double weight, symbol_func_t func, gpointer user_data);
 
+/**
+ * Register function for symbols parsing with strict priority
+ * @param name name of symbol
+ * @param func pointer to handler
+ * @param user_data pointer to user_data
+ */
+void register_callback_symbol_priority (struct symbols_cache **cache, const gchar *name, double weight, gint priority, symbol_func_t func, gpointer user_data);
+
 /**
  * Register function for dynamic symbols parsing
  * @param name name of symbol