diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-09-04 20:01:49 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-09-04 20:01:49 +0400 |
commit | ab946cd1efd6b2ffcf1080d2a4f4c66dda811ef3 (patch) | |
tree | e8c37dce549de1785acd02e9a200521386026ea4 | |
parent | 36e8776498484a27af13a623ca1c78603ba6c7f6 (diff) | |
download | rspamd-ab946cd1efd6b2ffcf1080d2a4f4c66dda811ef3.tar.gz rspamd-ab946cd1efd6b2ffcf1080d2a4f4c66dda811ef3.zip |
* Add asynchronous DNS resolver to lua API
* Add access to received headers to lua API
* Some code polishing
-rw-r--r-- | src/lua/lua_message.c | 4 | ||||
-rw-r--r-- | src/lua/lua_task.c | 169 | ||||
-rw-r--r-- | src/message.c | 2 |
3 files changed, 174 insertions, 1 deletions
diff --git a/src/lua/lua_message.c b/src/lua/lua_message.c index bef809230..12d3c05cb 100644 --- a/src/lua/lua_message.c +++ b/src/lua/lua_message.c @@ -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) { diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 6a6ce5bde..c688c7c00 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -25,18 +25,27 @@ #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) diff --git a/src/message.c b/src/message.c index e9d692a5d..c84aaf6bb 100644 --- a/src/message.c +++ b/src/message.c @@ -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) { |