suricata
flow.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 Victor Julien <victor@inliniac.net>
22  *
23  * Flow implementation.
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 
29 #include "action-globals.h"
30 #include "packet.h"
31 #include "decode.h"
32 #include "conf.h"
33 #include "threadvars.h"
34 
35 #include "util-random.h"
36 #include "util-time.h"
37 
38 #include "flow.h"
39 #include "flow-bindgen.h"
40 #include "flow-queue.h"
41 #include "flow-hash.h"
42 #include "flow-util.h"
43 #include "flow-private.h"
44 #include "flow-manager.h"
45 #include "flow-storage.h"
46 #include "flow-bypass.h"
47 #include "flow-spare-pool.h"
48 #include "flow-callbacks.h"
49 
50 #include "stream-tcp-private.h"
51 
52 #include "util-unittest.h"
53 #include "util-unittest-helper.h"
54 #include "util-byte.h"
55 #include "util-misc.h"
56 #include "util-macset.h"
57 #include "util-flow-rate.h"
58 
59 #include "util-debug.h"
60 
61 #include "rust.h"
62 #include "app-layer-parser.h"
63 #include "app-layer-expectation.h"
64 
65 #define FLOW_DEFAULT_EMERGENCY_RECOVERY 30
66 
67 //#define FLOW_DEFAULT_HASHSIZE 262144
68 #define FLOW_DEFAULT_HASHSIZE 65536
69 //#define FLOW_DEFAULT_MEMCAP 128 * 1024 * 1024 /* 128 MB */
70 #define FLOW_DEFAULT_MEMCAP (32 * 1024 * 1024) /* 32 MB */
71 
72 #define FLOW_DEFAULT_PREALLOC 10000
73 
75 
76 /** atomic int that is used when freeing a flow from the hash. In this
77  * case we walk the hash to find a flow to free. This var records where
78  * we left off in the hash. Without this only the top rows of the hash
79  * are freed. This isn't just about fairness. Under severe pressure, the
80  * hash rows on top would be all freed and the time to find a flow to
81  * free increased with every run. */
82 SC_ATOMIC_DECLARE(unsigned int, flow_prune_idx);
83 
84 /** atomic flags */
85 SC_ATOMIC_DECLARE(unsigned int, flow_flags);
86 
87 /** FlowProto specific timeouts and free/state functions */
88 
93 
95 
96 /** flow memuse counter (atomic), for enforcing memcap limit */
97 SC_ATOMIC_DECLARE(uint64_t, flow_memuse);
98 
99 void FlowRegisterTests(void);
100 void FlowInitFlowProto(void);
101 int FlowSetProtoFreeFunc(uint8_t, void (*Free)(void *));
102 
103 /**
104  * \brief Update memcap value
105  *
106  * \param size new memcap value
107  */
108 int FlowSetMemcap(uint64_t size)
109 {
110  if ((uint64_t)SC_ATOMIC_GET(flow_memuse) < size) {
111  SC_ATOMIC_SET(flow_config.memcap, size);
112  return 1;
113  }
114 
115  return 0;
116 }
117 
118 /**
119  * \brief Return memcap value
120  *
121  * \retval memcap value
122  */
123 uint64_t FlowGetMemcap(void)
124 {
125  uint64_t memcapcopy = SC_ATOMIC_GET(flow_config.memcap);
126  return memcapcopy;
127 }
128 
129 uint64_t FlowGetMemuse(void)
130 {
131  uint64_t memusecopy = SC_ATOMIC_GET(flow_memuse);
132  return memusecopy;
133 }
134 
136 {
137  return flow_config.memcap_policy;
138 }
139 
141 {
142  if (f == NULL || f->proto == 0)
143  return;
144 
146  f->alstate = NULL;
147  f->alparser = NULL;
148 }
149 
150 /** \brief Set flag to indicate that flow has alerts
151  *
152  * \param f flow
153  */
155 {
156  f->flags |= FLOW_HAS_ALERTS;
157 }
158 
159 /** \brief Check if flow has alerts
160  *
161  * \param f flow
162  * \retval 1 has alerts
163  * \retval 0 has not alerts
164  */
165 int FlowHasAlerts(const Flow *f)
166 {
167  if (f->flags & FLOW_HAS_ALERTS) {
168  return 1;
169  }
170 
171  return 0;
172 }
173 
174 /** \brief Set flag to indicate to change proto for the flow
175  *
176  * \param f flow
177  */
179 {
180  f->flags |= FLOW_CHANGE_PROTO;
181 }
182 
183 /** \brief Unset flag to indicate to change proto for the flow
184  *
185  * \param f flow
186  */
188 {
189  f->flags &= ~FLOW_CHANGE_PROTO;
190 }
191 
192 /** \brief Check if change proto flag is set for flow
193  * \param f flow
194  * \retval 1 change proto flag is set
195  * \retval 0 change proto flag is not set
196  */
198 {
199  if (f->flags & FLOW_CHANGE_PROTO) {
200  return 1;
201  }
202 
203  return 0;
204 }
205 
206 static inline void FlowSwapFlags(Flow *f)
207 {
210 
215 
217 }
218 
219 static inline void FlowSwapFileFlags(Flow *f)
220 {
222  SWAP_FLAGS(f->file_flags, FLOWFILE_NO_STORE_TS, FLOWFILE_NO_STORE_TC);
226 }
227 
228 static inline void TcpStreamFlowSwap(Flow *f)
229 {
230  TcpSession *ssn = f->protoctx;
231  SWAP_VARS(TcpStream, ssn->server, ssn->client);
232  if (ssn->data_first_seen_dir & STREAM_TOSERVER) {
233  ssn->data_first_seen_dir = STREAM_TOCLIENT;
234  } else if (ssn->data_first_seen_dir & STREAM_TOCLIENT) {
235  ssn->data_first_seen_dir = STREAM_TOSERVER;
236  }
237 }
238 
239 /** \brief swap the flow's direction
240  * \note leaves the 'header' untouched. Interpret that based
241  * on FLOW_DIR_REVERSED flag.
242  * \warning: only valid before applayer parsing started. This
243  * function doesn't swap anything in Flow::alparser,
244  * Flow::alstate
245  */
246 void FlowSwap(Flow *f)
247 {
248  f->flags |= FLOW_DIR_REVERSED;
249 
252 
253  FlowSwapFlags(f);
254  FlowSwapFileFlags(f);
255 
256  SWAP_VARS(FlowThreadId, f->thread_id[0], f->thread_id[1]);
257 
258  if (f->proto == IPPROTO_TCP) {
259  TcpStreamFlowSwap(f);
260  }
261 
265 
266  /* not touching Flow::alparser and Flow::alstate */
267 
268  SWAP_VARS(const void *, f->sgh_toclient, f->sgh_toserver);
269 
270  SWAP_VARS(uint32_t, f->todstpktcnt, f->tosrcpktcnt);
271  SWAP_VARS(uint64_t, f->todstbytecnt, f->tosrcbytecnt);
272 
273  if (MacSetFlowStorageEnabled()) {
275  if (ms != NULL) {
276  MacSetSwap(ms);
277  }
278  }
279 }
280 
281 /**
282  * \brief determine the direction of the packet compared to the flow
283  * \retval 0 to_server
284  * \retval 1 to_client
285  */
286 int FlowGetPacketDirection(const Flow *f, const Packet *p)
287 {
288  const int reverse = (f->flags & FLOW_DIR_REVERSED) != 0;
289 
290  if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) {
291  if (!(CMP_PORT(p->sp,p->dp))) {
292  /* update flags and counters */
293  if (CMP_PORT(f->sp,p->sp)) {
294  return TOSERVER ^ reverse;
295  } else {
296  return TOCLIENT ^ reverse;
297  }
298  } else {
299  if (CMP_ADDR(&f->src,&p->src)) {
300  return TOSERVER ^ reverse;
301  } else {
302  return TOCLIENT ^ reverse;
303  }
304  }
305  } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) {
306  if (CMP_ADDR(&f->src,&p->src)) {
307  return TOSERVER ^ reverse;
308  } else {
309  return TOCLIENT ^ reverse;
310  }
311  }
312 
313  /* default to toserver */
314  return TOSERVER;
315 }
316 
317 /**
318  * \brief Check to update "seen" flags
319  *
320  * \param p packet
321  *
322  * \retval 1 true
323  * \retval 0 false
324  */
325 static inline int FlowUpdateSeenFlag(const Packet *p)
326 {
327  if (PacketIsICMPv4(p)) {
328  if (ICMPV4_IS_ERROR_MSG(p->icmp_s.type)) {
329  return 0;
330  }
331  }
332 
333  return 1;
334 }
335 
336 static inline void FlowUpdateTtlTS(Flow *f, uint8_t ttl)
337 {
338  if (f->min_ttl_toserver == 0) {
339  f->min_ttl_toserver = ttl;
340  } else {
341  f->min_ttl_toserver = MIN(f->min_ttl_toserver, ttl);
342  }
343  f->max_ttl_toserver = MAX(f->max_ttl_toserver, ttl);
344 }
345 
346 static inline void FlowUpdateTtlTC(Flow *f, uint8_t ttl)
347 {
348  if (f->min_ttl_toclient == 0) {
349  f->min_ttl_toclient = ttl;
350  } else {
351  f->min_ttl_toclient = MIN(f->min_ttl_toclient, ttl);
352  }
353  f->max_ttl_toclient = MAX(f->max_ttl_toclient, ttl);
354 }
355 
356 static inline void FlowUpdateFlowRate(
357  ThreadVars *tv, DecodeThreadVars *dtv, Flow *f, const Packet *p, int dir)
358 {
359  if (FlowRateStorageEnabled()) {
360  /* No need to update the struct if flow is already marked as elephant flow */
361  if ((dir == TOSERVER) && (f->flags & FLOW_IS_ELEPHANT_TOSERVER))
362  return;
363  if ((dir == TOCLIENT) && (f->flags & FLOW_IS_ELEPHANT_TOCLIENT))
364  return;
366  if (frs != NULL) {
367  FlowRateStoreUpdate(frs, p->ts, GET_PKT_LEN(p), dir);
368  bool fr_exceeds = FlowRateIsExceeding(frs, dir);
369  if (fr_exceeds) {
370  SCLogDebug("Flow rate for flow %p exceeds the configured values, marking it as an "
371  "elephant flow",
372  f);
373  if (dir == TOSERVER) {
375  if (tv != NULL) {
376  if ((f->flags & FLOW_IS_ELEPHANT_TOCLIENT) == 0) {
378  }
380  }
381  } else {
383  if (tv != NULL) {
384  if ((f->flags & FLOW_IS_ELEPHANT_TOSERVER) == 0) {
386  }
388  }
389  }
390  }
391  }
392  }
393 }
394 
395 static inline void FlowUpdateEthernet(
396  ThreadVars *tv, DecodeThreadVars *dtv, Flow *f, const Packet *p, bool toserver)
397 {
398  if (PacketIsEthernet(p) && MacSetFlowStorageEnabled()) {
399  const EthernetHdr *ethh = PacketGetEthernet(p);
401  if (ms != NULL) {
402  if (toserver) {
403  MacSetAddWithCtr(ms, ethh->eth_src, ethh->eth_dst, tv,
406  } else {
407  MacSetAddWithCtr(ms, ethh->eth_dst, ethh->eth_src, tv,
410  }
411  }
412  }
413 }
414 
415 /** \brief Update Packet and Flow
416  *
417  * Updates packet and flow based on the new packet.
418  *
419  * \param f locked flow
420  * \param p packet
421  *
422  * \note overwrites p::flowflags
423  */
425 {
426  SCLogDebug("packet %" PRIu64 " -- flow %p", PcapPacketCntGet(p), f);
427 
428  const int pkt_dir = FlowGetPacketDirection(f, p);
429 #ifdef CAPTURE_OFFLOAD
430  int state = f->flow_state;
431 
432  if (state != FLOW_STATE_CAPTURE_BYPASSED) {
433 #endif
434  /* update the last seen timestamp of this flow */
435  if (SCTIME_CMP_GT(p->ts, f->lastts)) {
436  f->lastts = p->ts;
437  }
438 #ifdef CAPTURE_OFFLOAD
439  } else {
440  FlowProtoTimeoutPtr flow_timeouts = SC_ATOMIC_GET(flow_timeouts);
441  /* still seeing packet, we downgrade to local bypass */
442  if (SCTIME_SECS(p->ts) - SCTIME_SECS(f->lastts) >
443  flow_timeouts[f->protomap].bypassed_timeout / 2) {
444  SCLogDebug("Downgrading flow to local bypass");
445  f->lastts = p->ts;
447  } else {
448  /* In IPS mode the packet could come from the other interface so it would
449  * need to be bypassed */
450  if (EngineModeIsIPS()) {
451  BypassedFlowUpdate(f, p);
452  }
453  }
454  }
455 #endif
456  /* update flags and counters */
457  if (pkt_dir == TOSERVER) {
458  f->todstpktcnt++;
459  f->todstbytecnt += GET_PKT_LEN(p);
460  FlowUpdateFlowRate(tv, dtv, f, p, TOSERVER);
462  if (!(f->flags & FLOW_TO_DST_SEEN)) {
463  if (FlowUpdateSeenFlag(p)) {
464  f->flags |= FLOW_TO_DST_SEEN;
467  }
468  }
469  /* xfer proto detect ts flag to first packet in ts dir */
470  if (f->flags & FLOW_PROTO_DETECT_TS_DONE) {
473  }
474  FlowUpdateEthernet(tv, dtv, f, p, true);
475  /* update flow's ttl fields if needed */
476  if (PacketIsIPv4(p)) {
477  const IPV4Hdr *ip4h = PacketGetIPv4(p);
478  FlowUpdateTtlTS(f, IPV4_GET_RAW_IPTTL(ip4h));
479  } else if (PacketIsIPv6(p)) {
480  const IPV6Hdr *ip6h = PacketGetIPv6(p);
481  FlowUpdateTtlTS(f, IPV6_GET_RAW_HLIM(ip6h));
482  }
483  } else {
484  f->tosrcpktcnt++;
485  f->tosrcbytecnt += GET_PKT_LEN(p);
486  FlowUpdateFlowRate(tv, dtv, f, p, TOCLIENT);
488  if (!(f->flags & FLOW_TO_SRC_SEEN)) {
489  if (FlowUpdateSeenFlag(p)) {
490  f->flags |= FLOW_TO_SRC_SEEN;
493  }
494  }
495  /* xfer proto detect tc flag to first packet in tc dir */
496  if (f->flags & FLOW_PROTO_DETECT_TC_DONE) {
499  }
500  FlowUpdateEthernet(tv, dtv, f, p, false);
501  /* update flow's ttl fields if needed */
502  if (PacketIsIPv4(p)) {
503  const IPV4Hdr *ip4h = PacketGetIPv4(p);
504  FlowUpdateTtlTC(f, IPV4_GET_RAW_IPTTL(ip4h));
505  } else if (PacketIsIPv6(p)) {
506  const IPV6Hdr *ip6h = PacketGetIPv6(p);
507  FlowUpdateTtlTC(f, IPV6_GET_RAW_HLIM(ip6h));
508  }
509  }
510  if (f->thread_id[pkt_dir] == 0) {
511  f->thread_id[pkt_dir] = (FlowThreadId)tv->id;
512  }
513 
515  SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
517 
518  } else if (f->proto == IPPROTO_TCP) {
519  TcpSession *ssn = (TcpSession *)f->protoctx;
520  if (ssn != NULL && ssn->state >= TCP_ESTABLISHED) {
522  }
523  } else if ((f->flags & (FLOW_TO_DST_SEEN|FLOW_TO_SRC_SEEN)) ==
525  SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
527 
528  if (
529 #ifdef CAPTURE_OFFLOAD
530  (f->flow_state != FLOW_STATE_CAPTURE_BYPASSED) &&
531 #endif
534  }
535  }
536 
537  if (f->flags & FLOW_ACTION_DROP) {
538  if (f->flags & FLOW_ACTION_BY_FIREWALL) {
540  } else if (f->flags & FLOW_ACTION_BY_EXCEPTION_POLICY) {
542  } else {
544  }
545  }
546 
547  if (f->flags & FLOW_NOPAYLOAD_INSPECTION) {
548  SCLogDebug("setting FLOW_NOPAYLOAD_INSPECTION flag on flow %p", f);
549  DecodeSetNoPayloadInspectionFlag(p);
550  }
551 
553 }
554 
555 /** \brief Entry point for packet flow handling
556  *
557  * This is called for every packet.
558  *
559  * \param tv threadvars
560  * \param dtv decode thread vars (for flow output api thread data)
561  * \param p packet to handle flow for
562  */
564 {
565  /* Get this packet's flow from the hash. FlowHandlePacket() will setup
566  * a new flow if necessary. If we get NULL, we're out of flow memory.
567  * The returned flow is locked. */
568  Flow *f = FlowGetFlowFromHash(tv, fls, p, &p->flow);
569  if (f != NULL) {
570  /* set the flow in the packet */
571  p->flags |= PKT_HAS_FLOW;
572  }
573 }
574 
575 /** \brief initialize the configuration
576  * \warning Not thread safe */
577 void FlowInitConfig(bool quiet)
578 {
579  SCLogDebug("initializing flow engine...");
580 
581  memset(&flow_config, 0, sizeof(flow_config));
582  SC_ATOMIC_INIT(flow_flags);
583  SC_ATOMIC_INIT(flow_memuse);
584  SC_ATOMIC_INIT(flow_prune_idx);
585  SC_ATOMIC_INIT(flow_config.memcap);
587 
588  /* set defaults */
589  flow_config.hash_rand = (uint32_t)RandomGet();
593 
594  /* If we have specific config, overwrite the defaults with them,
595  * otherwise, leave the default values */
596  intmax_t val = 0;
597  if (SCConfGetInt("flow.emergency-recovery", &val) == 1) {
598  if (val <= 100 && val >= 1) {
599  flow_config.emergency_recovery = (uint8_t)val;
600  } else {
601  SCLogError("flow.emergency-recovery must be in the range of "
602  "1 and 100 (as percentage)");
604  }
605  } else {
606  SCLogDebug("flow.emergency-recovery, using default value");
608  }
609 
610  /* Check if we have memcap and hash_size defined at config */
611  const char *conf_val;
612  uint32_t configval = 0;
613 
614  /** set config values for memcap, prealloc and hash_size */
615  uint64_t flow_memcap_copy = 0;
616  if ((SCConfGet("flow.memcap", &conf_val)) == 1) {
617  if (conf_val == NULL) {
618  FatalError("Invalid value for flow.memcap: NULL");
619  }
620 
621  if (ParseSizeStringU64(conf_val, &flow_memcap_copy) < 0) {
622  SCLogError("Error parsing flow.memcap "
623  "from conf file - %s. Killing engine",
624  conf_val);
625  exit(EXIT_FAILURE);
626  } else {
627  SC_ATOMIC_SET(flow_config.memcap, flow_memcap_copy);
628  }
629  }
630  if ((SCConfGet("flow.hash-size", &conf_val)) == 1) {
631  if (conf_val == NULL) {
632  FatalError("Invalid value for flow.hash-size: NULL");
633  }
634 
635  if (StringParseUint32(&configval, 10, strlen(conf_val), conf_val) && configval != 0) {
636  flow_config.hash_size = configval;
637  } else {
638  FatalError("Invalid value for flow.hash-size. Must be a numeric value in the range "
639  "1-4294967295");
640  }
641  }
642  if ((SCConfGet("flow.prealloc", &conf_val)) == 1) {
643  if (conf_val == NULL) {
644  FatalError("Invalid value for flow.prealloc: NULL");
645  }
646 
647  if (StringParseUint32(&configval, 10, strlen(conf_val),
648  conf_val) > 0) {
649  flow_config.prealloc = configval;
650  }
651  }
652 
653  flow_config.memcap_policy = ExceptionPolicyParse("flow.memcap-policy", false);
654 
655  SCLogDebug("Flow config from suricata.yaml: memcap: %"PRIu64", hash-size: "
656  "%"PRIu32", prealloc: %"PRIu32, SC_ATOMIC_GET(flow_config.memcap),
658 
659  /* alloc hash memory */
660  uint64_t hash_size = flow_config.hash_size * sizeof(FlowBucket);
661  if (!(FLOW_CHECK_MEMCAP(hash_size))) {
662  SCLogError("allocating flow hash failed: "
663  "max flow memcap is smaller than projected hash size. "
664  "Memcap: %" PRIu64 ", Hash table size %" PRIu64 ". Calculate "
665  "total hash size by multiplying \"flow.hash-size\" with %" PRIuMAX ", "
666  "which is the hash bucket size.",
667  SC_ATOMIC_GET(flow_config.memcap), hash_size, (uintmax_t)sizeof(FlowBucket));
668  exit(EXIT_FAILURE);
669  }
670  flow_hash = SCMallocAligned(flow_config.hash_size * sizeof(FlowBucket), CLS);
671  if (unlikely(flow_hash == NULL)) {
672  FatalError("Fatal error encountered in FlowInitConfig. Exiting...");
673  }
674  memset(flow_hash, 0, flow_config.hash_size * sizeof(FlowBucket));
675 
676  uint32_t i = 0;
677  for (i = 0; i < flow_config.hash_size; i++) {
678  FBLOCK_INIT(&flow_hash[i]);
679  SC_ATOMIC_INIT(flow_hash[i].next_ts);
680  }
681  (void) SC_ATOMIC_ADD(flow_memuse, (flow_config.hash_size * sizeof(FlowBucket)));
682 
683  if (!quiet) {
684  SCLogConfig("allocated %"PRIu64" bytes of memory for the flow hash... "
685  "%" PRIu32 " buckets of size %" PRIuMAX "",
686  SC_ATOMIC_GET(flow_memuse), flow_config.hash_size,
687  (uintmax_t)sizeof(FlowBucket));
688  }
690  if (!quiet) {
691  SCLogConfig("flow memory usage: %"PRIu64" bytes, maximum: %"PRIu64,
692  SC_ATOMIC_GET(flow_memuse), SC_ATOMIC_GET(flow_config.memcap));
693  }
694 
696 
697  uint32_t sz = sizeof(Flow) + SCFlowStorageSize();
698  SCLogConfig("flow size %u, memcap allows for %" PRIu64 " flows. Per hash row in perfect "
699  "conditions %" PRIu64,
700  sz, flow_memcap_copy / sz, (flow_memcap_copy / sz) / flow_config.hash_size);
701 }
702 
703 void FlowReset(void)
704 {
705  // resets the flows (for reuse by fuzzing)
706  for (uint32_t u = 0; u < flow_config.hash_size; u++) {
707  Flow *f = flow_hash[u].head;
708  while (f) {
709  Flow *n = f->next;
710  uint8_t proto_map = FlowGetProtoMapping(f->proto);
711  FlowClearMemory(f, proto_map);
712  FlowFree(f);
713  f = n;
714  }
715  flow_hash[u].head = NULL;
716  }
717 }
718 
719 /** \brief shutdown the flow engine
720  * \warning Not thread safe */
721 void FlowShutdown(void)
722 {
723  Flow *f;
724  while ((f = FlowDequeue(&flow_recycle_q))) {
725  FlowFree(f);
726  }
727 
728  /* clear and free the hash */
729  if (flow_hash != NULL) {
730  /* clean up flow mutexes */
731  for (uint32_t u = 0; u < flow_config.hash_size; u++) {
732  f = flow_hash[u].head;
733  while (f) {
734  Flow *n = f->next;
735  uint8_t proto_map = FlowGetProtoMapping(f->proto);
736  FlowClearMemory(f, proto_map);
737  FlowFree(f);
738  f = n;
739  }
740  f = flow_hash[u].evicted;
741  while (f) {
742  Flow *n = f->next;
743  uint8_t proto_map = FlowGetProtoMapping(f->proto);
744  FlowClearMemory(f, proto_map);
745  FlowFree(f);
746  f = n;
747  }
748 
750  }
752  flow_hash = NULL;
753  }
754  (void) SC_ATOMIC_SUB(flow_memuse, flow_config.hash_size * sizeof(FlowBucket));
757  DEBUG_VALIDATE_BUG_ON(SC_ATOMIC_GET(flow_memuse) != 0);
758 }
759 
760 /**
761  * \brief Function to set the default timeout, free function and flow state
762  * function for all supported flow_proto.
763  */
764 
766 {
768 
769 #define SET_DEFAULTS(p, n, e, c, b, ne, ee, ce, be) \
770  flow_timeouts_normal[(p)].new_timeout = (n); \
771  flow_timeouts_normal[(p)].est_timeout = (e); \
772  flow_timeouts_normal[(p)].closed_timeout = (c); \
773  flow_timeouts_normal[(p)].bypassed_timeout = (b); \
774  flow_timeouts_emerg[(p)].new_timeout = (ne); \
775  flow_timeouts_emerg[(p)].est_timeout = (ee); \
776  flow_timeouts_emerg[(p)].closed_timeout = (ce); \
777  flow_timeouts_emerg[(p)].bypassed_timeout = (be); \
778 
799 
804 
805  /* Let's see if we have custom timeouts defined from config */
806  const char *new = NULL;
807  const char *established = NULL;
808  const char *closed = NULL;
809  const char *bypassed = NULL;
810  const char *emergency_new = NULL;
811  const char *emergency_established = NULL;
812  const char *emergency_closed = NULL;
813  const char *emergency_bypassed = NULL;
814 
815  SCConfNode *flow_timeouts = SCConfGetNode("flow-timeouts");
816  if (flow_timeouts != NULL) {
817  SCConfNode *proto = NULL;
818  uint32_t configval = 0;
819 
820  /* Defaults. */
821  proto = SCConfNodeLookupChild(flow_timeouts, "default");
822  if (proto != NULL) {
823  new = SCConfNodeLookupChildValue(proto, "new");
824  established = SCConfNodeLookupChildValue(proto, "established");
825  closed = SCConfNodeLookupChildValue(proto, "closed");
826  bypassed = SCConfNodeLookupChildValue(proto, "bypassed");
827  emergency_new = SCConfNodeLookupChildValue(proto, "emergency-new");
828  emergency_established = SCConfNodeLookupChildValue(proto, "emergency-established");
829  emergency_closed = SCConfNodeLookupChildValue(proto, "emergency-closed");
830  emergency_bypassed = SCConfNodeLookupChildValue(proto, "emergency-bypassed");
831 
832  if (new != NULL &&
833  StringParseUint32(&configval, 10, strlen(new), new) > 0) {
834 
836  }
837  if (established != NULL &&
838  StringParseUint32(&configval, 10, strlen(established),
839  established) > 0) {
840 
842  }
843  if (closed != NULL &&
844  StringParseUint32(&configval, 10, strlen(closed),
845  closed) > 0) {
846 
848  }
849  if (bypassed != NULL &&
850  StringParseUint32(&configval, 10,
851  strlen(bypassed),
852  bypassed) > 0) {
853 
855  }
856  if (emergency_new != NULL &&
857  StringParseUint32(&configval, 10, strlen(emergency_new),
858  emergency_new) > 0) {
859 
861  }
862  if (emergency_established != NULL &&
863  StringParseUint32(&configval, 10,
864  strlen(emergency_established),
865  emergency_established) > 0) {
866 
868  }
869  if (emergency_closed != NULL &&
870  StringParseUint32(&configval, 10,
871  strlen(emergency_closed),
872  emergency_closed) > 0) {
873 
875  }
876  if (emergency_bypassed != NULL &&
877  StringParseUint32(&configval, 10,
878  strlen(emergency_bypassed),
879  emergency_bypassed) > 0) {
880 
882  }
883  }
884 
885  /* TCP. */
886  proto = SCConfNodeLookupChild(flow_timeouts, "tcp");
887  if (proto != NULL) {
888  new = SCConfNodeLookupChildValue(proto, "new");
889  established = SCConfNodeLookupChildValue(proto, "established");
890  closed = SCConfNodeLookupChildValue(proto, "closed");
891  bypassed = SCConfNodeLookupChildValue(proto, "bypassed");
892  emergency_new = SCConfNodeLookupChildValue(proto, "emergency-new");
893  emergency_established = SCConfNodeLookupChildValue(proto, "emergency-established");
894  emergency_closed = SCConfNodeLookupChildValue(proto, "emergency-closed");
895  emergency_bypassed = SCConfNodeLookupChildValue(proto, "emergency-bypassed");
896 
897  if (new != NULL &&
898  StringParseUint32(&configval, 10, strlen(new), new) > 0) {
899 
901  }
902  if (established != NULL &&
903  StringParseUint32(&configval, 10, strlen(established),
904  established) > 0) {
905 
907  }
908  if (closed != NULL &&
909  StringParseUint32(&configval, 10, strlen(closed),
910  closed) > 0) {
911 
913  }
914  if (bypassed != NULL &&
915  StringParseUint32(&configval, 10,
916  strlen(bypassed),
917  bypassed) > 0) {
918 
920  }
921  if (emergency_new != NULL &&
922  StringParseUint32(&configval, 10, strlen(emergency_new),
923  emergency_new) > 0) {
924 
926  }
927  if (emergency_established != NULL &&
928  StringParseUint32(&configval, 10,
929  strlen(emergency_established),
930  emergency_established) > 0) {
931 
933  }
934  if (emergency_closed != NULL &&
935  StringParseUint32(&configval, 10,
936  strlen(emergency_closed),
937  emergency_closed) > 0) {
938 
940  }
941  if (emergency_bypassed != NULL &&
942  StringParseUint32(&configval, 10,
943  strlen(emergency_bypassed),
944  emergency_bypassed) > 0) {
945 
947  }
948  }
949 
950  /* UDP. */
951  proto = SCConfNodeLookupChild(flow_timeouts, "udp");
952  if (proto != NULL) {
953  new = SCConfNodeLookupChildValue(proto, "new");
954  established = SCConfNodeLookupChildValue(proto, "established");
955  bypassed = SCConfNodeLookupChildValue(proto, "bypassed");
956  emergency_new = SCConfNodeLookupChildValue(proto, "emergency-new");
957  emergency_established = SCConfNodeLookupChildValue(proto, "emergency-established");
958  emergency_bypassed = SCConfNodeLookupChildValue(proto, "emergency-bypassed");
959 
960  if (new != NULL &&
961  StringParseUint32(&configval, 10, strlen(new), new) > 0) {
962 
964  }
965  if (established != NULL &&
966  StringParseUint32(&configval, 10, strlen(established),
967  established) > 0) {
968 
970  }
971  if (bypassed != NULL &&
972  StringParseUint32(&configval, 10,
973  strlen(bypassed),
974  bypassed) > 0) {
975 
977  }
978  if (emergency_new != NULL &&
979  StringParseUint32(&configval, 10, strlen(emergency_new),
980  emergency_new) > 0) {
981 
983  }
984  if (emergency_established != NULL &&
985  StringParseUint32(&configval, 10,
986  strlen(emergency_established),
987  emergency_established) > 0) {
988 
990  }
991  if (emergency_bypassed != NULL &&
992  StringParseUint32(&configval, 10,
993  strlen(emergency_bypassed),
994  emergency_bypassed) > 0) {
995 
997  }
998  }
999 
1000  /* ICMP. */
1001  proto = SCConfNodeLookupChild(flow_timeouts, "icmp");
1002  if (proto != NULL) {
1003  new = SCConfNodeLookupChildValue(proto, "new");
1004  established = SCConfNodeLookupChildValue(proto, "established");
1005  bypassed = SCConfNodeLookupChildValue(proto, "bypassed");
1006  emergency_new = SCConfNodeLookupChildValue(proto, "emergency-new");
1007  emergency_established = SCConfNodeLookupChildValue(proto, "emergency-established");
1008  emergency_bypassed = SCConfNodeLookupChildValue(proto, "emergency-bypassed");
1009 
1010  if (new != NULL &&
1011  StringParseUint32(&configval, 10, strlen(new), new) > 0) {
1012 
1014  }
1015  if (established != NULL &&
1016  StringParseUint32(&configval, 10, strlen(established),
1017  established) > 0) {
1018 
1020  }
1021  if (bypassed != NULL &&
1022  StringParseUint32(&configval, 10,
1023  strlen(bypassed),
1024  bypassed) > 0) {
1025 
1027  }
1028  if (emergency_new != NULL &&
1029  StringParseUint32(&configval, 10, strlen(emergency_new),
1030  emergency_new) > 0) {
1031 
1033  }
1034  if (emergency_established != NULL &&
1035  StringParseUint32(&configval, 10,
1036  strlen(emergency_established),
1037  emergency_established) > 0) {
1038 
1040  }
1041  if (emergency_bypassed != NULL &&
1042  StringParseUint32(&configval, 10,
1043  strlen(emergency_bypassed),
1044  emergency_bypassed) > 0) {
1045 
1047  }
1048  }
1049  }
1050 
1051  /* validate and if needed update emergency timeout values */
1052  for (uint8_t i = 0; i < FLOW_PROTO_MAX; i++) {
1053  const FlowProtoTimeout *n = &flow_timeouts_normal[i];
1055 
1056  if (e->est_timeout > n->est_timeout) {
1057  SCLogWarning("emergency timeout value %u for \'established\' "
1058  "must be below regular value %u",
1059  e->est_timeout, n->est_timeout);
1060  e->est_timeout = n->est_timeout / 10;
1061  }
1062 
1063  if (e->new_timeout > n->new_timeout) {
1064  SCLogWarning("emergency timeout value %u for \'new\' must be "
1065  "below regular value %u",
1066  e->new_timeout, n->new_timeout);
1067  e->new_timeout = n->new_timeout / 10;
1068  }
1069 
1070  if (e->closed_timeout > n->closed_timeout) {
1071  SCLogWarning("emergency timeout value %u for \'closed\' must "
1072  "be below regular value %u",
1074  e->closed_timeout = n->closed_timeout / 10;
1075  }
1076 
1077  if (e->bypassed_timeout > n->bypassed_timeout) {
1078  SCLogWarning("emergency timeout value %u for \'bypassed\' "
1079  "must be below regular value %u",
1081  e->bypassed_timeout = n->bypassed_timeout / 10;
1082  }
1083  }
1084 
1085  for (uint8_t i = 0; i < FLOW_PROTO_MAX; i++) {
1089 
1090  if (e->est_timeout > n->est_timeout) {
1091  SCLogWarning("emergency timeout value for \'established\' must be below normal value");
1092  e->est_timeout = n->est_timeout / 10;
1093  }
1094  d->est_timeout = n->est_timeout - e->est_timeout;
1095 
1096  if (e->new_timeout > n->new_timeout) {
1097  SCLogWarning("emergency timeout value for \'new\' must be below normal value");
1098  e->new_timeout = n->new_timeout / 10;
1099  }
1100  d->new_timeout = n->new_timeout - e->new_timeout;
1101 
1102  if (e->closed_timeout > n->closed_timeout) {
1103  SCLogWarning("emergency timeout value for \'closed\' must be below normal value");
1104  e->closed_timeout = n->closed_timeout / 10;
1105  }
1107 
1108  if (e->bypassed_timeout > n->bypassed_timeout) {
1109  SCLogWarning("emergency timeout value for \'bypassed\' must be below normal value");
1110  e->bypassed_timeout = n->bypassed_timeout / 10;
1111  }
1113 
1114  SCLogDebug("deltas: new: -%u est: -%u closed: -%u bypassed: -%u",
1116  }
1117 }
1118 
1119 /**
1120  * \brief Function clear the flow memory before queueing it to spare flow
1121  * queue.
1122  *
1123  * \param f pointer to the flow needed to be cleared.
1124  * \param proto_map mapped value of the protocol to FLOW_PROTO's.
1125  */
1126 
1127 int FlowClearMemory(Flow* f, uint8_t proto_map)
1128 {
1129  SCEnter();
1130 
1131  if (unlikely(f->flags & FLOW_HAS_EXPECTATION)) {
1133  }
1134 
1135  /* call the protocol specific free function if we have one */
1136  if (flow_freefuncs[proto_map].Freefunc != NULL) {
1137  flow_freefuncs[proto_map].Freefunc(f->protoctx);
1138  }
1139 
1140  SCFlowFreeStorage(f);
1141 
1142  FLOW_RECYCLE(f);
1143 
1144  SCReturnInt(1);
1145 }
1146 
1147 /**
1148  * \brief Function to set the function to get protocol specific flow state.
1149  *
1150  * \param proto protocol of which function is needed to be set.
1151  * \param Free Function pointer which will be called to free the protocol
1152  * specific memory.
1153  */
1154 
1155 int FlowSetProtoFreeFunc (uint8_t proto, void (*Free)(void *))
1156 {
1157  uint8_t proto_map;
1158  proto_map = FlowGetProtoMapping(proto);
1159 
1160  flow_freefuncs[proto_map].Freefunc = Free;
1161  return 1;
1162 }
1163 
1164 /**
1165  * \brief get 'disruption' flags: GAP/DEPTH/PASS
1166  * \param f locked flow
1167  * \param flags existing flags to be amended
1168  * \retval flags original flags + disrupt flags (if any)
1169  * \TODO handle UDP
1170  */
1171 uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
1172 {
1173  if (f->proto != IPPROTO_TCP) {
1174  return flags;
1175  }
1176  if (f->protoctx == NULL) {
1177  return flags;
1178  }
1179 
1180  uint8_t newflags = flags;
1181  TcpSession *ssn = f->protoctx;
1182  TcpStream *stream = flags & STREAM_TOSERVER ? &ssn->client : &ssn->server;
1183 
1185  newflags |= STREAM_DEPTH;
1186  }
1187  /* todo: handle pass case (also for UDP!) */
1188 
1189  return newflags;
1190 }
1191 
1192 void FlowUpdateState(Flow *f, const enum FlowState s)
1193 {
1194  if (s != f->flow_state) {
1195  /* set the state */
1196  // Explicit cast from the enum type to the compact version
1197  f->flow_state = (FlowStateType)s;
1198 
1199  /* update timeout policy and value */
1200  const uint32_t timeout_policy = FlowGetTimeoutPolicy(f);
1201  if (timeout_policy != f->timeout_policy) {
1202  f->timeout_policy = timeout_policy;
1203  }
1204  }
1205 #ifdef UNITTESTS
1206  if (f->fb != NULL) {
1207 #endif
1208  /* and reset the flow bucket next_ts value so that the flow manager
1209  * has to revisit this row */
1210  SC_ATOMIC_SET(f->fb->next_ts, 0);
1211 #ifdef UNITTESTS
1212  }
1213 #endif
1214 }
1215 
1216 /**
1217  * \brief Get flow last time as individual values.
1218  *
1219  * Instead of returning a pointer to the timeval copy the timeval
1220  * parts into output pointers to make it simpler to call from Rust
1221  * over FFI using only basic data types.
1222  */
1223 void SCFlowGetLastTimeAsParts(const Flow *flow, uint64_t *secs, uint64_t *usecs)
1224 {
1225  *secs = (uint64_t)SCTIME_SECS(flow->lastts);
1226  *usecs = (uint64_t)SCTIME_USECS(flow->lastts);
1227 }
1228 
1229 /**
1230  * \brief Get flow source port.
1231  *
1232  * A function to get the flow sport useful when the caller only has an
1233  * opaque pointer to the flow structure.
1234  */
1235 uint16_t SCFlowGetSourcePort(const Flow *flow)
1236 {
1237  return flow->sp;
1238 }
1239 
1241 {
1242  return f->alproto;
1243 }
1244 
1245 /**
1246  * \brief Get flow destination port.
1247  *
1248  * A function to get the flow dport useful when the caller only has an
1249  * opaque pointer to the flow structure.
1250  */
1251 
1252 uint16_t SCFlowGetDestinationPort(const Flow *flow)
1253 {
1254  return flow->dp;
1255 }
1256 
1257 /**
1258  * \brief Get flow flags.
1259  *
1260  * A function to get the flow flags useful when the caller only has an
1261  * opaque pointer to the flow structure.
1262  */
1263 uint64_t SCFlowGetFlags(const Flow *flow)
1264 {
1265  return flow->flags;
1266 }
1267 /************************************Unittests*******************************/
1268 
1269 #ifdef UNITTESTS
1270 #include "threads.h"
1271 
1272 /**
1273  * \test Test the setting of the per protocol timeouts.
1274  *
1275  * \retval On success it returns 1 and on failure 0.
1276  */
1277 
1278 static int FlowTest01 (void)
1279 {
1280  uint8_t proto_map;
1281 
1283  proto_map = FlowGetProtoMapping(IPPROTO_TCP);
1284  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT);
1285  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_TCP_EST_TIMEOUT);
1288 
1289  proto_map = FlowGetProtoMapping(IPPROTO_UDP);
1290  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT);
1291  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_TIMEOUT);
1294 
1295  proto_map = FlowGetProtoMapping(IPPROTO_ICMP);
1296  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT);
1297  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_TIMEOUT);
1300 
1301  proto_map = FlowGetProtoMapping(IPPROTO_DCCP);
1302  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT);
1303  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_DEFAULT_EST_TIMEOUT);
1304  FAIL_IF(flow_timeouts_emerg[proto_map].new_timeout != FLOW_DEFAULT_EMERG_NEW_TIMEOUT);
1305  FAIL_IF(flow_timeouts_emerg[proto_map].est_timeout != FLOW_DEFAULT_EMERG_EST_TIMEOUT);
1306 
1307  PASS;
1308 }
1309 
1310 /*Test function for the unit test FlowTest02*/
1311 
1312 static void test(void *f) {}
1313 
1314 /**
1315  * \test Test the setting of the per protocol free function to free the
1316  * protocol specific memory.
1317  *
1318  * \retval On success it returns 1 and on failure 0.
1319  */
1320 
1321 static int FlowTest02 (void)
1322 {
1324  FlowSetProtoFreeFunc(IPPROTO_TCP, test);
1325  FlowSetProtoFreeFunc(IPPROTO_UDP, test);
1326  FlowSetProtoFreeFunc(IPPROTO_ICMP, test);
1327 
1328  FAIL_IF(flow_freefuncs[FLOW_PROTO_DEFAULT].Freefunc != test);
1329  FAIL_IF(flow_freefuncs[FLOW_PROTO_TCP].Freefunc != test);
1330  FAIL_IF(flow_freefuncs[FLOW_PROTO_UDP].Freefunc != test);
1331  FAIL_IF(flow_freefuncs[FLOW_PROTO_ICMP].Freefunc != test);
1332 
1333  PASS;
1334 }
1335 
1336 /**
1337  * \test Test flow allocations when it reach memcap
1338  *
1339  *
1340  * \retval On success it returns 1 and on failure 0.
1341  */
1342 
1343 static int FlowTest07 (void)
1344 {
1345  int result = 0;
1347  FlowConfig backup;
1348  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1349 
1350  uint32_t ini = 0;
1351  uint32_t end = FlowSpareGetPoolSize();
1352  SC_ATOMIC_SET(flow_config.memcap, 10000);
1353  flow_config.prealloc = 100;
1354 
1355  /* Let's get the flow spare pool empty */
1356  UTHBuildPacketOfFlows(ini, end, 0);
1357 
1358  /* And now let's try to reach the memcap val */
1359  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1360  ini = end + 1;
1361  end = end + 2;
1362  UTHBuildPacketOfFlows(ini, end, 0);
1363  }
1364 
1365  /* should time out normal */
1366  TimeSetIncrementTime(2000);
1367  ini = end + 1;
1368  end = end + 2;
1369  UTHBuildPacketOfFlows(ini, end, 0);
1370 
1371  /* This means that the engine entered emerg mode: should happen as easy
1372  * with flow mgr activated */
1373  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1374  result = 1;
1375 
1376  FlowShutdown();
1377  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1378 
1379  return result;
1380 }
1381 
1382 /**
1383  * \test Test flow allocations when it reach memcap
1384  *
1385  *
1386  * \retval On success it returns 1 and on failure 0.
1387  */
1388 
1389 static int FlowTest08 (void)
1390 {
1391  int result = 0;
1392 
1394  FlowConfig backup;
1395  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1396 
1397  uint32_t ini = 0;
1398  uint32_t end = FlowSpareGetPoolSize();
1399  SC_ATOMIC_SET(flow_config.memcap, 10000);
1400  flow_config.prealloc = 100;
1401 
1402  /* Let's get the flow spare pool empty */
1403  UTHBuildPacketOfFlows(ini, end, 0);
1404 
1405  /* And now let's try to reach the memcap val */
1406  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1407  ini = end + 1;
1408  end = end + 2;
1409  UTHBuildPacketOfFlows(ini, end, 0);
1410  }
1411 
1412  /* By default we use 30 for timing out new flows. This means
1413  * that the Emergency mode should be set */
1415  ini = end + 1;
1416  end = end + 2;
1417  UTHBuildPacketOfFlows(ini, end, 0);
1418 
1419  /* This means that the engine released 5 flows by emergency timeout */
1420  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1421  result = 1;
1422 
1423  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1424  FlowShutdown();
1425 
1426  return result;
1427 }
1428 
1429 /**
1430  * \test Test flow allocations when it reach memcap
1431  *
1432  *
1433  * \retval On success it returns 1 and on failure 0.
1434  */
1435 
1436 static int FlowTest09 (void)
1437 {
1438  int result = 0;
1439 
1441  FlowConfig backup;
1442  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1443 
1444  uint32_t ini = 0;
1445  uint32_t end = FlowSpareGetPoolSize();
1446  SC_ATOMIC_SET(flow_config.memcap, 10000);
1447  flow_config.prealloc = 100;
1448 
1449  /* Let's get the flow spare pool empty */
1450  UTHBuildPacketOfFlows(ini, end, 0);
1451 
1452  /* And now let's try to reach the memcap val */
1453  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1454  ini = end + 1;
1455  end = end + 2;
1456  UTHBuildPacketOfFlows(ini, end, 0);
1457  }
1458 
1459  /* No timeout will work */
1461  ini = end + 1;
1462  end = end + 2;
1463  UTHBuildPacketOfFlows(ini, end, 0);
1464 
1465  /* engine in emerg mode */
1466  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1467  result = 1;
1468 
1469  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1470  FlowShutdown();
1471 
1472  return result;
1473 }
1474 
1475 #endif /* UNITTESTS */
1476 
1477 /**
1478  * \brief Function to register the Flow Unitests.
1479  */
1481 {
1482 #ifdef UNITTESTS
1483  UtRegisterTest("FlowTest01 -- Protocol Specific Timeouts", FlowTest01);
1484  UtRegisterTest("FlowTest02 -- Setting Protocol Specific Free Function",
1485  FlowTest02);
1486  UtRegisterTest("FlowTest07 -- Test flow Allocations when it reach memcap",
1487  FlowTest07);
1488  UtRegisterTest("FlowTest08 -- Test flow Allocations when it reach memcap",
1489  FlowTest08);
1490  UtRegisterTest("FlowTest09 -- Test flow Allocations when it reach memcap",
1491  FlowTest09);
1492 
1494 #endif /* UNITTESTS */
1495 }
FLOWFILE_NO_MD5_TS
#define FLOWFILE_NO_MD5_TS
Definition: flow.h:142
util-byte.h
FlowUnsetChangeProtoFlag
void FlowUnsetChangeProtoFlag(Flow *f)
Unset flag to indicate to change proto for the flow.
Definition: flow.c:187
FLOWFILE_NO_MD5_TC
#define FLOWFILE_NO_MD5_TC
Definition: flow.h:143
FBLOCK_DESTROY
#define FBLOCK_DESTROY(fb)
Definition: flow-hash.h:72
FLOW_DEFAULT_NEW_TIMEOUT
#define FLOW_DEFAULT_NEW_TIMEOUT
Definition: flow-private.h:40
MacSetAddWithCtr
void MacSetAddWithCtr(MacSet *ms, const uint8_t *src_addr, const uint8_t *dst_addr, ThreadVars *tv, StatsCounterMaxId ctr_src, StatsCounterMaxId ctr_dst)
Definition: util-macset.c:180
Packet_::proto
uint8_t proto
Definition: decode.h:537
FLOW_DEFAULT_EMERG_BYPASSED_TIMEOUT
#define FLOW_DEFAULT_EMERG_BYPASSED_TIMEOUT
Definition: flow-private.h:56
TcpStream_
Definition: stream-tcp-private.h:106
flow-bypass.h
FLOW_HAS_EXPECTATION
#define FLOW_HAS_EXPECTATION
Definition: flow.h:113
FlowSetHasAlertsFlag
void FlowSetHasAlertsFlag(Flow *f)
Set flag to indicate that flow has alerts.
Definition: flow.c:154
FLOW_ACTION_BY_FIREWALL
#define FLOW_ACTION_BY_FIREWALL
Definition: flow.h:125
FlowCleanupAppLayer
void FlowCleanupAppLayer(Flow *f)
Definition: flow.c:140
FlowSetChangeProtoFlag
void FlowSetChangeProtoFlag(Flow *f)
Set flag to indicate to change proto for the flow.
Definition: flow.c:178
Flow_::flags
uint64_t flags
Definition: flow.h:403
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1310
PKT_DROP_REASON_FW_FLOW_DROP
@ PKT_DROP_REASON_FW_FLOW_DROP
Definition: decode.h:411
IPV6_GET_RAW_HLIM
#define IPV6_GET_RAW_HLIM(ip6h)
Definition: decode-ipv6.h:67
FlowSpareGetPoolSize
uint32_t FlowSpareGetPoolSize(void)
Definition: flow-spare-pool.c:46
FlowGetPacketDirection
int FlowGetPacketDirection(const Flow *f, const Packet *p)
determine the direction of the packet compared to the flow
Definition: flow.c:286
FLOW_STATE_ESTABLISHED
@ FLOW_STATE_ESTABLISHED
Definition: flow.h:505
flow-util.h
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:314
FBLOCK_INIT
#define FBLOCK_INIT(fb)
Definition: flow-hash.h:71
CLS
#define CLS
Definition: suricata-common.h:77
FLOW_DEFAULT_HASHSIZE
#define FLOW_DEFAULT_HASHSIZE
Definition: flow.c:68
SC_ATOMIC_DECLARE
SC_ATOMIC_DECLARE(FlowProtoTimeoutPtr, flow_timeouts)
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
FlowCnf_::emergency_recovery
uint32_t emergency_recovery
Definition: flow.h:298
FLOW_DEFAULT_PREALLOC
#define FLOW_DEFAULT_PREALLOC
Definition: flow.c:72
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
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:292
BIT_U16
#define BIT_U16(n)
Definition: suricata-common.h:424
SCFlowGetStorageById
void * SCFlowGetStorageById(const Flow *f, SCFlowStorageId id)
Definition: flow-storage.c:40
PcapPacketCntGet
uint64_t PcapPacketCntGet(const Packet *p)
Definition: decode.c:1180
FLOW_IS_ELEPHANT_TOCLIENT
#define FLOW_IS_ELEPHANT_TOCLIENT
Definition: flow.h:60
FlowRegisterTests
void FlowRegisterTests(void)
Function to register the Flow Unitests.
Definition: flow.c:1480
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT
#define FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT
Definition: flow-private.h:60
FLOW_SGH_TOCLIENT
#define FLOW_SGH_TOCLIENT
Definition: flow.h:74
ParseSizeStringU64
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition: util-misc.c:191
Flow_::proto
uint8_t proto
Definition: flow.h:376
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:87
action-globals.h
FLOWFILE_NO_MAGIC_TS
#define FLOWFILE_NO_MAGIC_TS
Definition: flow.h:134
Packet_::flags
uint32_t flags
Definition: decode.h:561
threads.h
util-macset.h
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:354
SCFlowStorageSize
unsigned int SCFlowStorageSize(void)
Definition: flow-storage.c:35
Flow_::protomap
uint8_t protomap
Definition: flow.h:445
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
FlowProtoTimeout_
Definition: flow.h:518
SCConfGet
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:353
flow-hash.h
FLOW_NOPAYLOAD_INSPECTION
#define FLOW_NOPAYLOAD_INSPECTION
Definition: flow.h:66
FLOW_TS_PM_ALPROTO_DETECT_DONE
#define FLOW_TS_PM_ALPROTO_DETECT_DONE
Definition: flow.h:85
FlowReset
void FlowReset(void)
Definition: flow.c:703
FlowLookupStruct_
Definition: flow.h:542
FLOW_DEFAULT_EMERG_NEW_TIMEOUT
#define FLOW_DEFAULT_EMERG_NEW_TIMEOUT
Definition: flow-private.h:54
FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT
#define FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT
Definition: flow-private.h:57
BypassedFlowUpdate
void BypassedFlowUpdate(Flow *f, Packet *p)
Definition: flow-bypass.c:209
FlowProtoTimeout_::bypassed_timeout
uint32_t bypassed_timeout
Definition: flow.h:522
FLOW_DEFAULT_EST_TIMEOUT
#define FLOW_DEFAULT_EST_TIMEOUT
Definition: flow-private.h:41
FlowRateGetStorageID
SCFlowStorageId FlowRateGetStorageID(void)
Definition: util-flow-rate.c:133
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:231
TCP_ESTABLISHED
@ TCP_ESTABLISHED
Definition: stream-tcp-private.h:155
FlowGetMemuse
uint64_t FlowGetMemuse(void)
Definition: flow.c:129
rust.h
MIN
#define MIN(x, y)
Definition: suricata-common.h:416
IPPROTO_DCCP
#define IPPROTO_DCCP
Definition: decode.h:1264
FlowGetMemcap
uint64_t FlowGetMemcap(void)
Return memcap value.
Definition: flow.c:123
FlowQueueDestroy
void FlowQueueDestroy(FlowQueue *q)
Destroy a flow queue.
Definition: flow-queue.c:60
FlowHandlePacket
void FlowHandlePacket(ThreadVars *tv, FlowLookupStruct *fls, Packet *p)
Entry point for packet flow handling.
Definition: flow.c:563
FLOW_ACTION_DROP
#define FLOW_ACTION_DROP
Definition: flow.h:69
TcpStream_::flags
uint16_t flags
Definition: stream-tcp-private.h:107
SCFlowRunUpdateCallbacks
void SCFlowRunUpdateCallbacks(ThreadVars *tv, Flow *f, Packet *p)
Definition: flow-callbacks.c:93
RandomGet
long int RandomGet(void)
Definition: util-random.c:130
FLOW_TOSERVER_DROP_LOGGED
#define FLOW_TOSERVER_DROP_LOGGED
Definition: flow.h:77
Flow_::max_ttl_toserver
uint8_t max_ttl_toserver
Definition: flow.h:468
proto
uint8_t proto
Definition: decode-template.h:0
p
Packet * p
Definition: fuzz_iprep.c:21
Flow_::dp
Port dp
Definition: flow.h:370
SCConfNodeLookupChildValue
const char * SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:878
FLOW_TC_PE_ALPROTO_DETECT_DONE
#define FLOW_TC_PE_ALPROTO_DETECT_DONE
Definition: flow.h:95
FLOW_DEFAULT_BYPASSED_TIMEOUT
#define FLOW_DEFAULT_BYPASSED_TIMEOUT
Definition: flow-private.h:42
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:546
MAX
#define MAX(x, y)
Definition: suricata-common.h:420
Flow_::protoctx
void * protoctx
Definition: flow.h:433
FLOW_PROTO_UDP
@ FLOW_PROTO_UDP
Definition: flow-private.h:67
ExceptionPolicyParse
enum ExceptionPolicy ExceptionPolicyParse(const char *option, bool support_flow)
Definition: util-exception-policy.c:312
FLOW_IPPROTO_UDP_BYPASSED_TIMEOUT
#define FLOW_IPPROTO_UDP_BYPASSED_TIMEOUT
Definition: flow-private.h:49
STREAMTCP_STREAM_FLAG_DEPTH_REACHED
#define STREAMTCP_STREAM_FLAG_DEPTH_REACHED
Definition: stream-tcp-private.h:223
util-unittest.h
util-unittest-helper.h
FLOW_IPPROTO_TCP_EMERG_CLOSED_TIMEOUT
#define FLOW_IPPROTO_TCP_EMERG_CLOSED_TIMEOUT
Definition: flow-private.h:59
FLOW_IPPROTO_ICMP_EST_TIMEOUT
#define FLOW_IPPROTO_ICMP_EST_TIMEOUT
Definition: flow-private.h:51
FlowCnf_::prealloc
uint32_t prealloc
Definition: flow.h:293
UTHBuildPacketOfFlows
uint32_t UTHBuildPacketOfFlows(uint32_t start, uint32_t end, uint8_t dir)
Definition: util-unittest-helper.c:879
AppLayerExpectationClean
void AppLayerExpectationClean(Flow *f)
Definition: app-layer-expectation.c:359
Flow_::flow_state
FlowStateType flow_state
Definition: flow.h:420
PKT_PROTO_DETECT_TS_DONE
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1343
Packet_::icmp_s
struct Packet_::@32::@39 icmp_s
Flow_::sgh_toserver
const struct SigGroupHead_ * sgh_toserver
Definition: flow.h:486
FLOW_CHECK_MEMCAP
#define FLOW_CHECK_MEMCAP(size)
check if a memory alloc would fit in the memcap
Definition: flow-util.h:134
FLOW_RECYCLE
#define FLOW_RECYCLE(f)
macro to recycle a flow before it goes into the spare queue for reuse.
Definition: flow-util.h:80
Flow_::tosrcbytecnt
uint64_t tosrcbytecnt
Definition: flow.h:498
flow-spare-pool.h
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:478
FlowRateStoreUpdate
void FlowRateStoreUpdate(FlowRateStore *frs, SCTime_t p_ts, uint32_t pkt_len, int direction)
Definition: util-flow-rate.c:192
DecodeThreadVars_::counter_flow_elephant
StatsCounterId counter_flow_elephant
Definition: decode.h:1079
FLOWFILE_NO_SHA1_TC
#define FLOWFILE_NO_SHA1_TC
Definition: flow.h:147
FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT
#define FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT
Definition: flow-private.h:63
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:577
Flow_::fb
struct FlowBucket_ * fb
Definition: flow.h:491
app-layer-expectation.h
FLOW_IPPROTO_UDP_EST_TIMEOUT
#define FLOW_IPPROTO_UDP_EST_TIMEOUT
Definition: flow-private.h:48
util-flow-rate.h
FLOW_STATE_LOCAL_BYPASSED
@ FLOW_STATE_LOCAL_BYPASSED
Definition: flow.h:507
Flow_::min_ttl_toserver
uint8_t min_ttl_toserver
Definition: flow.h:467
decode.h
util-debug.h
TOSERVER
#define TOSERVER
Definition: flow.h:45
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
Packet_::ts
SCTime_t ts
Definition: decode.h:569
Flow_::todstpktcnt
uint32_t todstpktcnt
Definition: flow.h:495
FLOW_IPPROTO_TCP_CLOSED_TIMEOUT
#define FLOW_IPPROTO_TCP_CLOSED_TIMEOUT
Definition: flow-private.h:45
FlowHandlePacketUpdate
void FlowHandlePacketUpdate(Flow *f, Packet *p, ThreadVars *tv, DecodeThreadVars *dtv)
Update Packet and Flow.
Definition: flow.c:424
Flow_::lastts
SCTime_t lastts
Definition: flow.h:418
SCConfGetInt
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:441
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
FLOW_CHANGE_PROTO
#define FLOW_CHANGE_PROTO
Definition: flow.h:107
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
Packet_::sp
Port sp
Definition: decode.h:522
FlowCnf_
Definition: flow.h:290
FLOWFILE_NO_SHA256_TS
#define FLOWFILE_NO_SHA256_TS
Definition: flow.h:150
FLOW_PKT_TOCLIENT_FIRST
#define FLOW_PKT_TOCLIENT_FIRST
Definition: flow.h:235
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:164
FlowQueueInit
FlowQueue * FlowQueueInit(FlowQueue *q)
Definition: flow-queue.c:46
FlowState
FlowState
Definition: flow.h:503
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:285
FlowProtoTimeout_::new_timeout
uint32_t new_timeout
Definition: flow.h:519
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:269
FlowProtoTimeout_::closed_timeout
uint32_t closed_timeout
Definition: flow.h:521
util-time.h
FLOW_PROTO_DEFAULT
@ FLOW_PROTO_DEFAULT
Definition: flow-private.h:69
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:262
app-layer-parser.h
AppLayerParserStateCleanup
void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1689
FLOW_PROTO_ICMP
@ FLOW_PROTO_ICMP
Definition: flow-private.h:68
FLOW_PROTO_DETECT_TC_DONE
#define FLOW_PROTO_DETECT_TC_DONE
Definition: flow.h:104
Packet_::pkt_hooks
uint16_t pkt_hooks
Definition: decode.h:555
Flow_::todstbytecnt
uint64_t todstbytecnt
Definition: flow.h:497
ThreadVars_::id
int id
Definition: threadvars.h:86
FLOW_TC_PP_ALPROTO_DETECT_DONE
#define FLOW_TC_PP_ALPROTO_DETECT_DONE
Definition: flow.h:93
Flow_::sgh_toclient
const struct SigGroupHead_ * sgh_toclient
Definition: flow.h:483
MacSetFlowStorageEnabled
bool MacSetFlowStorageEnabled(void)
Definition: util-macset.c:85
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:341
FlowThreadId
uint16_t FlowThreadId
Definition: flow.h:331
TimeSetIncrementTime
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
Definition: util-time.c:181
IPV6Hdr_
Definition: decode-ipv6.h:32
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:100
Packet_
Definition: decode.h:515
SCFreeAligned
#define SCFreeAligned(p)
Definition: util-mem.h:77
IPV4_GET_RAW_IPTTL
#define IPV4_GET_RAW_IPTTL(ip4h)
Definition: decode-ipv4.h:102
FLOW_DEFAULT_MEMCAP
#define FLOW_DEFAULT_MEMCAP
Definition: flow.c:70
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:209
stream-tcp-private.h
MacSet_
Definition: util-macset.c:45
SCFlowFreeStorage
void SCFlowFreeStorage(Flow *f)
Definition: flow-storage.c:55
conf.h
FLOW_IPPROTO_TCP_NEW_TIMEOUT
#define FLOW_IPPROTO_TCP_NEW_TIMEOUT
Definition: flow-private.h:43
FlowProtoFreeFunc_::Freefunc
void(* Freefunc)(void *)
Definition: flow.h:526
FlowClearMemory
int FlowClearMemory(Flow *f, uint8_t proto_map)
Function clear the flow memory before queueing it to spare flow queue.
Definition: flow.c:1127
flow_timeouts_delta
FlowProtoTimeout flow_timeouts_delta[FLOW_PROTO_MAX]
Definition: flow.c:91
FlowCnf_::hash_rand
uint32_t hash_rand
Definition: flow.h:291
SCFlowGetLastTimeAsParts
void SCFlowGetLastTimeAsParts(const Flow *flow, uint64_t *secs, uint64_t *usecs)
Get flow last time as individual values.
Definition: flow.c:1223
Flow_::min_ttl_toclient
uint8_t min_ttl_toclient
Definition: flow.h:469
flow-queue.h
Flow_::probing_parser_toclient_alproto_masks
uint32_t probing_parser_toclient_alproto_masks
Definition: flow.h:427
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:232
SCFlowGetDestinationPort
uint16_t SCFlowGetDestinationPort(const Flow *flow)
Get flow destination port.
Definition: flow.c:1252
FLOW_TO_DST_SEEN
#define FLOW_TO_DST_SEEN
Definition: flow.h:53
PKT_DROP_REASON_EP_FLOW_DROP
@ PKT_DROP_REASON_EP_FLOW_DROP
Definition: decode.h:389
FlowUpdateState
void FlowUpdateState(Flow *f, const enum FlowState s)
Definition: flow.c:1192
DecodeThreadVars_::counter_max_mac_addrs_dst
StatsCounterMaxId counter_max_mac_addrs_dst
Definition: decode.h:1004
Flow_::src
FlowAddress src
Definition: flow.h:357
Flow_::next
struct Flow_ * next
Definition: flow.h:401
Flow_::probing_parser_toserver_alproto_masks
uint32_t probing_parser_toserver_alproto_masks
Definition: flow.h:426
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:34
FLOWFILE_NO_SHA256_TC
#define FLOWFILE_NO_SHA256_TC
Definition: flow.h:151
DecodeThreadVars_::counter_max_mac_addrs_src
StatsCounterMaxId counter_max_mac_addrs_src
Definition: decode.h:1003
IPV4Hdr_
Definition: decode-ipv4.h:72
SCConfNodeLookupChild
SCConfNode * SCConfNodeLookupChild(const SCConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:850
flow_hash
FlowBucket * flow_hash
Definition: flow-hash.c:59
FlowDequeue
Flow * FlowDequeue(FlowQueue *q)
remove a flow from the queue
Definition: flow-queue.c:191
FLOW_TO_SRC_SEEN
#define FLOW_TO_SRC_SEEN
Definition: flow.h:51
flow-storage.h
FLOW_TS_PE_ALPROTO_DETECT_DONE
#define FLOW_TS_PE_ALPROTO_DETECT_DONE
Definition: flow.h:89
Packet_::flow
struct Flow_ * flow
Definition: decode.h:563
FLOW_IPPROTO_UDP_NEW_TIMEOUT
#define FLOW_IPPROTO_UDP_NEW_TIMEOUT
Definition: flow-private.h:47
FlowSetProtoFreeFunc
int FlowSetProtoFreeFunc(uint8_t, void(*Free)(void *))
Function to set the function to get protocol specific flow state.
Definition: flow.c:1155
FLOW_IPPROTO_ICMP_NEW_TIMEOUT
#define FLOW_IPPROTO_ICMP_NEW_TIMEOUT
Definition: flow-private.h:50
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
flow_timeouts_normal
FlowProtoTimeout flow_timeouts_normal[FLOW_PROTO_MAX]
Definition: flow.c:89
CMP_ADDR
#define CMP_ADDR(a1, a2)
Definition: decode.h:223
FlowStateType
unsigned short FlowStateType
Definition: flow.h:328
FLOWFILE_NO_MAGIC_TC
#define FLOWFILE_NO_MAGIC_TC
Definition: flow.h:135
flags
uint8_t flags
Definition: decode-gre.h:0
FlowGetMemcapExceptionPolicy
enum ExceptionPolicy FlowGetMemcapExceptionPolicy(void)
Definition: flow.c:135
SCFlowGetFlags
uint64_t SCFlowGetFlags(const Flow *flow)
Get flow flags.
Definition: flow.c:1263
flow-manager.h
suricata-common.h
FlowFree
void FlowFree(Flow *f)
cleanup & free the memory of a flow
Definition: flow-util.c:85
flow_config
FlowConfig flow_config
Definition: flow.c:94
FLOW_IPPROTO_TCP_BYPASSED_TIMEOUT
#define FLOW_IPPROTO_TCP_BYPASSED_TIMEOUT
Definition: flow-private.h:46
SCFlowGetSourcePort
uint16_t SCFlowGetSourcePort(const Flow *flow)
Get flow source port.
Definition: flow.c:1235
FLOW_HAS_ALERTS
#define FLOW_HAS_ALERTS
Definition: flow.h:82
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:721
FlowSparePoolDestroy
void FlowSparePoolDestroy(void)
Definition: flow-spare-pool.c:310
packet.h
SCMallocAligned
#define SCMallocAligned(size, align)
Definition: util-mem.h:68
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
SWAP_VARS
#define SWAP_VARS(type, a, b)
Definition: suricata-common.h:453
FlowTimeoutsInit
void FlowTimeoutsInit(void)
Definition: flow-manager.c:99
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
Flow
struct Flow_ Flow
Definition: app-layer-detect-proto.h:29
FLOW_PROTO_DETECT_TS_DONE
#define FLOW_PROTO_DETECT_TS_DONE
Definition: flow.h:103
FlowRateIsExceeding
bool FlowRateIsExceeding(FlowRateStore *frs, int direction)
Definition: util-flow-rate.c:227
FatalError
#define FatalError(...)
Definition: util-debug.h:517
Flow_::max_ttl_toclient
uint8_t max_ttl_toclient
Definition: flow.h:470
SCRegisterFlowStorageTests
void SCRegisterFlowStorageTests(void)
Definition: flow-storage.c:205
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:297
FLOW_TS_PP_ALPROTO_DETECT_DONE
#define FLOW_TS_PP_ALPROTO_DETECT_DONE
Definition: flow.h:87
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1344
FlowGetFlowFromHash
Flow * FlowGetFlowFromHash(ThreadVars *tv, FlowLookupStruct *fls, Packet *p, Flow **dest)
Get Flow for packet.
Definition: flow-hash.c:906
Flow_::timeout_policy
uint32_t timeout_policy
Definition: flow.h:413
FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT
#define FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT
Definition: flow-private.h:58
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:33
threadvars.h
FlowSwap
void FlowSwap(Flow *f)
swap the flow's direction
Definition: flow.c:246
FlowCnf_::memcap_policy
enum ExceptionPolicy memcap_policy
Definition: flow.h:300
MacSetSwap
void MacSetSwap(MacSet *ms)
Definition: util-macset.c:295
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
FlowInitFlowProto
void FlowInitFlowProto(void)
Function to set the default timeout, free function and flow state function for all supported flow_pro...
Definition: flow.c:765
SCTIME_CMP_GT
#define SCTIME_CMP_GT(a, b)
Definition: util-time.h:104
FLOWFILE_NO_SHA1_TS
#define FLOWFILE_NO_SHA1_TS
Definition: flow.h:146
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:296
SCConfGetNode
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
Definition: conf.c:184
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
flow_recycle_q
FlowQueue flow_recycle_q
Definition: flow-manager.c:66
flow-callbacks.h
SWAP_FLAGS
#define SWAP_FLAGS(flags, a, b)
Definition: suricata-common.h:442
FLOW_SGH_TOSERVER
#define FLOW_SGH_TOSERVER
Definition: flow.h:72
CMP_PORT
#define CMP_PORT(p1, p2)
Definition: decode.h:228
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:994
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:451
Flow_::alstate
void * alstate
Definition: flow.h:479
flow_freefuncs
FlowProtoFreeFunc flow_freefuncs[FLOW_PROTO_MAX]
Definition: flow.c:92
flow_timeouts_emerg
FlowProtoTimeout flow_timeouts_emerg[FLOW_PROTO_MAX]
Definition: flow.c:90
SCFlowGetAppProtocol
AppProto SCFlowGetAppProtocol(const Flow *f)
Definition: flow.c:1240
FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT
#define FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT
Definition: flow-private.h:61
flow-bindgen.h
FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT
#define FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT
Definition: flow-private.h:62
FLOW_TOCLIENT_DROP_LOGGED
#define FLOW_TOCLIENT_DROP_LOGGED
Definition: flow.h:79
util-random.h
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:233
FlowRateStorageEnabled
bool FlowRateStorageEnabled(void)
Definition: util-flow-rate.c:96
PacketDrop
void PacketDrop(Packet *p, const uint8_t action, enum PacketDropReason r)
issue drop action
Definition: packet.c:34
EngineModeIsIPS
int EngineModeIsIPS(void)
Definition: suricata.c:246
SIGNATURE_HOOK_PKT_FLOW_START
@ SIGNATURE_HOOK_PKT_FLOW_START
Definition: detect.h:541
FLOW_EMERGENCY
#define FLOW_EMERGENCY
Definition: flow-private.h:37
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
FLOW_TC_PM_ALPROTO_DETECT_DONE
#define FLOW_TC_PM_ALPROTO_DETECT_DONE
Definition: flow.h:91
FLOW_DEFAULT_EMERGENCY_RECOVERY
#define FLOW_DEFAULT_EMERGENCY_RECOVERY
Definition: flow.c:65
FlowHasAlerts
int FlowHasAlerts(const Flow *f)
Check if flow has alerts.
Definition: flow.c:165
FlowSparePoolInit
void FlowSparePoolInit(void)
Definition: flow-spare-pool.c:291
IPPROTO_SCTP
#define IPPROTO_SCTP
Definition: decode.h:1272
FLOW_DEFAULT_EMERG_EST_TIMEOUT
#define FLOW_DEFAULT_EMERG_EST_TIMEOUT
Definition: flow-private.h:55
FLOW_ACTION_BY_EXCEPTION_POLICY
#define FLOW_ACTION_BY_EXCEPTION_POLICY
Definition: flow.h:127
FLOW_IPPROTO_ICMP_BYPASSED_TIMEOUT
#define FLOW_IPPROTO_ICMP_BYPASSED_TIMEOUT
Definition: flow-private.h:52
FlowProtoTimeout_::est_timeout
uint32_t est_timeout
Definition: flow.h:520
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:197
Flow_::sp
Port sp
Definition: flow.h:359
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
DecodeThreadVars_::counter_flow_elephant_toclient
StatsCounterId counter_flow_elephant_toclient
Definition: decode.h:1081
DecodeThreadVars_::counter_flow_elephant_toserver
StatsCounterId counter_flow_elephant_toserver
Definition: decode.h:1080
FlowGetDisruptionFlags
uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
get 'disruption' flags: GAP/DEPTH/PASS
Definition: flow.c:1171
TcpSession_
Definition: stream-tcp-private.h:283
util-misc.h
TcpSession_::data_first_seen_dir
int8_t data_first_seen_dir
Definition: stream-tcp-private.h:288
flow.h
Flow_::alproto_tc
AppProto alproto_tc
Definition: flow.h:452
Flow_::file_flags
uint16_t file_flags
Definition: flow.h:405
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
Packet_::dp
Port dp
Definition: decode.h:530
ExceptionPolicy
ExceptionPolicy
Definition: util-exception-policy-types.h:26
FLOW_DIR_REVERSED
#define FLOW_DIR_REVERSED
Definition: flow.h:111
FLOW_PROTO_TCP
@ FLOW_PROTO_TCP
Definition: flow-private.h:66
ICMPV4_IS_ERROR_MSG
#define ICMPV4_IS_ERROR_MSG(type)
Definition: decode-icmpv4.h:267
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
SCConfNode_
Definition: conf.h:37
FLOW_IPPROTO_TCP_EST_TIMEOUT
#define FLOW_IPPROTO_TCP_EST_TIMEOUT
Definition: flow-private.h:44
SET_DEFAULTS
#define SET_DEFAULTS(p, n, e, c, b, ne, ee, ce, be)
TOCLIENT
#define TOCLIENT
Definition: flow.h:46
FLOW_PKT_TOSERVER_FIRST
#define FLOW_PKT_TOSERVER_FIRST
Definition: flow.h:234
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
PKT_DROP_REASON_FLOW_DROP
@ PKT_DROP_REASON_FLOW_DROP
Definition: decode.h:388
Packet_::src
Address src
Definition: decode.h:519
Flow_::tosrcpktcnt
uint32_t tosrcpktcnt
Definition: flow.h:496
FLOW_IS_ELEPHANT_TOSERVER
#define FLOW_IS_ELEPHANT_TOSERVER
Definition: flow.h:59
FLOW_PROTO_MAX
@ FLOW_PROTO_MAX
Definition: flow-private.h:72
FlowRateStore_
Definition: util-flow-rate.h:47
Flow_::thread_id
FlowThreadId thread_id[2]
Definition: flow.h:392
SCTIME_USECS
#define SCTIME_USECS(t)
Definition: util-time.h:56
FlowSetMemcap
int FlowSetMemcap(uint64_t size)
Update memcap value.
Definition: flow.c:108
FlowProtoFreeFunc_
Definition: flow.h:525
MacSetGetFlowStorageID
SCFlowStorageId MacSetGetFlowStorageID(void)
Definition: util-macset.c:113