You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lua_dns.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*-
  2. * Licensed under the Apache License, Version 2.0 (the "License");
  3. * you may not use this file except in compliance with the License.
  4. * You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. */
  14. #include "lua_common.h"
  15. #include "lua_dns_resolver.h"
  16. #include "lua_thread_pool.h"
  17. LUA_FUNCTION_DEF (dns, request);
  18. static const struct luaL_reg dns_f[] = {
  19. LUA_INTERFACE_DEF (dns, request),
  20. {"__tostring", rspamd_lua_class_tostring},
  21. {NULL, NULL}
  22. };
  23. static const gchar *M = "rspamd lua dns";
  24. void lua_dns_callback (struct rdns_reply *reply, void *arg);
  25. struct lua_rspamd_dns_cbdata {
  26. struct thread_entry *thread;
  27. struct rspamd_task *task;
  28. struct rspamd_dns_resolver *resolver;
  29. struct rspamd_symcache_item *item;
  30. struct rspamd_async_session *s;
  31. };
  32. static gint
  33. lua_dns_request (lua_State *L)
  34. {
  35. GError *err = NULL;
  36. struct rspamd_async_session *session = NULL;
  37. struct rspamd_config *cfg = NULL;
  38. struct lua_rspamd_dns_cbdata *cbdata = NULL;
  39. const gchar *to_resolve = NULL;
  40. const gchar *type_str = NULL;
  41. struct rspamd_task *task = NULL;
  42. rspamd_mempool_t *pool = NULL;
  43. gint ret = 0;
  44. gboolean forced = FALSE;
  45. /* Check arguments */
  46. if (!rspamd_lua_parse_table_arguments (L, 1, &err,
  47. RSPAMD_LUA_PARSE_ARGUMENTS_DEFAULT,
  48. "*name=S;task=U{task};*type=S;forced=B;session=U{session};config=U{config}",
  49. &to_resolve,
  50. &task,
  51. &type_str,
  52. &forced,
  53. &session,
  54. &cfg)) {
  55. if (err) {
  56. ret = luaL_error (L, "invalid arguments: %s", err->message);
  57. g_error_free (err);
  58. return ret;
  59. }
  60. return luaL_error (L, "invalid arguments");
  61. }
  62. if (task) {
  63. session = task->s;
  64. pool = task->task_pool;
  65. cfg = task->cfg;
  66. }
  67. else if (session && cfg) {
  68. pool = cfg->cfg_pool;
  69. }
  70. else {
  71. return luaL_error (L, "invalid arguments: either task or session/config should be set");
  72. }
  73. enum rdns_request_type type = rdns_type_fromstr (type_str);
  74. if (type == RDNS_REQUEST_INVALID) {
  75. return luaL_error (L, "invalid arguments: this record type is not supported");
  76. }
  77. cbdata = rspamd_mempool_alloc0 (pool, sizeof (*cbdata));
  78. cbdata->task = task;
  79. if (type == RDNS_REQUEST_PTR) {
  80. char *ptr_str;
  81. ptr_str = rdns_generate_ptr_from_str (to_resolve);
  82. if (ptr_str == NULL) {
  83. msg_err_task_check ("wrong resolve string to PTR request: %s",
  84. to_resolve);
  85. lua_pushnil (L);
  86. return 1;
  87. }
  88. to_resolve = rspamd_mempool_strdup (pool, ptr_str);
  89. free (ptr_str);
  90. }
  91. if (task == NULL) {
  92. ret = (rspamd_dns_resolver_request (cfg->dns_resolver,
  93. session,
  94. pool,
  95. lua_dns_callback,
  96. cbdata,
  97. type,
  98. to_resolve) != NULL);
  99. }
  100. else {
  101. if (forced) {
  102. ret = rspamd_dns_resolver_request_task_forced (task,
  103. lua_dns_callback,
  104. cbdata,
  105. type,
  106. to_resolve);
  107. }
  108. else {
  109. ret = rspamd_dns_resolver_request_task (task,
  110. lua_dns_callback,
  111. cbdata,
  112. type,
  113. to_resolve);
  114. }
  115. }
  116. if (ret) {
  117. cbdata->thread = lua_thread_pool_get_running_entry (cfg->lua_thread_pool);
  118. cbdata->s = session;
  119. if (task) {
  120. cbdata->item = rspamd_symcache_get_cur_item (task);
  121. rspamd_symcache_item_async_inc (task, cbdata->item, M);
  122. }
  123. return lua_thread_yield (cbdata->thread, 0);
  124. }
  125. else {
  126. lua_pushnil (L);
  127. return 1;
  128. }
  129. }
  130. void
  131. lua_dns_callback (struct rdns_reply *reply, void *arg)
  132. {
  133. struct lua_rspamd_dns_cbdata *cbdata = arg;
  134. lua_State *L = cbdata->thread->lua_state;
  135. if (reply->code != RDNS_RC_NOERROR) {
  136. lua_pushboolean (L, false);
  137. lua_pushstring (L, rdns_strerror (reply->code));
  138. }
  139. else {
  140. lua_push_dns_reply (L, reply);
  141. lua_pushboolean (L, reply->authenticated);
  142. lua_setfield (L, -3, "authenticated");
  143. /* result 1 - not and error */
  144. lua_pushboolean (L, true);
  145. /* push table into stack, result 2 - results itself */
  146. lua_pushvalue (L, -3);
  147. }
  148. lua_thread_resume (cbdata->thread, 2);
  149. if (cbdata->item) {
  150. rspamd_symcache_item_async_dec_check (cbdata->task, cbdata->item, M);
  151. }
  152. }
  153. static gint
  154. lua_load_dns (lua_State *L)
  155. {
  156. lua_newtable (L);
  157. luaL_register (L, NULL, dns_f);
  158. return 1;
  159. }
  160. void
  161. luaopen_dns (lua_State *L)
  162. {
  163. rspamd_lua_add_preload (L, "rspamd_dns", lua_load_dns);
  164. }