suricata
flow-worker.c
Go to the documentation of this file.
1 /* Copyright (C) 2016-2020 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 #include "app-layer-frames.h"
45 
46 #include "util-profiling.h"
47 #include "util-validate.h"
48 #include "util-time.h"
49 #include "tmqh-packetpool.h"
50 
51 #include "flow-util.h"
52 #include "flow-manager.h"
53 #include "flow-timeout.h"
54 #include "flow-spare-pool.h"
55 #include "flow-worker.h"
56 
58 
59 typedef struct FlowTimeoutCounters {
63 
64 typedef struct FlowWorkerThreadData_ {
66 
67  union {
70  };
71 
73 
74  void *output_thread; /* Output thread data. */
75  void *output_thread_flow; /* Output thread data. */
76 
79  uint16_t both_bypass_pkts;
81  /** Queue to put pseudo packets that have been created by the stream (RST response) and by the
82  * flush logic following a protocol change. */
85 
86  struct {
87  uint16_t flows_injected;
89  uint16_t flows_removed;
92  } cnt;
94 
96 
97 static void FlowWorkerFlowTimeout(ThreadVars *tv, Packet *p, FlowWorkerThreadData *fw, void *detect_thread);
99 
100 /**
101  * \internal
102  * \brief Forces reassembly for flow if it needs it.
103  *
104  * The function requires flow to be locked beforehand.
105  *
106  * \param f Pointer to the flow.
107  *
108  * \retval cnt number of packets injected
109  */
110 static int FlowFinish(ThreadVars *tv, Flow *f, FlowWorkerThreadData *fw, void *detect_thread)
111 {
112  Packet *p1 = NULL, *p2 = NULL;
113  const int server = f->ffr_tc;
114  const int client = f->ffr_ts;
115 
116  /* Get the tcp session for the flow */
117  TcpSession *ssn = (TcpSession *)f->protoctx;
118 
119  /* The packets we use are based on what segments in what direction are
120  * unprocessed.
121  * p1 if we have client segments for reassembly purpose only. If we
122  * have no server segments p2 can be a toserver packet with dummy
123  * seq/ack, and if we have server segments p2 has to carry out reassembly
124  * for server segment as well, in which case we will also need a p3 in the
125  * toclient which is now dummy since all we need it for is detection */
126 
127  /* insert a pseudo packet in the toserver direction */
129  p1 = FlowForceReassemblyPseudoPacketGet(0, f, ssn);
130  if (p1 == NULL) {
131  return 0;
132  }
134 
136  p2 = FlowForceReassemblyPseudoPacketGet(1, f, ssn);
137  if (p2 == NULL) {
138  FlowDeReference(&p1->flow);
139  TmqhOutputPacketpool(NULL, p1);
140  return 0;
141  }
143  p2->flowflags |= FLOW_PKT_LAST_PSEUDO;
144  } else {
146  }
147  } else {
149  p1 = FlowForceReassemblyPseudoPacketGet(1, f, ssn);
150  if (p1 == NULL) {
151  return 0;
152  }
155  } else {
156  /* impossible */
157  BUG_ON(1);
158  }
159  }
161 
162  FlowWorkerFlowTimeout(tv, p1, fw, detect_thread);
164  if (p2) {
165  FlowWorkerFlowTimeout(tv, p2, fw, detect_thread);
167  return 2;
168  }
169  return 1;
170 }
171 
172 /** \param[in] max_work Max flows to process. 0 if unlimited. */
173 static void CheckWorkQueue(ThreadVars *tv, FlowWorkerThreadData *fw,
174  void *detect_thread, // TODO proper type?
175  FlowTimeoutCounters *counters, FlowQueuePrivate *fq, const uint32_t max_work)
176 {
177  uint32_t i = 0;
178  Flow *f;
179  while ((f = FlowQueuePrivateGetFromTop(fq)) != NULL) {
180  FLOWLOCK_WRLOCK(f);
181  f->flow_end_flags |= FLOW_END_FLAG_TIMEOUT; //TODO emerg
182 
183  if (f->proto == IPPROTO_TCP) {
184  if (!(f->flags & FLOW_TIMEOUT_REASSEMBLY_DONE) && !FlowIsBypassed(f) &&
185  FlowForceReassemblyNeedReassembly(f) == 1 && f->ffr != 0) {
186  int cnt = FlowFinish(tv, f, fw, detect_thread);
187  counters->flows_aside_pkt_inject += cnt;
188  counters->flows_aside_needs_work++;
189  }
190  }
191 
192  /* no one is referring to this flow, removed from hash
193  * so we can unlock it and pass it to the flow recycler */
194 
195  if (fw->output_thread_flow != NULL)
196  (void)OutputFlowLog(tv, fw->output_thread_flow, f);
197 
198  FlowEndCountersUpdate(tv, &fw->fec, f);
199  if (f->proto == IPPROTO_TCP && f->protoctx != NULL) {
201  }
203 
204  FlowClearMemory (f, f->protomap);
205  FLOWLOCK_UNLOCK(f);
206 
207  if (fw->fls.spare_queue.len >= 200) { // TODO match to API? 200 = 2 * block size
209  } else {
211  }
212 
213  if (max_work != 0 && ++i == max_work)
214  break;
215  }
216 }
217 
218 /** \brief handle flow for packet
219  *
220  * Handle flow creation/lookup
221  */
222 static inline TmEcode FlowUpdate(ThreadVars *tv, FlowWorkerThreadData *fw, Packet *p)
223 {
224  FlowHandlePacketUpdate(p->flow, p, tv, fw->dtv);
225 
226  int state = p->flow->flow_state;
227  switch (state) {
228 #ifdef CAPTURE_OFFLOAD
229  case FLOW_STATE_CAPTURE_BYPASSED: {
232  Flow *f = p->flow;
233  FlowDeReference(&p->flow);
234  FLOWLOCK_UNLOCK(f);
235  return TM_ECODE_DONE;
236  }
237 #endif
241  Flow *f = p->flow;
242  FlowDeReference(&p->flow);
243  FLOWLOCK_UNLOCK(f);
244  return TM_ECODE_DONE;
245  }
246  default:
247  return TM_ECODE_OK;
248  }
249 }
250 
251 static TmEcode FlowWorkerThreadDeinit(ThreadVars *tv, void *data);
252 
253 static TmEcode FlowWorkerThreadInit(ThreadVars *tv, const void *initdata, void **data)
254 {
255  FlowWorkerThreadData *fw = SCCalloc(1, sizeof(*fw));
256  if (fw == NULL)
257  return TM_ECODE_FAILED;
258 
259  SC_ATOMIC_INITPTR(fw->detect_thread);
260  SC_ATOMIC_SET(fw->detect_thread, NULL);
261 
262  fw->local_bypass_pkts = StatsRegisterCounter("flow_bypassed.local_pkts", tv);
263  fw->local_bypass_bytes = StatsRegisterCounter("flow_bypassed.local_bytes", tv);
264  fw->both_bypass_pkts = StatsRegisterCounter("flow_bypassed.local_capture_pkts", tv);
265  fw->both_bypass_bytes = StatsRegisterCounter("flow_bypassed.local_capture_bytes", tv);
266 
267  fw->cnt.flows_aside_needs_work = StatsRegisterCounter("flow.wrk.flows_evicted_needs_work", tv);
268  fw->cnt.flows_aside_pkt_inject = StatsRegisterCounter("flow.wrk.flows_evicted_pkt_inject", tv);
269  fw->cnt.flows_removed = StatsRegisterCounter("flow.wrk.flows_evicted", tv);
270  fw->cnt.flows_injected = StatsRegisterCounter("flow.wrk.flows_injected", tv);
271  fw->cnt.flows_injected_max = StatsRegisterMaxCounter("flow.wrk.flows_injected_max", tv);
272 
273  fw->fls.dtv = fw->dtv = DecodeThreadVarsAlloc(tv);
274  if (fw->dtv == NULL) {
275  FlowWorkerThreadDeinit(tv, fw);
276  return TM_ECODE_FAILED;
277  }
278 
279  /* setup TCP */
280  if (StreamTcpThreadInit(tv, NULL, &fw->stream_thread_ptr) != TM_ECODE_OK) {
281  FlowWorkerThreadDeinit(tv, fw);
282  return TM_ECODE_FAILED;
283  }
284 
285  if (DetectEngineEnabled()) {
286  /* setup DETECT */
287  void *detect_thread = NULL;
288  if (DetectEngineThreadCtxInit(tv, NULL, &detect_thread) != TM_ECODE_OK) {
289  FlowWorkerThreadDeinit(tv, fw);
290  return TM_ECODE_FAILED;
291  }
292  SC_ATOMIC_SET(fw->detect_thread, detect_thread);
293  }
294 
295  /* Setup outputs for this thread. */
296  if (OutputLoggerThreadInit(tv, initdata, &fw->output_thread) != TM_ECODE_OK) {
297  FlowWorkerThreadDeinit(tv, fw);
298  return TM_ECODE_FAILED;
299  }
301  SCLogError("initializing flow log API for thread failed");
302  FlowWorkerThreadDeinit(tv, fw);
303  return TM_ECODE_FAILED;
304  }
305 
309 
310  /* setup pq for stream end pkts */
311  memset(&fw->pq, 0, sizeof(PacketQueueNoLock));
312  *data = fw;
313  return TM_ECODE_OK;
314 }
315 
316 static TmEcode FlowWorkerThreadDeinit(ThreadVars *tv, void *data)
317 {
318  FlowWorkerThreadData *fw = data;
319 
321 
322  /* free TCP */
323  StreamTcpThreadDeinit(tv, (void *)fw->stream_thread);
324 
325  /* free DETECT */
326  void *detect_thread = SC_ATOMIC_GET(fw->detect_thread);
327  if (detect_thread != NULL) {
328  DetectEngineThreadCtxDeinit(tv, detect_thread);
329  SC_ATOMIC_SET(fw->detect_thread, NULL);
330  }
331 
332  /* Free output. */
335 
336  /* free pq */
337  BUG_ON(fw->pq.len);
338 
339  Flow *f;
340  while ((f = FlowQueuePrivateGetFromTop(&fw->fls.spare_queue)) != NULL) {
341  FlowFree(f);
342  }
343 
344  SCFree(fw);
345  return TM_ECODE_OK;
346 }
347 
348 TmEcode Detect(ThreadVars *tv, Packet *p, void *data);
350 
351 static inline void UpdateCounters(ThreadVars *tv,
352  FlowWorkerThreadData *fw, const FlowTimeoutCounters *counters)
353 {
354  if (counters->flows_aside_needs_work) {
356  (uint64_t)counters->flows_aside_needs_work);
357  }
358  if (counters->flows_aside_pkt_inject) {
360  (uint64_t)counters->flows_aside_pkt_inject);
361  }
362 }
363 
364 /** \brief update stream engine
365  *
366  * We can be called from both the flow timeout path as well as from the
367  * "real" traffic path. If in the timeout path any additional packets we
368  * forge for flushing pipelines should not leave our scope. If the original
369  * packet is real (or related to a real packet) we need to push the packets
370  * on, so IPS logic stays valid.
371  */
372 static inline void FlowWorkerStreamTCPUpdate(ThreadVars *tv, FlowWorkerThreadData *fw, Packet *p,
373  void *detect_thread, const bool timeout)
374 {
376  StreamTcp(tv, p, fw->stream_thread, &fw->pq);
378 
379  if (FlowChangeProto(p->flow)) {
380  StreamTcpDetectLogFlush(tv, fw->stream_thread, p->flow, p, &fw->pq);
383  }
384 
385  /* Packets here can safely access p->flow as it's locked */
386  SCLogDebug("packet %"PRIu64": extra packets %u", p->pcap_cnt, fw->pq.len);
387  Packet *x;
388  while ((x = PacketDequeueNoLock(&fw->pq))) {
389  SCLogDebug("packet %"PRIu64" extra packet %p", p->pcap_cnt, x);
390 
391  if (detect_thread != NULL) {
393  Detect(tv, x, detect_thread);
395  }
396 
398 
399  FramesPrune(x->flow, x);
400  /* Release tcp segments. Done here after alerting can use them. */
403  x->flow, x->flowflags & FLOW_PKT_TOSERVER ? STREAM_TOSERVER : STREAM_TOCLIENT);
405 
406  /* no need to keep a flow ref beyond this point */
407  FlowDeReference(&x->flow);
408 
409  if (timeout) {
411  } else {
412  /* put these packets in the decode queue so that they are processed
413  * by the other thread modules before packet 'p'. */
415  }
416  }
417 }
418 
419 static void FlowWorkerFlowTimeout(ThreadVars *tv, Packet *p, FlowWorkerThreadData *fw,
420  void *detect_thread)
421 {
423 
424  SCLogDebug("packet %"PRIu64" is TCP. Direction %s", p->pcap_cnt, PKT_IS_TOSERVER(p) ? "TOSERVER" : "TOCLIENT");
427 
428  /* handle TCP and app layer */
429  FlowWorkerStreamTCPUpdate(tv, fw, p, detect_thread, true);
430 
432 
433  /* handle Detect */
434  SCLogDebug("packet %"PRIu64" calling Detect", p->pcap_cnt);
435  if (detect_thread != NULL) {
437  Detect(tv, p, detect_thread);
439  }
440 
441  // Outputs.
443 
444  FramesPrune(p->flow, p);
445 
446  /* Release tcp segments. Done here after alerting can use them. */
449  STREAM_TOSERVER : STREAM_TOCLIENT);
451 
452  /* run tx cleanup last */
454 
455  FlowDeReference(&p->flow);
456  /* flow is unlocked later in FlowFinish() */
457 }
458 
459 /** \internal
460  * \brief process flows injected into our queue by other threads
461  */
462 static inline void FlowWorkerProcessInjectedFlows(ThreadVars *tv,
463  FlowWorkerThreadData *fw, Packet *p, void *detect_thread)
464 {
465  /* take injected flows and append to our work queue */
467  FlowQueuePrivate injected = { NULL, NULL, 0 };
468  if (SC_ATOMIC_GET(tv->flow_queue->non_empty) == true)
470  if (injected.len > 0) {
471  StatsAddUI64(tv, fw->cnt.flows_injected, (uint64_t)injected.len);
472  if (p->pkt_src == PKT_SRC_WIRE)
473  StatsSetUI64(tv, fw->cnt.flows_injected_max, (uint64_t)injected.len);
474 
475  /* move to local queue so we can process over the course of multiple packets */
477  }
479 }
480 
481 /** \internal
482  * \brief process flows set aside locally during flow lookup
483  */
484 static inline void FlowWorkerProcessLocalFlows(ThreadVars *tv,
485  FlowWorkerThreadData *fw, Packet *p, void *detect_thread)
486 {
487  uint32_t max_work = 2;
488  if (PKT_IS_PSEUDOPKT(p))
489  max_work = 0;
490 
492  if (fw->fls.work_queue.len) {
493  StatsAddUI64(tv, fw->cnt.flows_removed, (uint64_t)fw->fls.work_queue.len);
494 
495  FlowTimeoutCounters counters = { 0, 0, };
496  CheckWorkQueue(tv, fw, detect_thread, &counters, &fw->fls.work_queue, max_work);
497  UpdateCounters(tv, fw, &counters);
498  }
500 }
501 
502 static TmEcode FlowWorker(ThreadVars *tv, Packet *p, void *data)
503 {
504  FlowWorkerThreadData *fw = data;
505  void *detect_thread = SC_ATOMIC_GET(fw->detect_thread);
506 
507  DEBUG_VALIDATE_BUG_ON(p == NULL);
509 
510  SCLogDebug("packet %"PRIu64, p->pcap_cnt);
511 
512  /* update time */
513  if (!(PKT_IS_PSEUDOPKT(p))) {
514  TimeSetByThread(tv->id, p->ts);
515  }
516 
517  /* handle Flow */
518  if (p->flags & PKT_WANTS_FLOW) {
520 
521  FlowHandlePacket(tv, &fw->fls, p);
522  if (likely(p->flow != NULL)) {
524  if (FlowUpdate(tv, fw, p) == TM_ECODE_DONE) {
525  goto housekeeping;
526  }
527  }
528  /* Flow is now LOCKED */
529 
531 
532  /* if PKT_WANTS_FLOW is not set, but PKT_HAS_FLOW is, then this is a
533  * pseudo packet created by the flow manager. */
534  } else if (p->flags & PKT_HAS_FLOW) {
535  FLOWLOCK_WRLOCK(p->flow);
537  }
538 
539  SCLogDebug("packet %"PRIu64" has flow? %s", p->pcap_cnt, p->flow ? "yes" : "no");
540 
541  /* handle TCP and app layer */
542  if (p->flow && PKT_IS_TCP(p)) {
543  SCLogDebug("packet %"PRIu64" is TCP. Direction %s", p->pcap_cnt, PKT_IS_TOSERVER(p) ? "TOSERVER" : "TOCLIENT");
545 
546  /* if detect is disabled, we need to apply file flags to the flow
547  * here on the first packet. */
548  if (detect_thread == NULL &&
551  {
553  }
554 
555  FlowWorkerStreamTCPUpdate(tv, fw, p, detect_thread, false);
556 
557  /* handle the app layer part of the UDP packet payload */
558  } else if (p->flow && p->proto == IPPROTO_UDP) {
562  }
563 
565 
566  /* handle Detect */
568  SCLogDebug("packet %"PRIu64" calling Detect", p->pcap_cnt);
569  if (detect_thread != NULL) {
571  Detect(tv, p, detect_thread);
573  }
574 
575  // Outputs.
577 
578  /* Release tcp segments. Done here after alerting can use them. */
579  if (p->flow != NULL) {
581 
582  if (FlowIsBypassed(p->flow)) {
584  if (p->proto == IPPROTO_TCP) {
586  }
587  } else if (p->proto == IPPROTO_TCP && p->flow->protoctx) {
588  FramesPrune(p->flow, p);
591  STREAM_TOSERVER : STREAM_TOCLIENT);
593  } else if (p->proto == IPPROTO_UDP) {
594  FramesPrune(p->flow, p);
595  }
596 
597  if ((PKT_IS_PSEUDOPKT(p)) || ((p->flags & PKT_APPLAYER_UPDATE) != 0)) {
598  SCLogDebug("pseudo or app update: run cleanup");
599  /* run tx cleanup last */
601  } else {
602  SCLogDebug("not pseudo, no app update: skip");
603  }
604  Flow *f = p->flow;
605  FlowDeReference(&p->flow);
606  FLOWLOCK_UNLOCK(f);
607  }
608 
609 housekeeping:
610 
611  /* take injected flows and add them to our local queue */
612  FlowWorkerProcessInjectedFlows(tv, fw, p, detect_thread);
613 
614  /* process local work queue */
615  FlowWorkerProcessLocalFlows(tv, fw, p, detect_thread);
616 
617  return TM_ECODE_OK;
618 }
619 
620 void FlowWorkerReplaceDetectCtx(void *flow_worker, void *detect_ctx)
621 {
622  FlowWorkerThreadData *fw = flow_worker;
623 
624  SC_ATOMIC_SET(fw->detect_thread, detect_ctx);
625 }
626 
627 void *FlowWorkerGetDetectCtxPtr(void *flow_worker)
628 {
629  FlowWorkerThreadData *fw = flow_worker;
630 
631  return SC_ATOMIC_GET(fw->detect_thread);
632 }
633 
635 {
636  switch (fwi) {
638  return "flow";
640  return "stream";
642  return "app-layer";
644  return "detect";
646  return "tcp-prune";
648  return "flow-inject";
650  return "flow-evict";
652  return "size";
653  }
654  return "error";
655 }
656 
657 static void FlowWorkerExitPrintStats(ThreadVars *tv, void *data)
658 {
659  FlowWorkerThreadData *fw = data;
661 }
662 
664 {
665  tmm_modules[TMM_FLOWWORKER].name = "FlowWorker";
666  tmm_modules[TMM_FLOWWORKER].ThreadInit = FlowWorkerThreadInit;
667  tmm_modules[TMM_FLOWWORKER].Func = FlowWorker;
668  tmm_modules[TMM_FLOWWORKER].ThreadDeinit = FlowWorkerThreadDeinit;
669  tmm_modules[TMM_FLOWWORKER].ThreadExitPrintStats = FlowWorkerExitPrintStats;
672 }
PKT_IS_TOCLIENT
#define PKT_IS_TOCLIENT(p)
Definition: decode.h:252
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:67
Flow_::ffr_tc
uint8_t ffr_tc
Definition: flow.h:389
FlowLookupStruct_::work_queue
FlowQueuePrivate work_queue
Definition: flow.h:547
ThreadVars_::flow_queue
struct FlowQueue_ * flow_queue
Definition: threadvars.h:134
OutputFlowLog
TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
Run flow logger(s)
Definition: output-flow.c:86
Packet_::proto
uint8_t proto
Definition: decode.h:450
FlowCleanupAppLayer
void FlowCleanupAppLayer(Flow *f)
Definition: flow.c:143
FlowTimeoutCounters
Definition: flow-worker.c:59
detect-engine.h
Flow_::ffr_ts
uint8_t ffr_ts
Definition: flow.h:388
PROFILE_FLOWWORKER_DETECT
@ PROFILE_FLOWWORKER_DETECT
Definition: flow-worker.h:25
DecodeThreadVars_::counter_flow_active
uint16_t counter_flow_active
Definition: decode.h:723
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1003
FlowSparePoolReturnFlow
void FlowSparePoolReturnFlow(Flow *f)
Definition: flow-spare-pool.c:100
PROFILE_FLOWWORKER_FLOW_INJECTED
@ PROFILE_FLOWWORKER_FLOW_INJECTED
Definition: flow-worker.h:27
flow-util.h
FlowWorkerThreadData
struct FlowWorkerThreadData_ FlowWorkerThreadData
FlowLookupStruct_::dtv
DecodeThreadVars * dtv
Definition: flow.h:546
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1059
stream-tcp.h
PacketPoolReturnPacket
void PacketPoolReturnPacket(Packet *p)
Return packet to Packet pool.
Definition: tmqh-packetpool.c:207
FLOW_PKT_LAST_PSEUDO
#define FLOW_PKT_LAST_PSEUDO
Definition: flow.h:236
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:387
AppLayerParserTransactionsCleanup
void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir)
remove obsolete (inspected and logged) transactions
Definition: app-layer-parser.c:921
PROFILE_FLOWWORKER_FLOW_EVICTED
@ PROFILE_FLOWWORKER_FLOW_EVICTED
Definition: flow-worker.h:28
ProfileFlowWorkerIdToString
const char * ProfileFlowWorkerIdToString(enum ProfileFlowWorkerId fwi)
Definition: flow-worker.c:634
OutputLoggerExitPrintStats
void OutputLoggerExitPrintStats(ThreadVars *tv, void *thread_data)
Definition: output.c:947
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:594
StreamTcpThread_
Definition: stream-tcp.h:75
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
Flow_::proto
uint8_t proto
Definition: flow.h:379
TM_ECODE_DONE
@ TM_ECODE_DONE
Definition: tm-threads-common.h:86
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:60
Packet_::flags
uint32_t flags
Definition: decode.h:463
Flow_
Flow data structure.
Definition: flow.h:357
Flow_::protomap
uint8_t protomap
Definition: flow.h:451
StatsSetUI64
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition: counters.c:210
PKT_WANTS_FLOW
#define PKT_WANTS_FLOW
Definition: decode.h:1033
FlowTimeoutCounters::flows_aside_pkt_inject
uint32_t flows_aside_pkt_inject
Definition: flow-worker.c:61
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:1135
FlowLookupStruct_
Definition: flow.h:543
FlowWorkerThreadData_::dtv
DecodeThreadVars * dtv
Definition: flow-worker.c:65
StreamTcpThreadInit
TmEcode StreamTcpThreadInit(ThreadVars *tv, void *initdata, void **data)
Definition: stream-tcp.c:5404
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:227
FlowHandlePacket
void FlowHandlePacket(ThreadVars *tv, FlowLookupStruct *fls, Packet *p)
Entry point for packet flow handling.
Definition: flow.c:527
FlowQueuePrivatePrependFlow
void FlowQueuePrivatePrependFlow(FlowQueuePrivate *fqc, Flow *f)
Definition: flow-queue.c:78
FlowWorkerThreadData_::flows_aside_needs_work
uint16_t flows_aside_needs_work
Definition: flow-worker.c:90
FlowWorkerThreadData_::stream_thread
StreamTcpThread * stream_thread
Definition: flow-worker.c:68
PKT_APPLAYER_UPDATE
#define PKT_APPLAYER_UPDATE
Definition: decode.h:1056
DecodeThreadVars_::counter_tcp_active_sessions
uint16_t counter_tcp_active_sessions
Definition: decode.h:721
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:459
FlowWorkerThreadData_::cnt
struct FlowWorkerThreadData_::@114 cnt
TmqhOutputPacketpool
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
Definition: tmqh-packetpool.c:356
PROFILE_FLOWWORKER_STREAM
@ PROFILE_FLOWWORKER_STREAM
Definition: flow-worker.h:23
APP_LAYER_PARSER_EOF_TS
#define APP_LAYER_PARSER_EOF_TS
Definition: app-layer-parser.h:39
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
FlowQueuePrivate_::len
uint32_t len
Definition: flow-queue.h:44
Flow_::protoctx
void * protoctx
Definition: flow.h:447
OutputLoggerThreadDeinit
TmEcode OutputLoggerThreadDeinit(ThreadVars *tv, void *thread_data)
Definition: output.c:921
DisableDetectFlowFileFlags
void DisableDetectFlowFileFlags(Flow *f)
disable file features we don't need Called if we have no detection engine.
Definition: detect.c:1799
PacketQueueNoLock_
simple fifo queue for packets
Definition: packet-queue.h:34
tmqh-packetpool.h
FLOW_TIMEOUT_REASSEMBLY_DONE
#define FLOW_TIMEOUT_REASSEMBLY_DONE
Definition: flow.h:94
FLOWWORKER_PROFILING_START
#define FLOWWORKER_PROFILING_START(p, id)
Definition: util-profiling.h:167
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:272
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
Flow_::flow_state
FlowStateType flow_state
Definition: flow.h:418
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1062
PKT_IS_TCP
#define PKT_IS_TCP(p)
Definition: decode.h:247
flow-spare-pool.h
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:481
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:526
DetectEngineThreadCtxPtr
DetectEngineThreadCtx * DetectEngineThreadCtxPtr
Definition: flow-worker.c:57
StatsDecr
void StatsDecr(ThreadVars *tv, uint16_t id)
Decrements the local counter.
Definition: counters.c:188
StatsRegisterMaxCounter
uint16_t StatsRegisterMaxCounter(const char *name, struct ThreadVars_ *tv)
Registers a counter, whose value holds the maximum of all the values assigned to it.
Definition: counters.c:995
FlowWorkerThreadData_::flows_aside_pkt_inject
uint16_t flows_aside_pkt_inject
Definition: flow-worker.c:91
FLOW_STATE_LOCAL_BYPASSED
@ FLOW_STATE_LOCAL_BYPASSED
Definition: flow.h:508
decode.h
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:54
PKT_IS_TOSERVER
#define PKT_IS_TOSERVER(p)
Definition: decode.h:251
DetectEngineThreadCtx_
Definition: detect.h:1025
FlowWorkerThreadData_::flows_injected
uint16_t flows_injected
Definition: flow-worker.c:87
Packet_::ts
SCTime_t ts
Definition: decode.h:471
OutputFlowLogThreadInit
TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void *initdata, void **data)
thread init for the flow logger This will run the thread init functions for the individual registered...
Definition: output-flow.c:124
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:78
FlowTimeoutCounters
struct FlowTimeoutCounters FlowTimeoutCounters
FlowHandlePacketUpdate
void FlowHandlePacketUpdate(Flow *f, Packet *p, ThreadVars *tv, DecodeThreadVars *dtv)
Update Packet and Flow.
Definition: flow.c:410
flow-worker.h
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:269
STREAM_FLAGS_FOR_PACKET
#define STREAM_FLAGS_FOR_PACKET(p)
Definition: stream.h:30
FlowForceReassemblyNeedReassembly
int FlowForceReassemblyNeedReassembly(Flow *f)
Check if a flow needs forced reassembly, or any other processing.
Definition: flow-timeout.c:295
StreamTcp
TmEcode StreamTcp(ThreadVars *, Packet *, void *, PacketQueueNoLock *pq)
Definition: stream-tcp.c:5362
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
DetectEngineEnabled
int DetectEngineEnabled(void)
Check if detection is enabled.
Definition: detect-engine.c:3577
Flow_::flow_end_flags
uint8_t flow_end_flags
Definition: flow.h:453
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
FLOW_PKT_TOCLIENT_FIRST
#define FLOW_PKT_TOCLIENT_FIRST
Definition: flow.h:233
FlowWorkerThreadData_::local_bypass_pkts
uint16_t local_bypass_pkts
Definition: flow-worker.c:77
PROFILE_FLOWWORKER_APPLAYERUDP
@ PROFILE_FLOWWORKER_APPLAYERUDP
Definition: flow-worker.h:24
util-time.h
FlowQueuePrivateGetFromTop
Flow * FlowQueuePrivateGetFromTop(FlowQueuePrivate *fqc)
Definition: flow-queue.c:151
FLOWWORKER_PROFILING_END
#define FLOWWORKER_PROFILING_END(p, id)
Definition: util-profiling.h:174
StreamTcpPruneSession
void StreamTcpPruneSession(Flow *f, uint8_t flags)
Remove idle TcpSegments from TcpSession.
Definition: stream-tcp-list.c:888
OutputLoggerThreadInit
TmEcode OutputLoggerThreadInit(ThreadVars *tv, const void *initdata, void **data)
Definition: output.c:890
app-layer-parser.h
ThreadVars_::id
int id
Definition: threadvars.h:86
STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION
@ STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION
Definition: stream-tcp.h:185
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:289
util-profiling.h
Packet_
Definition: decode.h:428
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:218
APP_LAYER_PARSER_EOF_TC
#define APP_LAYER_PARSER_EOF_TC
Definition: app-layer-parser.h:40
AppLayerHandleUdp
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
Handle a app layer UDP message.
Definition: app-layer.c:809
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:108
TmEcode
TmEcode
Definition: tm-threads-common.h:83
FlowClearMemory
int FlowClearMemory(Flow *f, uint8_t proto_map)
Function clear the flow memory before queueing it to spare flow queue.
Definition: flow.c:1107
TmModuleFlowWorkerRegister
void TmModuleFlowWorkerRegister(void)
Definition: flow-worker.c:663
FlowQueuePrivateAppendPrivate
void FlowQueuePrivateAppendPrivate(FlowQueuePrivate *dest, FlowQueuePrivate *src)
Definition: flow-queue.c:88
flow-timeout.h
TimeSetByThread
void TimeSetByThread(const int thread_id, SCTime_t tv)
Definition: util-time.c:116
TmModule_::name
const char * name
Definition: tm-modules.h:44
FlowLookupStruct_::spare_queue
FlowQueuePrivate spare_queue
Definition: flow.h:545
TMM_FLOWWORKER
@ TMM_FLOWWORKER
Definition: tm-threads-common.h:34
Flow_::ffr
uint8_t ffr
Definition: flow.h:391
AppLayerParserStateSetFlag
void AppLayerParserStateSetFlag(AppLayerParserState *pstate, uint16_t flag)
Definition: app-layer-parser.c:1814
FlowWorkerGetDetectCtxPtr
void * FlowWorkerGetDetectCtxPtr(void *flow_worker)
Definition: flow-worker.c:627
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:167
FlowWorkerThreadData_::stream_thread_ptr
void * stream_thread_ptr
Definition: flow-worker.c:69
FlowQueueExtractPrivate
FlowQueuePrivate FlowQueueExtractPrivate(FlowQueue *fq)
Definition: flow-queue.c:140
FlowWorkerThreadData_::pq
PacketQueueNoLock pq
Definition: flow-worker.c:83
app-layer-frames.h
FlowWorkerThreadData_::flows_removed
uint16_t flows_removed
Definition: flow-worker.c:89
Packet_::flow
struct Flow_ * flow
Definition: decode.h:465
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3153
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:708
flow-manager.h
suricata-common.h
PKT_SRC_FFR
@ PKT_SRC_FFR
Definition: decode.h:60
FlowFree
void FlowFree(Flow *f)
cleanup & free the memory of a flow
Definition: flow-util.c:83
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3367
PROFILE_FLOWWORKER_SIZE
@ PROFILE_FLOWWORKER_SIZE
Definition: flow-worker.h:29
FlowWorkerThreadData_::both_bypass_bytes
uint16_t both_bypass_bytes
Definition: flow-worker.c:80
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:154
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
Detect
TmEcode Detect(ThreadVars *tv, Packet *p, void *data)
Detection engine thread wrapper.
Definition: detect.c:1741
util-validate.h
FlowQueuePrivate_
Definition: flow-queue.h:41
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:6347
PacketQueueNoLock_::len
uint32_t len
Definition: packet-queue.h:37
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:146
FlowWorkerThreadData_::output_thread_flow
void * output_thread_flow
Definition: flow-worker.c:75
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
OutputFlowLogThreadDeinit
TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data)
Definition: output-flow.c:166
FramesPrune
void FramesPrune(Flow *f, Packet *p)
Definition: app-layer-frames.c:763
OutputLoggerLog
TmEcode OutputLoggerLog(ThreadVars *tv, Packet *p, void *thread_data)
Definition: output.c:876
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Packet_::pkt_src
uint8_t pkt_src
Definition: decode.h:579
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:664
Flow_::flags
uint32_t flags
Definition: flow.h:427
StreamTcpSessionCleanup
void StreamTcpSessionCleanup(TcpSession *ssn)
Session cleanup function. Does not free the ssn.
Definition: stream-tcp.c:211
FlowWorkerThreadData_::fls
FlowLookupStruct fls
Definition: flow-worker.c:84
SC_ATOMIC_INITPTR
#define SC_ATOMIC_INITPTR(name)
Definition: util-atomic.h:318
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:689
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:111
PROFILE_FLOWWORKER_FLOW
@ PROFILE_FLOWWORKER_FLOW
Definition: flow-worker.h:22
StreamTcpThread_::ra_ctx
TcpReassemblyThreadCtx * ra_ctx
Definition: stream-tcp.h:111
suricata.h
FLOW_END_FLAG_TIMEOUT
#define FLOW_END_FLAG_TIMEOUT
Definition: flow.h:242
FlowWorkerThreadData_::fec
FlowEndCounters fec
Definition: flow-worker.c:93
likely
#define likely(expr)
Definition: util-optimize.h:32
FlowWorkerThreadData_::output_thread
void * output_thread
Definition: flow-worker.c:74
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:230
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
TcpSession_
Definition: stream-tcp-private.h:272
FlowEndCountersRegister
void FlowEndCountersRegister(ThreadVars *t, FlowEndCounters *fec)
Definition: flow-util.c:242
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:955
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
FlowEndCounters_
Definition: flow-util.h:157
FLOW_PKT_TOSERVER_FIRST
#define FLOW_PKT_TOSERVER_FIRST
Definition: flow.h:232
FlowWorkerThreadData_::both_bypass_pkts
uint16_t both_bypass_pkts
Definition: flow-worker.c:79
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
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:64
StreamTcpThreadDeinit
TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data)
Definition: stream-tcp.c:5476
output.h
FlowWorkerThreadData_::flows_injected_max
uint16_t flows_injected_max
Definition: flow-worker.c:88
FlowWorkerReplaceDetectCtx
void FlowWorkerReplaceDetectCtx(void *flow_worker, void *detect_ctx)
Definition: flow-worker.c:620
app-layer.h
FlowForceReassemblyPseudoPacketGet
Packet * FlowForceReassemblyPseudoPacketGet(int direction, Flow *f, TcpSession *ssn)
Definition: flow-timeout.c:272
FlowTimeoutCounters::flows_aside_needs_work
uint32_t flows_aside_needs_work
Definition: flow-worker.c:60