Coverage Report

Created: 2026-03-31 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/flow-storage.c
Line
Count
Source
1
/* Copyright (C) 2013 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 Eric Leblond <eric@regit.org>
22
 *
23
 * based on host-storage by Victor Julien <victor@inliniac.net>
24
 *
25
 * Flow wrapper around storage api
26
 */
27
28
#include "suricata-common.h"
29
#include "flow-storage.h"
30
#include "flow-hash.h"
31
#include "flow-util.h"
32
#include "util-storage.h"
33
#include "util-unittest.h"
34
35
unsigned int FlowStorageSize(void)
36
3.13M
{
37
3.13M
    return StorageGetSize(STORAGE_FLOW);
38
3.13M
}
39
40
void *FlowGetStorageById(const Flow *f, FlowStorageId id)
41
1.20M
{
42
1.20M
    return StorageGetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id);
43
1.20M
}
44
45
int FlowSetStorageById(Flow *f, FlowStorageId id, void *ptr)
46
2.39k
{
47
2.39k
    return StorageSetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id, ptr);
48
2.39k
}
49
50
void *FlowAllocStorageById(Flow *f, FlowStorageId id)
51
0
{
52
0
    return StorageAllocByIdPrealloc((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id);
53
0
}
54
55
void FlowFreeStorageById(Flow *f, FlowStorageId id)
56
289
{
57
289
    StorageFreeById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id.id);
58
289
}
59
60
void FlowFreeStorage(Flow *f)
61
580k
{
62
580k
    if (FlowStorageSize() > 0)
63
580k
        StorageFreeAll((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW);
64
580k
}
65
66
FlowStorageId FlowStorageRegister(const char *name, const unsigned int size,
67
        void *(*Alloc)(unsigned int), void (*Free)(void *))
68
216
{
69
216
    int id = StorageRegister(STORAGE_FLOW, name, size, Alloc, Free);
70
216
    FlowStorageId fsi = { .id = id };
71
216
    return fsi;
72
216
}
73
74
#ifdef UNITTESTS
75
76
static void *StorageTestAlloc(unsigned int size)
77
{
78
    void *x = SCMalloc(size);
79
    return x;
80
}
81
static void StorageTestFree(void *x)
82
{
83
    if (x)
84
        SCFree(x);
85
}
86
87
static int FlowStorageTest01(void)
88
{
89
    Flow *f = NULL;
90
91
    StorageInit();
92
93
    FlowStorageId id1 = FlowStorageRegister("test", 8, StorageTestAlloc, StorageTestFree);
94
    if (id1.id < 0)
95
        goto error;
96
    FlowStorageId id2 = FlowStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree);
97
    if (id2.id < 0)
98
        goto error;
99
    FlowStorageId id3 =
100
            FlowStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree);
101
    if (id3.id < 0)
102
        goto error;
103
104
    if (StorageFinalize() < 0)
105
        goto error;
106
107
    FlowInitConfig(FLOW_QUIET);
108
109
    f = FlowAlloc();
110
    if (f == NULL) {
111
        goto error;
112
    }
113
114
    void *ptr = FlowGetStorageById(f, id1);
115
    if (ptr != NULL) {
116
        goto error;
117
    }
118
    ptr = FlowGetStorageById(f, id2);
119
    if (ptr != NULL) {
120
        goto error;
121
    }
122
    ptr = FlowGetStorageById(f, id3);
123
    if (ptr != NULL) {
124
        goto error;
125
    }
126
127
    void *ptr1a = FlowAllocStorageById(f, id1);
128
    if (ptr1a == NULL) {
129
        goto error;
130
    }
131
    void *ptr2a = FlowAllocStorageById(f, id2);
132
    if (ptr2a == NULL) {
133
        goto error;
134
    }
135
    void *ptr3a = FlowAllocStorageById(f, id3);
136
    if (ptr3a == NULL) {
137
        goto error;
138
    }
139
140
    void *ptr1b = FlowGetStorageById(f, id1);
141
    if (ptr1a != ptr1b) {
142
        goto error;
143
    }
144
    void *ptr2b = FlowGetStorageById(f, id2);
145
    if (ptr2a != ptr2b) {
146
        goto error;
147
    }
148
    void *ptr3b = FlowGetStorageById(f, id3);
149
    if (ptr3a != ptr3b) {
150
        goto error;
151
    }
152
153
    FlowClearMemory(f, 0);
154
    FlowFree(f);
155
    FlowShutdown();
156
    StorageCleanup();
157
    return 1;
158
error:
159
    if (f != NULL) {
160
        FlowClearMemory(f, 0);
161
        FlowFree(f);
162
    }
163
    FlowShutdown();
164
    StorageCleanup();
165
    return 0;
166
}
167
168
static int FlowStorageTest02(void)
169
{
170
    Flow *f = NULL;
171
172
    StorageInit();
173
174
    FlowStorageId id1 = FlowStorageRegister("test", sizeof(void *), NULL, StorageTestFree);
175
    if (id1.id < 0)
176
        goto error;
177
178
    if (StorageFinalize() < 0)
179
        goto error;
180
181
    FlowInitConfig(FLOW_QUIET);
182
    f = FlowAlloc();
183
    if (f == NULL) {
184
        goto error;
185
    }
186
187
    void *ptr = FlowGetStorageById(f, id1);
188
    if (ptr != NULL) {
189
        goto error;
190
    }
191
192
    void *ptr1a = SCMalloc(128);
193
    if (unlikely(ptr1a == NULL)) {
194
        goto error;
195
    }
196
    FlowSetStorageById(f, id1, ptr1a);
197
198
    void *ptr1b = FlowGetStorageById(f, id1);
199
    if (ptr1a != ptr1b) {
200
        goto error;
201
    }
202
203
204
    FlowClearMemory(f, 0);
205
    FlowFree(f);
206
    FlowShutdown();
207
    StorageCleanup();
208
    return 1;
209
error:
210
    if (f != NULL) {
211
        FlowClearMemory(f, 0);
212
        FlowFree(f);
213
    }
214
    FlowShutdown();
215
    StorageCleanup();
216
    return 0;
217
}
218
219
static int FlowStorageTest03(void)
220
{
221
    Flow *f = NULL;
222
223
    StorageInit();
224
225
    FlowStorageId id1 = FlowStorageRegister("test1", sizeof(void *), NULL, StorageTestFree);
226
    if (id1.id < 0)
227
        goto error;
228
    FlowStorageId id2 = FlowStorageRegister("test2", sizeof(void *), NULL, StorageTestFree);
229
    if (id2.id < 0)
230
        goto error;
231
    FlowStorageId id3 = FlowStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree);
232
    if (id3.id < 0)
233
        goto error;
234
235
    if (StorageFinalize() < 0)
236
        goto error;
237
238
    FlowInitConfig(FLOW_QUIET);
239
    f = FlowAlloc();
240
    if (f == NULL) {
241
        goto error;
242
    }
243
244
    void *ptr = FlowGetStorageById(f, id1);
245
    if (ptr != NULL) {
246
        goto error;
247
    }
248
249
    void *ptr1a = SCMalloc(128);
250
    if (unlikely(ptr1a == NULL)) {
251
        goto error;
252
    }
253
    FlowSetStorageById(f, id1, ptr1a);
254
255
    void *ptr2a = SCMalloc(256);
256
    if (unlikely(ptr2a == NULL)) {
257
        goto error;
258
    }
259
    FlowSetStorageById(f, id2, ptr2a);
260
261
    void *ptr3a = FlowAllocStorageById(f, id3);
262
    if (ptr3a == NULL) {
263
        goto error;
264
    }
265
266
    void *ptr1b = FlowGetStorageById(f, id1);
267
    if (ptr1a != ptr1b) {
268
        goto error;
269
    }
270
    void *ptr2b = FlowGetStorageById(f, id2);
271
    if (ptr2a != ptr2b) {
272
        goto error;
273
    }
274
    void *ptr3b = FlowGetStorageById(f, id3);
275
    if (ptr3a != ptr3b) {
276
        goto error;
277
    }
278
279
    FlowClearMemory(f, 0);
280
    FlowFree(f);
281
    FlowShutdown();
282
    StorageCleanup();
283
    return 1;
284
error:
285
    if (f != NULL) {
286
        FlowClearMemory(f, 0);
287
        FlowFree(f);
288
    }
289
    FlowShutdown();
290
    StorageCleanup();
291
    return 0;
292
}
293
#endif
294
295
void RegisterFlowStorageTests(void)
296
0
{
297
#ifdef UNITTESTS
298
    UtRegisterTest("FlowStorageTest01", FlowStorageTest01);
299
    UtRegisterTest("FlowStorageTest02", FlowStorageTest02);
300
    UtRegisterTest("FlowStorageTest03", FlowStorageTest03);
301
#endif
302
0
}