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 /**
250  * \brief determine the direction of the packet compared to the flow
251  * \retval 0 to_server
252  * \retval 1 to_client
253  */
254 int FlowGetPacketDirection(const Flow *f, const Packet *p)
255 {
256  if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) {
257  if (!(CMP_PORT(p->sp,p->dp))) {
258  /* update flags and counters */
259  if (CMP_PORT(f->sp,p->sp)) {
260  return TOSERVER;
261  } else {
262  return TOCLIENT;
263  }
264  } else {
265  if (CMP_ADDR(&f->src,&p->src)) {
266  return TOSERVER;
267  } else {
268  return TOCLIENT;
269  }
270  }
271  } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) {
272  if (CMP_ADDR(&f->src,&p->src)) {
273  return TOSERVER;
274  } else {
275  return TOCLIENT;
276  }
277  }
278 
279  /* default to toserver */
280  return TOSERVER;
281 }
282 
283 /**
284  * \brief Check to update "seen" flags
285  *
286  * \param p packet
287  *
288  * \retval 1 true
289  * \retval 0 false
290  */
291 static inline int FlowUpdateSeenFlag(const Packet *p)
292 {
293  if (PKT_IS_ICMPV4(p)) {
294  if (ICMPV4_IS_ERROR_MSG(p)) {
295  return 0;
296  }
297  }
298 
299  return 1;
300 }
301 
302 static inline void FlowUpdateTTL(Flow *f, Packet *p, uint8_t ttl)
303 {
304  if (FlowGetPacketDirection(f, p) == TOSERVER) {
305  if (f->min_ttl_toserver == 0) {
306  f->min_ttl_toserver = ttl;
307  } else {
308  f->min_ttl_toserver = MIN(f->min_ttl_toserver, ttl);
309  }
310  f->max_ttl_toserver = MAX(f->max_ttl_toserver, ttl);
311  } else {
312  if (f->min_ttl_toclient == 0) {
313  f->min_ttl_toclient = ttl;
314  } else {
315  f->min_ttl_toclient = MIN(f->min_ttl_toclient, ttl);
316  }
317  f->max_ttl_toclient = MAX(f->max_ttl_toclient, ttl);
318  }
319 }
320 
321 /** \brief Update Packet and Flow
322  *
323  * Updates packet and flow based on the new packet.
324  *
325  * \param f locked flow
326  * \param p packet
327  *
328  * \note overwrites p::flowflags
329  */
331 {
332  SCLogDebug("packet %"PRIu64" -- flow %p", p->pcap_cnt, f);
333 
334  int state = SC_ATOMIC_GET(f->flow_state);
335 
336  if (state != FLOW_STATE_CAPTURE_BYPASSED) {
337  /* update the last seen timestamp of this flow */
338  COPY_TIMESTAMP(&p->ts, &f->lastts);
339  } else {
340  /* still seeing packet, we downgrade to local bypass */
341  if (p->ts.tv_sec - f->lastts.tv_sec > FLOW_BYPASSED_TIMEOUT / 2) {
342  SCLogDebug("Downgrading flow to local bypass");
343  COPY_TIMESTAMP(&p->ts, &f->lastts);
345  } else {
346  /* In IPS mode the packet could come from the over interface so it would
347  * need to be bypassed */
348  if (EngineModeIsIPS()) {
349  BypassedFlowUpdate(f, p);
350  }
351  }
352  }
353 
354  /* update flags and counters */
355  if (FlowGetPacketDirection(f, p) == TOSERVER) {
356  f->todstpktcnt++;
357  f->todstbytecnt += GET_PKT_LEN(p);
359  if (!(f->flags & FLOW_TO_DST_SEEN)) {
360  if (FlowUpdateSeenFlag(p)) {
361  f->flags |= FLOW_TO_DST_SEEN;
363  }
364  }
365  /* xfer proto detect ts flag to first packet in ts dir */
366  if (f->flags & FLOW_PROTO_DETECT_TS_DONE) {
369  }
370  } else {
371  f->tosrcpktcnt++;
372  f->tosrcbytecnt += GET_PKT_LEN(p);
374  if (!(f->flags & FLOW_TO_SRC_SEEN)) {
375  if (FlowUpdateSeenFlag(p)) {
376  f->flags |= FLOW_TO_SRC_SEEN;
378  }
379  }
380  /* xfer proto detect tc flag to first packet in tc dir */
381  if (f->flags & FLOW_PROTO_DETECT_TC_DONE) {
384  }
385  }
386 
387  if (SC_ATOMIC_GET(f->flow_state) == FLOW_STATE_ESTABLISHED) {
388  SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
390 
391  } else if ((f->flags & (FLOW_TO_DST_SEEN|FLOW_TO_SRC_SEEN)) ==
393  SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
395 
396  if (f->proto != IPPROTO_TCP) {
398  }
399  }
400 
401  /*set the detection bypass flags*/
402  if (f->flags & FLOW_NOPACKET_INSPECTION) {
403  SCLogDebug("setting FLOW_NOPACKET_INSPECTION flag on flow %p", f);
405  }
406  if (f->flags & FLOW_NOPAYLOAD_INSPECTION) {
407  SCLogDebug("setting FLOW_NOPAYLOAD_INSPECTION flag on flow %p", f);
409  }
410 
411 
412  /* update flow's ttl fields if needed */
413  if (PKT_IS_IPV4(p)) {
414  FlowUpdateTTL(f, p, IPV4_GET_IPTTL(p));
415  } else if (PKT_IS_IPV6(p)) {
416  FlowUpdateTTL(f, p, IPV6_GET_HLIM(p));
417  }
418 }
419 
420 /** \brief Entry point for packet flow handling
421  *
422  * This is called for every packet.
423  *
424  * \param tv threadvars
425  * \param dtv decode thread vars (for flow output api thread data)
426  * \param p packet to handle flow for
427  */
429 {
430  /* Get this packet's flow from the hash. FlowHandlePacket() will setup
431  * a new flow if nescesary. If we get NULL, we're out of flow memory.
432  * The returned flow is locked. */
433  Flow *f = FlowGetFlowFromHash(tv, dtv, p, &p->flow);
434  if (f == NULL)
435  return;
436 
437  /* set the flow in the packet */
438  p->flags |= PKT_HAS_FLOW;
439  return;
440 }
441 
442 /** \brief initialize the configuration
443  * \warning Not thread safe */
444 void FlowInitConfig(char quiet)
445 {
446  SCLogDebug("initializing flow engine...");
447 
448  memset(&flow_config, 0, sizeof(flow_config));
449  SC_ATOMIC_INIT(flow_flags);
450  SC_ATOMIC_INIT(flow_memuse);
451  SC_ATOMIC_INIT(flow_prune_idx);
452  SC_ATOMIC_INIT(flow_config.memcap);
455 
456  /* set defaults */
457  flow_config.hash_rand = (uint32_t)RandomGet();
461 
462  /* If we have specific config, overwrite the defaults with them,
463  * otherwise, leave the default values */
464  intmax_t val = 0;
465  if (ConfGetInt("flow.emergency-recovery", &val) == 1) {
466  if (val <= 100 && val >= 1) {
467  flow_config.emergency_recovery = (uint8_t)val;
468  } else {
469  SCLogError(SC_ERR_INVALID_VALUE, "flow.emergency-recovery must be in the range of 1 and 100 (as percentage)");
471  }
472  } else {
473  SCLogDebug("flow.emergency-recovery, using default value");
475  }
476 
477  /* Check if we have memcap and hash_size defined at config */
478  const char *conf_val;
479  uint32_t configval = 0;
480 
481  /** set config values for memcap, prealloc and hash_size */
482  uint64_t flow_memcap_copy;
483  if ((ConfGet("flow.memcap", &conf_val)) == 1)
484  {
485  if (conf_val == NULL) {
486  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,"Invalid value for flow.memcap: NULL");
487  exit(EXIT_FAILURE);
488  }
489 
490  if (ParseSizeStringU64(conf_val, &flow_memcap_copy) < 0) {
491  SCLogError(SC_ERR_SIZE_PARSE, "Error parsing flow.memcap "
492  "from conf file - %s. Killing engine",
493  conf_val);
494  exit(EXIT_FAILURE);
495  } else {
496  SC_ATOMIC_SET(flow_config.memcap, flow_memcap_copy);
497  }
498  }
499  if ((ConfGet("flow.hash-size", &conf_val)) == 1)
500  {
501  if (conf_val == NULL) {
502  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,"Invalid value for flow.hash-size: NULL");
503  exit(EXIT_FAILURE);
504  }
505 
506  if (ByteExtractStringUint32(&configval, 10, strlen(conf_val),
507  conf_val) > 0) {
508  flow_config.hash_size = configval;
509  }
510  }
511  if ((ConfGet("flow.prealloc", &conf_val)) == 1)
512  {
513  if (conf_val == NULL) {
514  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,"Invalid value for flow.prealloc: NULL");
515  exit(EXIT_FAILURE);
516  }
517 
518  if (ByteExtractStringUint32(&configval, 10, strlen(conf_val),
519  conf_val) > 0) {
520  flow_config.prealloc = configval;
521  }
522  }
523  SCLogDebug("Flow config from suricata.yaml: memcap: %"PRIu64", hash-size: "
524  "%"PRIu32", prealloc: %"PRIu32, SC_ATOMIC_GET(flow_config.memcap),
526 
527  /* alloc hash memory */
528  uint64_t hash_size = flow_config.hash_size * sizeof(FlowBucket);
529  if (!(FLOW_CHECK_MEMCAP(hash_size))) {
530  SCLogError(SC_ERR_FLOW_INIT, "allocating flow hash failed: "
531  "max flow memcap is smaller than projected hash size. "
532  "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate "
533  "total hash size by multiplying \"flow.hash-size\" with %"PRIuMAX", "
534  "which is the hash bucket size.", SC_ATOMIC_GET(flow_config.memcap), hash_size,
535  (uintmax_t)sizeof(FlowBucket));
536  exit(EXIT_FAILURE);
537  }
538  flow_hash = SCMallocAligned(flow_config.hash_size * sizeof(FlowBucket), CLS);
539  if (unlikely(flow_hash == NULL)) {
540  SCLogError(SC_ERR_FATAL, "Fatal error encountered in FlowInitConfig. Exiting...");
541  exit(EXIT_FAILURE);
542  }
543  memset(flow_hash, 0, flow_config.hash_size * sizeof(FlowBucket));
544 
545  uint32_t i = 0;
546  for (i = 0; i < flow_config.hash_size; i++) {
547  FBLOCK_INIT(&flow_hash[i]);
548  SC_ATOMIC_INIT(flow_hash[i].next_ts);
549  }
550  (void) SC_ATOMIC_ADD(flow_memuse, (flow_config.hash_size * sizeof(FlowBucket)));
551 
552  if (quiet == FALSE) {
553  SCLogConfig("allocated %"PRIu64" bytes of memory for the flow hash... "
554  "%" PRIu32 " buckets of size %" PRIuMAX "",
555  SC_ATOMIC_GET(flow_memuse), flow_config.hash_size,
556  (uintmax_t)sizeof(FlowBucket));
557  }
558 
559  /* pre allocate flows */
560  for (i = 0; i < flow_config.prealloc; i++) {
561  if (!(FLOW_CHECK_MEMCAP(sizeof(Flow) + FlowStorageSize()))) {
562  SCLogError(SC_ERR_FLOW_INIT, "preallocating flows failed: "
563  "max flow memcap reached. Memcap %"PRIu64", "
564  "Memuse %"PRIu64".", SC_ATOMIC_GET(flow_config.memcap),
565  ((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)sizeof(Flow)));
566  exit(EXIT_FAILURE);
567  }
568 
569  Flow *f = FlowAlloc();
570  if (f == NULL) {
571  SCLogError(SC_ERR_FLOW_INIT, "preallocating flow failed: %s", strerror(errno));
572  exit(EXIT_FAILURE);
573  }
574 
576  }
577 
578  if (quiet == FALSE) {
579  SCLogConfig("preallocated %" PRIu32 " flows of size %" PRIuMAX "",
580  flow_spare_q.len, (uintmax_t)(sizeof(Flow) + + FlowStorageSize()));
581  SCLogConfig("flow memory usage: %"PRIu64" bytes, maximum: %"PRIu64,
582  SC_ATOMIC_GET(flow_memuse), SC_ATOMIC_GET(flow_config.memcap));
583  }
584 
586 
587  return;
588 }
589 
590 /** \brief print some flow stats
591  * \warning Not thread safe */
592 static void FlowPrintStats (void)
593 {
594  return;
595 }
596 
597 /** \brief shutdown the flow engine
598  * \warning Not thread safe */
599 void FlowShutdown(void)
600 {
601  Flow *f;
602  uint32_t u;
603 
604  FlowPrintStats();
605 
606  /* free queues */
607  while((f = FlowDequeue(&flow_spare_q))) {
608  FlowFree(f);
609  }
610  while((f = FlowDequeue(&flow_recycle_q))) {
611  FlowFree(f);
612  }
613 
614  /* clear and free the hash */
615  if (flow_hash != NULL) {
616  /* clean up flow mutexes */
617  for (u = 0; u < flow_config.hash_size; u++) {
618  f = flow_hash[u].head;
619  while (f) {
620 #ifdef DEBUG_VALIDATION
621  BUG_ON(SC_ATOMIC_GET(f->use_cnt) != 0);
622 #endif
623  Flow *n = f->hnext;
624  uint8_t proto_map = FlowGetProtoMapping(f->proto);
625  FlowClearMemory(f, proto_map);
626  FlowFree(f);
627  f = n;
628  }
629 
631  SC_ATOMIC_DESTROY(flow_hash[u].next_ts);
632  }
634  flow_hash = NULL;
635  }
636  (void) SC_ATOMIC_SUB(flow_memuse, flow_config.hash_size * sizeof(FlowBucket));
639 
641  SC_ATOMIC_DESTROY(flow_prune_idx);
642  SC_ATOMIC_DESTROY(flow_memuse);
643  SC_ATOMIC_DESTROY(flow_flags);
644  return;
645 }
646 
647 /**
648  * \brief Function to set the default timeout, free function and flow state
649  * function for all supported flow_proto.
650  */
651 
653 {
655 
656 #define SET_DEFAULTS(p, n, e, c, b, ne, ee, ce, be) \
657  flow_timeouts_normal[(p)].new_timeout = (n); \
658  flow_timeouts_normal[(p)].est_timeout = (e); \
659  flow_timeouts_normal[(p)].closed_timeout = (c); \
660  flow_timeouts_normal[(p)].bypassed_timeout = (b); \
661  flow_timeouts_emerg[(p)].new_timeout = (ne); \
662  flow_timeouts_emerg[(p)].est_timeout = (ee); \
663  flow_timeouts_emerg[(p)].closed_timeout = (ce); \
664  flow_timeouts_emerg[(p)].bypassed_timeout = (be); \
665 
686 
691 
692  /* Let's see if we have custom timeouts defined from config */
693  const char *new = NULL;
694  const char *established = NULL;
695  const char *closed = NULL;
696  const char *bypassed = NULL;
697  const char *emergency_new = NULL;
698  const char *emergency_established = NULL;
699  const char *emergency_closed = NULL;
700  const char *emergency_bypassed = NULL;
701 
702  ConfNode *flow_timeouts = ConfGetNode("flow-timeouts");
703  if (flow_timeouts != NULL) {
704  ConfNode *proto = NULL;
705  uint32_t configval = 0;
706 
707  /* Defaults. */
708  proto = ConfNodeLookupChild(flow_timeouts, "default");
709  if (proto != NULL) {
710  new = ConfNodeLookupChildValue(proto, "new");
711  established = ConfNodeLookupChildValue(proto, "established");
712  closed = ConfNodeLookupChildValue(proto, "closed");
713  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
714  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
715  emergency_established = ConfNodeLookupChildValue(proto,
716  "emergency-established");
717  emergency_closed = ConfNodeLookupChildValue(proto,
718  "emergency-closed");
719  emergency_bypassed = ConfNodeLookupChildValue(proto,
720  "emergency-bypassed");
721 
722  if (new != NULL &&
723  ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
724 
726  }
727  if (established != NULL &&
728  ByteExtractStringUint32(&configval, 10, strlen(established),
729  established) > 0) {
730 
732  }
733  if (closed != NULL &&
734  ByteExtractStringUint32(&configval, 10, strlen(closed),
735  closed) > 0) {
736 
738  }
739  if (bypassed != NULL &&
740  ByteExtractStringUint32(&configval, 10,
741  strlen(bypassed),
742  bypassed) > 0) {
743 
745  }
746  if (emergency_new != NULL &&
747  ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
748  emergency_new) > 0) {
749 
751  }
752  if (emergency_established != NULL &&
753  ByteExtractStringUint32(&configval, 10,
754  strlen(emergency_established),
755  emergency_established) > 0) {
756 
758  }
759  if (emergency_closed != NULL &&
760  ByteExtractStringUint32(&configval, 10,
761  strlen(emergency_closed),
762  emergency_closed) > 0) {
763 
765  }
766  if (emergency_bypassed != NULL &&
767  ByteExtractStringUint32(&configval, 10,
768  strlen(emergency_bypassed),
769  emergency_bypassed) > 0) {
770 
772  }
773  }
774 
775  /* TCP. */
776  proto = ConfNodeLookupChild(flow_timeouts, "tcp");
777  if (proto != NULL) {
778  new = ConfNodeLookupChildValue(proto, "new");
779  established = ConfNodeLookupChildValue(proto, "established");
780  closed = ConfNodeLookupChildValue(proto, "closed");
781  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
782  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
783  emergency_established = ConfNodeLookupChildValue(proto,
784  "emergency-established");
785  emergency_closed = ConfNodeLookupChildValue(proto,
786  "emergency-closed");
787  emergency_bypassed = ConfNodeLookupChildValue(proto,
788  "emergency-bypassed");
789 
790  if (new != NULL &&
791  ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
792 
794  }
795  if (established != NULL &&
796  ByteExtractStringUint32(&configval, 10, strlen(established),
797  established) > 0) {
798 
800  }
801  if (closed != NULL &&
802  ByteExtractStringUint32(&configval, 10, strlen(closed),
803  closed) > 0) {
804 
806  }
807  if (bypassed != NULL &&
808  ByteExtractStringUint32(&configval, 10,
809  strlen(bypassed),
810  bypassed) > 0) {
811 
813  }
814  if (emergency_new != NULL &&
815  ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
816  emergency_new) > 0) {
817 
819  }
820  if (emergency_established != NULL &&
821  ByteExtractStringUint32(&configval, 10,
822  strlen(emergency_established),
823  emergency_established) > 0) {
824 
826  }
827  if (emergency_closed != NULL &&
828  ByteExtractStringUint32(&configval, 10,
829  strlen(emergency_closed),
830  emergency_closed) > 0) {
831 
833  }
834  if (emergency_bypassed != NULL &&
835  ByteExtractStringUint32(&configval, 10,
836  strlen(emergency_bypassed),
837  emergency_bypassed) > 0) {
838 
840  }
841  }
842 
843  /* UDP. */
844  proto = ConfNodeLookupChild(flow_timeouts, "udp");
845  if (proto != NULL) {
846  new = ConfNodeLookupChildValue(proto, "new");
847  established = ConfNodeLookupChildValue(proto, "established");
848  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
849  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
850  emergency_established = ConfNodeLookupChildValue(proto,
851  "emergency-established");
852  emergency_bypassed = ConfNodeLookupChildValue(proto,
853  "emergency-bypassed");
854 
855  if (new != NULL &&
856  ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
857 
859  }
860  if (established != NULL &&
861  ByteExtractStringUint32(&configval, 10, strlen(established),
862  established) > 0) {
863 
865  }
866  if (bypassed != NULL &&
867  ByteExtractStringUint32(&configval, 10,
868  strlen(bypassed),
869  bypassed) > 0) {
870 
872  }
873  if (emergency_new != NULL &&
874  ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
875  emergency_new) > 0) {
876 
878  }
879  if (emergency_established != NULL &&
880  ByteExtractStringUint32(&configval, 10,
881  strlen(emergency_established),
882  emergency_established) > 0) {
883 
885  }
886  if (emergency_bypassed != NULL &&
887  ByteExtractStringUint32(&configval, 10,
888  strlen(emergency_bypassed),
889  emergency_bypassed) > 0) {
890 
892  }
893  }
894 
895  /* ICMP. */
896  proto = ConfNodeLookupChild(flow_timeouts, "icmp");
897  if (proto != NULL) {
898  new = ConfNodeLookupChildValue(proto, "new");
899  established = ConfNodeLookupChildValue(proto, "established");
900  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
901  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
902  emergency_established = ConfNodeLookupChildValue(proto,
903  "emergency-established");
904  emergency_bypassed = ConfNodeLookupChildValue(proto,
905  "emergency-bypassed");
906 
907  if (new != NULL &&
908  ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
909 
911  }
912  if (established != NULL &&
913  ByteExtractStringUint32(&configval, 10, strlen(established),
914  established) > 0) {
915 
917  }
918  if (bypassed != NULL &&
919  ByteExtractStringUint32(&configval, 10,
920  strlen(bypassed),
921  bypassed) > 0) {
922 
924  }
925  if (emergency_new != NULL &&
926  ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
927  emergency_new) > 0) {
928 
930  }
931  if (emergency_established != NULL &&
932  ByteExtractStringUint32(&configval, 10,
933  strlen(emergency_established),
934  emergency_established) > 0) {
935 
937  }
938  if (emergency_bypassed != NULL &&
939  ByteExtractStringUint32(&configval, 10,
940  strlen(emergency_bypassed),
941  emergency_bypassed) > 0) {
942 
944  }
945  }
946  }
947 
948  return;
949 }
950 
951 /**
952  * \brief Function clear the flow memory before queueing it to spare flow
953  * queue.
954  *
955  * \param f pointer to the flow needed to be cleared.
956  * \param proto_map mapped value of the protocol to FLOW_PROTO's.
957  */
958 
959 int FlowClearMemory(Flow* f, uint8_t proto_map)
960 {
961  SCEnter();
962 
963  /* call the protocol specific free function if we have one */
964  if (flow_freefuncs[proto_map].Freefunc != NULL) {
965  flow_freefuncs[proto_map].Freefunc(f->protoctx);
966  }
967 
968  FlowFreeStorage(f);
969 
970  FLOW_RECYCLE(f);
971 
972  SCReturnInt(1);
973 }
974 
975 /**
976  * \brief Function to set the function to get protocol specific flow state.
977  *
978  * \param proto protocol of which function is needed to be set.
979  * \param Free Function pointer which will be called to free the protocol
980  * specific memory.
981  */
982 
983 int FlowSetProtoFreeFunc (uint8_t proto, void (*Free)(void *))
984 {
985  uint8_t proto_map;
986  proto_map = FlowGetProtoMapping(proto);
987 
988  flow_freefuncs[proto_map].Freefunc = Free;
989  return 1;
990 }
991 
993 {
994  return f->alproto;
995 }
996 
997 void *FlowGetAppState(const Flow *f)
998 {
999  return f->alstate;
1000 }
1001 
1002 /**
1003  * \brief get 'disruption' flags: GAP/DEPTH/PASS
1004  * \param f locked flow
1005  * \param flags existing flags to be ammended
1006  * \retval flags original flags + disrupt flags (if any)
1007  * \TODO handle UDP
1008  */
1009 uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
1010 {
1011  if (f->proto != IPPROTO_TCP) {
1012  return flags;
1013  }
1014  if (f->protoctx == NULL) {
1015  return flags;
1016  }
1017 
1018  uint8_t newflags = flags;
1019  TcpSession *ssn = f->protoctx;
1020  TcpStream *stream = flags & STREAM_TOSERVER ? &ssn->client : &ssn->server;
1021 
1023  newflags |= STREAM_DEPTH;
1024  }
1025  if (stream->flags & STREAMTCP_STREAM_FLAG_GAP) {
1026  newflags |= STREAM_GAP;
1027  }
1028  /* todo: handle pass case (also for UDP!) */
1029 
1030  return newflags;
1031 }
1032 
1034 {
1035  /* set the state */
1036  SC_ATOMIC_SET(f->flow_state, s);
1037 
1038  if (f->fb) {
1039  /* and reset the flow buckup next_ts value so that the flow manager
1040  * has to revisit this row */
1041  SC_ATOMIC_SET(f->fb->next_ts, 0);
1042  }
1043 }
1044 
1045 /************************************Unittests*******************************/
1046 
1047 #ifdef UNITTESTS
1048 #include "threads.h"
1049 
1050 /**
1051  * \test Test the setting of the per protocol timeouts.
1052  *
1053  * \retval On success it returns 1 and on failure 0.
1054  */
1055 
1056 static int FlowTest01 (void)
1057 {
1058  uint8_t proto_map;
1059 
1061  proto_map = FlowGetProtoMapping(IPPROTO_TCP);
1062  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT);
1063  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_TCP_EST_TIMEOUT);
1066 
1067  proto_map = FlowGetProtoMapping(IPPROTO_UDP);
1068  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT);
1069  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_TIMEOUT);
1072 
1073  proto_map = FlowGetProtoMapping(IPPROTO_ICMP);
1074  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT);
1075  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_TIMEOUT);
1078 
1079  proto_map = FlowGetProtoMapping(IPPROTO_DCCP);
1080  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT);
1081  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_DEFAULT_EST_TIMEOUT);
1082  FAIL_IF(flow_timeouts_emerg[proto_map].new_timeout != FLOW_DEFAULT_EMERG_NEW_TIMEOUT);
1083  FAIL_IF(flow_timeouts_emerg[proto_map].est_timeout != FLOW_DEFAULT_EMERG_EST_TIMEOUT);
1084 
1085  PASS;
1086 }
1087 
1088 /*Test function for the unit test FlowTest02*/
1089 
1090 static void test(void *f) {}
1091 
1092 /**
1093  * \test Test the setting of the per protocol free function to free the
1094  * protocol specific memory.
1095  *
1096  * \retval On success it returns 1 and on failure 0.
1097  */
1098 
1099 static int FlowTest02 (void)
1100 {
1101  FlowSetProtoFreeFunc(IPPROTO_DCCP, test);
1102  FlowSetProtoFreeFunc(IPPROTO_TCP, test);
1103  FlowSetProtoFreeFunc(IPPROTO_UDP, test);
1104  FlowSetProtoFreeFunc(IPPROTO_ICMP, test);
1105 
1106  FAIL_IF(flow_freefuncs[FLOW_PROTO_DEFAULT].Freefunc != test);
1107  FAIL_IF(flow_freefuncs[FLOW_PROTO_TCP].Freefunc != test);
1108  FAIL_IF(flow_freefuncs[FLOW_PROTO_UDP].Freefunc != test);
1109  FAIL_IF(flow_freefuncs[FLOW_PROTO_ICMP].Freefunc != test);
1110 
1111  PASS;
1112 }
1113 
1114 /**
1115  * \test Test flow allocations when it reach memcap
1116  *
1117  *
1118  * \retval On success it returns 1 and on failure 0.
1119  */
1120 
1121 static int FlowTest07 (void)
1122 {
1123  int result = 0;
1124 
1126  FlowConfig backup;
1127  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1128 
1129  uint32_t ini = 0;
1130  uint32_t end = flow_spare_q.len;
1131  SC_ATOMIC_SET(flow_config.memcap, 10000);
1132  flow_config.prealloc = 100;
1133 
1134  /* Let's get the flow_spare_q empty */
1135  UTHBuildPacketOfFlows(ini, end, 0);
1136 
1137  /* And now let's try to reach the memcap val */
1138  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1139  ini = end + 1;
1140  end = end + 2;
1141  UTHBuildPacketOfFlows(ini, end, 0);
1142  }
1143 
1144  /* should time out normal */
1145  TimeSetIncrementTime(2000);
1146  ini = end + 1;
1147  end = end + 2;;
1148  UTHBuildPacketOfFlows(ini, end, 0);
1149 
1150  /* This means that the engine entered emerg mode: should happen as easy
1151  * with flow mgr activated */
1152  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1153  result = 1;
1154 
1155  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1156  FlowShutdown();
1157 
1158  return result;
1159 }
1160 
1161 /**
1162  * \test Test flow allocations when it reach memcap
1163  *
1164  *
1165  * \retval On success it returns 1 and on failure 0.
1166  */
1167 
1168 static int FlowTest08 (void)
1169 {
1170  int result = 0;
1171 
1173  FlowConfig backup;
1174  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1175 
1176  uint32_t ini = 0;
1177  uint32_t end = flow_spare_q.len;
1178  SC_ATOMIC_SET(flow_config.memcap, 10000);
1179  flow_config.prealloc = 100;
1180 
1181  /* Let's get the flow_spare_q empty */
1182  UTHBuildPacketOfFlows(ini, end, 0);
1183 
1184  /* And now let's try to reach the memcap val */
1185  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1186  ini = end + 1;
1187  end = end + 2;
1188  UTHBuildPacketOfFlows(ini, end, 0);
1189  }
1190 
1191  /* By default we use 30 for timing out new flows. This means
1192  * that the Emergency mode should be set */
1194  ini = end + 1;
1195  end = end + 2;
1196  UTHBuildPacketOfFlows(ini, end, 0);
1197 
1198  /* This means that the engine released 5 flows by emergency timeout */
1199  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1200  result = 1;
1201 
1202  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1203  FlowShutdown();
1204 
1205  return result;
1206 }
1207 
1208 /**
1209  * \test Test flow allocations when it reach memcap
1210  *
1211  *
1212  * \retval On success it returns 1 and on failure 0.
1213  */
1214 
1215 static int FlowTest09 (void)
1216 {
1217  int result = 0;
1218 
1220  FlowConfig backup;
1221  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1222 
1223  uint32_t ini = 0;
1224  uint32_t end = flow_spare_q.len;
1225  SC_ATOMIC_SET(flow_config.memcap, 10000);
1226  flow_config.prealloc = 100;
1227 
1228  /* Let's get the flow_spare_q empty */
1229  UTHBuildPacketOfFlows(ini, end, 0);
1230 
1231  /* And now let's try to reach the memcap val */
1232  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1233  ini = end + 1;
1234  end = end + 2;
1235  UTHBuildPacketOfFlows(ini, end, 0);
1236  }
1237 
1238  /* No timeout will work */
1240  ini = end + 1;
1241  end = end + 2;
1242  UTHBuildPacketOfFlows(ini, end, 0);
1243 
1244  /* engine in emerg mode */
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 #endif /* UNITTESTS */
1255 
1256 /**
1257  * \brief Function to register the Flow Unitests.
1258  */
1260 {
1261 #ifdef UNITTESTS
1262  UtRegisterTest("FlowTest01 -- Protocol Specific Timeouts", FlowTest01);
1263  UtRegisterTest("FlowTest02 -- Setting Protocol Specific Free Function",
1264  FlowTest02);
1265  UtRegisterTest("FlowTest07 -- Test flow Allocations when it reach memcap",
1266  FlowTest07);
1267  UtRegisterTest("FlowTest08 -- Test flow Allocations when it reach memcap",
1268  FlowTest08);
1269  UtRegisterTest("FlowTest09 -- Test flow Allocations when it reach memcap",
1270  FlowTest09);
1271 
1274 #endif /* UNITTESTS */
1275 }
#define FLOW_PROTO_DETECT_TC_DONE
Definition: flow.h:98
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:76
#define FLOW_CHECK_MEMCAP(size)
check if a memory alloc would fit in the memcap
Definition: flow-util.h:131
#define SCLogDebug(...)
Definition: util-debug.h:335
#define FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT
Definition: flow-private.h:56
#define MAX(x, y)
struct Flow_ * flow
Definition: decode.h:444
uint32_t bypassed_timeout
Definition: flow.h:476
FlowProtoFreeFunc flow_freefuncs[FLOW_PROTO_MAX]
Definition: flow-private.h:88
struct Flow_ * hnext
Definition: flow.h:449
#define FLOW_CHANGE_PROTO
Definition: flow.h:101
void FlowHandlePacket(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Entry point for packet flow handling.
Definition: flow.c:428
#define BUG_ON(x)
uint32_t new_timeout
Definition: flow.h:473
uint64_t todstbytecnt
Definition: flow.h:460
uint8_t proto
Definition: flow.h:346
#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:333
#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:81
int FlowSetProtoFreeFunc(uint8_t, void(*Free)(void *))
Function to set the function to get protocol specific flow state.
Definition: flow.c:983
#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:414
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:55
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:422
void FlowEnqueue(FlowQueue *q, Flow *f)
add a flow to a queue
Definition: flow-queue.c:72
#define IPV6_GET_HLIM(p)
Definition: decode-ipv6.h:89
uint32_t prealloc
Definition: flow.h:258
#define MIN(x, y)
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:108
#define FLOW_PKT_TOSERVER_FIRST
Definition: flow.h:198
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
#define FLOW_QUIET
Definition: flow.h:37
#define FLOW_EMERGENCY
Definition: flow-private.h:37
#define FLOW_PROTO_DETECT_TS_DONE
Definition: flow.h:97
#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:251
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:195
uint8_t max_ttl_toserver
Definition: flow.h:428
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:196
uint64_t pcap_cnt
Definition: decode.h:566
Flow * FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p, Flow **dest)
Get Flow for packet.
Definition: flow-hash.c:483
#define CLS
#define FLOW_TOSERVER_IPONLY_SET
Definition: flow.h:53
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:125
AppProto FlowGetAppProtocol(const Flow *f)
Definition: flow.c:992
uint32_t todstpktcnt
Definition: flow.h:458
uint16_t AppProto
int EngineModeIsIPS(void)
Definition: suricata.c:241
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.
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:992
uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
get &#39;disruption&#39; flags: GAP/DEPTH/PASS
Definition: flow.c:1009
#define PKT_IS_IPV4(p)
Definition: decode.h:250
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:98
void * protoctx
Definition: flow.h:398
#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
void * alstate
Definition: flow.h:436
#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:254
#define SC_ATOMIC_INIT(name)
Initialize the previously declared atomic variable and it&#39;s lock.
Definition: util-atomic.h:82
#define FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT
Definition: flow-private.h:59
#define COPY_TIMESTAMP(src, dst)
Definition: flow-util.h:30
#define FLOW_NOPACKET_INSPECTION
Definition: flow.h:58
uint64_t tosrcbytecnt
Definition: flow.h:461
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:980
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:429
void FlowRegisterTests(void)
Function to register the Flow Unitests.
Definition: flow.c:1259
#define SET_DEFAULTS(p, n, e, c, b, ne, ee, ce, be)
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_NOPAYLOAD_INSPECTION
Definition: flow.h:60
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1125
#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:642
int FlowSetMemcap(uint64_t size)
Update memcap value.
Definition: flow.c:98
uint32_t est_timeout
Definition: flow.h:474
#define SCEnter(...)
Definition: util-debug.h:337
uint8_t flowflags
Definition: decode.h:438
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:240
SC_ATOMIC_DECLARE(unsigned int, flow_prune_idx)
#define FLOW_PKT_TOSERVER
Definition: flow.h:193
#define FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT
Definition: flow-private.h:61
void(* Freefunc)(void *)
Definition: flow.h:480
#define FLOW_DEFAULT_EMERG_NEW_TIMEOUT
Definition: flow-private.h:54
#define FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT
Definition: flow-private.h:62
uint8_t proto
void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate)
#define SCReturnInt(x)
Definition: util-debug.h:341
uint32_t ttl
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:356
uint8_t min_ttl_toserver
Definition: flow.h:427
struct FlowBucket_ * fb
Definition: flow.h:451
#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:199
Definition: conf.h:32
#define FLOW_IPPROTO_ICMP_BYPASSED_TIMEOUT
Definition: flow-private.h:52
#define TOSERVER
Definition: flow.h:40
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
Definition: util-time.c:167
#define FLOW_TO_DST_SEEN
Definition: flow.h:48
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:208
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:238
#define SCMallocAligned(a, b)
wrapper for allocing aligned mem
Definition: util-mem.h:277
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:599
uint32_t closed_timeout
Definition: flow.h:475
uint8_t max_ttl_toclient
Definition: flow.h:430
#define PKT_IS_ICMPV4(p)
Definition: decode.h:254
#define FLOW_DEFAULT_NEW_TIMEOUT
Definition: flow-private.h:40
void FlowUpdateState(Flow *f, enum FlowState s)
Definition: flow.c:1033
#define STREAM_TOSERVER
Definition: stream.h:31
void FlowFreeStorage(Flow *f)
Definition: flow-storage.c:59
#define TOCLIENT
Definition: flow.h:41
void FlowHandlePacketUpdate(Flow *f, Packet *p)
Update Packet and Flow.
Definition: flow.c:330
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:193
uint8_t min_ttl_toclient
Definition: flow.h:429
void * FlowGetAppState(const Flow *f)
Definition: flow.c:997
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:1101
#define CMP_PORT(p1, p2)
Definition: decode.h:243
#define FLOW_DEFAULT_MEMCAP
Definition: flow.c:71
FlowAddress src
Definition: flow.h:331
uint32_t hash_rand
Definition: flow.h:255
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:959
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:450
#define FLOW_PKT_TOCLIENT
Definition: flow.h:194
AppProto alproto
application level protocol
Definition: flow.h:407
#define GET_PKT_LEN(p)
Definition: decode.h:223
uint32_t flags
Definition: decode.h:442
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:652
#define FLOW_IPPROTO_ICMP_NEW_TIMEOUT
Definition: flow-private.h:50
void BypassedFlowUpdate(Flow *f, Packet *p)
Definition: flow-bypass.c:88
#define FLOW_IPPROTO_TCP_BYPASSED_TIMEOUT
Definition: flow-private.h:46
#define FLOW_TO_SRC_SEEN
Definition: flow.h:46
Flow data structure.
Definition: flow.h:327
Definition: flow.h:253
#define FLOW_IPPROTO_UDP_BYPASSED_TIMEOUT
Definition: flow-private.h:49
uint32_t flags
Definition: flow.h:377
void FlowTimeoutsInit(void)
Definition: flow-manager.c:89
FlowState
Definition: flow.h:464
#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:435
Address src
Definition: decode.h:411
uint32_t emergency_recovery
Definition: flow.h:265
FlowQueue flow_spare_q
Definition: flow-private.h:91
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1126
#define SCFreeAligned(a)
Free aligned memory.
Definition: util-mem.h:302
uint32_t tosrcpktcnt
Definition: flow.h:459
#define IPV4_GET_IPTTL(p)
Definition: decode-ipv4.h:146
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:444
uint32_t hash_size
Definition: flow.h:256