suricata
flow-manager.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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  * \author Victor Julien <victor@inliniac.net>
23  */
24 
25 #include "suricata-common.h"
26 #include "conf.h"
27 #include "threadvars.h"
28 #include "tm-threads.h"
29 #include "runmodes.h"
30 
31 #include "util-time.h"
32 
33 #include "flow.h"
34 #include "flow-queue.h"
35 #include "flow-hash.h"
36 #include "flow-util.h"
37 #include "flow-private.h"
38 #include "flow-timeout.h"
39 #include "flow-manager.h"
40 #include "flow-storage.h"
41 #include "flow-spare-pool.h"
42 #include "flow-callbacks.h"
43 
44 #include "stream-tcp.h"
45 #include "stream-tcp-cache.h"
46 
47 #include "util-device-private.h"
48 
49 #include "util-debug.h"
50 
51 #include "threads.h"
53 
54 #include "host-timeout.h"
55 #include "defrag-hash.h"
56 #include "defrag-timeout.h"
57 #include "ippair-timeout.h"
58 #include "app-layer-htp-range.h"
59 
60 #include "output-flow.h"
61 
62 #include "runmode-unix-socket.h"
63 
64 /** queue to pass flows to cleanup/log thread(s) */
66 
67 /* multi flow manager support */
68 static uint32_t flowmgr_number = 1;
69 /* atomic counter for flow managers, to assign instance id */
70 SC_ATOMIC_DECLARE(uint32_t, flowmgr_cnt);
71 
72 /* multi flow recycler support */
73 static uint32_t flowrec_number = 1;
74 /* atomic counter for flow recyclers, to assign instance id */
75 SC_ATOMIC_DECLARE(uint32_t, flowrec_cnt);
76 SC_ATOMIC_DECLARE(uint32_t, flowrec_busy);
77 SC_ATOMIC_EXTERN(unsigned int, flow_flags);
78 
79 static SCCtrlCondT flow_manager_ctrl_cond = PTHREAD_COND_INITIALIZER;
80 static SCCtrlMutex flow_manager_ctrl_mutex = PTHREAD_MUTEX_INITIALIZER;
81 static SCCtrlCondT flow_recycler_ctrl_cond = PTHREAD_COND_INITIALIZER;
82 static SCCtrlMutex flow_recycler_ctrl_mutex = PTHREAD_MUTEX_INITIALIZER;
83 
85 {
86  SCCtrlMutexLock(&flow_manager_ctrl_mutex);
87  SCCtrlCondSignal(&flow_manager_ctrl_cond);
88  SCCtrlMutexUnlock(&flow_manager_ctrl_mutex);
89 }
90 
92 {
93  SCCtrlMutexLock(&flow_recycler_ctrl_mutex);
94  SCCtrlCondSignal(&flow_recycler_ctrl_cond);
95  SCCtrlMutexUnlock(&flow_recycler_ctrl_mutex);
96 }
97 
98 void FlowTimeoutsInit(void)
99 {
100  SC_ATOMIC_SET(flow_timeouts, flow_timeouts_normal);
101 }
102 
104 {
105  SC_ATOMIC_SET(flow_timeouts, flow_timeouts_emerg);
106 }
107 
108 typedef struct FlowTimeoutCounters_ {
109  uint32_t rows_checked;
110  uint32_t rows_skipped;
111  uint32_t rows_empty;
112  uint32_t rows_maxlen;
113 
114  uint32_t flows_checked;
115  uint32_t flows_notimeout;
116  uint32_t flows_timeout;
117  uint32_t flows_removed;
118  uint32_t flows_aside;
120 
121  uint32_t bypassed_count;
122  uint64_t bypassed_pkts;
123  uint64_t bypassed_bytes;
125 
126 /**
127  * \brief Used to disable flow manager thread(s).
128  *
129  * \todo Kinda hackish since it uses the tv name to identify flow manager
130  * thread. We need an all weather identification scheme.
131  */
133 {
135  /* flow manager thread(s) is/are a part of mgmt threads */
136  for (ThreadVars *tv = tv_root[TVT_MGMT]; tv != NULL; tv = tv->next) {
137  if (strncasecmp(tv->name, thread_name_flow_mgr,
138  strlen(thread_name_flow_mgr)) == 0)
139  {
141  }
142  }
144 
145  struct timeval start_ts;
146  struct timeval cur_ts;
147  gettimeofday(&start_ts, NULL);
148 
149 again:
150  gettimeofday(&cur_ts, NULL);
151  if ((cur_ts.tv_sec - start_ts.tv_sec) > 60) {
152  FatalError("unable to get all flow manager "
153  "threads to shutdown in time");
154  }
155 
157  for (ThreadVars *tv = tv_root[TVT_MGMT]; tv != NULL; tv = tv->next) {
158  if (strncasecmp(tv->name, thread_name_flow_mgr,
159  strlen(thread_name_flow_mgr)) == 0)
160  {
163  /* sleep outside lock */
164  SleepMsec(1);
165  goto again;
166  }
167  }
168  }
170 
171  /* reset count, so we can kill and respawn (unix socket) */
172  SC_ATOMIC_SET(flowmgr_cnt, 0);
173 }
174 
175 /** \internal
176  * \brief check if a flow is timed out
177  *
178  * Takes lastts, adds the timeout policy to it, compared to current time `ts`.
179  * In case of emergency mode, timeout_policy is ignored and the emerg table
180  * is used.
181  *
182  * \param f flow
183  * \param ts timestamp - realtime or a minimum of active threads in offline mode
184  * \param next_ts tracking the next timeout ts, so FM can skip the row until that time
185  * \param emerg bool to indicate if emergency timeout settings should be used
186  *
187  * \retval false not timed out
188  * \retval true timed out
189  */
190 static bool FlowManagerFlowTimeout(Flow *f, SCTime_t ts, uint32_t *next_ts, const bool emerg)
191 {
192  SCTime_t timesout_at;
193 
194  if (emerg) {
196  timesout_at = SCTIME_ADD_SECS(f->lastts,
197  FlowGetFlowTimeoutDirect(flow_timeouts_emerg, f->flow_state, f->protomap));
198  } else {
199  timesout_at = SCTIME_ADD_SECS(f->lastts, f->timeout_policy);
200  }
201  /* update next_ts if needed */
202  if (*next_ts == 0 || (uint32_t)SCTIME_SECS(timesout_at) < *next_ts)
203  *next_ts = (uint32_t)SCTIME_SECS(timesout_at);
204 
205  /* if time is live, we just use the `ts` */
206  if (TimeModeIsLive() || f->thread_id[0] == 0) {
207  /* do the timeout check */
208  if (SCTIME_CMP_LT(ts, timesout_at)) {
209  return false;
210  }
211  } else {
212  /* offline: take last ts from "owning" thread */
213  SCTime_t checkts = TmThreadsGetThreadTime(f->thread_id[0]);
214  /* do the timeout check */
215  if (SCTIME_CMP_LT(checkts, timesout_at)) {
216  return false;
217  }
218  }
219 
220  return true;
221 }
222 
223 #ifdef CAPTURE_OFFLOAD
224 /** \internal
225  * \brief check timeout of captured bypassed flow by querying capture method
226  *
227  * \param f Flow
228  * \param ts timestamp
229  * \param counters Flow timeout counters
230  *
231  * \retval false not timeout
232  * \retval true timeout (or not capture bypassed)
233  */
234 static inline bool FlowBypassedTimeout(Flow *f, SCTime_t ts, FlowTimeoutCounters *counters)
235 {
236  if (f->flow_state != FLOW_STATE_CAPTURE_BYPASSED) {
237  return true;
238  }
239 
241  if (fc && fc->BypassUpdate) {
242  /* flow will be possibly updated */
243  uint64_t pkts_tosrc = fc->tosrcpktcnt;
244  uint64_t bytes_tosrc = fc->tosrcbytecnt;
245  uint64_t pkts_todst = fc->todstpktcnt;
246  uint64_t bytes_todst = fc->todstbytecnt;
247  bool update = fc->BypassUpdate(f, fc->bypass_data, SCTIME_SECS(ts));
248  if (update) {
249  SCLogDebug("Updated flow: %"PRId64"", FlowGetId(f));
250  pkts_tosrc = fc->tosrcpktcnt - pkts_tosrc;
251  bytes_tosrc = fc->tosrcbytecnt - bytes_tosrc;
252  pkts_todst = fc->todstpktcnt - pkts_todst;
253  bytes_todst = fc->todstbytecnt - bytes_todst;
254  if (f->livedev) {
255  SC_ATOMIC_ADD(f->livedev->bypassed,
256  pkts_tosrc + pkts_todst);
257  }
258  counters->bypassed_pkts += pkts_tosrc + pkts_todst;
259  counters->bypassed_bytes += bytes_tosrc + bytes_todst;
260  return false;
261  }
262  SCLogDebug("No new packet, dead flow %" PRId64 "", FlowGetId(f));
263  if (f->livedev) {
264  if (FLOW_IS_IPV4(f)) {
265  LiveDevSubBypassStats(f->livedev, 1, AF_INET);
266  } else if (FLOW_IS_IPV6(f)) {
267  LiveDevSubBypassStats(f->livedev, 1, AF_INET6);
268  }
269  }
270  counters->bypassed_count++;
271  }
272  return true;
273 }
274 #endif /* CAPTURE_OFFLOAD */
275 
276 typedef struct FlowManagerTimeoutThread {
277  /* used to temporarily store flows that have timed out and are
278  * removed from the hash to reduce locking contention */
281 
282 /**
283  * \internal
284  *
285  * \brief Process the temporary Aside Queue
286  * This means that as long as a flow f is not waiting on detection
287  * engine to finish dealing with it, f will be put in the recycle
288  * queue for further processing later on.
289  *
290  * \param td FM Timeout Thread instance
291  * \param counters Flow Timeout counters to be updated
292  *
293  * \retval Number of flows that were recycled
294  */
295 static uint32_t ProcessAsideQueue(FlowManagerTimeoutThread *td, FlowTimeoutCounters *counters)
296 {
297  FlowQueuePrivate recycle = { NULL, NULL, 0 };
298  counters->flows_aside += td->aside_queue.len;
299 
300  uint32_t cnt = 0;
301  Flow *f;
302  while ((f = FlowQueuePrivateGetFromTop(&td->aside_queue)) != NULL) {
303  /* flow is still locked */
304 
305  if (f->proto == IPPROTO_TCP &&
307  !FlowIsBypassed(f) && FlowNeedsReassembly(f)) {
308  /* Send the flow to its thread */
310  FLOWLOCK_UNLOCK(f);
311  /* flow ownership is already passed to the worker thread */
312 
313  counters->flows_aside_needs_work++;
314  continue;
315  }
316  FLOWLOCK_UNLOCK(f);
317 
318  FlowQueuePrivateAppendFlow(&recycle, f);
319  if (recycle.len == 100) {
322  }
323  cnt++;
324  }
325  if (recycle.len) {
328  }
329  return cnt;
330 }
331 
332 /**
333  * \internal
334  *
335  * \brief check all flows in a hash row for timing out
336  *
337  * \param f last flow in the hash row
338  * \param ts timestamp
339  * \param emergency bool indicating emergency mode
340  * \param counters ptr to FlowTimeoutCounters structure
341  */
342 static void FlowManagerHashRowTimeout(FlowManagerTimeoutThread *td, Flow *f, SCTime_t ts,
343  int emergency, FlowTimeoutCounters *counters, uint32_t *next_ts)
344 {
345  uint32_t checked = 0;
346  Flow *prev_f = NULL;
347 
348  do {
349  checked++;
350 
351  FLOWLOCK_WRLOCK(f);
352 
353  /* check flow timeout based on lastts and state. Both can be
354  * accessed w/o Flow lock as we do have the hash row lock (so flow
355  * can't disappear) and flow_state is atomic. lastts can only
356  * be modified when we have both the flow and hash row lock */
357 
358  /* timeout logic goes here */
359  if (!FlowManagerFlowTimeout(f, ts, next_ts, emergency)) {
360  FLOWLOCK_UNLOCK(f);
361  counters->flows_notimeout++;
362 
363  prev_f = f;
364  f = f->next;
365  continue;
366  }
367 
368  Flow *next_flow = f->next;
369 
370 #ifdef CAPTURE_OFFLOAD
371  /* never prune a flow that is used by a packet we
372  * are currently processing in one of the threads */
373  if (!FlowBypassedTimeout(f, ts, counters)) {
374  FLOWLOCK_UNLOCK(f);
375  prev_f = f;
376  f = f->next;
377  continue;
378  }
379 #endif
381 
382  counters->flows_timeout++;
383 
384  RemoveFromHash(f, prev_f);
385 
387  /* flow is still locked in the queue */
388 
389  f = next_flow;
390  } while (f != NULL);
391 
392  counters->flows_checked += checked;
393  if (checked > counters->rows_maxlen)
394  counters->rows_maxlen = checked;
395 }
396 
397 /**
398  * \internal
399  *
400  * \brief Clear evicted list from Flow Manager.
401  * All the evicted flows are removed from the Flow bucket and added
402  * to the temporary Aside Queue.
403  *
404  * \param td FM timeout thread instance
405  * \param f head of the evicted list
406  */
407 static void FlowManagerHashRowClearEvictedList(FlowManagerTimeoutThread *td, Flow *f)
408 {
409  do {
410  FLOWLOCK_WRLOCK(f);
411  Flow *next_flow = f->next;
412  f->next = NULL;
413  f->fb = NULL;
414 
416  /* flow is still locked in the queue */
417 
418  f = next_flow;
419  } while (f != NULL);
420 }
421 
422 /**
423  * \brief time out flows from the hash
424  *
425  * \param ts timestamp
426  * \param hash_min min hash index to consider
427  * \param hash_max max hash index to consider
428  * \param counters ptr to FlowTimeoutCounters structure
429  *
430  * \retval cnt number of timed out flow
431  */
432 static uint32_t FlowTimeoutHash(FlowManagerTimeoutThread *td, SCTime_t ts, const uint32_t hash_min,
433  const uint32_t hash_max, FlowTimeoutCounters *counters)
434 {
435  uint32_t cnt = 0;
436  const int emergency = ((SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY));
437  const uint32_t rows_checked = hash_max - hash_min;
438  uint32_t rows_skipped = 0;
439  uint32_t rows_empty = 0;
440 
441 #if __WORDSIZE==64
442 #define BITS 64
443 #define TYPE uint64_t
444 #else
445 #define BITS 32
446 #define TYPE uint32_t
447 #endif
448 
449  const uint32_t ts_secs = (uint32_t)SCTIME_SECS(ts);
450  for (uint32_t idx = hash_min; idx < hash_max; idx+=BITS) {
451  TYPE check_bits = 0;
452  const uint32_t check = MIN(BITS, (hash_max - idx));
453  for (uint32_t i = 0; i < check; i++) {
454  FlowBucket *fb = &flow_hash[idx+i];
455  check_bits |= (TYPE)(SC_ATOMIC_LOAD_EXPLICIT(
456  fb->next_ts, SC_ATOMIC_MEMORY_ORDER_RELAXED) <= ts_secs)
457  << (TYPE)i;
458  }
459  if (check_bits == 0)
460  continue;
461 
462  for (uint32_t i = 0; i < check; i++) {
463  FlowBucket *fb = &flow_hash[idx+i];
464  if ((check_bits & ((TYPE)1 << (TYPE)i)) != 0 && SC_ATOMIC_GET(fb->next_ts) <= ts_secs) {
465  FBLOCK_LOCK(fb);
466  Flow *evicted = NULL;
467  if (fb->evicted != NULL || fb->head != NULL) {
468  if (fb->evicted != NULL) {
469  /* transfer out of bucket so we can do additional work outside
470  * of the bucket lock */
471  evicted = fb->evicted;
472  fb->evicted = NULL;
473  }
474  if (fb->head != NULL) {
475  uint32_t next_ts = 0;
476  FlowManagerHashRowTimeout(td, fb->head, ts, emergency, counters, &next_ts);
477 
478  if (SC_ATOMIC_GET(fb->next_ts) != next_ts)
479  SC_ATOMIC_SET(fb->next_ts, next_ts);
480  }
481  if (fb->evicted == NULL && fb->head == NULL) {
482  /* row is empty */
483  SC_ATOMIC_SET(fb->next_ts, UINT_MAX);
484  }
485  } else {
486  SC_ATOMIC_SET(fb->next_ts, UINT_MAX);
487  rows_empty++;
488  }
489  FBLOCK_UNLOCK(fb);
490  /* processed evicted list */
491  if (evicted) {
492  FlowManagerHashRowClearEvictedList(td, evicted);
493  }
494  } else {
495  rows_skipped++;
496  }
497  }
498  if (td->aside_queue.len) {
499  cnt += ProcessAsideQueue(td, counters);
500  }
501  }
502 
503  counters->rows_checked += rows_checked;
504  counters->rows_skipped += rows_skipped;
505  counters->rows_empty += rows_empty;
506 
507  if (td->aside_queue.len) {
508  cnt += ProcessAsideQueue(td, counters);
509  }
510  counters->flows_removed += cnt;
511  /* coverity[missing_unlock : FALSE] */
512  return cnt;
513 }
514 
515 /** \internal
516  *
517  * \brief handle timeout for a slice of hash rows
518  * If we wrap around we call FlowTimeoutHash twice
519  * \param td FM timeout thread
520  * \param ts timeout timestamp
521  * \param hash_min lower bound of the row slice
522  * \param hash_max upper bound of the row slice
523  * \param counters Flow timeout counters to be passed
524  * \param rows number of rows for this worker unit
525  * \param pos absolute position of the beginning of row slice in the hash table
526  * \param instance instance id of this FM
527  *
528  * \retval number of successfully timed out flows
529  */
530 static uint32_t FlowTimeoutHashInChunks(FlowManagerTimeoutThread *td, SCTime_t ts,
531  const uint32_t hash_min, const uint32_t hash_max, FlowTimeoutCounters *counters,
532  const uint32_t rows, uint32_t *pos, const uint32_t instance)
533 {
534  uint32_t start = 0;
535  uint32_t end = 0;
536  uint32_t cnt = 0;
537  uint32_t rows_left = rows;
538 
539 again:
540  start = (*pos);
541  if (start >= hash_max) {
542  start = hash_min;
543  }
544  end = start + rows_left;
545  if (end > hash_max) {
546  end = hash_max;
547  }
548  *pos = (end == hash_max) ? hash_min : end;
549  rows_left = rows_left - (end - start);
550 
551  SCLogDebug("instance %u: %u:%u (hash_min %u, hash_max %u *pos %u)", instance, start, end,
552  hash_min, hash_max, *pos);
553 
554  cnt += FlowTimeoutHash(td, ts, start, end, counters);
555  if (rows_left) {
556  goto again;
557  }
558  return cnt;
559 }
560 
561 /**
562  * \internal
563  *
564  * \brief move all flows out of a hash row
565  *
566  * \param f last flow in the hash row
567  * \param recycle_q Flow recycle queue
568  * \param mode emergency or not
569  *
570  * \retval cnt number of flows removed from the hash and added to the recycle queue
571  */
572 static uint32_t FlowManagerHashRowCleanup(Flow *f, FlowQueuePrivate *recycle_q, const int mode)
573 {
574  uint32_t cnt = 0;
575 
576  do {
577  FLOWLOCK_WRLOCK(f);
578 
579  Flow *next_flow = f->next;
580 
581  /* remove from the hash */
582  if (mode == 0) {
583  RemoveFromHash(f, NULL);
584  } else {
585  FlowBucket *fb = f->fb;
586  fb->evicted = f->next;
587  f->next = NULL;
588  f->fb = NULL;
589  }
591 
592  /* no one is referring to this flow, removed from hash
593  * so we can unlock it and move it to the recycle queue. */
594  FLOWLOCK_UNLOCK(f);
595  FlowQueuePrivateAppendFlow(recycle_q, f);
596 
597  cnt++;
598 
599  f = next_flow;
600  } while (f != NULL);
601 
602  return cnt;
603 }
604 
605 #define RECYCLE_MAX_QUEUE_ITEMS 25
606 /**
607  * \brief remove all flows from the hash
608  *
609  * \retval cnt number of removes out flows
610  */
611 static uint32_t FlowCleanupHash(void)
612 {
613  FlowQueuePrivate local_queue = { NULL, NULL, 0 };
614  uint32_t cnt = 0;
615 
616  for (uint32_t idx = 0; idx < flow_config.hash_size; idx++) {
617  FlowBucket *fb = &flow_hash[idx];
618 
619  FBLOCK_LOCK(fb);
620 
621  if (fb->head != NULL) {
622  /* we have a flow, or more than one */
623  cnt += FlowManagerHashRowCleanup(fb->head, &local_queue, 0);
624  }
625  if (fb->evicted != NULL) {
626  /* we have a flow, or more than one */
627  cnt += FlowManagerHashRowCleanup(fb->evicted, &local_queue, 1);
628  }
629 
630  FBLOCK_UNLOCK(fb);
631  if (local_queue.len >= RECYCLE_MAX_QUEUE_ITEMS) {
632  FlowQueueAppendPrivate(&flow_recycle_q, &local_queue);
634  }
635  }
637  FlowQueueAppendPrivate(&flow_recycle_q, &local_queue);
639 
640  return cnt;
641 }
642 
643 typedef struct FlowCounters_ {
646 
647  uint16_t flow_mgr_spare;
650 
656 
658 
662 
663  uint16_t memcap_pressure;
666 
667 typedef struct FlowManagerThreadData_ {
668  uint32_t instance;
669  uint32_t min;
670  uint32_t max;
671 
673 
678 
679 static void FlowCountersInit(ThreadVars *t, FlowCounters *fc)
680 {
681  fc->flow_mgr_full_pass = StatsRegisterCounter("flow.mgr.full_hash_pass", t);
682  fc->flow_mgr_rows_sec = StatsRegisterCounter("flow.mgr.rows_per_sec", t);
683 
684  fc->flow_mgr_spare = StatsRegisterCounter("flow.spare", t);
685  fc->flow_emerg_mode_enter = StatsRegisterCounter("flow.emerg_mode_entered", t);
686  fc->flow_emerg_mode_over = StatsRegisterCounter("flow.emerg_mode_over", t);
687 
688  fc->flow_mgr_rows_maxlen = StatsRegisterMaxCounter("flow.mgr.rows_maxlen", t);
689  fc->flow_mgr_flows_checked = StatsRegisterCounter("flow.mgr.flows_checked", t);
690  fc->flow_mgr_flows_notimeout = StatsRegisterCounter("flow.mgr.flows_notimeout", t);
691  fc->flow_mgr_flows_timeout = StatsRegisterCounter("flow.mgr.flows_timeout", t);
692  fc->flow_mgr_flows_aside = StatsRegisterCounter("flow.mgr.flows_evicted", t);
693  fc->flow_mgr_flows_aside_needs_work = StatsRegisterCounter("flow.mgr.flows_evicted_needs_work", t);
694 
695  fc->flow_bypassed_cnt_clo = StatsRegisterCounter("flow_bypassed.closed", t);
696  fc->flow_bypassed_pkts = StatsRegisterCounter("flow_bypassed.pkts", t);
697  fc->flow_bypassed_bytes = StatsRegisterCounter("flow_bypassed.bytes", t);
698 
699  fc->memcap_pressure = StatsRegisterCounter("memcap.pressure", t);
700  fc->memcap_pressure_max = StatsRegisterMaxCounter("memcap.pressure_max", t);
701 }
702 
703 static void FlowCountersUpdate(
704  ThreadVars *th_v, const FlowManagerThreadData *ftd, const FlowTimeoutCounters *counters)
705 {
706  StatsAddUI64(th_v, ftd->cnt.flow_mgr_flows_checked, (uint64_t)counters->flows_checked);
707  StatsAddUI64(th_v, ftd->cnt.flow_mgr_flows_notimeout, (uint64_t)counters->flows_notimeout);
708 
709  StatsAddUI64(th_v, ftd->cnt.flow_mgr_flows_timeout, (uint64_t)counters->flows_timeout);
710  StatsAddUI64(th_v, ftd->cnt.flow_mgr_flows_aside, (uint64_t)counters->flows_aside);
712  (uint64_t)counters->flows_aside_needs_work);
713 
714  StatsAddUI64(th_v, ftd->cnt.flow_bypassed_cnt_clo, (uint64_t)counters->bypassed_count);
715  StatsAddUI64(th_v, ftd->cnt.flow_bypassed_pkts, (uint64_t)counters->bypassed_pkts);
716  StatsAddUI64(th_v, ftd->cnt.flow_bypassed_bytes, (uint64_t)counters->bypassed_bytes);
717 
718  StatsSetUI64(th_v, ftd->cnt.flow_mgr_rows_maxlen, (uint64_t)counters->rows_maxlen);
719 }
720 
721 static TmEcode FlowManagerThreadInit(ThreadVars *t, const void *initdata, void **data)
722 {
724  if (ftd == NULL)
725  return TM_ECODE_FAILED;
726 
727  ftd->instance = SC_ATOMIC_ADD(flowmgr_cnt, 1);
728  SCLogDebug("flow manager instance %u", ftd->instance);
729 
730  /* set the min and max value used for hash row walking
731  * each thread has it's own section of the flow hash */
732  uint32_t range = flow_config.hash_size / flowmgr_number;
733 
734  ftd->min = ftd->instance * range;
735  ftd->max = (ftd->instance + 1) * range;
736 
737  /* last flow-manager takes on hash_size % flowmgr_number extra rows */
738  if ((ftd->instance + 1) == flowmgr_number) {
739  ftd->max = flow_config.hash_size;
740  }
742 
743  SCLogDebug("instance %u hash range %u %u", ftd->instance, ftd->min, ftd->max);
744 
745  /* pass thread data back to caller */
746  *data = ftd;
747 
748  FlowCountersInit(t, &ftd->cnt);
749  ftd->counter_defrag_timeout = StatsRegisterCounter("defrag.mgr.tracker_timeout", t);
750  ftd->counter_defrag_memuse = StatsRegisterCounter("defrag.memuse", t);
751 
752  PacketPoolInit();
753  return TM_ECODE_OK;
754 }
755 
756 static TmEcode FlowManagerThreadDeinit(ThreadVars *t, void *data)
757 {
760  SCFree(data);
761  return TM_ECODE_OK;
762 }
763 
764 /** \internal
765  * \brief calculate number of rows to scan and how much time to sleep
766  * based on the busy score `mp` (0 idle, 100 max busy).
767  *
768  * We try to to make sure we scan the hash once a second. The number size
769  * of the slice of the hash scanned is determined by our busy score 'mp'.
770  * We sleep for the remainder of the second after processing the slice,
771  * or at least an approximation of it.
772  * A minimum busy score of 10 is assumed to avoid a longer than 10 second
773  * full hash pass. This is to avoid burstiness in scanning when there is
774  * a rapid increase of the busy score, which could lead to the flow manager
775  * suddenly scanning a much larger slice of the hash leading to a burst
776  * in scan/eviction work.
777  *
778  * \param rows number of rows for the work unit
779  * \param mp current memcap pressure value
780  * \param emergency emergency mode is set or not
781  * \param wu_sleep holds value of sleep time per worker unit
782  * \param wu_rows holds value of calculated rows to be processed per second
783  * \param rows_sec same as wu_rows, only used for counter updates
784  */
785 static void GetWorkUnitSizing(const uint32_t rows, const uint32_t mp, const bool emergency,
786  uint64_t *wu_sleep, uint32_t *wu_rows, uint32_t *rows_sec)
787 {
788  if (emergency) {
789  *wu_rows = rows;
790  *wu_sleep = 250;
791  return;
792  }
793  /* minimum busy score is 10 */
794  const uint32_t emp = MAX(mp, 10);
795  const uint32_t rows_per_sec = (uint32_t)((float)rows * (float)((float)emp / (float)100));
796  /* calc how much time we estimate the work will take, in ms. We assume
797  * each row takes an average of 1usec. Maxing out at 1sec. */
798  const uint32_t work_per_unit = MIN(rows_per_sec / 1000, 1000);
799  /* calc how much time we need to sleep to get to the per second cadence
800  * but sleeping for at least 250ms. */
801  const uint32_t sleep_per_unit = MAX(250, 1000 - work_per_unit);
802  SCLogDebug("mp %u emp %u rows %u rows_sec %u sleep %ums", mp, emp, rows, rows_per_sec,
803  sleep_per_unit);
804 
805  *wu_sleep = sleep_per_unit;
806  *wu_rows = rows_per_sec;
807  *rows_sec = rows_per_sec;
808 }
809 
810 /** \brief Thread that manages the flow table and times out flows.
811  *
812  * \param td ThreadVars cast to void ptr
813  *
814  * Keeps an eye on the spare list, alloc flows if needed...
815  */
816 static TmEcode FlowManager(ThreadVars *th_v, void *thread_data)
817 {
818  FlowManagerThreadData *ftd = thread_data;
819  const uint32_t rows = ftd->max - ftd->min;
820  const bool time_is_live = TimeModeIsLive();
821 
822  uint32_t emerg_over_cnt = 0;
823  uint64_t next_run_ms = 0;
824  uint32_t pos = ftd->min;
825  uint32_t rows_sec = 0;
826  uint32_t rows_per_wu = 0;
827  uint64_t sleep_per_wu = 0;
828  bool prev_emerg = false;
829  uint32_t other_last_sec = 0; /**< last sec stamp when defrag etc ran */
830 
831  uint32_t mp = MemcapsGetPressure() * 100;
832  if (ftd->instance == 0) {
833  StatsSetUI64(th_v, ftd->cnt.memcap_pressure, mp);
834  StatsSetUI64(th_v, ftd->cnt.memcap_pressure_max, mp);
835  }
836  GetWorkUnitSizing(rows, mp, false, &sleep_per_wu, &rows_per_wu, &rows_sec);
837  StatsSetUI64(th_v, ftd->cnt.flow_mgr_rows_sec, rows_sec);
838 
840  /* don't start our activities until time is setup */
841  while (!TimeModeIsReady()) {
842  if (suricata_ctl_flags != 0)
843  return TM_ECODE_OK;
844  usleep(10);
845  }
846  bool run = TmThreadsWaitForUnpause(th_v);
847 
848  while (run) {
849  bool emerg = ((SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) != 0);
850 
851  /* Get the time: real time in live mode, or a min() of the
852  * "active" threads in offline mode. See TmThreadsGetMinimalTimestamp */
853  SCTime_t ts = TimeGet();
854 
855  SCLogDebug("ts %" PRIdMAX "", (intmax_t)SCTIME_SECS(ts));
856  uint64_t ts_ms = SCTIME_MSECS(ts);
857  const bool emerge_p = (emerg && !prev_emerg);
858  if (emerge_p) {
859  next_run_ms = 0;
860  prev_emerg = true;
861  SCLogNotice("Flow emergency mode entered...");
862  StatsIncr(th_v, ftd->cnt.flow_emerg_mode_enter);
863  }
864  if (ts_ms >= next_run_ms) {
865  if (ftd->instance == 0) {
866  const uint32_t sq_len = FlowSpareGetPoolSize();
867  const uint32_t spare_perc = sq_len * 100 / MAX(flow_config.prealloc, 1);
868  /* see if we still have enough spare flows */
869  if (spare_perc < 90 || spare_perc > 110) {
870  FlowSparePoolUpdate(sq_len);
871  }
872  }
873 
874  /* try to time out flows */
875  // clang-format off
876  FlowTimeoutCounters counters = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
877  // clang-format on
878 
879  if (emerg) {
880  /* in emergency mode, do a full pass of the hash table */
881  FlowTimeoutHash(&ftd->timeout, ts, ftd->min, ftd->max, &counters);
882  StatsIncr(th_v, ftd->cnt.flow_mgr_full_pass);
883  } else {
884  SCLogDebug("hash %u:%u slice starting at %u with %u rows", ftd->min, ftd->max, pos,
885  rows_per_wu);
886 
887  const uint32_t ppos = pos;
888  FlowTimeoutHashInChunks(&ftd->timeout, ts, ftd->min, ftd->max, &counters,
889  rows_per_wu, &pos, ftd->instance);
890  if (ppos > pos) {
891  StatsIncr(th_v, ftd->cnt.flow_mgr_full_pass);
892  }
893  }
894 
895  const uint32_t spare_pool_len = FlowSpareGetPoolSize();
896  StatsSetUI64(th_v, ftd->cnt.flow_mgr_spare, (uint64_t)spare_pool_len);
897 
898  FlowCountersUpdate(th_v, ftd, &counters);
899 
900  if (emerg) {
901  SCLogDebug("flow_sparse_q.len = %" PRIu32 " prealloc: %" PRIu32
902  "flow_spare_q status: %" PRIu32 "%% flows at the queue",
903  spare_pool_len, flow_config.prealloc,
904  spare_pool_len * 100 / MAX(flow_config.prealloc, 1));
905 
906  /* only if we have pruned this "emergency_recovery" percentage
907  * of flows, we will unset the emergency bit */
908  if ((spare_pool_len * 100 / MAX(flow_config.prealloc, 1)) >
910  emerg_over_cnt++;
911  } else {
912  emerg_over_cnt = 0;
913  }
914 
915  if (emerg_over_cnt >= 30) {
916  SC_ATOMIC_AND(flow_flags, ~FLOW_EMERGENCY);
918 
919  emerg = false;
920  prev_emerg = false;
921  emerg_over_cnt = 0;
922  SCLogNotice("Flow emergency mode over, back to normal... unsetting"
923  " FLOW_EMERGENCY bit (ts.tv_sec: %" PRIuMAX ", "
924  "ts.tv_usec:%" PRIuMAX ") flow_spare_q status(): %" PRIu32
925  "%% flows at the queue",
926  (uintmax_t)SCTIME_SECS(ts), (uintmax_t)SCTIME_USECS(ts),
927  spare_pool_len * 100 / MAX(flow_config.prealloc, 1));
928 
929  StatsIncr(th_v, ftd->cnt.flow_emerg_mode_over);
930  }
931  }
932 
933  /* update work units */
934  const uint32_t pmp = mp;
935  mp = MemcapsGetPressure() * 100;
936  if (ftd->instance == 0) {
937  StatsSetUI64(th_v, ftd->cnt.memcap_pressure, mp);
938  StatsSetUI64(th_v, ftd->cnt.memcap_pressure_max, mp);
939  }
940  GetWorkUnitSizing(rows, mp, emerg, &sleep_per_wu, &rows_per_wu, &rows_sec);
941  if (pmp != mp) {
942  StatsSetUI64(th_v, ftd->cnt.flow_mgr_rows_sec, rows_sec);
943  }
944 
945  next_run_ms = ts_ms + sleep_per_wu;
946  }
947  if (other_last_sec == 0 || other_last_sec < (uint32_t)SCTIME_SECS(ts)) {
948  if (ftd->instance == 0) {
950  uint32_t defrag_cnt = DefragTimeoutHash(ts);
951  if (defrag_cnt) {
952  StatsAddUI64(th_v, ftd->counter_defrag_timeout, defrag_cnt);
953  }
958  other_last_sec = (uint32_t)SCTIME_SECS(ts);
959  }
960  }
961 
962  if (TmThreadsCheckFlag(th_v, THV_KILL)) {
963  StatsSyncCounters(th_v);
964  break;
965  }
966 
967  if (emerg || !time_is_live) {
968  usleep(250);
969  } else {
970  struct timeval cond_tv;
971  gettimeofday(&cond_tv, NULL);
972  struct timeval add_tv;
973  add_tv.tv_sec = sleep_per_wu / 1000;
974  add_tv.tv_usec = (sleep_per_wu % 1000) * 1000;
975  timeradd(&cond_tv, &add_tv, &cond_tv);
976 
977  struct timespec cond_time = FROM_TIMEVAL(cond_tv);
978  SCCtrlMutexLock(&flow_manager_ctrl_mutex);
979  while (1) {
980  int rc = SCCtrlCondTimedwait(
981  &flow_manager_ctrl_cond, &flow_manager_ctrl_mutex, &cond_time);
982  if (rc == ETIMEDOUT || rc < 0)
983  break;
984  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) {
985  break;
986  }
987  }
988  SCCtrlMutexUnlock(&flow_manager_ctrl_mutex);
989  }
990 
991  SCLogDebug("woke up... %s", SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY ? "emergency":"");
992 
994  }
995  return TM_ECODE_OK;
996 }
997 
998 /** \brief spawn the flow manager thread */
1000 {
1001  intmax_t setting = 1;
1002  (void)SCConfGetInt("flow.managers", &setting);
1003 
1004  if (setting < 1 || setting > 1024) {
1005  FatalError("invalid flow.managers setting %" PRIdMAX, setting);
1006  }
1007  flowmgr_number = (uint32_t)setting;
1008 
1009  SCLogConfig("using %u flow manager threads", flowmgr_number);
1010  StatsRegisterGlobalCounter("flow.memuse", FlowGetMemuse);
1011 
1012  for (uint32_t u = 0; u < flowmgr_number; u++) {
1013  char name[TM_THREAD_NAME_MAX];
1014  snprintf(name, sizeof(name), "%s#%02u", thread_name_flow_mgr, u+1);
1015 
1017  "FlowManager", 0);
1018  BUG_ON(tv_flowmgr == NULL);
1019 
1020  if (tv_flowmgr == NULL) {
1021  FatalError("flow manager thread creation failed");
1022  }
1023  if (TmThreadSpawn(tv_flowmgr) != TM_ECODE_OK) {
1024  FatalError("flow manager thread spawn failed");
1025  }
1026  }
1027 }
1028 
1029 typedef struct FlowRecyclerThreadData_ {
1031 
1032  uint16_t counter_flows;
1035 
1040 
1041 static TmEcode FlowRecyclerThreadInit(ThreadVars *t, const void *initdata, void **data)
1042 {
1044  if (ftd == NULL)
1045  return TM_ECODE_FAILED;
1047  SCLogError("initializing flow log API for thread failed");
1048  SCFree(ftd);
1049  return TM_ECODE_FAILED;
1050  }
1051  SCLogDebug("output_thread_data %p", ftd->output_thread_data);
1052 
1053  ftd->counter_flows = StatsRegisterCounter("flow.recycler.recycled", t);
1054  ftd->counter_queue_avg = StatsRegisterAvgCounter("flow.recycler.queue_avg", t);
1055  ftd->counter_queue_max = StatsRegisterMaxCounter("flow.recycler.queue_max", t);
1056 
1057  ftd->counter_flow_active = StatsRegisterCounter("flow.active", t);
1058  ftd->counter_tcp_active_sessions = StatsRegisterCounter("tcp.active_sessions", t);
1059 
1060  FlowEndCountersRegister(t, &ftd->fec);
1061 
1062  *data = ftd;
1063  return TM_ECODE_OK;
1064 }
1065 
1066 static TmEcode FlowRecyclerThreadDeinit(ThreadVars *t, void *data)
1067 {
1069 
1071  if (ftd->output_thread_data != NULL)
1073 
1074  SCFree(data);
1075  return TM_ECODE_OK;
1076 }
1077 
1078 static void Recycler(ThreadVars *tv, FlowRecyclerThreadData *ftd, Flow *f)
1079 {
1080  FLOWLOCK_WRLOCK(f);
1081 
1082  (void)OutputFlowLog(tv, ftd->output_thread_data, f);
1083 
1084  FlowEndCountersUpdate(tv, &ftd->fec, f);
1085  if (f->proto == IPPROTO_TCP && f->protoctx != NULL) {
1087  }
1090  FlowClearMemory(f, f->protomap);
1091  FLOWLOCK_UNLOCK(f);
1092 }
1093 
1094 /** \brief Thread that manages timed out flows.
1095  *
1096  * \param td ThreadVars cast to void ptr
1097  */
1098 static TmEcode FlowRecycler(ThreadVars *th_v, void *thread_data)
1099 {
1100  FlowRecyclerThreadData *ftd = (FlowRecyclerThreadData *)thread_data;
1101  BUG_ON(ftd == NULL);
1102  const bool time_is_live = TimeModeIsLive();
1103  uint64_t recycled_cnt = 0;
1104  FlowQueuePrivate ret_queue = { NULL, NULL, 0 };
1105 
1107  bool run = TmThreadsWaitForUnpause(th_v);
1108 
1109  while (run) {
1110  SC_ATOMIC_ADD(flowrec_busy,1);
1112 
1113  StatsAddUI64(th_v, ftd->counter_queue_avg, list.len);
1114  StatsSetUI64(th_v, ftd->counter_queue_max, list.len);
1115 
1116  const int bail = (TmThreadsCheckFlag(th_v, THV_KILL));
1117 
1118  /* Get the time */
1119  SCLogDebug("ts %" PRIdMAX "", (intmax_t)SCTIME_SECS(TimeGet()));
1120 
1121  uint64_t cnt = 0;
1122  Flow *f;
1123  while ((f = FlowQueuePrivateGetFromTop(&list)) != NULL) {
1124  Recycler(th_v, ftd, f);
1125  cnt++;
1126 
1127  /* for every full sized block, add it to the spare pool */
1128  FlowQueuePrivateAppendFlow(&ret_queue, f);
1129  if (ret_queue.len == FLOW_SPARE_POOL_BLOCK_SIZE) {
1130  FlowSparePoolReturnFlows(&ret_queue);
1131  }
1132  }
1133  if (ret_queue.len > 0) {
1134  FlowSparePoolReturnFlows(&ret_queue);
1135  }
1136  if (cnt > 0) {
1137  recycled_cnt += cnt;
1138  StatsAddUI64(th_v, ftd->counter_flows, cnt);
1139  }
1140  SC_ATOMIC_SUB(flowrec_busy,1);
1141 
1142  if (bail) {
1143  break;
1144  }
1145 
1146  const bool emerg = (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY);
1147  if (emerg || !time_is_live) {
1148  usleep(250);
1149  } else {
1150  struct timeval cond_tv;
1151  gettimeofday(&cond_tv, NULL);
1152  cond_tv.tv_sec += 1;
1153  struct timespec cond_time = FROM_TIMEVAL(cond_tv);
1154  SCCtrlMutexLock(&flow_recycler_ctrl_mutex);
1155  while (1) {
1156  int rc = SCCtrlCondTimedwait(
1157  &flow_recycler_ctrl_cond, &flow_recycler_ctrl_mutex, &cond_time);
1158  if (rc == ETIMEDOUT || rc < 0) {
1159  break;
1160  }
1161  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) {
1162  break;
1163  }
1164  if (SC_ATOMIC_GET(flow_recycle_q.non_empty)) {
1165  break;
1166  }
1167  }
1168  SCCtrlMutexUnlock(&flow_recycler_ctrl_mutex);
1169  }
1170 
1171  SCLogDebug("woke up...");
1172 
1174  }
1175  StatsSyncCounters(th_v);
1176  SCLogPerf("%"PRIu64" flows processed", recycled_cnt);
1177  return TM_ECODE_OK;
1178 }
1179 
1180 static bool FlowRecyclerReadyToShutdown(void)
1181 {
1182  if (SC_ATOMIC_GET(flowrec_busy) != 0) {
1183  return false;
1184  }
1185  uint32_t len = 0;
1187  len = flow_recycle_q.qlen;
1189 
1190  return ((len == 0));
1191 }
1192 
1193 /** \brief spawn the flow recycler thread */
1195 {
1196  intmax_t setting = 1;
1197  (void)SCConfGetInt("flow.recyclers", &setting);
1198 
1199  if (setting < 1 || setting > 1024) {
1200  FatalError("invalid flow.recyclers setting %" PRIdMAX, setting);
1201  }
1202  flowrec_number = (uint32_t)setting;
1203 
1204  SCLogConfig("using %u flow recycler threads", flowrec_number);
1205 
1206  for (uint32_t u = 0; u < flowrec_number; u++) {
1207  char name[TM_THREAD_NAME_MAX];
1208  snprintf(name, sizeof(name), "%s#%02u", thread_name_flow_rec, u+1);
1209 
1211  "FlowRecycler", 0);
1212 
1213  if (tv_flowrec == NULL) {
1214  FatalError("flow recycler thread creation failed");
1215  }
1216  if (TmThreadSpawn(tv_flowrec) != TM_ECODE_OK) {
1217  FatalError("flow recycler thread spawn failed");
1218  }
1219  }
1220 }
1221 
1222 /**
1223  * \brief Used to disable flow recycler thread(s).
1224  *
1225  * \note this should only be called when the flow manager is already gone
1226  *
1227  * \todo Kinda hackish since it uses the tv name to identify flow recycler
1228  * thread. We need an all weather identification scheme.
1229  */
1231 {
1232  /* move all flows still in the hash to the recycler queue */
1233 #ifndef DEBUG
1234  (void)FlowCleanupHash();
1235 #else
1236  uint32_t flows = FlowCleanupHash();
1237  SCLogDebug("flows to progress: %u", flows);
1238 #endif
1239 
1240  /* make sure all flows are processed */
1241  do {
1243  usleep(10);
1244  } while (!FlowRecyclerReadyToShutdown());
1245 
1247  /* flow recycler thread(s) is/are a part of mgmt threads */
1248  for (ThreadVars *tv = tv_root[TVT_MGMT]; tv != NULL; tv = tv->next) {
1249  if (strncasecmp(tv->name, thread_name_flow_rec,
1250  strlen(thread_name_flow_rec)) == 0)
1251  {
1253  }
1254  }
1256 
1257  struct timeval start_ts;
1258  struct timeval cur_ts;
1259  gettimeofday(&start_ts, NULL);
1260 
1261 again:
1262  gettimeofday(&cur_ts, NULL);
1263  if ((cur_ts.tv_sec - start_ts.tv_sec) > 60) {
1264  FatalError("unable to get all flow recycler "
1265  "threads to shutdown in time");
1266  }
1267 
1269  for (ThreadVars *tv = tv_root[TVT_MGMT]; tv != NULL; tv = tv->next) {
1270  if (strncasecmp(tv->name, thread_name_flow_rec,
1271  strlen(thread_name_flow_rec)) == 0)
1272  {
1276  /* sleep outside lock */
1277  SleepMsec(1);
1278  goto again;
1279  }
1280  }
1281  }
1283 
1284  /* reset count, so we can kill and respawn (unix socket) */
1285  SC_ATOMIC_SET(flowrec_cnt, 0);
1286 }
1287 
1289 {
1290  tmm_modules[TMM_FLOWMANAGER].name = "FlowManager";
1291  tmm_modules[TMM_FLOWMANAGER].ThreadInit = FlowManagerThreadInit;
1292  tmm_modules[TMM_FLOWMANAGER].ThreadDeinit = FlowManagerThreadDeinit;
1293  tmm_modules[TMM_FLOWMANAGER].Management = FlowManager;
1296  SCLogDebug("%s registered", tmm_modules[TMM_FLOWMANAGER].name);
1297 
1298  SC_ATOMIC_INIT(flowmgr_cnt);
1299  SC_ATOMIC_INITPTR(flow_timeouts);
1300 }
1301 
1303 {
1304  tmm_modules[TMM_FLOWRECYCLER].name = "FlowRecycler";
1305  tmm_modules[TMM_FLOWRECYCLER].ThreadInit = FlowRecyclerThreadInit;
1306  tmm_modules[TMM_FLOWRECYCLER].ThreadDeinit = FlowRecyclerThreadDeinit;
1307  tmm_modules[TMM_FLOWRECYCLER].Management = FlowRecycler;
1310  SCLogDebug("%s registered", tmm_modules[TMM_FLOWRECYCLER].name);
1311 
1312  SC_ATOMIC_INIT(flowrec_cnt);
1313  SC_ATOMIC_INIT(flowrec_busy);
1314 }
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:73
FlowTimeoutCounters_::rows_empty
uint32_t rows_empty
Definition: flow-manager.c:111
FlowSparePoolUpdate
void FlowSparePoolUpdate(uint32_t size)
Definition: flow-spare-pool.c:217
FlowManagerThreadSpawn
void FlowManagerThreadSpawn(void)
spawn the flow manager thread
Definition: flow-manager.c:999
util-device-private.h
tm-threads.h
FROM_TIMEVAL
#define FROM_TIMEVAL(timev)
initialize a 'struct timespec' from a 'struct timeval'.
Definition: util-time.h:124
OutputFlowLog
TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
Run flow logger(s)
Definition: output-flow.c:87
FlowRecyclerThreadData_::fec
FlowEndCounters fec
Definition: flow-manager.c:1038
len
uint8_t len
Definition: app-layer-dnp3.h:2
ts
uint64_t ts
Definition: source-erf-file.c:55
TmThreadSpawn
TmEcode TmThreadSpawn(ThreadVars *tv)
Spawns a thread associated with the ThreadVars instance tv.
Definition: tm-threads.c:1684
app-layer-htp-range.h
FlowTimeoutCounters
Definition: flow-worker.c:61
TmThreadCreateMgmtThreadByName
ThreadVars * TmThreadCreateMgmtThreadByName(const char *name, const char *module, int mucond)
Creates and returns the TV instance for a Management thread(MGMT). This function supports only custom...
Definition: tm-threads.c:1109
FlowBucket_::evicted
Flow * evicted
Definition: flow-hash.h:48
OutputFlowLogThreadInit
TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void **data)
thread init for the flow logger This will run the thread init functions for the individual registered...
Definition: output-flow.c:123
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
FLOW_IS_IPV6
#define FLOW_IS_IPV6(f)
Definition: flow.h:172
FlowManagerThreadData_::max
uint32_t max
Definition: flow-manager.c:670
FlowManagerTimeoutThread
Definition: flow-manager.c:276
ThreadVars_::name
char name[16]
Definition: threadvars.h:65
thread_name_flow_mgr
const char * thread_name_flow_mgr
Definition: runmodes.c:70
FlowSpareGetPoolSize
uint32_t FlowSpareGetPoolSize(void)
Definition: flow-spare-pool.c:46
flow-util.h
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:314
FlowManagerThreadData_::cnt
FlowCounters cnt
Definition: flow-manager.c:672
FBLOCK_LOCK
#define FBLOCK_LOCK(fb)
Definition: flow-hash.h:73
SCTIME_MSECS
#define SCTIME_MSECS(t)
Definition: util-time.h:58
TMM_FLOWRECYCLER
@ TMM_FLOWRECYCLER
Definition: tm-threads-common.h:70
stream-tcp.h
GetFlowBypassInfoID
FlowStorageId GetFlowBypassInfoID(void)
Definition: flow-util.c:222
FlowBypassInfo_
Definition: flow.h:529
FlowCnf_::emergency_recovery
uint32_t emergency_recovery
Definition: flow.h:300
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
FlowCnf_::hash_size
uint32_t hash_size
Definition: flow.h:294
FlowManagerThreadData_::instance
uint32_t instance
Definition: flow-manager.c:668
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:270
IPPairTimeoutHash
uint32_t IPPairTimeoutHash(SCTime_t ts)
time out ippairs from the hash
Definition: ippair-timeout.c:124
TmThreadsSetFlag
void TmThreadsSetFlag(ThreadVars *tv, uint32_t flag)
Set a thread flag.
Definition: tm-threads.c:101
StatsRegisterGlobalCounter
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1010
Flow_::proto
uint8_t proto
Definition: flow.h:378
SC_ATOMIC_DECLARE
SC_ATOMIC_DECLARE(uint32_t, flowmgr_cnt)
threads.h
FlowSendToLocalThread
void FlowSendToLocalThread(Flow *f)
Definition: flow-timeout.c:349
flow-private.h
FlowCounters_::flow_mgr_flows_notimeout
uint16_t flow_mgr_flows_notimeout
Definition: flow-manager.c:652
Flow_
Flow data structure.
Definition: flow.h:356
TYPE
#define TYPE
Flow_::protomap
uint8_t protomap
Definition: flow.h:445
SC_ATOMIC_EXTERN
SC_ATOMIC_EXTERN(unsigned int, flow_flags)
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
thread_name_flow_rec
const char * thread_name_flow_rec
Definition: runmodes.c:71
FlowProtoTimeout_
Definition: flow.h:518
StatsSetUI64
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition: counters.c:207
THV_RUNNING
#define THV_RUNNING
Definition: threadvars.h:55
flow-hash.h
TmModuleFlowRecyclerRegister
void TmModuleFlowRecyclerRegister(void)
Definition: flow-manager.c:1302
FlowTimeoutCounters_::flows_removed
uint32_t flows_removed
Definition: flow-manager.c:117
FlowBypassInfo_::tosrcbytecnt
uint64_t tosrcbytecnt
Definition: flow.h:534
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
FlowGetMemuse
uint64_t FlowGetMemuse(void)
Definition: flow.c:127
MIN
#define MIN(x, y)
Definition: suricata-common.h:408
tv_root
ThreadVars * tv_root[TVT_MAX]
Definition: tm-threads.c:82
FlowTimeoutCounters_::flows_timeout
uint32_t flows_timeout
Definition: flow-manager.c:116
defrag-timeout.h
FlowRecyclerThreadData_::counter_flows
uint16_t counter_flows
Definition: flow-manager.c:1032
FlowManagerThreadData_::counter_defrag_memuse
uint16_t counter_defrag_memuse
Definition: flow-manager.c:676
FLOW_ACTION_DROP
#define FLOW_ACTION_DROP
Definition: flow.h:70
LiveDevSubBypassStats
void LiveDevSubBypassStats(LiveDevice *dev, uint64_t cnt, int family)
Definition: util-device.c:520
TVT_MGMT
@ TVT_MGMT
Definition: tm-threads-common.h:89
MAX
#define MAX(x, y)
Definition: suricata-common.h:412
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
FlowQueuePrivate_::len
uint32_t len
Definition: flow-queue.h:43
Flow_::protoctx
void * protoctx
Definition: flow.h:441
FlowCounters_
Definition: flow-manager.c:643
FlowManagerTimeoutThread
struct FlowManagerTimeoutThread FlowManagerTimeoutThread
SCCtrlCondSignal
#define SCCtrlCondSignal
Definition: threads-debug.h:384
FlowCounters_::flow_mgr_flows_aside
uint16_t flow_mgr_flows_aside
Definition: flow-manager.c:654
FLOW_TIMEOUT_REASSEMBLY_DONE
#define FLOW_TIMEOUT_REASSEMBLY_DONE
Definition: flow.h:97
runmode-unix-socket.h
FlowTimeoutCounters_::bypassed_count
uint32_t bypassed_count
Definition: flow-manager.c:121
TmThreadsGetThreadTime
SCTime_t TmThreadsGetThreadTime(const int idx)
Definition: tm-threads.c:2321
FlowSparePoolReturnFlows
void FlowSparePoolReturnFlows(FlowQueuePrivate *fqp)
Definition: flow-spare-pool.c:120
TM_THREAD_NAME_MAX
#define TM_THREAD_NAME_MAX
Definition: tm-threads.h:49
FlowCnf_::prealloc
uint32_t prealloc
Definition: flow.h:295
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:273
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
PacketPoolInit
void PacketPoolInit(void)
Definition: tmqh-packetpool.c:244
Flow_::flow_state
FlowStateType flow_state
Definition: flow.h:412
FQLOCK_LOCK
#define FQLOCK_LOCK(q)
Definition: flow-queue.h:72
FLOW_PROTO_MAX
@ FLOW_PROTO_MAX
Definition: flow-private.h:74
FlowWakeupFlowManagerThread
void FlowWakeupFlowManagerThread(void)
Definition: flow-manager.c:84
FlowDisableFlowRecyclerThread
void FlowDisableFlowRecyclerThread(void)
Used to disable flow recycler thread(s).
Definition: flow-manager.c:1230
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
FlowTimeoutCounters_::rows_maxlen
uint32_t rows_maxlen
Definition: flow-manager.c:112
FlowCounters_::flow_bypassed_bytes
uint16_t flow_bypassed_bytes
Definition: flow-manager.c:661
FlowTimeoutCounters_::flows_checked
uint32_t flows_checked
Definition: flow-manager.c:114
THV_RUNNING_DONE
#define THV_RUNNING_DONE
Definition: threadvars.h:46
flow-spare-pool.h
StatsDecr
void StatsDecr(ThreadVars *tv, uint16_t id)
Decrements the local counter.
Definition: counters.c:186
Flow_::fb
struct FlowBucket_ * fb
Definition: flow.h:491
FlowCounters_::flow_mgr_full_pass
uint16_t flow_mgr_full_pass
Definition: flow-manager.c:644
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:992
SC_ATOMIC_MEMORY_ORDER_RELAXED
#define SC_ATOMIC_MEMORY_ORDER_RELAXED
Definition: util-atomic.h:165
util-debug.h
FlowWakeupFlowRecyclerThread
void FlowWakeupFlowRecyclerThread(void)
Definition: flow-manager.c:91
FlowBypassInfo_::todstbytecnt
uint64_t todstbytecnt
Definition: flow.h:536
SCFlowRunFinishCallbacks
void SCFlowRunFinishCallbacks(ThreadVars *tv, Flow *f)
Definition: flow-callbacks.c:122
FlowBypassInfo_::BypassUpdate
bool(* BypassUpdate)(Flow *f, void *data, time_t tsec)
Definition: flow.h:530
FlowRecyclerThreadData_::counter_queue_avg
uint16_t counter_queue_avg
Definition: flow-manager.c:1033
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
FlowCounters_::flow_mgr_rows_maxlen
uint16_t flow_mgr_rows_maxlen
Definition: flow-manager.c:657
Flow_::lastts
SCTime_t lastts
Definition: flow.h:410
SCConfGetInt
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:414
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:270
FlowTimeoutsReset
#define FlowTimeoutsReset()
Definition: flow-manager.h:30
FlowDisableFlowManagerThread
void FlowDisableFlowManagerThread(void)
Used to disable flow manager thread(s).
Definition: flow-manager.c:132
SCCtrlCondT
#define SCCtrlCondT
Definition: threads-debug.h:382
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
TmModule_::Management
TmEcode(* Management)(ThreadVars *, void *)
Definition: tm-modules.h:65
TimeModeIsReady
bool TimeModeIsReady(void)
Definition: util-time.c:92
Flow_::flow_end_flags
uint8_t flow_end_flags
Definition: flow.h:447
THV_KILL
#define THV_KILL
Definition: threadvars.h:40
MemcapsGetPressure
float MemcapsGetPressure(void)
Definition: runmode-unix-socket.c:110
FlowBypassInfo_::todstpktcnt
uint64_t todstpktcnt
Definition: flow.h:535
util-time.h
FlowQueuePrivateGetFromTop
Flow * FlowQueuePrivateGetFromTop(FlowQueuePrivate *fqc)
Definition: flow-queue.c:151
FlowBypassInfo_::bypass_data
void * bypass_data
Definition: flow.h:532
FlowQueueAppendPrivate
void FlowQueueAppendPrivate(FlowQueue *fq, FlowQueuePrivate *fqc)
Definition: flow-queue.c:119
FlowCounters_::flow_mgr_flows_aside_needs_work
uint16_t flow_mgr_flows_aside_needs_work
Definition: flow-manager.c:655
DefragTrackerGetMemcap
uint64_t DefragTrackerGetMemcap(void)
Return memcap value.
Definition: defrag-hash.c:63
ThreadVars_::next
struct ThreadVars_ * next
Definition: threadvars.h:125
FlowRecyclerThreadData_
Definition: flow-manager.c:1029
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
FLOW_IS_IPV4
#define FLOW_IS_IPV4(f)
Definition: flow.h:170
FlowRecyclerThreadData_::counter_tcp_active_sessions
uint16_t counter_tcp_active_sessions
Definition: flow-manager.c:1037
FlowCounters_::flow_bypassed_cnt_clo
uint16_t flow_bypassed_cnt_clo
Definition: flow-manager.c:659
tv_root_lock
SCMutex tv_root_lock
Definition: tm-threads.c:85
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:341
flow_timeouts_emerg
FlowProtoTimeout flow_timeouts_emerg[FLOW_PROTO_MAX]
Definition: flow.c:88
TimeModeIsLive
bool TimeModeIsLive(void)
Definition: util-time.c:111
SCCtrlMutexLock
#define SCCtrlMutexLock(mut)
Definition: threads-debug.h:376
FlowTimeoutsEmergency
void FlowTimeoutsEmergency(void)
Definition: flow-manager.c:103
FlowTimeoutCounters
struct FlowTimeoutCounters_ FlowTimeoutCounters
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:29
TimeGet
SCTime_t TimeGet(void)
Definition: util-time.c:152
conf.h
FlowRecyclerThreadData_::output_thread_data
void * output_thread_data
Definition: flow-manager.c:1030
FlowTimeoutCounters_::rows_checked
uint32_t rows_checked
Definition: flow-manager.c:109
FBLOCK_UNLOCK
#define FBLOCK_UNLOCK(fb)
Definition: flow-hash.h:75
SCTime_t
Definition: util-time.h:40
TmEcode
TmEcode
Definition: tm-threads-common.h:80
FlowClearMemory
int FlowClearMemory(Flow *f, uint8_t proto_map)
Function clear the flow memory before queueing it to spare flow queue.
Definition: flow.c:1096
name
const char * name
Definition: tm-threads.c:2123
FlowRecyclerThreadSpawn
void FlowRecyclerThreadSpawn(void)
spawn the flow recycler thread
Definition: flow-manager.c:1194
output-flow.h
flow-timeout.h
flow-queue.h
FlowManagerThreadData_::counter_defrag_timeout
uint16_t counter_defrag_timeout
Definition: flow-manager.c:675
TmModule_::name
const char * name
Definition: tm-modules.h:44
FlowRecyclerThreadData
struct FlowRecyclerThreadData_ FlowRecyclerThreadData
FlowBypassInfo_::tosrcpktcnt
uint64_t tosrcpktcnt
Definition: flow.h:533
host-timeout.h
SCCtrlCondTimedwait
#define SCCtrlCondTimedwait
Definition: threads-debug.h:385
StreamTcpThreadCacheCleanup
void StreamTcpThreadCacheCleanup(void)
Definition: stream-tcp-cache.c:134
runmodes.h
FlowTimeoutCounters_::flows_aside_needs_work
uint32_t flows_aside_needs_work
Definition: flow-manager.c:119
FlowGetStorageById
void * FlowGetStorageById(const Flow *f, FlowStorageId id)
Definition: flow-storage.c:40
Flow_::next
struct Flow_ * next
Definition: flow.h:396
FlowQueue_
Definition: flow-queue.h:48
FlowCounters_::flow_bypassed_pkts
uint16_t flow_bypassed_pkts
Definition: flow-manager.c:660
TMM_FLOWMANAGER
@ TMM_FLOWMANAGER
Definition: tm-threads-common.h:69
SCTIME_CMP_LT
#define SCTIME_CMP_LT(a, b)
Definition: util-time.h:105
RECYCLE_MAX_QUEUE_ITEMS
#define RECYCLE_MAX_QUEUE_ITEMS
Definition: flow-manager.c:605
flow_hash
FlowBucket * flow_hash
Definition: flow-hash.c:59
SCCtrlMutexUnlock
#define SCCtrlMutexUnlock(mut)
Definition: threads-debug.h:378
FlowQueueExtractPrivate
FlowQueuePrivate FlowQueueExtractPrivate(FlowQueue *fq)
Definition: flow-queue.c:140
flow-storage.h
cnt
uint32_t cnt
Definition: tmqh-packetpool.h:7
FlowTimeoutCounters_
Definition: flow-manager.c:108
FlowManagerThreadData_
Definition: flow-manager.c:667
SleepMsec
#define SleepMsec(msec)
Definition: tm-threads.h:45
flow-manager.h
suricata-common.h
SCCtrlMutex
#define SCCtrlMutex
Definition: threads-debug.h:373
DefragTimeoutHash
uint32_t DefragTimeoutHash(SCTime_t ts)
time out tracker from the hash
Definition: defrag-timeout.c:122
FlowManagerThreadData
struct FlowManagerThreadData_ FlowManagerThreadData
flow_config
FlowConfig flow_config
Definition: flow.c:92
TmThreadsWaitForUnpause
bool TmThreadsWaitForUnpause(ThreadVars *tv)
Wait for a thread to become unpaused.
Definition: tm-threads.c:363
TmModuleFlowManagerRegister
void TmModuleFlowManagerRegister(void)
Definition: flow-manager.c:1288
FlowCounters_::memcap_pressure
uint16_t memcap_pressure
Definition: flow-manager.c:663
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:231
FlowTimeoutsInit
void FlowTimeoutsInit(void)
Definition: flow-manager.c:98
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
SC_ATOMIC_LOAD_EXPLICIT
#define SC_ATOMIC_LOAD_EXPLICIT(name, order)
Definition: util-atomic.h:378
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
FatalError
#define FatalError(...)
Definition: util-debug.h:503
Flow_::timeout_policy
uint32_t timeout_policy
Definition: flow.h:405
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
StatsSyncCounters
void StatsSyncCounters(ThreadVars *tv)
Definition: counters.c:445
Flow_::livedev
struct LiveDevice_ * livedev
Definition: flow.h:398
threadvars.h
FlowQueuePrivate_
Definition: flow-queue.h:40
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
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
FlowRecyclerThreadData_::counter_queue_max
uint16_t counter_queue_max
Definition: flow-manager.c:1034
FlowTimeoutCounters_::bypassed_bytes
uint64_t bypassed_bytes
Definition: flow-manager.c:123
FlowManagerThreadData_::min
uint32_t min
Definition: flow-manager.c:669
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:262
OutputFlowLogThreadDeinit
TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data)
Definition: output-flow.c:163
flow_recycle_q
FlowQueue flow_recycle_q
Definition: flow-manager.c:65
flow-callbacks.h
SCFree
#define SCFree(p)
Definition: util-mem.h:61
FlowTimeoutCounters_::bypassed_pkts
uint64_t bypassed_pkts
Definition: flow-manager.c:122
FlowCounters_::memcap_pressure_max
uint16_t memcap_pressure_max
Definition: flow-manager.c:664
Flow_::flags
uint32_t flags
Definition: flow.h:421
HostTimeoutHash
uint32_t HostTimeoutHash(SCTime_t ts)
time out hosts from the hash
Definition: host-timeout.c:126
SC_ATOMIC_INITPTR
#define SC_ATOMIC_INITPTR(name)
Definition: util-atomic.h:317
stream-tcp-cache.h
FlowManagerThreadData_::timeout
FlowManagerTimeoutThread timeout
Definition: flow-manager.c:674
FlowCounters
struct FlowCounters_ FlowCounters
FlowCounters_::flow_emerg_mode_enter
uint16_t flow_emerg_mode_enter
Definition: flow-manager.c:648
FLOW_END_FLAG_SHUTDOWN
#define FLOW_END_FLAG_SHUTDOWN
Definition: flow.h:245
FLOW_EMERGENCY
#define FLOW_EMERGENCY
Definition: flow-private.h:37
defrag-hash.h
ippair-timeout.h
FlowRecyclerThreadData_::counter_flow_active
uint16_t counter_flow_active
Definition: flow-manager.c:1036
FlowCounters_::flow_mgr_flows_timeout
uint16_t flow_mgr_flows_timeout
Definition: flow-manager.c:653
FlowManagerTimeoutThread::aside_queue
FlowQueuePrivate aside_queue
Definition: flow-manager.c:279
timeradd
#define timeradd(a, b, r)
Definition: util-time.h:127
FLOW_END_FLAG_TIMEOUT
#define FLOW_END_FLAG_TIMEOUT
Definition: flow.h:243
FlowTimeoutCounters_::flows_notimeout
uint32_t flows_notimeout
Definition: flow-manager.c:115
flow_timeouts_normal
FlowProtoTimeout flow_timeouts_normal[FLOW_PROTO_MAX]
Definition: flow.c:87
FlowNeedsReassembly
bool FlowNeedsReassembly(Flow *f)
Check if a flow needs forced reassembly, or any other processing.
Definition: flow-timeout.c:285
StatsRegisterAvgCounter
uint16_t StatsRegisterAvgCounter(const char *name, struct ThreadVars_ *tv)
Registers a counter, whose value holds the average of all the values assigned to it.
Definition: counters.c:972
StatsSyncCountersIfSignalled
void StatsSyncCountersIfSignalled(ThreadVars *tv)
Definition: counters.c:450
FlowCounters_::flow_mgr_spare
uint16_t flow_mgr_spare
Definition: flow-manager.c:647
FlowTimeoutCounters_::flows_aside
uint32_t flows_aside
Definition: flow-manager.c:118
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
PacketPoolDestroy
void PacketPoolDestroy(void)
Definition: tmqh-packetpool.c:274
flow.h
FlowQueuePrivateAppendFlow
void FlowQueuePrivateAppendFlow(FlowQueuePrivate *fqc, Flow *f)
Definition: flow-queue.c:65
FlowEndCountersRegister
void FlowEndCountersRegister(ThreadVars *t, FlowEndCounters *fec)
Definition: flow-util.c:246
TmThreadsCheckFlag
int TmThreadsCheckFlag(ThreadVars *tv, uint32_t flag)
Check if a thread flag is set.
Definition: tm-threads.c:93
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:238
SCTIME_ADD_SECS
#define SCTIME_ADD_SECS(ts, s)
Definition: util-time.h:64
evicted
Flow * evicted
Definition: flow-hash.h:4
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:952
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
BITS
#define BITS
FlowEndCounters_
Definition: flow-util.h:146
FLOW_SPARE_POOL_BLOCK_SIZE
#define FLOW_SPARE_POOL_BLOCK_SIZE
Definition: flow-spare-pool.h:30
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:76
SC_ATOMIC_AND
#define SC_ATOMIC_AND(name, val)
Bitwise AND a value to our atomic variable.
Definition: util-atomic.h:359
FlowCounters_::flow_emerg_mode_over
uint16_t flow_emerg_mode_over
Definition: flow-manager.c:649
TM_FLAG_MANAGEMENT_TM
#define TM_FLAG_MANAGEMENT_TM
Definition: tm-modules.h:36
suricata_ctl_flags
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:171
detect-engine-threshold.h
FlowTimeoutCounters_::rows_skipped
uint32_t rows_skipped
Definition: flow-manager.c:110
Flow_::thread_id
FlowThreadId thread_id[2]
Definition: flow.h:394
FlowCounters_::flow_mgr_flows_checked
uint16_t flow_mgr_flows_checked
Definition: flow-manager.c:651
ThresholdsExpire
uint32_t ThresholdsExpire(const SCTime_t ts)
Definition: detect-engine-threshold.c:233
SCTIME_USECS
#define SCTIME_USECS(t)
Definition: util-time.h:56
FlowCounters_::flow_mgr_rows_sec
uint16_t flow_mgr_rows_sec
Definition: flow-manager.c:645
FlowTimeoutCounters::flows_aside_needs_work
uint32_t flows_aside_needs_work
Definition: flow-worker.c:62
FQLOCK_UNLOCK
#define FQLOCK_UNLOCK(q)
Definition: flow-queue.h:74
HttpRangeContainersTimeoutHash
uint32_t HttpRangeContainersTimeoutHash(const SCTime_t ts)
Definition: app-layer-htp-range.c:209