aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/libucl/lua_ucl.h44
-rw-r--r--src/libserver/cfg_file.h6
-rw-r--r--src/libserver/cfg_rcl.cxx39
-rw-r--r--src/libserver/cfg_utils.cxx7
-rw-r--r--src/libserver/protocol.c123
-rw-r--r--src/lua/lua_util.c4
-rw-r--r--src/rspamadm/confighelp.c2
7 files changed, 130 insertions, 95 deletions
diff --git a/contrib/libucl/lua_ucl.h b/contrib/libucl/lua_ucl.h
index 5b7f88e03..4a759e3b4 100644
--- a/contrib/libucl/lua_ucl.h
+++ b/contrib/libucl/lua_ucl.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2023 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/* Copyright (c) 2014, Vsevolod Stakhov
* All rights reserved.
*
@@ -26,11 +42,16 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include "ucl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Include C++ guard as Lua headers miss one */
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
-#include "ucl.h"
/**
* Closure structure for lua function storing inside UCL
@@ -44,7 +65,7 @@ struct ucl_lua_funcdata {
/**
* Initialize lua UCL API
*/
-UCL_EXTERN int luaopen_ucl (lua_State *L);
+UCL_EXTERN int luaopen_ucl(lua_State *L);
/**
* Import UCL object from lua state
@@ -52,7 +73,7 @@ UCL_EXTERN int luaopen_ucl (lua_State *L);
* @param idx index of object at the lua stack to convert to UCL
* @return new UCL object or NULL, the caller should unref object after using
*/
-UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx);
+UCL_EXTERN ucl_object_t *ucl_object_lua_import(lua_State *L, int idx);
/**
* Import UCL object from lua state, escaping JSON strings
@@ -60,7 +81,7 @@ UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx);
* @param idx index of object at the lua stack to convert to UCL
* @return new UCL object or NULL, the caller should unref object after using
*/
-UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx);
+UCL_EXTERN ucl_object_t *ucl_object_lua_import_escape(lua_State *L, int idx);
/**
* Push an object to lua
@@ -68,18 +89,21 @@ UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx);
* @param obj object to push
* @param allow_array traverse over implicit arrays
*/
-UCL_EXTERN int ucl_object_push_lua (lua_State *L,
- const ucl_object_t *obj, bool allow_array);
+UCL_EXTERN int ucl_object_push_lua(lua_State *L,
+ const ucl_object_t *obj, bool allow_array);
/**
* Push an object to lua replacing all ucl.null with `false`
* @param L lua state
* @param obj object to push
* @param allow_array traverse over implicit arrays
*/
-UCL_EXTERN int ucl_object_push_lua_filter_nil (lua_State *L,
- const ucl_object_t *obj,
- bool allow_array);
+UCL_EXTERN int ucl_object_push_lua_filter_nil(lua_State *L,
+ const ucl_object_t *obj,
+ bool allow_array);
-UCL_EXTERN struct ucl_lua_funcdata* ucl_object_toclosure (const ucl_object_t *obj);
+UCL_EXTERN struct ucl_lua_funcdata *ucl_object_toclosure(const ucl_object_t *obj);
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
#endif /* LUA_UCL_H_ */
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index 0d85e5f5e..3f876ab23 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -856,9 +856,9 @@ gboolean rspamd_config_libs(struct rspamd_external_libs_ctx *ctx,
cfg->cfg_pool->tag.tagname, cfg->checksum, \
RSPAMD_LOG_FUNC, \
__VA_ARGS__)
-#define msg_err_config_forced(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL | RSPAMD_LOG_FORCED, \
- cfg->cfg_pool->tag.tagname, cfg->checksum, \
- RSPAMD_LOG_FUNC, \
+#define msg_err_config_forced(...) rspamd_default_log_function((gint) G_LOG_LEVEL_CRITICAL | (gint) RSPAMD_LOG_FORCED, \
+ cfg->cfg_pool->tag.tagname, cfg->checksum, \
+ RSPAMD_LOG_FUNC, \
__VA_ARGS__)
#define msg_warn_config(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING, \
cfg->cfg_pool->tag.tagname, cfg->checksum, \
diff --git a/src/libserver/cfg_rcl.cxx b/src/libserver/cfg_rcl.cxx
index 5234e4fa3..1ca9e5b69 100644
--- a/src/libserver/cfg_rcl.cxx
+++ b/src/libserver/cfg_rcl.cxx
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#include "lua/lua_common.h"
#include "cfg_rcl.h"
#include "rspamd.h"
#include "cfg_file_private.h"
#include "utlist.h"
#include "cfg_file.h"
-#include "lua/lua_common.h"
#include "expression.h"
#include "src/libserver/composites/composites.h"
#include "libserver/worker_util.h"
@@ -31,7 +32,6 @@
#include <string>
#include <filesystem>
#include <memory>
-#include <algorithm>
#include "contrib/ankerl/unordered_dense.h"
#include "fmt/core.h"
#include "libutil/cxx/util.hxx"
@@ -52,20 +52,20 @@ struct rspamd_rcl_default_handler_data {
struct rspamd_rcl_sections_map;
struct rspamd_rcl_section {
- struct rspamd_rcl_sections_map *top;
+ struct rspamd_rcl_sections_map *top{};
std::string name; /**< name of section */
std::optional<std::string> key_attr;
std::optional<std::string> default_key;
- rspamd_rcl_handler_t handler; /**< handler of section attributes */
- enum ucl_type type; /**< type of attribute */
- bool required; /**< whether this param is required */
- bool strict_type; /**< whether we need strict type */
- mutable bool processed; /**< whether this section was processed */
+ rspamd_rcl_handler_t handler{}; /**< handler of section attributes */
+ enum ucl_type type; /**< type of attribute */
+ bool required{}; /**< whether this param is required */
+ bool strict_type{}; /**< whether we need strict type */
+ mutable bool processed{}; /**< whether this section was processed */
ankerl::unordered_dense::map<std::string, std::shared_ptr<struct rspamd_rcl_section>> subsections;
ankerl::unordered_dense::map<std::string, struct rspamd_rcl_default_handler_data> default_parser; /**< generic parsing fields */
- rspamd_rcl_section_fin_t fin; /** called at the end of section parsing */
- gpointer fin_ud;
- ucl_object_t *doc_ref; /**< reference to the section's documentation */
+ rspamd_rcl_section_fin_t fin{}; /** called at the end of section parsing */
+ gpointer fin_ud{};
+ ucl_object_t *doc_ref{}; /**< reference to the section's documentation */
};
struct rspamd_worker_param_parser {
@@ -74,10 +74,19 @@ struct rspamd_worker_param_parser {
};
struct rspamd_worker_cfg_parser {
- ankerl::unordered_dense::map<std::pair<std::string, gpointer>, rspamd_worker_param_parser> parsers; /**< parsers hash */
- gint type; /**< workers quark */
- gboolean (*def_obj_parser)(ucl_object_t *obj, gpointer ud); /**<
- default object parser */
+ struct pair_hash {
+ using is_avalanching = void;
+ template<class T1, class T2>
+ std::size_t operator()(const std::pair<T1, T2> &pair) const
+ {
+ return ankerl::unordered_dense::hash<T1>()(pair.first) ^ ankerl::unordered_dense::hash<T2>()(pair.second);
+ }
+ };
+ ankerl::unordered_dense::map<std::pair<std::string, gpointer>,
+ rspamd_worker_param_parser, pair_hash>
+ parsers; /**< parsers hash */
+ gint type; /**< workers quark */
+ gboolean (*def_obj_parser)(ucl_object_t *obj, gpointer ud); /**< default object parser */
gpointer def_ud;
};
diff --git a/src/libserver/cfg_utils.cxx b/src/libserver/cfg_utils.cxx
index 2c820bfa4..a088559f1 100644
--- a/src/libserver/cfg_utils.cxx
+++ b/src/libserver/cfg_utils.cxx
@@ -15,12 +15,13 @@
*/
#include "config.h"
+#include "lua/lua_common.h"
+#include "lua/lua_thread_pool.h"
+
#include "cfg_file.h"
#include "rspamd.h"
#include "cfg_file_private.h"
-#include "scan_result.h"
-#include "lua/lua_common.h"
-#include "lua/lua_thread_pool.h"
+
#include "maps/map.h"
#include "maps/map_helpers.h"
#include "maps/map_private.h"
diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c
index c8e3fe441..867455754 100644
--- a/src/libserver/protocol.c
+++ b/src/libserver/protocol.c
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2016 Vsevolod Stakhov
+/*
+ * Copyright 2023 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -793,65 +793,66 @@ rspamd_protocol_parse_task_flags(rspamd_mempool_t *pool,
return TRUE;
}
-static struct rspamd_rcl_section *control_parser = NULL;
+static struct rspamd_rcl_sections_map *control_parser = NULL;
-static void
-rspamd_protocol_control_parser_init(void)
+RSPAMD_CONSTRUCTOR(rspamd_protocol_control_parser_ctor)
{
- struct rspamd_rcl_section *sub;
-
- if (control_parser == NULL) {
- sub = rspamd_rcl_add_section(&control_parser,
- "*",
- NULL,
- NULL,
- UCL_OBJECT,
- FALSE,
- TRUE);
- /* Default handlers */
- rspamd_rcl_add_default_handler(sub,
- "ip",
- rspamd_rcl_parse_struct_addr,
- G_STRUCT_OFFSET(struct rspamd_task, from_addr),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "from",
- rspamd_rcl_parse_struct_mime_addr,
- G_STRUCT_OFFSET(struct rspamd_task, from_envelope),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "rcpt",
- rspamd_rcl_parse_struct_mime_addr,
- G_STRUCT_OFFSET(struct rspamd_task, rcpt_envelope),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "helo",
- rspamd_rcl_parse_struct_string,
- G_STRUCT_OFFSET(struct rspamd_task, helo),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "user",
- rspamd_rcl_parse_struct_string,
- G_STRUCT_OFFSET(struct rspamd_task, auth_user),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "pass_all",
- rspamd_protocol_parse_task_flags,
- G_STRUCT_OFFSET(struct rspamd_task, flags),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "json",
- rspamd_protocol_parse_task_flags,
- G_STRUCT_OFFSET(struct rspamd_task, flags),
- 0,
- NULL);
- }
+
+ struct rspamd_rcl_section *sub = rspamd_rcl_add_section(&control_parser, NULL,
+ "*",
+ NULL,
+ NULL,
+ UCL_OBJECT,
+ FALSE,
+ TRUE);
+ /* Default handlers */
+ rspamd_rcl_add_default_handler(sub,
+ "ip",
+ rspamd_rcl_parse_struct_addr,
+ G_STRUCT_OFFSET(struct rspamd_task, from_addr),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "from",
+ rspamd_rcl_parse_struct_mime_addr,
+ G_STRUCT_OFFSET(struct rspamd_task, from_envelope),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "rcpt",
+ rspamd_rcl_parse_struct_mime_addr,
+ G_STRUCT_OFFSET(struct rspamd_task, rcpt_envelope),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "helo",
+ rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET(struct rspamd_task, helo),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "user",
+ rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET(struct rspamd_task, auth_user),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "pass_all",
+ rspamd_protocol_parse_task_flags,
+ G_STRUCT_OFFSET(struct rspamd_task, flags),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "json",
+ rspamd_protocol_parse_task_flags,
+ G_STRUCT_OFFSET(struct rspamd_task, flags),
+ 0,
+ NULL);
+}
+
+RSPAMD_DESTRUCTOR(rspamd_protocol_control_parser_dtor)
+{
+ rspamd_rcl_sections_free(control_parser);
}
gboolean
@@ -860,8 +861,6 @@ rspamd_protocol_handle_control(struct rspamd_task *task,
{
GError *err = NULL;
- rspamd_protocol_control_parser_init();
-
if (!rspamd_rcl_parse(control_parser, task->cfg, task, task->task_pool,
control, &err)) {
msg_warn_protocol("cannot parse control block: %e", err);
diff --git a/src/lua/lua_util.c b/src/lua/lua_util.c
index 550e0a9ee..40f6f6c48 100644
--- a/src/lua/lua_util.c
+++ b/src/lua/lua_util.c
@@ -858,7 +858,7 @@ lua_util_config_from_ucl(lua_State *L)
{
LUA_TRACE_POINT;
struct rspamd_config *cfg = NULL, **pcfg;
- struct rspamd_rcl_section *top;
+ struct rspamd_rcl_sections_map *top;
GError *err = NULL;
ucl_object_t *obj;
const char *str_options = NULL;
@@ -901,6 +901,8 @@ lua_util_config_from_ucl(lua_State *L)
rspamd_lua_setclass(L, "rspamd{config}", -1);
*pcfg = cfg;
}
+
+ rspamd_rcl_sections_free(top);
}
return 1;
diff --git a/src/rspamadm/confighelp.c b/src/rspamadm/confighelp.c
index 4c035ac94..2ad07c0a6 100644
--- a/src/rspamadm/confighelp.c
+++ b/src/rspamadm/confighelp.c
@@ -233,7 +233,7 @@ rspamadm_confighelp(gint argc, gchar **argv, const struct rspamadm_command *cmd)
rspamd_rcl_config_init(cfg, NULL);
lua_pushboolean(cfg->lua_state, true);
lua_setglobal(cfg->lua_state, "confighelp");
- rspamd_rcl_add_lua_plugins_path(cfg, plugins_path, FALSE, NULL, NULL);
+ rspamd_rcl_add_lua_plugins_path(cfg->rcl_top_section, cfg, plugins_path, FALSE, NULL);
/* Init modules to get documentation strings */
i = 0;