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