static const unsigned char rspamd_hs_magic[] = {'r', 's', 'h', 's', 'r', 'e', '1', '2'};
#define RSPAMD_HS_MAGIC_LEN (sizeof(rspamd_hs_magic))
+const unsigned char *
+rspamd_hyperscan_get_magic(gsize *len)
+{
+ if (len) {
+ *len = RSPAMD_HS_MAGIC_LEN;
+ }
+ return rspamd_hs_magic;
+}
+
gboolean rspamd_hyperscan_serialize_with_header(hs_database_t *db,
const unsigned int *ids,
const unsigned int *flags,
gsize len,
GError **err);
+/**
+ * Get the hyperscan serialization magic bytes.
+ * Used to include magic in hash computations so that version bumps
+ * invalidate cached databases.
+ * @param[out] len length of magic bytes
+ * @return pointer to magic bytes (static storage)
+ */
+const unsigned char *rspamd_hyperscan_get_magic(gsize *len);
+
G_END_DECLS
#endif
else {
if (data->cur_data) {
re_map = data->cur_data;
+#ifdef WITH_HYPERSCAN
+ /* Include serialization magic so version bumps invalidate cache */
+ gsize magic_len;
+ const unsigned char *magic = rspamd_hyperscan_get_magic(&magic_len);
+ rspamd_cryptobox_hash_update(&re_map->hst, magic, magic_len);
+#endif
rspamd_cryptobox_hash_final(&re_map->hst, re_map->re_digest);
memcpy(&data->map->digest, re_map->re_digest, sizeof(data->map->digest));
rspamd_re_map_finalize(re_map);
rspamd_cryptobox_hash_update(re_class->st,
(gpointer) &re_class->num_local_re,
sizeof(re_class->num_local_re));
+ /* Include serialization magic so version bumps invalidate cache */
+ rspamd_cryptobox_hash_update(re_class->st,
+ rspamd_hs_magic,
+ RSPAMD_HS_MAGIC_LEN);
rspamd_cryptobox_hash_final(re_class->st, hash_out);
rspamd_snprintf(re_class->hash, sizeof(re_class->hash), "%*xs",
(int) rspamd_cryptobox_HASHBYTES, hash_out);
g_assert(hs_populate_platform(&plt) == HS_SUCCESS);
rspamd_cryptobox_hash_update(&hash_state, (void *) &plt, sizeof(plt));
+ /* Include serialization magic so version bumps invalidate cache */
+ gsize magic_len;
+ const unsigned char *magic = rspamd_hyperscan_get_magic(&magic_len);
+ rspamd_cryptobox_hash_update(&hash_state, magic, magic_len);
+
rspamd_cryptobox_hash_final(&hash_state, hash_out);
return;
}