suricata
flow-storage.c
Go to the documentation of this file.
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
35unsigned int FlowStorageSize(void)
36{
38}
39
41{
42 return StorageGetById(f->storage, STORAGE_FLOW, id.id);
43}
44
46{
47 return StorageSetById(f->storage, STORAGE_FLOW, id.id, ptr);
48}
49
54
59
65
66FlowStorageId FlowStorageRegister(const char *name, const unsigned int size,
67 void *(*Alloc)(unsigned int), void (*Free)(void *))
68{
69 int id = StorageRegister(STORAGE_FLOW, name, size, Alloc, Free);
70 FlowStorageId fsi = { .id = id };
71 return fsi;
72}
73
74#ifdef UNITTESTS
75
76static void *StorageTestAlloc(unsigned int size)
77{
78 void *x = SCMalloc(size);
79 return x;
80}
81static void StorageTestFree(void *x)
82{
83 if (x)
84 SCFree(x);
85}
86
87static int FlowStorageTest01(void)
88{
89 Flow *f = NULL;
90
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
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();
157 return 1;
158error:
159 if (f != NULL) {
160 FlowClearMemory(f, 0);
161 FlowFree(f);
162 }
163 FlowShutdown();
165 return 0;
166}
167
168static 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
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();
208 return 1;
209error:
210 if (f != NULL) {
211 FlowClearMemory(f, 0);
212 FlowFree(f);
213 }
214 FlowShutdown();
216 return 0;
217}
218
219static 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
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();
283 return 1;
284error:
285 if (f != NULL) {
286 FlowClearMemory(f, 0);
287 FlowFree(f);
288 }
289 FlowShutdown();
291 return 0;
292}
293#endif
294
296{
297#ifdef UNITTESTS
298 UtRegisterTest("FlowStorageTest01", FlowStorageTest01);
299 UtRegisterTest("FlowStorageTest02", FlowStorageTest02);
300 UtRegisterTest("FlowStorageTest03", FlowStorageTest03);
301#endif
302}
void * FlowGetStorageById(const Flow *f, FlowStorageId id)
void RegisterFlowStorageTests(void)
int FlowSetStorageById(Flow *f, FlowStorageId id, void *ptr)
void * FlowAllocStorageById(Flow *f, FlowStorageId id)
void FlowFreeStorageById(Flow *f, FlowStorageId id)
void FlowFreeStorage(Flow *f)
FlowStorageId FlowStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
unsigned int FlowStorageSize(void)
Flow * FlowAlloc(void)
allocate a flow
Definition flow-util.c:56
void FlowFree(Flow *f)
cleanup & free the memory of a flow
Definition flow-util.c:84
void FlowInitConfig(bool quiet)
initialize the configuration
Definition flow.c:547
int FlowClearMemory(Flow *f, uint8_t proto_map)
Function clear the flow memory before queueing it to spare flow queue.
Definition flow.c:1097
void FlowShutdown(void)
shutdown the flow engine
Definition flow.c:691
#define FLOW_QUIET
Definition flow.h:43
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Flow data structure.
Definition flow.h:356
Storage storage[]
Definition flow.h:500
const char * name
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)
void * StorageGetById(const Storage *storage, const StorageEnum type, const int id)
get storage for id
void StorageCleanup(void)
int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Register new storage.
unsigned int StorageGetSize(StorageEnum type)
get the size of the void array used to store the pointers
void StorageFreeAll(Storage *storage, StorageEnum type)
void StorageFreeById(Storage *storage, StorageEnum type, int id)
int StorageFinalize(void)
int StorageSetById(Storage *storage, const StorageEnum type, const int id, void *ptr)
set storage for id
void StorageInit(void)
void * StorageAllocByIdPrealloc(Storage *storage, StorageEnum type, int id)
AllocById func for prealloc'd base storage (storage ptrs are part of another memory block)
@ STORAGE_FLOW