/src/suricata7/src/util-thash.h
Line | Count | Source |
1 | | /* Copyright (C) 2007-2016 Open Information Security Foundation |
2 | | * |
3 | | * You can copy, redistribute or modify this Program under the terms of |
4 | | * the GNU General Public License version 2 as published by the Free |
5 | | * Software Foundation. |
6 | | * |
7 | | * This program is distributed in the hope that it will be useful, |
8 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | | * GNU General Public License for more details. |
11 | | * |
12 | | * You should have received a copy of the GNU General Public License |
13 | | * version 2 along with this program; if not, write to the Free Software |
14 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
15 | | * 02110-1301, USA. |
16 | | */ |
17 | | |
18 | | /** |
19 | | * \file |
20 | | * |
21 | | * \author Victor Julien <victor@inliniac.net> |
22 | | * |
23 | | * thash -> thread hash. Hash table with locking handling. |
24 | | */ |
25 | | |
26 | | #ifndef __THASH_H__ |
27 | | #define __THASH_H__ |
28 | | |
29 | | #include "threads.h" |
30 | | |
31 | | /** Spinlocks or Mutex for the buckets. */ |
32 | | //#define HRLOCK_SPIN |
33 | | #define HRLOCK_MUTEX |
34 | | |
35 | | #ifdef HRLOCK_SPIN |
36 | | #ifdef HRLOCK_MUTEX |
37 | | #error Cannot enable both HRLOCK_SPIN and HRLOCK_MUTEX |
38 | | #endif |
39 | | #endif |
40 | | |
41 | | #ifdef HRLOCK_SPIN |
42 | | #define HRLOCK_TYPE SCSpinlock |
43 | | #define HRLOCK_INIT(fb) SCSpinInit(&(fb)->lock, 0) |
44 | | #define HRLOCK_DESTROY(fb) SCSpinDestroy(&(fb)->lock) |
45 | | #define HRLOCK_LOCK(fb) SCSpinLock(&(fb)->lock) |
46 | | #define HRLOCK_TRYLOCK(fb) SCSpinTrylock(&(fb)->lock) |
47 | | #define HRLOCK_UNLOCK(fb) SCSpinUnlock(&(fb)->lock) |
48 | | #elif defined HRLOCK_MUTEX |
49 | | #define HRLOCK_TYPE SCMutex |
50 | 37.4M | #define HRLOCK_INIT(fb) SCMutexInit(&(fb)->lock, NULL) |
51 | 8.78M | #define HRLOCK_DESTROY(fb) SCMutexDestroy(&(fb)->lock) |
52 | 92.8k | #define HRLOCK_LOCK(fb) SCMutexLock(&(fb)->lock) |
53 | 0 | #define HRLOCK_TRYLOCK(fb) SCMutexTrylock(&(fb)->lock) |
54 | 92.8k | #define HRLOCK_UNLOCK(fb) SCMutexUnlock(&(fb)->lock) |
55 | | #else |
56 | | #error Enable HRLOCK_SPIN or HRLOCK_MUTEX |
57 | | #endif |
58 | | |
59 | | /** Spinlocks or Mutex for the queues. */ |
60 | | //#define HQLOCK_SPIN |
61 | | #define HQLOCK_MUTEX |
62 | | |
63 | | #ifdef HQLOCK_SPIN |
64 | | #ifdef HQLOCK_MUTEX |
65 | | #error Cannot enable both HQLOCK_SPIN and HQLOCK_MUTEX |
66 | | #endif |
67 | | #endif |
68 | | |
69 | | #ifdef HQLOCK_SPIN |
70 | | #define HQLOCK_INIT(q) SCSpinInit(&(q)->s, 0) |
71 | | #define HQLOCK_DESTROY(q) SCSpinDestroy(&(q)->s) |
72 | | #define HQLOCK_LOCK(q) SCSpinLock(&(q)->s) |
73 | | #define HQLOCK_TRYLOCK(q) SCSpinTrylock(&(q)->s) |
74 | | #define HQLOCK_UNLOCK(q) SCSpinUnlock(&(q)->s) |
75 | | #elif defined HQLOCK_MUTEX |
76 | 11.5k | #define HQLOCK_INIT(q) SCMutexInit(&(q)->m, NULL) |
77 | 10.2k | #define HQLOCK_DESTROY(q) SCMutexDestroy(&(q)->m) |
78 | 20.7M | #define HQLOCK_LOCK(q) SCMutexLock(&(q)->m) |
79 | | #define HQLOCK_TRYLOCK(q) SCMutexTrylock(&(q)->m) |
80 | 20.7M | #define HQLOCK_UNLOCK(q) SCMutexUnlock(&(q)->m) |
81 | | #else |
82 | | #error Enable HQLOCK_SPIN or HQLOCK_MUTEX |
83 | | #endif |
84 | | |
85 | | typedef struct THashData_ { |
86 | | /** ippair mutex */ |
87 | | SCMutex m; |
88 | | |
89 | | /** use cnt, reference counter */ |
90 | | SC_ATOMIC_DECLARE(unsigned int, use_cnt); |
91 | | |
92 | | void *data; |
93 | | |
94 | | struct THashData_ *next; |
95 | | struct THashData_ *prev; |
96 | | } THashData; |
97 | | |
98 | | typedef struct THashHashRow_ { |
99 | | HRLOCK_TYPE lock; |
100 | | THashData *head; |
101 | | THashData *tail; |
102 | | } __attribute__((aligned(CLS))) THashHashRow; |
103 | | |
104 | | typedef struct THashDataQueue_ |
105 | | { |
106 | | THashData *top; |
107 | | THashData *bot; |
108 | | uint32_t len; |
109 | | #ifdef DBG_PERF |
110 | | uint32_t dbg_maxlen; |
111 | | #endif /* DBG_PERF */ |
112 | | #ifdef HQLOCK_MUTEX |
113 | | SCMutex m; |
114 | | #elif defined HQLOCK_SPIN |
115 | | SCSpinlock s; |
116 | | #else |
117 | | #error Enable HQLOCK_SPIN or HQLOCK_MUTEX |
118 | | #endif |
119 | | } THashDataQueue; |
120 | | |
121 | | typedef int (*THashOutputFunc)(void *output_ctx, const uint8_t *data, const uint32_t data_len); |
122 | | typedef int (*THashFormatFunc)(const void *in_data, char *output, size_t output_size); |
123 | | |
124 | | typedef struct THashDataConfig_ { |
125 | | uint64_t memcap; |
126 | | uint32_t hash_rand; |
127 | | uint32_t hash_size; |
128 | | uint32_t prealloc; |
129 | | |
130 | | uint32_t data_size; |
131 | | int (*DataSet)(void *dst, void *src); |
132 | | void (*DataFree)(void *); |
133 | | uint32_t (*DataHash)(uint32_t, void *); |
134 | | bool (*DataCompare)(void *, void *); |
135 | | } THashConfig; |
136 | | |
137 | 11.0M | #define THASH_DATA_SIZE(ctx) (sizeof(THashData) + (ctx)->config.data_size) |
138 | | |
139 | | typedef struct THashTableContext_ { |
140 | | /* array of rows indexed by the hash value % hash size */ |
141 | | THashHashRow *array; |
142 | | |
143 | | SC_ATOMIC_DECLARE(uint64_t, memuse); |
144 | | SC_ATOMIC_DECLARE(uint32_t, counter); |
145 | | SC_ATOMIC_DECLARE(uint32_t, prune_idx); |
146 | | |
147 | | THashDataQueue spare_q; |
148 | | |
149 | | THashConfig config; |
150 | | |
151 | | /* flag set if memcap was reached at least once. */ |
152 | | SC_ATOMIC_DECLARE(bool, memcap_reached); |
153 | | } THashTableContext; |
154 | | |
155 | | /** \brief check if a memory alloc would fit in the memcap |
156 | | * |
157 | | * \param size memory allocation size to check |
158 | | * |
159 | | * \retval 1 it fits |
160 | | * \retval 0 no fit |
161 | | */ |
162 | | #define THASH_CHECK_MEMCAP(ctx, size) \ |
163 | 22.1M | ((((uint64_t)SC_ATOMIC_GET((ctx)->memuse) + (uint64_t)(size)) <= (ctx)->config.memcap)) |
164 | | |
165 | | #define THashIncrUsecnt(h) \ |
166 | 92.4k | (void)SC_ATOMIC_ADD((h)->use_cnt, 1) |
167 | | #define THashDecrUsecnt(h) \ |
168 | 68.5k | (void)SC_ATOMIC_SUB((h)->use_cnt, 1) |
169 | | |
170 | | THashTableContext *THashInit(const char *cnf_prefix, size_t data_size, |
171 | | int (*DataSet)(void *dst, void *src), void (*DataFree)(void *), |
172 | | uint32_t (*DataHash)(uint32_t, void *), bool (*DataCompare)(void *, void *), |
173 | | bool reset_memcap, uint64_t memcap, uint32_t hashsize); |
174 | | |
175 | | void THashShutdown(THashTableContext *ctx); |
176 | | |
177 | | static inline void THashDataLock(THashData *d) |
178 | 33.1k | { |
179 | 33.1k | SCMutexLock(&d->m); |
180 | 33.1k | } Unexecuted instantiation: flow-manager.c:THashDataLock Unexecuted instantiation: runmode-unix-socket.c:THashDataLock Unexecuted instantiation: suricata.c:THashDataLock Unexecuted instantiation: util-thash.c:THashDataLock Unexecuted instantiation: app-layer-htp.c:THashDataLock app-layer-htp-file.c:THashDataLock Line | Count | Source | 178 | 7.60k | { | 179 | 7.60k | SCMutexLock(&d->m); | 180 | 7.60k | } |
app-layer-htp-range.c:THashDataLock Line | Count | Source | 178 | 25.5k | { | 179 | 25.5k | SCMutexLock(&d->m); | 180 | 25.5k | } |
Unexecuted instantiation: datasets.c:THashDataLock Unexecuted instantiation: datasets-ipv4.c:THashDataLock Unexecuted instantiation: datasets-ipv6.c:THashDataLock Unexecuted instantiation: datasets-md5.c:THashDataLock Unexecuted instantiation: datasets-sha256.c:THashDataLock Unexecuted instantiation: datasets-string.c:THashDataLock Unexecuted instantiation: detect-engine.c:THashDataLock Unexecuted instantiation: detect-engine-content-inspection.c:THashDataLock Unexecuted instantiation: detect-engine-register.c:THashDataLock Unexecuted instantiation: rust-context.c:THashDataLock Unexecuted instantiation: detect-datarep.c:THashDataLock Unexecuted instantiation: detect-dataset.c:THashDataLock |
181 | | |
182 | | static inline void THashDataUnlock(THashData *d) |
183 | 118k | { |
184 | 118k | SCMutexUnlock(&d->m); |
185 | 118k | } Unexecuted instantiation: flow-manager.c:THashDataUnlock Unexecuted instantiation: runmode-unix-socket.c:THashDataUnlock Unexecuted instantiation: suricata.c:THashDataUnlock Unexecuted instantiation: util-thash.c:THashDataUnlock Unexecuted instantiation: app-layer-htp.c:THashDataUnlock app-layer-htp-file.c:THashDataUnlock Line | Count | Source | 183 | 7.60k | { | 184 | 7.60k | SCMutexUnlock(&d->m); | 185 | 7.60k | } |
app-layer-htp-range.c:THashDataUnlock Line | Count | Source | 183 | 79.5k | { | 184 | 79.5k | SCMutexUnlock(&d->m); | 185 | 79.5k | } |
datasets.c:THashDataUnlock Line | Count | Source | 183 | 31.7k | { | 184 | 31.7k | SCMutexUnlock(&d->m); | 185 | 31.7k | } |
Unexecuted instantiation: datasets-ipv4.c:THashDataUnlock Unexecuted instantiation: datasets-ipv6.c:THashDataUnlock Unexecuted instantiation: datasets-md5.c:THashDataUnlock Unexecuted instantiation: datasets-sha256.c:THashDataUnlock Unexecuted instantiation: datasets-string.c:THashDataUnlock Unexecuted instantiation: detect-engine.c:THashDataUnlock Unexecuted instantiation: detect-engine-content-inspection.c:THashDataUnlock Unexecuted instantiation: detect-engine-register.c:THashDataUnlock Unexecuted instantiation: rust-context.c:THashDataUnlock Unexecuted instantiation: detect-datarep.c:THashDataUnlock Unexecuted instantiation: detect-dataset.c:THashDataUnlock |
186 | | |
187 | | struct THashDataGetResult { |
188 | | THashData *data; |
189 | | bool is_new; |
190 | | }; |
191 | | |
192 | | struct THashDataGetResult THashGetFromHash (THashTableContext *ctx, void *data); |
193 | | THashData *THashLookupFromHash (THashTableContext *ctx, void *data); |
194 | | THashDataQueue *THashDataQueueNew(void); |
195 | | void THashCleanup(THashTableContext *ctx); |
196 | | int THashWalk(THashTableContext *, THashFormatFunc, THashOutputFunc, void *); |
197 | | int THashRemoveFromHash (THashTableContext *ctx, void *data); |
198 | | void THashConsolidateMemcap(THashTableContext *ctx); |
199 | | void THashDataMoveToSpare(THashTableContext *ctx, THashData *h); |
200 | | |
201 | | #endif /* __THASH_H__ */ |