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