123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754 |
- /*-
- * Copyright 2016 Vsevolod Stakhov
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "lua_common.h"
- #include "lua_thread_pool.h"
- #include "utlist.h"
-
-
- /***
- * @module rspamd_resolver
- * This module allows to resolve DNS names from LUA code. All resolving is executed
- * asynchronously. Here is an example of name resolution:
- * @example
- local function symbol_callback(task)
- local host = 'example.com'
-
- local function dns_cb(resolver, to_resolve, results, err, _, authenticated)
- if not results then
- rspamd_logger.infox('DNS resolving of %1 failed: %2', host, err)
- return
- end
- for _,r in ipairs(results) do
- -- r is of type rspamd{ip} here, but it can be converted to string
- rspamd_logger.infox('Resolved %1 to %2', host, tostring(r))
- end
- end
-
- task:get_resolver():resolve_a({task = task, name = host, callback = dns_cb})
- end
- */
-
- static const char *M = "rspamd lua dns resolver";
-
- /* Lua bindings */
- LUA_FUNCTION_DEF(dns_resolver, init);
- LUA_FUNCTION_DEF(dns_resolver, resolve_a);
- LUA_FUNCTION_DEF(dns_resolver, resolve_ptr);
- LUA_FUNCTION_DEF(dns_resolver, resolve_txt);
- LUA_FUNCTION_DEF(dns_resolver, resolve_mx);
- LUA_FUNCTION_DEF(dns_resolver, resolve_ns);
- LUA_FUNCTION_DEF(dns_resolver, resolve);
- LUA_FUNCTION_DEF(dns_resolver, idna_convert_utf8);
-
- void lua_push_dns_reply(lua_State *L, const struct rdns_reply *reply);
-
- static const struct luaL_reg dns_resolverlib_f[] = {
- LUA_INTERFACE_DEF(dns_resolver, init),
- {NULL, NULL}};
-
- static const struct luaL_reg dns_resolverlib_m[] = {
- LUA_INTERFACE_DEF(dns_resolver, resolve_a),
- LUA_INTERFACE_DEF(dns_resolver, resolve_ptr),
- LUA_INTERFACE_DEF(dns_resolver, resolve_txt),
- LUA_INTERFACE_DEF(dns_resolver, resolve_mx),
- LUA_INTERFACE_DEF(dns_resolver, resolve_ns),
- LUA_INTERFACE_DEF(dns_resolver, resolve),
- LUA_INTERFACE_DEF(dns_resolver, idna_convert_utf8),
- {"__tostring", rspamd_lua_class_tostring},
- {NULL, NULL}};
-
- struct rspamd_dns_resolver *
- lua_check_dns_resolver(lua_State *L, int pos)
- {
- void *ud = rspamd_lua_check_udata(L, pos, rspamd_resolver_classname);
- luaL_argcheck(L, ud != NULL, pos, "'resolver' expected");
- return ud ? *((struct rspamd_dns_resolver **) ud) : NULL;
- }
-
- struct lua_dns_cbdata {
- struct rspamd_task *task;
- rspamd_mempool_t *pool;
- struct rspamd_dns_resolver *resolver;
- int cbref;
- char *to_resolve;
- char *user_str;
- struct rspamd_symcache_dynamic_item *item;
- struct rspamd_async_session *s;
- };
-
- static int
- lua_dns_get_type(lua_State *L, int argno)
- {
- int type = RDNS_REQUEST_A;
- const char *strtype;
-
- if (lua_type(L, argno) != LUA_TSTRING) {
- lua_pushvalue(L, argno);
- lua_gettable(L, lua_upvalueindex(1));
-
- type = lua_tonumber(L, -1);
- lua_pop(L, 1);
- if (type == 0) {
- rspamd_lua_typerror(L, argno, "dns_request_type");
- }
- }
- else {
- strtype = lua_tostring(L, argno);
- type = rdns_type_fromstr(strtype);
- }
-
- return type;
- }
-
- static void
- lua_dns_resolver_callback(struct rdns_reply *reply, gpointer arg)
- {
- struct lua_dns_cbdata *cd = arg;
- struct rspamd_dns_resolver **presolver;
- lua_State *L;
- struct lua_callback_state cbs;
- rspamd_mempool_t *pool;
- int err_idx;
-
- pool = cd->pool;
- lua_thread_pool_prepare_callback(cd->resolver->cfg->lua_thread_pool, &cbs);
- L = cbs.L;
-
- lua_pushcfunction(L, &rspamd_lua_traceback);
- err_idx = lua_gettop(L);
-
- lua_rawgeti(L, LUA_REGISTRYINDEX, cd->cbref);
-
- presolver = lua_newuserdata(L, sizeof(gpointer));
- rspamd_lua_setclass(L, rspamd_resolver_classname, -1);
-
- *presolver = cd->resolver;
- lua_pushstring(L, cd->to_resolve);
-
- lua_push_dns_reply(L, reply);
-
- /*
- * 1 - resolver
- * 2 - to_resolve
- * 3 - entries | nil
- * 4 - error | nil
- * 5 - user_str
- * 6 - reply->flags & RDNS_AUTH
- * 7 - server
- */
- if (reply->code != RDNS_RC_NOERROR) {
- lua_pushnil(L);
- lua_pushstring(L, rdns_strerror(reply->code));
- }
- if (cd->user_str != NULL) {
- lua_pushstring(L, cd->user_str);
- }
- else {
- lua_pushnil(L);
- }
-
- lua_pushboolean(L, reply->flags & RDNS_AUTH);
-
- const char *servname = rdns_request_get_server(reply->request);
-
- if (servname) {
- lua_pushstring(L, servname);
- }
- else {
- lua_pushnil(L);
- }
-
- if (cd->item) {
- /* We also need to restore the item in case there are some chains */
- rspamd_symcache_set_cur_item(cd->task, cd->item);
- }
-
- if (lua_pcall(L, 7, 0, err_idx) != 0) {
- msg_err_pool_check("call to dns callback failed: %s",
- lua_tostring(L, -1));
- }
-
- lua_settop(L, err_idx - 1);
-
- /* Unref function */
- luaL_unref(L, LUA_REGISTRYINDEX, cd->cbref);
- lua_thread_pool_restore_callback(&cbs);
-
- if (cd->item) {
- rspamd_symcache_item_async_dec_check(cd->task, cd->item, M);
- }
-
- if (!cd->pool) {
- g_free(cd->to_resolve);
- g_free(cd->user_str);
- g_free(cd);
- }
- }
-
- void lua_push_dns_reply(lua_State *L, const struct rdns_reply *reply)
- {
- int i = 0, naddrs = 0;
- struct rdns_reply_entry *elt;
- rspamd_inet_addr_t *addr;
-
- if (reply->code == RDNS_RC_NOERROR) {
- LL_FOREACH(reply->entries, elt)
- {
- naddrs++;
- }
-
- lua_createtable(L, naddrs, 0);
-
- LL_FOREACH(reply->entries, elt)
- {
- if (!rdns_request_has_type(reply->request, elt->type)) {
- /* Unrequested type has been returned, ignore it */
- continue;
- }
-
- switch (elt->type) {
- case RDNS_REQUEST_A:
- addr = rspamd_inet_address_new(AF_INET, &elt->content.a.addr);
- rspamd_lua_ip_push(L, addr);
- rspamd_inet_address_free(addr);
- lua_rawseti(L, -2, ++i);
- break;
- case RDNS_REQUEST_AAAA:
- addr = rspamd_inet_address_new(AF_INET6, &elt->content.aaa.addr);
- rspamd_lua_ip_push(L, addr);
- rspamd_inet_address_free(addr);
- lua_rawseti(L, -2, ++i);
- break;
- case RDNS_REQUEST_NS:
- lua_pushstring(L, elt->content.ns.name);
- lua_rawseti(L, -2, ++i);
- break;
- case RDNS_REQUEST_PTR:
- lua_pushstring(L, elt->content.ptr.name);
- lua_rawseti(L, -2, ++i);
- break;
- case RDNS_REQUEST_TXT:
- case RDNS_REQUEST_SPF:
- lua_pushstring(L, elt->content.txt.data);
- lua_rawseti(L, -2, ++i);
- break;
- case RDNS_REQUEST_MX:
- /* mx['name'], mx['priority'] */
- lua_createtable(L, 0, 2);
- rspamd_lua_table_set(L, "name", elt->content.mx.name);
- lua_pushstring(L, "priority");
- lua_pushinteger(L, elt->content.mx.priority);
- lua_settable(L, -3);
-
- lua_rawseti(L, -2, ++i);
- break;
- case RDNS_REQUEST_SOA:
- lua_createtable(L, 0, 7);
- rspamd_lua_table_set(L, "ns", elt->content.soa.mname);
- rspamd_lua_table_set(L, "contact", elt->content.soa.admin);
- lua_pushstring(L, "serial");
- lua_pushinteger(L, elt->content.soa.serial);
- lua_settable(L, -3);
- lua_pushstring(L, "refresh");
- lua_pushinteger(L, elt->content.soa.refresh);
- lua_settable(L, -3);
- lua_pushstring(L, "retry");
- lua_pushinteger(L, elt->content.soa.retry);
- lua_settable(L, -3);
- lua_pushstring(L, "expiry");
- lua_pushinteger(L, elt->content.soa.expire);
- lua_settable(L, -3);
- /* Negative TTL */
- lua_pushstring(L, "nx");
- lua_pushinteger(L, elt->content.soa.minimum);
- lua_settable(L, -3);
-
- lua_rawseti(L, -2, ++i);
- break;
- case RDNS_REQUEST_CNAME:
- lua_pushstring(L, elt->content.cname.name);
- lua_rawseti(L, -2, ++i);
- break;
- default:
- continue;
- }
- }
- lua_pushnil(L);
- }
- }
-
- /***
- * @function rspamd_resolver.init(ev_base, config)
- * @param {event_base} ev_base event base used for asynchronous events
- * @param {rspamd_config} config rspamd configuration parameters
- * @return {rspamd_resolver} new resolver object associated with the specified base
- */
- static int
- lua_dns_resolver_init(lua_State *L)
- {
- struct rspamd_dns_resolver *resolver, **presolver;
- struct rspamd_config *cfg, **pcfg;
- struct ev_loop *base, **pbase;
-
- /* Check args */
- pbase = rspamd_lua_check_udata(L, 1, rspamd_ev_base_classname);
- luaL_argcheck(L, pbase != NULL, 1, "'ev_base' expected");
- base = pbase ? *(pbase) : NULL;
- pcfg = rspamd_lua_check_udata(L, 2, rspamd_config_classname);
- luaL_argcheck(L, pcfg != NULL, 2, "'config' expected");
- cfg = pcfg ? *(pcfg) : NULL;
-
- if (base != NULL && cfg != NULL) {
- resolver = rspamd_dns_resolver_init(NULL, base, cfg);
- if (resolver) {
- presolver = lua_newuserdata(L, sizeof(gpointer));
- rspamd_lua_setclass(L, rspamd_resolver_classname, -1);
- *presolver = resolver;
- }
- else {
- lua_pushnil(L);
- }
- }
- else {
- lua_pushnil(L);
- }
-
- return 1;
- }
-
- static int
- lua_dns_resolver_resolve_common(lua_State *L,
- struct rspamd_dns_resolver *resolver,
- enum rdns_request_type type,
- int first)
- {
- LUA_TRACE_POINT;
- struct rspamd_async_session *session = NULL;
- rspamd_mempool_t *pool = NULL;
- const char *to_resolve = NULL, *user_str = NULL;
- struct lua_dns_cbdata *cbdata;
- int cbref = -1, ret;
- struct rspamd_task *task = NULL;
- GError *err = NULL;
- gboolean forced = FALSE;
- struct rspamd_symcache_dynamic_item *item = NULL;
-
- /* Check arguments */
- if (!rspamd_lua_parse_table_arguments(L, first, &err,
- RSPAMD_LUA_PARSE_ARGUMENTS_DEFAULT,
- "session=U{session};mempool=U{mempool};*name=S;*callback=F;"
- "option=S;task=U{task};forced=B",
- &session, &pool, &to_resolve, &cbref, &user_str, &task, &forced)) {
-
- if (err) {
- ret = luaL_error(L, "invalid arguments: %s", err->message);
- g_error_free(err);
-
- return ret;
- }
-
- return luaL_error(L, "invalid arguments");
- }
-
- if (task) {
- pool = task->task_pool;
- session = task->s;
- item = rspamd_symcache_get_cur_item(task);
- }
-
- if (to_resolve != NULL) {
- if (pool != NULL) {
- cbdata = rspamd_mempool_alloc0(pool, sizeof(struct lua_dns_cbdata));
- cbdata->user_str = rspamd_mempool_strdup(pool, user_str);
-
- if (type != RDNS_REQUEST_PTR) {
- cbdata->to_resolve = rspamd_mempool_strdup(pool, to_resolve);
- }
- else {
- char *ptr_str;
-
- ptr_str = rdns_generate_ptr_from_str(to_resolve);
-
- if (ptr_str == NULL) {
- msg_err_task_check("wrong resolve string to PTR request: %s",
- to_resolve);
- goto err;
- }
-
- cbdata->to_resolve = rspamd_mempool_strdup(pool, ptr_str);
- to_resolve = cbdata->to_resolve;
- free(ptr_str);
- }
- }
- else {
- cbdata = g_malloc0(sizeof(struct lua_dns_cbdata));
- cbdata->user_str = user_str ? g_strdup(user_str) : NULL;
-
- if (type != RDNS_REQUEST_PTR) {
- cbdata->to_resolve = g_strdup(to_resolve);
- }
- else {
- char *ptr_str;
-
- ptr_str = rdns_generate_ptr_from_str(to_resolve);
-
- if (ptr_str == NULL) {
- msg_err_task_check("wrong resolve string to PTR request: %s",
- to_resolve);
- goto err;
- }
-
- cbdata->to_resolve = g_strdup(ptr_str);
- free(ptr_str);
- }
- }
-
- cbdata->resolver = resolver;
- cbdata->cbref = cbref;
- cbdata->task = task;
- cbdata->pool = pool;
-
- if (task == NULL) {
- if (rspamd_dns_resolver_request(resolver,
- session,
- pool,
- lua_dns_resolver_callback,
- cbdata,
- type,
- to_resolve)) {
-
- lua_pushboolean(L, TRUE);
-
- if (session) {
- cbdata->s = session;
- }
- }
- else {
- goto err;
- }
- }
- else {
- /* Fail-safety as this function can, in theory, call
- * lua_dns_resolver_callback without switching to the event loop
- */
- if (item) {
- rspamd_symcache_item_async_inc(task, item, M);
- }
-
- if (forced) {
- ret = rspamd_dns_resolver_request_task_forced(task,
- lua_dns_resolver_callback,
- cbdata,
- type,
- to_resolve);
- }
- else {
- ret = rspamd_dns_resolver_request_task(task,
- lua_dns_resolver_callback,
- cbdata,
- type,
- to_resolve);
- }
-
- if (ret) {
- cbdata->s = session;
-
- if (item) {
- cbdata->item = item;
- rspamd_symcache_item_async_inc(task, item, M);
- }
- /* callback was set up */
- lua_pushboolean(L, TRUE);
- }
- else {
- if (item) {
- rspamd_symcache_item_async_dec_check(task, item, M);
- }
-
- goto err;
- }
-
- if (item) {
- rspamd_symcache_item_async_dec_check(task, item, M);
- }
- }
- }
- else {
- return luaL_error(L, "invalid arguments to lua_resolve");
- }
-
- return 1;
-
- err:
- /* Callback is not called in this case */
- if (cbdata->cbref != -1) {
- luaL_unref(L, LUA_REGISTRYINDEX, cbdata->cbref);
- }
-
- if (!pool) {
- /* Free resources */
- g_free(cbdata->to_resolve);
- g_free(cbdata->user_str);
- g_free(cbdata);
- }
-
- lua_pushnil(L);
-
- return 1;
- }
-
- /***
- * @method resolver:resolve_a(table)
- * Resolve A record for a specified host.
- * Table elements:
- * * `task` - task element (preferred, required to track dependencies) -or-
- * * `session` - asynchronous session normally associated with rspamd task (`task:get_session()`)
- * * `mempool` - pool memory pool for storing intermediate data
- * * `name` - host name to resolve
- * * `callback` - callback callback function to be called upon name resolution is finished; must be of type `function (resolver, to_resolve, results, err)`
- * * `forced` - true if needed to override normal limit for DNS requests
- * @return {boolean} `true` if DNS request has been scheduled
- */
- static int
- lua_dns_resolver_resolve_a(lua_State *L)
- {
- struct rspamd_dns_resolver *dns_resolver = lua_check_dns_resolver(L, 1);
-
- if (dns_resolver) {
- return lua_dns_resolver_resolve_common(L,
- dns_resolver,
- RDNS_REQUEST_A,
- 2);
- }
- else {
- lua_pushnil(L);
- }
-
- return 1;
- }
-
- /***
- * @method resolver:resolve_ptr(table)
- * Resolve PTR record for a specified host.
- * Table elements:
- * * `task` - task element (preferred, required to track dependencies) -or-
- * * `session` - asynchronous session normally associated with rspamd task (`task:get_session()`)
- * * `mempool` - pool memory pool for storing intermediate data
- * * `name` - host name to resolve
- * * `callback` - callback callback function to be called upon name resolution is finished; must be of type `function (resolver, to_resolve, results, err)`
- * * `forced` - true if needed to override normal limit for DNS requests
- * @return {boolean} `true` if DNS request has been scheduled
- */
- static int
- lua_dns_resolver_resolve_ptr(lua_State *L)
- {
- struct rspamd_dns_resolver *dns_resolver = lua_check_dns_resolver(L, 1);
-
- if (dns_resolver) {
- return lua_dns_resolver_resolve_common(L,
- dns_resolver,
- RDNS_REQUEST_PTR,
- 2);
- }
- else {
- lua_pushnil(L);
- }
-
- return 1;
- }
-
- /***
- * @method resolver:resolve_txt(table)
- * Resolve TXT record for a specified host.
- * Table elements:
- * * `task` - task element (preferred, required to track dependencies) -or-
- * * `session` - asynchronous session normally associated with rspamd task (`task:get_session()`)
- * * `mempool` - pool memory pool for storing intermediate data
- * * `name` - host name to resolve
- * * `callback` - callback callback function to be called upon name resolution is finished; must be of type `function (resolver, to_resolve, results, err)`
- * * `forced` - true if needed to override normal limit for DNS requests
- * @return {boolean} `true` if DNS request has been scheduled
- */
- static int
- lua_dns_resolver_resolve_txt(lua_State *L)
- {
- struct rspamd_dns_resolver *dns_resolver = lua_check_dns_resolver(L, 1);
-
- if (dns_resolver) {
- return lua_dns_resolver_resolve_common(L,
- dns_resolver,
- RDNS_REQUEST_TXT,
- 2);
- }
- else {
- lua_pushnil(L);
- }
-
- return 1;
- }
-
- /***
- * @method resolver:resolve_mx(table)
- * Resolve MX record for a specified host.
- * Table elements:
- * * `task` - task element (preferred, required to track dependencies) -or-
- * * `session` - asynchronous session normally associated with rspamd task (`task:get_session()`)
- * * `mempool` - pool memory pool for storing intermediate data
- * * `name` - host name to resolve
- * * `callback` - callback callback function to be called upon name resolution is finished; must be of type `function (resolver, to_resolve, results, err)`
- * * `forced` - true if needed to override normal limit for DNS requests
- * @return {boolean} `true` if DNS request has been scheduled
- */
- static int
- lua_dns_resolver_resolve_mx(lua_State *L)
- {
- struct rspamd_dns_resolver *dns_resolver = lua_check_dns_resolver(L, 1);
-
- if (dns_resolver) {
- return lua_dns_resolver_resolve_common(L,
- dns_resolver,
- RDNS_REQUEST_MX,
- 2);
- }
- else {
- lua_pushnil(L);
- }
-
- return 1;
- }
-
- /***
- * @method resolver:resolve_ns(table)
- * Resolve NS records for a specified host.
- * Table elements:
- * * `task` - task element (preferred, required to track dependencies) -or-
- * * `session` - asynchronous session normally associated with rspamd task (`task:get_session()`)
- * * `mempool` - pool memory pool for storing intermediate data
- * * `name` - host name to resolve
- * * `callback` - callback callback function to be called upon name resolution is finished; must be of type `function (resolver, to_resolve, results, err)`
- * * `forced` - true if needed to override normal limit for DNS requests
- * @return {boolean} `true` if DNS request has been scheduled
- */
- static int
- lua_dns_resolver_resolve_ns(lua_State *L)
- {
- struct rspamd_dns_resolver *dns_resolver = lua_check_dns_resolver(L, 1);
-
- if (dns_resolver) {
- return lua_dns_resolver_resolve_common(L,
- dns_resolver,
- RDNS_REQUEST_NS,
- 2);
- }
- else {
- lua_pushnil(L);
- }
-
- return 1;
- }
-
- /* XXX: broken currently */
- static int
- lua_dns_resolver_resolve(lua_State *L)
- {
- struct rspamd_dns_resolver *dns_resolver = lua_check_dns_resolver(L, 1);
- int type;
-
- type = lua_dns_get_type(L, 2);
-
- if (dns_resolver && type != 0) {
- return lua_dns_resolver_resolve_common(L, dns_resolver, type, 3);
- }
- else {
- lua_pushnil(L);
- }
-
- return 1;
- }
-
- /***
- * @method resolver:idna_convert_utf8(hostname[, pool])
- * Converts domain name from IDN (in utf8 format) to punycode
- * @return {string} new name converted
- */
- static int
- lua_dns_resolver_idna_convert_utf8(lua_State *L)
- {
- struct rspamd_dns_resolver *dns_resolver = lua_check_dns_resolver(L, 1);
- gsize hlen;
- unsigned int conv_len = 0;
- const char *hname = luaL_checklstring(L, 2, &hlen);
- char *converted;
- rspamd_mempool_t *pool = rspamd_lua_check_udata_maybe(L, 3, rspamd_mempool_classname);
-
-
- if (dns_resolver && hname) {
- if (!rspamd_str_has_8bit(hname, hlen)) {
- /* No 8 bit, no reasons to call idna */
- lua_pushlstring(L, hname, hlen);
- }
- else {
- converted = rspamd_dns_resolver_idna_convert_utf8(dns_resolver, pool,
- hname, hlen, &conv_len);
-
- if (converted == NULL) {
- lua_pushnil(L);
- }
- else {
- lua_pushlstring(L, converted, conv_len);
-
- if (pool == NULL) {
- g_free(converted);
- }
- }
- }
- }
- else {
- return luaL_error(L, "invalid arguments");
- }
-
- return 1;
- }
-
- static int
- lua_load_dns_resolver(lua_State *L)
- {
- lua_newtable(L);
- luaL_register(L, NULL, dns_resolverlib_f);
-
- return 1;
- }
-
- void luaopen_dns_resolver(lua_State *L)
- {
-
- rspamd_lua_new_class(L, rspamd_resolver_classname, dns_resolverlib_m);
- {
- LUA_ENUM(L, DNS_A, RDNS_REQUEST_A);
- LUA_ENUM(L, DNS_PTR, RDNS_REQUEST_PTR);
- LUA_ENUM(L, DNS_MX, RDNS_REQUEST_MX);
- LUA_ENUM(L, DNS_TXT, RDNS_REQUEST_TXT);
- LUA_ENUM(L, DNS_SRV, RDNS_REQUEST_SRV);
- LUA_ENUM(L, DNS_SPF, RDNS_REQUEST_SPF);
- LUA_ENUM(L, DNS_AAAA, RDNS_REQUEST_AAAA);
- LUA_ENUM(L, DNS_SOA, RDNS_REQUEST_SOA);
- LUA_ENUM(L, DNS_CNAME, RDNS_REQUEST_CNAME);
- }
-
- lua_pop(L, 1);
-
- rspamd_lua_add_preload(L, "rspamd_resolver", lua_load_dns_resolver);
- }
|