Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}