32 #ifdef BUILD_HYPERSCAN
40 static int MatchEvent(
unsigned int id,
unsigned long long from,
41 unsigned long long to,
unsigned int flags,
void *context)
43 uint64_t *match_offset = context;
44 BUG_ON(*match_offset != UINT64_MAX);
49 typedef struct SpmHsCtx_ {
59 SpmHsCtx *sctx =
ctx->ctx;
61 hs_free_database(sctx->db);
67 static int HSBuildDatabase(
const uint8_t *needle, uint16_t needle_len,
68 int nocase, SpmHsCtx *sctx,
77 unsigned flags = nocase ? HS_FLAG_CASELESS : 0;
79 hs_database_t *db = NULL;
80 hs_compile_error_t *compile_err = NULL;
81 hs_error_t err = hs_compile(expr,
flags, HS_MODE_BLOCK, NULL, &db,
83 if (err != HS_SUCCESS) {
84 SCLogError(
"Unable to compile '%s' with Hyperscan, "
93 hs_scratch_t *scratch = global_thread_ctx->
ctx;
94 err = hs_alloc_scratch(db, &scratch);
95 if (err != HS_SUCCESS) {
98 SCLogError(
"Unable to alloc scratch for Hyperscan, returned %d.", err);
101 global_thread_ctx->
ctx = scratch;
103 sctx->needle_len = needle_len;
108 static SpmCtx *HSInitCtx(
const uint8_t *needle, uint16_t needle_len,
int nocase,
118 SpmHsCtx *sctx =
SCCalloc(1,
sizeof(SpmHsCtx));
126 if (HSBuildDatabase(needle, needle_len, nocase, sctx,
127 global_thread_ctx) != 0) {
137 const uint8_t *haystack, uint32_t haystack_len)
139 const SpmHsCtx *sctx =
ctx->ctx;
140 hs_scratch_t *scratch = thread_ctx->
ctx;
146 uint64_t match_offset = UINT64_MAX;
147 hs_error_t err = hs_scan(sctx->db, (
const char *)haystack, haystack_len, 0,
148 scratch, MatchEvent, &match_offset);
149 if (err != HS_SUCCESS && err != HS_SCAN_TERMINATED) {
153 SCLogError(
"Hyperscan returned fatal error %d.", err);
157 if (match_offset == UINT64_MAX) {
161 BUG_ON(match_offset < sctx->needle_len);
164 return (uint8_t *)haystack + (match_offset - sctx->needle_len);
170 if (global_thread_ctx == NULL) {
171 SCLogDebug(
"Unable to alloc SpmGlobalThreadCtx.");
178 global_thread_ctx->
ctx = NULL;
180 return global_thread_ctx;
185 if (global_thread_ctx == NULL) {
188 hs_free_scratch(global_thread_ctx->
ctx);
189 SCFree(global_thread_ctx);
192 static void HSDestroyThreadCtx(
SpmThreadCtx *thread_ctx)
194 if (thread_ctx == NULL) {
197 hs_free_scratch(thread_ctx->
ctx);
204 if (thread_ctx == NULL) {
210 if (global_thread_ctx->
ctx != NULL) {
211 hs_scratch_t *scratch = NULL;
212 hs_error_t err = hs_clone_scratch(global_thread_ctx->
ctx, &scratch);
213 if (err != HS_SUCCESS) {
214 SCLogError(
"Unable to clone scratch (error %d).", err);
217 thread_ctx->
ctx = scratch;