Go to the documentation of this file.
43 THashDataEnqueue(&
ctx->spare_q, h);
60 SCLogError(
"Fatal error encountered in THashDataQueueNew. Exiting...");
63 q = THashDataQueueInit(q);
86 BUG_ON(q == NULL || h == NULL);
103 if (q->
len > q->dbg_maxlen)
104 q->dbg_maxlen = q->
len;
168 size_t total_data_size = thash_data_size + data_size;
195 uint32_t data_size = 0;
196 if (h->
data != NULL) {
197 if (
ctx->config.DataSize) {
198 data_size =
ctx->config.DataSize(h->
data);
208 #define THASH_DEFAULT_HASHSIZE 4096
209 #define THASH_DEFAULT_MEMCAP 16777216
210 #define THASH_DEFAULT_PREALLOC 1000
212 #define GET_VAR(prefix,name) \
213 snprintf(varname, sizeof(varname), "%s.%s", (prefix), (name))
224 const char *conf_val;
225 uint32_t configval = 0;
229 if ((
ConfGet(varname, &conf_val)) == 1)
233 "from conf file - %s. Killing engine",
238 GET_VAR(cnf_prefix,
"hash-size");
239 if ((
ConfGet(varname, &conf_val)) == 1)
241 if (
StringParseUint32(&configval, 10, (uint16_t)strlen(conf_val), conf_val) > 0) {
242 ctx->config.hash_size = configval;
246 GET_VAR(cnf_prefix,
"prealloc");
247 if ((
ConfGet(varname, &conf_val)) == 1)
249 if (
StringParseUint32(&configval, 10, (uint16_t)strlen(conf_val), conf_val) > 0) {
250 ctx->config.prealloc = configval;
257 uint64_t hash_size =
ctx->config.hash_size *
sizeof(THashHashRow);
260 "max hash memcap is smaller than projected hash size. "
261 "Memcap: %" PRIu64
", Hash table size %" PRIu64
". Calculate "
262 "total hash size by multiplying \"hash-size\" with %" PRIuMAX
", "
263 "which is the hash bucket size.",
264 ctx->config.memcap, hash_size, (uintmax_t)
sizeof(THashHashRow));
269 SCLogError(
"Fatal error encountered in THashInitConfig. Exiting...");
272 memset(
ctx->array, 0,
ctx->config.hash_size *
sizeof(THashHashRow));
275 for (i = 0; i <
ctx->config.hash_size; i++) {
281 for (i = 0; i <
ctx->config.prealloc; i++) {
284 "max thash memcap reached. Memcap %" PRIu64
", "
285 "Memuse %" PRIu64
".",
293 SCLogError(
"preallocating data failed: %s", strerror(errno));
296 THashDataEnqueue(&
ctx->spare_q,h);
303 int (*DataSet)(
void *,
void *),
void (*DataFree)(
void *),
304 uint32_t (*DataHash)(uint32_t,
void *),
bool (*DataCompare)(
void *,
void *),
305 bool (*DataExpired)(
void *,
SCTime_t), uint32_t (*DataSize)(
void *),
bool reset_memcap,
311 ctx->config.data_size = data_size;
312 ctx->config.DataSet = DataSet;
313 ctx->config.DataFree = DataFree;
314 ctx->config.DataHash = DataHash;
315 ctx->config.DataCompare = DataCompare;
316 ctx->config.DataExpired = DataExpired;
317 ctx->config.DataSize = DataSize;
324 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
329 ctx->config.memcap = memcap;
339 THashDataQueueInit(&
ctx->spare_q);
341 if (THashInitConfig(
ctx, cnf_prefix) < 0) {
353 SCLogDebug(
"memcap after load set to: %" PRIu64,
ctx->config.memcap);
363 while ((h = THashDataDequeue(&
ctx->spare_q))) {
365 THashDataFree(
ctx, h);
369 if (
ctx->array != NULL) {
370 for (uint32_t u = 0; u <
ctx->config.hash_size; u++) {
371 h =
ctx->array[u].head;
374 THashDataFree(
ctx, h);
384 THashDataQueueDestroy(&
ctx->spare_q);
396 if (
ctx->array == NULL)
400 for (u = 0; u <
ctx->config.hash_size; u++) {
401 THashHashRow *hb = &
ctx->array[u];
405 char output_string[1024] =
"";
406 int size = FormatterFunc(h->
data, output_string,
sizeof(output_string));
408 if (OutputterFunc(output_ctx, (
const uint8_t *)output_string, size) < 0) {
429 if (
ctx->config.DataExpired == NULL)
435 for (uint32_t i = 0; i <
ctx->config.hash_size; i++) {
436 THashHashRow *hb = &
ctx->array[i];
459 if (
ctx->config.DataSize) {
460 uint32_t data_size =
ctx->config.DataSize(h->
data);
489 if (
ctx->array == NULL)
492 for (u = 0; u <
ctx->config.hash_size; u++) {
493 THashHashRow *hb = &
ctx->array[u];
512 if (
ctx->config.DataSize) {
513 uint32_t data_size =
ctx->config.DataSize(h->
data);
531 static uint32_t THashGetKey(
const THashConfig *cnf,
void *data)
541 static inline int THashCompare(
const THashConfig *cnf,
void *a,
void *b)
559 uint32_t data_size = 0;
560 if (
ctx->config.DataSize) {
561 data_size =
ctx->config.DataSize(data);
565 h = THashDataDequeue(&
ctx->spare_q);
569 h = THashGetUsed(
ctx, data_size);
581 h = THashDataAlloc(
ctx, data_size);
600 SCLogError(
"Adding data will exceed memcap: %" PRIu64
", current memuse: %" PRIu64,
624 uint32_t key = THashGetKey(&
ctx->config,
data);
626 THashHashRow *hb = &
ctx->array[key];
630 if (hb->head == NULL) {
631 h = THashDataGetNew(
ctx,
data);
654 if (THashCompare(&
ctx->config, h->
data,
data) == 0) {
682 if (THashCompare(&
ctx->config, h->
data,
data) != 0) {
733 uint32_t key = THashGetKey(&
ctx->config,
data);
735 THashHashRow *hb = &
ctx->array[key];
738 if (hb->head == NULL) {
747 if (THashCompare(&
ctx->config, h->
data,
data) == 0) {
755 if (THashCompare(&
ctx->config, h->
data,
data) != 0) {
805 uint32_t
cnt =
ctx->config.hash_size;
808 if (++idx >=
ctx->config.hash_size)
811 THashHashRow *hb = &
ctx->array[idx];
847 if (h->
data != NULL) {
848 if (
ctx->config.DataSize) {
849 uint32_t h_data_size =
ctx->config.DataSize(h->
data);
850 if (h_data_size > 0) {
874 uint32_t key = THashGetKey(&
ctx->config,
data);
876 THashHashRow *hb = &
ctx->array[key];
882 if (THashCompare(&
ctx->config, h->
data,
data) == 0) {
908 THashDataFree(
ctx, h);
#define HRLOCK_DESTROY(fb)
void THashCleanup(THashTableContext *ctx)
Cleanup the thash engine.
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
#define HQLOCK_DESTROY(q)
int(* THashOutputFunc)(void *output_ctx, const uint8_t *data, const uint32_t data_len)
int ParseSizeStringU64(const char *size, uint64_t *res)
struct HtpBodyChunk_ * next
int THashRemoveFromHash(THashTableContext *ctx, void *data)
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
void THashConsolidateMemcap(THashTableContext *ctx)
bool(* DataCompare)(void *, void *)
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
#define HRLOCK_UNLOCK(fb)
#define THASH_DEFAULT_HASHSIZE
#define SCMutexUnlock(mut)
#define THASH_DATA_SIZE(ctx)
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
#define GET_VAR(prefix, name)
void THashDataMoveToSpare(THashTableContext *ctx, THashData *h)
#define SCMutexInit(mut, mutattrs)
#define WarnInvalidConfEntry(param_name, format, value)
Generic API that can be used by all to log an invalid conf entry.
void THashShutdown(THashTableContext *ctx)
shutdown the flow engine
#define THASH_DEFAULT_MEMCAP
#define SCMallocAligned(size, align)
struct THashDataGetResult THashGetFromHash(THashTableContext *ctx, void *data)
THashData * THashLookupFromHash(THashTableContext *ctx, void *data)
look up data in the hash
#define THASH_DEFAULT_PREALLOC
#define SCLogError(...)
Macro used to log ERROR messages.
int THashWalk(THashTableContext *ctx, THashFormatFunc FormatterFunc, THashOutputFunc OutputterFunc, void *output_ctx)
Walk the hash.
int(* THashFormatFunc)(const void *in_data, char *output, size_t output_size)
uint32_t(* DataHash)(uint32_t, void *)
#define HRLOCK_TRYLOCK(fb)
uint32_t THashExpire(THashTableContext *ctx, const SCTime_t ts)
expire data from the hash Walk the hash table and remove data that is exprired according to the DataE...
THashTableContext * THashInit(const char *cnf_prefix, size_t data_size, int(*DataSet)(void *, void *), void(*DataFree)(void *), uint32_t(*DataHash)(uint32_t, void *), bool(*DataCompare)(void *, void *), bool(*DataExpired)(void *, SCTime_t), uint32_t(*DataSize)(void *), bool reset_memcap, uint64_t memcap, uint32_t hashsize)
#define THashIncrUsecnt(h)
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define THASH_CHECK_MEMCAP(ctx, size)
check if a memory alloc would fit in the memcap
#define DEBUG_VALIDATE_BUG_ON(exp)
THashDataQueue * THashDataQueueNew(void)
#define SCMutexTrylock(mut)