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