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  int state = SC_ATOMIC_GET(f->flow_state);
403 
404  if (state != FLOW_STATE_CAPTURE_BYPASSED) {
405  /* update the last seen timestamp of this flow */
406  COPY_TIMESTAMP(&p->ts, &f->lastts);
407  } else {
408  /* still seeing packet, we downgrade to local bypass */
409  if (p->ts.tv_sec - f->lastts.tv_sec > FLOW_BYPASSED_TIMEOUT / 2) {
410  SCLogDebug("Downgrading flow to local bypass");
411  COPY_TIMESTAMP(&p->ts, &f->lastts);
413  } else {
414  /* In IPS mode the packet could come from the other interface so it would
415  * need to be bypassed */
416  if (EngineModeIsIPS()) {
417  BypassedFlowUpdate(f, p);
418  }
419  }
420  }
421 
422  /* update flags and counters */
423  if (FlowGetPacketDirection(f, p) == TOSERVER) {
424  f->todstpktcnt++;
425  f->todstbytecnt += GET_PKT_LEN(p);
427  if (!(f->flags & FLOW_TO_DST_SEEN)) {
428  if (FlowUpdateSeenFlag(p)) {
429  f->flags |= FLOW_TO_DST_SEEN;
431  }
432  }
433  /* xfer proto detect ts flag to first packet in ts dir */
434  if (f->flags & FLOW_PROTO_DETECT_TS_DONE) {
437  }
438  } else {
439  f->tosrcpktcnt++;
440  f->tosrcbytecnt += GET_PKT_LEN(p);
442  if (!(f->flags & FLOW_TO_SRC_SEEN)) {
443  if (FlowUpdateSeenFlag(p)) {
444  f->flags |= FLOW_TO_SRC_SEEN;
446  }
447  }
448  /* xfer proto detect tc flag to first packet in tc dir */
449  if (f->flags & FLOW_PROTO_DETECT_TC_DONE) {
452  }
453  }
454 
455  if (SC_ATOMIC_GET(f->flow_state) == FLOW_STATE_ESTABLISHED) {
456  SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
458 
459  } else if ((f->flags & (FLOW_TO_DST_SEEN|FLOW_TO_SRC_SEEN)) ==
461  SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
463 
464  if (f->proto != IPPROTO_TCP) {
466  }
467  }
468 
469  /*set the detection bypass flags*/
470  if (f->flags & FLOW_NOPACKET_INSPECTION) {
471  SCLogDebug("setting FLOW_NOPACKET_INSPECTION flag on flow %p", f);
473  }
474  if (f->flags & FLOW_NOPAYLOAD_INSPECTION) {
475  SCLogDebug("setting FLOW_NOPAYLOAD_INSPECTION flag on flow %p", f);
477  }
478 
479 
480  /* update flow's ttl fields if needed */
481  if (PKT_IS_IPV4(p)) {
482  FlowUpdateTTL(f, p, IPV4_GET_IPTTL(p));
483  } else if (PKT_IS_IPV6(p)) {
484  FlowUpdateTTL(f, p, IPV6_GET_HLIM(p));
485  }
486 }
487 
488 /** \brief Entry point for packet flow handling
489  *
490  * This is called for every packet.
491  *
492  * \param tv threadvars
493  * \param dtv decode thread vars (for flow output api thread data)
494  * \param p packet to handle flow for
495  */
497 {
498  /* Get this packet's flow from the hash. FlowHandlePacket() will setup
499  * a new flow if nescesary. If we get NULL, we're out of flow memory.
500  * The returned flow is locked. */
501  Flow *f = FlowGetFlowFromHash(tv, dtv, p, &p->flow);
502  if (f == NULL)
503  return;
504 
505  /* set the flow in the packet */
506  p->flags |= PKT_HAS_FLOW;
507  return;
508 }
509 
510 /** \brief initialize the configuration
511  * \warning Not thread safe */
512 void FlowInitConfig(char quiet)
513 {
514  SCLogDebug("initializing flow engine...");
515 
516  memset(&flow_config, 0, sizeof(flow_config));
517  SC_ATOMIC_INIT(flow_flags);
518  SC_ATOMIC_INIT(flow_memuse);
519  SC_ATOMIC_INIT(flow_prune_idx);
520  SC_ATOMIC_INIT(flow_config.memcap);
523 
524  /* set defaults */
525  flow_config.hash_rand = (uint32_t)RandomGet();
529 
530  /* If we have specific config, overwrite the defaults with them,
531  * otherwise, leave the default values */
532  intmax_t val = 0;
533  if (ConfGetInt("flow.emergency-recovery", &val) == 1) {
534  if (val <= 100 && val >= 1) {
535  flow_config.emergency_recovery = (uint8_t)val;
536  } else {
537  SCLogError(SC_ERR_INVALID_VALUE, "flow.emergency-recovery must be in the range of 1 and 100 (as percentage)");
539  }
540  } else {
541  SCLogDebug("flow.emergency-recovery, using default value");
543  }
544 
545  /* Check if we have memcap and hash_size defined at config */
546  const char *conf_val;
547  uint32_t configval = 0;
548 
549  /** set config values for memcap, prealloc and hash_size */
550  uint64_t flow_memcap_copy;
551  if ((ConfGet("flow.memcap", &conf_val)) == 1)
552  {
553  if (conf_val == NULL) {
554  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,"Invalid value for flow.memcap: NULL");
555  exit(EXIT_FAILURE);
556  }
557 
558  if (ParseSizeStringU64(conf_val, &flow_memcap_copy) < 0) {
559  SCLogError(SC_ERR_SIZE_PARSE, "Error parsing flow.memcap "
560  "from conf file - %s. Killing engine",
561  conf_val);
562  exit(EXIT_FAILURE);
563  } else {
564  SC_ATOMIC_SET(flow_config.memcap, flow_memcap_copy);
565  }
566  }
567  if ((ConfGet("flow.hash-size", &conf_val)) == 1)
568  {
569  if (conf_val == NULL) {
570  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,"Invalid value for flow.hash-size: NULL");
571  exit(EXIT_FAILURE);
572  }
573 
574  if (ByteExtractStringUint32(&configval, 10, strlen(conf_val),
575  conf_val) > 0) {
576  flow_config.hash_size = configval;
577  }
578  }
579  if ((ConfGet("flow.prealloc", &conf_val)) == 1)
580  {
581  if (conf_val == NULL) {
582  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,"Invalid value for flow.prealloc: NULL");
583  exit(EXIT_FAILURE);
584  }
585 
586  if (ByteExtractStringUint32(&configval, 10, strlen(conf_val),
587  conf_val) > 0) {
588  flow_config.prealloc = configval;
589  }
590  }
591  SCLogDebug("Flow config from suricata.yaml: memcap: %"PRIu64", hash-size: "
592  "%"PRIu32", prealloc: %"PRIu32, SC_ATOMIC_GET(flow_config.memcap),
594 
595  /* alloc hash memory */
596  uint64_t hash_size = flow_config.hash_size * sizeof(FlowBucket);
597  if (!(FLOW_CHECK_MEMCAP(hash_size))) {
598  SCLogError(SC_ERR_FLOW_INIT, "allocating flow hash failed: "
599  "max flow memcap is smaller than projected hash size. "
600  "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate "
601  "total hash size by multiplying \"flow.hash-size\" with %"PRIuMAX", "
602  "which is the hash bucket size.", SC_ATOMIC_GET(flow_config.memcap), hash_size,
603  (uintmax_t)sizeof(FlowBucket));
604  exit(EXIT_FAILURE);
605  }
606  flow_hash = SCMallocAligned(flow_config.hash_size * sizeof(FlowBucket), CLS);
607  if (unlikely(flow_hash == NULL)) {
608  SCLogError(SC_ERR_FATAL, "Fatal error encountered in FlowInitConfig. Exiting...");
609  exit(EXIT_FAILURE);
610  }
611  memset(flow_hash, 0, flow_config.hash_size * sizeof(FlowBucket));
612 
613  uint32_t i = 0;
614  for (i = 0; i < flow_config.hash_size; i++) {
615  FBLOCK_INIT(&flow_hash[i]);
616  SC_ATOMIC_INIT(flow_hash[i].next_ts);
617  }
618  (void) SC_ATOMIC_ADD(flow_memuse, (flow_config.hash_size * sizeof(FlowBucket)));
619 
620  if (quiet == FALSE) {
621  SCLogConfig("allocated %"PRIu64" bytes of memory for the flow hash... "
622  "%" PRIu32 " buckets of size %" PRIuMAX "",
623  SC_ATOMIC_GET(flow_memuse), flow_config.hash_size,
624  (uintmax_t)sizeof(FlowBucket));
625  }
626 
627  /* pre allocate flows */
628  for (i = 0; i < flow_config.prealloc; i++) {
629  if (!(FLOW_CHECK_MEMCAP(sizeof(Flow) + FlowStorageSize()))) {
630  SCLogError(SC_ERR_FLOW_INIT, "preallocating flows failed: "
631  "max flow memcap reached. Memcap %"PRIu64", "
632  "Memuse %"PRIu64".", SC_ATOMIC_GET(flow_config.memcap),
633  ((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)sizeof(Flow)));
634  exit(EXIT_FAILURE);
635  }
636 
637  Flow *f = FlowAlloc();
638  if (f == NULL) {
639  SCLogError(SC_ERR_FLOW_INIT, "preallocating flow failed: %s", strerror(errno));
640  exit(EXIT_FAILURE);
641  }
642 
644  }
645 
646  if (quiet == FALSE) {
647  SCLogConfig("preallocated %" PRIu32 " flows of size %" PRIuMAX "",
648  flow_spare_q.len, (uintmax_t)(sizeof(Flow) + + FlowStorageSize()));
649  SCLogConfig("flow memory usage: %"PRIu64" bytes, maximum: %"PRIu64,
650  SC_ATOMIC_GET(flow_memuse), SC_ATOMIC_GET(flow_config.memcap));
651  }
652 
654 
655  return;
656 }
657 
658 /** \brief print some flow stats
659  * \warning Not thread safe */
660 static void FlowPrintStats (void)
661 {
662  return;
663 }
664 
665 /** \brief shutdown the flow engine
666  * \warning Not thread safe */
667 void FlowShutdown(void)
668 {
669  Flow *f;
670  uint32_t u;
671 
672  FlowPrintStats();
673 
674  /* free queues */
675  while((f = FlowDequeue(&flow_spare_q))) {
676  FlowFree(f);
677  }
678  while((f = FlowDequeue(&flow_recycle_q))) {
679  FlowFree(f);
680  }
681 
682  /* clear and free the hash */
683  if (flow_hash != NULL) {
684  /* clean up flow mutexes */
685  for (u = 0; u < flow_config.hash_size; u++) {
686  f = flow_hash[u].head;
687  while (f) {
688 #ifdef DEBUG_VALIDATION
689  BUG_ON(SC_ATOMIC_GET(f->use_cnt) != 0);
690 #endif
691  Flow *n = f->hnext;
692  uint8_t proto_map = FlowGetProtoMapping(f->proto);
693  FlowClearMemory(f, proto_map);
694  FlowFree(f);
695  f = n;
696  }
697 
699  SC_ATOMIC_DESTROY(flow_hash[u].next_ts);
700  }
702  flow_hash = NULL;
703  }
704  (void) SC_ATOMIC_SUB(flow_memuse, flow_config.hash_size * sizeof(FlowBucket));
707 
709  SC_ATOMIC_DESTROY(flow_prune_idx);
710  SC_ATOMIC_DESTROY(flow_memuse);
711  SC_ATOMIC_DESTROY(flow_flags);
712  return;
713 }
714 
715 /**
716  * \brief Function to set the default timeout, free function and flow state
717  * function for all supported flow_proto.
718  */
719 
721 {
723 
724 #define SET_DEFAULTS(p, n, e, c, b, ne, ee, ce, be) \
725  flow_timeouts_normal[(p)].new_timeout = (n); \
726  flow_timeouts_normal[(p)].est_timeout = (e); \
727  flow_timeouts_normal[(p)].closed_timeout = (c); \
728  flow_timeouts_normal[(p)].bypassed_timeout = (b); \
729  flow_timeouts_emerg[(p)].new_timeout = (ne); \
730  flow_timeouts_emerg[(p)].est_timeout = (ee); \
731  flow_timeouts_emerg[(p)].closed_timeout = (ce); \
732  flow_timeouts_emerg[(p)].bypassed_timeout = (be); \
733 
754 
759 
760  /* Let's see if we have custom timeouts defined from config */
761  const char *new = NULL;
762  const char *established = NULL;
763  const char *closed = NULL;
764  const char *bypassed = NULL;
765  const char *emergency_new = NULL;
766  const char *emergency_established = NULL;
767  const char *emergency_closed = NULL;
768  const char *emergency_bypassed = NULL;
769 
770  ConfNode *flow_timeouts = ConfGetNode("flow-timeouts");
771  if (flow_timeouts != NULL) {
772  ConfNode *proto = NULL;
773  uint32_t configval = 0;
774 
775  /* Defaults. */
776  proto = ConfNodeLookupChild(flow_timeouts, "default");
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  /* TCP. */
844  proto = ConfNodeLookupChild(flow_timeouts, "tcp");
845  if (proto != NULL) {
846  new = ConfNodeLookupChildValue(proto, "new");
847  established = ConfNodeLookupChildValue(proto, "established");
848  closed = ConfNodeLookupChildValue(proto, "closed");
849  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
850  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
851  emergency_established = ConfNodeLookupChildValue(proto,
852  "emergency-established");
853  emergency_closed = ConfNodeLookupChildValue(proto,
854  "emergency-closed");
855  emergency_bypassed = ConfNodeLookupChildValue(proto,
856  "emergency-bypassed");
857 
858  if (new != NULL &&
859  ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
860 
862  }
863  if (established != NULL &&
864  ByteExtractStringUint32(&configval, 10, strlen(established),
865  established) > 0) {
866 
868  }
869  if (closed != NULL &&
870  ByteExtractStringUint32(&configval, 10, strlen(closed),
871  closed) > 0) {
872 
874  }
875  if (bypassed != NULL &&
876  ByteExtractStringUint32(&configval, 10,
877  strlen(bypassed),
878  bypassed) > 0) {
879 
881  }
882  if (emergency_new != NULL &&
883  ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
884  emergency_new) > 0) {
885 
887  }
888  if (emergency_established != NULL &&
889  ByteExtractStringUint32(&configval, 10,
890  strlen(emergency_established),
891  emergency_established) > 0) {
892 
894  }
895  if (emergency_closed != NULL &&
896  ByteExtractStringUint32(&configval, 10,
897  strlen(emergency_closed),
898  emergency_closed) > 0) {
899 
901  }
902  if (emergency_bypassed != NULL &&
903  ByteExtractStringUint32(&configval, 10,
904  strlen(emergency_bypassed),
905  emergency_bypassed) > 0) {
906 
908  }
909  }
910 
911  /* UDP. */
912  proto = ConfNodeLookupChild(flow_timeouts, "udp");
913  if (proto != NULL) {
914  new = ConfNodeLookupChildValue(proto, "new");
915  established = ConfNodeLookupChildValue(proto, "established");
916  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
917  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
918  emergency_established = ConfNodeLookupChildValue(proto,
919  "emergency-established");
920  emergency_bypassed = ConfNodeLookupChildValue(proto,
921  "emergency-bypassed");
922 
923  if (new != NULL &&
924  ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
925 
927  }
928  if (established != NULL &&
929  ByteExtractStringUint32(&configval, 10, strlen(established),
930  established) > 0) {
931 
933  }
934  if (bypassed != NULL &&
935  ByteExtractStringUint32(&configval, 10,
936  strlen(bypassed),
937  bypassed) > 0) {
938 
940  }
941  if (emergency_new != NULL &&
942  ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
943  emergency_new) > 0) {
944 
946  }
947  if (emergency_established != NULL &&
948  ByteExtractStringUint32(&configval, 10,
949  strlen(emergency_established),
950  emergency_established) > 0) {
951 
953  }
954  if (emergency_bypassed != NULL &&
955  ByteExtractStringUint32(&configval, 10,
956  strlen(emergency_bypassed),
957  emergency_bypassed) > 0) {
958 
960  }
961  }
962 
963  /* ICMP. */
964  proto = ConfNodeLookupChild(flow_timeouts, "icmp");
965  if (proto != NULL) {
966  new = ConfNodeLookupChildValue(proto, "new");
967  established = ConfNodeLookupChildValue(proto, "established");
968  bypassed = ConfNodeLookupChildValue(proto, "bypassed");
969  emergency_new = ConfNodeLookupChildValue(proto, "emergency-new");
970  emergency_established = ConfNodeLookupChildValue(proto,
971  "emergency-established");
972  emergency_bypassed = ConfNodeLookupChildValue(proto,
973  "emergency-bypassed");
974 
975  if (new != NULL &&
976  ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) {
977 
979  }
980  if (established != NULL &&
981  ByteExtractStringUint32(&configval, 10, strlen(established),
982  established) > 0) {
983 
985  }
986  if (bypassed != NULL &&
987  ByteExtractStringUint32(&configval, 10,
988  strlen(bypassed),
989  bypassed) > 0) {
990 
992  }
993  if (emergency_new != NULL &&
994  ByteExtractStringUint32(&configval, 10, strlen(emergency_new),
995  emergency_new) > 0) {
996 
998  }
999  if (emergency_established != NULL &&
1000  ByteExtractStringUint32(&configval, 10,
1001  strlen(emergency_established),
1002  emergency_established) > 0) {
1003 
1005  }
1006  if (emergency_bypassed != NULL &&
1007  ByteExtractStringUint32(&configval, 10,
1008  strlen(emergency_bypassed),
1009  emergency_bypassed) > 0) {
1010 
1012  }
1013  }
1014  }
1015 
1016  return;
1017 }
1018 
1019 /**
1020  * \brief Function clear the flow memory before queueing it to spare flow
1021  * queue.
1022  *
1023  * \param f pointer to the flow needed to be cleared.
1024  * \param proto_map mapped value of the protocol to FLOW_PROTO's.
1025  */
1026 
1027 int FlowClearMemory(Flow* f, uint8_t proto_map)
1028 {
1029  SCEnter();
1030 
1031  /* call the protocol specific free function if we have one */
1032  if (flow_freefuncs[proto_map].Freefunc != NULL) {
1033  flow_freefuncs[proto_map].Freefunc(f->protoctx);
1034  }
1035 
1036  FlowFreeStorage(f);
1037 
1038  FLOW_RECYCLE(f);
1039 
1040  SCReturnInt(1);
1041 }
1042 
1043 /**
1044  * \brief Function to set the function to get protocol specific flow state.
1045  *
1046  * \param proto protocol of which function is needed to be set.
1047  * \param Free Function pointer which will be called to free the protocol
1048  * specific memory.
1049  */
1050 
1051 int FlowSetProtoFreeFunc (uint8_t proto, void (*Free)(void *))
1052 {
1053  uint8_t proto_map;
1054  proto_map = FlowGetProtoMapping(proto);
1055 
1056  flow_freefuncs[proto_map].Freefunc = Free;
1057  return 1;
1058 }
1059 
1061 {
1062  return f->alproto;
1063 }
1064 
1065 void *FlowGetAppState(const Flow *f)
1066 {
1067  return f->alstate;
1068 }
1069 
1070 /**
1071  * \brief get 'disruption' flags: GAP/DEPTH/PASS
1072  * \param f locked flow
1073  * \param flags existing flags to be ammended
1074  * \retval flags original flags + disrupt flags (if any)
1075  * \TODO handle UDP
1076  */
1077 uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
1078 {
1079  if (f->proto != IPPROTO_TCP) {
1080  return flags;
1081  }
1082  if (f->protoctx == NULL) {
1083  return flags;
1084  }
1085 
1086  uint8_t newflags = flags;
1087  TcpSession *ssn = f->protoctx;
1088  TcpStream *stream = flags & STREAM_TOSERVER ? &ssn->client : &ssn->server;
1089 
1091  newflags |= STREAM_DEPTH;
1092  }
1093  if (stream->flags & STREAMTCP_STREAM_FLAG_GAP) {
1094  newflags |= STREAM_GAP;
1095  }
1096  /* todo: handle pass case (also for UDP!) */
1097 
1098  return newflags;
1099 }
1100 
1102 {
1103  /* set the state */
1104  SC_ATOMIC_SET(f->flow_state, s);
1105 
1106  if (f->fb) {
1107  /* and reset the flow buckup next_ts value so that the flow manager
1108  * has to revisit this row */
1109  SC_ATOMIC_SET(f->fb->next_ts, 0);
1110  }
1111 }
1112 
1113 /************************************Unittests*******************************/
1114 
1115 #ifdef UNITTESTS
1116 #include "threads.h"
1117 
1118 /**
1119  * \test Test the setting of the per protocol timeouts.
1120  *
1121  * \retval On success it returns 1 and on failure 0.
1122  */
1123 
1124 static int FlowTest01 (void)
1125 {
1126  uint8_t proto_map;
1127 
1129  proto_map = FlowGetProtoMapping(IPPROTO_TCP);
1130  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT);
1131  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_TCP_EST_TIMEOUT);
1134 
1135  proto_map = FlowGetProtoMapping(IPPROTO_UDP);
1136  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT);
1137  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_TIMEOUT);
1140 
1141  proto_map = FlowGetProtoMapping(IPPROTO_ICMP);
1142  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT);
1143  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_TIMEOUT);
1146 
1147  proto_map = FlowGetProtoMapping(IPPROTO_DCCP);
1148  FAIL_IF(flow_timeouts_normal[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT);
1149  FAIL_IF(flow_timeouts_normal[proto_map].est_timeout != FLOW_DEFAULT_EST_TIMEOUT);
1150  FAIL_IF(flow_timeouts_emerg[proto_map].new_timeout != FLOW_DEFAULT_EMERG_NEW_TIMEOUT);
1151  FAIL_IF(flow_timeouts_emerg[proto_map].est_timeout != FLOW_DEFAULT_EMERG_EST_TIMEOUT);
1152 
1153  PASS;
1154 }
1155 
1156 /*Test function for the unit test FlowTest02*/
1157 
1158 static void test(void *f) {}
1159 
1160 /**
1161  * \test Test the setting of the per protocol free function to free the
1162  * protocol specific memory.
1163  *
1164  * \retval On success it returns 1 and on failure 0.
1165  */
1166 
1167 static int FlowTest02 (void)
1168 {
1169  FlowSetProtoFreeFunc(IPPROTO_DCCP, test);
1170  FlowSetProtoFreeFunc(IPPROTO_TCP, test);
1171  FlowSetProtoFreeFunc(IPPROTO_UDP, test);
1172  FlowSetProtoFreeFunc(IPPROTO_ICMP, test);
1173 
1174  FAIL_IF(flow_freefuncs[FLOW_PROTO_DEFAULT].Freefunc != test);
1175  FAIL_IF(flow_freefuncs[FLOW_PROTO_TCP].Freefunc != test);
1176  FAIL_IF(flow_freefuncs[FLOW_PROTO_UDP].Freefunc != test);
1177  FAIL_IF(flow_freefuncs[FLOW_PROTO_ICMP].Freefunc != test);
1178 
1179  PASS;
1180 }
1181 
1182 /**
1183  * \test Test flow allocations when it reach memcap
1184  *
1185  *
1186  * \retval On success it returns 1 and on failure 0.
1187  */
1188 
1189 static int FlowTest07 (void)
1190 {
1191  int result = 0;
1192 
1194  FlowConfig backup;
1195  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1196 
1197  uint32_t ini = 0;
1198  uint32_t end = flow_spare_q.len;
1199  SC_ATOMIC_SET(flow_config.memcap, 10000);
1200  flow_config.prealloc = 100;
1201 
1202  /* Let's get the flow_spare_q empty */
1203  UTHBuildPacketOfFlows(ini, end, 0);
1204 
1205  /* And now let's try to reach the memcap val */
1206  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1207  ini = end + 1;
1208  end = end + 2;
1209  UTHBuildPacketOfFlows(ini, end, 0);
1210  }
1211 
1212  /* should time out normal */
1213  TimeSetIncrementTime(2000);
1214  ini = end + 1;
1215  end = end + 2;;
1216  UTHBuildPacketOfFlows(ini, end, 0);
1217 
1218  /* This means that the engine entered emerg mode: should happen as easy
1219  * with flow mgr activated */
1220  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1221  result = 1;
1222 
1223  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1224  FlowShutdown();
1225 
1226  return result;
1227 }
1228 
1229 /**
1230  * \test Test flow allocations when it reach memcap
1231  *
1232  *
1233  * \retval On success it returns 1 and on failure 0.
1234  */
1235 
1236 static int FlowTest08 (void)
1237 {
1238  int result = 0;
1239 
1241  FlowConfig backup;
1242  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1243 
1244  uint32_t ini = 0;
1245  uint32_t end = flow_spare_q.len;
1246  SC_ATOMIC_SET(flow_config.memcap, 10000);
1247  flow_config.prealloc = 100;
1248 
1249  /* Let's get the flow_spare_q empty */
1250  UTHBuildPacketOfFlows(ini, end, 0);
1251 
1252  /* And now let's try to reach the memcap val */
1253  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1254  ini = end + 1;
1255  end = end + 2;
1256  UTHBuildPacketOfFlows(ini, end, 0);
1257  }
1258 
1259  /* By default we use 30 for timing out new flows. This means
1260  * that the Emergency mode should be set */
1262  ini = end + 1;
1263  end = end + 2;
1264  UTHBuildPacketOfFlows(ini, end, 0);
1265 
1266  /* This means that the engine released 5 flows by emergency timeout */
1267  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1268  result = 1;
1269 
1270  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1271  FlowShutdown();
1272 
1273  return result;
1274 }
1275 
1276 /**
1277  * \test Test flow allocations when it reach memcap
1278  *
1279  *
1280  * \retval On success it returns 1 and on failure 0.
1281  */
1282 
1283 static int FlowTest09 (void)
1284 {
1285  int result = 0;
1286 
1288  FlowConfig backup;
1289  memcpy(&backup, &flow_config, sizeof(FlowConfig));
1290 
1291  uint32_t ini = 0;
1292  uint32_t end = flow_spare_q.len;
1293  SC_ATOMIC_SET(flow_config.memcap, 10000);
1294  flow_config.prealloc = 100;
1295 
1296  /* Let's get the flow_spare_q empty */
1297  UTHBuildPacketOfFlows(ini, end, 0);
1298 
1299  /* And now let's try to reach the memcap val */
1300  while (FLOW_CHECK_MEMCAP(sizeof(Flow))) {
1301  ini = end + 1;
1302  end = end + 2;
1303  UTHBuildPacketOfFlows(ini, end, 0);
1304  }
1305 
1306  /* No timeout will work */
1308  ini = end + 1;
1309  end = end + 2;
1310  UTHBuildPacketOfFlows(ini, end, 0);
1311 
1312  /* engine in emerg mode */
1313  if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
1314  result = 1;
1315 
1316  memcpy(&flow_config, &backup, sizeof(FlowConfig));
1317  FlowShutdown();
1318 
1319  return result;
1320 }
1321 
1322 #endif /* UNITTESTS */
1323 
1324 /**
1325  * \brief Function to register the Flow Unitests.
1326  */
1328 {
1329 #ifdef UNITTESTS
1330  UtRegisterTest("FlowTest01 -- Protocol Specific Timeouts", FlowTest01);
1331  UtRegisterTest("FlowTest02 -- Setting Protocol Specific Free Function",
1332  FlowTest02);
1333  UtRegisterTest("FlowTest07 -- Test flow Allocations when it reach memcap",
1334  FlowTest07);
1335  UtRegisterTest("FlowTest08 -- Test flow Allocations when it reach memcap",
1336  FlowTest08);
1337  UtRegisterTest("FlowTest09 -- Test flow Allocations when it reach memcap",
1338  FlowTest09);
1339 
1342 #endif /* UNITTESTS */
1343 }
#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:135
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:443
uint32_t bypassed_timeout
Definition: flow.h:478
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:496
#define BUG_ON(x)
uint32_t new_timeout
Definition: flow.h:475
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:83
int FlowSetProtoFreeFunc(uint8_t, void(*Free)(void *))
Function to set the function to get protocol specific flow state.
Definition: flow.c:1051
#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:413
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:421
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:89
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:250
#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:547
#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:1060
uint32_t todstpktcnt
Definition: flow.h:460
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.
#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:983
uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
get &#39;disruption&#39; flags: GAP/DEPTH/PASS
Definition: flow.c:1077
#define PKT_IS_IPV4(p)
Definition: decode.h:249
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:971
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:428
void FlowRegisterTests(void)
Function to register the Flow Unitests.
Definition: flow.c:1327
#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:1116
#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:476
#define SCEnter(...)
Definition: util-debug.h:337
uint8_t flowflags
Definition: decode.h:437
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:482
#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:237
#define SCMallocAligned(a, b)
wrapper for allocing aligned mem
Definition: util-mem.h:269
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:667
#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:477
uint8_t max_ttl_toclient
Definition: flow.h:432
#define PKT_IS_ICMPV4(p)
Definition: decode.h:253
#define FLOW_DEFAULT_NEW_TIMEOUT
Definition: flow-private.h:40
void FlowUpdateState(Flow *f, enum FlowState s)
Definition: flow.c:1101
#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:1065
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:1092
#define CMP_PORT(p1, p2)
Definition: decode.h:242
#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:1027
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:449
#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:222
uint32_t flags
Definition: decode.h:441
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:720
#define FLOW_IPPROTO_ICMP_NEW_TIMEOUT
Definition: flow-private.h:50
void BypassedFlowUpdate(Flow *f, Packet *p)
Definition: flow-bypass.c:199
#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:410
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:1117
#define SCFreeAligned(a)
Free aligned memory.
Definition: util-mem.h:294
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:512
uint32_t hash_size
Definition: flow.h:264