suricata
flow-worker.c
Go to the documentation of this file.
1 /* Copyright (C) 2016 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 Workers are single thread modules taking care of (almost)
24  * everything related to packets with flows:
25  *
26  * - Lookup/creation
27  * - Stream tracking, reassembly
28  * - Applayer update
29  * - Detection
30  *
31  * This all while holding the flow lock.
32  */
33 
34 #include "suricata-common.h"
35 #include "suricata.h"
36 
37 #include "decode.h"
38 #include "detect.h"
39 #include "stream-tcp.h"
40 #include "app-layer.h"
41 #include "detect-engine.h"
42 #include "output.h"
43 #include "app-layer-parser.h"
44 
45 #include "util-validate.h"
46 
47 #include "flow-util.h"
48 
50 
51 typedef struct FlowWorkerThreadData_ {
53 
54  union {
57  };
58 
60 
61  void *output_thread; /* Output thread data. */
62 
65  uint16_t both_bypass_pkts;
67 
69 
71 
72 /** \brief handle flow for packet
73  *
74  * Handle flow creation/lookup
75  */
76 static inline TmEcode FlowUpdate(ThreadVars *tv, FlowWorkerThreadData *fw, Packet *p)
77 {
79 
80  int state = SC_ATOMIC_GET(p->flow->flow_state);
81  switch (state) {
82 #ifdef CAPTURE_OFFLOAD
83  case FLOW_STATE_CAPTURE_BYPASSED:
86  return TM_ECODE_DONE;
87 #endif
91  return TM_ECODE_DONE;
92  default:
93  return TM_ECODE_OK;
94  }
95 }
96 
97 static TmEcode FlowWorkerThreadDeinit(ThreadVars *tv, void *data);
98 
99 static TmEcode FlowWorkerThreadInit(ThreadVars *tv, const void *initdata, void **data)
100 {
101  FlowWorkerThreadData *fw = SCCalloc(1, sizeof(*fw));
102  if (fw == NULL)
103  return TM_ECODE_FAILED;
104 
105  SC_ATOMIC_INITPTR(fw->detect_thread);
106  SC_ATOMIC_SET(fw->detect_thread, NULL);
107 
108  fw->local_bypass_pkts = StatsRegisterCounter("flow_bypassed.local_pkts", tv);
109  fw->local_bypass_bytes = StatsRegisterCounter("flow_bypassed.local_bytes", tv);
110  fw->both_bypass_pkts = StatsRegisterCounter("flow_bypassed.local_capture_pkts", tv);
111  fw->both_bypass_bytes = StatsRegisterCounter("flow_bypassed.local_capture_bytes", tv);
112 
114  if (fw->dtv == NULL) {
115  FlowWorkerThreadDeinit(tv, fw);
116  return TM_ECODE_FAILED;
117  }
118 
119  /* setup TCP */
120  if (StreamTcpThreadInit(tv, NULL, &fw->stream_thread_ptr) != TM_ECODE_OK) {
121  FlowWorkerThreadDeinit(tv, fw);
122  return TM_ECODE_FAILED;
123  }
124 
125  if (DetectEngineEnabled()) {
126  /* setup DETECT */
127  void *detect_thread = NULL;
128  if (DetectEngineThreadCtxInit(tv, NULL, &detect_thread) != TM_ECODE_OK) {
129  FlowWorkerThreadDeinit(tv, fw);
130  return TM_ECODE_FAILED;
131  }
132  SC_ATOMIC_SET(fw->detect_thread, detect_thread);
133  }
134 
135  /* Setup outputs for this thread. */
136  if (OutputLoggerThreadInit(tv, initdata, &fw->output_thread) != TM_ECODE_OK) {
137  FlowWorkerThreadDeinit(tv, fw);
138  return TM_ECODE_FAILED;
139  }
140 
143 
144  /* setup pq for stream end pkts */
145  memset(&fw->pq, 0, sizeof(PacketQueueNoLock));
146 
147  *data = fw;
148  return TM_ECODE_OK;
149 }
150 
151 static TmEcode FlowWorkerThreadDeinit(ThreadVars *tv, void *data)
152 {
153  FlowWorkerThreadData *fw = data;
154 
156 
157  /* free TCP */
158  StreamTcpThreadDeinit(tv, (void *)fw->stream_thread);
159 
160  /* free DETECT */
161  void *detect_thread = SC_ATOMIC_GET(fw->detect_thread);
162  if (detect_thread != NULL) {
163  DetectEngineThreadCtxDeinit(tv, detect_thread);
164  SC_ATOMIC_SET(fw->detect_thread, NULL);
165  }
166 
167  /* Free output. */
169 
170  /* free pq */
171  BUG_ON(fw->pq.len);
172 
173  SCFree(fw);
174  return TM_ECODE_OK;
175 }
176 
177 static void FlowPruneFiles(Packet *p)
178 {
179  if (p->flow && p->flow->alstate) {
180  Flow *f = p->flow;
183  if (fc != NULL) {
184  FilePrune(fc);
185  }
186  }
187 }
188 
189 static TmEcode FlowWorker(ThreadVars *tv, Packet *p, void *data)
190 {
191  FlowWorkerThreadData *fw = data;
192  void *detect_thread = SC_ATOMIC_GET(fw->detect_thread);
193 
194  SCLogDebug("packet %"PRIu64, p->pcap_cnt);
195 
196  /* update time */
197  if (!(PKT_IS_PSEUDOPKT(p))) {
198  TimeSetByThread(tv->id, &p->ts);
199  }
200 
201  /* handle Flow */
202  if (p->flags & PKT_WANTS_FLOW) {
204 
205  FlowHandlePacket(tv, fw->dtv, p);
206  if (likely(p->flow != NULL)) {
208  if (FlowUpdate(tv, fw, p) == TM_ECODE_DONE) {
209  FLOWLOCK_UNLOCK(p->flow);
210  return TM_ECODE_OK;
211  }
212  }
213  /* Flow is now LOCKED */
214 
216 
217  /* if PKT_WANTS_FLOW is not set, but PKT_HAS_FLOW is, then this is a
218  * pseudo packet created by the flow manager. */
219  } else if (p->flags & PKT_HAS_FLOW) {
220  FLOWLOCK_WRLOCK(p->flow);
221  }
222 
223  SCLogDebug("packet %"PRIu64" has flow? %s", p->pcap_cnt, p->flow ? "yes" : "no");
224 
225  /* handle TCP and app layer */
226  if (p->flow && PKT_IS_TCP(p)) {
227  SCLogDebug("packet %"PRIu64" is TCP. Direction %s", p->pcap_cnt, PKT_IS_TOSERVER(p) ? "TOSERVER" : "TOCLIENT");
229 
230  /* if detect is disabled, we need to apply file flags to the flow
231  * here on the first packet. */
232  if (detect_thread == NULL &&
235  {
237  }
238 
240  StreamTcp(tv, p, fw->stream_thread, &fw->pq);
242 
243  if (FlowChangeProto(p->flow)) {
244  StreamTcpDetectLogFlush(tv, fw->stream_thread, p->flow, p, &fw->pq);
245  }
246 
247  /* Packets here can safely access p->flow as it's locked */
248  SCLogDebug("packet %"PRIu64": extra packets %u", p->pcap_cnt, fw->pq.len);
249  Packet *x;
250  while ((x = PacketDequeueNoLock(&fw->pq))) {
251  SCLogDebug("packet %"PRIu64" extra packet %p", p->pcap_cnt, x);
252 
253  // TODO do we need to call StreamTcp on these pseudo packets or not?
254  //StreamTcp(tv, x, fw->stream_thread, &fw->pq, NULL);
255  if (detect_thread != NULL) {
257  Detect(tv, x, detect_thread);
259  }
260 
261  // Outputs
263 
264  /* put these packets in the preq queue so that they are
265  * by the other thread modules before packet 'p'. */
267  }
268 
269  /* handle the app layer part of the UDP packet payload */
270  } else if (p->flow && p->proto == IPPROTO_UDP) {
274  }
275 
277 
278  /* handle Detect */
280  SCLogDebug("packet %"PRIu64" calling Detect", p->pcap_cnt);
281 
282  if (detect_thread != NULL) {
284  Detect(tv, p, detect_thread);
286  }
287 
288  // Outputs.
290 
291  /* Prune any stored files. */
292  FlowPruneFiles(p);
293 
294  /* Release tcp segments. Done here after alerting can use them. */
295  if (p->flow != NULL && p->proto == IPPROTO_TCP) {
300  }
301 
302  if (p->flow) {
304 
305  /* run tx cleanup last */
307  FLOWLOCK_UNLOCK(p->flow);
308  }
309 
310  return TM_ECODE_OK;
311 }
312 
313 void FlowWorkerReplaceDetectCtx(void *flow_worker, void *detect_ctx)
314 {
315  FlowWorkerThreadData *fw = flow_worker;
316 
317  SC_ATOMIC_SET(fw->detect_thread, detect_ctx);
318 }
319 
320 void *FlowWorkerGetDetectCtxPtr(void *flow_worker)
321 {
322  FlowWorkerThreadData *fw = flow_worker;
323 
324  return SC_ATOMIC_GET(fw->detect_thread);
325 }
326 
328 {
329  switch (fwi) {
331  return "flow";
333  return "stream";
335  return "app-layer";
337  return "detect";
339  return "tcp-prune";
341  return "size";
342  }
343  return "error";
344 }
345 
346 static void FlowWorkerExitPrintStats(ThreadVars *tv, void *data)
347 {
348  FlowWorkerThreadData *fw = data;
350 }
351 
353 {
354  tmm_modules[TMM_FLOWWORKER].name = "FlowWorker";
355  tmm_modules[TMM_FLOWWORKER].ThreadInit = FlowWorkerThreadInit;
356  tmm_modules[TMM_FLOWWORKER].Func = FlowWorker;
357  tmm_modules[TMM_FLOWWORKER].ThreadDeinit = FlowWorkerThreadDeinit;
358  tmm_modules[TMM_FLOWWORKER].ThreadExitPrintStats = FlowWorkerExitPrintStats;
361 }
PKT_IS_TOCLIENT
#define PKT_IS_TOCLIENT(p)
Definition: decode.h:261
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:67
Packet_::proto
uint8_t proto
Definition: decode.h:433
FileContainer_
Definition: util-file.h:100
TimeSetByThread
void TimeSetByThread(const int thread_id, const struct timeval *tv)
Definition: util-time.c:114
detect-engine.h
PROFILE_FLOWWORKER_DETECT
@ PROFILE_FLOWWORKER_DETECT
Definition: flow-worker.h:25
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1087
flow-util.h
FlowWorkerThreadData
struct FlowWorkerThreadData_ FlowWorkerThreadData
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1125
stream-tcp.h
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:355
ProfileFlowWorkerIdToString
const char * ProfileFlowWorkerIdToString(enum ProfileFlowWorkerId fwi)
Definition: flow-worker.c:327
OutputLoggerExitPrintStats
void OutputLoggerExitPrintStats(ThreadVars *tv, void *thread_data)
Definition: output.c:983
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:564
StreamTcpThread_
Definition: stream-tcp.h:70
PROFILE_FLOWWORKER_TCPPRUNE
@ PROFILE_FLOWWORKER_TCPPRUNE
Definition: flow-worker.h:26
TM_FLAG_DETECT_TM
#define TM_FLAG_DETECT_TM
Definition: tm-modules.h:34
TM_ECODE_DONE
@ TM_ECODE_DONE
Definition: tm-threads-common.h:80
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:61
Packet_::flags
uint32_t flags
Definition: decode.h:446
Flow_
Flow data structure.
Definition: flow.h:343
PKT_WANTS_FLOW
#define PKT_WANTS_FLOW
Definition: decode.h:1108
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:936
FlowWorkerThreadData_::dtv
DecodeThreadVars * dtv
Definition: flow-worker.c:52
StreamTcpThreadInit
TmEcode StreamTcpThreadInit(ThreadVars *tv, void *initdata, void **data)
Definition: stream-tcp.c:5216
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:218
AppLayerParserGetFiles
FileContainer * AppLayerParserGetFiles(const Flow *f, const uint8_t direction)
Definition: app-layer-parser.c:857
Detect
TmEcode Detect(ThreadVars *tv, Packet *p, void *data)
Detection engine thread wrapper.
Definition: detect.c:1620
FlowWorkerThreadData_::stream_thread
StreamTcpThread * stream_thread
Definition: flow-worker.c:55
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:442
PROFILE_FLOWWORKER_STREAM
@ PROFILE_FLOWWORKER_STREAM
Definition: flow-worker.h:23
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:79
OutputLoggerThreadDeinit
TmEcode OutputLoggerThreadDeinit(ThreadVars *tv, void *thread_data)
Definition: output.c:957
DisableDetectFlowFileFlags
void DisableDetectFlowFileFlags(Flow *f)
disable file features we don't need Called if we have no detection engine.
Definition: detect.c:1678
PacketQueueNoLock_
simple fifo queue for packets
Definition: packet-queue.h:32
FLOWWORKER_PROFILING_START
#define FLOWWORKER_PROFILING_START(p, id)
Definition: util-profiling.h:166
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:260
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:78
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
PKT_IS_TCP
#define PKT_IS_TCP(p)
Definition: decode.h:256
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:478
DetectEngineThreadCtxPtr
DetectEngineThreadCtx * DetectEngineThreadCtxPtr
Definition: flow-worker.c:49
FilePrune
void FilePrune(FileContainer *ffc)
Definition: util-file.c:388
FLOW_STATE_LOCAL_BYPASSED
@ FLOW_STATE_LOCAL_BYPASSED
Definition: flow.h:486
decode.h
PKT_IS_TOSERVER
#define PKT_IS_TOSERVER(p)
Definition: decode.h:260
DetectEngineThreadCtx_
Definition: detect.h:1009
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:206
ProfileFlowWorkerId
ProfileFlowWorkerId
Definition: flow-worker.h:21
FlowWorkerThreadData_::local_bypass_bytes
uint16_t local_bypass_bytes
Definition: flow-worker.c:64
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:257
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
StreamTcp
TmEcode StreamTcp(ThreadVars *tv, Packet *p, void *data, PacketQueueNoLock *pq)
Definition: stream-tcp.c:5180
DetectEngineEnabled
int DetectEngineEnabled(void)
Check if detection is enabled.
Definition: detect-engine.c:3198
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
FLOW_PKT_TOCLIENT_FIRST
#define FLOW_PKT_TOCLIENT_FIRST
Definition: flow.h:224
FlowWorkerThreadData_::local_bypass_pkts
uint16_t local_bypass_pkts
Definition: flow-worker.c:63
PROFILE_FLOWWORKER_APPLAYERUDP
@ PROFILE_FLOWWORKER_APPLAYERUDP
Definition: flow-worker.h:24
FLOWWORKER_PROFILING_END
#define FLOWWORKER_PROFILING_END(p, id)
Definition: util-profiling.h:173
StreamTcpPruneSession
void StreamTcpPruneSession(Flow *f, uint8_t flags)
Remove idle TcpSegments from TcpSession.
Definition: stream-tcp-list.c:801
OutputLoggerThreadInit
TmEcode OutputLoggerThreadInit(ThreadVars *tv, const void *initdata, void **data)
Definition: output.c:926
app-layer-parser.h
ThreadVars_::id
int id
Definition: threadvars.h:87
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:282
Packet_
Definition: decode.h:411
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:227
AppLayerHandleUdp
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
Handle a app layer UDP message.
Definition: app-layer.c:698
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:108
TmEcode
TmEcode
Definition: tm-threads-common.h:77
TmModuleFlowWorkerRegister
void TmModuleFlowWorkerRegister(void)
Definition: flow-worker.c:352
TmModule_::name
const char * name
Definition: tm-modules.h:44
TMM_FLOWWORKER
@ TMM_FLOWWORKER
Definition: tm-threads-common.h:34
FlowWorkerGetDetectCtxPtr
void * FlowWorkerGetDetectCtxPtr(void *flow_worker)
Definition: flow-worker.c:320
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:167
FlowWorkerThreadData_::stream_thread_ptr
void * stream_thread_ptr
Definition: flow-worker.c:56
FlowWorkerThreadData_::pq
PacketQueueNoLock pq
Definition: flow-worker.c:68
Packet_::flow
struct Flow_ * flow
Definition: decode.h:448
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:2796
AppLayerParserTransactionsCleanup
void AppLayerParserTransactionsCleanup(Flow *f)
remove obsolete (inspected and logged) transactions
Definition: app-layer-parser.c:875
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:638
Packet_::ts
struct timeval ts
Definition: decode.h:454
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3004
PROFILE_FLOWWORKER_SIZE
@ PROFILE_FLOWWORKER_SIZE
Definition: flow-worker.h:27
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
FlowWorkerThreadData_::both_bypass_bytes
uint16_t both_bypass_bytes
Definition: flow-worker.c:66
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
PacketUpdateEngineEventCounters
void PacketUpdateEngineEventCounters(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Definition: decode.c:125
FlowHandlePacketUpdate
void FlowHandlePacketUpdate(Flow *f, Packet *p)
Update Packet and Flow.
Definition: flow.c:414
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
util-validate.h
StreamTcpDetectLogFlush
void StreamTcpDetectLogFlush(ThreadVars *tv, StreamTcpThread *stt, Flow *f, Packet *p, PacketQueueNoLock *pq)
create packets in both directions to flush out logging and detection before switching protocols....
Definition: stream-tcp.c:6180
FlowHandlePacket
void FlowHandlePacket(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Entry point for packet flow handling.
Definition: flow.c:515
PacketQueueNoLock_::len
uint32_t len
Definition: packet-queue.h:35
StatsAddUI64
void StatsAddUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Adds a value of type uint64_t to the local counter.
Definition: counters.c:148
OutputLoggerLog
TmEcode OutputLoggerLog(ThreadVars *tv, Packet *p, void *thread_data)
Definition: output.c:911
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:625
Flow_::alstate
void * alstate
Definition: flow.h:454
SC_ATOMIC_INITPTR
#define SC_ATOMIC_INITPTR(name)
Definition: util-atomic.h:289
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:619
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:110
PROFILE_FLOWWORKER_FLOW
@ PROFILE_FLOWWORKER_FLOW
Definition: flow-worker.h:22
StreamTcpThread_::ra_ctx
TcpReassemblyThreadCtx * ra_ctx
Definition: stream-tcp.h:103
suricata.h
likely
#define likely(expr)
Definition: util-optimize.h:32
FlowWorkerThreadData_::output_thread
void * output_thread
Definition: flow-worker.c:61
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:256
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:347
FlowWorkerThreadData_::SC_ATOMIC_DECLARE
SC_ATOMIC_DECLARE(DetectEngineThreadCtxPtr, detect_thread)
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:939
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
FLOW_PKT_TOSERVER_FIRST
#define FLOW_PKT_TOSERVER_FIRST
Definition: flow.h:223
FlowWorkerThreadData_::both_bypass_pkts
uint16_t both_bypass_pkts
Definition: flow-worker.c:65
TM_FLAG_STREAM_TM
#define TM_FLAG_STREAM_TM
Definition: tm-modules.h:33
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:70
FlowWorkerThreadData_
Definition: flow-worker.c:51
StreamTcpThreadDeinit
TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data)
Definition: stream-tcp.c:5283
output.h
FlowWorkerReplaceDetectCtx
void FlowWorkerReplaceDetectCtx(void *flow_worker, void *detect_ctx)
Definition: flow-worker.c:313
app-layer.h