diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lua/lua_redis.c | 19 | ||||
-rw-r--r-- | src/lua/lua_task.c | 17 | ||||
-rw-r--r-- | src/plugins/lua/ratelimit.lua | 13 |
3 files changed, 44 insertions, 5 deletions
diff --git a/src/lua/lua_redis.c b/src/lua/lua_redis.c index 0358a6960..0c1934345 100644 --- a/src/lua/lua_redis.c +++ b/src/lua/lua_redis.c @@ -98,8 +98,12 @@ static void lua_redis_push_error (const gchar *err, struct lua_redis_userdata *ud, gboolean connected) { struct worker_task **ptask; + gboolean need_unlock = FALSE; - g_mutex_lock (lua_mtx); + /* Avoid LOR here as mutex can be acquired before in lua_call */ + if (g_mutex_trylock (lua_mtx)) { + need_unlock = TRUE; + } /* Push error */ lua_rawgeti (ud->L, LUA_REGISTRYINDEX, ud->cbref); ptask = lua_newuserdata (ud->L, sizeof (struct worker_task *)); @@ -113,7 +117,9 @@ lua_redis_push_error (const gchar *err, struct lua_redis_userdata *ud, gboolean if (lua_pcall (ud->L, 3, 0, 0) != 0) { msg_info ("call to callback failed: %s", lua_tostring (ud->L, -1)); } - g_mutex_unlock (lua_mtx); + if (need_unlock) { + g_mutex_unlock (lua_mtx); + } if (connected) { remove_normal_event (ud->task->s, lua_redis_fin, ud); @@ -130,8 +136,11 @@ static void lua_redis_push_data (const redisReply *r, struct lua_redis_userdata *ud) { struct worker_task **ptask; + gboolean need_unlock = FALSE; - g_mutex_lock (lua_mtx); + if (g_mutex_trylock (lua_mtx)) { + need_unlock = TRUE; + } /* Push error */ lua_rawgeti (ud->L, LUA_REGISTRYINDEX, ud->cbref); ptask = lua_newuserdata (ud->L, sizeof (struct worker_task *)); @@ -161,7 +170,9 @@ lua_redis_push_data (const redisReply *r, struct lua_redis_userdata *ud) if (lua_pcall (ud->L, 3, 0, 0) != 0) { msg_info ("call to callback failed: %s", lua_tostring (ud->L, -1)); } - g_mutex_unlock (lua_mtx); + if (need_unlock) { + g_mutex_unlock (lua_mtx); + } remove_normal_event (ud->task->s, lua_redis_fin, ud); } diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 5695b6f42..e44b873c0 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -69,6 +69,7 @@ LUA_FUNCTION_DEF (task, get_helo); LUA_FUNCTION_DEF (task, get_images); LUA_FUNCTION_DEF (task, get_symbol); LUA_FUNCTION_DEF (task, get_date); +LUA_FUNCTION_DEF (task, get_message_id); LUA_FUNCTION_DEF (task, get_timeval); LUA_FUNCTION_DEF (task, get_metric_score); LUA_FUNCTION_DEF (task, get_metric_action); @@ -101,6 +102,7 @@ static const struct luaL_reg tasklib_m[] = { LUA_INTERFACE_DEF (task, get_images), LUA_INTERFACE_DEF (task, get_symbol), LUA_INTERFACE_DEF (task, get_date), + LUA_INTERFACE_DEF (task, get_message_id), LUA_INTERFACE_DEF (task, get_timeval), LUA_INTERFACE_DEF (task, get_metric_score), LUA_INTERFACE_DEF (task, get_metric_action), @@ -1194,6 +1196,21 @@ lua_task_get_date (lua_State *L) } static gint +lua_task_get_message_id (lua_State *L) +{ + struct worker_task *task = lua_check_task (L); + + if (task != NULL && task->message_id != NULL) { + lua_pushstring (L, task->message_id); + } + else { + lua_pushnil (L); + } + + return 1; +} + +static gint lua_task_get_timeval (lua_State *L) { struct worker_task *task = lua_check_task (L); diff --git a/src/plugins/lua/ratelimit.lua b/src/plugins/lua/ratelimit.lua index 7b1ea3eff..39bac5534 100644 --- a/src/plugins/lua/ratelimit.lua +++ b/src/plugins/lua/ratelimit.lua @@ -21,6 +21,7 @@ local bounce_senders = {'postmaster', 'mailer-daemon', '', 'null', 'fetchmail-da -- Do not check ratelimits for these senders local whitelisted_rcpts = {'postmaster', 'mailer-daemon'} local whitelisted_ip = nil +local max_rcpt = 5 local upstreams = nil --- Parse atime and bucket of limit @@ -167,6 +168,11 @@ local function rate_test_set(task, func) rcpts = task:get_recipients_headers() end if rcpts then + if table.maxn(rcpts) > max_rcpt then + rspamd_logger.info(string.format('message <%s> contains %d recipients, maximum is %d', + task:get_message_id(), table.maxn(rcpts), max_rcpt)) + return + end for i,r in ipairs(rcpts) do rcpts_user[i] = get_local_part(r['addr']) end @@ -276,6 +282,7 @@ if rspamd_config:get_api_version() >= 9 then rspamd_config:register_module_option('ratelimit', 'whitelisted_rcpts', 'string') rspamd_config:register_module_option('ratelimit', 'whitelisted_ip', 'map') rspamd_config:register_module_option('ratelimit', 'limit', 'string') + rspamd_config:register_module_option('ratelimit', 'max_rcpt', 'uint') end local function parse_whitelisted_rcpts(str) @@ -301,6 +308,10 @@ if opts then whitelisted_ip = rspamd_config:add_hash_map (opts['whitelisted_ip']) end + if opts['max_rcpt'] then + max_rcpt = tonumber (opts['max_rcpt']) + end + if not opts['servers'] then rspamd_logger.err('no servers are specified') else @@ -312,4 +323,4 @@ if opts then rspamd_config:register_post_filter(rate_set) end end -end +end
\ No newline at end of file |