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 
30 unsigned 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 
59 HostStorageId 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 
75 int HostSetStorageById(Host *h, HostStorageId id, void *ptr)
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 
100 {
101  return StorageAllocByIdPrealloc(h->storage, STORAGE_HOST, id.id);
102 }
103 
105 {
106  if (HostStorageSize() > 0)
108 }
109 
110 
111 #ifdef UNITTESTS
112 
113 static void *StorageTestAlloc(unsigned int size)
114 {
115  void *x = SCMalloc(size);
116  return x;
117 }
118 static void StorageTestFree(void *x)
119 {
120  if (x)
121  SCFree(x);
122 }
123 
124 static int HostStorageTest01(void)
125 {
126  StorageCleanup();
127  StorageInit();
128 
129  HostStorageId id1 = HostStorageRegister("test", 8, StorageTestAlloc, StorageTestFree);
130  if (id1.id < 0)
131  goto error;
132  HostStorageId id2 = HostStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree);
133  if (id2.id < 0)
134  goto error;
135  HostStorageId id3 =
136  HostStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree);
137  if (id3.id < 0)
138  goto error;
139 
140  if (StorageFinalize() < 0)
141  goto error;
142 
143  HostInitConfig(1);
144 
145  Address a;
146  memset(&a, 0x00, sizeof(a));
147  a.addr_data32[0] = 0x01020304;
148  a.family = AF_INET;
149  Host *h = HostGetHostFromHash(&a);
150  if (h == NULL) {
151  printf("failed to get host: ");
152  goto error;
153  }
154 
155  void *ptr = HostGetStorageById(h, id1);
156  if (ptr != NULL) {
157  goto error;
158  }
159  ptr = HostGetStorageById(h, id2);
160  if (ptr != NULL) {
161  goto error;
162  }
163  ptr = HostGetStorageById(h, id3);
164  if (ptr != NULL) {
165  goto error;
166  }
167 
168  void *ptr1a = HostAllocStorageById(h, id1);
169  if (ptr1a == NULL) {
170  goto error;
171  }
172  void *ptr2a = HostAllocStorageById(h, id2);
173  if (ptr2a == NULL) {
174  goto error;
175  }
176  void *ptr3a = HostAllocStorageById(h, id3);
177  if (ptr3a == NULL) {
178  goto error;
179  }
180 
181  void *ptr1b = HostGetStorageById(h, id1);
182  if (ptr1a != ptr1b) {
183  goto error;
184  }
185  void *ptr2b = HostGetStorageById(h, id2);
186  if (ptr2a != ptr2b) {
187  goto error;
188  }
189  void *ptr3b = HostGetStorageById(h, id3);
190  if (ptr3a != ptr3b) {
191  goto error;
192  }
193 
194  HostRelease(h);
195 
196  HostShutdown();
197  StorageCleanup();
198  return 1;
199 error:
200  HostShutdown();
201  StorageCleanup();
202  return 0;
203 }
204 
205 static int HostStorageTest02(void)
206 {
207  StorageCleanup();
208  StorageInit();
209 
210  HostStorageId id1 = HostStorageRegister("test", sizeof(void *), NULL, StorageTestFree);
211  if (id1.id < 0)
212  goto error;
213 
214  if (StorageFinalize() < 0)
215  goto error;
216 
217  HostInitConfig(1);
218 
219  Address a;
220  memset(&a, 0x00, sizeof(a));
221  a.addr_data32[0] = 0x01020304;
222  a.family = AF_INET;
223  Host *h = HostGetHostFromHash(&a);
224  if (h == NULL) {
225  printf("failed to get host: ");
226  goto error;
227  }
228 
229  void *ptr = HostGetStorageById(h, id1);
230  if (ptr != NULL) {
231  goto error;
232  }
233 
234  void *ptr1a = SCMalloc(128);
235  if (unlikely(ptr1a == NULL)) {
236  goto error;
237  }
238  HostSetStorageById(h, id1, ptr1a);
239 
240  void *ptr1b = HostGetStorageById(h, id1);
241  if (ptr1a != ptr1b) {
242  goto error;
243  }
244 
245  HostRelease(h);
246 
247  HostShutdown();
248  StorageCleanup();
249  return 1;
250 error:
251  HostShutdown();
252  StorageCleanup();
253  return 0;
254 }
255 
256 static int HostStorageTest03(void)
257 {
258  StorageCleanup();
259  StorageInit();
260 
261  HostStorageId id1 = HostStorageRegister("test1", sizeof(void *), NULL, StorageTestFree);
262  if (id1.id < 0)
263  goto error;
264  HostStorageId id2 = HostStorageRegister("test2", sizeof(void *), NULL, StorageTestFree);
265  if (id2.id < 0)
266  goto error;
267  HostStorageId id3 = HostStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree);
268  if (id3.id < 0)
269  goto error;
270 
271  if (StorageFinalize() < 0)
272  goto error;
273 
274  HostInitConfig(1);
275 
276  Address a;
277  memset(&a, 0x00, sizeof(a));
278  a.addr_data32[0] = 0x01020304;
279  a.family = AF_INET;
280  Host *h = HostGetHostFromHash(&a);
281  if (h == NULL) {
282  printf("failed to get host: ");
283  goto error;
284  }
285 
286  void *ptr = HostGetStorageById(h, id1);
287  if (ptr != NULL) {
288  goto error;
289  }
290 
291  void *ptr1a = SCMalloc(128);
292  if (unlikely(ptr1a == NULL)) {
293  goto error;
294  }
295  HostSetStorageById(h, id1, ptr1a);
296 
297  void *ptr2a = SCMalloc(256);
298  if (unlikely(ptr2a == NULL)) {
299  goto error;
300  }
301  HostSetStorageById(h, id2, ptr2a);
302 
303  void *ptr3a = HostAllocStorageById(h, id3);
304  if (ptr3a == NULL) {
305  goto error;
306  }
307 
308  void *ptr1b = HostGetStorageById(h, id1);
309  if (ptr1a != ptr1b) {
310  goto error;
311  }
312  void *ptr2b = HostGetStorageById(h, id2);
313  if (ptr2a != ptr2b) {
314  goto error;
315  }
316  void *ptr3b = HostGetStorageById(h, id3);
317  if (ptr3a != ptr3b) {
318  goto error;
319  }
320 
321  HostRelease(h);
322 
323  HostShutdown();
324  StorageCleanup();
325  return 1;
326 error:
327  HostShutdown();
328  StorageCleanup();
329  return 0;
330 }
331 #endif
332 
334 {
335 #ifdef UNITTESTS
336  UtRegisterTest("HostStorageTest01", HostStorageTest01);
337  UtRegisterTest("HostStorageTest02", HostStorageTest02);
338  UtRegisterTest("HostStorageTest03", HostStorageTest03);
339 #endif
340 }
StorageFreeAll
void StorageFreeAll(Storage *storage, StorageEnum type)
Definition: util-storage.c:278
host-storage.h
StorageInit
void StorageInit(void)
Definition: util-storage.c:70
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
HostStorageRegister
HostStorageId HostStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Register a Host storage.
Definition: host-storage.c:59
Host_::storage
Storage storage[]
Definition: host.h:80
HostRelease
void HostRelease(Host *h)
Definition: host.c:461
HostGetHostFromHash
Host * HostGetHostFromHash(Address *a)
Definition: host.c:486
StorageCleanup
void StorageCleanup(void)
Definition: util-storage.c:78
HostGetStorageById
void * HostGetStorageById(Host *h, HostStorageId id)
Get a value from a given Host storage.
Definition: host-storage.c:88
Address_
Definition: decode.h:112
STORAGE_HOST
@ STORAGE_HOST
Definition: util-storage.h:30
util-unittest.h
RegisterHostStorageTests
void RegisterHostStorageTests(void)
Definition: host-storage.c:333
HostFreeStorage
void HostFreeStorage(Host *h)
Definition: host-storage.c:104
HostStorageSize
unsigned int HostStorageSize(void)
Definition: host-storage.c:30
StorageFinalize
int StorageFinalize(void)
Definition: util-storage.c:140
name
const char * name
Definition: tm-threads.c:2163
suricata-common.h
HostShutdown
void HostShutdown(void)
shutdown the flow engine
Definition: host.c:296
StorageSetById
int StorageSetById(Storage *storage, const StorageEnum type, const int id, void *ptr)
set storage for id
Definition: util-storage.c:226
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:238
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
HostStorageId_
Definition: host-storage.h:31
HostStorageId_::id
int id
Definition: host-storage.h:32
SCFree
#define SCFree(p)
Definition: util-mem.h:61
HostAllocStorageById
void * HostAllocStorageById(Host *h, HostStorageId id)
Definition: host-storage.c:99
Address_::family
char family
Definition: decode.h:113
HostInitConfig
void HostInitConfig(bool quiet)
initialize the configuration
Definition: host.c:168
StorageGetById
void * StorageGetById(const Storage *storage, const StorageEnum type, const int id)
get storage for id
Definition: util-storage.c:215
Host_
Definition: host.h:58
HostSetStorageById
int HostSetStorageById(Host *h, HostStorageId id, void *ptr)
Store a pointer in a given Host storage.
Definition: host-storage.c:75
StorageGetSize
unsigned int StorageGetSize(StorageEnum type)
get the size of the void array used to store the pointers
Definition: util-storage.c:210
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:102