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-unittest.h"
33 
34 unsigned int FlowStorageSize(void)
35 {
37 }
38 
39 void *FlowGetStorageById(Flow *f, int id)
40 {
41  return StorageGetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id);
42 }
43 
44 int FlowSetStorageById(Flow *f, int id, void *ptr)
45 {
46  return StorageSetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id, ptr);
47 }
48 
49 void *FlowAllocStorageById(Flow *f, int id)
50 {
51  return StorageAllocByIdPrealloc((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id);
52 }
53 
54 void FlowFreeStorageById(Flow *f, int id)
55 {
56  StorageFreeById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id);
57 }
58 
60 {
61  if (FlowStorageSize() > 0)
62  StorageFreeAll((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW);
63 }
64 
65 int FlowStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)) {
66  return StorageRegister(STORAGE_FLOW, name, size, Alloc, Free);
67 }
68 
69 #ifdef UNITTESTS
70 
71 static void *StorageTestAlloc(unsigned int size)
72 {
73  void *x = SCMalloc(size);
74  return x;
75 }
76 static void StorageTestFree(void *x)
77 {
78  if (x)
79  SCFree(x);
80 }
81 
82 static int FlowStorageTest01(void)
83 {
84  Flow *f = NULL;
85 
86  StorageInit();
87 
88  int id1 = FlowStorageRegister("test", 8, StorageTestAlloc, StorageTestFree);
89  if (id1 < 0)
90  goto error;
91  int id2 = FlowStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree);
92  if (id2 < 0)
93  goto error;
94  int id3 = FlowStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree);
95  if (id3 < 0)
96  goto error;
97 
98  if (StorageFinalize() < 0)
99  goto error;
100 
102 
103  f = FlowAlloc();
104  if (f == NULL) {
105  goto error;
106  }
107 
108  void *ptr = FlowGetStorageById(f, id1);
109  if (ptr != NULL) {
110  goto error;
111  }
112  ptr = FlowGetStorageById(f, id2);
113  if (ptr != NULL) {
114  goto error;
115  }
116  ptr = FlowGetStorageById(f, id3);
117  if (ptr != NULL) {
118  goto error;
119  }
120 
121  void *ptr1a = FlowAllocStorageById(f, id1);
122  if (ptr1a == NULL) {
123  goto error;
124  }
125  void *ptr2a = FlowAllocStorageById(f, id2);
126  if (ptr2a == NULL) {
127  goto error;
128  }
129  void *ptr3a = FlowAllocStorageById(f, id3);
130  if (ptr3a == NULL) {
131  goto error;
132  }
133 
134  void *ptr1b = FlowGetStorageById(f, id1);
135  if (ptr1a != ptr1b) {
136  goto error;
137  }
138  void *ptr2b = FlowGetStorageById(f, id2);
139  if (ptr2a != ptr2b) {
140  goto error;
141  }
142  void *ptr3b = FlowGetStorageById(f, id3);
143  if (ptr3a != ptr3b) {
144  goto error;
145  }
146 
147  FlowClearMemory(f, 0);
148  FlowFree(f);
149  FlowShutdown();
150  StorageCleanup();
151  return 1;
152 error:
153  if (f != NULL) {
154  FlowClearMemory(f, 0);
155  FlowFree(f);
156  }
157  FlowShutdown();
158  StorageCleanup();
159  return 0;
160 }
161 
162 static int FlowStorageTest02(void)
163 {
164  Flow *f = NULL;
165 
166  StorageInit();
167 
168  int id1 = FlowStorageRegister("test", sizeof(void *), NULL, StorageTestFree);
169  if (id1 < 0)
170  goto error;
171 
172  if (StorageFinalize() < 0)
173  goto error;
174 
176  f = FlowAlloc();
177  if (f == NULL) {
178  goto error;
179  }
180 
181  void *ptr = FlowGetStorageById(f, id1);
182  if (ptr != NULL) {
183  goto error;
184  }
185 
186  void *ptr1a = SCMalloc(128);
187  if (unlikely(ptr1a == NULL)) {
188  goto error;
189  }
190  FlowSetStorageById(f, id1, ptr1a);
191 
192  void *ptr1b = FlowGetStorageById(f, id1);
193  if (ptr1a != ptr1b) {
194  goto error;
195  }
196 
197 
198  FlowClearMemory(f, 0);
199  FlowFree(f);
200  FlowShutdown();
201  StorageCleanup();
202  return 1;
203 error:
204  if (f != NULL) {
205  FlowClearMemory(f, 0);
206  FlowFree(f);
207  }
208  FlowShutdown();
209  StorageCleanup();
210  return 0;
211 }
212 
213 static int FlowStorageTest03(void)
214 {
215  Flow *f = NULL;
216 
217  StorageInit();
218 
219  int id1 = FlowStorageRegister("test1", sizeof(void *), NULL, StorageTestFree);
220  if (id1 < 0)
221  goto error;
222  int id2 = FlowStorageRegister("test2", sizeof(void *), NULL, StorageTestFree);
223  if (id2 < 0)
224  goto error;
225  int id3 = FlowStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree);
226  if (id3 < 0)
227  goto error;
228 
229  if (StorageFinalize() < 0)
230  goto error;
231 
233  f = FlowAlloc();
234  if (f == NULL) {
235  goto error;
236  }
237 
238  void *ptr = FlowGetStorageById(f, id1);
239  if (ptr != NULL) {
240  goto error;
241  }
242 
243  void *ptr1a = SCMalloc(128);
244  if (unlikely(ptr1a == NULL)) {
245  goto error;
246  }
247  FlowSetStorageById(f, id1, ptr1a);
248 
249  void *ptr2a = SCMalloc(256);
250  if (unlikely(ptr2a == NULL)) {
251  goto error;
252  }
253  FlowSetStorageById(f, id2, ptr2a);
254 
255  void *ptr3a = FlowAllocStorageById(f, id3);
256  if (ptr3a == NULL) {
257  goto error;
258  }
259 
260  void *ptr1b = FlowGetStorageById(f, id1);
261  if (ptr1a != ptr1b) {
262  goto error;
263  }
264  void *ptr2b = FlowGetStorageById(f, id2);
265  if (ptr2a != ptr2b) {
266  goto error;
267  }
268  void *ptr3b = FlowGetStorageById(f, id3);
269  if (ptr3a != ptr3b) {
270  goto error;
271  }
272 
273  FlowClearMemory(f, 0);
274  FlowFree(f);
275  FlowShutdown();
276  StorageCleanup();
277  return 1;
278 error:
279  if (f != NULL) {
280  FlowClearMemory(f, 0);
281  FlowFree(f);
282  }
283  FlowShutdown();
284  StorageCleanup();
285  return 0;
286 }
287 #endif
288 
290 {
291 #ifdef UNITTESTS
292  UtRegisterTest("FlowStorageTest01", FlowStorageTest01);
293  UtRegisterTest("FlowStorageTest02", FlowStorageTest02);
294  UtRegisterTest("FlowStorageTest03", FlowStorageTest03);
295 #endif
296 }
int StorageFinalize(void)
Definition: util-storage.c:139
#define unlikely(expr)
Definition: util-optimize.h:35
void FlowFree(Flow *f)
cleanup & free the memory of a flow
Definition: flow-util.c:80
int StorageSetById(Storage *storage, const StorageEnum type, const int id, void *ptr)
set storage for id
Definition: util-storage.c:227
#define FLOW_QUIET
Definition: flow.h:38
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:99
void RegisterFlowStorageTests(void)
Definition: flow-storage.c:289
void * StorageAllocByIdPrealloc(Storage *storage, StorageEnum type, int id)
AllocById func for prealloc&#39;d base storage (storage ptrs are part of another memory block) ...
Definition: util-storage.c:239
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
int FlowSetStorageById(Flow *f, int id, void *ptr)
Definition: flow-storage.c:44
Flow * FlowAlloc(void)
allocate a flow
Definition: flow-util.c:51
void * FlowAllocStorageById(Flow *f, int id)
Definition: flow-storage.c:49
void * Storage
Definition: util-storage.h:39
#define SCMalloc(a)
Definition: util-mem.h:222
void StorageFreeAll(Storage *storage, StorageEnum type)
Definition: util-storage.c:310
int FlowStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Definition: flow-storage.c:65
#define SCFree(a)
Definition: util-mem.h:322
unsigned int StorageGetSize(StorageEnum type)
get the size of the void array used to store the pointers
Definition: util-storage.c:211
void StorageInit(void)
Definition: util-storage.c:67
unsigned int FlowStorageSize(void)
Definition: flow-storage.c:34
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:670
void StorageCleanup(void)
Definition: util-storage.c:75
void * StorageGetById(const Storage *storage, const StorageEnum type, const int id)
get storage for id
Definition: util-storage.c:216
void FlowFreeStorage(Flow *f)
Definition: flow-storage.c:59
void * FlowGetStorageById(Flow *f, int id)
Definition: flow-storage.c:39
int FlowClearMemory(Flow *f, uint8_t proto_map)
Function clear the flow memory before queueing it to spare flow queue.
Definition: flow.c:1030
void FlowFreeStorageById(Flow *f, int id)
Definition: flow-storage.c:54
void StorageFreeById(Storage *storage, StorageEnum type, int id)
Definition: util-storage.c:288
Flow data structure.
Definition: flow.h:325
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:515