/src/suricata7/src/flow-storage.c
Line | Count | Source |
1 | | /* Copyright (C) 2013 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 Eric Leblond <eric@regit.org> |
22 | | * |
23 | | * based on host-storage by Victor Julien <victor@inliniac.net> |
24 | | * |
25 | | * Flow wrapper around storage api |
26 | | */ |
27 | | |
28 | | #include "suricata-common.h" |
29 | | #include "flow-storage.h" |
30 | | #include "flow-hash.h" |
31 | | #include "flow-util.h" |
32 | | #include "util-storage.h" |
33 | | #include "util-unittest.h" |
34 | | |
35 | | unsigned int FlowStorageSize(void) |
36 | 3.13M | { |
37 | 3.13M | return StorageGetSize(STORAGE_FLOW); |
38 | 3.13M | } |
39 | | |
40 | | void *FlowGetStorageById(const Flow *f, FlowStorageId id) |
41 | 1.20M | { |
42 | 1.20M | return StorageGetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id); |
43 | 1.20M | } |
44 | | |
45 | | int FlowSetStorageById(Flow *f, FlowStorageId id, void *ptr) |
46 | 2.39k | { |
47 | 2.39k | return StorageSetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id, ptr); |
48 | 2.39k | } |
49 | | |
50 | | void *FlowAllocStorageById(Flow *f, FlowStorageId id) |
51 | 0 | { |
52 | 0 | return StorageAllocByIdPrealloc((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id); |
53 | 0 | } |
54 | | |
55 | | void FlowFreeStorageById(Flow *f, FlowStorageId id) |
56 | 289 | { |
57 | 289 | StorageFreeById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id); |
58 | 289 | } |
59 | | |
60 | | void FlowFreeStorage(Flow *f) |
61 | 580k | { |
62 | 580k | if (FlowStorageSize() > 0) |
63 | 580k | StorageFreeAll((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW); |
64 | 580k | } |
65 | | |
66 | | FlowStorageId FlowStorageRegister(const char *name, const unsigned int size, |
67 | | void *(*Alloc)(unsigned int), void (*Free)(void *)) |
68 | 216 | { |
69 | 216 | int id = StorageRegister(STORAGE_FLOW, name, size, Alloc, Free); |
70 | 216 | FlowStorageId fsi = { .id = id }; |
71 | 216 | return fsi; |
72 | 216 | } |
73 | | |
74 | | #ifdef UNITTESTS |
75 | | |
76 | | static void *StorageTestAlloc(unsigned int size) |
77 | | { |
78 | | void *x = SCMalloc(size); |
79 | | return x; |
80 | | } |
81 | | static void StorageTestFree(void *x) |
82 | | { |
83 | | if (x) |
84 | | SCFree(x); |
85 | | } |
86 | | |
87 | | static int FlowStorageTest01(void) |
88 | | { |
89 | | Flow *f = NULL; |
90 | | |
91 | | StorageInit(); |
92 | | |
93 | | FlowStorageId id1 = FlowStorageRegister("test", 8, StorageTestAlloc, StorageTestFree); |
94 | | if (id1.id < 0) |
95 | | goto error; |
96 | | FlowStorageId id2 = FlowStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree); |
97 | | if (id2.id < 0) |
98 | | goto error; |
99 | | FlowStorageId id3 = |
100 | | FlowStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree); |
101 | | if (id3.id < 0) |
102 | | goto error; |
103 | | |
104 | | if (StorageFinalize() < 0) |
105 | | goto error; |
106 | | |
107 | | FlowInitConfig(FLOW_QUIET); |
108 | | |
109 | | f = FlowAlloc(); |
110 | | if (f == NULL) { |
111 | | goto error; |
112 | | } |
113 | | |
114 | | void *ptr = FlowGetStorageById(f, id1); |
115 | | if (ptr != NULL) { |
116 | | goto error; |
117 | | } |
118 | | ptr = FlowGetStorageById(f, id2); |
119 | | if (ptr != NULL) { |
120 | | goto error; |
121 | | } |
122 | | ptr = FlowGetStorageById(f, id3); |
123 | | if (ptr != NULL) { |
124 | | goto error; |
125 | | } |
126 | | |
127 | | void *ptr1a = FlowAllocStorageById(f, id1); |
128 | | if (ptr1a == NULL) { |
129 | | goto error; |
130 | | } |
131 | | void *ptr2a = FlowAllocStorageById(f, id2); |
132 | | if (ptr2a == NULL) { |
133 | | goto error; |
134 | | } |
135 | | void *ptr3a = FlowAllocStorageById(f, id3); |
136 | | if (ptr3a == NULL) { |
137 | | goto error; |
138 | | } |
139 | | |
140 | | void *ptr1b = FlowGetStorageById(f, id1); |
141 | | if (ptr1a != ptr1b) { |
142 | | goto error; |
143 | | } |
144 | | void *ptr2b = FlowGetStorageById(f, id2); |
145 | | if (ptr2a != ptr2b) { |
146 | | goto error; |
147 | | } |
148 | | void *ptr3b = FlowGetStorageById(f, id3); |
149 | | if (ptr3a != ptr3b) { |
150 | | goto error; |
151 | | } |
152 | | |
153 | | FlowClearMemory(f, 0); |
154 | | FlowFree(f); |
155 | | FlowShutdown(); |
156 | | StorageCleanup(); |
157 | | return 1; |
158 | | error: |
159 | | if (f != NULL) { |
160 | | FlowClearMemory(f, 0); |
161 | | FlowFree(f); |
162 | | } |
163 | | FlowShutdown(); |
164 | | StorageCleanup(); |
165 | | return 0; |
166 | | } |
167 | | |
168 | | static int FlowStorageTest02(void) |
169 | | { |
170 | | Flow *f = NULL; |
171 | | |
172 | | StorageInit(); |
173 | | |
174 | | FlowStorageId id1 = FlowStorageRegister("test", sizeof(void *), NULL, StorageTestFree); |
175 | | if (id1.id < 0) |
176 | | goto error; |
177 | | |
178 | | if (StorageFinalize() < 0) |
179 | | goto error; |
180 | | |
181 | | FlowInitConfig(FLOW_QUIET); |
182 | | f = FlowAlloc(); |
183 | | if (f == NULL) { |
184 | | goto error; |
185 | | } |
186 | | |
187 | | void *ptr = FlowGetStorageById(f, id1); |
188 | | if (ptr != NULL) { |
189 | | goto error; |
190 | | } |
191 | | |
192 | | void *ptr1a = SCMalloc(128); |
193 | | if (unlikely(ptr1a == NULL)) { |
194 | | goto error; |
195 | | } |
196 | | FlowSetStorageById(f, id1, ptr1a); |
197 | | |
198 | | void *ptr1b = FlowGetStorageById(f, id1); |
199 | | if (ptr1a != ptr1b) { |
200 | | goto error; |
201 | | } |
202 | | |
203 | | |
204 | | FlowClearMemory(f, 0); |
205 | | FlowFree(f); |
206 | | FlowShutdown(); |
207 | | StorageCleanup(); |
208 | | return 1; |
209 | | error: |
210 | | if (f != NULL) { |
211 | | FlowClearMemory(f, 0); |
212 | | FlowFree(f); |
213 | | } |
214 | | FlowShutdown(); |
215 | | StorageCleanup(); |
216 | | return 0; |
217 | | } |
218 | | |
219 | | static int FlowStorageTest03(void) |
220 | | { |
221 | | Flow *f = NULL; |
222 | | |
223 | | StorageInit(); |
224 | | |
225 | | FlowStorageId id1 = FlowStorageRegister("test1", sizeof(void *), NULL, StorageTestFree); |
226 | | if (id1.id < 0) |
227 | | goto error; |
228 | | FlowStorageId id2 = FlowStorageRegister("test2", sizeof(void *), NULL, StorageTestFree); |
229 | | if (id2.id < 0) |
230 | | goto error; |
231 | | FlowStorageId id3 = FlowStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree); |
232 | | if (id3.id < 0) |
233 | | goto error; |
234 | | |
235 | | if (StorageFinalize() < 0) |
236 | | goto error; |
237 | | |
238 | | FlowInitConfig(FLOW_QUIET); |
239 | | f = FlowAlloc(); |
240 | | if (f == NULL) { |
241 | | goto error; |
242 | | } |
243 | | |
244 | | void *ptr = FlowGetStorageById(f, id1); |
245 | | if (ptr != NULL) { |
246 | | goto error; |
247 | | } |
248 | | |
249 | | void *ptr1a = SCMalloc(128); |
250 | | if (unlikely(ptr1a == NULL)) { |
251 | | goto error; |
252 | | } |
253 | | FlowSetStorageById(f, id1, ptr1a); |
254 | | |
255 | | void *ptr2a = SCMalloc(256); |
256 | | if (unlikely(ptr2a == NULL)) { |
257 | | goto error; |
258 | | } |
259 | | FlowSetStorageById(f, id2, ptr2a); |
260 | | |
261 | | void *ptr3a = FlowAllocStorageById(f, id3); |
262 | | if (ptr3a == NULL) { |
263 | | goto error; |
264 | | } |
265 | | |
266 | | void *ptr1b = FlowGetStorageById(f, id1); |
267 | | if (ptr1a != ptr1b) { |
268 | | goto error; |
269 | | } |
270 | | void *ptr2b = FlowGetStorageById(f, id2); |
271 | | if (ptr2a != ptr2b) { |
272 | | goto error; |
273 | | } |
274 | | void *ptr3b = FlowGetStorageById(f, id3); |
275 | | if (ptr3a != ptr3b) { |
276 | | goto error; |
277 | | } |
278 | | |
279 | | FlowClearMemory(f, 0); |
280 | | FlowFree(f); |
281 | | FlowShutdown(); |
282 | | StorageCleanup(); |
283 | | return 1; |
284 | | error: |
285 | | if (f != NULL) { |
286 | | FlowClearMemory(f, 0); |
287 | | FlowFree(f); |
288 | | } |
289 | | FlowShutdown(); |
290 | | StorageCleanup(); |
291 | | return 0; |
292 | | } |
293 | | #endif |
294 | | |
295 | | void RegisterFlowStorageTests(void) |
296 | 0 | { |
297 | | #ifdef UNITTESTS |
298 | | UtRegisterTest("FlowStorageTest01", FlowStorageTest01); |
299 | | UtRegisterTest("FlowStorageTest02", FlowStorageTest02); |
300 | | UtRegisterTest("FlowStorageTest03", FlowStorageTest03); |
301 | | #endif |
302 | 0 | } |