]> source.dussan.org Git - rspamd.git/commitdiff
* Add asynchronous DNS resolver to lua API
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 4 Sep 2009 16:01:49 +0000 (20:01 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 4 Sep 2009 16:01:49 +0000 (20:01 +0400)
* Add access to received headers to lua API
* Some code polishing

src/lua/lua_message.c
src/lua/lua_task.c
src/message.c

index bef809230ebade524133d8884febb147975bed97..12d3c05cb893c4e09a3f795c4562a79dda7ff0a5 100644 (file)
@@ -111,6 +111,7 @@ lua_message_get_header (lua_State *L)
        const char *headern;
        GMimeMessage *obj = lua_check_message (L);
        GList *res = NULL, *cur;
+    int i = 1;
 
        if (obj != NULL) {
                headern = luaL_checkstring (L, 2);
@@ -118,8 +119,10 @@ lua_message_get_header (lua_State *L)
                        res = message_get_header (NULL, obj, headern);
                        if (res) {
                                cur = res;
+                lua_newtable (L);
                                while (cur) {
                                        lua_pushstring (L, (const char *)cur->data);
+                    lua_rawseti(L, -2, i++);
                                        g_free (cur->data);
                                        cur = g_list_next (cur);
                                }
@@ -140,6 +143,7 @@ lua_message_get_header (lua_State *L)
        return 1;
 }
 
+
 static int
 lua_message_set_header (lua_State *L)
 {
index 6a6ce5bde99c79dd9084a521d46ad5fe9e8e398b..c688c7c00e5a0dbed2d03598eeafe3c9e8cadaec 100644 (file)
 
 #include "lua_common.h"
 #include "../message.h"
+#include <evdns.h>
 
 /* Task methods */
 LUA_FUNCTION_DEF(task, get_message);
 LUA_FUNCTION_DEF(task, insert_result);
 LUA_FUNCTION_DEF(task, get_urls);
 LUA_FUNCTION_DEF(task, get_text_parts);
+LUA_FUNCTION_DEF(task, get_raw_headers);
+LUA_FUNCTION_DEF(task, get_received_headers);
+LUA_FUNCTION_DEF(task, resolve_dns_a);
+LUA_FUNCTION_DEF(task, resolve_dns_ptr);
 
 static const struct luaL_reg tasklib_m[] = {
        LUA_INTERFACE_DEF(task, get_message),
        LUA_INTERFACE_DEF(task, insert_result),
        LUA_INTERFACE_DEF(task, get_urls),
        LUA_INTERFACE_DEF(task, get_text_parts),
+    LUA_INTERFACE_DEF(task, get_raw_headers),
+    LUA_INTERFACE_DEF(task, get_received_headers),
+       LUA_INTERFACE_DEF(task, resolve_dns_a),
+       LUA_INTERFACE_DEF(task, resolve_dns_ptr),
        {"__tostring", lua_class_tostring},
        {NULL, NULL}
 };
@@ -153,6 +162,165 @@ lua_task_get_text_parts (lua_State *L)
        return 1;
 }
 
+static int
+lua_task_get_raw_headers (lua_State *L)
+{
+       struct worker_task *task = lua_check_task (L);
+
+    if (task) {
+               lua_pushstring (L, task->raw_headers);
+    }
+       else {
+               lua_pushnil (L);
+       }
+
+    return 1;
+}
+
+static int
+lua_task_get_received_headers (lua_State *L)
+{
+       struct worker_task *task = lua_check_task (L);
+       GList *cur;
+       struct received_header *rh;
+       int i = 1;
+
+    if (task) {
+               lua_newtable (L);
+               cur = g_list_first (task->received);
+               while (cur) {
+                       rh = cur->data;
+                       lua_newtable (L);
+                       lua_set_table_index (L, "from_hostname", rh->from_hostname);
+                       lua_set_table_index (L, "from_ip", rh->from_ip);
+                       lua_set_table_index (L, "real_hostname", rh->real_hostname);
+                       lua_set_table_index (L, "real_ip", rh->real_ip);
+                       lua_set_table_index (L, "by_hostname", rh->by_hostname);
+                       lua_rawseti(L, -2, i++);
+                       cur = g_list_next (cur);
+               }
+    }
+       else {
+               lua_pushnil (L);
+       }
+       
+       return 1;
+}
+
+struct lua_dns_callback_data {
+       lua_State *L;
+       struct worker_task *task;
+       const char *callback;
+       const char *to_resolve;
+};
+
+static void 
+lua_dns_callback (int result, char type, int count, int ttl, void *addresses, void *arg)
+{
+       struct lua_dns_callback_data *cd = arg;
+       int i;
+       struct in_addr ina;
+       struct worker_task **ptask;
+
+       lua_getglobal (cd->L, cd->callback);
+       ptask = lua_newuserdata (cd->L, sizeof (struct worker_task *));
+       lua_setclass (cd->L, "rspamd{task}", -1);
+
+       *ptask = cd->task;
+       lua_pushstring (cd->L, cd->to_resolve);
+
+       if (result == DNS_ERR_NONE) {
+               if (type == DNS_IPv4_A) {
+
+                       lua_newtable (cd->L);
+                       for (i = 1; i <= count; i ++) {
+                               memcpy (&ina.s_addr, ((in_addr_t *)addresses) + i - 1, sizeof (in_addr_t));
+                               /* Actually this copy memory, so using of inet_ntoa is valid */
+                               lua_pushstring (cd->L, inet_ntoa (ina));
+                               lua_rawseti (cd->L, -2, i);
+                       }
+                       lua_pushnil (cd->L);
+               }
+               else if (type == DNS_PTR) {
+                       lua_newtable (cd->L);
+                       for (i = 1; i <= count; i ++) {
+                               lua_pushstring (cd->L, ((char **)addresses)[i - 1]);
+                               lua_rawseti (cd->L, -2, i);
+                       }
+                       lua_pushnil (cd->L);
+               }
+               else {
+                       lua_pushnil (cd->L);
+                       lua_pushstring (cd->L, "Unknown reply type");
+               }
+       }
+       else {
+               lua_pushnil (cd->L);
+               lua_pushstring (cd->L, evdns_err_to_string (result));
+       }
+
+       if (lua_pcall (cd->L, 4, 0, 0) != 0) {
+               msg_info ("lua_dns_callback: call to %s failed: %s", cd->callback, lua_tostring (cd->L, -1));
+       }
+
+       cd->task->save.saved --;
+       if (cd->task->save.saved == 0) {
+               /* Call other filters */
+               cd->task->save.saved = 1;
+               process_filters (cd->task);
+       }
+
+}
+
+static int
+lua_task_resolve_dns_a (lua_State *L)
+{
+       struct worker_task *task = lua_check_task (L);
+       struct lua_dns_callback_data *cd;
+
+       if (task) {
+               cd = memory_pool_alloc (task->task_pool, sizeof (struct lua_dns_callback_data));
+               cd->task = task;
+               cd->L = L;
+               cd->to_resolve = memory_pool_strdup (task->task_pool, luaL_checkstring (L, 2));
+               cd->callback = memory_pool_strdup (task->task_pool, luaL_checkstring (L, 3));
+               if (!cd->to_resolve || !cd->callback) {
+                       msg_info ("lua_task_resolve_dns_a: invalid parameters passed to function");
+                       return 0;
+               }
+               if (evdns_resolve_ipv4 (cd->to_resolve, DNS_QUERY_NO_SEARCH, lua_dns_callback, (void *)cd) == 0) {
+                       task->save.saved ++;
+        }
+       }
+       return 0;
+}
+
+static int
+lua_task_resolve_dns_ptr (lua_State *L)
+{
+       struct worker_task *task = lua_check_task (L);
+       struct lua_dns_callback_data *cd;
+       struct in_addr *ina;
+
+       if (task) {
+               cd = memory_pool_alloc (task->task_pool, sizeof (struct lua_dns_callback_data));
+               cd->task = task;
+               cd->L = L;
+               cd->to_resolve = memory_pool_strdup (task->task_pool, luaL_checkstring (L, 2));
+               cd->callback = memory_pool_strdup (task->task_pool, luaL_checkstring (L, 3));
+               ina = memory_pool_alloc (task->task_pool, sizeof (struct in_addr));
+               if (!cd->to_resolve || !cd->callback || !inet_aton (cd->to_resolve, ina)) {
+                       msg_info ("lua_task_resolve_dns_a: invalid parameters passed to function");
+                       return 0;
+               }
+               if (evdns_resolve_reverse (ina, DNS_QUERY_NO_SEARCH, lua_dns_callback, (void *)cd) == 0) {
+                       task->save.saved ++;
+        }
+       }
+       return 0;
+}
+
+
 /**** Textpart implementation *****/
 
 static int
@@ -214,6 +382,7 @@ lua_textpart_get_fuzzy (lua_State *L)
        return 1;
 }
 
+
 /* Init part */
 int
 luaopen_task (lua_State *L)
index e9d692a5d6c494cc3383eb54008b2735450c305a..c84aaf6bbaf6cc882e80af3af33f77195de7ab62 100644 (file)
@@ -286,9 +286,9 @@ parse_recv_header (memory_pool_t *pool, char *line, struct received_header *r)
        char *p, *s, t, **res = NULL;
        int state = 0, next_state = 0;
        
+       g_strstrip (line);
        p = line;
        s = line;
-       while (g_ascii_isspace (*++p));
 
        while (*p) {
                switch (state) {