33 #ifdef BUILD_HYPERSCAN
41 static int MatchEvent(
unsigned int id,
unsigned long long from,
42 unsigned long long to,
unsigned int flags,
void *context)
44 uint64_t *match_offset = context;
50 typedef struct SpmHsCtx_ {
60 SpmHsCtx *sctx =
ctx->ctx;
62 hs_free_database(sctx->db);
68 static int HSBuildDatabase(
const uint8_t *needle, uint16_t needle_len,
69 int nocase, SpmHsCtx *sctx,
78 unsigned flags = nocase ? HS_FLAG_CASELESS : 0;
80 hs_database_t *db = NULL;
81 hs_compile_error_t *compile_err = NULL;
82 hs_error_t err = hs_compile(expr,
flags, HS_MODE_BLOCK, NULL, &db,
84 if (err != HS_SUCCESS) {
85 SCLogError(
"Unable to compile '%s' with Hyperscan, "
94 hs_scratch_t *scratch = global_thread_ctx->
ctx;
95 err = hs_alloc_scratch(db, &scratch);
96 if (err != HS_SUCCESS) {
99 SCLogError(
"Unable to alloc scratch for Hyperscan, returned %d.", err);
102 global_thread_ctx->
ctx = scratch;
104 sctx->needle_len = needle_len;
109 static SpmCtx *HSInitCtx(
const uint8_t *needle, uint16_t needle_len,
int nocase,
119 SpmHsCtx *sctx =
SCCalloc(1,
sizeof(SpmHsCtx));
127 if (HSBuildDatabase(needle, needle_len, nocase, sctx,
128 global_thread_ctx) != 0) {
138 const uint8_t *haystack, uint32_t haystack_len)
140 const SpmHsCtx *sctx =
ctx->ctx;
141 hs_scratch_t *scratch = thread_ctx->
ctx;
147 uint64_t match_offset = UINT64_MAX;
148 hs_error_t err = hs_scan(sctx->db, (
const char *)haystack, haystack_len, 0,
149 scratch, MatchEvent, &match_offset);
150 if (err != HS_SUCCESS && err != HS_SCAN_TERMINATED) {
154 SCLogError(
"Hyperscan returned fatal error %d.", err);
158 if (match_offset == UINT64_MAX) {
165 return (uint8_t *)haystack + (match_offset - sctx->needle_len);
171 if (global_thread_ctx == NULL) {
172 SCLogDebug(
"Unable to alloc SpmGlobalThreadCtx.");
179 global_thread_ctx->
ctx = NULL;
181 return global_thread_ctx;
186 if (global_thread_ctx == NULL) {
189 hs_free_scratch(global_thread_ctx->
ctx);
190 SCFree(global_thread_ctx);
193 static void HSDestroyThreadCtx(
SpmThreadCtx *thread_ctx)
195 if (thread_ctx == NULL) {
198 hs_free_scratch(thread_ctx->
ctx);
205 if (thread_ctx == NULL) {
211 if (global_thread_ctx->
ctx != NULL) {
212 hs_scratch_t *scratch = NULL;
213 hs_error_t err = hs_clone_scratch(global_thread_ctx->
ctx, &scratch);
214 if (err != HS_SUCCESS) {
215 SCLogError(
"Unable to clone scratch (error %d).", err);
218 thread_ctx->
ctx = scratch;