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_ {
54 static void HSDestroyCtx(
SpmCtx *ctx)
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,
116 memset(ctx, 0,
sizeof(
SpmCtx));
119 SpmHsCtx *sctx =
SCMalloc(
sizeof(SpmHsCtx));
127 memset(sctx, 0,
sizeof(SpmHsCtx));
128 if (HSBuildDatabase(needle, needle_len, nocase, sctx,
129 global_thread_ctx) != 0) {
139 const uint8_t *haystack, uint32_t haystack_len)
141 const SpmHsCtx *sctx = ctx->
ctx;
142 hs_scratch_t *scratch = thread_ctx->
ctx;
148 uint64_t match_offset = UINT64_MAX;
149 hs_error_t err = hs_scan(sctx->db, (
const char *)haystack, haystack_len, 0,
150 scratch, MatchEvent, &match_offset);
151 if (err != HS_SUCCESS && err != HS_SCAN_TERMINATED) {
155 SCLogError(
"Hyperscan returned fatal error %d.", err);
159 if (match_offset == UINT64_MAX) {
163 BUG_ON(match_offset < sctx->needle_len);
166 return (uint8_t *)haystack + (match_offset - sctx->needle_len);
172 if (global_thread_ctx == NULL) {
173 SCLogDebug(
"Unable to alloc SpmGlobalThreadCtx.");
176 memset(global_thread_ctx, 0,
sizeof(*global_thread_ctx));
181 global_thread_ctx->
ctx = NULL;
183 return global_thread_ctx;
188 if (global_thread_ctx == NULL) {
191 hs_free_scratch(global_thread_ctx->
ctx);
192 SCFree(global_thread_ctx);
195 static void HSDestroyThreadCtx(
SpmThreadCtx *thread_ctx)
197 if (thread_ctx == NULL) {
200 hs_free_scratch(thread_ctx->
ctx);
207 if (thread_ctx == NULL) {
211 memset(thread_ctx, 0,
sizeof(*thread_ctx));
214 if (global_thread_ctx->
ctx != NULL) {
215 hs_scratch_t *scratch = NULL;
216 hs_error_t err = hs_clone_scratch(global_thread_ctx->
ctx, &scratch);
217 if (err != HS_SUCCESS) {
218 SCLogError(
"Unable to clone scratch (error %d).", err);
221 thread_ctx->
ctx = scratch;