diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-12-08 00:55:26 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-12-08 00:55:26 +0000 |
commit | 239c4e5d2e8ede4bcdc35058208371e8febaf6c1 (patch) | |
tree | c80592a9a7d0f6e153acb4c7f3ccd2f1ee3eb465 /src/libserver | |
parent | b19163b84133ada0ff04581065905be7a7436d96 (diff) | |
download | rspamd-239c4e5d2e8ede4bcdc35058208371e8febaf6c1.tar.gz rspamd-239c4e5d2e8ede4bcdc35058208371e8febaf6c1.zip |
Fix re-using of hyperscan hashes
Diffstat (limited to 'src/libserver')
-rw-r--r-- | src/libserver/re_cache.c | 40 |
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 } |