aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lualib/rspamadm/fuzzy_stat.lua40
-rw-r--r--src/fuzzy_storage.c20
2 files changed, 59 insertions, 1 deletions
diff --git a/lualib/rspamadm/fuzzy_stat.lua b/lualib/rspamadm/fuzzy_stat.lua
index ef8a5de08..c5b6ec384 100644
--- a/lualib/rspamadm/fuzzy_stat.lua
+++ b/lualib/rspamadm/fuzzy_stat.lua
@@ -59,7 +59,34 @@ local function add_data(target, src)
if type(v.extensions.name) == 'string' then
target.name = v.extensions.name
end
+ if type(v.extensions.email) == 'string' then
+ target.email = v.extensions.email
+ end
+ if type(v.extensions.ratelimit) == 'table' then
+ if not target.ratelimit then
+ target.ratelimit = {
+ cur = {
+ last = 0,
+ count = 0
+ },
+ }
+ end
+ -- Passed as {burst = x, rate = y}
+ target.ratelimit.limit = v.extensions.ratelimit
+ end
+ end
+ elseif k == 'ratelimit' then
+ if not target.ratelimit then
+ target.ratelimit = {
+ cur = {
+ last = 0,
+ count = 0
+ },
+ }
end
+ -- Ratelimit is passed as {cur = count, last = time}
+ target.ratelimit.cur.count = v.cur + target.ratelimit.cur.count
+ target.ratelimit.cur.last = math.max(v.last, target.ratelimit.cur.last)
end
end
end
@@ -301,7 +328,8 @@ return function(args, res)
for _, key in ipairs(sorted_keys) do
local key_stat = key.data
if key_stat.name then
- print(string.format('Key id: %s, name: %s', key.key, key_stat.name))
+ print(string.format('Key id: %s, name: %s (email: %s)', key.key, key_stat.name,
+ key_stat.email or 'unknown'))
else
print(string.format('Key id: %s', key.key))
end
@@ -332,6 +360,16 @@ return function(args, res)
end
end
+ if key_stat.ratelimit then
+ print('')
+ print('\tRatelimit stat:')
+ print(string.format('\tLimit: %s (%.2f per hour leak rate)',
+ print_num(key_stat.ratelimit.limit.burst), (key_stat.ratelimit.limit.rate or 0.0) * 3600))
+ print(string.format('\tCurrent: %s (%s last)',
+ print_num(key_stat.ratelimit.cur.count), os.date('%c', key_stat.ratelimit.cur.last)))
+ print('')
+ end
+
print('')
end
end
diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c
index f21992a94..0d7a1c2a8 100644
--- a/src/fuzzy_storage.c
+++ b/src/fuzzy_storage.c
@@ -268,6 +268,7 @@ static struct fuzzy_key *fuzzy_add_keypair_from_ucl(struct rspamd_config *cfg,
const ucl_object_t *obj,
khash_t(rspamd_fuzzy_keys_hash) * target);
+static ucl_object_t *rspamd_leaky_bucket_to_ucl(struct rspamd_leaky_bucket_elt *p_elt);
struct fuzzy_keymap_ucl_buf {
rspamd_fstring_t *buf;
struct rspamd_fuzzy_storage_ctx *ctx;
@@ -2456,9 +2457,28 @@ rspamd_fuzzy_key_stat_iter(const unsigned char *pk_iter, struct fuzzy_key *fuzzy
rspamd_keypair_to_ucl(fuzzy_key->key, RSPAMD_KEYPAIR_ENCODING_DEFAULT,
RSPAMD_KEYPAIR_DUMP_NO_SECRET | RSPAMD_KEYPAIR_DUMP_FLATTENED),
"keypair", 0, false);
+
+ if (fuzzy_key->rl_bucket) {
+ ucl_object_insert_key(elt,
+ rspamd_leaky_bucket_to_ucl(fuzzy_key->rl_bucket),
+ "ratelimit", 0, false);
+ }
+
ucl_object_insert_key(keys_obj, elt, keyname, 0, true);
}
}
+static ucl_object_t *
+rspamd_leaky_bucket_to_ucl(struct rspamd_leaky_bucket_elt *p_elt)
+{
+ ucl_object_t *res;
+
+ res = ucl_object_typed_new(UCL_OBJECT);
+
+ ucl_object_insert_key(res, ucl_object_fromdouble(p_elt->cur), "cur", 0, false);
+ ucl_object_insert_key(res, ucl_object_fromdouble(p_elt->last), "last", 0, false);
+
+ return res;
+}
static ucl_object_t *
rspamd_fuzzy_stat_to_ucl(struct rspamd_fuzzy_storage_ctx *ctx, gboolean ip_stat)