suricata
util-profiling-rules.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2012 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 Endace Technology Limited.
22  * \author Victor Julien <victor@inliniac.net>
23  *
24  * An API for rule profiling operations.
25  */
26 
27 #include "suricata-common.h"
28 #include "util-profiling.h"
29 
30 #ifdef PROFILING
31 #include "util-byte.h"
32 #include "util-conf.h"
33 #include "util-time.h"
34 
35 /**
36  * Extra data for rule profiling.
37  */
38 typedef struct SCProfileData_ {
39  uint32_t sid;
40  uint32_t gid;
41  uint32_t rev;
42  uint64_t checks;
43  uint64_t matches;
44  uint64_t max;
45  uint64_t ticks_match;
46  uint64_t ticks_no_match;
48 
49 typedef struct SCProfileDetectCtx_ {
50  uint32_t size;
51  uint16_t id;
53  pthread_mutex_t data_m;
55 
56 /**
57  * Used for generating the summary data to print.
58  */
59 typedef struct SCProfileSummary_ {
60  uint32_t sid;
61  uint32_t gid;
62  uint32_t rev;
63  uint64_t ticks;
64  double avgticks;
67  uint64_t checks;
68  uint64_t matches;
69  uint64_t max;
70  uint64_t ticks_match;
71  uint64_t ticks_no_match;
73 
74 extern int profiling_output_to_file;
76 static char profiling_file_name[PATH_MAX] = "";
77 static const char *profiling_file_mode = "a";
78 static int profiling_rule_json = 0;
79 
80 /**
81  * Sort orders for dumping profiled rules.
82  */
83 enum {
91 };
92 
93 static int profiling_rules_sort_orders[8] = {
101  -1 };
102 
103 /**
104  * Maximum number of rules to dump.
105  */
106 static uint32_t profiling_rules_limit = UINT32_MAX;
107 
109 {
110 #define SET_ONE(x) { \
111  profiling_rules_sort_orders[0] = (x); \
112  profiling_rules_sort_orders[1] = -1; \
113  }
114 
115  ConfNode *conf;
116  const char *val;
117 
118  conf = ConfGetNode("profiling.rules");
119  if (conf != NULL) {
120  if (ConfNodeChildValueIsTrue(conf, "enabled")) {
122 
123  val = ConfNodeLookupChildValue(conf, "sort");
124  if (val != NULL) {
125  if (strcmp(val, "ticks") == 0) {
127  }
128  else if (strcmp(val, "avgticks") == 0) {
130  }
131  else if (strcmp(val, "avgticks_match") == 0) {
133  }
134  else if (strcmp(val, "avgticks_no_match") == 0) {
136  }
137  else if (strcmp(val, "checks") == 0) {
139  }
140  else if (strcmp(val, "matches") == 0) {
142  }
143  else if (strcmp(val, "maxticks") == 0) {
145  }
146  else {
148  "Invalid profiling sort order: %s", val);
149  exit(EXIT_FAILURE);
150  }
151  }
152 
153  val = ConfNodeLookupChildValue(conf, "limit");
154  if (val != NULL) {
155  if (StringParseUint32(&profiling_rules_limit, 10,
156  (uint16_t)strlen(val), val) <= 0) {
157  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid limit: %s", val);
158  exit(EXIT_FAILURE);
159  }
160  }
161  const char *filename = ConfNodeLookupChildValue(conf, "filename");
162  if (filename != NULL) {
163 
164  const char *log_dir;
165  log_dir = ConfigGetLogDirectory();
166 
167  snprintf(profiling_file_name, sizeof(profiling_file_name),
168  "%s/%s", log_dir, filename);
169 
170  const char *v = ConfNodeLookupChildValue(conf, "append");
171  if (v == NULL || ConfValIsTrue(v)) {
172  profiling_file_mode = "a";
173  } else {
174  profiling_file_mode = "w";
175  }
176 
178  }
179  if (ConfNodeChildValueIsTrue(conf, "json")) {
180  profiling_rule_json = 1;
181  }
182  }
183  }
184 #undef SET_ONE
185 }
186 
187 /**
188  * \brief Qsort comparison function to sort by ticks.
189  */
190 static int
191 SCProfileSummarySortByTicks(const void *a, const void *b)
192 {
193  const SCProfileSummary *s0 = a;
194  const SCProfileSummary *s1 = b;
195  if (s1->ticks == s0->ticks)
196  return 0;
197  else
198  return s0->ticks > s1->ticks ? -1 : 1;
199 }
200 
201 /**
202  * \brief Qsort comparison function to sort by average ticks per match.
203  */
204 static int
205 SCProfileSummarySortByAvgTicksMatch(const void *a, const void *b)
206 {
207  const SCProfileSummary *s0 = a;
208  const SCProfileSummary *s1 = b;
209  if (s1->avgticks_match == s0->avgticks_match)
210  return 0;
211  else
212  return s0->avgticks_match > s1->avgticks_match ? -1 : 1;
213 }
214 
215 /**
216  * \brief Qsort comparison function to sort by average ticks per non match.
217  */
218 static int
219 SCProfileSummarySortByAvgTicksNoMatch(const void *a, const void *b)
220 {
221  const SCProfileSummary *s0 = a;
222  const SCProfileSummary *s1 = b;
223  if (s1->avgticks_no_match == s0->avgticks_no_match)
224  return 0;
225  else
226  return s0->avgticks_no_match > s1->avgticks_no_match ? -1 : 1;
227 }
228 
229 /**
230  * \brief Qsort comparison function to sort by average ticks.
231  */
232 static int
233 SCProfileSummarySortByAvgTicks(const void *a, const void *b)
234 {
235  const SCProfileSummary *s0 = a;
236  const SCProfileSummary *s1 = b;
237  if (s1->avgticks == s0->avgticks)
238  return 0;
239  else
240  return s0->avgticks > s1->avgticks ? -1 : 1;
241 }
242 
243 /**
244  * \brief Qsort comparison function to sort by checks.
245  */
246 static int
247 SCProfileSummarySortByChecks(const void *a, const void *b)
248 {
249  const SCProfileSummary *s0 = a;
250  const SCProfileSummary *s1 = b;
251  if (s1->checks == s0->checks)
252  return 0;
253  else
254  return s0->checks > s1->checks ? -1 : 1;
255 }
256 
257 /**
258  * \brief Qsort comparison function to sort by matches.
259  */
260 static int
261 SCProfileSummarySortByMatches(const void *a, const void *b)
262 {
263  const SCProfileSummary *s0 = a;
264  const SCProfileSummary *s1 = b;
265  if (s1->matches == s0->matches)
266  return 0;
267  else
268  return s0->matches > s1->matches ? -1 : 1;
269 }
270 
271 /**
272  * \brief Qsort comparison function to sort by max ticks.
273  */
274 static int
275 SCProfileSummarySortByMaxTicks(const void *a, const void *b)
276 {
277  const SCProfileSummary *s0 = a;
278  const SCProfileSummary *s1 = b;
279  if (s1->max == s0->max)
280  return 0;
281  else
282  return s0->max > s1->max ? -1 : 1;
283 }
284 
285 static void DumpJson(FILE *fp, SCProfileSummary *summary,
286  uint32_t count, uint64_t total_ticks,
287  const char *sort_desc)
288 {
289  char timebuf[64];
290  uint32_t i;
291  struct timeval tval;
292 
293  json_t *js = json_object();
294  if (js == NULL)
295  return;
296  json_t *jsa = json_array();
297  if (jsa == NULL) {
298  json_decref(js);
299  return;
300  }
301 
302  gettimeofday(&tval, NULL);
303  CreateIsoTimeString(&tval, timebuf, sizeof(timebuf));
304  json_object_set_new(js, "timestamp", json_string(timebuf));
305  json_object_set_new(js, "sort", json_string(sort_desc));
306 
307  for (i = 0; i < MIN(count, profiling_rules_limit); i++) {
308  /* Stop dumping when we hit our first rule with 0 checks. Due
309  * to sorting this will be the beginning of all the rules with
310  * 0 checks. */
311  if (summary[i].checks == 0)
312  break;
313 
314  json_t *jsm = json_object();
315  if (jsm) {
316  json_object_set_new(jsm, "signature_id", json_integer(summary[i].sid));
317  json_object_set_new(jsm, "gid", json_integer(summary[i].gid));
318  json_object_set_new(jsm, "rev", json_integer(summary[i].rev));
319 
320  json_object_set_new(jsm, "checks", json_integer(summary[i].checks));
321  json_object_set_new(jsm, "matches", json_integer(summary[i].matches));
322 
323  json_object_set_new(jsm, "ticks_total", json_integer(summary[i].ticks));
324  json_object_set_new(jsm, "ticks_max", json_integer(summary[i].max));
325  json_object_set_new(jsm, "ticks_avg", json_integer(summary[i].avgticks));
326  json_object_set_new(jsm, "ticks_avg_match", json_integer(summary[i].avgticks_match));
327  json_object_set_new(jsm, "ticks_avg_nomatch", json_integer(summary[i].avgticks_no_match));
328 
329  double percent = (long double)summary[i].ticks /
330  (long double)total_ticks * 100;
331  json_object_set_new(jsm, "percent", json_integer(percent));
332  json_array_append_new(jsa, jsm);
333  }
334  }
335  json_object_set_new(js, "rules", jsa);
336 
337  char *js_s = json_dumps(js,
338  JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII|
340 
341  if (unlikely(js_s == NULL))
342  return;
343  fprintf(fp, "%s\n", js_s);
344  free(js_s);
345  json_decref(js);
346 }
347 
348 static void DumpText(FILE *fp, SCProfileSummary *summary,
349  uint32_t count, uint64_t total_ticks,
350  const char *sort_desc)
351 {
352  uint32_t i;
353  struct timeval tval;
354  struct tm *tms;
355  gettimeofday(&tval, NULL);
356  struct tm local_tm;
357  tms = SCLocalTime(tval.tv_sec, &local_tm);
358 
359  fprintf(fp, " ----------------------------------------------"
360  "----------------------------\n");
361  fprintf(fp, " Date: %" PRId32 "/%" PRId32 "/%04d -- "
362  "%02d:%02d:%02d.", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900,
363  tms->tm_hour,tms->tm_min, tms->tm_sec);
364  fprintf(fp, " Sorted by: %s.\n", sort_desc);
365  fprintf(fp, " ----------------------------------------------"
366  "----------------------------\n");
367  fprintf(fp, " %-8s %-12s %-8s %-8s %-12s %-6s %-8s %-8s %-11s %-11s %-11s %-11s\n", "Num", "Rule", "Gid", "Rev", "Ticks", "%", "Checks", "Matches", "Max Ticks", "Avg Ticks", "Avg Match", "Avg No Match");
368  fprintf(fp, " -------- "
369  "------------ "
370  "-------- "
371  "-------- "
372  "------------ "
373  "------ "
374  "-------- "
375  "-------- "
376  "----------- "
377  "----------- "
378  "----------- "
379  "-------------- "
380  "\n");
381  for (i = 0; i < MIN(count, profiling_rules_limit); i++) {
382 
383  /* Stop dumping when we hit our first rule with 0 checks. Due
384  * to sorting this will be the beginning of all the rules with
385  * 0 checks. */
386  if (summary[i].checks == 0)
387  break;
388 
389  double percent = (long double)summary[i].ticks /
390  (long double)total_ticks * 100;
391  fprintf(fp,
392  " %-8"PRIu32" %-12u %-8"PRIu32" %-8"PRIu32" %-12"PRIu64" %-6.2f %-8"PRIu64" %-8"PRIu64" %-11"PRIu64" %-11.2f %-11.2f %-11.2f\n",
393  i + 1,
394  summary[i].sid,
395  summary[i].gid,
396  summary[i].rev,
397  summary[i].ticks,
398  percent,
399  summary[i].checks,
400  summary[i].matches,
401  summary[i].max,
402  summary[i].avgticks,
403  summary[i].avgticks_match,
404  summary[i].avgticks_no_match);
405  }
406 
407  fprintf(fp,"\n");
408 }
409 
410 /**
411  * \brief Dump rule profiling information to file
412  *
413  * \param de_ctx The active DetectEngineCtx, used to get at the loaded rules.
414  */
415 static void
416 SCProfilingRuleDump(SCProfileDetectCtx *rules_ctx)
417 {
418  uint32_t i;
419  FILE *fp;
420 
421  if (rules_ctx == NULL)
422  return;
423 
424  if (profiling_output_to_file == 1) {
425  fp = fopen(profiling_file_name, profiling_file_mode);
426 
427  if (fp == NULL) {
428  SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", profiling_file_name,
429  strerror(errno));
430  return;
431  }
432  } else {
433  fp = stdout;
434  }
435 
436  int summary_size = sizeof(SCProfileSummary) * rules_ctx->size;
437  SCProfileSummary *summary = SCMalloc(summary_size);
438  if (unlikely(summary == NULL)) {
439  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for profiling summary");
440  return;
441  }
442 
443  uint32_t count = rules_ctx->size;
444  uint64_t total_ticks = 0;
445 
446  SCLogPerf("Dumping profiling data for %u rules.", count);
447 
448  memset(summary, 0, summary_size);
449  for (i = 0; i < count; i++) {
450  summary[i].sid = rules_ctx->data[i].sid;
451  summary[i].rev = rules_ctx->data[i].rev;
452  summary[i].gid = rules_ctx->data[i].gid;
453 
454  summary[i].ticks = rules_ctx->data[i].ticks_match + rules_ctx->data[i].ticks_no_match;
455  summary[i].checks = rules_ctx->data[i].checks;
456 
457  if (summary[i].ticks > 0) {
458  summary[i].avgticks = (long double)summary[i].ticks / (long double)summary[i].checks;
459  }
460 
461  summary[i].matches = rules_ctx->data[i].matches;
462  summary[i].max = rules_ctx->data[i].max;
463  summary[i].ticks_match = rules_ctx->data[i].ticks_match;
464  summary[i].ticks_no_match = rules_ctx->data[i].ticks_no_match;
465  if (summary[i].ticks_match > 0) {
466  summary[i].avgticks_match = (long double)summary[i].ticks_match /
467  (long double)summary[i].matches;
468  }
469 
470  if (summary[i].ticks_no_match > 0) {
471  summary[i].avgticks_no_match = (long double)summary[i].ticks_no_match /
472  ((long double)summary[i].checks - (long double)summary[i].matches);
473  }
474  total_ticks += summary[i].ticks;
475  }
476 
477  int *order = profiling_rules_sort_orders;
478  while (*order != -1) {
479  const char *sort_desc = NULL;
480  switch (*order) {
482  qsort(summary, count, sizeof(SCProfileSummary),
483  SCProfileSummarySortByTicks);
484  sort_desc = "ticks";
485  break;
487  qsort(summary, count, sizeof(SCProfileSummary),
488  SCProfileSummarySortByAvgTicks);
489  sort_desc = "average ticks";
490  break;
492  qsort(summary, count, sizeof(SCProfileSummary),
493  SCProfileSummarySortByChecks);
494  sort_desc = "number of checks";
495  break;
497  qsort(summary, count, sizeof(SCProfileSummary),
498  SCProfileSummarySortByMatches);
499  sort_desc = "number of matches";
500  break;
502  qsort(summary, count, sizeof(SCProfileSummary),
503  SCProfileSummarySortByMaxTicks);
504  sort_desc = "max ticks";
505  break;
507  qsort(summary, count, sizeof(SCProfileSummary),
508  SCProfileSummarySortByAvgTicksMatch);
509  sort_desc = "average ticks (match)";
510  break;
512  qsort(summary, count, sizeof(SCProfileSummary),
513  SCProfileSummarySortByAvgTicksNoMatch);
514  sort_desc = "average ticks (no match)";
515  break;
516  }
517  if (profiling_rule_json) {
518  DumpJson(fp, summary, count, total_ticks, sort_desc);
519  } else {
520  DumpText(fp, summary, count, total_ticks, sort_desc);
521  }
522  order++;
523  }
524 
525  if (fp != stdout)
526  fclose(fp);
527  SCFree(summary);
528  SCLogPerf("Done dumping profiling data.");
529 }
530 
531 /**
532  * \brief Register a rule profiling counter.
533  *
534  * \retval Returns the ID of the counter on success, 0 on failure.
535  */
536 static uint16_t
537 SCProfilingRegisterRuleCounter(SCProfileDetectCtx *ctx)
538 {
539  ctx->size++;
540  return ctx->id++;
541 }
542 
543 /**
544  * \brief Update a rule counter.
545  *
546  * \param id The ID of this counter.
547  * \param ticks Number of CPU ticks for this rule.
548  * \param match Did the rule match?
549  */
550 void
551 SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *det_ctx, uint16_t id, uint64_t ticks, int match)
552 {
553  if (det_ctx != NULL && det_ctx->rule_perf_data != NULL && det_ctx->rule_perf_data_size > id) {
554  SCProfileData *p = &det_ctx->rule_perf_data[id];
555 
556  p->checks++;
557  p->matches += match;
558  if (ticks > p->max)
559  p->max = ticks;
560  if (match == 1)
561  p->ticks_match += ticks;
562  else
563  p->ticks_no_match += ticks;
564  }
565 }
566 
567 static SCProfileDetectCtx *SCProfilingRuleInitCtx(void)
568 {
570  if (ctx != NULL) {
571  memset(ctx, 0x00, sizeof(SCProfileDetectCtx));
572 
573  if (pthread_mutex_init(&ctx->data_m, NULL) != 0) {
575  "Failed to initialize hash table mutex.");
576  }
577  }
578 
579  return ctx;
580 }
581 
583 {
584  if (ctx != NULL) {
585  SCProfilingRuleDump(ctx);
586  if (ctx->data != NULL)
587  SCFree(ctx->data);
588  pthread_mutex_destroy(&ctx->data_m);
589  SCFree(ctx);
590  }
591 }
592 
594 {
595  if (ctx == NULL|| ctx->size == 0)
596  return;
597 
598  SCProfileData *a = SCMalloc(sizeof(SCProfileData) * ctx->size);
599  if (a != NULL) {
600  memset(a, 0x00, sizeof(SCProfileData) * ctx->size);
601 
602  det_ctx->rule_perf_data = a;
603  det_ctx->rule_perf_data_size = ctx->size;
604  }
605 }
606 
607 static void SCProfilingRuleThreadMerge(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx)
608 {
609  if (de_ctx == NULL || de_ctx->profile_ctx == NULL || de_ctx->profile_ctx->data == NULL ||
610  det_ctx == NULL || det_ctx->rule_perf_data == NULL)
611  return;
612 
613  int i;
614  for (i = 0; i < det_ctx->rule_perf_data_size; i++) {
615  de_ctx->profile_ctx->data[i].checks += det_ctx->rule_perf_data[i].checks;
616  de_ctx->profile_ctx->data[i].matches += det_ctx->rule_perf_data[i].matches;
619  if (det_ctx->rule_perf_data[i].max > de_ctx->profile_ctx->data[i].max)
620  de_ctx->profile_ctx->data[i].max = det_ctx->rule_perf_data[i].max;
621  }
622 }
623 
625 {
626  if (det_ctx == NULL || det_ctx->de_ctx == NULL || det_ctx->rule_perf_data == NULL)
627  return;
628 
629  pthread_mutex_lock(&det_ctx->de_ctx->profile_ctx->data_m);
630  SCProfilingRuleThreadMerge(det_ctx->de_ctx, det_ctx);
631  pthread_mutex_unlock(&det_ctx->de_ctx->profile_ctx->data_m);
632 
633  SCFree(det_ctx->rule_perf_data);
634  det_ctx->rule_perf_data = NULL;
635  det_ctx->rule_perf_data_size = 0;
636 }
637 
638 /**
639  * \brief Register the rule profiling counters.
640  *
641  * \param de_ctx The active DetectEngineCtx, used to get at the loaded rules.
642  */
643 void
645 {
646  if (profiling_rules_enabled == 0)
647  return;
648 
649  de_ctx->profile_ctx = SCProfilingRuleInitCtx();
650  BUG_ON(de_ctx->profile_ctx == NULL);
651 
652  Signature *sig = de_ctx->sig_list;
653  uint32_t count = 0;
654  while (sig != NULL) {
655  sig->profiling_id = SCProfilingRegisterRuleCounter(de_ctx->profile_ctx);
656  sig = sig->next;
657  count++;
658  }
659 
660  if (count > 0) {
662  BUG_ON(de_ctx->profile_ctx->data == NULL);
663  memset(de_ctx->profile_ctx->data, 0x00, sizeof(SCProfileData) * de_ctx->profile_ctx->size);
664 
665  sig = de_ctx->sig_list;
666  while (sig != NULL) {
667  de_ctx->profile_ctx->data[sig->profiling_id].sid = sig->id;
668  de_ctx->profile_ctx->data[sig->profiling_id].gid = sig->gid;
669  de_ctx->profile_ctx->data[sig->profiling_id].rev = sig->rev;
670  sig = sig->next;
671  }
672  }
673 
674  SCLogPerf("Registered %"PRIu32" rule profiling counters.", count);
675 }
676 
677 #endif /* PROFILING */
678 
util-byte.h
profiling_rules_enabled
int profiling_rules_enabled
Definition: util-profiling-rules.c:75
ConfNodeChildValueIsTrue
int ConfNodeChildValueIsTrue(const ConfNode *node, const char *key)
Test if a configuration node has a true value.
Definition: conf.c:844
SCProfileSummary
struct SCProfileSummary_ SCProfileSummary
SCProfileSummary_::ticks_no_match
uint64_t ticks_no_match
Definition: util-profiling-rules.c:71
CreateIsoTimeString
void CreateIsoTimeString(const struct timeval *ts, char *str, size_t size)
Definition: util-time.c:215
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SCProfileSummary_::matches
uint64_t matches
Definition: util-profiling-rules.c:68
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:176
SCProfileData_::rev
uint32_t rev
Definition: util-profiling-rules.c:41
SCProfilingRuleUpdateCounter
void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *det_ctx, uint16_t id, uint64_t ticks, int match)
Update a rule counter.
Definition: util-profiling-rules.c:551
SCProfileSummary_::rev
uint32_t rev
Definition: util-profiling-rules.c:62
SCProfileData_::gid
uint32_t gid
Definition: util-profiling-rules.c:40
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:784
SET_ONE
#define SET_ONE(x)
SCProfileSummary_::ticks
uint64_t ticks
Definition: util-profiling-rules.c:63
SCProfileSummary_
Definition: util-profiling-rules.c:59
SCProfilingRuleInitCounters
void SCProfilingRuleInitCounters(DetectEngineCtx *de_ctx)
Register the rule profiling counters.
Definition: util-profiling-rules.c:644
MIN
#define MIN(x, y)
Definition: suricata-common.h:380
JSON_ESCAPE_SLASH
#define JSON_ESCAPE_SLASH
Definition: suricata-common.h:270
Signature_::profiling_id
uint16_t profiling_id
Definition: detect.h:582
SCProfileDetectCtx_::id
uint16_t id
Definition: util-profiling-rules.c:51
SCProfileDetectCtx_::data
SCProfileData * data
Definition: util-profiling-rules.c:52
SC_PROFILING_RULES_SORT_BY_AVG_TICKS_NO_MATCH
@ SC_PROFILING_RULES_SORT_BY_AVG_TICKS_NO_MATCH
Definition: util-profiling-rules.c:90
ConfValIsTrue
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:522
SCProfileData_::matches
uint64_t matches
Definition: util-profiling-rules.c:43
Signature_::gid
uint32_t gid
Definition: detect.h:574
Signature_::next
struct Signature_ * next
Definition: detect.h:613
SC_PROFILING_RULES_SORT_BY_MAX_TICKS
@ SC_PROFILING_RULES_SORT_BY_MAX_TICKS
Definition: util-profiling-rules.c:88
SCProfileData_::checks
uint64_t checks
Definition: util-profiling-rules.c:42
SCProfileDetectCtx_::data_m
pthread_mutex_t data_m
Definition: util-profiling-rules.c:53
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1024
SCProfileSummary_::sid
uint32_t sid
Definition: util-profiling-rules.c:60
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:313
util-time.h
SC_ERR_INVALID_ARGUMENT
@ SC_ERR_INVALID_ARGUMENT
Definition: util-error.h:43
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:289
util-profiling.h
DetectEngineCtx_::profile_ctx
struct SCProfileDetectCtx_ * profile_ctx
Definition: detect.h:907
SC_ERR_FOPEN
@ SC_ERR_FOPEN
Definition: util-error.h:74
SCLocalTime
struct tm * SCLocalTime(time_t timep, struct tm *result)
Definition: util-time.c:273
DetectEngineThreadCtx_::rule_perf_data_size
int rule_perf_data_size
Definition: detect.h:1184
SCProfilingRuleThreadCleanup
void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *det_ctx)
Definition: util-profiling-rules.c:624
SCProfileSummary_::avgticks_match
double avgticks_match
Definition: util-profiling-rules.c:65
SCProfileData_
Definition: util-profiling-rules.c:38
SC_PROFILING_RULES_SORT_BY_TICKS
@ SC_PROFILING_RULES_SORT_BY_TICKS
Definition: util-profiling-rules.c:84
profiling_output_to_file
int profiling_output_to_file
Definition: util-profiling.c:97
DetectEngineThreadCtx_::rule_perf_data
struct SCProfileData_ * rule_perf_data
Definition: detect.h:1183
SCProfileData_::max
uint64_t max
Definition: util-profiling-rules.c:44
SC_PROFILING_RULES_SORT_BY_AVG_TICKS_MATCH
@ SC_PROFILING_RULES_SORT_BY_AVG_TICKS_MATCH
Definition: util-profiling-rules.c:89
util-conf.h
SCProfileSummary_::gid
uint32_t gid
Definition: util-profiling-rules.c:61
suricata-common.h
SCProfileDetectCtx_::size
uint32_t size
Definition: util-profiling-rules.c:50
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:222
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:255
SCProfilingRuleDestroyCtx
void SCProfilingRuleDestroyCtx(SCProfileDetectCtx *ctx)
Definition: util-profiling-rules.c:582
Signature_::rev
uint32_t rev
Definition: detect.h:575
SCProfileSummary_::max
uint64_t max
Definition: util-profiling-rules.c:69
FatalError
#define FatalError(x,...)
Definition: util-debug.h:530
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:790
SCProfileData_::sid
uint32_t sid
Definition: util-profiling-rules.c:39
SCProfileSummary_::avgticks_no_match
double avgticks_no_match
Definition: util-profiling-rules.c:66
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCProfileSummary_::ticks_match
uint64_t ticks_match
Definition: util-profiling-rules.c:70
SCProfileSummary_::checks
uint64_t checks
Definition: util-profiling-rules.c:67
ConfigGetLogDirectory
const char * ConfigGetLogDirectory()
Definition: util-conf.c:37
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
Signature_::id
uint32_t id
Definition: detect.h:573
Signature_
Signature container.
Definition: detect.h:539
SCProfileDetectCtx_
Definition: util-profiling-rules.c:49
SC_PROFILING_RULES_SORT_BY_CHECKS
@ SC_PROFILING_RULES_SORT_BY_CHECKS
Definition: util-profiling-rules.c:86
SCProfileDetectCtx
struct SCProfileDetectCtx_ SCProfileDetectCtx
SCProfilingRulesGlobalInit
void SCProfilingRulesGlobalInit(void)
Definition: util-profiling-rules.c:108
SC_PROFILING_RULES_SORT_BY_AVG_TICKS
@ SC_PROFILING_RULES_SORT_BY_AVG_TICKS
Definition: util-profiling-rules.c:85
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
DetectEngineThreadCtx_::de_ctx
DetectEngineCtx * de_ctx
Definition: detect.h:1156
SCProfileData_::ticks_match
uint64_t ticks_match
Definition: util-profiling-rules.c:45
SCProfilingRuleThreadSetup
void SCProfilingRuleThreadSetup(SCProfileDetectCtx *ctx, DetectEngineThreadCtx *det_ctx)
Definition: util-profiling-rules.c:593
SC_PROFILING_RULES_SORT_BY_MATCHES
@ SC_PROFILING_RULES_SORT_BY_MATCHES
Definition: util-profiling-rules.c:87
SCProfileData
struct SCProfileData_ SCProfileData
SCProfileSummary_::avgticks
double avgticks
Definition: util-profiling-rules.c:64
SCProfileData_::ticks_no_match
uint64_t ticks_no_match
Definition: util-profiling-rules.c:46
ConfNodeLookupChildValue
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:799