suricata
flow-manager.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 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 "suricata.h"
27 #include "decode.h"
28 #include "conf.h"
29 #include "threadvars.h"
30 #include "tm-threads.h"
31 #include "runmodes.h"
32 
33 #include "util-random.h"
34 #include "util-time.h"
35 
36 #include "flow.h"
37 #include "flow-queue.h"
38 #include "flow-hash.h"
39 #include "flow-util.h"
40 #include "flow-var.h"
41 #include "flow-private.h"
42 #include "flow-timeout.h"
43 #include "flow-manager.h"
44 #include "flow-storage.h"
45 
46 #include "stream-tcp-private.h"
47 #include "stream-tcp-reassemble.h"
48 #include "stream-tcp.h"
49 
50 #include "util-unittest.h"
51 #include "util-unittest-helper.h"
52 #include "util-byte.h"
53 
54 #include "util-debug.h"
55 #include "util-privs.h"
56 #include "util-signal.h"
57 
58 #include "threads.h"
59 #include "detect.h"
60 #include "detect-engine-state.h"
61 #include "stream.h"
62 
63 #include "app-layer-parser.h"
64 
65 #include "host-timeout.h"
66 #include "defrag-timeout.h"
67 #include "ippair-timeout.h"
68 
69 #include "output-flow.h"
70 
71 /* Run mode selected at suricata.c */
72 extern int run_mode;
73 
74 /** queue to pass flows to cleanup/log thread(s) */
76 
77 /* multi flow mananger support */
78 static uint32_t flowmgr_number = 1;
79 /* atomic counter for flow managers, to assign instance id */
80 SC_ATOMIC_DECLARE(uint32_t, flowmgr_cnt);
81 
82 /* multi flow recycler support */
83 static uint32_t flowrec_number = 1;
84 /* atomic counter for flow recyclers, to assign instance id */
85 SC_ATOMIC_DECLARE(uint32_t, flowrec_cnt);
86 
87 SC_ATOMIC_EXTERN(unsigned int, flow_flags);
88 
91 
94 
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 /* 1 seconds */
109 #define FLOW_NORMAL_MODE_UPDATE_DELAY_SEC 1
110 #define FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC 0
111 /* 0.1 seconds */
112 #define FLOW_EMERG_MODE_UPDATE_DELAY_SEC 0
113 #define FLOW_EMERG_MODE_UPDATE_DELAY_NSEC 100000
114 #define NEW_FLOW_COUNT_COND 10
115 
116 typedef struct FlowTimeoutCounters_ {
117  uint32_t new;
118  uint32_t est;
119  uint32_t clo;
120  uint32_t byp;
121  uint32_t tcp_reuse;
122 
123  uint32_t flows_checked;
124  uint32_t flows_notimeout;
125  uint32_t flows_timeout;
127  uint32_t flows_removed;
128 
129  uint32_t rows_checked;
130  uint32_t rows_skipped;
131  uint32_t rows_empty;
132  uint32_t rows_busy;
133  uint32_t rows_maxlen;
134 
135  uint32_t bypassed_count;
136  uint64_t bypassed_pkts;
137  uint64_t bypassed_bytes;
139 
140 /**
141  * \brief Used to disable flow manager thread(s).
142  *
143  * \todo Kinda hackish since it uses the tv name to identify flow manager
144  * thread. We need an all weather identification scheme.
145  */
147 {
148  /* wake up threads */
149  uint32_t u;
150  for (u = 0; u < flowmgr_number; u++)
152 
154  /* flow manager thread(s) is/are a part of mgmt threads */
155  for (ThreadVars *tv = tv_root[TVT_MGMT]; tv != NULL; tv = tv->next) {
156  if (strncasecmp(tv->name, thread_name_flow_mgr,
157  strlen(thread_name_flow_mgr)) == 0)
158  {
160  }
161  }
163 
164  struct timeval start_ts;
165  struct timeval cur_ts;
166  gettimeofday(&start_ts, NULL);
167 
168 again:
169  gettimeofday(&cur_ts, NULL);
170  if ((cur_ts.tv_sec - start_ts.tv_sec) > 60) {
171  FatalError(SC_ERR_SHUTDOWN, "unable to get all flow manager "
172  "threads to shutdown in time");
173  }
174 
176  for (ThreadVars *tv = tv_root[TVT_MGMT]; tv != NULL; tv = tv->next) {
177  if (strncasecmp(tv->name, thread_name_flow_mgr,
178  strlen(thread_name_flow_mgr)) == 0)
179  {
182  /* sleep outside lock */
183  SleepMsec(1);
184  goto again;
185  }
186  }
187  }
189 
190  /* reset count, so we can kill and respawn (unix socket) */
191  SC_ATOMIC_SET(flowmgr_cnt, 0);
192  return;
193 }
194 
195 /** \internal
196  * \brief get timeout for flow
197  *
198  * \param f flow
199  * \param state flow state
200  *
201  * \retval timeout timeout in seconds
202  */
203 static inline uint32_t FlowGetFlowTimeout(const Flow *f, enum FlowState state)
204 {
205  uint32_t timeout;
206  FlowProtoTimeoutPtr flow_timeouts = SC_ATOMIC_GET(flow_timeouts);
207  switch(state) {
208  default:
209  case FLOW_STATE_NEW:
210  timeout = flow_timeouts[f->protomap].new_timeout;
211  break;
213  timeout = flow_timeouts[f->protomap].est_timeout;
214  break;
215  case FLOW_STATE_CLOSED:
216  timeout = flow_timeouts[f->protomap].closed_timeout;
217  break;
218 #ifdef CAPTURE_OFFLOAD
219  case FLOW_STATE_CAPTURE_BYPASSED:
220  timeout = FLOW_BYPASSED_TIMEOUT;
221  break;
222 #endif
224  timeout = flow_timeouts[f->protomap].bypassed_timeout;
225  break;
226  }
227  return timeout;
228 }
229 
230 /** \internal
231  * \brief check if a flow is timed out
232  *
233  * \param f flow
234  * \param ts timestamp
235  *
236  * \retval 0 not timed out
237  * \retval 1 timed out
238  */
239 static int FlowManagerFlowTimeout(Flow *f, enum FlowState state, struct timeval *ts, int32_t *next_ts)
240 {
241  /* set the timeout value according to the flow operating mode,
242  * flow's state and protocol.*/
243  uint32_t timeout = FlowGetFlowTimeout(f, state);
244 
245  int32_t flow_times_out_at = (int32_t)(f->lastts.tv_sec + timeout);
246  if (*next_ts == 0 || flow_times_out_at < *next_ts)
247  *next_ts = flow_times_out_at;
248 
249  /* do the timeout check */
250  if (flow_times_out_at >= ts->tv_sec) {
251  return 0;
252  }
253 
254  return 1;
255 }
256 
257 static inline int FlowBypassedTimeout(Flow *f, struct timeval *ts,
258  FlowTimeoutCounters *counters)
259 {
260 #ifdef CAPTURE_OFFLOAD
261  if (SC_ATOMIC_GET(f->flow_state) != FLOW_STATE_CAPTURE_BYPASSED) {
262  return 1;
263  }
264 
266  if (fc && fc->BypassUpdate) {
267  /* flow will be possibly updated */
268  uint64_t pkts_tosrc = fc->tosrcpktcnt;
269  uint64_t bytes_tosrc = fc->tosrcbytecnt;
270  uint64_t pkts_todst = fc->todstpktcnt;
271  uint64_t bytes_todst = fc->todstbytecnt;
272  bool update = fc->BypassUpdate(f, fc->bypass_data, ts->tv_sec);
273  if (update) {
274  SCLogDebug("Updated flow: %"PRId64"", FlowGetId(f));
275  pkts_tosrc = fc->tosrcpktcnt - pkts_tosrc;
276  bytes_tosrc = fc->tosrcbytecnt - bytes_tosrc;
277  pkts_todst = fc->todstpktcnt - pkts_todst;
278  bytes_todst = fc->todstbytecnt - bytes_todst;
279  if (f->livedev) {
280  SC_ATOMIC_ADD(f->livedev->bypassed,
281  pkts_tosrc + pkts_todst);
282  }
283  counters->bypassed_pkts += pkts_tosrc + pkts_todst;
284  counters->bypassed_bytes += bytes_tosrc + bytes_todst;
285  return 0;
286  } else {
287  SCLogDebug("No new packet, dead flow %"PRId64"", FlowGetId(f));
288  if (f->livedev) {
289  if (FLOW_IS_IPV4(f)) {
290  LiveDevSubBypassStats(f->livedev, 1, AF_INET);
291  } else if (FLOW_IS_IPV6(f)) {
292  LiveDevSubBypassStats(f->livedev, 1, AF_INET6);
293  }
294  }
295  counters->bypassed_count++;
296  return 1;
297  }
298  }
299 #endif /* CAPTURE_OFFLOAD */
300  return 1;
301 }
302 
303 /** \internal
304  * \brief See if we can really discard this flow. Check use_cnt reference
305  * counter and force reassembly if necessary.
306  *
307  * \param f flow
308  * \param ts timestamp
309  *
310  * \retval 0 not timed out just yet
311  * \retval 1 fully timed out, lets kill it
312  */
313 static inline int FlowManagerFlowTimedOut(Flow *f, struct timeval *ts,
314  FlowTimeoutCounters *counters)
315 {
316  /* never prune a flow that is used by a packet we
317  * are currently processing in one of the threads */
318  if (SC_ATOMIC_GET(f->use_cnt) > 0) {
319  return 0;
320  }
321 
322  if (!FlowBypassedTimeout(f, ts, counters)) {
323  return 0;
324  }
325 
326  int server = 0, client = 0;
327 
328  if (!(f->flags & FLOW_TIMEOUT_REASSEMBLY_DONE) &&
329 #ifdef CAPTURE_OFFLOAD
330  SC_ATOMIC_GET(f->flow_state) != FLOW_STATE_CAPTURE_BYPASSED &&
331 #endif
332  SC_ATOMIC_GET(f->flow_state) != FLOW_STATE_LOCAL_BYPASSED &&
333  FlowForceReassemblyNeedReassembly(f, &server, &client) == 1) {
334  FlowForceReassemblyForFlow(f, server, client);
335  return 0;
336  }
337 #ifdef DEBUG
338  /* this should not be possible */
339  BUG_ON(SC_ATOMIC_GET(f->use_cnt) > 0);
340 #endif
341 
342  return 1;
343 }
344 
345 /**
346  * \internal
347  *
348  * \brief check all flows in a hash row for timing out
349  *
350  * \param f last flow in the hash row
351  * \param ts timestamp
352  * \param emergency bool indicating emergency mode
353  * \param counters ptr to FlowTimeoutCounters structure
354  *
355  * \retval cnt timed out flows
356  */
357 static uint32_t FlowManagerHashRowTimeout(Flow *f, struct timeval *ts,
358  int emergency, FlowTimeoutCounters *counters, int32_t *next_ts)
359 {
360  uint32_t cnt = 0;
361  uint32_t checked = 0;
362 
363  do {
364  checked++;
365 
366  /* check flow timeout based on lastts and state. Both can be
367  * accessed w/o Flow lock as we do have the hash row lock (so flow
368  * can't disappear) and flow_state is atomic. lastts can only
369  * be modified when we have both the flow and hash row lock */
370 
371  enum FlowState state = SC_ATOMIC_GET(f->flow_state);
372 
373  /* timeout logic goes here */
374  if (FlowManagerFlowTimeout(f, state, ts, next_ts) == 0) {
375 
376  counters->flows_notimeout++;
377 
378  f = f->hprev;
379  continue;
380  }
381 
382  /* before grabbing the flow lock, make sure we have at least
383  * 3 packets in the pool */
385 
386  FLOWLOCK_WRLOCK(f);
387 
388  Flow *next_flow = f->hprev;
389 
390  counters->flows_timeout++;
391 
392  /* check if the flow is fully timed out and
393  * ready to be discarded. */
394  if (FlowManagerFlowTimedOut(f, ts, counters) == 1) {
395  /* remove from the hash */
396  if (f->hprev != NULL)
397  f->hprev->hnext = f->hnext;
398  if (f->hnext != NULL)
399  f->hnext->hprev = f->hprev;
400  if (f->fb->head == f)
401  f->fb->head = f->hnext;
402  if (f->fb->tail == f)
403  f->fb->tail = f->hprev;
404 
405  f->hnext = NULL;
406  f->hprev = NULL;
407 
408  if (f->flags & FLOW_TCP_REUSED)
409  counters->tcp_reuse++;
410 
411  if (state == FLOW_STATE_NEW)
413  else if (state == FLOW_STATE_ESTABLISHED)
415  else if (state == FLOW_STATE_CLOSED)
417  else if (state == FLOW_STATE_LOCAL_BYPASSED)
419 #ifdef CAPTURE_OFFLOAD
420  else if (state == FLOW_STATE_CAPTURE_BYPASSED)
422 #endif
423 
424  if (emergency)
427 
428  /* no one is referring to this flow, use_cnt 0, removed from hash
429  * so we can unlock it and pass it to the flow recycler */
430  FLOWLOCK_UNLOCK(f);
432 
433  cnt++;
434 
435  switch (state) {
436  case FLOW_STATE_NEW:
437  default:
438  counters->new++;
439  break;
441  counters->est++;
442  break;
443  case FLOW_STATE_CLOSED:
444  counters->clo++;
445  break;
447 #ifdef CAPTURE_OFFLOAD
448  case FLOW_STATE_CAPTURE_BYPASSED:
449 #endif
450  counters->byp++;
451  break;
452  }
453  counters->flows_removed++;
454  } else {
455  counters->flows_timeout_inuse++;
456  FLOWLOCK_UNLOCK(f);
457  }
458 
459  f = next_flow;
460  } while (f != NULL);
461 
462  counters->flows_checked += checked;
463  if (checked > counters->rows_maxlen)
464  counters->rows_maxlen = checked;
465 
466  return cnt;
467 }
468 
469 /**
470  * \brief time out flows from the hash
471  *
472  * \param ts timestamp
473  * \param try_cnt number of flows to time out max (0 is unlimited)
474  * \param hash_min min hash index to consider
475  * \param hash_max max hash index to consider
476  * \param counters ptr to FlowTimeoutCounters structure
477  *
478  * \retval cnt number of timed out flow
479  */
480 static uint32_t FlowTimeoutHash(struct timeval *ts, uint32_t try_cnt,
481  uint32_t hash_min, uint32_t hash_max,
482  FlowTimeoutCounters *counters)
483 {
484  uint32_t idx = 0;
485  uint32_t cnt = 0;
486  int emergency = 0;
487 
488  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
489  emergency = 1;
490 
491  for (idx = hash_min; idx < hash_max; idx++) {
492  FlowBucket *fb = &flow_hash[idx];
493 
494  counters->rows_checked++;
495 
496  int32_t check_ts = SC_ATOMIC_GET(fb->next_ts);
497  if (check_ts > (int32_t)ts->tv_sec) {
498  counters->rows_skipped++;
499  continue;
500  }
501 
502  /* before grabbing the row lock, make sure we have at least
503  * 9 packets in the pool */
505 
506  if (FBLOCK_TRYLOCK(fb) != 0) {
507  counters->rows_busy++;
508  continue;
509  }
510 
511  /* flow hash bucket is now locked */
512 
513  if (fb->tail == NULL) {
514  SC_ATOMIC_SET(fb->next_ts, INT_MAX);
515  counters->rows_empty++;
516  goto next;
517  }
518 
519  int32_t next_ts = 0;
520 
521  /* we have a flow, or more than one */
522  cnt += FlowManagerHashRowTimeout(fb->tail, ts, emergency, counters, &next_ts);
523 
524  SC_ATOMIC_SET(fb->next_ts, next_ts);
525 
526 next:
527  FBLOCK_UNLOCK(fb);
528 
529  if (try_cnt > 0 && cnt >= try_cnt)
530  break;
531  }
532 
533  return cnt;
534 }
535 
536 /**
537  * \internal
538  *
539  * \brief move all flows out of a hash row
540  *
541  * \param f last flow in the hash row
542  *
543  * \retval cnt removed out flows
544  */
545 static uint32_t FlowManagerHashRowCleanup(Flow *f)
546 {
547  uint32_t cnt = 0;
548 
549  do {
550  FLOWLOCK_WRLOCK(f);
551 
552  Flow *next_flow = f->hprev;
553 
554  int state = SC_ATOMIC_GET(f->flow_state);
555 
556  /* remove from the hash */
557  if (f->hprev != NULL)
558  f->hprev->hnext = f->hnext;
559  if (f->hnext != NULL)
560  f->hnext->hprev = f->hprev;
561  if (f->fb->head == f)
562  f->fb->head = f->hnext;
563  if (f->fb->tail == f)
564  f->fb->tail = f->hprev;
565 
566  f->hnext = NULL;
567  f->hprev = NULL;
568 
569  if (state == FLOW_STATE_NEW)
571  else if (state == FLOW_STATE_ESTABLISHED)
573  else if (state == FLOW_STATE_CLOSED)
575 
577 
578  /* no one is referring to this flow, use_cnt 0, removed from hash
579  * so we can unlock it and move it to the recycle queue. */
580  FLOWLOCK_UNLOCK(f);
581 
583 
584  cnt++;
585 
586  f = next_flow;
587  } while (f != NULL);
588 
589  return cnt;
590 }
591 
592 /**
593  * \brief remove all flows from the hash
594  *
595  * \retval cnt number of removes out flows
596  */
597 static uint32_t FlowCleanupHash(void)
598 {
599  uint32_t cnt = 0;
600 
601  for (uint32_t idx = 0; idx < flow_config.hash_size; idx++) {
602  FlowBucket *fb = &flow_hash[idx];
603 
604  FBLOCK_LOCK(fb);
605 
606  if (fb->tail != NULL) {
607  /* we have a flow, or more than one */
608  cnt += FlowManagerHashRowCleanup(fb->tail);
609  }
610 
611  FBLOCK_UNLOCK(fb);
612  }
613 
614  return cnt;
615 }
616 
617 extern int g_detect_disabled;
618 
619 typedef struct FlowManagerThreadData_ {
620  uint32_t instance;
621  uint32_t min;
622  uint32_t max;
623 
628  uint16_t flow_mgr_spare;
631  uint16_t flow_tcp_reuse;
632 
638 
644 
648 
650 
651 static TmEcode FlowManagerThreadInit(ThreadVars *t, const void *initdata, void **data)
652 {
654  if (ftd == NULL)
655  return TM_ECODE_FAILED;
656 
657  ftd->instance = SC_ATOMIC_ADD(flowmgr_cnt, 1);
658  SCLogDebug("flow manager instance %u", ftd->instance);
659 
660  /* set the min and max value used for hash row walking
661  * each thread has it's own section of the flow hash */
662  uint32_t range = flow_config.hash_size / flowmgr_number;
663  if (ftd->instance == 1)
664  ftd->max = range;
665  else if (ftd->instance == flowmgr_number) {
666  ftd->min = (range * (ftd->instance - 1));
667  ftd->max = flow_config.hash_size;
668  } else {
669  ftd->min = (range * (ftd->instance - 1));
670  ftd->max = (range * ftd->instance);
671  }
673 
674  SCLogDebug("instance %u hash range %u %u", ftd->instance, ftd->min, ftd->max);
675 
676  /* pass thread data back to caller */
677  *data = ftd;
678 
679  ftd->flow_mgr_cnt_clo = StatsRegisterCounter("flow_mgr.closed_pruned", t);
680  ftd->flow_mgr_cnt_new = StatsRegisterCounter("flow_mgr.new_pruned", t);
681  ftd->flow_mgr_cnt_est = StatsRegisterCounter("flow_mgr.est_pruned", t);
682  ftd->flow_mgr_cnt_byp = StatsRegisterCounter("flow_mgr.bypassed_pruned", t);
683  ftd->flow_mgr_spare = StatsRegisterCounter("flow.spare", t);
684  ftd->flow_emerg_mode_enter = StatsRegisterCounter("flow.emerg_mode_entered", t);
685  ftd->flow_emerg_mode_over = StatsRegisterCounter("flow.emerg_mode_over", t);
686  ftd->flow_tcp_reuse = StatsRegisterCounter("flow.tcp_reuse", t);
687 
688  ftd->flow_mgr_flows_checked = StatsRegisterCounter("flow_mgr.flows_checked", t);
689  ftd->flow_mgr_flows_notimeout = StatsRegisterCounter("flow_mgr.flows_notimeout", t);
690  ftd->flow_mgr_flows_timeout = StatsRegisterCounter("flow_mgr.flows_timeout", t);
691  ftd->flow_mgr_flows_timeout_inuse = StatsRegisterCounter("flow_mgr.flows_timeout_inuse", t);
692  ftd->flow_mgr_flows_removed = StatsRegisterCounter("flow_mgr.flows_removed", t);
693 
694  ftd->flow_mgr_rows_checked = StatsRegisterCounter("flow_mgr.rows_checked", t);
695  ftd->flow_mgr_rows_skipped = StatsRegisterCounter("flow_mgr.rows_skipped", t);
696  ftd->flow_mgr_rows_empty = StatsRegisterCounter("flow_mgr.rows_empty", t);
697  ftd->flow_mgr_rows_busy = StatsRegisterCounter("flow_mgr.rows_busy", t);
698  ftd->flow_mgr_rows_maxlen = StatsRegisterCounter("flow_mgr.rows_maxlen", t);
699 
700  ftd->flow_bypassed_cnt_clo = StatsRegisterCounter("flow_bypassed.closed", t);
701  ftd->flow_bypassed_pkts = StatsRegisterCounter("flow_bypassed.pkts", t);
702  ftd->flow_bypassed_bytes = StatsRegisterCounter("flow_bypassed.bytes", t);
703 
704  PacketPoolInit();
705  return TM_ECODE_OK;
706 }
707 
708 static TmEcode FlowManagerThreadDeinit(ThreadVars *t, void *data)
709 {
711  SCFree(data);
712  return TM_ECODE_OK;
713 }
714 
715 
716 /** \brief Thread that manages the flow table and times out flows.
717  *
718  * \param td ThreadVars casted to void ptr
719  *
720  * Keeps an eye on the spare list, alloc flows if needed...
721  */
722 static TmEcode FlowManager(ThreadVars *th_v, void *thread_data)
723 {
724  FlowManagerThreadData *ftd = thread_data;
725  struct timeval ts;
726  uint32_t established_cnt = 0, new_cnt = 0, closing_cnt = 0;
727  int emerg = FALSE;
728  int prev_emerg = FALSE;
729  struct timespec cond_time;
730  int flow_update_delay_sec = FLOW_NORMAL_MODE_UPDATE_DELAY_SEC;
731  int flow_update_delay_nsec = FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC;
732 /* VJ leaving disabled for now, as hosts are only used by tags and the numbers
733  * are really low. Might confuse ppl
734  uint16_t flow_mgr_host_prune = StatsRegisterCounter("hosts.pruned", th_v);
735  uint16_t flow_mgr_host_active = StatsRegisterCounter("hosts.active", th_v);
736  uint16_t flow_mgr_host_spare = StatsRegisterCounter("hosts.spare", th_v);
737 */
738  memset(&ts, 0, sizeof(ts));
739 
740  /* don't start our activities until time is setup */
741  while (!TimeModeIsReady()) {
742  if (suricata_ctl_flags != 0)
743  return TM_ECODE_OK;
744  }
745 
746  while (1)
747  {
748  if (TmThreadsCheckFlag(th_v, THV_PAUSE)) {
752  }
753 
754  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) {
755  emerg = TRUE;
756 
757  if (emerg == TRUE && prev_emerg == FALSE) {
758  prev_emerg = TRUE;
759 
760  SCLogDebug("Flow emergency mode entered...");
761 
762  StatsIncr(th_v, ftd->flow_emerg_mode_enter);
763  }
764  }
765 
766  /* Get the time */
767  memset(&ts, 0, sizeof(ts));
768  TimeGet(&ts);
769  SCLogDebug("ts %" PRIdMAX "", (intmax_t)ts.tv_sec);
770 
771  /* see if we still have enough spare flows */
772  if (ftd->instance == 1)
774 
775  /* try to time out flows */
776  FlowTimeoutCounters counters = { 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0};
777  FlowTimeoutHash(&ts, 0 /* check all */, ftd->min, ftd->max, &counters);
778 
779 
780  if (ftd->instance == 1) {
782  //uint32_t hosts_pruned =
785  }
786 /*
787  StatsAddUI64(th_v, flow_mgr_host_prune, (uint64_t)hosts_pruned);
788  uint32_t hosts_active = HostGetActiveCount();
789  StatsSetUI64(th_v, flow_mgr_host_active, (uint64_t)hosts_active);
790  uint32_t hosts_spare = HostGetSpareCount();
791  StatsSetUI64(th_v, flow_mgr_host_spare, (uint64_t)hosts_spare);
792 */
793  StatsAddUI64(th_v, ftd->flow_mgr_cnt_clo, (uint64_t)counters.clo);
794  StatsAddUI64(th_v, ftd->flow_mgr_cnt_new, (uint64_t)counters.new);
795  StatsAddUI64(th_v, ftd->flow_mgr_cnt_est, (uint64_t)counters.est);
796  StatsAddUI64(th_v, ftd->flow_mgr_cnt_byp, (uint64_t)counters.byp);
797  StatsAddUI64(th_v, ftd->flow_tcp_reuse, (uint64_t)counters.tcp_reuse);
798 
799  StatsSetUI64(th_v, ftd->flow_mgr_flows_checked, (uint64_t)counters.flows_checked);
800  StatsSetUI64(th_v, ftd->flow_mgr_flows_notimeout, (uint64_t)counters.flows_notimeout);
801  StatsSetUI64(th_v, ftd->flow_mgr_flows_timeout, (uint64_t)counters.flows_timeout);
802  StatsSetUI64(th_v, ftd->flow_mgr_flows_removed, (uint64_t)counters.flows_removed);
803  StatsSetUI64(th_v, ftd->flow_mgr_flows_timeout_inuse, (uint64_t)counters.flows_timeout_inuse);
804 
805  StatsSetUI64(th_v, ftd->flow_mgr_rows_checked, (uint64_t)counters.rows_checked);
806  StatsSetUI64(th_v, ftd->flow_mgr_rows_skipped, (uint64_t)counters.rows_skipped);
807  StatsSetUI64(th_v, ftd->flow_mgr_rows_maxlen, (uint64_t)counters.rows_maxlen);
808  StatsSetUI64(th_v, ftd->flow_mgr_rows_busy, (uint64_t)counters.rows_busy);
809  StatsSetUI64(th_v, ftd->flow_mgr_rows_empty, (uint64_t)counters.rows_empty);
810 
811  StatsAddUI64(th_v, ftd->flow_bypassed_cnt_clo, (uint64_t)counters.bypassed_count);
812  StatsAddUI64(th_v, ftd->flow_bypassed_pkts, (uint64_t)counters.bypassed_pkts);
813  StatsAddUI64(th_v, ftd->flow_bypassed_bytes, (uint64_t)counters.bypassed_bytes);
814 
815  uint32_t len = 0;
817  len = flow_spare_q.len;
819  StatsSetUI64(th_v, ftd->flow_mgr_spare, (uint64_t)len);
820 
821  /* Don't fear, FlowManagerThread is here...
822  * clear emergency bit if we have at least xx flows pruned. */
823  if (emerg == TRUE) {
824  SCLogDebug("flow_sparse_q.len = %"PRIu32" prealloc: %"PRIu32
825  "flow_spare_q status: %"PRIu32"%% flows at the queue",
827  /* only if we have pruned this "emergency_recovery" percentage
828  * of flows, we will unset the emergency bit */
830  SC_ATOMIC_AND(flow_flags, ~FLOW_EMERGENCY);
831 
833 
834  emerg = FALSE;
835  prev_emerg = FALSE;
836 
837  flow_update_delay_sec = FLOW_NORMAL_MODE_UPDATE_DELAY_SEC;
838  flow_update_delay_nsec = FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC;
839  SCLogInfo("Flow emergency mode over, back to normal... unsetting"
840  " FLOW_EMERGENCY bit (ts.tv_sec: %"PRIuMAX", "
841  "ts.tv_usec:%"PRIuMAX") flow_spare_q status(): %"PRIu32
842  "%% flows at the queue", (uintmax_t)ts.tv_sec,
843  (uintmax_t)ts.tv_usec, len * 100 / flow_config.prealloc);
844 
845  StatsIncr(th_v, ftd->flow_emerg_mode_over);
846  } else {
847  flow_update_delay_sec = FLOW_EMERG_MODE_UPDATE_DELAY_SEC;
848  flow_update_delay_nsec = FLOW_EMERG_MODE_UPDATE_DELAY_NSEC;
849  }
850  }
851 
852  if (TmThreadsCheckFlag(th_v, THV_KILL)) {
853  StatsSyncCounters(th_v);
854  break;
855  }
856 
857  cond_time.tv_sec = time(NULL) + flow_update_delay_sec;
858  cond_time.tv_nsec = flow_update_delay_nsec;
861  &cond_time);
863 
864  SCLogDebug("woke up... %s", SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY ? "emergency":"");
865 
867  }
868 
869  SCLogPerf("%" PRIu32 " new flows, %" PRIu32 " established flows were "
870  "timed out, %"PRIu32" flows in closed state", new_cnt,
871  established_cnt, closing_cnt);
872 
873  return TM_ECODE_OK;
874 }
875 
876 /** \brief spawn the flow manager thread */
878 {
879  intmax_t setting = 1;
880  (void)ConfGetInt("flow.managers", &setting);
881 
882  if (setting < 1 || setting > 1024) {
884  "invalid flow.managers setting %"PRIdMAX, setting);
885  }
886  flowmgr_number = (uint32_t)setting;
887 
888  SCLogConfig("using %u flow manager threads", flowmgr_number);
891 
893 
894  for (uint32_t u = 0; u < flowmgr_number; u++) {
895  char name[TM_THREAD_NAME_MAX];
896  snprintf(name, sizeof(name), "%s#%02u", thread_name_flow_mgr, u+1);
897 
898  ThreadVars *tv_flowmgr = TmThreadCreateMgmtThreadByName(name,
899  "FlowManager", 0);
900  BUG_ON(tv_flowmgr == NULL);
901 
902  if (tv_flowmgr == NULL) {
903  FatalError(SC_ERR_FATAL, "flow manager thread creation failed");
904  }
905  if (TmThreadSpawn(tv_flowmgr) != TM_ECODE_OK) {
906  FatalError(SC_ERR_FATAL, "flow manager thread spawn failed");
907  }
908  }
909  return;
910 }
911 
912 typedef struct FlowRecyclerThreadData_ {
915 
916 static TmEcode FlowRecyclerThreadInit(ThreadVars *t, const void *initdata, void **data)
917 {
919  if (ftd == NULL)
920  return TM_ECODE_FAILED;
921 
922  if (OutputFlowLogThreadInit(t, NULL, &ftd->output_thread_data) != TM_ECODE_OK) {
923  SCLogError(SC_ERR_THREAD_INIT, "initializing flow log API for thread failed");
924  SCFree(ftd);
925  return TM_ECODE_FAILED;
926  }
927  SCLogDebug("output_thread_data %p", ftd->output_thread_data);
928 
929  *data = ftd;
930  return TM_ECODE_OK;
931 }
932 
933 static TmEcode FlowRecyclerThreadDeinit(ThreadVars *t, void *data)
934 {
936  if (ftd->output_thread_data != NULL)
938 
939  SCFree(data);
940  return TM_ECODE_OK;
941 }
942 
943 /** \brief Thread that manages timed out flows.
944  *
945  * \param td ThreadVars casted to void ptr
946  */
947 static TmEcode FlowRecycler(ThreadVars *th_v, void *thread_data)
948 {
949  struct timeval ts;
950  struct timespec cond_time;
951  int flow_update_delay_sec = FLOW_NORMAL_MODE_UPDATE_DELAY_SEC;
952  int flow_update_delay_nsec = FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC;
953  uint64_t recycled_cnt = 0;
954  FlowRecyclerThreadData *ftd = (FlowRecyclerThreadData *)thread_data;
955  BUG_ON(ftd == NULL);
956 
957  memset(&ts, 0, sizeof(ts));
958 
959  while (1)
960  {
961  if (TmThreadsCheckFlag(th_v, THV_PAUSE)) {
965  }
966 
967  /* Get the time */
968  memset(&ts, 0, sizeof(ts));
969  TimeGet(&ts);
970  SCLogDebug("ts %" PRIdMAX "", (intmax_t)ts.tv_sec);
971 
972  uint32_t len = 0;
976 
977  /* Loop through the queue and clean up all flows in it */
978  if (len) {
979  Flow *f;
980 
981  while ((f = FlowDequeue(&flow_recycle_q)) != NULL) {
982  FLOWLOCK_WRLOCK(f);
983 
984  (void)OutputFlowLog(th_v, ftd->output_thread_data, f);
985 
986  FlowClearMemory (f, f->protomap);
987  FLOWLOCK_UNLOCK(f);
988  FlowMoveToSpare(f);
989  recycled_cnt++;
990  }
991  }
992 
993  SCLogDebug("%u flows to recycle", len);
994 
995  if (TmThreadsCheckFlag(th_v, THV_KILL)) {
996  StatsSyncCounters(th_v);
997  break;
998  }
999 
1000  cond_time.tv_sec = time(NULL) + flow_update_delay_sec;
1001  cond_time.tv_nsec = flow_update_delay_nsec;
1004  &flow_recycler_ctrl_mutex, &cond_time);
1006 
1007  SCLogDebug("woke up...");
1008 
1010  }
1011 
1012  SCLogPerf("%"PRIu64" flows processed", recycled_cnt);
1013 
1014  return TM_ECODE_OK;
1015 }
1016 
1017 static int FlowRecyclerReadyToShutdown(void)
1018 {
1019  uint32_t len = 0;
1023 
1024  return ((len == 0));
1025 }
1026 
1027 /** \brief spawn the flow recycler thread */
1029 {
1030  intmax_t setting = 1;
1031  (void)ConfGetInt("flow.recyclers", &setting);
1032 
1033  if (setting < 1 || setting > 1024) {
1035  "invalid flow.recyclers setting %"PRIdMAX, setting);
1036  }
1037  flowrec_number = (uint32_t)setting;
1038 
1039  SCLogConfig("using %u flow recycler threads", flowrec_number);
1040 
1043 
1044  for (uint32_t u = 0; u < flowrec_number; u++) {
1045  char name[TM_THREAD_NAME_MAX];
1046  snprintf(name, sizeof(name), "%s#%02u", thread_name_flow_rec, u+1);
1047 
1048  ThreadVars *tv_flowrec = TmThreadCreateMgmtThreadByName(name,
1049  "FlowRecycler", 0);
1050 
1051  if (tv_flowrec == NULL) {
1052  FatalError(SC_ERR_FATAL, "flow recycler thread creation failed");
1053  }
1054  if (TmThreadSpawn(tv_flowrec) != TM_ECODE_OK) {
1055  FatalError(SC_ERR_FATAL, "flow recycler thread spawn failed");
1056  }
1057  }
1058  return;
1059 }
1060 
1061 /**
1062  * \brief Used to disable flow recycler thread(s).
1063  *
1064  * \note this should only be called when the flow manager is already gone
1065  *
1066  * \todo Kinda hackish since it uses the tv name to identify flow recycler
1067  * thread. We need an all weather identification scheme.
1068  */
1070 {
1071  int cnt = 0;
1072 
1073  /* move all flows still in the hash to the recycler queue */
1074  FlowCleanupHash();
1075 
1076  /* make sure all flows are processed */
1077  do {
1079  usleep(10);
1080  } while (FlowRecyclerReadyToShutdown() == 0);
1081 
1082  /* wake up threads */
1083  for (uint32_t u = 0; u < flowrec_number; u++) {
1085  }
1086 
1088  /* flow recycler thread(s) is/are a part of mgmt threads */
1089  for (ThreadVars *tv = tv_root[TVT_MGMT]; tv != NULL; tv = tv->next) {
1090  if (strncasecmp(tv->name, thread_name_flow_rec,
1091  strlen(thread_name_flow_rec)) == 0)
1092  {
1094  cnt++;
1095  }
1096  }
1098 
1099  struct timeval start_ts;
1100  struct timeval cur_ts;
1101  gettimeofday(&start_ts, NULL);
1102 
1103 again:
1104  gettimeofday(&cur_ts, NULL);
1105  if ((cur_ts.tv_sec - start_ts.tv_sec) > 60) {
1106  FatalError(SC_ERR_SHUTDOWN, "unable to get all flow recycler "
1107  "threads to shutdown in time");
1108  }
1109 
1111  for (ThreadVars *tv = tv_root[TVT_MGMT]; tv != NULL; tv = tv->next) {
1112  if (strncasecmp(tv->name, thread_name_flow_rec,
1113  strlen(thread_name_flow_rec)) == 0)
1114  {
1117  /* sleep outside lock */
1118  SleepMsec(1);
1119  goto again;
1120  }
1121  }
1122  }
1124 
1125  /* reset count, so we can kill and respawn (unix socket) */
1126  SC_ATOMIC_SET(flowrec_cnt, 0);
1127  return;
1128 }
1129 
1131 {
1132  tmm_modules[TMM_FLOWMANAGER].name = "FlowManager";
1133  tmm_modules[TMM_FLOWMANAGER].ThreadInit = FlowManagerThreadInit;
1134  tmm_modules[TMM_FLOWMANAGER].ThreadDeinit = FlowManagerThreadDeinit;
1135  tmm_modules[TMM_FLOWMANAGER].Management = FlowManager;
1138  SCLogDebug("%s registered", tmm_modules[TMM_FLOWMANAGER].name);
1139 
1140  SC_ATOMIC_INIT(flowmgr_cnt);
1141  SC_ATOMIC_INIT(flow_timeouts);
1142 }
1143 
1145 {
1146  tmm_modules[TMM_FLOWRECYCLER].name = "FlowRecycler";
1147  tmm_modules[TMM_FLOWRECYCLER].ThreadInit = FlowRecyclerThreadInit;
1148  tmm_modules[TMM_FLOWRECYCLER].ThreadDeinit = FlowRecyclerThreadDeinit;
1149  tmm_modules[TMM_FLOWRECYCLER].Management = FlowRecycler;
1152  SCLogDebug("%s registered", tmm_modules[TMM_FLOWRECYCLER].name);
1153 
1154  SC_ATOMIC_INIT(flowrec_cnt);
1155 }
1156 
1157 #ifdef UNITTESTS
1158 
1159 /**
1160  * \test Test the timing out of a flow with a fresh TcpSession
1161  * (just initialized, no data segments) in normal mode.
1162  *
1163  * \retval On success it returns 1 and on failure 0.
1164  */
1165 
1166 static int FlowMgrTest01 (void)
1167 {
1168  TcpSession ssn;
1169  Flow f;
1170  FlowBucket fb;
1171  struct timeval ts;
1172 
1174 
1175  memset(&ssn, 0, sizeof(TcpSession));
1176  memset(&f, 0, sizeof(Flow));
1177  memset(&ts, 0, sizeof(ts));
1178  memset(&fb, 0, sizeof(FlowBucket));
1179 
1180  FBLOCK_INIT(&fb);
1181 
1182  FLOW_INITIALIZE(&f);
1184 
1185  TimeGet(&ts);
1186  f.lastts.tv_sec = ts.tv_sec - 5000;
1187  f.protoctx = &ssn;
1188  f.fb = &fb;
1189 
1190  f.proto = IPPROTO_TCP;
1191 
1192  int32_t next_ts = 0;
1193  int state = SC_ATOMIC_GET(f.flow_state);
1194  FlowTimeoutCounters counters = { 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1195  if (FlowManagerFlowTimeout(&f, state, &ts, &next_ts) != 1 && FlowManagerFlowTimedOut(&f, &ts, &counters) != 1) {
1196  FBLOCK_DESTROY(&fb);
1197  FLOW_DESTROY(&f);
1199  return 0;
1200  }
1201 
1202  FBLOCK_DESTROY(&fb);
1203  FLOW_DESTROY(&f);
1204 
1206  return 1;
1207 }
1208 
1209 /**
1210  * \test Test the timing out of a flow with a TcpSession
1211  * (with data segments) in normal mode.
1212  *
1213  * \retval On success it returns 1 and on failure 0.
1214  */
1215 
1216 static int FlowMgrTest02 (void)
1217 {
1218  TcpSession ssn;
1219  Flow f;
1220  FlowBucket fb;
1221  struct timeval ts;
1222  TcpSegment seg;
1223  TcpStream client;
1224 
1226 
1227  memset(&ssn, 0, sizeof(TcpSession));
1228  memset(&f, 0, sizeof(Flow));
1229  memset(&fb, 0, sizeof(FlowBucket));
1230  memset(&ts, 0, sizeof(ts));
1231  memset(&seg, 0, sizeof(TcpSegment));
1232  memset(&client, 0, sizeof(TcpStream));
1233 
1234  FBLOCK_INIT(&fb);
1235  FLOW_INITIALIZE(&f);
1237 
1238  TimeGet(&ts);
1239  TCP_SEG_LEN(&seg) = 3;
1240  TCPSEG_RB_INSERT(&client.seg_tree, &seg);
1241  ssn.client = client;
1242  ssn.server = client;
1243  ssn.state = TCP_ESTABLISHED;
1244  f.lastts.tv_sec = ts.tv_sec - 5000;
1245  f.protoctx = &ssn;
1246  f.fb = &fb;
1247  f.proto = IPPROTO_TCP;
1248 
1249  int32_t next_ts = 0;
1250  int state = SC_ATOMIC_GET(f.flow_state);
1251  FlowTimeoutCounters counters = { 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1252  if (FlowManagerFlowTimeout(&f, state, &ts, &next_ts) != 1 && FlowManagerFlowTimedOut(&f, &ts, &counters) != 1) {
1253  FBLOCK_DESTROY(&fb);
1254  FLOW_DESTROY(&f);
1256  return 0;
1257  }
1258  FBLOCK_DESTROY(&fb);
1259  FLOW_DESTROY(&f);
1261  return 1;
1262 
1263 }
1264 
1265 /**
1266  * \test Test the timing out of a flow with a fresh TcpSession
1267  * (just initialized, no data segments) in emergency mode.
1268  *
1269  * \retval On success it returns 1 and on failure 0.
1270  */
1271 
1272 static int FlowMgrTest03 (void)
1273 {
1274  TcpSession ssn;
1275  Flow f;
1276  FlowBucket fb;
1277  struct timeval ts;
1278 
1280 
1281  memset(&ssn, 0, sizeof(TcpSession));
1282  memset(&f, 0, sizeof(Flow));
1283  memset(&ts, 0, sizeof(ts));
1284  memset(&fb, 0, sizeof(FlowBucket));
1285 
1286  FBLOCK_INIT(&fb);
1287  FLOW_INITIALIZE(&f);
1289 
1290  TimeGet(&ts);
1291  ssn.state = TCP_SYN_SENT;
1292  f.lastts.tv_sec = ts.tv_sec - 300;
1293  f.protoctx = &ssn;
1294  f.fb = &fb;
1295  f.proto = IPPROTO_TCP;
1296  f.flags |= FLOW_EMERGENCY;
1297 
1298  int next_ts = 0;
1299  int state = SC_ATOMIC_GET(f.flow_state);
1300  FlowTimeoutCounters counters = { 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1301  if (FlowManagerFlowTimeout(&f, state, &ts, &next_ts) != 1 && FlowManagerFlowTimedOut(&f, &ts, &counters) != 1) {
1302  FBLOCK_DESTROY(&fb);
1303  FLOW_DESTROY(&f);
1305  return 0;
1306  }
1307 
1308  FBLOCK_DESTROY(&fb);
1309  FLOW_DESTROY(&f);
1311  return 1;
1312 }
1313 
1314 /**
1315  * \test Test the timing out of a flow with a TcpSession
1316  * (with data segments) in emergency mode.
1317  *
1318  * \retval On success it returns 1 and on failure 0.
1319  */
1320 
1321 static int FlowMgrTest04 (void)
1322 {
1323 
1324  TcpSession ssn;
1325  Flow f;
1326  FlowBucket fb;
1327  struct timeval ts;
1328  TcpSegment seg;
1329  TcpStream client;
1330 
1332 
1333  memset(&ssn, 0, sizeof(TcpSession));
1334  memset(&f, 0, sizeof(Flow));
1335  memset(&fb, 0, sizeof(FlowBucket));
1336  memset(&ts, 0, sizeof(ts));
1337  memset(&seg, 0, sizeof(TcpSegment));
1338  memset(&client, 0, sizeof(TcpStream));
1339 
1340  FBLOCK_INIT(&fb);
1341  FLOW_INITIALIZE(&f);
1343 
1344  TimeGet(&ts);
1345  TCP_SEG_LEN(&seg) = 3;
1346  TCPSEG_RB_INSERT(&client.seg_tree, &seg);
1347  ssn.client = client;
1348  ssn.server = client;
1349  ssn.state = TCP_ESTABLISHED;
1350  f.lastts.tv_sec = ts.tv_sec - 5000;
1351  f.protoctx = &ssn;
1352  f.fb = &fb;
1353  f.proto = IPPROTO_TCP;
1354  f.flags |= FLOW_EMERGENCY;
1355 
1356  int next_ts = 0;
1357  int state = SC_ATOMIC_GET(f.flow_state);
1358  FlowTimeoutCounters counters = { 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1359  if (FlowManagerFlowTimeout(&f, state, &ts, &next_ts) != 1 && FlowManagerFlowTimedOut(&f, &ts, &counters) != 1) {
1360  FBLOCK_DESTROY(&fb);
1361  FLOW_DESTROY(&f);
1363  return 0;
1364  }
1365 
1366  FBLOCK_DESTROY(&fb);
1367  FLOW_DESTROY(&f);
1369  return 1;
1370 }
1371 
1372 /**
1373  * \test Test flow allocations when it reach memcap
1374  *
1375  *
1376  * \retval On success it returns 1 and on failure 0.
1377  */
1378 
1379 static int FlowMgrTest05 (void)
1380 {
1381  int result = 0;
1382 
1384  FlowConfig backup;
1385  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1386 
1387  uint32_t ini = 0;
1388  uint32_t end = flow_spare_q.len;
1389  SC_ATOMIC_SET(flow_config.memcap, 10000);
1390  flow_config.prealloc = 100;
1391 
1392  /* Let's get the flow_spare_q empty */
1393  UTHBuildPacketOfFlows(ini, end, 0);
1394 
1395  /* And now let's try to reach the memcap val */
1396  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1397  ini = end + 1;
1398  end = end + 2;
1399  UTHBuildPacketOfFlows(ini, end, 0);
1400  }
1401 
1402  /* should time out normal */
1403  TimeSetIncrementTime(2000);
1404  ini = end + 1;
1405  end = end + 2;;
1406  UTHBuildPacketOfFlows(ini, end, 0);
1407 
1408  struct timeval ts;
1409  TimeGet(&ts);
1410  /* try to time out flows */
1411  FlowTimeoutCounters counters = { 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1412  FlowTimeoutHash(&ts, 0 /* check all */, 0, flow_config.hash_size, &counters);
1413 
1414  if (flow_recycle_q.len > 0) {
1415  result = 1;
1416  }
1417 
1418  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1419  FlowShutdown();
1420  return result;
1421 }
1422 #endif /* UNITTESTS */
1423 
1424 /**
1425  * \brief Function to register the Flow Unitests.
1426  */
1428 {
1429 #ifdef UNITTESTS
1430  UtRegisterTest("FlowMgrTest01 -- Timeout a flow having fresh TcpSession",
1431  FlowMgrTest01);
1432  UtRegisterTest("FlowMgrTest02 -- Timeout a flow having TcpSession with segments",
1433  FlowMgrTest02);
1434  UtRegisterTest("FlowMgrTest03 -- Timeout a flow in emergency having fresh TcpSession",
1435  FlowMgrTest03);
1436  UtRegisterTest("FlowMgrTest04 -- Timeout a flow in emergency having TcpSession with segments",
1437  FlowMgrTest04);
1438  UtRegisterTest("FlowMgrTest05 -- Test flow Allocations when it reach memcap",
1439  FlowMgrTest05);
1440 #endif /* UNITTESTS */
1441 }
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:67
FlowTimeoutCounters_::rows_empty
uint32_t rows_empty
Definition: flow-manager.c:131
FlowBucket_::tail
Flow * tail
Definition: flow-hash.h:43
util-byte.h
FlowMgrRegisterTests
void FlowMgrRegisterTests(void)
Function to register the Flow Unitests.
Definition: flow-manager.c:1427
FBLOCK_DESTROY
#define FBLOCK_DESTROY(fb)
Definition: flow-hash.h:67
tm-threads.h
ConfGetInt
int ConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:437
OutputFlowLog
TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f)
Run flow logger(s)
Definition: output-flow.c:91
FlowManagerThreadData_::flow_mgr_cnt_est
uint16_t flow_mgr_cnt_est
Definition: flow-manager.c:626
flow_manager_ctrl_mutex
SCCtrlMutex flow_manager_ctrl_mutex
Definition: flow-manager.c:90
TcpStream_
Definition: stream-tcp-private.h:94
len
uint8_t len
Definition: app-layer-dnp3.h:4
ts
uint64_t ts
Definition: source-erf-file.c:2
FlowManagerThreadData_::flow_emerg_mode_enter
uint16_t flow_emerg_mode_enter
Definition: flow-manager.c:629
TmThreadSpawn
TmEcode TmThreadSpawn(ThreadVars *tv)
Spawns a thread associated with the ThreadVars instance tv.
Definition: tm-threads.c:1630
FlowManagerThreadData_::flow_mgr_flows_removed
uint16_t flow_mgr_flows_removed
Definition: flow-manager.c:637
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:1099
run_mode
int run_mode
Definition: suricata.c:201
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:168
FLOW_IS_IPV6
#define FLOW_IS_IPV6(f)
Definition: flow.h:151
FlowManagerThreadData_::max
uint32_t max
Definition: flow-manager.c:622
FlowManagerThreadData_::flow_mgr_cnt_byp
uint16_t flow_mgr_cnt_byp
Definition: flow-manager.c:627
TCP_SEG_LEN
#define TCP_SEG_LEN(seg)
Definition: stream-tcp-private.h:82
ThreadVars_::name
char name[16]
Definition: threadvars.h:64
thread_name_flow_mgr
const char * thread_name_flow_mgr
Definition: runmodes.c:65
FLOW_STATE_ESTABLISHED
@ FLOW_STATE_ESTABLISHED
Definition: flow.h:482
flow-util.h
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
Initialize the previously declared atomic variable and it's lock.
Definition: util-atomic.h:81
FBLOCK_LOCK
#define FBLOCK_LOCK(fb)
Definition: flow-hash.h:68
FBLOCK_INIT
#define FBLOCK_INIT(fb)
Definition: flow-hash.h:66
FlowManagerThreadData_::flow_mgr_rows_skipped
uint16_t flow_mgr_rows_skipped
Definition: flow-manager.c:640
TMM_FLOWRECYCLER
@ TMM_FLOWRECYCLER
Definition: tm-threads-common.h:67
stream-tcp.h
SCFree
#define SCFree(a)
Definition: util-mem.h:322
FLOW_END_FLAG_STATE_NEW
#define FLOW_END_FLAG_STATE_NEW
Definition: flow.h:224
FlowBypassInfo_
Definition: flow.h:501
FlowCnf_::emergency_recovery
uint32_t emergency_recovery
Definition: flow.h:288
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:207
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
FlowCnf_::hash_size
uint32_t hash_size
Definition: flow.h:279
FlowManagerThreadData_::instance
uint32_t instance
Definition: flow-manager.c:620
TcpStream_::seg_tree
struct TCPSEG seg_tree
Definition: stream-tcp-private.h:123
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:335
Flow_::hnext
struct Flow_ * hnext
Definition: flow.h:465
TmThreadsSetFlag
void TmThreadsSetFlag(ThreadVars *tv, uint32_t flag)
Set a thread flag.
Definition: tm-threads.c:97
StatsRegisterGlobalCounter
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:997
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:2
Flow_::proto
uint8_t proto
Definition: flow.h:359
SC_ATOMIC_DECLARE
SC_ATOMIC_DECLARE(uint32_t, flowmgr_cnt)
flow_manager_ctrl_cond
SCCtrlCondT flow_manager_ctrl_cond
Definition: flow-manager.c:89
threads.h
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:340
flow_recycler_ctrl_cond
SCCtrlCondT flow_recycler_ctrl_cond
Definition: flow-manager.c:92
Flow_::protomap
uint8_t protomap
Definition: flow.h:418
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:107
thread_name_flow_rec
const char * thread_name_flow_rec
Definition: runmodes.c:66
FlowInitConfig
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:529
FlowProtoTimeout_
Definition: flow.h:490
StatsSetUI64
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition: counters.c:190
flow-hash.h
FLOW_END_FLAG_STATE_ESTABLISHED
#define FLOW_END_FLAG_STATE_ESTABLISHED
Definition: flow.h:225
TmModuleFlowRecyclerRegister
void TmModuleFlowRecyclerRegister(void)
Definition: flow-manager.c:1144
FlowTimeoutCounters_::flows_removed
uint32_t flows_removed
Definition: flow-manager.c:127
FlowForceReassemblyNeedReassembly
int FlowForceReassemblyNeedReassembly(Flow *f, int *server, int *client)
Check if a flow needs forced reassembly, or any other processing.
Definition: flow-timeout.c:285
FLOW_END_FLAG_STATE_BYPASSED
#define FLOW_END_FLAG_STATE_BYPASSED
Definition: flow.h:231
FlowProtoTimeout_::bypassed_timeout
uint32_t bypassed_timeout
Definition: flow.h:494
FlowBypassInfo_::tosrcbytecnt
uint64_t tosrcbytecnt
Definition: flow.h:506
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
FlowGetMemuse
uint64_t FlowGetMemuse(void)
Definition: flow.c:133
FBLOCK_TRYLOCK
#define FBLOCK_TRYLOCK(fb)
Definition: flow-hash.h:69
tv_root
ThreadVars * tv_root[TVT_MAX]
Definition: tm-threads.c:78
FlowTimeoutCounters_::flows_timeout
uint32_t flows_timeout
Definition: flow-manager.c:125
FlowQueueDestroy
void FlowQueueDestroy(FlowQueue *q)
Destroy a flow queue.
Definition: flow-queue.c:61
util-privs.h
defrag-timeout.h
stream-tcp-reassemble.h
StatsSyncCountersIfSignalled
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:137
FlowMoveToSpare
void FlowMoveToSpare(Flow *f)
Transfer a flow from a queue to the spare queue.
Definition: flow-queue.c:146
FlowTimeoutCounters_::new
uint32_t new
Definition: flow-manager.c:117
LiveDevSubBypassStats
void LiveDevSubBypassStats(LiveDevice *dev, uint64_t cnt, int family)
Definition: util-device.c:565
FlowManagerThreadData_::flow_bypassed_pkts
uint16_t flow_bypassed_pkts
Definition: flow-manager.c:646
SC_ERR_SHUTDOWN
@ SC_ERR_SHUTDOWN
Definition: util-error.h:220
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:79
Flow_::protoctx
void * protoctx
Definition: flow.h:414
FlowManagerThreadData_::flow_bypassed_cnt_clo
uint16_t flow_bypassed_cnt_clo
Definition: flow-manager.c:645
SCCtrlCondSignal
#define SCCtrlCondSignal
Definition: threads-debug.h:384
FLOW_EMERG_MODE_UPDATE_DELAY_NSEC
#define FLOW_EMERG_MODE_UPDATE_DELAY_NSEC
Definition: flow-manager.c:113
SC_ERR_INVALID_ARGUMENTS
@ SC_ERR_INVALID_ARGUMENTS
Definition: util-error.h:82
FlowEnqueue
void FlowEnqueue(FlowQueue *q, Flow *f)
add a flow to a queue
Definition: flow-queue.c:72
TVT_MGMT
@ TVT_MGMT
Definition: tm-threads-common.h:86
FlowQueue_::len
uint32_t len
Definition: flow-queue.h:45
FLOW_TIMEOUT_REASSEMBLY_DONE
#define FLOW_TIMEOUT_REASSEMBLY_DONE
Definition: flow.h:91
util-unittest.h
FlowTimeoutCounters_::bypassed_count
uint32_t bypassed_count
Definition: flow-manager.c:135
THV_PAUSE
#define THV_PAUSE
Definition: threadvars.h:38
FLOW_BYPASSED_TIMEOUT
#define FLOW_BYPASSED_TIMEOUT
Definition: flow-private.h:65
TM_THREAD_NAME_MAX
#define TM_THREAD_NAME_MAX
Definition: tm-threads.h:48
util-unittest-helper.h
FlowCnf_::prealloc
uint32_t prealloc
Definition: flow.h:281
FLOWLOCK_UNLOCK
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:258
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:78
PacketPoolInit
void PacketPoolInit(void)
Definition: tmqh-packetpool.c:370
UTHBuildPacketOfFlows
uint32_t UTHBuildPacketOfFlows(uint32_t start, uint32_t end, uint8_t dir)
Definition: util-unittest-helper.c:902
flow_spare_q
FlowQueue flow_spare_q
Definition: flow.c:93
FlowManagerThreadData_::flow_mgr_rows_busy
uint16_t flow_mgr_rows_busy
Definition: flow-manager.c:642
FLOW_NORMAL_MODE_UPDATE_DELAY_SEC
#define FLOW_NORMAL_MODE_UPDATE_DELAY_SEC
Definition: flow-manager.c:109
FQLOCK_LOCK
#define FQLOCK_LOCK(q)
Definition: flow-queue.h:67
FlowDisableFlowRecyclerThread
void FlowDisableFlowRecyclerThread(void)
Used to disable flow recycler thread(s).
Definition: flow-manager.c:1069
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
FlowTimeoutCounters_::rows_maxlen
uint32_t rows_maxlen
Definition: flow-manager.c:133
FlowTimeoutCounters_::flows_checked
uint32_t flows_checked
Definition: flow-manager.c:123
THV_RUNNING_DONE
#define THV_RUNNING_DONE
Definition: threadvars.h:46
TmThreadsUnsetFlag
void TmThreadsUnsetFlag(ThreadVars *tv, uint32_t flag)
Unset a thread flag.
Definition: tm-threads.c:105
FLOW_CHECK_MEMCAP
#define FLOW_CHECK_MEMCAP(size)
check if a memory alloc would fit in the memcap
Definition: flow-util.h:137
util-signal.h
SC_ERR_THREAD_INIT
@ SC_ERR_THREAD_INIT
Definition: util-error.h:79
FlowManagerThreadData_::flow_mgr_rows_empty
uint16_t flow_mgr_rows_empty
Definition: flow-manager.c:641
SCCtrlCondInit
#define SCCtrlCondInit
Definition: threads-debug.h:383
FlowTimeoutCounters_::byp
uint32_t byp
Definition: flow-manager.c:120
Flow_::fb
struct FlowBucket_ * fb
Definition: flow.h:467
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
FlowManagerThreadData_::flow_bypassed_bytes
uint16_t flow_bypassed_bytes
Definition: flow-manager.c:647
FLOW_STATE_LOCAL_BYPASSED
@ FLOW_STATE_LOCAL_BYPASSED
Definition: flow.h:484
decode.h
util-debug.h
FlowBypassInfo_::todstbytecnt
uint64_t todstbytecnt
Definition: flow.h:508
DefragTimeoutHash
uint32_t DefragTimeoutHash(struct timeval *ts)
time out tracker from the hash
Definition: defrag-timeout.c:119
FlowBypassInfo_::BypassUpdate
bool(* BypassUpdate)(Flow *f, void *data, time_t tsec)
Definition: flow.h:502
OutputFlowLogThreadInit
TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void *initdata, void **data)
thread init for the flow logger This will run the thread init functions for the individual registered...
Definition: output-flow.c:129
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
FlowProtoTimeoutPtr
FlowProtoTimeout * FlowProtoTimeoutPtr
Definition: flow-manager.c:95
FlowManagerThreadData_::flow_mgr_cnt_clo
uint16_t flow_mgr_cnt_clo
Definition: flow-manager.c:624
FLOWLOCK_WRLOCK
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:255
FlowTimeoutsReset
#define FlowTimeoutsReset()
Definition: flow-manager.h:27
FlowDisableFlowManagerThread
void FlowDisableFlowManagerThread(void)
Used to disable flow manager thread(s).
Definition: flow-manager.c:146
SCCtrlCondT
#define SCCtrlCondT
Definition: threads-debug.h:382
PacketPoolWaitForN
void PacketPoolWaitForN(int n)
Wait until we have the requested amount of packets in the pool.
Definition: tmqh-packetpool.c:177
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
TmThreadTestThreadUnPaused
void TmThreadTestThreadUnPaused(ThreadVars *tv)
Tests if the thread represented in the arg has been unpaused or not.
Definition: tm-threads.c:1712
TmModule_::Management
TmEcode(* Management)(ThreadVars *, void *)
Definition: tm-modules.h:59
TimeModeIsReady
bool TimeModeIsReady(void)
Definition: util-time.c:90
Flow_::flow_end_flags
uint8_t flow_end_flags
Definition: flow.h:420
THV_KILL
#define THV_KILL
Definition: threadvars.h:40
FlowCnf_
Definition: flow.h:276
FlowQueueInit
FlowQueue * FlowQueueInit(FlowQueue *q)
Definition: flow-queue.c:47
FlowState
FlowState
Definition: flow.h:480
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:262
FlowBypassInfo_::todstpktcnt
uint64_t todstpktcnt
Definition: flow.h:507
FlowProtoTimeout_::new_timeout
uint32_t new_timeout
Definition: flow.h:491
FlowProtoTimeout_::closed_timeout
uint32_t closed_timeout
Definition: flow.h:493
util-time.h
FlowBypassInfo_::bypass_data
void * bypass_data
Definition: flow.h:504
FlowManagerThreadData_::flow_mgr_spare
uint16_t flow_mgr_spare
Definition: flow-manager.c:628
app-layer-parser.h
TRUE
#define TRUE
Definition: suricata-common.h:33
ThreadVars_::next
struct ThreadVars_ * next
Definition: threadvars.h:122
FlowRecyclerThreadData_
Definition: flow-manager.c:912
TCP_ESTABLISHED
@ TCP_ESTABLISHED
Definition: stream-tcp-private.h:143
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:265
FLOW_IS_IPV4
#define FLOW_IS_IPV4(f)
Definition: flow.h:149
FlowManagerThreadData_::flow_mgr_flows_timeout
uint16_t flow_mgr_flows_timeout
Definition: flow-manager.c:635
tv_root_lock
SCMutex tv_root_lock
Definition: tm-threads.c:81
FALSE
#define FALSE
Definition: suricata-common.h:34
flow_timeouts_emerg
FlowProtoTimeout flow_timeouts_emerg[FLOW_PROTO_MAX]
Definition: flow.c:89
stream.h
SCCtrlMutexLock
#define SCCtrlMutexLock(mut)
Definition: threads-debug.h:376
FlowTimeoutsEmergency
void FlowTimeoutsEmergency(void)
Definition: flow-manager.c:103
TimeSetIncrementTime
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
Definition: util-time.c:182
TcpSegment
Definition: stream-tcp-private.h:61
SCCalloc
#define SCCalloc(nm, a)
Definition: util-mem.h:253
FlowTimeoutCounters
struct FlowTimeoutCounters_ FlowTimeoutCounters
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
FlowManagerThreadSpawn
void FlowManagerThreadSpawn()
spawn the flow manager thread
Definition: flow-manager.c:877
stream-tcp-private.h
conf.h
FlowRecyclerThreadData_::output_thread_data
void * output_thread_data
Definition: flow-manager.c:913
FlowTimeoutCounters_::rows_checked
uint32_t rows_checked
Definition: flow-manager.c:129
FLOW_END_FLAG_EMERGENCY
#define FLOW_END_FLAG_EMERGENCY
Definition: flow.h:227
FBLOCK_UNLOCK
#define FBLOCK_UNLOCK(fb)
Definition: flow-hash.h:70
TmEcode
TmEcode
Definition: tm-threads-common.h:77
FlowClearMemory
int FlowClearMemory(Flow *f, uint8_t proto_map)
Function clear the flow memory before queueing it to spare flow queue.
Definition: flow.c:1044
output-flow.h
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
flow-timeout.h
g_detect_disabled
int g_detect_disabled
Definition: suricata.c:215
FlowManagerThreadData_::flow_mgr_flows_checked
uint16_t flow_mgr_flows_checked
Definition: flow-manager.c:633
flow-queue.h
TmModule_::name
const char * name
Definition: tm-modules.h:44
FlowManagerThreadData_::flow_mgr_flows_timeout_inuse
uint16_t flow_mgr_flows_timeout_inuse
Definition: flow-manager.c:636
FlowRecyclerThreadData
struct FlowRecyclerThreadData_ FlowRecyclerThreadData
FlowBypassInfo_::tosrcpktcnt
uint64_t tosrcpktcnt
Definition: flow.h:505
host-timeout.h
SCCtrlCondTimedwait
#define SCCtrlCondTimedwait
Definition: threads-debug.h:385
FlowRecyclerThreadSpawn
void FlowRecyclerThreadSpawn()
spawn the flow recycler thread
Definition: flow-manager.c:1028
runmodes.h
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
FlowQueue_
Definition: flow-queue.h:41
Flow_::lastts
struct timeval lastts
Definition: flow.h:373
TMM_FLOWMANAGER
@ TMM_FLOWMANAGER
Definition: tm-threads-common.h:66
THV_PAUSED
#define THV_PAUSED
Definition: threadvars.h:39
HostTimeoutHash
uint32_t HostTimeoutHash(struct timeval *ts)
time out hosts from the hash
Definition: host-timeout.c:156
flow_hash
FlowBucket * flow_hash
Definition: flow-hash.c:52
FlowBucket_::head
Flow * head
Definition: flow-hash.h:42
FlowDequeue
Flow * FlowDequeue(FlowQueue *q)
remove a flow from the queue
Definition: flow-queue.c:105
SCCtrlMutexUnlock
#define SCCtrlMutexUnlock(mut)
Definition: threads-debug.h:378
flow-storage.h
FlowTimeoutCounters_::rows_busy
uint32_t rows_busy
Definition: flow-manager.c:132
FlowTimeoutCounters_
Definition: flow-manager.c:116
FlowManagerThreadData_
Definition: flow-manager.c:619
SleepMsec
#define SleepMsec(msec)
Definition: tm-threads.h:44
FLOW_STATE_NEW
@ FLOW_STATE_NEW
Definition: flow.h:481
flow-manager.h
suricata-common.h
SCCtrlMutex
#define SCCtrlMutex
Definition: threads-debug.h:373
FlowManagerThreadData
struct FlowManagerThreadData_ FlowManagerThreadData
FlowTimeoutCounters_::tcp_reuse
uint32_t tcp_reuse
Definition: flow-manager.c:121
flow_config
FlowConfig flow_config
Definition: flow.c:95
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:684
TmModuleFlowManagerRegister
void TmModuleFlowManagerRegister(void)
Definition: flow-manager.c:1130
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:261
FlowTimeoutsInit
void FlowTimeoutsInit(void)
Definition: flow-manager.c:98
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC
#define FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC
Definition: flow-manager.c:110
FlowForceReassemblyForFlow
int FlowForceReassemblyForFlow(Flow *f, int server, int client)
Definition: flow-timeout.c:339
FatalError
#define FatalError(x,...)
Definition: util-debug.h:569
FLOW_END_FLAG_STATE_CLOSED
#define FLOW_END_FLAG_STATE_CLOSED
Definition: flow.h:226
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:272
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
FlowTimeoutCounters_::est
uint32_t est
Definition: flow-manager.c:118
Flow_::livedev
struct LiveDevice_ * livedev
Definition: flow.h:365
threadvars.h
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:147
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
FlowTimeoutCounters_::bypassed_bytes
uint64_t bypassed_bytes
Definition: flow-manager.c:137
FlowManagerThreadData_::flow_mgr_flows_notimeout
uint16_t flow_mgr_flows_notimeout
Definition: flow-manager.c:634
FLOW_TCP_REUSED
#define FLOW_TCP_REUSED
Definition: flow.h:51
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:271
FlowManagerThreadData_::min
uint32_t min
Definition: flow-manager.c:621
FLOW_STATE_CLOSED
@ FLOW_STATE_CLOSED
Definition: flow.h:483
OutputFlowLogThreadDeinit
TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data)
Definition: output-flow.c:171
flow_recycle_q
FlowQueue flow_recycle_q
Definition: flow-manager.c:75
FlowTimeoutCounters_::bypassed_pkts
uint64_t bypassed_pkts
Definition: flow-manager.c:136
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
Flow_::flags
uint32_t flags
Definition: flow.h:394
FlowManagerThreadData_::flow_mgr_rows_maxlen
uint16_t flow_mgr_rows_maxlen
Definition: flow-manager.c:643
util-random.h
SCCtrlMutexInit
#define SCCtrlMutexInit(mut, mutattr)
Definition: threads-debug.h:375
TimeGet
void TimeGet(struct timeval *tv)
Definition: util-time.c:153
FlowGetStorageById
void * FlowGetStorageById(Flow *f, int id)
Definition: flow-storage.c:39
FLOW_END_FLAG_SHUTDOWN
#define FLOW_END_FLAG_SHUTDOWN
Definition: flow.h:230
FLOW_EMERGENCY
#define FLOW_EMERGENCY
Definition: flow-private.h:37
IPPairTimeoutHash
uint32_t IPPairTimeoutHash(struct timeval *ts)
time out ippairs from the hash
Definition: ippair-timeout.c:142
suricata.h
FlowManagerThreadData_::flow_emerg_mode_over
uint16_t flow_emerg_mode_over
Definition: flow-manager.c:630
ippair-timeout.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:38
FLOW_END_FLAG_TIMEOUT
#define FLOW_END_FLAG_TIMEOUT
Definition: flow.h:228
StatsSyncCounters
#define StatsSyncCounters(tv)
Definition: counters.h:134
FlowTimeoutCounters_::flows_notimeout
uint32_t flows_notimeout
Definition: flow-manager.c:124
flow_timeouts_normal
FlowProtoTimeout flow_timeouts_normal[FLOW_PROTO_MAX]
Definition: flow.c:88
Flow_::hprev
struct Flow_ * hprev
Definition: flow.h:466
FlowProtoTimeout_::est_timeout
uint32_t est_timeout
Definition: flow.h:492
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:192
FlowUpdateSpareFlows
int FlowUpdateSpareFlows(void)
Make sure we have enough spare flows.
Definition: flow.c:158
TcpSession_
Definition: stream-tcp-private.h:260
PacketPoolDestroy
void PacketPoolDestroy(void)
Definition: tmqh-packetpool.c:407
FlowTimeoutCounters_::clo
uint32_t clo
Definition: flow-manager.c:119
flow.h
TmThreadsCheckFlag
int TmThreadsCheckFlag(ThreadVars *tv, uint32_t flag)
Check if a thread flag is set.
Definition: tm-threads.c:89
GetFlowBypassInfoID
int GetFlowBypassInfoID(void)
Definition: flow-util.c:209
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:939
FlowTimeoutCounters_::flows_timeout_inuse
uint32_t flows_timeout_inuse
Definition: flow-manager.c:126
flow_recycler_ctrl_mutex
SCCtrlMutex flow_recycler_ctrl_mutex
Definition: flow-manager.c:93
flow-var.h
FLOW_EMERG_MODE_UPDATE_DELAY_SEC
#define FLOW_EMERG_MODE_UPDATE_DELAY_SEC
Definition: flow-manager.c:112
FlowManagerThreadData_::flow_tcp_reuse
uint16_t flow_tcp_reuse
Definition: flow-manager.c:631
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
FlowManagerThreadData_::flow_mgr_cnt_new
uint16_t flow_mgr_cnt_new
Definition: flow-manager.c:625
FlowManagerThreadData_::flow_mgr_rows_checked
uint16_t flow_mgr_rows_checked
Definition: flow-manager.c:639
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:70
SC_ATOMIC_AND
#define SC_ATOMIC_AND(name, val)
Bitwise AND a value from our atomic variable.
Definition: util-atomic.h:141
TCP_SYN_SENT
@ TCP_SYN_SENT
Definition: stream-tcp-private.h:141
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:198
FlowTimeoutCounters_::rows_skipped
uint32_t rows_skipped
Definition: flow-manager.c:130
FQLOCK_UNLOCK
#define FQLOCK_UNLOCK(q)
Definition: flow-queue.h:69