diff options
-rw-r--r-- | contrib/libucl/lua_ucl.h | 44 | ||||
-rw-r--r-- | src/libserver/cfg_file.h | 6 | ||||
-rw-r--r-- | src/libserver/cfg_rcl.cxx | 39 | ||||
-rw-r--r-- | src/libserver/cfg_utils.cxx | 7 | ||||
-rw-r--r-- | src/libserver/protocol.c | 123 | ||||
-rw-r--r-- | src/lua/lua_util.c | 4 | ||||
-rw-r--r-- | src/rspamadm/confighelp.c | 2 |
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; |