]> source.dussan.org Git - rspamd.git/commitdiff
* Remove evdns and use only rspamd resolver
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 9 Jul 2010 15:49:59 +0000 (19:49 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 9 Jul 2010 15:49:59 +0000 (19:49 +0400)
CMakeLists.txt
src/dns.c
src/lua/lua_task.c
src/plugins/regexp.c
src/smtp.c
src/smtp.h

index 4de580fbb6cf00884fca621b75df760c115c41e6..f7c7ade72ddf8bb6d9f1a65756c4412bc01c467b 100644 (file)
@@ -487,7 +487,7 @@ ENDIF(ENABLE_PERL MATCHES "ON")
 ADD_SUBDIRECTORY(src/lua)
 
 ADD_SUBDIRECTORY(src/json)
-ADD_SUBDIRECTORY(src/evdns)
+ADD_SUBDIRECTORY(src/evdns)
 ADD_SUBDIRECTORY(src/plugins/custom)
 
 SET(TOKENIZERSSRC  src/tokenizers/tokenizers.c
@@ -594,7 +594,7 @@ TARGET_LINK_LIBRARIES(rspamd "${LUA_LIBRARY}")
 IF(LIBJUDY_LIBRARY)
        TARGET_LINK_LIBRARIES(rspamd Judy)
 ENDIF(LIBJUDY_LIBRARY)
-TARGET_LINK_LIBRARIES(rspamd rspamd_evdns)
+TARGET_LINK_LIBRARIES(rspamd rspamd_evdns)
 TARGET_LINK_LIBRARIES(rspamd event)
 TARGET_LINK_LIBRARIES(rspamd rspamd_json)
 TARGET_LINK_LIBRARIES(rspamd ${CMAKE_REQUIRED_LIBRARIES})
index e9f057b5ef11b5c9b057e47d72a7314f93556c87..58ca9ffe2f01f5d98262d9ea7b96239e6701717d 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -560,6 +560,7 @@ dns_fin_cb (gpointer arg)
 {
        struct rspamd_dns_request *req = arg;
        
+       event_del (&req->timer_event);
        g_hash_table_remove (req->resolver->requests, GUINT_TO_POINTER (req->id));
 }
 
@@ -735,7 +736,6 @@ dns_parse_rr (guint8 *in, union rspamd_reply_element *elt, guint8 **pos, struct
 {
        guint8 *p = *pos;
        guint16 type, datalen;
-       guint16 addrcount;
 
        /* Skip the whole name */
        if (! dns_parse_labels (in, NULL, &p, rep, remain, FALSE)) {
@@ -759,10 +759,8 @@ dns_parse_rr (guint8 *in, union rspamd_reply_element *elt, guint8 **pos, struct
                }
                else {
                        if (!(datalen & 0x3) && datalen <= *remain) {
-                               addrcount = MIN (elt->a.addrcount + (datalen >> 2), MAX_ADDRS);
-                               memcpy (&elt->a.addr[elt->a.addrcount], p, addrcount * sizeof (struct in_addr));
+                               memcpy (&elt->a.addr[0], p, sizeof (struct in_addr));
                                p += datalen;
-                               elt->a.addrcount += addrcount;
                        }
                        else {
                                msg_info ("corrupted A record");
index 123cd048ea5fbefe1848b899772ee3bd83bf3c3d..a8258cb2a86f837a0b3249a2706064f21bb66761 100644 (file)
@@ -26,7 +26,7 @@
 #include "lua_common.h"
 #include "../message.h"
 #include "../expressions.h"
-#include "../evdns/evdns.h"
+#include "../dns.h"
 
 /* Task methods */
 LUA_FUNCTION_DEF (task, get_message);
@@ -37,6 +37,7 @@ 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);
+LUA_FUNCTION_DEF (task, resolve_dns_txt);
 LUA_FUNCTION_DEF (task, call_rspamd_function);
 LUA_FUNCTION_DEF (task, get_recipients);
 LUA_FUNCTION_DEF (task, get_from);
@@ -54,6 +55,7 @@ static const struct luaL_reg    tasklib_m[] = {
        LUA_INTERFACE_DEF (task, get_received_headers),
        LUA_INTERFACE_DEF (task, resolve_dns_a),
        LUA_INTERFACE_DEF (task, resolve_dns_ptr),
+       LUA_INTERFACE_DEF (task, resolve_dns_txt),
        LUA_INTERFACE_DEF (task, call_rspamd_function),
        LUA_INTERFACE_DEF (task, get_recipients),
        LUA_INTERFACE_DEF (task, get_from),
@@ -238,12 +240,14 @@ struct lua_dns_callback_data {
 };
 
 static void
-lua_dns_callback (int result, char type, int count, int ttl, void *addresses, void *arg)
+lua_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
 {
        struct lua_dns_callback_data   *cd = arg;
-       int                             i;
+       int                             i = 0;
        struct in_addr                  ina;
        struct worker_task            **ptask;
+       union rspamd_reply_element     *elt;
+       GList                          *cur;
 
        lua_getglobal (cd->L, cd->callback);
        ptask = lua_newuserdata (cd->L, sizeof (struct worker_task *));
@@ -252,25 +256,41 @@ lua_dns_callback (int result, char type, int count, int ttl, void *addresses, vo
        *ptask = cd->task;
        lua_pushstring (cd->L, cd->to_resolve);
 
-       if (result == DNS_ERR_NONE) {
-               if (type == DNS_IPv4_A) {
+       if (reply->code == DNS_RC_NOERROR) {
+               if (reply->type == DNS_REQUEST_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));
+                       cur = reply->elements;
+                       while (cur) {
+                               elt = cur->data;
+                               memcpy (&ina, elt->a.addr, 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_rawseti (cd->L, -2, ++i);
+                       }
+                       lua_pushnil (cd->L);
+               }
+               else if (reply->type == DNS_REQUEST_A) {
+                       lua_newtable (cd->L);
+                       cur = reply->elements;
+                       while (cur) {
+                               elt = cur->data;
+                               lua_pushstring (cd->L, elt->ptr.name);
+                               lua_rawseti (cd->L, -2, ++i);
                        }
                        lua_pushnil (cd->L);
+
                }
-               else if (type == DNS_PTR) {
+               else if (reply->type == DNS_REQUEST_TXT) {
                        lua_newtable (cd->L);
-                       for (i = 1; i <= count; i++) {
-                               lua_pushstring (cd->L, ((char **)addresses)[i - 1]);
-                               lua_rawseti (cd->L, -2, i);
+                       cur = reply->elements;
+                       while (cur) {
+                               elt = cur->data;
+                               lua_pushstring (cd->L, elt->txt.data);
+                               lua_rawseti (cd->L, -2, ++i);
                        }
                        lua_pushnil (cd->L);
+
                }
                else {
                        lua_pushnil (cd->L);
@@ -279,7 +299,7 @@ lua_dns_callback (int result, char type, int count, int ttl, void *addresses, vo
        }
        else {
                lua_pushnil (cd->L);
-               lua_pushstring (cd->L, evdns_err_to_string (result));
+               lua_pushstring (cd->L, dns_strerror (reply->code));
        }
 
        if (lua_pcall (cd->L, 4, 0, 0) != 0) {
@@ -292,8 +312,6 @@ lua_dns_callback (int result, char type, int count, int ttl, void *addresses, vo
                cd->task->save.saved = 1;
                process_filters (cd->task);
        }
-       remove_forced_event (cd->task->s, (event_finalizer_t) lua_dns_callback);
-
 }
 
 static int
@@ -312,9 +330,31 @@ lua_task_resolve_dns_a (lua_State * L)
                        msg_info ("invalid parameters passed to function");
                        return 0;
                }
-               if (evdns_resolve_ipv4 (cd->to_resolve, DNS_QUERY_NO_SEARCH, lua_dns_callback, (void *)cd) == 0) {
+               if (make_dns_request (task->resolver, task->s, task->task_pool, lua_dns_callback, (void *)cd, DNS_REQUEST_A, cd->to_resolve)) {
+                       task->save.saved++;
+               }
+       }
+       return 0;
+}
+
+static int
+lua_task_resolve_dns_txt (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 ("invalid parameters passed to function");
+                       return 0;
+               }
+               if (make_dns_request (task->resolver, task->s, task->task_pool, lua_dns_callback, (void *)cd, DNS_REQUEST_TXT, cd->to_resolve)) {
                        task->save.saved++;
-                       register_async_event (task->s, (event_finalizer_t) lua_dns_callback, NULL, TRUE);
                }
        }
        return 0;
@@ -338,9 +378,8 @@ lua_task_resolve_dns_ptr (lua_State * L)
                        msg_info ("invalid parameters passed to function");
                        return 0;
                }
-               if (evdns_resolve_reverse (ina, DNS_QUERY_NO_SEARCH, lua_dns_callback, (void *)cd) == 0) {
+               if (make_dns_request (task->resolver, task->s, task->task_pool, lua_dns_callback, (void *)cd, DNS_REQUEST_PTR, ina)) {
                        task->save.saved++;
-                       register_async_event (task->s, (event_finalizer_t) lua_dns_callback, NULL, TRUE);
                }
        }
        return 0;
index 58e91d14bded82ca6901d5b9f20d3f1de7b61ba6..160d9e2078e8a76e9f79ea429ccd7ff2774c172e 100644 (file)
@@ -39,7 +39,6 @@
 #include "../view.h"
 #include "../lua/lua_common.h"
 #include "../json/jansson.h"
-#include "../evdns/evdns.h"
 
 #define DEFAULT_STATFILE_PREFIX "./"
 
index 885a1f681c6f0d5bd964a3168fbadfbe3c915a4a..24f03296c6ab7c13917eeb87ec3e171d587cb500 100644 (file)
@@ -31,7 +31,7 @@
 #include "map.h"
 #include "message.h"
 #include "settings.h"
-#include "evdns/evdns.h"
+#include "dns.h"
 
 /* Max line size as it is defined in rfc2822 */
 #define OUTBUFSIZ 1000
@@ -190,7 +190,6 @@ call_stage_filters (struct smtp_session *session, enum rspamd_smtp_stage stage)
 static gboolean
 read_smtp_command (struct smtp_session *session, f_str_t *line)
 {
-       /* XXX: write dialog implementation */
        struct smtp_command             *cmd;
        char                             outbuf[BUFSIZ];
        int                              r;
@@ -703,19 +702,21 @@ smtp_make_delay (struct smtp_session *session)
  * Handle DNS replies
  */
 static void
-smtp_dns_cb (int result, char type, int count, int ttl, void *addresses, void *arg)
+smtp_dns_cb (struct rspamd_dns_reply *reply, void *arg)
 {
        struct smtp_session            *session = arg;
-       int                             i, res = 0;
+       int                             res = 0;
+       union rspamd_reply_element     *elt;
+       GList                          *cur;
        
        remove_forced_event (session->s, (event_finalizer_t)smtp_dns_cb);
        switch (session->state) {
                case SMTP_STATE_RESOLVE_REVERSE:
                        /* Parse reverse reply and start resolve of this ip */
-                       if (result != DNS_ERR_NONE || type != DNS_PTR) {
-                               debug_ip (session->client_addr.s_addr, "DNS error: %s", evdns_err_to_string (result));
+                       if (reply->code != DNS_RC_NOERROR) {
+                               debug_ip (session->client_addr.s_addr, "DNS error: %s", dns_strerror (reply->code));
                                
-                               if (result == DNS_ERR_NOTEXIST) {
+                               if (reply->code == DNS_RC_NXDOMAIN) {
                                        session->hostname = memory_pool_strdup (session->pool, "unknown");
                                }
                                else {
@@ -725,19 +726,20 @@ smtp_dns_cb (int result, char type, int count, int ttl, void *addresses, void *a
                                smtp_make_delay (session);
                        }
                        else {
-                               if (addresses) {
-                                       session->hostname = memory_pool_strdup (session->pool, * ((const char**)addresses));
+                               if (reply->elements) {
+                                       elt = reply->elements->data;
+                                       session->hostname = memory_pool_strdup (session->pool, elt->ptr.name);
                                        session->state = SMTP_STATE_RESOLVE_NORMAL;
-                                       evdns_resolve_ipv4 (session->hostname, DNS_QUERY_NO_SEARCH, smtp_dns_cb, (void *)session);
-                                       register_async_event (session->s, (event_finalizer_t)smtp_dns_cb, NULL, TRUE);
+                                       make_dns_request (session->resolver, session->s, session->pool, smtp_dns_cb, session, DNS_REQUEST_A, session->hostname);
                                        
                                }
                        }
                        break;
                case SMTP_STATE_RESOLVE_NORMAL:
-                       if (result != DNS_ERR_NONE || type != DNS_IPv4_A) {
-                               debug_ip (session->client_addr.s_addr, "DNS error: %s", evdns_err_to_string (result));
-                               if (result == DNS_ERR_NOTEXIST) {
+                       if (reply->code != DNS_RC_NOERROR) {
+                               debug_ip (session->client_addr.s_addr, "DNS error: %s", dns_strerror (reply->code));
+
+                               if (reply->code == DNS_RC_NXDOMAIN) {
                                        session->hostname = memory_pool_strdup (session->pool, "unknown");
                                }
                                else {
@@ -748,12 +750,15 @@ smtp_dns_cb (int result, char type, int count, int ttl, void *addresses, void *a
                        }
                        else {
                                res = 0;
-                               for (i = 0; i < count; i++) {
-                                       if (session->client_addr.s_addr == ((in_addr_t *)addresses)[i]) {
+                               cur = reply->elements;
+                               while (cur) {
+                                       elt = cur->data;
+                                       if (memcmp (&session->client_addr, &elt->a.addr[0], sizeof (struct in_addr)) == 0) {
                                                res = 1;
                                                session->resolved = TRUE;
                                                break;
                                        }
+                                       cur = g_list_next (cur);
                                }
 
                                if (res == 0) {
@@ -786,6 +791,7 @@ accept_socket (int fd, short what, void *arg)
        struct rspamd_worker           *worker = (struct rspamd_worker *)arg;
        union sa_union                  su;
        struct smtp_session            *session;
+       struct smtp_worker_ctx         *ctx;
 
        socklen_t                       addrlen = sizeof (su.ss);
        int                             nfd;
@@ -799,6 +805,7 @@ accept_socket (int fd, short what, void *arg)
                return;
        }
 
+       ctx = worker->ctx;
        session = g_malloc0 (sizeof (struct smtp_session));
        session->pool = memory_pool_new (memory_pool_get_size ());
 
@@ -814,24 +821,23 @@ accept_socket (int fd, short what, void *arg)
        session->sock = nfd;
        session->temp_fd = -1;
        session->worker = worker;
-       session->ctx = worker->ctx;
+       session->ctx = ctx;
        session->cfg = worker->srv->cfg;
        session->session_time = time (NULL);
+       session->resolver = ctx->resolver;
        worker->srv->stat->connections_count++;
 
        /* Resolve client's addr */
+       /* Set up async session */
+       session->s = new_async_session (session->pool, free_smtp_session, session);
        session->state = SMTP_STATE_RESOLVE_REVERSE;
-       if (evdns_resolve_reverse (&session->client_addr, DNS_QUERY_NO_SEARCH, smtp_dns_cb, session) != 0) {
+       if (! make_dns_request (session->resolver, session->s, session->pool, smtp_dns_cb, session, DNS_REQUEST_A, session->client_addr)) {
                msg_err ("cannot resolve %s", inet_ntoa (session->client_addr));
                g_free (session);
                close (nfd);
                return;
        }
        else {
-               /* Set up async session */
-               session->s = new_async_session (session->pool, free_smtp_session, session);
-               register_async_event (session->s, (event_finalizer_t)smtp_dns_cb, NULL, TRUE);
-               /* Set up dispatcher */
                session->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, 
                                                                smtp_read_socket, smtp_write_socket, smtp_err_socket, &session->ctx->smtp_timeout, session);
                session->dispatcher->peer_addr = session->client_addr.s_addr;
@@ -1092,6 +1098,8 @@ config_smtp_worker (struct rspamd_worker *worker)
                ctx->reject_message = DEFAULT_REJECT_MESSAGE;
        }
 
+       ctx->resolver = dns_resolver_init (worker->srv->cfg);
+
        /* Set ctx */
        worker->ctx = ctx;
        
@@ -1119,7 +1127,6 @@ start_smtp_worker (struct rspamd_worker *worker)
        }
 
        event_init ();
-       evdns_init ();
 
        init_signals (&signals, sig_handler);
        sigprocmask (SIG_UNBLOCK, &signals.sa_mask, NULL);
index 595917dfca68ae1d566b24e2c28d08c5e136c2cc..411d03003368c75c2b2854f5571b5f83f51bf48b 100644 (file)
@@ -14,6 +14,8 @@ struct smtp_upstream {
        gboolean is_unix;
 }; 
 
+struct rspamd_dns_resolver;
+
 #define MAX_UPSTREAM 128
 #define DEFAULT_MAX_ERRORS 10
 
@@ -44,6 +46,7 @@ struct smtp_worker_ctx {
        guint max_errors;
        char *metric;
        GList *smtp_filters[SMTP_STAGE_MAX];
+       struct rspamd_dns_resolver *resolver;
 };
 
 enum rspamd_smtp_state {
@@ -102,6 +105,7 @@ struct smtp_session {
 
        gboolean resolved;
        gboolean esmtp;
+       struct rspamd_dns_resolver *resolver;
 };
 
 typedef gboolean (*smtp_filter_t)(struct smtp_session *session, gpointer filter_data);