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 
35 unsigned int FlowStorageSize(void)
36 {
38 }
39 
41 {
42  return StorageGetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id);
43 }
44 
45 int FlowSetStorageById(Flow *f, FlowStorageId id, void *ptr)
46 {
47  return StorageSetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id, ptr);
48 }
49 
51 {
52  return StorageAllocByIdPrealloc((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id);
53 }
54 
56 {
57  StorageFreeById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id);
58 }
59 
61 {
62  if (FlowStorageSize() > 0)
63  StorageFreeAll((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW);
64 }
65 
66 FlowStorageId 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 
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 
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 
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 
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 
296 {
297 #ifdef UNITTESTS
298  UtRegisterTest("FlowStorageTest01", FlowStorageTest01);
299  UtRegisterTest("FlowStorageTest02", FlowStorageTest02);
300  UtRegisterTest("FlowStorageTest03", FlowStorageTest03);
301 #endif
302 }
FlowStorageId
Definition: flow-storage.h:31
StorageFreeAll
void StorageFreeAll(Storage *storage, StorageEnum type)
Definition: util-storage.c:311
StorageInit
void StorageInit(void)
Definition: util-storage.c:68
flow-util.h
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
Flow_
Flow data structure.
Definition: flow.h:356
flow-hash.h
StorageCleanup
void StorageCleanup(void)
Definition: util-storage.c:76
FlowAllocStorageById
void * FlowAllocStorageById(Flow *f, FlowStorageId id)
Definition: flow-storage.c:50
util-unittest.h
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:543
STORAGE_FLOW
@ STORAGE_FLOW
Definition: util-storage.h:31
FlowStorageSize
unsigned int FlowStorageSize(void)
Definition: flow-storage.c:35
FlowSetStorageById
int FlowSetStorageById(Flow *f, FlowStorageId id, void *ptr)
Definition: flow-storage.c:45
FlowStorageRegister
FlowStorageId FlowStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Definition: flow-storage.c:66
StorageFinalize
int StorageFinalize(void)
Definition: util-storage.c:140
FlowClearMemory
int FlowClearMemory(Flow *f, uint8_t proto_map)
Function clear the flow memory before queueing it to spare flow queue.
Definition: flow.c:1106
FlowGetStorageById
void * FlowGetStorageById(const Flow *f, FlowStorageId id)
Definition: flow-storage.c:40
flow-storage.h
suricata-common.h
FlowFree
void FlowFree(Flow *f)
cleanup & free the memory of a flow
Definition: flow-util.c:81
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:690
StorageSetById
int StorageSetById(Storage *storage, const StorageEnum type, const int id, void *ptr)
set storage for id
Definition: util-storage.c:228
StorageAllocByIdPrealloc
void * StorageAllocByIdPrealloc(Storage *storage, StorageEnum type, int id)
AllocById func for prealloc'd base storage (storage ptrs are part of another memory block)
Definition: util-storage.c:240
StorageFreeById
void StorageFreeById(Storage *storage, StorageEnum type, int id)
Definition: util-storage.c:289
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
FlowFreeStorageById
void FlowFreeStorageById(Flow *f, FlowStorageId id)
Definition: flow-storage.c:55
SCFree
#define SCFree(p)
Definition: util-mem.h:61
FlowFreeStorage
void FlowFreeStorage(Flow *f)
Definition: flow-storage.c:60
Storage
void * Storage
Definition: util-storage.h:39
FlowStorageId::id
int id
Definition: flow-storage.h:32
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:40
FlowAlloc
Flow * FlowAlloc(void)
allocate a flow
Definition: flow-util.c:52
StorageGetById
void * StorageGetById(const Storage *storage, const StorageEnum type, const int id)
get storage for id
Definition: util-storage.c:217
RegisterFlowStorageTests
void RegisterFlowStorageTests(void)
Definition: flow-storage.c:295
StorageGetSize
unsigned int StorageGetSize(StorageEnum type)
get the size of the void array used to store the pointers
Definition: util-storage.c:212
util-storage.h
StorageRegister
int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Register new storage.
Definition: util-storage.c:100