suricata
flow.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Flow implementation.
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 #include "decode.h"
29 #include "conf.h"
30 #include "threadvars.h"
31 #include "tm-threads.h"
32 #include "runmodes.h"
33 
34 #include "util-random.h"
35 #include "util-time.h"
36 
37 #include "flow.h"
38 #include "flow-queue.h"
39 #include "flow-hash.h"
40 #include "flow-util.h"
41 #include "flow-var.h"
42 #include "flow-private.h"
43 #include "flow-timeout.h"
44 #include "flow-manager.h"
45 #include "flow-storage.h"
46 #include "flow-bypass.h"
47 
48 #include "stream-tcp-private.h"
49 #include "stream-tcp-reassemble.h"
50 #include "stream-tcp.h"
51 
52 #include "util-unittest.h"
53 #include "util-unittest-helper.h"
54 #include "util-byte.h"
55 #include "util-misc.h"
56 
57 #include "util-debug.h"
58 #include "util-privs.h"
59 #include "util-validate.h"
60 
61 #include "detect.h"
62 #include "detect-engine-state.h"
63 #include "stream.h"
64 
65 #include "app-layer-parser.h"
66 #include "app-layer-expectation.h"
67 
68 #define FLOW_DEFAULT_EMERGENCY_RECOVERY 30
69 
70 //#define FLOW_DEFAULT_HASHSIZE 262144
71 #define FLOW_DEFAULT_HASHSIZE 65536
72 //#define FLOW_DEFAULT_MEMCAP 128 * 1024 * 1024 /* 128 MB */
73 #define FLOW_DEFAULT_MEMCAP (32 * 1024 * 1024) /* 32 MB */
74 
75 #define FLOW_DEFAULT_PREALLOC 10000
76 
77 /** atomic int that is used when freeing a flow from the hash. In this
78  * case we walk the hash to find a flow to free. This var records where
79  * we left off in the hash. Without this only the top rows of the hash
80  * are freed. This isn't just about fairness. Under severe presure, the
81  * hash rows on top would be all freed and the time to find a flow to
82  * free increased with every run. */
83 SC_ATOMIC_DECLARE(unsigned int, flow_prune_idx);
84 
85 /** atomic flags */
86 SC_ATOMIC_DECLARE(unsigned int, flow_flags);
87 
88 /** FlowProto specific timeouts and free/state functions */
89 
93 
94 /** spare/unused/prealloced flows live here */
96 
98 
99 /** flow memuse counter (atomic), for enforcing memcap limit */
100 SC_ATOMIC_DECLARE(uint64_t, flow_memuse);
101 
102 void FlowRegisterTests(void);
103 void FlowInitFlowProto(void);
104 int FlowSetProtoFreeFunc(uint8_t, void (*Free)(void *));
105 
106 /* Run mode selected at suricata.c */
107 extern int run_mode;
108 
109 /**
110  * \brief Update memcap value
111  *
112  * \param size new memcap value
113  */
114 int FlowSetMemcap(uint64_t size)
115 {
116  if ((uint64_t)SC_ATOMIC_GET(flow_memuse) < size) {
117  SC_ATOMIC_SET(flow_config.memcap, size);
118  return 1;
119  }
120 
121  return 0;
122 }
123 
124 /**
125  * \brief Return memcap value
126  *
127  * \retval memcap value
128  */
129 uint64_t FlowGetMemcap(void)
130 {
131  uint64_t memcapcopy = SC_ATOMIC_GET(flow_config.memcap);
132  return memcapcopy;
133 }
134 
135 uint64_t FlowGetMemuse(void)
136 {
137  uint64_t memusecopy = SC_ATOMIC_GET(flow_memuse);
138  return memusecopy;
139 }
140 
142 {
143  if (f == NULL || f->proto == 0)
144  return;
145 
147  f->alstate = NULL;
148  f->alparser = NULL;
149  return;
150 }
151 
152 /** \brief Make sure we have enough spare flows.
153  *
154  * Enforce the prealloc parameter, so keep at least prealloc flows in the
155  * spare queue and free flows going over the limit.
156  *
157  * \retval 1 if the queue was properly updated (or if it already was in good shape)
158  * \retval 0 otherwise.
159  */
161 {
162  SCEnter();
163  uint32_t toalloc = 0, tofree = 0, len;
164 
166  len = flow_spare_q.len;
168 
169  if (len < flow_config.prealloc) {
170  toalloc = flow_config.prealloc - len;
171 
172  uint32_t i;
173  for (i = 0; i < toalloc; i++) {
174  Flow *f = FlowAlloc();
175  if (f == NULL)
176  return 0;
177 
179  }
180  } else if (len > flow_config.prealloc) {
181  tofree = len - flow_config.prealloc;
182 
183  uint32_t i;
184  for (i = 0; i < tofree; i++) {
185  /* FlowDequeue locks the queue */
187  if (f == NULL)
188  return 1;
189 
190  FlowFree(f);
191  }
192  }
193 
194  return 1;
195 }
196 
197 /** \brief Set the IPOnly scanned flag for 'direction'.
198  *
199  * \param f Flow to set the flag in
200  * \param direction direction to set the flag in
201  */
202 void FlowSetIPOnlyFlag(Flow *f, int direction)
203 {
204  direction ? (f->flags |= FLOW_TOSERVER_IPONLY_SET) :
206  return;
207 }
208 
209 /** \brief Set flag to indicate that flow has alerts
210  *
211  * \param f flow
212  */
214 {
215  f->flags |= FLOW_HAS_ALERTS;
216 }
217 
218 /** \brief Check if flow has alerts
219  *
220  * \param f flow
221  * \retval 1 has alerts
222  * \retval 0 has not alerts
223  */
224 int FlowHasAlerts(const Flow *f)
225 {
226  if (f->flags & FLOW_HAS_ALERTS) {
227  return 1;
228  }
229 
230  return 0;
231 }
232 
233 /** \brief Set flag to indicate to change proto for the flow
234  *
235  * \param f flow
236  */
238 {
239  f->flags |= FLOW_CHANGE_PROTO;
240 }
241 
242 /** \brief Unset flag to indicate to change proto for the flow
243  *
244  * \param f flow
245  */
247 {
248  f->flags &= ~FLOW_CHANGE_PROTO;
249 }
250 
251 /** \brief Check if change proto flag is set for flow
252  * \param f flow
253  * \retval 1 change proto flag is set
254  * \retval 0 change proto flag is not set
255  */
257 {
258  if (f->flags & FLOW_CHANGE_PROTO) {
259  return 1;
260  }
261 
262  return 0;
263 }
264 
265 static inline void FlowSwapFlags(Flow *f)
266 {
270 
275 
277 }
278 
279 static inline void FlowSwapFileFlags(Flow *f)
280 {
285 }
286 
287 static inline void TcpStreamFlowSwap(Flow *f)
288 {
289  TcpSession *ssn = f->protoctx;
290  SWAP_VARS(TcpStream, ssn->server, ssn->client);
293  } else if (ssn->data_first_seen_dir & STREAM_TOCLIENT) {
295  }
296 }
297 
298 /** \brief swap the flow's direction
299  * \note leaves the 'header' untouched. Interpret that based
300  * on FLOW_DIR_REVERSED flag.
301  * \warning: only valid before applayer parsing started. This
302  * function doesn't swap anything in Flow::alparser,
303  * Flow::alstate
304  */
305 void FlowSwap(Flow *f)
306 {
307  f->flags |= FLOW_DIR_REVERSED;
308 
311 
312  FlowSwapFlags(f);
313  FlowSwapFileFlags(f);
314 
315  if (f->proto == IPPROTO_TCP) {
316  TcpStreamFlowSwap(f);
317  }
318 
322 
323  /* not touching Flow::alparser and Flow::alstate */
324 
325  SWAP_VARS(const void *, f->sgh_toclient, f->sgh_toserver);
326 
327  SWAP_VARS(uint32_t, f->todstpktcnt, f->tosrcpktcnt);
328  SWAP_VARS(uint64_t, f->todstbytecnt, f->tosrcbytecnt);
329 }
330 
331 /**
332  * \brief determine the direction of the packet compared to the flow
333  * \retval 0 to_server
334  * \retval 1 to_client
335  */
336 int FlowGetPacketDirection(const Flow *f, const Packet *p)
337 {
338  const int reverse = (f->flags & FLOW_DIR_REVERSED) != 0;
339 
340  if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) {
341  if (!(CMP_PORT(p->sp,p->dp))) {
342  /* update flags and counters */
343  if (CMP_PORT(f->sp,p->sp)) {
344  return TOSERVER ^ reverse;
345  } else {
346  return TOCLIENT ^ reverse;
347  }
348  } else {
349  if (CMP_ADDR(&f->src,&p->src)) {
350  return TOSERVER ^ reverse;
351  } else {
352  return TOCLIENT ^ reverse;
353  }
354  }
355  } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) {
356  if (CMP_ADDR(&f->src,&p->src)) {
357  return TOSERVER ^ reverse;
358  } else {
359  return TOCLIENT ^ reverse;
360  }
361  }
362 
363  /* default to toserver */
364  return TOSERVER;
365 }
366 
367 /**
368  * \brief Check to update "seen" flags
369  *
370  * \param p packet
371  *
372  * \retval 1 true
373  * \retval 0 false
374  */
375 static inline int FlowUpdateSeenFlag(const Packet *p)
376 {
377  if (PKT_IS_ICMPV4(p)) {
378  if (ICMPV4_IS_ERROR_MSG(p)) {
379  return 0;
380  }
381  }
382 
383  return 1;
384 }
385 
386 static inline void FlowUpdateTTL(Flow *f, Packet *p, uint8_t ttl)
387 {
388  if (FlowGetPacketDirection(f, p) == TOSERVER) {
389  if (f->min_ttl_toserver == 0) {
390  f->min_ttl_toserver = ttl;
391  } else {
392  f->min_ttl_toserver = MIN(f->min_ttl_toserver, ttl);
393  }
394  f->max_ttl_toserver = MAX(f->max_ttl_toserver, ttl);
395  } else {
396  if (f->min_ttl_toclient == 0) {
397  f->min_ttl_toclient = ttl;
398  } else {
399  f->min_ttl_toclient = MIN(f->min_ttl_toclient, ttl);
400  }
401  f->max_ttl_toclient = MAX(f->max_ttl_toclient, ttl);
402  }
403 }
404 
405 /** \brief Update Packet and Flow
406  *
407  * Updates packet and flow based on the new packet.
408  *
409  * \param f locked flow
410  * \param p packet
411  *
412  * \note overwrites p::flowflags
413  */
415 {
416  SCLogDebug("packet %"PRIu64" -- flow %p", p->pcap_cnt, f);
417 
418 #ifdef CAPTURE_OFFLOAD
419  int state = SC_ATOMIC_GET(f->flow_state);
420 
421  if (state != FLOW_STATE_CAPTURE_BYPASSED) {
422 #endif
423  /* update the last seen timestamp of this flow */
424  COPY_TIMESTAMP(&p->ts, &f->lastts);
425 #ifdef CAPTURE_OFFLOAD
426  } else {
427  /* still seeing packet, we downgrade to local bypass */
428  if (p->ts.tv_sec - f->lastts.tv_sec > FLOW_BYPASSED_TIMEOUT / 2) {
429  SCLogDebug("Downgrading flow to local bypass");
430  COPY_TIMESTAMP(&p->ts, &f->lastts);
432  } else {
433  /* In IPS mode the packet could come from the other interface so it would
434  * need to be bypassed */
435  if (EngineModeIsIPS()) {
436  BypassedFlowUpdate(f, p);
437  }
438  }
439  }
440 #endif
441  /* update flags and counters */
442  if (FlowGetPacketDirection(f, p) == TOSERVER) {
443  f->todstpktcnt++;
444  f->todstbytecnt += GET_PKT_LEN(p);
446  if (!(f->flags & FLOW_TO_DST_SEEN)) {
447  if (FlowUpdateSeenFlag(p)) {
448  f->flags |= FLOW_TO_DST_SEEN;
450  }
451  }
452  /* xfer proto detect ts flag to first packet in ts dir */
453  if (f->flags & FLOW_PROTO_DETECT_TS_DONE) {
456  }
457  } else {
458  f->tosrcpktcnt++;
459  f->tosrcbytecnt += GET_PKT_LEN(p);
461  if (!(f->flags & FLOW_TO_SRC_SEEN)) {
462  if (FlowUpdateSeenFlag(p)) {
463  f->flags |= FLOW_TO_SRC_SEEN;
465  }
466  }
467  /* xfer proto detect tc flag to first packet in tc dir */
468  if (f->flags & FLOW_PROTO_DETECT_TC_DONE) {
471  }
472  }
473 
474  if (SC_ATOMIC_GET(f->flow_state) == FLOW_STATE_ESTABLISHED) {
475  SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
477 
478  } else if ((f->flags & (FLOW_TO_DST_SEEN|FLOW_TO_SRC_SEEN)) ==
480  SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
482 
483  if (f->proto != IPPROTO_TCP) {
485  }
486  }
487 
488  /*set the detection bypass flags*/
489  if (f->flags & FLOW_NOPACKET_INSPECTION) {
490  SCLogDebug("setting FLOW_NOPACKET_INSPECTION flag on flow %p", f);
492  }
493  if (f->flags & FLOW_NOPAYLOAD_INSPECTION) {
494  SCLogDebug("setting FLOW_NOPAYLOAD_INSPECTION flag on flow %p", f);
496  }
497 
498 
499  /* update flow's ttl fields if needed */
500  if (PKT_IS_IPV4(p)) {
501  FlowUpdateTTL(f, p, IPV4_GET_IPTTL(p));
502  } else if (PKT_IS_IPV6(p)) {
503  FlowUpdateTTL(f, p, IPV6_GET_HLIM(p));
504  }
505 }
506 
507 /** \brief Entry point for packet flow handling
508  *
509  * This is called for every packet.
510  *
511  * \param tv threadvars
512  * \param dtv decode thread vars (for flow output api thread data)
513  * \param p packet to handle flow for
514  */
516 {
517  /* Get this packet's flow from the hash. FlowHandlePacket() will setup
518  * a new flow if nescesary. If we get NULL, we're out of flow memory.
519  * The returned flow is locked. */
520  Flow *f = FlowGetFlowFromHash(tv, dtv, p, &p->flow);
521  if (f == NULL)
522  return;
523 
524  /* set the flow in the packet */
525  p->flags |= PKT_HAS_FLOW;
526  return;
527 }
528 
529 /** \brief initialize the configuration
530  * \warning Not thread safe */
531 void FlowInitConfig(char quiet)
532 {
533  SCLogDebug("initializing flow engine...");
534 
535  memset(&flow_config, 0, sizeof(flow_config));
536  SC_ATOMIC_INIT(flow_flags);
537  SC_ATOMIC_INIT(flow_memuse);
538  SC_ATOMIC_INIT(flow_prune_idx);
539  SC_ATOMIC_INIT(flow_config.memcap);
542 
543  /* set defaults */
544  flow_config.hash_rand = (uint32_t)RandomGet();
548 
549  /* If we have specific config, overwrite the defaults with them,
550  * otherwise, leave the default values */
551  intmax_t val = 0;
552  if (ConfGetInt("flow.emergency-recovery", &val) == 1) {
553  if (val <= 100 && val >= 1) {
554  flow_config.emergency_recovery = (uint8_t)val;
555  } else {
556  SCLogError(SC_ERR_INVALID_VALUE, "flow.emergency-recovery must be in the range of 1 and 100 (as percentage)");
558  }
559  } else {
560  SCLogDebug("flow.emergency-recovery, using default value");
562  }
563 
564  /* Check if we have memcap and hash_size defined at config */
565  const char *conf_val;
566  uint32_t configval = 0;
567 
568  /** set config values for memcap, prealloc and hash_size */
569  uint64_t flow_memcap_copy;
570  if ((ConfGet("flow.memcap", &conf_val)) == 1)
571  {
572  if (conf_val == NULL) {
573  FatalError(SC_ERR_FATAL, "Invalid value for flow.memcap: NULL");
574  }
575 
576  if (ParseSizeStringU64(conf_val, &flow_memcap_copy) < 0) {
577  SCLogError(SC_ERR_SIZE_PARSE, "Error parsing flow.memcap "
578  "from conf file - %s. Killing engine",
579  conf_val);
580  exit(EXIT_FAILURE);
581  } else {
582  SC_ATOMIC_SET(flow_config.memcap, flow_memcap_copy);
583  }
584  }
585  if ((ConfGet("flow.hash-size", &conf_val)) == 1)
586  {
587  if (conf_val == NULL) {
588  FatalError(SC_ERR_FATAL, "Invalid value for flow.hash-size: NULL");
589  }
590 
591  if (StringParseUint32(&configval, 10, strlen(conf_val),
592  conf_val) > 0) {
593  flow_config.hash_size = configval;
594  }
595  }
596  if ((ConfGet("flow.prealloc", &conf_val)) == 1)
597  {
598  if (conf_val == NULL) {
599  FatalError(SC_ERR_FATAL, "Invalid value for flow.prealloc: NULL");
600  }
601 
602  if (StringParseUint32(&configval, 10, strlen(conf_val),
603  conf_val) > 0) {
604  flow_config.prealloc = configval;
605  }
606  }
607  SCLogDebug("Flow config from suricata.yaml: memcap: %"PRIu64", hash-size: "
608  "%"PRIu32", prealloc: %"PRIu32, SC_ATOMIC_GET(flow_config.memcap),
610 
611  /* alloc hash memory */
612  uint64_t hash_size = flow_config.hash_size * sizeof(FlowBucket);
613  if (!(FLOW_CHECK_MEMCAP(hash_size))) {
614  SCLogError(SC_ERR_FLOW_INIT, "allocating flow hash failed: "
615  "max flow memcap is smaller than projected hash size. "
616  "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate "
617  "total hash size by multiplying \"flow.hash-size\" with %"PRIuMAX", "
618  "which is the hash bucket size.", SC_ATOMIC_GET(flow_config.memcap), hash_size,
619  (uintmax_t)sizeof(FlowBucket));
620  exit(EXIT_FAILURE);
621  }
622  flow_hash = SCMallocAligned(flow_config.hash_size * sizeof(FlowBucket), CLS);
623  if (unlikely(flow_hash == NULL)) {
625  "Fatal error encountered in FlowInitConfig. Exiting...");
626  }
627  memset(flow_hash, 0, flow_config.hash_size * sizeof(FlowBucket));
628 
629  uint32_t i = 0;
630  for (i = 0; i < flow_config.hash_size; i++) {
631  FBLOCK_INIT(&flow_hash[i]);
632  SC_ATOMIC_INIT(flow_hash[i].next_ts);
633  }
634  (void) SC_ATOMIC_ADD(flow_memuse, (flow_config.hash_size * sizeof(FlowBucket)));
635 
636  if (quiet == FALSE) {
637  SCLogConfig("allocated %"PRIu64" bytes of memory for the flow hash... "
638  "%" PRIu32 " buckets of size %" PRIuMAX "",
639  SC_ATOMIC_GET(flow_memuse), flow_config.hash_size,
640  (uintmax_t)sizeof(FlowBucket));
641  }
642 
643  /* pre allocate flows */
644  for (i = 0; i < flow_config.prealloc; i++) {
645  if (!(FLOW_CHECK_MEMCAP(sizeof(Flow) + FlowStorageSize()))) {
646  SCLogError(SC_ERR_FLOW_INIT, "preallocating flows failed: "
647  "max flow memcap reached. Memcap %"PRIu64", "
648  "Memuse %"PRIu64".", SC_ATOMIC_GET(flow_config.memcap),
649  ((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)sizeof(Flow)));
650  exit(EXIT_FAILURE);
651  }
652 
653  Flow *f = FlowAlloc();
654  if (f == NULL) {
655  SCLogError(SC_ERR_FLOW_INIT, "preallocating flow failed: %s", strerror(errno));
656  exit(EXIT_FAILURE);
657  }
658 
660  }
661 
662  if (quiet == FALSE) {
663  SCLogConfig("preallocated %" PRIu32 " flows of size %" PRIuMAX "",
664  flow_spare_q.len, (uintmax_t)(sizeof(Flow) + + FlowStorageSize()));
665  SCLogConfig("flow memory usage: %"PRIu64" bytes, maximum: %"PRIu64,
666  SC_ATOMIC_GET(flow_memuse), SC_ATOMIC_GET(flow_config.memcap));
667  }
668 
670 
671  return;
672 }
673 
674 /** \brief print some flow stats
675  * \warning Not thread safe */
676 static void FlowPrintStats (void)
677 {
678  return;
679 }
680 
681 /** \brief shutdown the flow engine
682  * \warning Not thread safe */
683 void FlowShutdown(void)
684 {
685  Flow *f;
686  uint32_t u;
687 
688  FlowPrintStats();
689 
690  /* free queues */
691  while((f = FlowDequeue(&flow_spare_q))) {
692  FlowFree(f);
693  }
694  while((f = FlowDequeue(&flow_recycle_q))) {
695  FlowFree(f);
696  }
697 
698  /* clear and free the hash */
699  if (flow_hash != NULL) {
700  /* clean up flow mutexes */
701  for (u = 0; u < flow_config.hash_size; u++) {
702  f = flow_hash[u].head;
703  while (f) {
704  DEBUG_VALIDATE_BUG_ON(SC_ATOMIC_GET(f->use_cnt) != 0);
705  Flow *n = f->hnext;
706  uint8_t proto_map = FlowGetProtoMapping(f->proto);
707  FlowClearMemory(f, proto_map);
708  FlowFree(f);
709  f = n;
710  }
711 
713  }
715  flow_hash = NULL;
716  }
717  (void) SC_ATOMIC_SUB(flow_memuse, flow_config.hash_size * sizeof(FlowBucket));
720  return;
721 }
722 
723 /**
724  * \brief Function to set the default timeout, free function and flow state
725  * function for all supported flow_proto.
726  */
727 
729 {
731 
732 #define SET_DEFAULTS(p, n, e, c, b, ne, ee, ce, be) \
733  flow_timeouts_normal[(p)].new_timeout = (n); \
734  flow_timeouts_normal[(p)].est_timeout = (e); \
735  flow_timeouts_normal[(p)].closed_timeout = (c); \
736  flow_timeouts_normal[(p)].bypassed_timeout = (b); \
737  flow_timeouts_emerg[(p)].new_timeout = (ne); \
738  flow_timeouts_emerg[(p)].est_timeout = (ee); \
739  flow_timeouts_emerg[(p)].closed_timeout = (ce); \
740  flow_timeouts_emerg[(p)].bypassed_timeout = (be); \
741 
762 
767 
768  /* Let's see if we have custom timeouts defined from config */
769  const char *new = NULL;
770  const char *established = NULL;
771  const char *closed = NULL;
772  const char *bypassed = NULL;
773  const char *emergency_new = NULL;
774  const char *emergency_established = NULL;
775  const char *emergency_closed = NULL;
776  const char *emergency_bypassed = NULL;
777 
778  ConfNode *flow_timeouts = ConfGetNode("flow-timeouts");
779  if (flow_timeouts != NULL) {
780  ConfNode *proto = NULL;
781  uint32_t configval = 0;
782 
783  /* Defaults. */
784  proto = ConfNodeLookupChild(flow_timeouts, "default");
785  if (proto != NULL) {
786  new = ConfNodeLookupChildValue(proto, "new");
787  established = ConfNodeLookupChildValue(proto, "established");
788  closed = ConfNodeLookupChildValue(proto, "closed");
789  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
790  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
791  emergency_established = ConfNodeLookupChildValue(proto,
792  "emergency-established");
793  emergency_closed = ConfNodeLookupChildValue(proto,
794  "emergency-closed");
795  emergency_bypassed = ConfNodeLookupChildValue(proto,
796  "emergency-bypassed");
797 
798  if (new != NULL &&
799  StringParseUint32(&configval, 10, strlen(new), new) > 0) {
800 
802  }
803  if (established != NULL &&
804  StringParseUint32(&configval, 10, strlen(established),
805  established) > 0) {
806 
808  }
809  if (closed != NULL &&
810  StringParseUint32(&configval, 10, strlen(closed),
811  closed) > 0) {
812 
814  }
815  if (bypassed != NULL &&
816  StringParseUint32(&configval, 10,
817  strlen(bypassed),
818  bypassed) > 0) {
819 
821  }
822  if (emergency_new != NULL &&
823  StringParseUint32(&configval, 10, strlen(emergency_new),
824  emergency_new) > 0) {
825 
827  }
828  if (emergency_established != NULL &&
829  StringParseUint32(&configval, 10,
830  strlen(emergency_established),
831  emergency_established) > 0) {
832 
834  }
835  if (emergency_closed != NULL &&
836  StringParseUint32(&configval, 10,
837  strlen(emergency_closed),
838  emergency_closed) > 0) {
839 
841  }
842  if (emergency_bypassed != NULL &&
843  StringParseUint32(&configval, 10,
844  strlen(emergency_bypassed),
845  emergency_bypassed) > 0) {
846 
848  }
849  }
850 
851  /* TCP. */
852  proto = ConfNodeLookupChild(flow_timeouts, "tcp");
853  if (proto != NULL) {
854  new = ConfNodeLookupChildValue(proto, "new");
855  established = ConfNodeLookupChildValue(proto, "established");
856  closed = ConfNodeLookupChildValue(proto, "closed");
857  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
858  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
859  emergency_established = ConfNodeLookupChildValue(proto,
860  "emergency-established");
861  emergency_closed = ConfNodeLookupChildValue(proto,
862  "emergency-closed");
863  emergency_bypassed = ConfNodeLookupChildValue(proto,
864  "emergency-bypassed");
865 
866  if (new != NULL &&
867  StringParseUint32(&configval, 10, strlen(new), new) > 0) {
868 
870  }
871  if (established != NULL &&
872  StringParseUint32(&configval, 10, strlen(established),
873  established) > 0) {
874 
876  }
877  if (closed != NULL &&
878  StringParseUint32(&configval, 10, strlen(closed),
879  closed) > 0) {
880 
882  }
883  if (bypassed != NULL &&
884  StringParseUint32(&configval, 10,
885  strlen(bypassed),
886  bypassed) > 0) {
887 
889  }
890  if (emergency_new != NULL &&
891  StringParseUint32(&configval, 10, strlen(emergency_new),
892  emergency_new) > 0) {
893 
895  }
896  if (emergency_established != NULL &&
897  StringParseUint32(&configval, 10,
898  strlen(emergency_established),
899  emergency_established) > 0) {
900 
902  }
903  if (emergency_closed != NULL &&
904  StringParseUint32(&configval, 10,
905  strlen(emergency_closed),
906  emergency_closed) > 0) {
907 
909  }
910  if (emergency_bypassed != NULL &&
911  StringParseUint32(&configval, 10,
912  strlen(emergency_bypassed),
913  emergency_bypassed) > 0) {
914 
916  }
917  }
918 
919  /* UDP. */
920  proto = ConfNodeLookupChild(flow_timeouts, "udp");
921  if (proto != NULL) {
922  new = ConfNodeLookupChildValue(proto, "new");
923  established = ConfNodeLookupChildValue(proto, "established");
924  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
925  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
926  emergency_established = ConfNodeLookupChildValue(proto,
927  "emergency-established");
928  emergency_bypassed = ConfNodeLookupChildValue(proto,
929  "emergency-bypassed");
930 
931  if (new != NULL &&
932  StringParseUint32(&configval, 10, strlen(new), new) > 0) {
933 
935  }
936  if (established != NULL &&
937  StringParseUint32(&configval, 10, strlen(established),
938  established) > 0) {
939 
941  }
942  if (bypassed != NULL &&
943  StringParseUint32(&configval, 10,
944  strlen(bypassed),
945  bypassed) > 0) {
946 
948  }
949  if (emergency_new != NULL &&
950  StringParseUint32(&configval, 10, strlen(emergency_new),
951  emergency_new) > 0) {
952 
954  }
955  if (emergency_established != NULL &&
956  StringParseUint32(&configval, 10,
957  strlen(emergency_established),
958  emergency_established) > 0) {
959 
961  }
962  if (emergency_bypassed != NULL &&
963  StringParseUint32(&configval, 10,
964  strlen(emergency_bypassed),
965  emergency_bypassed) > 0) {
966 
968  }
969  }
970 
971  /* ICMP. */
972  proto = ConfNodeLookupChild(flow_timeouts, "icmp");
973  if (proto != NULL) {
974  new = ConfNodeLookupChildValue(proto, "new");
975  established = ConfNodeLookupChildValue(proto, "established");
976  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
977  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
978  emergency_established = ConfNodeLookupChildValue(proto,
979  "emergency-established");
980  emergency_bypassed = ConfNodeLookupChildValue(proto,
981  "emergency-bypassed");
982 
983  if (new != NULL &&
984  StringParseUint32(&configval, 10, strlen(new), new) > 0) {
985 
987  }
988  if (established != NULL &&
989  StringParseUint32(&configval, 10, strlen(established),
990  established) > 0) {
991 
993  }
994  if (bypassed != NULL &&
995  StringParseUint32(&configval, 10,
996  strlen(bypassed),
997  bypassed) > 0) {
998 
1000  }
1001  if (emergency_new != NULL &&
1002  StringParseUint32(&configval, 10, strlen(emergency_new),
1003  emergency_new) > 0) {
1004 
1006  }
1007  if (emergency_established != NULL &&
1008  StringParseUint32(&configval, 10,
1009  strlen(emergency_established),
1010  emergency_established) > 0) {
1011 
1013  }
1014  if (emergency_bypassed != NULL &&
1015  StringParseUint32(&configval, 10,
1016  strlen(emergency_bypassed),
1017  emergency_bypassed) > 0) {
1018 
1020  }
1021  }
1022  }
1023 
1024  return;
1025 }
1026 
1027 /**
1028  * \brief Function clear the flow memory before queueing it to spare flow
1029  * queue.
1030  *
1031  * \param f pointer to the flow needed to be cleared.
1032  * \param proto_map mapped value of the protocol to FLOW_PROTO's.
1033  */
1034 
1035 int FlowClearMemory(Flow* f, uint8_t proto_map)
1036 {
1037  SCEnter();
1038 
1039  if (unlikely(f->flags & FLOW_HAS_EXPECTATION)) {
1041  }
1042 
1043  /* call the protocol specific free function if we have one */
1044  if (flow_freefuncs[proto_map].Freefunc != NULL) {
1045  flow_freefuncs[proto_map].Freefunc(f->protoctx);
1046  }
1047 
1048  FlowFreeStorage(f);
1049 
1050  FLOW_RECYCLE(f);
1051 
1052  SCReturnInt(1);
1053 }
1054 
1055 /**
1056  * \brief Function to set the function to get protocol specific flow state.
1057  *
1058  * \param proto protocol of which function is needed to be set.
1059  * \param Free Function pointer which will be called to free the protocol
1060  * specific memory.
1061  */
1062 
1063 int FlowSetProtoFreeFunc (uint8_t proto, void (*Free)(void *))
1064 {
1065  uint8_t proto_map;
1066  proto_map = FlowGetProtoMapping(proto);
1067 
1068  flow_freefuncs[proto_map].Freefunc = Free;
1069  return 1;
1070 }
1071 
1073 {
1074  return f->alproto;
1075 }
1076 
1077 void *FlowGetAppState(const Flow *f)
1078 {
1079  return f->alstate;
1080 }
1081 
1082 /**
1083  * \brief get 'disruption' flags: GAP/DEPTH/PASS
1084  * \param f locked flow
1085  * \param flags existing flags to be ammended
1086  * \retval flags original flags + disrupt flags (if any)
1087  * \TODO handle UDP
1088  */
1089 uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
1090 {
1091  if (f->proto != IPPROTO_TCP) {
1092  return flags;
1093  }
1094  if (f->protoctx == NULL) {
1095  return flags;
1096  }
1097 
1098  uint8_t newflags = flags;
1099  TcpSession *ssn = f->protoctx;
1100  TcpStream *stream = flags & STREAM_TOSERVER ? &ssn->client : &ssn->server;
1101 
1103  newflags |= STREAM_DEPTH;
1104  }
1105  if (stream->flags & STREAMTCP_STREAM_FLAG_GAP) {
1106  newflags |= STREAM_GAP;
1107  }
1108  /* todo: handle pass case (also for UDP!) */
1109 
1110  return newflags;
1111 }
1112 
1114 {
1115  /* set the state */
1116  SC_ATOMIC_SET(f->flow_state, s);
1117 
1118  if (f->fb) {
1119  /* and reset the flow buckup next_ts value so that the flow manager
1120  * has to revisit this row */
1121  SC_ATOMIC_SET(f->fb->next_ts, 0);
1122  }
1123 }
1124 
1125 /**
1126  * \brief Get flow last time as individual values.
1127  *
1128  * Instead of returning a pointer to the timeval copy the timeval
1129  * parts into output pointers to make it simpler to call from Rust
1130  * over FFI using only basic data types.
1131  */
1132 void FlowGetLastTimeAsParts(Flow *flow, uint64_t *secs, uint64_t *usecs)
1133 {
1134  *secs = (uint64_t)flow->lastts.tv_sec;
1135  *usecs = (uint64_t)flow->lastts.tv_usec;
1136 }
1137 
1138 /************************************Unittests*******************************/
1139 
1140 #ifdef UNITTESTS
1141 #include "threads.h"
1142 
1143 /**
1144  * \test Test the setting of the per protocol timeouts.
1145  *
1146  * \retval On success it returns 1 and on failure 0.
1147  */
1148 
1149 static int FlowTest01 (void)
1150 {
1151  uint8_t proto_map;
1152 
1154  proto_map = FlowGetProtoMapping(IPPROTO_TCP);
1155  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT);
1156  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_TCP_EST_TIMEOUT);
1159 
1160  proto_map = FlowGetProtoMapping(IPPROTO_UDP);
1161  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT);
1162  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_TIMEOUT);
1165 
1166  proto_map = FlowGetProtoMapping(IPPROTO_ICMP);
1167  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT);
1168  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_TIMEOUT);
1171 
1172  proto_map = FlowGetProtoMapping(IPPROTO_DCCP);
1173  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT);
1174  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_DEFAULT_EST_TIMEOUT);
1175  FAIL_IF(flow_timeouts_emerg[proto_map].new_timeout != FLOW_DEFAULT_EMERG_NEW_TIMEOUT);
1176  FAIL_IF(flow_timeouts_emerg[proto_map].est_timeout != FLOW_DEFAULT_EMERG_EST_TIMEOUT);
1177 
1178  PASS;
1179 }
1180 
1181 /*Test function for the unit test FlowTest02*/
1182 
1183 static void test(void *f) {}
1184 
1185 /**
1186  * \test Test the setting of the per protocol free function to free the
1187  * protocol specific memory.
1188  *
1189  * \retval On success it returns 1 and on failure 0.
1190  */
1191 
1192 static int FlowTest02 (void)
1193 {
1194  FlowSetProtoFreeFunc(IPPROTO_DCCP, test);
1195  FlowSetProtoFreeFunc(IPPROTO_TCP, test);
1196  FlowSetProtoFreeFunc(IPPROTO_UDP, test);
1197  FlowSetProtoFreeFunc(IPPROTO_ICMP, test);
1198 
1199  FAIL_IF(flow_freefuncs[FLOW_PROTO_DEFAULT].Freefunc != test);
1200  FAIL_IF(flow_freefuncs[FLOW_PROTO_TCP].Freefunc != test);
1201  FAIL_IF(flow_freefuncs[FLOW_PROTO_UDP].Freefunc != test);
1202  FAIL_IF(flow_freefuncs[FLOW_PROTO_ICMP].Freefunc != test);
1203 
1204  PASS;
1205 }
1206 
1207 /**
1208  * \test Test flow allocations when it reach memcap
1209  *
1210  *
1211  * \retval On success it returns 1 and on failure 0.
1212  */
1213 
1214 static int FlowTest07 (void)
1215 {
1216  int result = 0;
1217 
1219  FlowConfig backup;
1220  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1221 
1222  uint32_t ini = 0;
1223  uint32_t end = flow_spare_q.len;
1224  SC_ATOMIC_SET(flow_config.memcap, 10000);
1225  flow_config.prealloc = 100;
1226 
1227  /* Let's get the flow_spare_q empty */
1228  UTHBuildPacketOfFlows(ini, end, 0);
1229 
1230  /* And now let's try to reach the memcap val */
1231  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1232  ini = end + 1;
1233  end = end + 2;
1234  UTHBuildPacketOfFlows(ini, end, 0);
1235  }
1236 
1237  /* should time out normal */
1238  TimeSetIncrementTime(2000);
1239  ini = end + 1;
1240  end = end + 2;;
1241  UTHBuildPacketOfFlows(ini, end, 0);
1242 
1243  /* This means that the engine entered emerg mode: should happen as easy
1244  * with flow mgr activated */
1245  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1246  result = 1;
1247 
1248  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1249  FlowShutdown();
1250 
1251  return result;
1252 }
1253 
1254 /**
1255  * \test Test flow allocations when it reach memcap
1256  *
1257  *
1258  * \retval On success it returns 1 and on failure 0.
1259  */
1260 
1261 static int FlowTest08 (void)
1262 {
1263  int result = 0;
1264 
1266  FlowConfig backup;
1267  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1268 
1269  uint32_t ini = 0;
1270  uint32_t end = flow_spare_q.len;
1271  SC_ATOMIC_SET(flow_config.memcap, 10000);
1272  flow_config.prealloc = 100;
1273 
1274  /* Let's get the flow_spare_q empty */
1275  UTHBuildPacketOfFlows(ini, end, 0);
1276 
1277  /* And now let's try to reach the memcap val */
1278  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1279  ini = end + 1;
1280  end = end + 2;
1281  UTHBuildPacketOfFlows(ini, end, 0);
1282  }
1283 
1284  /* By default we use 30 for timing out new flows. This means
1285  * that the Emergency mode should be set */
1287  ini = end + 1;
1288  end = end + 2;
1289  UTHBuildPacketOfFlows(ini, end, 0);
1290 
1291  /* This means that the engine released 5 flows by emergency timeout */
1292  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1293  result = 1;
1294 
1295  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1296  FlowShutdown();
1297 
1298  return result;
1299 }
1300 
1301 /**
1302  * \test Test flow allocations when it reach memcap
1303  *
1304  *
1305  * \retval On success it returns 1 and on failure 0.
1306  */
1307 
1308 static int FlowTest09 (void)
1309 {
1310  int result = 0;
1311 
1313  FlowConfig backup;
1314  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1315 
1316  uint32_t ini = 0;
1317  uint32_t end = flow_spare_q.len;
1318  SC_ATOMIC_SET(flow_config.memcap, 10000);
1319  flow_config.prealloc = 100;
1320 
1321  /* Let's get the flow_spare_q empty */
1322  UTHBuildPacketOfFlows(ini, end, 0);
1323 
1324  /* And now let's try to reach the memcap val */
1325  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1326  ini = end + 1;
1327  end = end + 2;
1328  UTHBuildPacketOfFlows(ini, end, 0);
1329  }
1330 
1331  /* No timeout will work */
1333  ini = end + 1;
1334  end = end + 2;
1335  UTHBuildPacketOfFlows(ini, end, 0);
1336 
1337  /* engine in emerg mode */
1338  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1339  result = 1;
1340 
1341  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1342  FlowShutdown();
1343 
1344  return result;
1345 }
1346 
1347 #endif /* UNITTESTS */
1348 
1349 /**
1350  * \brief Function to register the Flow Unitests.
1351  */
1353 {
1354 #ifdef UNITTESTS
1355  UtRegisterTest("FlowTest01 -- Protocol Specific Timeouts", FlowTest01);
1356  UtRegisterTest("FlowTest02 -- Setting Protocol Specific Free Function",
1357  FlowTest02);
1358  UtRegisterTest("FlowTest07 -- Test flow Allocations when it reach memcap",
1359  FlowTest07);
1360  UtRegisterTest("FlowTest08 -- Test flow Allocations when it reach memcap",
1361  FlowTest08);
1362  UtRegisterTest("FlowTest09 -- Test flow Allocations when it reach memcap",
1363  FlowTest09);
1364 
1367 #endif /* UNITTESTS */
1368 }
util-byte.h
FlowUnsetChangeProtoFlag
void FlowUnsetChangeProtoFlag(Flow *f)
Unset flag to indicate to change proto for the flow.
Definition: flow.c:246
FlowMgrRegisterTests
void FlowMgrRegisterTests(void)
Function to register the Flow Unitests.
Definition: flow-manager.c:1427
FBLOCK_DESTROY
#define FBLOCK_DESTROY(fb)
Definition: flow-hash.h:67
FLOW_DEFAULT_NEW_TIMEOUT
#define FLOW_DEFAULT_NEW_TIMEOUT
Definition: flow-private.h:40
tm-threads.h
ConfGetInt
int ConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:436
Packet_::proto
uint8_t proto
Definition: decode.h:433
DecodeSetNoPacketInspectionFlag
#define DecodeSetNoPacketInspectionFlag(p)
Set the No packet inspection Flag for the packet.
Definition: decode.h:973
FLOW_DEFAULT_EMERG_BYPASSED_TIMEOUT
#define FLOW_DEFAULT_EMERG_BYPASSED_TIMEOUT
Definition: flow-private.h:58
TcpStream_
Definition: stream-tcp-private.h:94
flow-bypass.h
FLOW_HAS_EXPECTATION
#define FLOW_HAS_EXPECTATION
Definition: flow.h:108
len
uint8_t len
Definition: app-layer-dnp3.h:2
FlowSetHasAlertsFlag
void FlowSetHasAlertsFlag(Flow *f)
Set flag to indicate that flow has alerts.
Definition: flow.c:213
FlowCleanupAppLayer
void FlowCleanupAppLayer(Flow *f)
Definition: flow.c:141
FlowSetChangeProtoFlag
void FlowSetChangeProtoFlag(Flow *f)
Set flag to indicate to change proto for the flow.
Definition: flow.c:237
FLOW_PROTO_DEFAULT
@ FLOW_PROTO_DEFAULT
Definition: flow-private.h:73
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1087
SC_ERR_INVALID_VALUE
@ SC_ERR_INVALID_VALUE
Definition: util-error.h:160
FlowGetPacketDirection
int FlowGetPacketDirection(const Flow *f, const Packet *p)
determine the direction of the packet compared to the flow
Definition: flow.c:336
FLOW_STATE_ESTABLISHED
@ FLOW_STATE_ESTABLISHED
Definition: flow.h:484
flow-util.h
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:286
FBLOCK_INIT
#define FBLOCK_INIT(fb)
Definition: flow-hash.h:66
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:255
CLS
#define CLS
Definition: suricata-common.h:45
stream-tcp.h
FLOW_DEFAULT_HASHSIZE
#define FLOW_DEFAULT_HASHSIZE
Definition: flow.c:71
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
FlowCnf_::emergency_recovery
uint32_t emergency_recovery
Definition: flow.h:290
FLOW_DEFAULT_PREALLOC
#define FLOW_DEFAULT_PREALLOC
Definition: flow.c:75
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:355
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:281
FlowRegisterTests
void FlowRegisterTests(void)
Function to register the Flow Unitests.
Definition: flow.c:1352
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT
#define FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT
Definition: flow-private.h:62
FLOW_SGH_TOCLIENT
#define FLOW_SGH_TOCLIENT
Definition: flow.h:69
Flow_::hnext
struct Flow_ * hnext
Definition: flow.h:467
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:564
ParseSizeStringU64
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition: util-misc.c:203
Flow_::proto
uint8_t proto
Definition: flow.h:361
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:71
FLOWFILE_NO_MAGIC_TS
#define FLOWFILE_NO_MAGIC_TS
Definition: flow.h:115
Packet_::flags
uint32_t flags
Definition: decode.h:446
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:175
threads.h
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:343
run_mode
int run_mode
Definition: suricata.c:200
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:304
FlowInitConfig
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:531
FlowProtoTimeout_
Definition: flow.h:492
flow-hash.h
FLOW_NOPAYLOAD_INSPECTION
#define FLOW_NOPAYLOAD_INSPECTION
Definition: flow.h:61
FLOW_TS_PM_ALPROTO_DETECT_DONE
#define FLOW_TS_PM_ALPROTO_DETECT_DONE
Definition: flow.h:80
FLOW_DEFAULT_EMERG_NEW_TIMEOUT
#define FLOW_DEFAULT_EMERG_NEW_TIMEOUT
Definition: flow-private.h:55
FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT
#define FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT
Definition: flow-private.h:59
BypassedFlowUpdate
void BypassedFlowUpdate(Flow *f, Packet *p)
Definition: flow-bypass.c:203
FlowProtoTimeout_::bypassed_timeout
uint32_t bypassed_timeout
Definition: flow.h:496
FLOW_DEFAULT_EST_TIMEOUT
#define FLOW_DEFAULT_EST_TIMEOUT
Definition: flow-private.h:41
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:218
FlowGetMemuse
uint64_t FlowGetMemuse(void)
Definition: flow.c:135
MIN
#define MIN(x, y)
Definition: suricata-common.h:377
FlowGetMemcap
uint64_t FlowGetMemcap(void)
Return memcap value.
Definition: flow.c:129
FlowQueueDestroy
void FlowQueueDestroy(FlowQueue *q)
Destroy a flow queue.
Definition: flow-queue.c:61
util-privs.h
stream-tcp-reassemble.h
TcpStream_::flags
uint16_t flags
Definition: stream-tcp-private.h:95
RandomGet
long int RandomGet(void)
Definition: util-random.c:129
FLOW_TOSERVER_DROP_LOGGED
#define FLOW_TOSERVER_DROP_LOGGED
Definition: flow.h:72
Flow_::max_ttl_toserver
uint8_t max_ttl_toserver
Definition: flow.h:446
proto
uint8_t proto
Definition: decode-template.h:0
FLOW_TC_PE_ALPROTO_DETECT_DONE
#define FLOW_TC_PE_ALPROTO_DETECT_DONE
Definition: flow.h:90
FLOW_DEFAULT_BYPASSED_TIMEOUT
#define FLOW_DEFAULT_BYPASSED_TIMEOUT
Definition: flow-private.h:43
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:442
MAX
#define MAX(x, y)
Definition: suricata-common.h:381
Flow_::protoctx
void * protoctx
Definition: flow.h:416
FLOW_IPPROTO_UDP_BYPASSED_TIMEOUT
#define FLOW_IPPROTO_UDP_BYPASSED_TIMEOUT
Definition: flow-private.h:50
STREAMTCP_STREAM_FLAG_DEPTH_REACHED
#define STREAMTCP_STREAM_FLAG_DEPTH_REACHED
Definition: stream-tcp-private.h:204
FlowEnqueue
void FlowEnqueue(FlowQueue *q, Flow *f)
add a flow to a queue
Definition: flow-queue.c:72
FlowQueue_::len
uint32_t len
Definition: flow-queue.h:45
util-unittest.h
FLOW_BYPASSED_TIMEOUT
#define FLOW_BYPASSED_TIMEOUT
Definition: flow-private.h:67
FlowGetAppState
void * FlowGetAppState(const Flow *f)
Definition: flow.c:1077
util-unittest-helper.h
FLOW_IPPROTO_TCP_EMERG_CLOSED_TIMEOUT
#define FLOW_IPPROTO_TCP_EMERG_CLOSED_TIMEOUT
Definition: flow-private.h:61
FLOW_IPPROTO_ICMP_EST_TIMEOUT
#define FLOW_IPPROTO_ICMP_EST_TIMEOUT
Definition: flow-private.h:52
FlowCnf_::prealloc
uint32_t prealloc
Definition: flow.h:283
UTHBuildPacketOfFlows
uint32_t UTHBuildPacketOfFlows(uint32_t start, uint32_t end, uint8_t dir)
Definition: util-unittest-helper.c:930
AppLayerExpectationClean
void AppLayerExpectationClean(Flow *f)
Definition: app-layer-expectation.c:359
PKT_PROTO_DETECT_TS_DONE
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1111
FQLOCK_LOCK
#define FQLOCK_LOCK(q)
Definition: flow-queue.h:67
Flow_::sgh_toserver
const struct SigGroupHead_ * sgh_toserver
Definition: flow.h:461
FLOW_CHECK_MEMCAP
#define FLOW_CHECK_MEMCAP(size)
check if a memory alloc would fit in the memcap
Definition: flow-util.h:135
FLOW_PROTO_ICMP
@ FLOW_PROTO_ICMP
Definition: flow-private.h:72
FLOW_RECYCLE
#define FLOW_RECYCLE(f)
macro to recycle a flow before it goes into the spare queue for reuse.
Definition: flow-util.h:84
Flow_::tosrcbytecnt
uint64_t tosrcbytecnt
Definition: flow.h:479
SC_ERR_SIZE_PARSE
@ SC_ERR_SIZE_PARSE
Definition: util-error.h:230
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:330
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:453
FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT
#define FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT
Definition: flow-private.h:65
Flow_::fb
struct FlowBucket_ * fb
Definition: flow.h:469
app-layer-expectation.h
FLOW_IPPROTO_UDP_EST_TIMEOUT
#define FLOW_IPPROTO_UDP_EST_TIMEOUT
Definition: flow-private.h:49
SC_ERR_FLOW_INIT
@ SC_ERR_FLOW_INIT
Definition: util-error.h:237
FLOW_STATE_LOCAL_BYPASSED
@ FLOW_STATE_LOCAL_BYPASSED
Definition: flow.h:486
Flow_::min_ttl_toserver
uint8_t min_ttl_toserver
Definition: flow.h:445
FLOW_PROTO_MAX
@ FLOW_PROTO_MAX
Definition: flow-private.h:76
decode.h
util-debug.h
TOSERVER
#define TOSERVER
Definition: flow.h:41
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
Flow_::todstpktcnt
uint32_t todstpktcnt
Definition: flow.h:476
DecodeSetNoPayloadInspectionFlag
#define DecodeSetNoPayloadInspectionFlag(p)
Set the No payload inspection Flag for the packet.
Definition: decode.h:961
FLOW_IPPROTO_TCP_CLOSED_TIMEOUT
#define FLOW_IPPROTO_TCP_CLOSED_TIMEOUT
Definition: flow-private.h:46
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
FLOW_CHANGE_PROTO
#define FLOW_CHANGE_PROTO
Definition: flow.h:102
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
FlowStorageSize
unsigned int FlowStorageSize(void)
Definition: flow-storage.c:34
Packet_::sp
Port sp
Definition: decode.h:418
FlowCnf_
Definition: flow.h:279
FLOW_PKT_TOCLIENT_FIRST
#define FLOW_PKT_TOCLIENT_FIRST
Definition: flow.h:224
FlowQueueInit
FlowQueue * FlowQueueInit(FlowQueue *q)
Definition: flow-queue.c:47
FlowState
FlowState
Definition: flow.h:482
FlowProtoTimeout_::new_timeout
uint32_t new_timeout
Definition: flow.h:493
FlowProtoTimeout_::closed_timeout
uint32_t closed_timeout
Definition: flow.h:495
util-time.h
app-layer-parser.h
AppLayerParserStateCleanup
void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1435
FLOW_PROTO_DETECT_TC_DONE
#define FLOW_PROTO_DETECT_TC_DONE
Definition: flow.h:99
Flow_::todstbytecnt
uint64_t todstbytecnt
Definition: flow.h:478
FLOW_TC_PP_ALPROTO_DETECT_DONE
#define FLOW_TC_PP_ALPROTO_DETECT_DONE
Definition: flow.h:88
Flow_::sgh_toclient
const struct SigGroupHead_ * sgh_toclient
Definition: flow.h:458
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:313
FALSE
#define FALSE
Definition: suricata-common.h:34
stream.h
TimeSetIncrementTime
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
Definition: util-time.c:182
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:95
Packet_
Definition: decode.h:411
SCFreeAligned
#define SCFreeAligned(p)
Definition: util-mem.h:77
STREAM_DEPTH
#define STREAM_DEPTH
Definition: stream.h:34
FLOW_DEFAULT_MEMCAP
#define FLOW_DEFAULT_MEMCAP
Definition: flow.c:73
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:227
stream-tcp-private.h
conf.h
FlowSetIPOnlyFlag
void FlowSetIPOnlyFlag(Flow *f, int direction)
Set the IPOnly scanned flag for 'direction'.
Definition: flow.c:202
FLOW_TOSERVER_IPONLY_SET
#define FLOW_TOSERVER_IPONLY_SET
Definition: flow.h:54
FLOW_IPPROTO_TCP_NEW_TIMEOUT
#define FLOW_IPPROTO_TCP_NEW_TIMEOUT
Definition: flow-private.h:44
FlowProtoFreeFunc_::Freefunc
void(* Freefunc)(void *)
Definition: flow.h:500
FlowClearMemory
int FlowClearMemory(Flow *f, uint8_t proto_map)
Function clear the flow memory before queueing it to spare flow queue.
Definition: flow.c:1035
FlowGetFlowFromHash
Flow * FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p, Flow **dest)
Get Flow for packet.
Definition: flow-hash.c:604
FlowCnf_::hash_rand
uint32_t hash_rand
Definition: flow.h:280
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
STREAM_GAP
#define STREAM_GAP
Definition: stream.h:33
flow-timeout.h
Flow_::min_ttl_toclient
uint8_t min_ttl_toclient
Definition: flow.h:447
flow-queue.h
Flow_::probing_parser_toclient_alproto_masks
uint32_t probing_parser_toclient_alproto_masks
Definition: flow.h:394
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:219
runmodes.h
FLOW_TO_DST_SEEN
#define FLOW_TO_DST_SEEN
Definition: flow.h:49
Flow_::src
FlowAddress src
Definition: flow.h:346
FlowQueue_
Definition: flow-queue.h:42
Flow_::probing_parser_toserver_alproto_masks
uint32_t probing_parser_toserver_alproto_masks
Definition: flow.h:393
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
Flow_::lastts
struct timeval lastts
Definition: flow.h:375
ConfNodeLookupChild
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:814
FLOW_PROTO_TCP
@ FLOW_PROTO_TCP
Definition: flow-private.h:70
flow_hash
FlowBucket * flow_hash
Definition: flow-hash.c:52
FlowDequeue
Flow * FlowDequeue(FlowQueue *q)
remove a flow from the queue
Definition: flow-queue.c:105
FLOW_TO_SRC_SEEN
#define FLOW_TO_SRC_SEEN
Definition: flow.h:47
StringParseUint32
int StringParseUint32(uint32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:313
flow-storage.h
FLOW_TS_PE_ALPROTO_DETECT_DONE
#define FLOW_TS_PE_ALPROTO_DETECT_DONE
Definition: flow.h:84
Packet_::flow
struct Flow_ * flow
Definition: decode.h:448
FLOW_IPPROTO_UDP_NEW_TIMEOUT
#define FLOW_IPPROTO_UDP_NEW_TIMEOUT
Definition: flow-private.h:48
FlowSetProtoFreeFunc
int FlowSetProtoFreeFunc(uint8_t, void(*Free)(void *))
Function to set the function to get protocol specific flow state.
Definition: flow.c:1063
FLOW_IPPROTO_ICMP_NEW_TIMEOUT
#define FLOW_IPPROTO_ICMP_NEW_TIMEOUT
Definition: flow-private.h:51
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
flow_timeouts_normal
FlowProtoTimeout flow_timeouts_normal[FLOW_PROTO_MAX]
Definition: flow.c:90
CMP_ADDR
#define CMP_ADDR(a1, a2)
Definition: decode.h:242
flow_spare_q
FlowQueue flow_spare_q
Definition: flow.c:95
FLOWFILE_NO_MAGIC_TC
#define FLOWFILE_NO_MAGIC_TC
Definition: flow.h:116
flags
uint8_t flags
Definition: decode-gre.h:0
FLOW_TOCLIENT_IPONLY_SET
#define FLOW_TOCLIENT_IPONLY_SET
Definition: flow.h:56
Packet_::ts
struct timeval ts
Definition: decode.h:454
flow-manager.h
suricata-common.h
FlowFree
void FlowFree(Flow *f)
cleanup & free the memory of a flow
Definition: flow-util.c:80
flow_config
FlowConfig flow_config
Definition: flow.c:97
FLOW_IPPROTO_TCP_BYPASSED_TIMEOUT
#define FLOW_IPPROTO_TCP_BYPASSED_TIMEOUT
Definition: flow-private.h:47
FLOW_HAS_ALERTS
#define FLOW_HAS_ALERTS
Definition: flow.h:77
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:683
SCMallocAligned
#define SCMallocAligned(size, align)
Definition: util-mem.h:68
SWAP_VARS
#define SWAP_VARS(type, a, b)
Definition: suricata-common.h:412
FlowTimeoutsInit
void FlowTimeoutsInit(void)
Definition: flow-manager.c:98
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
FLOW_PROTO_DETECT_TS_DONE
#define FLOW_PROTO_DETECT_TS_DONE
Definition: flow.h:98
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
Flow_::max_ttl_toclient
uint8_t max_ttl_toclient
Definition: flow.h:448
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:272
FLOW_TS_PP_ALPROTO_DETECT_DONE
#define FLOW_TS_PP_ALPROTO_DETECT_DONE
Definition: flow.h:82
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1112
FlowGetLastTimeAsParts
void FlowGetLastTimeAsParts(Flow *flow, uint64_t *secs, uint64_t *usecs)
Get flow last time as individual values.
Definition: flow.c:1132
FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT
#define FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT
Definition: flow-private.h:60
FlowHandlePacketUpdate
void FlowHandlePacketUpdate(Flow *f, Packet *p)
Update Packet and Flow.
Definition: flow.c:414
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
PKT_IS_ICMPV4
#define PKT_IS_ICMPV4(p)
Definition: decode.h:258
threadvars.h
util-validate.h
FlowSwap
void FlowSwap(Flow *f)
swap the flow's direction
Definition: flow.c:305
FlowGetAppProtocol
AppProto FlowGetAppProtocol(const Flow *f)
Definition: flow.c:1072
FlowHandlePacket
void FlowHandlePacket(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Entry point for packet flow handling.
Definition: flow.c:515
ICMPV4_IS_ERROR_MSG
#define ICMPV4_IS_ERROR_MSG(p)
Definition: decode-icmpv4.h:264
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:728
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:271
flow_recycle_q
FlowQueue flow_recycle_q
Definition: flow-manager.c:75
SWAP_FLAGS
#define SWAP_FLAGS(flags, a, b)
Definition: suricata-common.h:401
FLOW_SGH_TOSERVER
#define FLOW_SGH_TOSERVER
Definition: flow.h:67
CMP_PORT
#define CMP_PORT(p1, p2)
Definition: decode.h:247
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:625
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:426
ConfNode_
Definition: conf.h:32
Flow_::alstate
void * alstate
Definition: flow.h:454
flow_freefuncs
FlowProtoFreeFunc flow_freefuncs[FLOW_PROTO_MAX]
Definition: flow.c:92
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
flow_timeouts_emerg
FlowProtoTimeout flow_timeouts_emerg[FLOW_PROTO_MAX]
Definition: flow.c:91
Flow_::flags
uint32_t flags
Definition: flow.h:396
FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT
#define FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT
Definition: flow-private.h:63
FlowFreeStorage
void FlowFreeStorage(Flow *f)
Definition: flow-storage.c:59
SC_ATOMIC_DECLARE
SC_ATOMIC_DECLARE(unsigned int, flow_prune_idx)
FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT
#define FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT
Definition: flow-private.h:64
FLOW_TOCLIENT_DROP_LOGGED
#define FLOW_TOCLIENT_DROP_LOGGED
Definition: flow.h:74
util-random.h
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:220
IPV6_GET_HLIM
#define IPV6_GET_HLIM(p)
Definition: decode-ipv6.h:90
EngineModeIsIPS
int EngineModeIsIPS(void)
Definition: suricata.c:243
FLOW_EMERGENCY
#define FLOW_EMERGENCY
Definition: flow-private.h:37
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:38
FLOW_TC_PM_ALPROTO_DETECT_DONE
#define FLOW_TC_PM_ALPROTO_DETECT_DONE
Definition: flow.h:86
FLOW_DEFAULT_EMERGENCY_RECOVERY
#define FLOW_DEFAULT_EMERGENCY_RECOVERY
Definition: flow.c:68
FlowHasAlerts
int FlowHasAlerts(const Flow *f)
Check if flow has alerts.
Definition: flow.c:224
COPY_TIMESTAMP
#define COPY_TIMESTAMP(src, dst)
Definition: flow-util.h:30
STREAMTCP_STREAM_FLAG_GAP
#define STREAMTCP_STREAM_FLAG_GAP
Definition: stream-tcp-private.h:198
FLOW_DEFAULT_EMERG_EST_TIMEOUT
#define FLOW_DEFAULT_EMERG_EST_TIMEOUT
Definition: flow-private.h:56
FLOW_NOPACKET_INSPECTION
#define FLOW_NOPACKET_INSPECTION
Definition: flow.h:59
FLOW_IPPROTO_ICMP_BYPASSED_TIMEOUT
#define FLOW_IPPROTO_ICMP_BYPASSED_TIMEOUT
Definition: flow-private.h:53
FlowProtoTimeout_::est_timeout
uint32_t est_timeout
Definition: flow.h:494
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:256
Flow_::sp
Port sp
Definition: flow.h:348
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:347
FlowUpdateSpareFlows
int FlowUpdateSpareFlows(void)
Make sure we have enough spare flows.
Definition: flow.c:160
FlowGetDisruptionFlags
uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
get 'disruption' flags: GAP/DEPTH/PASS
Definition: flow.c:1089
TcpSession_
Definition: stream-tcp-private.h:260
util-misc.h
TcpSession_::data_first_seen_dir
int8_t data_first_seen_dir
Definition: stream-tcp-private.h:265
FLOW_PROTO_UDP
@ FLOW_PROTO_UDP
Definition: flow-private.h:71
flow.h
FlowAlloc
Flow * FlowAlloc(void)
allocate a flow
Definition: flow-util.c:51
Flow_::alproto_tc
AppProto alproto_tc
Definition: flow.h:427
Flow_::file_flags
uint16_t file_flags
Definition: flow.h:398
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:425
Packet_::dp
Port dp
Definition: decode.h:426
FLOW_DIR_REVERSED
#define FLOW_DIR_REVERSED
Definition: flow.h:106
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
FLOW_IPPROTO_TCP_EST_TIMEOUT
#define FLOW_IPPROTO_TCP_EST_TIMEOUT
Definition: flow-private.h:45
RegisterFlowStorageTests
void RegisterFlowStorageTests(void)
Definition: flow-storage.c:289
SET_DEFAULTS
#define SET_DEFAULTS(p, n, e, c, b, ne, ee, ce, be)
flow-var.h
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:254
TOCLIENT
#define TOCLIENT
Definition: flow.h:42
FLOW_PKT_TOSERVER_FIRST
#define FLOW_PKT_TOSERVER_FIRST
Definition: flow.h:223
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
Packet_::src
Address src
Definition: decode.h:415
Flow_::tosrcpktcnt
uint32_t tosrcpktcnt
Definition: flow.h:477
FlowUpdateState
void FlowUpdateState(Flow *f, enum FlowState s)
Definition: flow.c:1113
IPV4_GET_IPTTL
#define IPV4_GET_IPTTL(p)
Definition: decode-ipv4.h:146
FlowSetMemcap
int FlowSetMemcap(uint64_t size)
Update memcap value.
Definition: flow.c:114
FlowProtoFreeFunc_
Definition: flow.h:499
FQLOCK_UNLOCK
#define FQLOCK_UNLOCK(q)
Definition: flow-queue.h:69
ConfNodeLookupChildValue
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:842