summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-09-05 16:57:40 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-09-05 16:57:40 +0100
commit0a52bb55e954a56fc4d2a934e4d33ee1e77795a0 (patch)
tree14dc357df11ab04402ecde1f9bb4682d5aaece5f
parentaaf486034f4c95b63d7cd8f8dc02af66d515b5cb (diff)
downloadrspamd-0a52bb55e954a56fc4d2a934e4d33ee1e77795a0.tar.gz
rspamd-0a52bb55e954a56fc4d2a934e4d33ee1e77795a0.zip
[Minor] Fix multiple issues in redis fuzzy backend
-rw-r--r--src/libserver/fuzzy_backend.c10
-rw-r--r--src/libserver/fuzzy_backend_redis.c136
2 files changed, 137 insertions, 9 deletions
diff --git a/src/libserver/fuzzy_backend.c b/src/libserver/fuzzy_backend.c
index 030028389..3dec60c57 100644
--- a/src/libserver/fuzzy_backend.c
+++ b/src/libserver/fuzzy_backend.c
@@ -85,6 +85,16 @@ static const struct rspamd_fuzzy_backend_subr fuzzy_subrs[] = {
.id = rspamd_fuzzy_backend_id_sqlite,
.periodic = rspamd_fuzzy_backend_expire_sqlite,
.close = rspamd_fuzzy_backend_close_sqlite,
+ },
+ [RSPAMD_FUZZY_BACKEND_REDIS] = {
+ .init = rspamd_fuzzy_backend_init_redis,
+ .check = rspamd_fuzzy_backend_check_redis,
+ .update = rspamd_fuzzy_backend_update_redis,
+ .count = rspamd_fuzzy_backend_count_redis,
+ .version = rspamd_fuzzy_backend_version_redis,
+ .id = rspamd_fuzzy_backend_id_redis,
+ .periodic = rspamd_fuzzy_backend_expire_redis,
+ .close = rspamd_fuzzy_backend_close_redis,
}
};
diff --git a/src/libserver/fuzzy_backend_redis.c b/src/libserver/fuzzy_backend_redis.c
index 66490d386..a03c29a6c 100644
--- a/src/libserver/fuzzy_backend_redis.c
+++ b/src/libserver/fuzzy_backend_redis.c
@@ -193,7 +193,7 @@ rspamd_fuzzy_backend_redis_dtor (struct rspamd_fuzzy_backend_redis *backend)
rspamd_upstreams_destroy (backend->read_servers);
}
if (backend->write_servers) {
- rspamd_upstreams_destroy (backend->read_servers);
+ rspamd_upstreams_destroy (backend->write_servers);
}
if (backend->id) {
@@ -893,6 +893,7 @@ rspamd_fuzzy_update_append_command (struct rspamd_fuzzy_backend *bk,
{
GString *key, *value;
guint cur_shift = *shift;
+ guint i;
struct rspamd_fuzzy_cmd *cmd;
if (io_cmd->is_shingle) {
@@ -933,7 +934,7 @@ rspamd_fuzzy_update_append_command (struct rspamd_fuzzy_backend *bk,
g_string_free (value, FALSE);
if (redisAsyncCommandArgv (session->ctx, NULL, NULL,
- 3,
+ 4,
(const gchar **)&session->argv[cur_shift - 4],
&session->argv_lens[cur_shift - 4]) != REDIS_OK) {
@@ -957,7 +958,7 @@ rspamd_fuzzy_update_append_command (struct rspamd_fuzzy_backend *bk,
g_string_free (value, FALSE);
if (redisAsyncCommandArgv (session->ctx, NULL, NULL,
- 3,
+ 4,
(const gchar **)&session->argv[cur_shift - 4],
&session->argv_lens[cur_shift - 4]) != REDIS_OK) {
@@ -986,6 +987,121 @@ rspamd_fuzzy_update_append_command (struct rspamd_fuzzy_backend *bk,
return FALSE;
}
+
+ /* INCR */
+ key = g_string_new (session->backend->redis_object);
+ g_string_append (key, "_count");
+ session->argv[cur_shift] = g_strdup ("INCR");
+ session->argv_lens[cur_shift++] = sizeof ("INCR") - 1;
+ session->argv[cur_shift] = key->str;
+ session->argv_lens[cur_shift++] = key->len;
+ g_string_free (key, FALSE);
+
+ if (redisAsyncCommandArgv (session->ctx, NULL, NULL,
+ 2,
+ (const gchar **)&session->argv[cur_shift - 2],
+ &session->argv_lens[cur_shift - 2]) != REDIS_OK) {
+
+ return FALSE;
+ }
+ }
+ else if (cmd->cmd == FUZZY_DEL) {
+ /* DEL */
+ key = g_string_new (session->backend->redis_object);
+ g_string_append_len (key, cmd->digest, sizeof (cmd->digest));
+ session->argv[cur_shift] = g_strdup ("DEL");
+ session->argv_lens[cur_shift++] = sizeof ("DEL") - 1;
+ session->argv[cur_shift] = key->str;
+ session->argv_lens[cur_shift++] = key->len;
+ g_string_free (key, FALSE);
+
+ if (redisAsyncCommandArgv (session->ctx, NULL, NULL,
+ 2,
+ (const gchar **)&session->argv[cur_shift - 2],
+ &session->argv_lens[cur_shift - 2]) != REDIS_OK) {
+
+ return FALSE;
+ }
+
+ /* DECR */
+ key = g_string_new (session->backend->redis_object);
+ g_string_append (key, "_count");
+ session->argv[cur_shift] = g_strdup ("DECR");
+ session->argv_lens[cur_shift++] = sizeof ("DECR") - 1;
+ session->argv[cur_shift] = key->str;
+ session->argv_lens[cur_shift++] = key->len;
+ g_string_free (key, FALSE);
+
+ if (redisAsyncCommandArgv (session->ctx, NULL, NULL,
+ 2,
+ (const gchar **)&session->argv[cur_shift - 2],
+ &session->argv_lens[cur_shift - 2]) != REDIS_OK) {
+
+ return FALSE;
+ }
+ }
+
+ if (io_cmd->is_shingle) {
+
+
+ if (cmd->cmd == FUZZY_WRITE) {
+ for (i = 0; i < RSPAMD_SHINGLE_SIZE; i ++) {
+ guchar *hval;
+ /*
+ * For each command with shingles we additionally emit 32 commands:
+ * SETEX <prefix>_<number>_<value> <expire> <digest>
+ */
+
+ /* SETEX */
+ key = g_string_new (session->backend->redis_object);
+ rspamd_printf_gstring (key, "_%d_%uL", i,
+ io_cmd->cmd.shingle.sgl.hashes[i]);
+ value = g_string_sized_new (32);
+ rspamd_printf_gstring (value, "%d",
+ (gint)rspamd_fuzzy_backend_get_expire (bk));
+ hval = g_malloc (sizeof (io_cmd->cmd.shingle.basic.digest));
+ memcpy (hval, io_cmd->cmd.shingle.basic.digest,
+ sizeof (io_cmd->cmd.shingle.basic.digest));
+ session->argv[cur_shift] = g_strdup ("SETEX");
+ session->argv_lens[cur_shift++] = sizeof ("SETEX") - 1;
+ session->argv[cur_shift] = key->str;
+ session->argv_lens[cur_shift++] = key->len;
+ session->argv[cur_shift] = value->str;
+ session->argv_lens[cur_shift++] = value->len;
+ session->argv[cur_shift] = hval;
+ session->argv_lens[cur_shift++] = sizeof (io_cmd->cmd.shingle.basic.digest);
+ g_string_free (key, FALSE);
+ g_string_free (value, FALSE);
+
+ if (redisAsyncCommandArgv (session->ctx, NULL, NULL,
+ 4,
+ (const gchar **)&session->argv[cur_shift - 4],
+ &session->argv_lens[cur_shift - 4]) != REDIS_OK) {
+
+ return FALSE;
+ }
+ }
+ }
+ else if (cmd->cmd == FUZZY_DEL) {
+ for (i = 0; i < RSPAMD_SHINGLE_SIZE; i ++) {
+ key = g_string_new (session->backend->redis_object);
+ rspamd_printf_gstring (key, "_%d_%uL", i,
+ io_cmd->cmd.shingle.sgl.hashes[i]);
+ session->argv[cur_shift] = g_strdup ("DEL");
+ session->argv_lens[cur_shift++] = sizeof ("DEL") - 1;
+ session->argv[cur_shift] = key->str;
+ session->argv_lens[cur_shift++] = key->len;
+ g_string_free (key, FALSE);
+
+ if (redisAsyncCommandArgv (session->ctx, NULL, NULL,
+ 2,
+ (const gchar **)&session->argv[cur_shift - 2],
+ &session->argv_lens[cur_shift - 2]) != REDIS_OK) {
+
+ return FALSE;
+ }
+ }
+ }
}
*shift = cur_shift;
@@ -1055,6 +1171,7 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk,
* HSET <key> F <flag>
* HINCRBY <key> V <weight>
* EXPIRE <key> <expire>
+ * INCR <prefix||fuzzy_count>
*
* Where <key> is <prefix> || <digest>
*
@@ -1066,10 +1183,11 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk,
*
* For each delete command with shingles we emit also 32 commands:
* DEL <prefix>_<number>_<value>
+ * DECR <prefix||fuzzy_count>
*/
- ncommands = 3; /* For MULTI + EXEC */
- nargs = 5;
+ ncommands = 3; /* For MULTI + EXEC + INCR <src> */
+ nargs = 4;
for (cur = updates->head; cur != NULL; cur = g_list_next (cur)) {
io_cmd = cur->data;
@@ -1082,8 +1200,8 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk,
}
if (cmd->cmd == FUZZY_WRITE) {
- ncommands += 3;
- nargs += 11;
+ ncommands += 4;
+ nargs += 13;
if (io_cmd->is_shingle) {
ncommands += RSPAMD_SHINGLE_SIZE;
@@ -1092,8 +1210,8 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk,
}
else if (cmd->cmd == FUZZY_DEL) {
- ncommands += 1;
- nargs += 2;
+ ncommands += 2;
+ nargs += 4;
if (io_cmd->is_shingle) {
ncommands += RSPAMD_SHINGLE_SIZE;