Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata/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 SCHostStorageSize(void)
31
120
{
32
120
    return SCStorageGetSize(STORAGE_HOST);
33
120
}
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 SCHostStorageRegister() during
41
 * the init of your module. Then you can attach data via SCHostSetStorageById()
42
 * and access them via SCHostGetStorageById().
43
 * @{
44
 */
45
46
/**
47
 * \brief Register a Host storage
48
 *
49
 * \param name the name of the storage
50
 * \param Free free function for the new storage
51
 *
52
 * \retval The ID of the newly register storage that will be used to access data
53
 *
54
 * It has to be called once during the init of the sub system
55
 */
56
57
SCHostStorageId SCHostStorageRegister(const char *name, void (*Free)(void *))
58
80
{
59
80
    int id = SCStorageRegister(STORAGE_HOST, name, Free);
60
80
    SCHostStorageId hsi = { .id = id };
61
80
    return hsi;
62
80
}
63
64
/**
65
 * \brief Store a pointer in a given Host storage
66
 *
67
 * \param h a pointer to the Host
68
 * \param id the id of the storage (return of SCHostStorageRegister() call)
69
 * \param ptr pointer to the data to store
70
 */
71
72
int SCHostSetStorageById(Host *h, SCHostStorageId id, void *ptr)
73
71
{
74
71
    return SCStorageSetById(h->storage, STORAGE_HOST, id.id, ptr);
75
71
}
76
77
/**
78
 * \brief Get a value from a given Host storage
79
 *
80
 * \param h a pointer to the Host
81
 * \param id the id of the storage (return of SCHostStorageRegister() call)
82
 *
83
 */
84
85
void *SCHostGetStorageById(Host *h, SCHostStorageId id)
86
49.8k
{
87
49.8k
    return SCStorageGetById(h->storage, STORAGE_HOST, id.id);
88
49.8k
}
89
90
/**
91
 * @}
92
 */
93
94
/* Start of "private" function */
95
96
void SCHostFreeStorage(Host *h)
97
0
{
98
0
    if (SCHostStorageSize() > 0)
99
0
        SCStorageFreeAll(h->storage, STORAGE_HOST);
100
0
}
101
102
103
#ifdef UNITTESTS
104
105
static void StorageTestFree(void *x)
106
{
107
    if (x)
108
        SCFree(x);
109
}
110
111
static int HostStorageTest01(void)
112
{
113
    SCStorageCleanup();
114
    SCStorageInit();
115
116
    SCHostStorageId id1 = SCHostStorageRegister("test", StorageTestFree);
117
    FAIL_IF(id1.id < 0);
118
    SCHostStorageId id2 = SCHostStorageRegister("variable", StorageTestFree);
119
    FAIL_IF(id2.id < 0);
120
    SCHostStorageId id3 = SCHostStorageRegister("store", StorageTestFree);
121
    FAIL_IF(id3.id < 0);
122
123
    FAIL_IF(SCStorageFinalize() < 0);
124
125
    HostInitConfig(1);
126
127
    Address a;
128
    memset(&a, 0x00, sizeof(a));
129
    a.addr_data32[0] = 0x01020304;
130
    a.family = AF_INET;
131
    Host *h = HostGetHostFromHash(&a);
132
    FAIL_IF_NULL(h);
133
134
    void *ptr = SCHostGetStorageById(h, id1);
135
    FAIL_IF_NOT_NULL(ptr);
136
    ptr = SCHostGetStorageById(h, id2);
137
    FAIL_IF_NOT_NULL(ptr);
138
    ptr = SCHostGetStorageById(h, id3);
139
    FAIL_IF_NOT_NULL(ptr);
140
141
    void *ptr1a = SCMalloc(8);
142
    FAIL_IF_NULL(ptr1a);
143
    FAIL_IF(SCHostSetStorageById(h, id1, ptr1a) != 0);
144
    void *ptr2a = SCMalloc(24);
145
    FAIL_IF_NULL(ptr2a);
146
    FAIL_IF(SCHostSetStorageById(h, id2, ptr2a) != 0);
147
    void *ptr3a = SCMalloc(16);
148
    FAIL_IF_NULL(ptr3a);
149
    FAIL_IF(SCHostSetStorageById(h, id3, ptr3a) != 0);
150
151
    void *ptr1b = SCHostGetStorageById(h, id1);
152
    FAIL_IF(ptr1a != ptr1b);
153
    void *ptr2b = SCHostGetStorageById(h, id2);
154
    FAIL_IF(ptr2a != ptr2b);
155
    void *ptr3b = SCHostGetStorageById(h, id3);
156
    FAIL_IF(ptr3a != ptr3b);
157
158
    HostRelease(h);
159
160
    HostShutdown();
161
    SCStorageCleanup();
162
    PASS;
163
}
164
165
static int HostStorageTest02(void)
166
{
167
    SCStorageCleanup();
168
    SCStorageInit();
169
170
    SCHostStorageId id1 = SCHostStorageRegister("test", StorageTestFree);
171
    FAIL_IF(id1.id < 0);
172
173
    FAIL_IF(SCStorageFinalize() < 0);
174
175
    HostInitConfig(1);
176
177
    Address a;
178
    memset(&a, 0x00, sizeof(a));
179
    a.addr_data32[0] = 0x01020304;
180
    a.family = AF_INET;
181
    Host *h = HostGetHostFromHash(&a);
182
    FAIL_IF_NULL(h);
183
184
    void *ptr = SCHostGetStorageById(h, id1);
185
    FAIL_IF_NOT_NULL(ptr);
186
187
    void *ptr1a = SCMalloc(128);
188
    FAIL_IF_NULL(ptr1a);
189
    SCHostSetStorageById(h, id1, ptr1a);
190
191
    void *ptr1b = SCHostGetStorageById(h, id1);
192
    FAIL_IF(ptr1a != ptr1b);
193
194
    HostRelease(h);
195
196
    HostShutdown();
197
    SCStorageCleanup();
198
    PASS;
199
}
200
201
static int HostStorageTest03(void)
202
{
203
    SCStorageCleanup();
204
    SCStorageInit();
205
206
    SCHostStorageId id1 = SCHostStorageRegister("test1", StorageTestFree);
207
    FAIL_IF(id1.id < 0);
208
    SCHostStorageId id2 = SCHostStorageRegister("test2", StorageTestFree);
209
    FAIL_IF(id2.id < 0);
210
    SCHostStorageId id3 = SCHostStorageRegister("test3", StorageTestFree);
211
    FAIL_IF(id3.id < 0);
212
213
    FAIL_IF(SCStorageFinalize() < 0);
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
    FAIL_IF_NULL(h);
223
224
    void *ptr = SCHostGetStorageById(h, id1);
225
    FAIL_IF_NOT_NULL(ptr);
226
227
    void *ptr1a = SCMalloc(128);
228
    FAIL_IF_NULL(ptr1a);
229
    SCHostSetStorageById(h, id1, ptr1a);
230
231
    void *ptr2a = SCMalloc(256);
232
    FAIL_IF_NULL(ptr2a);
233
    SCHostSetStorageById(h, id2, ptr2a);
234
235
    void *ptr3a = SCMalloc(32);
236
    FAIL_IF_NULL(ptr3a);
237
    SCHostSetStorageById(h, id3, ptr3a);
238
239
    void *ptr1b = SCHostGetStorageById(h, id1);
240
    FAIL_IF(ptr1a != ptr1b);
241
    void *ptr2b = SCHostGetStorageById(h, id2);
242
    FAIL_IF(ptr2a != ptr2b);
243
    void *ptr3b = SCHostGetStorageById(h, id3);
244
    FAIL_IF(ptr3a != ptr3b);
245
246
    HostRelease(h);
247
248
    HostShutdown();
249
    SCStorageCleanup();
250
    PASS;
251
}
252
#endif
253
254
void SCRegisterHostStorageTests(void)
255
0
{
256
#ifdef UNITTESTS
257
    UtRegisterTest("HostStorageTest01", HostStorageTest01);
258
    UtRegisterTest("HostStorageTest02", HostStorageTest02);
259
    UtRegisterTest("HostStorageTest03", HostStorageTest03);
260
#endif
261
0
}