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