diff options
Diffstat (limited to 'src/fuzzy_storage.c')
-rw-r--r-- | src/fuzzy_storage.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index b7d9ea781..db30fc6f8 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -84,6 +84,12 @@ struct fuzzy_key_stat { rspamd_lru_hash_t *last_ips; }; +struct rspamd_fuzzy_mirror { + gchar *name; + struct upstream_list *u; + struct rspamd_cryptobox_pubkey *key; +}; + static const guint64 rspamd_fuzzy_storage_magic = 0x291a3253eb1b3ea5ULL; struct rspamd_fuzzy_storage_ctx { @@ -98,6 +104,7 @@ struct rspamd_fuzzy_storage_ctx { struct rspamd_cryptobox_pubkey *master_key; struct timeval master_io_tv; gdouble master_timeout; + GPtrArray *mirrors; gchar *update_map; gchar *masters_map; guint keypair_cache_size; @@ -114,6 +121,7 @@ struct rspamd_fuzzy_storage_ctx { struct rspamd_fuzzy_backend *backend; GQueue *updates_pending; struct rspamd_dns_resolver *resolver; + struct rspamd_config *cfg; }; enum fuzzy_cmd_type { @@ -1403,6 +1411,88 @@ rspamd_fuzzy_storage_stat (struct rspamd_main *rspamd_main, } static gboolean +fuzzy_storage_parse_mirror (rspamd_mempool_t *pool, + const ucl_object_t *obj, + gpointer ud, + struct rspamd_rcl_section *section, + GError **err) +{ + const ucl_object_t *elt; + struct rspamd_fuzzy_mirror *up = NULL; + struct rspamd_rcl_struct_parser *pd = ud; + struct rspamd_fuzzy_storage_ctx *ctx; + + ctx = pd->user_struct; + + if (ucl_object_type (obj) != UCL_OBJECT) { + g_set_error (err, g_quark_try_string ("fuzzy"), 100, + "mirror/slave option must be an object"); + + return FALSE; + } + + elt = ucl_object_lookup (obj, "name"); + if (elt == NULL) { + g_set_error (err, g_quark_try_string ("fuzzy"), 100, + "mirror option must have some name definition"); + + return FALSE; + } + + up = g_slice_alloc0 (sizeof (*up)); + up->name = g_strdup (ucl_object_tostring (elt)); + + elt = ucl_object_lookup (obj, "key"); + if (elt != NULL) { + up->key = rspamd_pubkey_from_base32 (ucl_object_tostring (elt), 0, + RSPAMD_KEYPAIR_KEX, RSPAMD_CRYPTOBOX_MODE_25519); + } + + if (up->key == NULL) { + g_set_error (err, g_quark_try_string ("fuzzy"), 100, + "cannot read mirror key"); + + goto err; + } + + elt = ucl_object_lookup (obj, "hosts"); + + if (elt == NULL) { + g_set_error (err, g_quark_try_string ("fuzzy"), 100, + "mirror option must have some hosts definition"); + + goto err; + } + + up->u = rspamd_upstreams_create (ctx->cfg->ups_ctx); + if (!rspamd_upstreams_from_ucl (up->u, elt, 11335, NULL)) { + g_set_error (err, g_quark_try_string ("fuzzy"), 100, + "mirror has bad hosts definition"); + + goto err; + } + + g_ptr_array_add (ctx->mirrors, up); + + return TRUE; + +err: + + if (up) { + g_free (up->name); + rspamd_upstreams_destroy (up->u); + + if (up->key) { + rspamd_pubkey_unref (up->key); + } + + g_slice_free1 (sizeof (*up), up); + } + + return FALSE; +} + +static gboolean fuzzy_parse_keypair (rspamd_mempool_t *pool, const ucl_object_t *obj, gpointer ud, @@ -1504,6 +1594,7 @@ init_fuzzy (struct rspamd_config *cfg) ctx->errors_ips = rspamd_lru_hash_new_full (1024, (GDestroyNotify) rspamd_inet_address_destroy, g_free, rspamd_inet_address_hash, rspamd_inet_address_equal); + ctx->cfg = cfg; rspamd_rcl_register_worker_option (cfg, type, @@ -1637,6 +1728,24 @@ init_fuzzy (struct rspamd_config *cfg) 0, "Allow master/slave updates merely using the specified key"); + rspamd_rcl_register_worker_option (cfg, + type, + "mirror", + fuzzy_storage_parse_mirror, + ctx, + 0, + RSPAMD_CL_FLAG_MULTIPLE, + "List of slave hosts"); + + rspamd_rcl_register_worker_option (cfg, + type, + "slave", + fuzzy_storage_parse_mirror, + ctx, + 0, + RSPAMD_CL_FLAG_MULTIPLE, + "List of slave hosts"); + return ctx; } |