return TRUE;
}
-static inline int
+static inline struct rspamd_fuzzy_node *
check_hash_node (GQueue *hash, fuzzy_hash_t *s, int update_value)
{
GList *cur;
if (update_value) {
h->value += update_value;
}
- return h->value;
+ return h;
}
}
}
msg_info ("new hash weight: %d", h->value);
h->value += update_value;
}
- return h->value;
+ return h;
}
cur = g_list_next (cur);
}
g_queue_push_head_link (frequent, cur);
msg_info ("moved hash to frequent list");
}
- return h->value;
+ return h;
}
cur = g_list_next (cur);
}
}
#endif
- return 0;
+ return NULL;
}
static int
-process_check_command (struct fuzzy_cmd *cmd)
+process_check_command (struct fuzzy_cmd *cmd, int *flag)
{
fuzzy_hash_t s;
+ struct rspamd_fuzzy_node *h;
if (!bloom_check (bf, cmd->hash)) {
return 0;
memcpy (s.hash_pipe, cmd->hash, sizeof (s.hash_pipe));
s.block_size = cmd->blocksize;
- return check_hash_node (hashes[cmd->blocksize % BUCKETS], &s, 0);
+ h = check_hash_node (hashes[cmd->blocksize % BUCKETS], &s, 0);
+
+ if (h == NULL) {
+ return 0;
+ }
+ else {
+ *flag = h->flag;
+ return h->value;
+ }
}
static gboolean
memcpy (s.hash_pipe, cmd->hash, sizeof (s.hash_pipe));
s.block_size = cmd->blocksize;
- return check_hash_node (hashes[cmd->blocksize % BUCKETS], &s, cmd->value);
+ return check_hash_node (hashes[cmd->blocksize % BUCKETS], &s, cmd->value) != NULL;
}
static gboolean
h->h.block_size = cmd->blocksize;
h->time = (uint64_t) time (NULL);
h->value = cmd->value;
+ h->flag = cmd->flag;
#ifdef WITH_JUDY
if (use_judy) {
pvalue = JudySLIns (&jtree, h->h.hash_pipe, PJE0);
static void
process_fuzzy_command (struct fuzzy_session *session)
{
- int r;
+ int r, flag = 0;
char buf[64];
switch (session->cmd.cmd) {
case FUZZY_CHECK:
- if ((r = process_check_command (&session->cmd))) {
- r = snprintf (buf, sizeof (buf), "OK %d" CRLF, r);
+ if ((r = process_check_command (&session->cmd, &flag))) {
+ r = snprintf (buf, sizeof (buf), "OK %d %d" CRLF, r, flag);
if (sendto (session->fd, buf, r, 0, (struct sockaddr *)&session->sa, session->salen) == -1) {
msg_err ("error while writing reply: %s", strerror (errno));
}
double max_score;
uint32_t min_hash_len;
radix_tree_t *whitelist;
+ GHashTable *flags;
};
struct fuzzy_client_session {
static void fuzzy_add_handler (char **args, struct controller_session *session);
static void fuzzy_delete_handler (char **args, struct controller_session *session);
+/* Flags string is in format <numeric_flag>:<SYMBOL>[, <numeric_flag>:<SYMBOL>...] */
+static void
+parse_flags_string (char *str)
+{
+ char **strvec, *p, *item, *err_str;
+ int num, i, flag;
+
+ strvec = g_strsplit (str, ", ;", 0);
+ num = g_strv_length (strvec);
+
+ for (i = 0; i < num; i ++) {
+ item = strvec[i];
+ if ((p = strchr (item, ':')) != NULL) {
+ *p = '\0';
+ p ++;
+ /* Now in p we have name of symbol and in item we have its number */
+ errno = 0;
+ flag = strtol (item, &err_str, 10);
+ if (errno != 0 || (err_str && *err_str != '\0')) {
+ msg_info ("cannot parse flag %s: %s", item, strerror (errno));
+ }
+ else {
+ /* Add flag to hash table */
+ g_hash_table_insert (fuzzy_module_ctx->flags, GINT_TO_POINTER(flag), memory_pool_strdup (fuzzy_module_ctx->fuzzy_pool, p));
+ }
+ }
+ }
+
+ g_strfreev (strvec);
+}
+
static void
parse_servers_string (char *str)
{
fuzzy_module_ctx->fuzzy_pool = memory_pool_new (memory_pool_get_size ());
fuzzy_module_ctx->servers = NULL;
fuzzy_module_ctx->servers_num = 0;
+ fuzzy_module_ctx->flags = g_hash_table_new (g_int_hash, g_int_equal);
*ctx = (struct module_ctx *)fuzzy_module_ctx;
fuzzy_module_ctx->whitelist = NULL;
}
-
if ((value = get_module_opt (cfg, "fuzzy_check", "servers")) != NULL) {
parse_servers_string (value);
}
+ if ((value = get_module_opt (cfg, "fuzzy_check", "flags")) != NULL) {
+ parse_flags_string (value);
+ }
metric = g_hash_table_lookup (cfg->metrics, fuzzy_module_ctx->metric);
if (metric == NULL) {
fuzzy_module_ctx->servers = NULL;
fuzzy_module_ctx->servers_num = 0;
fuzzy_module_ctx->fuzzy_pool = memory_pool_new (memory_pool_get_size ());
-
+
+ g_hash_table_remove_all (fuzzy_module_ctx->flags);
return fuzzy_check_module_config (cfg);
}
{
struct fuzzy_client_session *session = arg;
struct fuzzy_cmd cmd;
- char buf[62], *err_str;
+ char buf[62], *err_str, *symbol;
int value = 0, flag = 0, r;
double nval;
}
*err_str = '\0';
nval = fuzzy_normalize (value);
+ /* Get symbol by flag */
+ if ((symbol = g_hash_table_lookup (fuzzy_module_ctx->flags, GINT_TO_POINTER (flag))) == NULL) {
+ /* Default symbol */
+ symbol = fuzzy_module_ctx->symbol;
+ }
snprintf (buf, sizeof (buf), "%d: %d / %.2f", flag, value, nval);
- insert_result (session->task, fuzzy_module_ctx->metric, fuzzy_module_ctx->symbol, nval, g_list_prepend (NULL,
+ insert_result (session->task, fuzzy_module_ctx->metric, symbol, nval, g_list_prepend (NULL,
memory_pool_strdup (session->task->task_pool, buf)));
}
goto ok;