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));
85 SCLogDebug(
"Failed to rewind file %s: %s", file_path, strerror(errno));
90 size_t bytes_read = fread(buffer, 1, file_sz, file);
91 if (bytes_read != (
size_t)file_sz) {
92 SCLogDebug(
"Failed to read the entire file %s: %s", file_path, strerror(errno));
107 static void SCHSCachePatternHash(
const SCHSPattern *p, uint32_t *h1, uint32_t *h2)
109 BUG_ON(p->original_pat == NULL);
122 int HSLoadCache(hs_database_t **hs_db, uint64_t hs_db_hash,
const char *dirpath)
124 const char *hash_file_static = HSCacheConstructFPath(dirpath, hs_db_hash);
125 if (hash_file_static == NULL)
128 SCLogDebug(
"Loading the cached HS DB from %s", hash_file_static);
132 FILE *db_cache = fopen(hash_file_static,
"r");
137 buffer = HSReadStream(hash_file_static, &buffer_size);
139 SCLogWarning(
"Hyperscan cached DB file %s cannot be read", hash_file_static);
144 hs_error_t error = hs_deserialize_database(buffer, buffer_size, hs_db);
145 if (error != HS_SUCCESS) {
146 SCLogWarning(
"Failed to deserialize Hyperscan database of %s: %s", hash_file_static,
147 HSErrorToStr(error));
164 static int HSSaveCache(hs_database_t *hs_db, uint64_t hs_db_hash,
const char *dstpath)
166 static bool notified =
false;
167 char *db_stream = NULL;
171 hs_error_t err = hs_serialize_database(hs_db, &db_stream, &db_size);
172 if (err != HS_SUCCESS) {
173 SCLogWarning(
"Failed to serialize Hyperscan database: %s", HSErrorToStr(err));
177 const char *hash_file_static = HSCacheConstructFPath(dstpath, hs_db_hash);
178 SCLogDebug(
"Caching the compiled HS at %s", hash_file_static);
184 SCLogWarning(
"Overwriting cache file %s. If the problem persists consider switching off "
189 FILE *db_cache_out = fopen(hash_file_static,
"w");
192 SCLogWarning(
"Failed to create Hyperscan cache file, make sure the folder exist and is "
193 "writable or adjust sgh-mpm-caching-path setting (%s)",
199 size_t r = fwrite(db_stream,
sizeof(db_stream[0]), db_size, db_cache_out);
200 if (r > 0 && (
size_t)r != db_size) {
201 SCLogWarning(
"Failed to write to file: %s", hash_file_static);
204 r = remove(hash_file_static);
206 SCLogWarning(
"Failed to remove corrupted cache file: %s", hash_file_static);
210 ret = fclose(db_cache_out);
212 SCLogWarning(
"Failed to close file: %s", hash_file_static);
223 uint64_t HSHashDb(
const PatternDatabase *pd)
225 uint64_t cached_hash = 0;
226 uint32_t *hash = (uint32_t *)(&cached_hash);
227 hashword2(&pd->pattern_cnt, 1, &hash[0], &hash[1]);
228 for (uint32_t i = 0; i < pd->pattern_cnt; i++) {
229 SCHSCachePatternHash(pd->parray[i], &hash[0], &hash[1]);
235 void HSSaveCacheIterator(
void *data,
void *aux)
237 PatternDatabase *pd = (PatternDatabase *)data;
238 struct HsIteratorData *iter_data = (
struct HsIteratorData *)aux;
243 iter_data->pd_stats->hs_cacheable_dbs_cnt++;
245 iter_data->pd_stats->hs_dbs_cache_loaded_cnt++;
249 if (HSSaveCache(pd->hs_db, HSHashDb(pd), iter_data->cache_path) == 0) {
251 iter_data->pd_stats->hs_dbs_cache_saved_cnt++;