diff options
author | Mikhail Galanin <mgalanin@mimecast.com> | 2018-08-17 16:45:12 +0100 |
---|---|---|
committer | Mikhail Galanin <mgalanin@mimecast.com> | 2018-08-17 16:45:12 +0100 |
commit | 3b5ba9b74e772d9de998350c03e10fb621dc7a3e (patch) | |
tree | 2c28ac85784de96b5406835f713ea1dde307282e /src/lua/lua_dns.c | |
parent | 7eec047b37de8aacaba8d23f6e211cc4ce680b4d (diff) | |
download | rspamd-3b5ba9b74e772d9de998350c03e10fb621dc7a3e.tar.gz rspamd-3b5ba9b74e772d9de998350c03e10fb621dc7a3e.zip |
[Minor] Better naming: lua_rspamd_dns -> lua_dns
Diffstat (limited to 'src/lua/lua_dns.c')
-rw-r--r-- | src/lua/lua_dns.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/lua/lua_dns.c b/src/lua/lua_dns.c new file mode 100644 index 000000000..0d12a137c --- /dev/null +++ b/src/lua/lua_dns.c @@ -0,0 +1,170 @@ +/*- + * 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_dns_resolver.h" +#include "lua_thread_pool.h" + +LUA_FUNCTION_DEF (dns, request); + +static const struct luaL_reg dns_f[] = { + LUA_INTERFACE_DEF (dns, request), + {"__tostring", rspamd_lua_class_tostring}, + {NULL, NULL} +}; + +void +lua_dns_callback (struct rdns_reply *reply, void *arg); + +struct lua_rspamd_dns_cbdata { + struct thread_entry *thread; + struct rspamd_task *task; + struct rspamd_dns_resolver *resolver; + struct rspamd_async_watcher *w; + struct rspamd_async_session *s; +}; + +static gint +lua_dns_request (lua_State *L) +{ + GError *err = NULL; + struct rspamd_async_session *session = NULL; + struct lua_rspamd_dns_cbdata *cbdata = NULL; + const gchar *to_resolve = NULL; + const gchar *type_str = NULL; + struct rspamd_task *task = NULL; + rspamd_mempool_t *pool = NULL; + gint ret = 0; + gboolean forced = FALSE; + + /* Check arguments */ + if (!rspamd_lua_parse_table_arguments (L, 1, &err, + "*name=S;*task=U{task};*type=S;forced=B", + &to_resolve, &task, &type_str, &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) { + session = task->s; + pool = task->task_pool; + } + else { + return luaL_error (L, "invalid arguments: either task or session/config should be set"); + } + + enum rdns_request_type type = rdns_type_fromstr (type_str); + + if (type == RDNS_REQUEST_INVALID) { + return luaL_error (L, "invalid arguments: this record type is not supported"); + } + + cbdata = rspamd_mempool_alloc0 (pool, sizeof (*cbdata)); + + cbdata->task = task; + + if (type == RDNS_REQUEST_PTR) { + 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); + lua_pushnil (L); + + return 1; + } + + to_resolve = rspamd_mempool_strdup (pool, ptr_str); + free (ptr_str); + } + + if (forced) { + ret = make_dns_request_task_forced (task, + lua_dns_callback, + cbdata, + type, + to_resolve); + } + else { + ret = make_dns_request_task (task, + lua_dns_callback, + cbdata, + type, + to_resolve); + } + + if (ret) { + cbdata->thread = lua_thread_pool_get_running_entry (task->cfg->lua_thread_pool); + cbdata->s = session; + cbdata->w = rspamd_session_get_watcher (session); + rspamd_session_watcher_push (session); + return lua_yield_thread (cbdata->thread, 0); + } + else { + lua_pushnil (L); + return 1; + } +} + +void +lua_dns_callback (struct rdns_reply *reply, void *arg) +{ + struct lua_rspamd_dns_cbdata *cbdata = arg; + lua_State *L = cbdata->thread->lua_state; + + if (reply->code != RDNS_RC_NOERROR) { + lua_pushboolean (L, false); + lua_pushstring (L, rdns_strerror (reply->code)); + } + else { + lua_push_dns_reply (L, reply); + + lua_pushboolean (L, reply->authenticated); + lua_setfield (L, -3, "authenticated"); + + /* result 1 - not and error */ + lua_pushboolean (L, true); + /* push table into stack, result 2 - results itself */ + lua_pushvalue (L, -3); + } + + lua_resume_thread (cbdata->task, cbdata->thread, 2); + + if (cbdata->s) { + rspamd_session_watcher_pop (cbdata->s, cbdata->w); + } +} + +static gint +lua_load_dns (lua_State *L) +{ + lua_newtable (L); + luaL_register (L, NULL, dns_f); + + return 1; +} + +void +luaopen_dns (lua_State *L) +{ + rspamd_lua_add_preload (L, "rspamd_dns", lua_load_dns); +} |