aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-05 17:20:13 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-05 17:20:13 +0000
commit348e129aac10e5668aa16d19bffdb95473d52883 (patch)
treea620182417f9ea49d4411a19c7baba9a22861d75
parentd26c0a18a7c5670e97bc23c902b609e17979122f (diff)
downloadrspamd-348e129aac10e5668aa16d19bffdb95473d52883.tar.gz
rspamd-348e129aac10e5668aa16d19bffdb95473d52883.zip
[Feature] Add neighbours option to support Rspamd cluster in WebUI
-rw-r--r--src/controller.c29
-rw-r--r--src/libserver/cfg_file.h1
-rw-r--r--src/libserver/cfg_rcl.c101
-rw-r--r--src/libserver/cfg_utils.c2
4 files changed, 131 insertions, 2 deletions
diff --git a/src/controller.c b/src/controller.c
index b780e3c4c..78c397c80 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -57,6 +57,7 @@
#define PATH_STAT_RESET "/statreset"
#define PATH_COUNTERS "/counters"
#define PATH_ERRORS "/errors"
+#define PATH_NEIGHBOURS "/neighbours"
#define msg_err_session(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL, \
session->pool->tag.tagname, session->pool->tag.uid, \
@@ -1403,6 +1404,31 @@ rspamd_controller_handle_errors (struct rspamd_http_connection_entry *conn_ent,
return 0;
}
+/*
+ * Neighbours command handler:
+ * request: /neighbours
+ * headers: Password
+ * reply: json {name: {url: "http://...", host: "host"}}
+ */
+static int
+rspamd_controller_handle_neighbours (struct rspamd_http_connection_entry *conn_ent,
+ struct rspamd_http_message *msg)
+{
+ struct rspamd_controller_session *session = conn_ent->ud;
+ struct rspamd_controller_worker_ctx *ctx;
+
+ ctx = session->ctx;
+
+ if (!rspamd_controller_check_password (conn_ent, session, msg, FALSE)) {
+ return 0;
+ }
+
+ rspamd_controller_send_ucl (conn_ent, ctx->cfg->neighbours);
+
+ return 0;
+}
+
+
static int
rspamd_controller_handle_history_reset (struct rspamd_http_connection_entry *conn_ent,
struct rspamd_http_message *msg)
@@ -3140,6 +3166,9 @@ start_controller_worker (struct rspamd_worker *worker)
rspamd_http_router_add_path (ctx->http,
PATH_ERRORS,
rspamd_controller_handle_errors);
+ rspamd_http_router_add_path (ctx->http,
+ PATH_NEIGHBOURS,
+ rspamd_controller_handle_neighbours);
rspamd_regexp_t *lua_re = rspamd_regexp_new ("^/.*/.*\\.lua$", NULL, NULL);
rspamd_http_router_add_regexp (ctx->http, lua_re,
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index 3be0c7c4d..a6399010b 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -425,6 +425,7 @@ struct rspamd_config {
gchar *ssl_ciphers; /**< set of preferred ciphers */
gchar *zstd_input_dictionary; /**< path to zstd input dictionary */
gchar *zstd_output_dictionary; /**< path to zstd output dictionary */
+ ucl_object_t *neighbours; /**< other servers in the cluster */
ref_entry_t ref; /**< reference counter */
};
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c
index 20dc7ea60..f2d8bcd08 100644
--- a/src/libserver/cfg_rcl.c
+++ b/src/libserver/cfg_rcl.c
@@ -236,9 +236,9 @@ rspamd_rcl_options_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
const gchar *key, gpointer ud,
struct rspamd_rcl_section *section, GError **err)
{
- const ucl_object_t *dns, *upstream;
+ const ucl_object_t *dns, *upstream, *neighbours;
struct rspamd_config *cfg = ud;
- struct rspamd_rcl_section *dns_section, *upstream_section;
+ struct rspamd_rcl_section *dns_section, *upstream_section, *neighbours_section;
HASH_FIND_STR (section->subsections, "dns", dns_section);
@@ -262,6 +262,20 @@ rspamd_rcl_options_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
}
}
+ HASH_FIND_STR (section->subsections, "neighbours", neighbours_section);
+
+ neighbours = ucl_object_lookup (obj, "neighbours");
+ if (neighbours_section != NULL && neighbours != NULL) {
+ const ucl_object_t *cur;
+
+ LL_FOREACH (neighbours, cur) {
+ if (!rspamd_rcl_process_section (cfg, neighbours_section, cfg, cur,
+ pool, err)) {
+ return FALSE;
+ }
+ }
+ }
+
if (rspamd_rcl_section_parse_defaults (cfg,
section, cfg->cfg_pool, obj,
cfg, err)) {
@@ -1489,6 +1503,82 @@ rspamd_rcl_composites_handler (rspamd_mempool_t *pool,
return success;
}
+static gboolean
+rspamd_rcl_neighbours_handler (rspamd_mempool_t *pool,
+ const ucl_object_t *obj,
+ const gchar *key,
+ gpointer ud,
+ struct rspamd_rcl_section *section,
+ GError **err)
+{
+ struct rspamd_config *cfg = ud;
+ const ucl_object_t *hostval, *pathval;
+ ucl_object_t *neigh;
+ gboolean has_port = FALSE, has_proto = FALSE;
+ GString *urlstr;
+ const gchar *p;
+
+ if (key == NULL) {
+ g_set_error (err,
+ CFG_RCL_ERROR,
+ EINVAL,
+ "missing name for neighbour");
+ return FALSE;
+ }
+
+ hostval = ucl_object_lookup (obj, "host");
+
+ if (hostval == NULL || ucl_object_type (hostval) != UCL_STRING) {
+ g_set_error (err,
+ CFG_RCL_ERROR,
+ EINVAL,
+ "missing host for neighbour: %s", ucl_object_key (obj));
+ return FALSE;
+ }
+
+ neigh = ucl_object_typed_new (UCL_OBJECT);
+ ucl_object_insert_key (neigh, ucl_object_ref (hostval), "host", 0, false);
+
+ if ((p = strrchr (ucl_object_tostring (hostval), ':')) != NULL) {
+ if (g_ascii_isdigit (p[1])) {
+ has_port = TRUE;
+ }
+ }
+
+ if (strstr (ucl_object_tostring (hostval), "://") != NULL) {
+ has_proto = TRUE;
+ }
+
+ /* Now make url */
+ urlstr = g_string_sized_new (63);
+ pathval = ucl_object_lookup (obj, "path");
+
+ if (!has_proto) {
+ g_string_append_len (urlstr, "http://", sizeof ("http://") - 1);
+ }
+
+ g_string_append (urlstr, ucl_object_tostring (hostval));
+
+ if (!has_port) {
+ g_string_append (urlstr, ":11334");
+ }
+
+ if (pathval == NULL) {
+ g_string_append (urlstr, "/rspamd/");
+ }
+ else {
+ g_string_append (urlstr, ucl_object_tostring (pathval));
+ }
+
+ ucl_object_insert_key (neigh,
+ ucl_object_fromlstring (urlstr->str, urlstr->len),
+ "url", 0, false);
+ g_string_free (urlstr, TRUE);
+ ucl_object_insert_key (cfg->neighbours, neigh, key, 0, true);
+
+ return TRUE;
+}
+
struct rspamd_rcl_section *
rspamd_rcl_add_section (struct rspamd_rcl_section **top,
@@ -2032,6 +2122,13 @@ rspamd_rcl_config_init (struct rspamd_config *cfg)
0,
"Use pre 1.4 style of messages in the protocol");
+ /* Neighbours configuration */
+ rspamd_rcl_add_section_doc (&sub->subsections, "neighbours", "name",
+ rspamd_rcl_neighbours_handler,
+ UCL_OBJECT, FALSE, TRUE,
+ cfg->doc_strings,
+ "List of members of Rspamd cluster");
+
/* New DNS configuration */
ssub = rspamd_rcl_add_section_doc (&sub->subsections, "dns", NULL, NULL,
UCL_OBJECT, FALSE, TRUE,
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 306965df8..8ee284212 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -175,6 +175,7 @@ rspamd_config_new (void)
cfg->max_pic_size = DEFAULT_MAX_PIC;
cfg->images_cache_size = 256;
cfg->monitored_ctx = rspamd_monitored_ctx_init ();
+ cfg->neighbours = ucl_object_typed_new (UCL_OBJECT);
#ifdef WITH_HIREDIS
cfg->redis_pool = rspamd_redis_pool_init ();
#endif
@@ -193,6 +194,7 @@ rspamd_config_free (struct rspamd_config *cfg)
ucl_object_unref (cfg->rcl_obj);
ucl_object_unref (cfg->config_comments);
ucl_object_unref (cfg->doc_strings);
+ ucl_object_unref (cfg->neighbours);
g_hash_table_remove_all (cfg->metrics);
g_hash_table_unref (cfg->metrics);
g_hash_table_unref (cfg->c_modules);