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