suricata
host-storage.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2021 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 * Host wrapper around storage api
24 */
25
26#include "suricata-common.h"
27#include "host-storage.h"
28#include "util-unittest.h"
29
30unsigned int HostStorageSize(void)
31{
33}
34
35/** \defgroup hoststorage Host storage API
36 *
37 * The Host storage API is a per-host storage. It is a mean to extend
38 * the Host structure with arbitrary data.
39 *
40 * You have first to register the storage via HostStorageRegister() during
41 * the init of your module. Then you can attach data via HostSetStorageById()
42 * and access them via HostGetStorageById().
43 * @{
44 */
45
46/**
47 * \brief Register a Host storage
48 *
49 * \param name the name of the storage
50 * \param size integer coding the size of the stored value (sizeof(void *) is best choice here)
51 * \param Alloc allocation function for the storage (can be null)
52 * \param Free free function for the new storage
53 *
54 * \retval The ID of the newly register storage that will be used to access data
55 *
56 * It has to be called once during the init of the sub system
57 */
58
59HostStorageId HostStorageRegister(const char *name, const unsigned int size,
60 void *(*Alloc)(unsigned int), void (*Free)(void *))
61{
62 int id = StorageRegister(STORAGE_HOST, name, size, Alloc, Free);
63 HostStorageId hsi = { .id = id };
64 return hsi;
65}
66
67/**
68 * \brief Store a pointer in a given Host storage
69 *
70 * \param h a pointer to the Host
71 * \param id the id of the storage (return of HostStorageRegister() call)
72 * \param ptr pointer to the data to store
73 */
74
76{
77 return StorageSetById(h->storage, STORAGE_HOST, id.id, ptr);
78}
79
80/**
81 * \brief Get a value from a given Host storage
82 *
83 * \param h a pointer to the Host
84 * \param id the id of the storage (return of HostStorageRegister() call)
85 *
86 */
87
89{
90 return StorageGetById(h->storage, STORAGE_HOST, id.id);
91}
92
93/**
94 * @}
95 */
96
97/* Start of "private" function */
98
103
105{
106 if (HostStorageSize() > 0)
108}
109
110
111#ifdef UNITTESTS
112
113static void *StorageTestAlloc(unsigned int size)
114{
115 void *x = SCMalloc(size);
116 return x;
117}
118static void StorageTestFree(void *x)
119{
120 if (x)
121 SCFree(x);
122}
123
124static int HostStorageTest01(void)
125{
126 StorageInit();
127
128 HostStorageId id1 = HostStorageRegister("test", 8, StorageTestAlloc, StorageTestFree);
129 if (id1.id < 0)
130 goto error;
131 HostStorageId id2 = HostStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree);
132 if (id2.id < 0)
133 goto error;
134 HostStorageId id3 =
135 HostStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree);
136 if (id3.id < 0)
137 goto error;
138
139 if (StorageFinalize() < 0)
140 goto error;
141
143
144 Address a;
145 memset(&a, 0x00, sizeof(a));
146 a.addr_data32[0] = 0x01020304;
147 a.family = AF_INET;
148 Host *h = HostGetHostFromHash(&a);
149 if (h == NULL) {
150 printf("failed to get host: ");
151 goto error;
152 }
153
154 void *ptr = HostGetStorageById(h, id1);
155 if (ptr != NULL) {
156 goto error;
157 }
158 ptr = HostGetStorageById(h, id2);
159 if (ptr != NULL) {
160 goto error;
161 }
162 ptr = HostGetStorageById(h, id3);
163 if (ptr != NULL) {
164 goto error;
165 }
166
167 void *ptr1a = HostAllocStorageById(h, id1);
168 if (ptr1a == NULL) {
169 goto error;
170 }
171 void *ptr2a = HostAllocStorageById(h, id2);
172 if (ptr2a == NULL) {
173 goto error;
174 }
175 void *ptr3a = HostAllocStorageById(h, id3);
176 if (ptr3a == NULL) {
177 goto error;
178 }
179
180 void *ptr1b = HostGetStorageById(h, id1);
181 if (ptr1a != ptr1b) {
182 goto error;
183 }
184 void *ptr2b = HostGetStorageById(h, id2);
185 if (ptr2a != ptr2b) {
186 goto error;
187 }
188 void *ptr3b = HostGetStorageById(h, id3);
189 if (ptr3a != ptr3b) {
190 goto error;
191 }
192
193 HostRelease(h);
194
195 HostShutdown();
197 return 1;
198error:
199 HostShutdown();
201 return 0;
202}
203
204static int HostStorageTest02(void)
205{
206 StorageInit();
207
208 HostStorageId id1 = HostStorageRegister("test", sizeof(void *), NULL, StorageTestFree);
209 if (id1.id < 0)
210 goto error;
211
212 if (StorageFinalize() < 0)
213 goto error;
214
216
217 Address a;
218 memset(&a, 0x00, sizeof(a));
219 a.addr_data32[0] = 0x01020304;
220 a.family = AF_INET;
221 Host *h = HostGetHostFromHash(&a);
222 if (h == NULL) {
223 printf("failed to get host: ");
224 goto error;
225 }
226
227 void *ptr = HostGetStorageById(h, id1);
228 if (ptr != NULL) {
229 goto error;
230 }
231
232 void *ptr1a = SCMalloc(128);
233 if (unlikely(ptr1a == NULL)) {
234 goto error;
235 }
236 HostSetStorageById(h, id1, ptr1a);
237
238 void *ptr1b = HostGetStorageById(h, id1);
239 if (ptr1a != ptr1b) {
240 goto error;
241 }
242
243 HostRelease(h);
244
245 HostShutdown();
247 return 1;
248error:
249 HostShutdown();
251 return 0;
252}
253
254static int HostStorageTest03(void)
255{
256 StorageInit();
257
258 HostStorageId id1 = HostStorageRegister("test1", sizeof(void *), NULL, StorageTestFree);
259 if (id1.id < 0)
260 goto error;
261 HostStorageId id2 = HostStorageRegister("test2", sizeof(void *), NULL, StorageTestFree);
262 if (id2.id < 0)
263 goto error;
264 HostStorageId id3 = HostStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree);
265 if (id3.id < 0)
266 goto error;
267
268 if (StorageFinalize() < 0)
269 goto error;
270
272
273 Address a;
274 memset(&a, 0x00, sizeof(a));
275 a.addr_data32[0] = 0x01020304;
276 a.family = AF_INET;
277 Host *h = HostGetHostFromHash(&a);
278 if (h == NULL) {
279 printf("failed to get host: ");
280 goto error;
281 }
282
283 void *ptr = HostGetStorageById(h, id1);
284 if (ptr != NULL) {
285 goto error;
286 }
287
288 void *ptr1a = SCMalloc(128);
289 if (unlikely(ptr1a == NULL)) {
290 goto error;
291 }
292 HostSetStorageById(h, id1, ptr1a);
293
294 void *ptr2a = SCMalloc(256);
295 if (unlikely(ptr2a == NULL)) {
296 goto error;
297 }
298 HostSetStorageById(h, id2, ptr2a);
299
300 void *ptr3a = HostAllocStorageById(h, id3);
301 if (ptr3a == NULL) {
302 goto error;
303 }
304
305 void *ptr1b = HostGetStorageById(h, id1);
306 if (ptr1a != ptr1b) {
307 goto error;
308 }
309 void *ptr2b = HostGetStorageById(h, id2);
310 if (ptr2a != ptr2b) {
311 goto error;
312 }
313 void *ptr3b = HostGetStorageById(h, id3);
314 if (ptr3a != ptr3b) {
315 goto error;
316 }
317
318 HostRelease(h);
319
320 HostShutdown();
322 return 1;
323error:
324 HostShutdown();
326 return 0;
327}
328#endif
329
331{
332#ifdef UNITTESTS
333 UtRegisterTest("HostStorageTest01", HostStorageTest01);
334 UtRegisterTest("HostStorageTest02", HostStorageTest02);
335 UtRegisterTest("HostStorageTest03", HostStorageTest03);
336#endif
337}
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
HostStorageId HostStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Register a Host storage.
int HostSetStorageById(Host *h, HostStorageId id, void *ptr)
Store a pointer in a given Host storage.
void * HostGetStorageById(Host *h, HostStorageId id)
Get a value from a given Host storage.
void * HostAllocStorageById(Host *h, HostStorageId id)
void RegisterHostStorageTests(void)
unsigned int HostStorageSize(void)
void HostFreeStorage(Host *h)
void HostShutdown(void)
shutdown the flow engine
Definition host.c:296
void HostInitConfig(bool quiet)
initialize the configuration
Definition host.c:168
Host * HostGetHostFromHash(Address *a)
Definition host.c:486
void HostRelease(Host *h)
Definition host.c:461
char family
Definition decode.h:113
Definition host.h:58
Storage storage[]
Definition host.h:80
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)
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_HOST