summaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-12-08 00:55:26 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-12-08 00:55:26 +0000
commit239c4e5d2e8ede4bcdc35058208371e8febaf6c1 (patch)
treec80592a9a7d0f6e153acb4c7f3ccd2f1ee3eb465 /src/libserver
parentb19163b84133ada0ff04581065905be7a7436d96 (diff)
downloadrspamd-239c4e5d2e8ede4bcdc35058208371e8febaf6c1.tar.gz
rspamd-239c4e5d2e8ede4bcdc35058208371e8febaf6c1.zip
Fix re-using of hyperscan hashes
Diffstat (limited to 'src/libserver')
-rw-r--r--src/libserver/re_cache.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/libserver/re_cache.c b/src/libserver/re_cache.c
index af11f02c5..9614bd36f 100644
--- a/src/libserver/re_cache.c
+++ b/src/libserver/re_cache.c
@@ -63,7 +63,7 @@ struct rspamd_re_class {
gpointer type_data;
gsize type_len;
GHashTable *re;
- gchar hash[rspamd_cryptobox_HASHBYTES * 2 + 1];
+ gchar hash[rspamd_cryptobox_HASHBYTES + 1];
#ifdef WITH_HYPERSCAN
hs_database_t *hs_db;
@@ -87,7 +87,7 @@ struct rspamd_re_cache {
ref_entry_t ref;
guint nre;
guint max_re_data;
- gchar hash[rspamd_cryptobox_HASHBYTES * 2 + 1];
+ gchar hash[rspamd_cryptobox_HASHBYTES + 1];
#ifdef WITH_HYPERSCAN
hs_platform_info_t plt;
#endif
@@ -112,7 +112,7 @@ rspamd_re_cache_class_id (enum rspamd_re_type type,
{
XXH64_state_t st;
- XXH64_reset (&st, rspamd_hash_seed ());
+ XXH64_reset (&st, 0xdeadbabe);
XXH64_update (&st, &type, sizeof (type));
if (datalen > 0) {
@@ -209,7 +209,7 @@ rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re,
elt->re = rspamd_regexp_ref (re);
g_ptr_array_add (cache->re, elt);
rspamd_regexp_set_class (re, re_class);
- g_hash_table_insert (re_class->re, nre, nre);
+ g_hash_table_insert (re_class->re, rspamd_regexp_get_id (nre), nre);
}
void
@@ -243,7 +243,9 @@ rspamd_re_cache_replace (struct rspamd_re_cache *cache,
/*
* On calling of this function, we actually unref old re (what)
*/
- g_hash_table_insert (re_class->re, what, rspamd_regexp_ref (with));
+ g_hash_table_insert (re_class->re,
+ rspamd_regexp_get_id (what),
+ rspamd_regexp_ref (with));
}
if (elt) {
@@ -732,6 +734,21 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
re_class = v;
rspamd_snprintf (path, sizeof (path), "%s%c%s.hs", cache_dir,
G_DIR_SEPARATOR, re_class->hash);
+
+ if (rspamd_re_cache_is_valid_hyperscan_file (cache, path)) {
+ msg_info_re_cache ("skip already valid file for re class '%s'",
+ re_class->hash);
+
+ fd = open (path, O_RDONLY, 00600);
+
+ /* Read number of regexps */
+ g_assert (fd != -1);
+ lseek (fd, SEEK_SET, RSPAMD_HS_MAGIC_LEN);
+ read (fd, &n, sizeof (n));
+ total += n;
+ continue;
+ }
+
fd = open (path, O_CREAT|O_TRUNC|O_EXCL|O_WRONLY, 00600);
if (fd == -1) {
@@ -888,7 +905,7 @@ rspamd_re_cache_is_valid_hyperscan_file (struct rspamd_re_cache *cache,
len = strlen (path);
- if (len < sizeof (rspamd_cryptobox_HASHBYTES * 2 + 3)) {
+ if (len < sizeof (rspamd_cryptobox_HASHBYTES + 3)) {
return FALSE;
}
@@ -896,7 +913,8 @@ rspamd_re_cache_is_valid_hyperscan_file (struct rspamd_re_cache *cache,
return FALSE;
}
- hash_pos = path + len - 3 - rspamd_cryptobox_HASHBYTES * 2;
+ hash_pos = path + len - 3 - rspamd_cryptobox_HASHBYTES;
+ g_hash_table_iter_init (&it, cache->re_classes);
while (g_hash_table_iter_next (&it, &k, &v)) {
re_class = v;
@@ -918,6 +936,8 @@ rspamd_re_cache_is_valid_hyperscan_file (struct rspamd_re_cache *cache,
return FALSE;
}
+ close (fd);
+
if (memcmp (magicbuf, rspamd_hs_magic, sizeof (magicbuf)) != 0) {
msg_err_re_cache ("cannot open hyperscan cache file %s: "
"bad magic ('%*xs', '%*xs' expected)",
@@ -927,7 +947,13 @@ rspamd_re_cache_is_valid_hyperscan_file (struct rspamd_re_cache *cache,
return FALSE;
}
+
+ return TRUE;
}
}
+
+ msg_warn_re_cache ("unknown hyperscan cache file %s", path);
+
+ return FALSE;
#endif
}