From 54792e26fbc26ef0a724c2b301dd74a788e3f6dd Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 9 Jul 2010 19:49:59 +0400 Subject: [PATCH] * Remove evdns and use only rspamd resolver --- CMakeLists.txt | 4 +-- src/dns.c | 6 ++-- src/lua/lua_task.c | 77 +++++++++++++++++++++++++++++++++----------- src/plugins/regexp.c | 1 - src/smtp.c | 53 +++++++++++++++++------------- src/smtp.h | 4 +++ 6 files changed, 96 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4de580fbb..f7c7ade72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}) diff --git a/src/dns.c b/src/dns.c index e9f057b5e..58ca9ffe2 100644 --- 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"); diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 123cd048e..a8258cb2a 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -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; diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index 58e91d14b..160d9e207 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -39,7 +39,6 @@ #include "../view.h" #include "../lua/lua_common.h" #include "../json/jansson.h" -#include "../evdns/evdns.h" #define DEFAULT_STATFILE_PREFIX "./" diff --git a/src/smtp.c b/src/smtp.c index 885a1f681..24f03296c 100644 --- a/src/smtp.c +++ b/src/smtp.c @@ -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); diff --git a/src/smtp.h b/src/smtp.h index 595917dfc..411d03003 100644 --- a/src/smtp.h +++ b/src/smtp.h @@ -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); -- 2.39.5