aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver/rspamd_control.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libserver/rspamd_control.c')
-rw-r--r--src/libserver/rspamd_control.c86
1 files changed, 65 insertions, 21 deletions
diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c
index 1bff2ff12..e212f7e91 100644
--- a/src/libserver/rspamd_control.c
+++ b/src/libserver/rspamd_control.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -214,7 +214,7 @@ rspamd_control_write_reply(struct rspamd_control_session *session)
case RSPAMD_CONTROL_FUZZY_STAT:
if (elt->attached_fd != -1) {
/* We have some data to parse */
- parser = ucl_parser_new(0);
+ parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
ucl_object_insert_key(cur,
ucl_object_fromint(
elt->reply.reply.fuzzy_stat.status),
@@ -724,6 +724,9 @@ rspamd_control_default_cmd_handler(int fd,
case RSPAMD_CONTROL_CHILD_CHANGE:
case RSPAMD_CONTROL_FUZZY_BLOCKED:
break;
+ case RSPAMD_CONTROL_WORKERS_SPAWNED:
+ rep.reply.workers_spawned.status = 0;
+ break;
case RSPAMD_CONTROL_RERESOLVE:
if (cd->worker->srv->cfg) {
REF_RETAIN(cd->worker->srv->cfg);
@@ -1065,30 +1068,58 @@ rspamd_srv_handler(EV_P_ ev_io *w, int revents)
case RSPAMD_SRV_HYPERSCAN_LOADED:
#ifdef WITH_HYPERSCAN
/* Load RE cache to provide it for new forks */
- if (rspamd_re_cache_is_hs_loaded(rspamd_main->cfg->re_cache) != RSPAMD_HYPERSCAN_LOADED_FULL ||
- cmd.cmd.hs_loaded.forced) {
- rspamd_re_cache_load_hyperscan(
+ if (cmd.cmd.hs_loaded.scope[0] != '\0') {
+ /* Scoped loading */
+ const char *scope = cmd.cmd.hs_loaded.scope;
+ msg_info_main("received scoped hyperscan cache loaded from %s for scope: %s",
+ cmd.cmd.hs_loaded.cache_dir, scope);
+
+ /* Load specific scope */
+ rspamd_re_cache_load_hyperscan_scoped(
rspamd_main->cfg->re_cache,
cmd.cmd.hs_loaded.cache_dir,
false);
- }
-
- /* After getting this notice, we can clean up old hyperscan files */
-
- rspamd_hyperscan_notice_loaded();
- msg_info_main("received hyperscan cache loaded from %s",
- cmd.cmd.hs_loaded.cache_dir);
+ /* Broadcast scoped command to all workers */
+ memset(&wcmd, 0, sizeof(wcmd));
+ wcmd.type = RSPAMD_CONTROL_HYPERSCAN_LOADED;
+ rspamd_strlcpy(wcmd.cmd.hs_loaded.cache_dir,
+ cmd.cmd.hs_loaded.cache_dir,
+ sizeof(wcmd.cmd.hs_loaded.cache_dir));
+ rspamd_strlcpy(wcmd.cmd.hs_loaded.scope,
+ cmd.cmd.hs_loaded.scope,
+ sizeof(wcmd.cmd.hs_loaded.scope));
+ wcmd.cmd.hs_loaded.forced = cmd.cmd.hs_loaded.forced;
+ rspamd_control_broadcast_cmd(rspamd_main, &wcmd, rfd,
+ rspamd_control_ignore_io_handler, NULL, worker->pid);
+ }
+ else {
+ /* Legacy full cache loading */
+ if (rspamd_re_cache_is_hs_loaded(rspamd_main->cfg->re_cache) != RSPAMD_HYPERSCAN_LOADED_FULL ||
+ cmd.cmd.hs_loaded.forced) {
+ rspamd_re_cache_load_hyperscan(
+ rspamd_main->cfg->re_cache,
+ cmd.cmd.hs_loaded.cache_dir,
+ false);
+ }
- /* Broadcast command to all workers */
- memset(&wcmd, 0, sizeof(wcmd));
- wcmd.type = RSPAMD_CONTROL_HYPERSCAN_LOADED;
- rspamd_strlcpy(wcmd.cmd.hs_loaded.cache_dir,
- cmd.cmd.hs_loaded.cache_dir,
- sizeof(wcmd.cmd.hs_loaded.cache_dir));
- wcmd.cmd.hs_loaded.forced = cmd.cmd.hs_loaded.forced;
- rspamd_control_broadcast_cmd(rspamd_main, &wcmd, rfd,
- rspamd_control_ignore_io_handler, NULL, worker->pid);
+ /* After getting this notice, we can clean up old hyperscan files */
+ rspamd_hyperscan_notice_loaded();
+
+ msg_info_main("received hyperscan cache loaded from %s",
+ cmd.cmd.hs_loaded.cache_dir);
+
+ /* Broadcast command to all workers */
+ memset(&wcmd, 0, sizeof(wcmd));
+ wcmd.type = RSPAMD_CONTROL_HYPERSCAN_LOADED;
+ rspamd_strlcpy(wcmd.cmd.hs_loaded.cache_dir,
+ cmd.cmd.hs_loaded.cache_dir,
+ sizeof(wcmd.cmd.hs_loaded.cache_dir));
+ wcmd.cmd.hs_loaded.forced = cmd.cmd.hs_loaded.forced;
+ wcmd.cmd.hs_loaded.scope[0] = '\0'; /* Empty scope for legacy */
+ rspamd_control_broadcast_cmd(rspamd_main, &wcmd, rfd,
+ rspamd_control_ignore_io_handler, NULL, worker->pid);
+ }
#endif
break;
case RSPAMD_SRV_MONITORED_CHANGE:
@@ -1137,6 +1168,10 @@ rspamd_srv_handler(EV_P_ ev_io *w, int revents)
rspamd_control_broadcast_cmd(rspamd_main, &wcmd, rfd,
rspamd_control_ignore_io_handler, NULL, worker->pid);
break;
+ case RSPAMD_SRV_WORKERS_SPAWNED:
+ /* No need to broadcast, this is just a notification from main to specific workers */
+ rdata->rep.reply.workers_spawned.status = 0;
+ break;
default:
msg_err_main("unknown command type: %d", cmd.type);
break;
@@ -1390,6 +1425,9 @@ rspamd_control_command_from_string(const char *str)
else if (g_ascii_strcasecmp(str, "child_change") == 0) {
ret = RSPAMD_CONTROL_CHILD_CHANGE;
}
+ else if (g_ascii_strcasecmp(str, "workers_spawned") == 0) {
+ ret = RSPAMD_CONTROL_WORKERS_SPAWNED;
+ }
return ret;
}
@@ -1430,6 +1468,9 @@ rspamd_control_command_to_string(enum rspamd_control_type cmd)
case RSPAMD_CONTROL_CHILD_CHANGE:
reply = "child_change";
break;
+ case RSPAMD_CONTROL_WORKERS_SPAWNED:
+ reply = "workers_spawned";
+ break;
default:
break;
}
@@ -1469,6 +1510,9 @@ const char *rspamd_srv_command_to_string(enum rspamd_srv_type cmd)
case RSPAMD_SRV_FUZZY_BLOCKED:
reply = "fuzzy_blocked";
break;
+ case RSPAMD_SRV_WORKERS_SPAWNED:
+ reply = "workers_spawned";
+ break;
}
return reply;