auto *ctx = g_new0(struct rspamd_external_libs_ctx, 1);
ctx->crypto_ctx = rspamd_cryptobox_init();
+ rspamd_task_registry_init();
ottery_cfg = (struct ottery_config *) g_malloc0(ottery_get_sizeof_config());
ottery_config_init(ottery_cfg);
ctx->ottery_cfg = ottery_cfg;
}
rspamd_cryptobox_deinit(ctx->crypto_ctx);
+ rspamd_task_registry_destroy();
g_free(ctx);
}
rspamd_ftok_t *, struct rspamd_request_header_chain *, 1,
rspamd_ftok_icase_hash, rspamd_ftok_icase_equal)
+/* Task registry: maps lua_key -> task pointer for safe Lua references */
+KHASH_INIT(rspamd_task_registry, uint64_t, struct rspamd_task *, 1,
+ kh_int64_hash_func, kh_int64_hash_equal);
+
+static khash_t(rspamd_task_registry) *task_registry = NULL;
+static uint64_t task_lua_key_counter = 0;
+
+void rspamd_task_registry_init(void)
+{
+ if (task_registry == NULL) {
+ task_registry = kh_init(rspamd_task_registry);
+ }
+}
+
+void rspamd_task_registry_destroy(void)
+{
+ if (task_registry != NULL) {
+ kh_destroy(rspamd_task_registry, task_registry);
+ task_registry = NULL;
+ }
+}
+
+struct rspamd_task *
+rspamd_task_by_lua_key(uint64_t lua_key)
+{
+ if (task_registry == NULL || lua_key == 0) {
+ return NULL;
+ }
+
+ khiter_t k = kh_get(rspamd_task_registry, task_registry, lua_key);
+ if (k != kh_end(task_registry)) {
+ return kh_value(task_registry, k);
+ }
+
+ return NULL;
+}
+
+static inline void
+rspamd_task_registry_add(struct rspamd_task *task)
+{
+ if (task_registry == NULL) {
+ rspamd_task_registry_init();
+ }
+
+ task->lua_key = ++task_lua_key_counter;
+
+ int ret;
+ khiter_t k = kh_put(rspamd_task_registry, task_registry, task->lua_key, &ret);
+ if (ret > 0) {
+ kh_value(task_registry, k) = task;
+ }
+}
+
+static inline void
+rspamd_task_registry_remove(struct rspamd_task *task)
+{
+ if (task_registry == NULL || task->lua_key == 0) {
+ return;
+ }
+
+ khiter_t k = kh_get(rspamd_task_registry, task_registry, task->lua_key);
+ if (k != kh_end(task_registry)) {
+ kh_del(rspamd_task_registry, task_registry, k);
+ }
+
+ task->lua_key = 0;
+}
+
static GQuark
rspamd_task_quark(void)
{
new_task->mail_esmtp_args = NULL;
new_task->rcpt_esmtp_args = NULL;
+ rspamd_task_registry_add(new_task);
+
return new_task;
}
unsigned int i;
if (task) {
+ rspamd_task_registry_remove(task);
+
debug_task("free pointer %p", task);
if (task->rcpt_envelope) {
*/
struct rspamd_task {
struct rspamd_worker *worker; /**< pointer to worker object */
+ uint64_t lua_key; /**< unique key for Lua task registry */
enum rspamd_command cmd; /**< command */
int sock; /**< socket descriptor */
uint32_t dns_requests; /**< number of DNS requests per this task */
*/
void rspamd_worker_guard_handler(EV_P_ ev_io *w, int revents);
+/*
+ * Task registry for safe Lua task references
+ */
+void rspamd_task_registry_init(void);
+void rspamd_task_registry_destroy(void);
+struct rspamd_task *rspamd_task_by_lua_key(uint64_t lua_key);
+
#ifdef __cplusplus
}
#endif
{
void *ud = rspamd_lua_check_udata(L, pos, rspamd_task_classname);
luaL_argcheck(L, ud != NULL, pos, "'task' expected");
- return ud ? *((struct rspamd_task **) ud) : NULL;
+ if (ud) {
+ uint64_t lua_key = *((uint64_t *) ud);
+ return rspamd_task_by_lua_key(lua_key);
+ }
+ return NULL;
}
struct rspamd_task *
{
void *ud = rspamd_lua_check_udata_maybe(L, pos, rspamd_task_classname);
- return ud ? *((struct rspamd_task **) ud) : NULL;
+ if (ud) {
+ uint64_t lua_key = *((uint64_t *) ud);
+ return rspamd_task_by_lua_key(lua_key);
+ }
+ return NULL;
}
static struct rspamd_image *
void rspamd_lua_task_push(lua_State *L, struct rspamd_task *task)
{
- struct rspamd_task **ptask;
+ uint64_t *pkey;
- ptask = lua_newuserdata(L, sizeof(gpointer));
+ pkey = lua_newuserdata(L, sizeof(uint64_t));
rspamd_lua_setclass(L, rspamd_task_classname, -1);
- *ptask = task;
+ *pkey = task->lua_key;
}