35 #ifdef BUILD_HYPERSCAN
39 static const char *HSCacheConstructFPath(
const char *folder_path, uint64_t hs_db_hash)
41 static char hash_file_path[PATH_MAX];
43 char hash_file_path_suffix[] =
"_v1.hs";
44 char filename[PATH_MAX];
46 snprintf(filename,
sizeof(filename),
"%020lu%s", hs_db_hash, hash_file_path_suffix);
47 if (r != (uint64_t)(20 + strlen(hash_file_path_suffix)))
50 r =
PathMerge(hash_file_path,
sizeof(hash_file_path), folder_path, filename);
54 return hash_file_path;
57 static char *HSReadStream(
const char *file_path,
size_t *buffer_sz)
59 FILE *file = fopen(file_path,
"rb");
61 SCLogDebug(
"Failed to open file %s: %s", file_path, strerror(errno));
66 fseek(file, 0, SEEK_END);
67 long file_sz = ftell(file);
69 SCLogDebug(
"Failed to determine file size of %s: %s", file_path, strerror(errno));
74 char *buffer = (
char *)
SCCalloc(file_sz,
sizeof(
char));
83 size_t bytes_read = fread(buffer, 1, file_sz, file);
84 if (bytes_read != (
size_t)file_sz) {
85 SCLogDebug(
"Failed to read the entire file %s: %s", file_path, strerror(errno));
100 static void SCHSCachePatternHash(
const SCHSPattern *p, uint32_t *h1, uint32_t *h2)
102 BUG_ON(p->original_pat == NULL);
115 int HSLoadCache(hs_database_t **hs_db, uint64_t hs_db_hash,
const char *dirpath)
117 const char *hash_file_static = HSCacheConstructFPath(dirpath, hs_db_hash);
118 if (hash_file_static == NULL)
121 SCLogDebug(
"Loading the cached HS DB from %s", hash_file_static);
125 FILE *db_cache = fopen(hash_file_static,
"r");
130 buffer = HSReadStream(hash_file_static, &buffer_size);
132 SCLogWarning(
"Hyperscan cached DB file %s cannot be read", hash_file_static);
137 hs_error_t error = hs_deserialize_database(buffer, buffer_size, hs_db);
138 if (error != HS_SUCCESS) {
139 SCLogWarning(
"Failed to deserialize Hyperscan database of %s: %s", hash_file_static,
140 HSErrorToStr(error));
157 static int HSSaveCache(hs_database_t *hs_db, uint64_t hs_db_hash,
const char *dstpath)
159 static bool notified =
false;
160 char *db_stream = NULL;
164 hs_error_t err = hs_serialize_database(hs_db, &db_stream, &db_size);
165 if (err != HS_SUCCESS) {
166 SCLogWarning(
"Failed to serialize Hyperscan database: %s", HSErrorToStr(err));
170 const char *hash_file_static = HSCacheConstructFPath(dstpath, hs_db_hash);
171 SCLogDebug(
"Caching the compiled HS at %s", hash_file_static);
177 SCLogWarning(
"Overwriting cache file %s. If the problem persists consider switching off "
182 FILE *db_cache_out = fopen(hash_file_static,
"w");
185 SCLogWarning(
"Failed to create Hyperscan cache file, make sure the folder exist and is "
186 "writable or adjust sgh-mpm-caching-path setting (%s)",
192 size_t r = fwrite(db_stream,
sizeof(db_stream[0]), db_size, db_cache_out);
193 if (r > 0 && (
size_t)r != db_size) {
194 SCLogWarning(
"Failed to write to file: %s", hash_file_static);
197 r = remove(hash_file_static);
199 SCLogWarning(
"Failed to remove corrupted cache file: %s", hash_file_static);
203 ret = fclose(db_cache_out);
205 SCLogWarning(
"Failed to close file: %s", hash_file_static);
216 uint64_t HSHashDb(
const PatternDatabase *pd)
218 uint64_t cached_hash = 0;
219 uint32_t *hash = (uint32_t *)(&cached_hash);
220 hashword2(&pd->pattern_cnt, 1, &hash[0], &hash[1]);
221 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
222 SCHSCachePatternHash(pd->parray[i], &hash[0], &hash[1]);
228 void HSSaveCacheIterator(
void *data,
void *aux)
230 PatternDatabase *pd = (PatternDatabase *)data;
231 struct HsIteratorData *iter_data = (
struct HsIteratorData *)aux;
236 iter_data->pd_stats->hs_cacheable_dbs_cnt++;
238 iter_data->pd_stats->hs_dbs_cache_loaded_cnt++;
242 if (HSSaveCache(pd->hs_db, HSHashDb(pd), iter_data->cache_path) == 0) {
244 iter_data->pd_stats->hs_dbs_cache_saved_cnt++;