suricata
output-flow.c
Go to the documentation of this file.
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. */
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'. */
41typedef struct OutputFlowLogger_ {
43
44 /** Data that will be passed to the ThreadInit callback. */
45 void *initdata;
46
48
49 /** A name for this logger, used for debugging only. */
50 const char *name;
51
52 TmEcode (*ThreadInit)(ThreadVars *, const void *, void **);
55
56static OutputFlowLogger *list = NULL;
57
60{
61 OutputFlowLogger *op = SCCalloc(1, sizeof(*op));
62 if (op == NULL)
63 return -1;
64
65 op->LogFunc = LogFunc;
66 op->initdata = initdata;
67 op->name = name;
70
71 if (list == NULL)
72 list = op;
73 else {
74 OutputFlowLogger *t = list;
75 while (t->next)
76 t = t->next;
77 t->next = op;
78 }
79
80 SCLogDebug("OutputRegisterFlowLogger happy");
81 return 0;
82}
83
84/** \brief Run flow logger(s)
85 * \note flow is already write locked
86 */
87TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
88{
89 DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
90
91 if (list == NULL)
92 return TM_ECODE_OK;
93
94 OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
95 OutputFlowLogger *logger = list;
96 OutputLoggerThreadStore *store = op_thread_data->store;
97
98 DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
99 DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
100 DEBUG_VALIDATE_BUG_ON(logger == NULL && store == NULL);
101
102 while (logger && store) {
103 DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL);
104
105 SCLogDebug("logger %p", logger);
106 //PACKET_PROFILING_LOGGER_START(p, logger->module_id);
107 logger->LogFunc(tv, store->thread_data, f);
108 //PACKET_PROFILING_LOGGER_END(p, logger->module_id);
109
110 logger = logger->next;
111 store = store->next;
112
113 DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
114 DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
115 }
116
117 return TM_ECODE_OK;
118}
119
120/** \brief thread init for the flow logger
121 * This will run the thread init functions for the individual registered
122 * loggers */
124{
125 OutputFlowLoggerThreadData *td = SCCalloc(1, sizeof(*td));
126 if (td == NULL)
127 return TM_ECODE_FAILED;
128
129 *data = (void *)td;
130
131 SCLogDebug("OutputFlowLogThreadInit happy (*data %p)", *data);
132
133 OutputFlowLogger *logger = list;
134 while (logger) {
135 if (logger->ThreadInit) {
136 void *retptr = NULL;
137 if (logger->ThreadInit(tv, (void *)logger->initdata, &retptr) == TM_ECODE_OK) {
138 OutputLoggerThreadStore *ts = SCCalloc(1, sizeof(*ts));
139 /* todo */ BUG_ON(ts == NULL);
140
141 /* store thread handle */
142 ts->thread_data = retptr;
143
144 if (td->store == NULL) {
145 td->store = ts;
146 } else {
148 while (tmp->next != NULL)
149 tmp = tmp->next;
150 tmp->next = ts;
151 }
152
153 SCLogDebug("%s is now set up", logger->name);
154 }
155 }
156
157 logger = logger->next;
158 }
159
160 return TM_ECODE_OK;
161}
162
164{
165 OutputFlowLoggerThreadData *op_thread_data = (OutputFlowLoggerThreadData *)thread_data;
166 if (op_thread_data == NULL)
167 return TM_ECODE_OK;
168
169 OutputLoggerThreadStore *store = op_thread_data->store;
170 OutputFlowLogger *logger = list;
171
172 while (logger && store) {
173 if (logger->ThreadDeinit) {
174 logger->ThreadDeinit(tv, store->thread_data);
175 }
176
177 OutputLoggerThreadStore *next_store = store->next;
178 SCFree(store);
179 store = next_store;
180 logger = logger->next;
181 }
182
183 SCFree(op_thread_data);
184 return TM_ECODE_OK;
185}
186
188{
189 OutputFlowLogger *logger = list;
190 while (logger) {
191 OutputFlowLogger *next_logger = logger->next;
192 SCFree(logger);
193 logger = next_logger;
194 }
195 list = NULL;
196}
ThreadVars * tv
struct OutputFlowLoggerThreadData_ OutputFlowLoggerThreadData
TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data)
void OutputFlowShutdown(void)
struct OutputFlowLogger_ OutputFlowLogger
TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void **data)
thread init for the flow logger This will run the thread init functions for the individual registered...
int SCOutputRegisterFlowLogger(const char *name, FlowLogger LogFunc, void *initdata, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a flow logger.
Definition output-flow.c:58
TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
Run flow logger(s)
Definition output-flow.c:87
int(* FlowLogger)(ThreadVars *, void *thread_data, Flow *f)
Flow logger function pointer type.
Definition output-flow.h:36
uint64_t ts
Flow data structure.
Definition flow.h:356
OutputLoggerThreadStore * store
Definition output-flow.c:35
FlowLogger LogFunc
Definition output-flow.c:42
const char * name
Definition output-flow.c:50
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition output-flow.c:53
struct OutputFlowLogger_ * next
Definition output-flow.c:47
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition output-flow.c:52
struct OutputLoggerThreadStore_ * next
Definition output.h:35
Per thread variable structure.
Definition threadvars.h:58
#define BUG_ON(x)
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition tm-modules.h:44
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition tm-modules.h:43
@ TM_ECODE_FAILED
@ TM_ECODE_OK
const char * name
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define DEBUG_VALIDATE_BUG_ON(exp)