• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.71
/src/output-flow.c
1
/* Copyright (C) 2007-2024 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
 * Flow Logger Output registration functions
24
 */
25

26
#include "suricata-common.h"
27
#include "output.h"
28
#include "output-flow.h"
29
#include "util-profiling.h"
30
#include "util-validate.h"
31

32
/** per thread data for this module, contains a list of per thread
33
 *  data for the packet loggers. */
34
typedef struct OutputFlowLoggerThreadData_ {
35
    OutputLoggerThreadStore *store;
36
} OutputFlowLoggerThreadData;
37

38
/* logger instance, a module + a output ctx,
39
 * it's perfectly valid that have multiple instances of the same
40
 * log module (e.g. http.log) with different output ctx'. */
41
typedef struct OutputFlowLogger_ {
42
    FlowLogger LogFunc;
43

44
    /** Data that will be passed to the ThreadInit callback. */
45
    void *initdata;
46

47
    struct OutputFlowLogger_ *next;
48

49
    /** A name for this logger, used for debugging only. */
50
    const char *name;
51

52
    TmEcode (*ThreadInit)(ThreadVars *, const void *, void **);
53
    TmEcode (*ThreadDeinit)(ThreadVars *, void *);
54
} OutputFlowLogger;
55

56
static OutputFlowLogger *list = NULL;
57

58
int SCOutputRegisterFlowLogger(const char *name, FlowLogger LogFunc, void *initdata,
59
        ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
60
{
2✔
61
    OutputFlowLogger *op = SCCalloc(1, sizeof(*op));
2✔
62
    if (op == NULL)
2✔
63
        return -1;
×
64

65
    op->LogFunc = LogFunc;
2✔
66
    op->initdata = initdata;
2✔
67
    op->name = name;
2✔
68
    op->ThreadInit = ThreadInit;
2✔
69
    op->ThreadDeinit = ThreadDeinit;
2✔
70

71
    if (list == NULL)
2✔
72
        list = op;
1✔
73
    else {
1✔
74
        OutputFlowLogger *t = list;
1✔
75
        while (t->next)
1✔
76
            t = t->next;
×
77
        t->next = op;
1✔
78
    }
1✔
79

80
    SCLogDebug("OutputRegisterFlowLogger happy");
2✔
81
    return 0;
2✔
82
}
2✔
83

84
/** \brief Run flow logger(s)
85
 *  \note flow is already write locked
86
 */
87
TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
88
{
9,384✔
89
    DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
9,384✔
90

91
    if (list == NULL)
9,384✔
UNCOV
92
        return TM_ECODE_OK;
×
93

94
    OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
9,384✔
95
    OutputFlowLogger *logger = list;
9,384✔
96
    OutputLoggerThreadStore *store = op_thread_data->store;
9,384✔
97

98
    DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
9,384✔
99
    DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
9,384✔
100
    DEBUG_VALIDATE_BUG_ON(logger == NULL && store == NULL);
9,384✔
101

102
    while (logger && store) {
28,152✔
103
        DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL);
18,768✔
104

105
        SCLogDebug("logger %p", logger);
18,768✔
106
        //PACKET_PROFILING_LOGGER_START(p, logger->module_id);
107
        logger->LogFunc(tv, store->thread_data, f);
18,768✔
108
        //PACKET_PROFILING_LOGGER_END(p, logger->module_id);
109

110
        logger = logger->next;
18,768✔
111
        store = store->next;
18,768✔
112

113
        DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
18,768✔
114
        DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
18,768✔
115
    }
18,768✔
116

117
    return TM_ECODE_OK;
9,384✔
118
}
9,384✔
119

120
/** \brief thread init for the flow logger
121
 *  This will run the thread init functions for the individual registered
122
 *  loggers */
123
TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void **data)
124
{
4✔
125
    OutputFlowLoggerThreadData *td = SCCalloc(1, sizeof(*td));
4✔
126
    if (td == NULL)
4✔
127
        return TM_ECODE_FAILED;
×
128

129
    *data = (void *)td;
4✔
130

131
    SCLogDebug("OutputFlowLogThreadInit happy (*data %p)", *data);
4✔
132

133
    OutputFlowLogger *logger = list;
4✔
134
    while (logger) {
10✔
135
        if (logger->ThreadInit) {
6✔
136
            void *retptr = NULL;
6✔
137
            if (logger->ThreadInit(tv, (void *)logger->initdata, &retptr) == TM_ECODE_OK) {
6✔
138
                OutputLoggerThreadStore *ts = SCCalloc(1, sizeof(*ts));
6✔
139
                /* todo */ BUG_ON(ts == NULL);
6✔
140

141
                /* store thread handle */
142
                ts->thread_data = retptr;
6✔
143

144
                if (td->store == NULL) {
6✔
145
                    td->store = ts;
3✔
146
                } else {
3✔
147
                    OutputLoggerThreadStore *tmp = td->store;
3✔
148
                    while (tmp->next != NULL)
3✔
149
                        tmp = tmp->next;
×
150
                    tmp->next = ts;
3✔
151
                }
3✔
152

153
                SCLogDebug("%s is now set up", logger->name);
6✔
154
            }
6✔
155
        }
6✔
156

157
        logger = logger->next;
6✔
158
    }
6✔
159

160
    return TM_ECODE_OK;
4✔
161
}
4✔
162

163
TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data)
UNCOV
164
{
×
UNCOV
165
    OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
×
UNCOV
166
    if (op_thread_data == NULL)
×
167
        return TM_ECODE_OK;
×
168

UNCOV
169
    OutputLoggerThreadStore *store = op_thread_data->store;
×
UNCOV
170
    OutputFlowLogger *logger = list;
×
171

UNCOV
172
    while (logger && store) {
×
UNCOV
173
        if (logger->ThreadDeinit) {
×
UNCOV
174
            logger->ThreadDeinit(tv, store->thread_data);
×
UNCOV
175
        }
×
176

UNCOV
177
        OutputLoggerThreadStore *next_store = store->next;
×
UNCOV
178
        SCFree(store);
×
UNCOV
179
        store = next_store;
×
UNCOV
180
        logger = logger->next;
×
UNCOV
181
    }
×
182

UNCOV
183
    SCFree(op_thread_data);
×
UNCOV
184
    return TM_ECODE_OK;
×
UNCOV
185
}
×
186

187
void OutputFlowShutdown(void)
UNCOV
188
{
×
UNCOV
189
    OutputFlowLogger *logger = list;
×
UNCOV
190
    while (logger) {
×
UNCOV
191
        OutputFlowLogger *next_logger = logger->next;
×
UNCOV
192
        SCFree(logger);
×
UNCOV
193
        logger = next_logger;
×
UNCOV
194
    }
×
195
    list = NULL;
UNCOV
196
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc