diff options
author | Larry Hynes <larry@larryhynes.com> | 2016-06-09 20:09:17 +0100 |
---|---|---|
committer | Larry Hynes <larry@larryhynes.com> | 2016-06-09 20:09:17 +0100 |
commit | 6ec2e81512e068e798da20e4ab486ade81d3b9dc (patch) | |
tree | c84faf049dea2e52bc8da120d25f242fa9c0c397 /src/libserver | |
parent | 25083072e809ac328b8c4b4c98cdf6c9e35c112e (diff) | |
parent | fb326efc2b3fa1c25705d218987199a608b87b87 (diff) | |
download | rspamd-6ec2e81512e068e798da20e4ab486ade81d3b9dc.tar.gz rspamd-6ec2e81512e068e798da20e4ab486ade81d3b9dc.zip |
Merge remote-tracking branch 'upstream/master' into documentation
* upstream/master: (90 commits)
[Fix] Plug memory leak in proxy
[Feature] Do not print garbadge in --compact output
[Fix] Fix encrypted proxy requests
[Fix] Do not delete uninitialized events
[Feature] Add protection against open files limit and accepting sockets
[Fix] Another fix for redis timeouts
[Fix] Fix order of initialization
[Feature] Use file lock in logger to avoid deadlocks
[Fix] Fix errors handling in the proxy
[Fix] More fixes for redis refcounts
[Fix] Initialize parser scripts properly
[Fix] Try to fix issue in redis stats backend when task is closed
[Fix] Fix usage of rdns reply structure
[Fix] Fix symbol name for spf soft fail
[Fix] Fix setting path for lua
[Doc] Update regexp module documentation
[Minor] Fix names
[Fix] Add missing types
[Feature] Implement braced regexp quantifiers
[Fix] Implement new automata to skip empty lines for dkim signing
...
Diffstat (limited to 'src/libserver')
-rw-r--r-- | src/libserver/cfg_rcl.c | 44 | ||||
-rw-r--r-- | src/libserver/cfg_rcl.h | 15 | ||||
-rw-r--r-- | src/libserver/dkim.c | 169 | ||||
-rw-r--r-- | src/libserver/fuzzy_backend.c | 205 | ||||
-rw-r--r-- | src/libserver/fuzzy_backend.h | 8 | ||||
-rw-r--r-- | src/libserver/protocol.c | 18 | ||||
-rw-r--r-- | src/libserver/protocol.h | 8 | ||||
-rw-r--r-- | src/libserver/re_cache.c | 7 | ||||
-rw-r--r-- | src/libserver/worker_util.c | 37 |
9 files changed, 416 insertions, 95 deletions
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index f774ac126..ebbc29d61 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -2668,7 +2668,6 @@ rspamd_rcl_parse_struct_keypair (rspamd_mempool_t *pool, struct rspamd_rcl_struct_parser *pd = ud; struct rspamd_cryptobox_keypair **target, *kp; - target = (struct rspamd_cryptobox_keypair **)(((gchar *)pd->user_struct) + pd->offset); if (obj->type == UCL_OBJECT) { @@ -2698,6 +2697,49 @@ rspamd_rcl_parse_struct_keypair (rspamd_mempool_t *pool, return TRUE; } +gboolean +rspamd_rcl_parse_struct_pubkey (rspamd_mempool_t *pool, + const ucl_object_t *obj, + gpointer ud, + struct rspamd_rcl_section *section, + GError **err) +{ + struct rspamd_rcl_struct_parser *pd = ud; + struct rspamd_cryptobox_pubkey **target, *pk; + gsize len; + const gchar *str; + + target = (struct rspamd_cryptobox_pubkey **)(((gchar *)pd->user_struct) + + pd->offset); + if (obj->type == UCL_STRING) { + str = ucl_object_tolstring (obj, &len); + pk = rspamd_pubkey_from_base32 (str, len, RSPAMD_KEYPAIR_KEX, + RSPAMD_CRYPTOBOX_MODE_25519); + + if (pk != NULL) { + *target = pk; + } + else { + g_set_error (err, + CFG_RCL_ERROR, + EINVAL, + "cannot load the pubkey specified: %s", + ucl_object_key (obj)); + return FALSE; + } + } + else { + g_set_error (err, + CFG_RCL_ERROR, + EINVAL, + "no sane pubkey found in the element: %s", + ucl_object_key (obj)); + return FALSE; + } + + return TRUE; +} + static void rspamd_rcl_insert_string_list_item (gpointer *target, rspamd_mempool_t *pool, const gchar *src, gboolean is_hash) diff --git a/src/libserver/cfg_rcl.h b/src/libserver/cfg_rcl.h index ee0a1b526..1a27b056f 100644 --- a/src/libserver/cfg_rcl.h +++ b/src/libserver/cfg_rcl.h @@ -278,6 +278,21 @@ gboolean rspamd_rcl_parse_struct_keypair (rspamd_mempool_t *pool, GError **err); /** + * Parse a pubkey field of a structure + * @param cfg config pointer + * @param obj object to parse + * @param ud struct_parser structure (flags mean the exact structure used) + * @param section the current section + * @param err error pointer + * @return TRUE if a value has been successfully parsed + */ +gboolean rspamd_rcl_parse_struct_pubkey (rspamd_mempool_t *pool, + const ucl_object_t *obj, + gpointer ud, + struct rspamd_rcl_section *section, + GError **err); + +/** * Parse a inet addr field of a structure * @param cfg config pointer * @param obj object to parse diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c index 5052960f0..1f65733ba 100644 --- a/src/libserver/dkim.c +++ b/src/libserver/dkim.c @@ -1260,6 +1260,147 @@ rspamd_dkim_simple_body_step (rspamd_dkim_context_t *ctx, return (len != 0); } +static const gchar * +rspamd_dkim_skip_empty_lines (const gchar *start, const gchar *end, + guint type, gboolean *need_crlf) +{ + const gchar *p = end - 1, *t; + enum { + init = 0, + init_2, + got_cr, + got_lf, + got_crlf, + test_spaces, + } state = init; + guint skip = 0; + + while (p >= start + 2) { + switch (state) { + case init: + if (*p == '\r') { + state = got_cr; + } + else if (*p == '\n') { + state = got_lf; + } + else if (type == DKIM_CANON_RELAXED && *p == ' ') { + skip = 0; + state = test_spaces; + } + else { + if (type == DKIM_CANON_SIMPLE) { + *need_crlf = TRUE; + } + + goto end; + } + break; + case init_2: + if (*p == '\r') { + state = got_cr; + } + else if (*p == '\n') { + state = got_lf; + } + else if (type == DKIM_CANON_RELAXED && *p == ' ') { + skip = 0; + state = test_spaces; + } + else { + goto end; + } + break; + case got_cr: + if (*(p - 1) == '\r') { + p --; + state = got_cr; + } + else if (*(p - 1) == '\n') { + if ((*p - 2) == '\r') { + /* \r\n\r -> we know about one line */ + p -= 1; + state = got_crlf; + } + else { + /* \n\r -> we know about one line */ + p -= 1; + state = got_lf; + } + } + else if (type == DKIM_CANON_RELAXED && *(p - 1) == ' ') { + skip = 1; + state = test_spaces; + } + else { + goto end; + } + break; + case got_lf: + if (*(p - 1) == '\r') { + state = got_crlf; + } + else if (*(p - 1) == '\n') { + /* We know about one line */ + p --; + state = got_lf; + } + else if (type == DKIM_CANON_RELAXED && *(p - 1) == ' ') { + skip = 1; + state = test_spaces; + } + else { + goto end; + } + break; + case got_crlf: + if (p > start - 2) { + if (*(p - 3) == '\r') { + p -= 2; + state = got_cr; + } + else if (*(p - 3) == '\n') { + p -= 2; + state = got_lf; + } + else if (type == DKIM_CANON_RELAXED && *(p - 3) == ' ') { + skip = 2; + state = test_spaces; + } + else { + goto end; + } + } + else { + goto end; + } + break; + case test_spaces: + t = p - skip; + + while (t > start - 2 && *t == ' ') { + t --; + } + + if (*t == '\r') { + p = t; + state = got_cr; + } + else if (*t == '\n') { + p = t; + state = got_lf; + } + else { + goto end; + } + break; + } + } + +end: + return p; +} + static gboolean rspamd_dkim_canonize_body (rspamd_dkim_context_t *ctx, const gchar *start, @@ -1267,6 +1408,7 @@ rspamd_dkim_canonize_body (rspamd_dkim_context_t *ctx, { const gchar *p; guint remain = ctx->len ? ctx->len : (guint)(end - start); + gboolean need_crlf = FALSE; if (start == NULL) { /* Empty body */ @@ -1279,22 +1421,9 @@ rspamd_dkim_canonize_body (rspamd_dkim_context_t *ctx, } else { /* Strip extra ending CRLF */ - p = end - 1; - while (p >= start + 2) { - if (*p == '\n' && *(p - 1) == '\r' && *(p - 2) == '\n') { - p -= 2; - } - else if (*p == '\n' && *(p - 1) == '\n') { - p--; - } - else if (*p == '\r' && *(p - 1) == '\r') { - p--; - } - else { - break; - } - } + p = rspamd_dkim_skip_empty_lines (start, end, ctx->body_canon_type, &need_crlf); end = p + 1; + if (end == start) { /* Empty body */ if (ctx->body_canon_type == DKIM_CANON_SIMPLE) { @@ -1308,7 +1437,15 @@ rspamd_dkim_canonize_body (rspamd_dkim_context_t *ctx, if (ctx->body_canon_type == DKIM_CANON_SIMPLE) { /* Simple canonization */ while (rspamd_dkim_simple_body_step (ctx, ctx->body_hash, - &start, end - start, &remain)) ; + &start, end - start, &remain)); + + if (need_crlf) { + start = "\r\n"; + end = start + 2; + remain = 2; + rspamd_dkim_simple_body_step (ctx, ctx->body_hash, + &start, end - start, &remain); + } } else { while (rspamd_dkim_relaxed_body_step (ctx, ctx->body_hash, diff --git a/src/libserver/fuzzy_backend.c b/src/libserver/fuzzy_backend.c index 26e595e5f..e58e8a546 100644 --- a/src/libserver/fuzzy_backend.c +++ b/src/libserver/fuzzy_backend.c @@ -32,6 +32,7 @@ struct rspamd_fuzzy_backend { static const gdouble sql_sleep_time = 0.1; static const guint max_retries = 10; +static const guint32 flags_mask = (1U << 31); #define msg_err_fuzzy_backend(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \ backend->pool->tag.tagname, backend->pool->tag.uid, \ @@ -52,17 +53,21 @@ static const guint max_retries = 10; static const char *create_tables_sql = "BEGIN;" - "CREATE TABLE digests(" - "id INTEGER PRIMARY KEY," - "flag INTEGER NOT NULL," - "digest TEXT NOT NULL," - "value INTEGER," - "time INTEGER);" - "CREATE TABLE shingles(" - "value INTEGER NOT NULL," - "number INTEGER NOT NULL," - "digest_id INTEGER REFERENCES digests(id) ON DELETE CASCADE " - "ON UPDATE CASCADE);" + "CREATE TABLE IF NOT EXISTS digests(" + " id INTEGER PRIMARY KEY," + " flag INTEGER NOT NULL," + " digest TEXT NOT NULL," + " value INTEGER," + " time INTEGER);" + "CREATE TABLE IF NOT EXISTS shingles(" + " value INTEGER NOT NULL," + " number INTEGER NOT NULL," + " digest_id INTEGER REFERENCES digests(id) ON DELETE CASCADE " + " ON UPDATE CASCADE);" + "CREATE TABLE IF NOT EXISTS sources(" + " name TEXT UNIQUE," + " version INTEGER," + " last INTEGER);" "CREATE UNIQUE INDEX IF NOT EXISTS d ON digests(digest);" "CREATE INDEX IF NOT EXISTS t ON digests(time);" "CREATE INDEX IF NOT EXISTS dgst_id ON shingles(digest_id);" @@ -93,7 +98,9 @@ enum rspamd_fuzzy_statement_idx { RSPAMD_FUZZY_BACKEND_EXPIRE, RSPAMD_FUZZY_BACKEND_VACUUM, RSPAMD_FUZZY_BACKEND_DELETE_ORPHANED, + RSPAMD_FUZZY_BACKEND_ADD_SOURCE, RSPAMD_FUZZY_BACKEND_VERSION, + RSPAMD_FUZZY_BACKEND_SET_VERSION, RSPAMD_FUZZY_BACKEND_MAX }; static struct rspamd_fuzzy_stmts { @@ -214,12 +221,26 @@ static struct rspamd_fuzzy_stmts { .result = SQLITE_DONE }, { + .idx = RSPAMD_FUZZY_BACKEND_ADD_SOURCE, + .sql = "INSERT OR IGNORE INTO sources(name, version, last) VALUES (?1, ?2, ?3);", + .args = "TII", + .stmt = NULL, + .result = SQLITE_DONE + }, + { .idx = RSPAMD_FUZZY_BACKEND_VERSION, - .sql = "PRAGMA user_version;", - .args = "", + .sql = "SELECT version FROM sources WHERE name=?1;", + .args = "T", .stmt = NULL, .result = SQLITE_ROW }, + { + .idx = RSPAMD_FUZZY_BACKEND_SET_VERSION, + .sql = "UPDATE sources SET version=?1, last=?2 WHERE name=?3;", + .args = "IIT", + .stmt = NULL, + .result = SQLITE_DONE + }, }; static GQuark @@ -410,7 +431,7 @@ rspamd_fuzzy_backend_open_db (const gchar *path, GError **err) bk->expired = 0; bk->pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "fuzzy_backend"); bk->db = rspamd_sqlite3_open_or_create (bk->pool, bk->path, - create_tables_sql, err); + create_tables_sql, 1, err); if (bk->db == NULL) { rspamd_fuzzy_backend_close (bk); @@ -506,6 +527,10 @@ rspamd_fuzzy_backend_check (struct rspamd_fuzzy_backend *backend, rep.prob = 1.0; rep.flag = sqlite3_column_int ( prepared_stmts[RSPAMD_FUZZY_BACKEND_CHECK].stmt, 2); + + if (!(rep.flag & flags_mask) && rep.flag > 0) { + rep.flag = (1U << (rep.flag - 1)) | flags_mask; + } } } else if (cmd->shingles_count > 0) { @@ -589,6 +614,10 @@ rspamd_fuzzy_backend_check (struct rspamd_fuzzy_backend *backend, rep.flag = sqlite3_column_int ( prepared_stmts[RSPAMD_FUZZY_BACKEND_GET_DIGEST_BY_ID].stmt, 3); + + if (!(rep.flag & flags_mask) && rep.flag > 0) { + rep.flag = (1U << (rep.flag - 1)) | flags_mask; + } } } } @@ -610,7 +639,8 @@ rspamd_fuzzy_backend_check (struct rspamd_fuzzy_backend *backend, } gboolean -rspamd_fuzzy_backend_prepare_update (struct rspamd_fuzzy_backend *backend) +rspamd_fuzzy_backend_prepare_update (struct rspamd_fuzzy_backend *backend, + const gchar *source) { gint rc; @@ -643,6 +673,11 @@ rspamd_fuzzy_backend_add (struct rspamd_fuzzy_backend *backend, return FALSE; } + if (cmd->flag > 31 || cmd->flag == 0) { + msg_err_fuzzy_backend ("flag more than 31 is no longer supported"); + return FALSE; + } + rc = rspamd_fuzzy_backend_run_stmt (backend, FALSE, RSPAMD_FUZZY_BACKEND_CHECK, cmd->digest); @@ -654,7 +689,7 @@ rspamd_fuzzy_backend_add (struct rspamd_fuzzy_backend *backend, 2); rspamd_fuzzy_backend_cleanup_stmt (backend, RSPAMD_FUZZY_BACKEND_CHECK); - if (flag == cmd->flag) { + if (flag & (1U << (cmd->flag - 1))) { /* We need to increase weight */ rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE, RSPAMD_FUZZY_BACKEND_UPDATE, @@ -669,11 +704,28 @@ rspamd_fuzzy_backend_add (struct rspamd_fuzzy_backend *backend, } else { /* We need to relearn actually */ + if (flag & flags_mask) { + /* This is already new format */ + flag |= (1U << (cmd->flag - 1)); + } + else { + /* Convert to the new format */ + if (flag > 31 || flag == 0) { + msg_warn_fuzzy_backend ("storage had flag more than 31, remove " + "it"); + flag = cmd->flag | flags_mask; + } + else { + flag = (1U << (flag - 1)) | (1U << (cmd->flag - 1)) | flags_mask; + } + } + rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE, RSPAMD_FUZZY_BACKEND_UPDATE_FLAG, (gint64) cmd->value, - (gint64) cmd->flag, + (gint64) flag, cmd->digest); + if (rc != SQLITE_OK) { msg_warn_fuzzy_backend ("cannot update hash to %d -> " "%*xs: %s", (gint) cmd->flag, @@ -686,7 +738,7 @@ rspamd_fuzzy_backend_add (struct rspamd_fuzzy_backend *backend, rspamd_fuzzy_backend_cleanup_stmt (backend, RSPAMD_FUZZY_BACKEND_CHECK); rc = rspamd_fuzzy_backend_run_stmt (backend, FALSE, RSPAMD_FUZZY_BACKEND_INSERT, - (gint) cmd->flag, + (gint) (1U << (cmd->flag - 1)), cmd->digest, (gint64) cmd->value, (gint64) timestamp); @@ -729,42 +781,47 @@ rspamd_fuzzy_backend_add (struct rspamd_fuzzy_backend *backend, } gboolean -rspamd_fuzzy_backend_finish_update (struct rspamd_fuzzy_backend *backend) +rspamd_fuzzy_backend_finish_update (struct rspamd_fuzzy_backend *backend, + const gchar *source) { gint rc, wal_frames, wal_checkpointed, ver; - gint64 version = 0; - gchar version_buf[128]; + + /* Get and update version */ + ver = rspamd_fuzzy_backend_version (backend, source); + ++ver; rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE, - RSPAMD_FUZZY_BACKEND_TRANSACTION_COMMIT); + RSPAMD_FUZZY_BACKEND_SET_VERSION, + (gint64)ver, (gint64)time (NULL), source); - if (rc != SQLITE_OK) { - msg_warn_fuzzy_backend ("cannot commit updates: %s", - sqlite3_errmsg (backend->db)); - rspamd_fuzzy_backend_run_stmt (backend, TRUE, - RSPAMD_FUZZY_BACKEND_TRANSACTION_ROLLBACK); - return FALSE; - } - else { - if (!rspamd_sqlite3_sync (backend->db, &wal_frames, &wal_checkpointed)) { - msg_warn_fuzzy_backend ("cannot commit checkpoint: %s", + if (rc == SQLITE_OK) { + rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE, + RSPAMD_FUZZY_BACKEND_TRANSACTION_COMMIT); + + if (rc != SQLITE_OK) { + msg_warn_fuzzy_backend ("cannot commit updates: %s", sqlite3_errmsg (backend->db)); + rspamd_fuzzy_backend_run_stmt (backend, TRUE, + RSPAMD_FUZZY_BACKEND_TRANSACTION_ROLLBACK); + return FALSE; } - else if (wal_checkpointed > 0) { - msg_info_fuzzy_backend ("total number of frames in the wal file: " - "%d, checkpointed: %d", wal_frames, wal_checkpointed); + else { + if (!rspamd_sqlite3_sync (backend->db, &wal_frames, &wal_checkpointed)) { + msg_warn_fuzzy_backend ("cannot commit checkpoint: %s", + sqlite3_errmsg (backend->db)); + } + else if (wal_checkpointed > 0) { + msg_info_fuzzy_backend ("total number of frames in the wal file: " + "%d, checkpointed: %d", wal_frames, wal_checkpointed); + } } } - - /* Get and update version */ - ver = rspamd_fuzzy_backend_version (backend); - ++ver; - rspamd_snprintf (version_buf, sizeof (version_buf), "PRAGMA user_version=%d;", - ver); - - if (sqlite3_exec (backend->db, version_buf, NULL, NULL, NULL) != SQLITE_OK) { - msg_err_fuzzy_backend ("cannot set database version to %L: %s", - version, sqlite3_errmsg (backend->db)); + else { + msg_warn_fuzzy_backend ("cannot update version for %s: %s", source, + sqlite3_errmsg (backend->db)); + rspamd_fuzzy_backend_run_stmt (backend, TRUE, + RSPAMD_FUZZY_BACKEND_TRANSACTION_ROLLBACK); + return FALSE; } return TRUE; @@ -774,16 +831,61 @@ gboolean rspamd_fuzzy_backend_del (struct rspamd_fuzzy_backend *backend, const struct rspamd_fuzzy_cmd *cmd) { - int rc; + int rc = -1; + guint32 flag; if (backend == NULL) { return FALSE; } - rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE, - RSPAMD_FUZZY_BACKEND_DELETE, + rc = rspamd_fuzzy_backend_run_stmt (backend, FALSE, + RSPAMD_FUZZY_BACKEND_CHECK, cmd->digest); + if (rc == SQLITE_OK) { + /* Check flag */ + flag = sqlite3_column_int64 ( + prepared_stmts[RSPAMD_FUZZY_BACKEND_CHECK].stmt, + 2); + rspamd_fuzzy_backend_cleanup_stmt (backend, RSPAMD_FUZZY_BACKEND_CHECK); + + if (!(flag & flags_mask)) { + flag = (1U << (flag - 1)) | flags_mask; + } + + if (flag & (1U << (cmd->flag - 1))) { + flag &= ~(1U << (cmd->flag - 1)); + + if (flag == 0) { + /* It is the last flag, so delete hash completely */ + rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE, + RSPAMD_FUZZY_BACKEND_DELETE, + cmd->digest); + } + else { + /* We need to delete specific flag */ + rc = rspamd_fuzzy_backend_run_stmt (backend, TRUE, + RSPAMD_FUZZY_BACKEND_UPDATE_FLAG, + (gint64) cmd->value, + (gint64) flag, + cmd->digest); + if (rc != SQLITE_OK) { + msg_warn_fuzzy_backend ("cannot update hash to %d -> " + "%*xs: %s", (gint) cmd->flag, + (gint) sizeof (cmd->digest), cmd->digest, + sqlite3_errmsg (backend->db)); + } + } + } + else { + /* The hash has a wrong flag, ignoring */ + } + } + else { + /* Hash is missing */ + rspamd_fuzzy_backend_cleanup_stmt (backend, RSPAMD_FUZZY_BACKEND_CHECK); + } + return (rc == SQLITE_OK); } @@ -976,13 +1078,14 @@ rspamd_fuzzy_backend_count (struct rspamd_fuzzy_backend *backend) } gint -rspamd_fuzzy_backend_version (struct rspamd_fuzzy_backend *backend) +rspamd_fuzzy_backend_version (struct rspamd_fuzzy_backend *backend, + const gchar *source) { - gint ret = 0; + gint ret = -1; if (backend) { if (rspamd_fuzzy_backend_run_stmt (backend, FALSE, - RSPAMD_FUZZY_BACKEND_VERSION) == SQLITE_OK) { + RSPAMD_FUZZY_BACKEND_VERSION, source) == SQLITE_OK) { ret = sqlite3_column_int64 ( prepared_stmts[RSPAMD_FUZZY_BACKEND_VERSION].stmt, 0); } diff --git a/src/libserver/fuzzy_backend.h b/src/libserver/fuzzy_backend.h index bcd199d1a..91a613f2a 100644 --- a/src/libserver/fuzzy_backend.h +++ b/src/libserver/fuzzy_backend.h @@ -46,7 +46,8 @@ struct rspamd_fuzzy_reply rspamd_fuzzy_backend_check ( /** * Prepare storage for updates (by starting transaction) */ -gboolean rspamd_fuzzy_backend_prepare_update (struct rspamd_fuzzy_backend *backend); +gboolean rspamd_fuzzy_backend_prepare_update (struct rspamd_fuzzy_backend *backend, + const gchar *source); /** * Add digest to the database @@ -72,7 +73,8 @@ gboolean rspamd_fuzzy_backend_del ( /** * Commit updates to storage */ -gboolean rspamd_fuzzy_backend_finish_update (struct rspamd_fuzzy_backend *backend); +gboolean rspamd_fuzzy_backend_finish_update (struct rspamd_fuzzy_backend *backend, + const gchar *source); /** * Sync storage @@ -90,7 +92,7 @@ gboolean rspamd_fuzzy_backend_sync (struct rspamd_fuzzy_backend *backend, void rspamd_fuzzy_backend_close (struct rspamd_fuzzy_backend *backend); gsize rspamd_fuzzy_backend_count (struct rspamd_fuzzy_backend *backend); -gint rspamd_fuzzy_backend_version (struct rspamd_fuzzy_backend *backend); +gint rspamd_fuzzy_backend_version (struct rspamd_fuzzy_backend *backend, const gchar *source); gsize rspamd_fuzzy_backend_expired (struct rspamd_fuzzy_backend *backend); const gchar * rspamd_fuzzy_backend_id (struct rspamd_fuzzy_backend *backend); diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index d314d3fdc..a48de05dc 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -873,9 +873,8 @@ rspamd_metric_result_ucl (struct rspamd_task *task, return obj; } -static void -rspamd_ucl_torspamc_output (struct rspamd_task *task, - ucl_object_t *top, +void +rspamd_ucl_torspamc_output (const ucl_object_t *top, rspamd_fstring_t **out) { const ucl_object_t *metric, *score, @@ -927,12 +926,15 @@ rspamd_ucl_torspamc_output (struct rspamd_task *task, } } - rspamd_printf_fstring (out, "Message-ID: %s\r\n", task->message_id); + elt = ucl_object_lookup (top, "message-id"); + if (elt != NULL) { + rspamd_printf_fstring (out, "Message-ID: %s\r\n", + ucl_object_tostring (elt)); + } } static void -rspamd_ucl_tospamc_output (struct rspamd_task *task, - ucl_object_t *top, +rspamd_ucl_tospamc_output (const ucl_object_t *top, rspamd_fstring_t **out) { const ucl_object_t *metric, *score, @@ -1055,10 +1057,10 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg, } else { if (RSPAMD_TASK_IS_SPAMC (task)) { - rspamd_ucl_tospamc_output (task, top, &msg->body); + rspamd_ucl_tospamc_output (top, &msg->body); } else { - rspamd_ucl_torspamc_output (task, top, &msg->body); + rspamd_ucl_torspamc_output (top, &msg->body); } } diff --git a/src/libserver/protocol.h b/src/libserver/protocol.h index 3c8383565..1f7acbab2 100644 --- a/src/libserver/protocol.h +++ b/src/libserver/protocol.h @@ -82,5 +82,13 @@ ucl_object_t * rspamd_protocol_write_ucl (struct rspamd_task *task); */ void rspamd_protocol_write_reply (struct rspamd_task *task); +/** + * Convert rspamd output to legacy protocol reply + * @param task + * @param top + * @param out + */ +void rspamd_ucl_torspamc_output (const ucl_object_t *top, + rspamd_fstring_t **out); #endif diff --git a/src/libserver/re_cache.c b/src/libserver/re_cache.c index 3e308415d..332486cdd 100644 --- a/src/libserver/re_cache.c +++ b/src/libserver/re_cache.c @@ -746,7 +746,7 @@ rspamd_re_cache_exec_re (struct rspamd_task *task, re_class->type_data, is_strong); - if (headerlist) { + if (headerlist && headerlist->len > 0) { scvec = g_malloc (sizeof (*scvec) * headerlist->len); lenvec = g_malloc (sizeof (*lenvec) * headerlist->len); @@ -795,7 +795,7 @@ rspamd_re_cache_exec_re (struct rspamd_task *task, re_class->type_data, is_strong); - if (headerlist) { + if (headerlist && headerlist->len > 0) { scvec = g_malloc (sizeof (*scvec) * headerlist->len); lenvec = g_malloc (sizeof (*lenvec) * headerlist->len); @@ -1494,7 +1494,8 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache, * crc - 8 bytes checksum * <hyperscan blob> */ - crc = XXH64 (hs_serialized, serialized_len, 0xdeadbabe); + crc = rspamd_cryptobox_fast_hash_specific (RSPAMD_CRYPTOBOX_XXHASH64, + hs_serialized, serialized_len, 0xdeadbabe); if (cache->vectorized_hyperscan) { iov[0].iov_base = (void *) rspamd_hs_magic_vector; diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 740c4cd7a..bf596a343 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -248,9 +248,9 @@ rspamd_prepare_worker (struct rspamd_worker *worker, const char *name, void (*accept_handler)(int, short, void *)) { struct event_base *ev_base; - struct event *accept_event; + struct event *accept_events; GList *cur; - gint listen_socket; + struct rspamd_worker_listen_socket *ls; #ifdef WITH_PROFILER extern void _start (void), etext (void); @@ -271,17 +271,20 @@ rspamd_prepare_worker (struct rspamd_worker *worker, const char *name, /* Accept all sockets */ if (accept_handler) { cur = worker->cf->listen_socks; + while (cur) { - listen_socket = GPOINTER_TO_INT (cur->data); - if (listen_socket != -1) { - accept_event = g_slice_alloc0 (sizeof (struct event)); - event_set (accept_event, listen_socket, EV_READ | EV_PERSIST, + ls = cur->data; + + if (ls->fd != -1) { + accept_events = g_slice_alloc0 (sizeof (struct event) * 2); + event_set (&accept_events[0], ls->fd, EV_READ | EV_PERSIST, accept_handler, worker); - event_base_set (ev_base, accept_event); - event_add (accept_event, NULL); + event_base_set (ev_base, &accept_events[0]); + event_add (&accept_events[0], NULL); worker->accept_events = g_list_prepend (worker->accept_events, - accept_event); + accept_events); } + cur = g_list_next (cur); } } @@ -293,7 +296,7 @@ void rspamd_worker_stop_accept (struct rspamd_worker *worker) { GList *cur; - struct event *event; + struct event *events; GHashTableIter it; struct rspamd_worker_signal_handler *sigh; gpointer k, v; @@ -302,10 +305,18 @@ rspamd_worker_stop_accept (struct rspamd_worker *worker) /* Remove all events */ cur = worker->accept_events; while (cur) { - event = cur->data; - event_del (event); + events = cur->data; + + if (event_get_base (&events[0])) { + event_del (&events[0]); + } + + if (event_get_base (&events[1])) { + event_del (&events[1]); + } + cur = g_list_next (cur); - g_slice_free1 (sizeof (struct event), event); + g_slice_free1 (sizeof (struct event) * 2, events); } if (worker->accept_events != NULL) { |