Coverage Report

Created: 2026-09-06 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata8/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
114
{
32
114
    return StorageGetSize(STORAGE_HOST);
33
114
}
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
76
{
62
76
    int id = StorageRegister(STORAGE_HOST, name, size, Alloc, Free);
63
76
    HostStorageId hsi = { .id = id };
64
76
    return hsi;
65
76
}
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
5
{
77
5
    return StorageSetById(h->storage, STORAGE_HOST, id.id, ptr);
78
5
}
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
18
{
90
18
    return StorageGetById(h->storage, STORAGE_HOST, id.id);
91
18
}
92
93
/**
94
 * @}
95
 */
96
97
/* Start of "private" function */
98
99
void *HostAllocStorageById(Host *h, HostStorageId id)
100
0
{
101
0
    return StorageAllocByIdPrealloc(h->storage, STORAGE_HOST, id.id);
102
0
}
103
104
void HostFreeStorage(Host *h)
105
0
{
106
0
    if (HostStorageSize() > 0)
107
0
        StorageFreeAll(h->storage, STORAGE_HOST);
108
0
}
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
    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
142
    HostInitConfig(1);
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();
196
    StorageCleanup();
197
    return 1;
198
error:
199
    HostShutdown();
200
    StorageCleanup();
201
    return 0;
202
}
203
204
static 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
215
    HostInitConfig(1);
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();
246
    StorageCleanup();
247
    return 1;
248
error:
249
    HostShutdown();
250
    StorageCleanup();
251
    return 0;
252
}
253
254
static 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
271
    HostInitConfig(1);
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();
321
    StorageCleanup();
322
    return 1;
323
error:
324
    HostShutdown();
325
    StorageCleanup();
326
    return 0;
327
}
328
#endif
329
330
void RegisterHostStorageTests(void)
331
0
{
332
#ifdef UNITTESTS
333
    UtRegisterTest("HostStorageTest01", HostStorageTest01);
334
    UtRegisterTest("HostStorageTest02", HostStorageTest02);
335
    UtRegisterTest("HostStorageTest03", HostStorageTest03);
336
#endif
337
0
}