aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libserver/cfg_file.h4
-rw-r--r--src/libserver/cfg_rcl.c13
-rw-r--r--src/libserver/task.c41
-rw-r--r--src/libutil/util.c52
-rw-r--r--src/rspamd.h8
5 files changed, 114 insertions, 4 deletions
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index 7ce7f98a4..9a0fa0d22 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -417,7 +417,9 @@ struct rspamd_config {
struct rspamd_config_post_load_script *on_load; /**< list of scripts executed on config load */
gchar *ssl_ca_path; /**< path to CA certs */
- gchar *ssl_ciphers; /**< set of preferred ciphers */
+ 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 */
ref_entry_t ref; /**< reference counter */
};
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c
index 0cca28575..c89392207 100644
--- a/src/libserver/cfg_rcl.c
+++ b/src/libserver/cfg_rcl.c
@@ -1974,6 +1974,19 @@ rspamd_rcl_config_init (struct rspamd_config *cfg)
G_STRUCT_OFFSET (struct rspamd_config, max_message),
RSPAMD_CL_FLAG_INT_SIZE,
"Maximum size of the message to be scanned");
+ rspamd_rcl_add_default_handler (sub,
+ "zstd_input_dictionary",
+ rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET (struct rspamd_config, zstd_input_dictionary),
+ RSPAMD_CL_FLAG_STRING_PATH,
+ "Dictionary for zstd inbound protocol compression");
+ rspamd_rcl_add_default_handler (sub,
+ "zstd_output_dictionary",
+ rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET (struct rspamd_config, zstd_output_dictionary),
+ RSPAMD_CL_FLAG_STRING_PATH,
+ "Dictionary for outbound zstd compression");
+
/* New DNS configuration */
ssub = rspamd_rcl_add_section_doc (&sub->subsections, "dns", NULL, NULL,
UCL_OBJECT, FALSE, TRUE,
diff --git a/src/libserver/task.c b/src/libserver/task.c
index f24ee0858..d4b5cb696 100644
--- a/src/libserver/task.c
+++ b/src/libserver/task.c
@@ -492,6 +492,44 @@ rspamd_task_load_message (struct rspamd_task *task,
ZSTD_outBuffer zout;
guchar *out;
gsize outlen, r;
+ gulong dict_id;
+
+ tok = rspamd_task_get_request_header (task, "dictionary");
+
+ if (tok != NULL) {
+ /* We need to use custom dictionary */
+ if (!rspamd_strtoul (tok->begin, tok->len, &dict_id)) {
+ g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
+ "Non numeric dictionary");
+
+ return FALSE;
+ }
+
+ if (!task->cfg->libs_ctx->in_dict) {
+ g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
+ "Unknown dictionary, undefined locally");
+
+ return FALSE;
+ }
+
+ if (task->cfg->libs_ctx->in_dict->id != dict_id) {
+ g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
+ "Unknown dictionary, invalid dictionary id");
+
+ return FALSE;
+ }
+
+ zstream = ZSTD_createDStream ();
+ g_assert (zstream != NULL);
+ g_assert (!ZSTD_isError (ZSTD_initDStream_usingDict(zstream,
+ task->cfg->libs_ctx->in_dict->dict,
+ task->cfg->libs_ctx->in_dict->size)));
+ }
+ else {
+ zstream = ZSTD_createDStream ();
+ g_assert (zstream != NULL);
+ g_assert (!ZSTD_isError (ZSTD_initDStream (zstream)));
+ }
zin.pos = 0;
zin.src = start;
@@ -502,9 +540,6 @@ rspamd_task_load_message (struct rspamd_task *task,
}
out = g_malloc (outlen);
- zstream = ZSTD_createDStream ();
- g_assert (zstream != NULL);
- g_assert (!ZSTD_isError (ZSTD_initDStream (zstream)));
zout.dst = out;
zout.pos = 0;
zout.size = outlen;
diff --git a/src/libutil/util.c b/src/libutil/util.c
index 889cc1c6c..fbc06c039 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -23,6 +23,7 @@
#include "ottery.h"
#include "cryptobox.h"
#include "libutil/map.h"
+#include "contrib/zstd/zdict.h"
#ifdef HAVE_OPENSSL
#include <openssl/rand.h>
@@ -2090,6 +2091,38 @@ rspamd_init_libs (void)
return ctx;
}
+static struct zstd_dictionary *
+rspamd_open_zstd_dictionary (const char *path)
+{
+ struct zstd_dictionary *dict;
+
+ dict = g_slice_alloc0 (sizeof (*dict));
+ dict->dict = rspamd_file_xmap (path, PROT_READ, &dict->size);
+
+ if (dict->dict == NULL) {
+ g_slice_free1 (sizeof (*dict), dict);
+ return NULL;
+ }
+
+ dict->id = ZDICT_getDictID (dict->dict, dict->size);
+
+ if (dict->id == 0) {
+ g_slice_free1 (sizeof (*dict), dict);
+ return NULL;
+ }
+
+ return dict;
+}
+
+static void
+rspamd_free_zstd_dictionary (struct zstd_dictionary *dict)
+{
+ if (dict) {
+ munmap (dict->dict, dict->size);
+ g_slice_free1 (sizeof (*dict), dict);
+ }
+}
+
void
rspamd_config_libs (struct rspamd_external_libs_ctx *ctx,
struct rspamd_config *cfg)
@@ -2131,6 +2164,23 @@ rspamd_config_libs (struct rspamd_external_libs_ctx *ctx,
if (ctx->libmagic) {
magic_load (ctx->libmagic, cfg->magic_file);
}
+
+ if (cfg->zstd_input_dictionary) {
+ ctx->in_dict = rspamd_open_zstd_dictionary (cfg->zstd_input_dictionary);
+
+ if (ctx->in_dict == NULL) {
+ msg_err_config ("cannot open zstd dictionary in %s",
+ cfg->zstd_input_dictionary);
+ }
+ }
+ if (cfg->zstd_output_dictionary) {
+ ctx->out_dict = rspamd_open_zstd_dictionary (cfg->zstd_output_dictionary);
+
+ if (ctx->out_dict == NULL) {
+ msg_err_config ("cannot open zstd dictionary in %s",
+ cfg->zstd_output_dictionary);
+ }
+ }
}
}
@@ -2151,6 +2201,8 @@ rspamd_deinit_libs (struct rspamd_external_libs_ctx *ctx)
SSL_CTX_free (ctx->ssl_ctx);
#endif
rspamd_inet_library_destroy ();
+ rspamd_free_zstd_dictionary (ctx->in_dict);
+ rspamd_free_zstd_dictionary (ctx->out_dict);
g_slice_free1 (sizeof (*ctx), ctx);
}
}
diff --git a/src/rspamd.h b/src/rspamd.h
index e99e4c18d..545681bf5 100644
--- a/src/rspamd.h
+++ b/src/rspamd.h
@@ -299,12 +299,20 @@ struct controller_session {
struct event_base *ev_base; /**< Event base */
};
+struct zstd_dictionary {
+ const void *dict;
+ gsize size;
+ guint id;
+};
+
struct rspamd_external_libs_ctx {
magic_t libmagic;
radix_compressed_t **local_addrs;
struct rspamd_cryptobox_library_ctx *crypto_ctx;
struct ottery_config *ottery_cfg;
SSL_CTX *ssl_ctx;
+ struct zstd_dictionary *in_dict;
+ struct zstd_dictionary *out_dict;
ref_entry_t ref;
};