33 #ifdef BUILD_HYPERSCAN
39 static int MatchEvent(
unsigned int id,
unsigned long long from,
40 unsigned long long to,
unsigned int flags,
void *context)
42 uint64_t *match_offset = context;
48 typedef struct SpmHsCtx_ {
58 SpmHsCtx *sctx =
ctx->ctx;
60 hs_free_database(sctx->db);
66 static int HSBuildDatabase(
const uint8_t *needle, uint16_t needle_len,
67 int nocase, SpmHsCtx *sctx,
70 char *expr = HSRenderPattern(needle, needle_len);
76 unsigned flags = nocase ? HS_FLAG_CASELESS : 0;
78 hs_database_t *db = NULL;
79 hs_compile_error_t *compile_err = NULL;
80 hs_error_t err = hs_compile(expr,
flags, HS_MODE_BLOCK, NULL, &db,
82 if (err != HS_SUCCESS) {
83 HSLogCompileError(expr, compile_err, err);
91 hs_scratch_t *scratch = global_thread_ctx->
ctx;
92 err = hs_alloc_scratch(db, &scratch);
93 if (err != HS_SUCCESS) {
96 SCLogError(
"Unable to alloc scratch for Hyperscan, returned %d.", err);
100 global_thread_ctx->
ctx = scratch;
102 sctx->needle_len = needle_len;
107 static SpmCtx *HSInitCtx(
const uint8_t *needle, uint16_t needle_len,
int nocase,
117 SpmHsCtx *sctx =
SCCalloc(1,
sizeof(SpmHsCtx));
125 if (HSBuildDatabase(needle, needle_len, nocase, sctx,
126 global_thread_ctx) != 0) {
136 const uint8_t *haystack, uint32_t haystack_len)
138 const SpmHsCtx *sctx =
ctx->ctx;
139 hs_scratch_t *scratch = thread_ctx->
ctx;
145 uint64_t match_offset = UINT64_MAX;
146 hs_error_t err = hs_scan(sctx->db, (
const char *)haystack, haystack_len, 0,
147 scratch, MatchEvent, &match_offset);
148 if (err != HS_SUCCESS && err != HS_SCAN_TERMINATED) {
152 SCLogError(
"Hyperscan returned fatal error %d.", err);
156 if (match_offset == UINT64_MAX) {
163 return (uint8_t *)haystack + (match_offset - sctx->needle_len);
169 if (global_thread_ctx == NULL) {
170 SCLogDebug(
"Unable to alloc SpmGlobalThreadCtx.");
177 global_thread_ctx->
ctx = NULL;
179 return global_thread_ctx;
184 if (global_thread_ctx == NULL) {
187 hs_free_scratch(global_thread_ctx->
ctx);
188 SCFree(global_thread_ctx);
191 static void HSDestroyThreadCtx(
SpmThreadCtx *thread_ctx)
193 if (thread_ctx == NULL) {
196 hs_free_scratch(thread_ctx->
ctx);
203 if (thread_ctx == NULL) {
209 if (global_thread_ctx->
ctx != NULL) {
210 hs_scratch_t *scratch = NULL;
211 hs_error_t err = hs_clone_scratch(global_thread_ctx->
ctx, &scratch);
212 if (err != HS_SUCCESS) {
213 SCLogError(
"Unable to clone scratch (error %d).", err);
216 thread_ctx->
ctx = scratch;