From: Russ Combs (rucombs) Date: Fri, 16 Oct 2015 18:16:26 +0000 (-0400) Subject: Merge pull request #79 in SNORT/snort3 from perf_prof to master X-Git-Tag: 3.0.0-233~783 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ca132b243feb145b3ebc578af98fbe428b89608;p=thirdparty%2Fsnort3.git Merge pull request #79 in SNORT/snort3 from perf_prof to master Squashed commit of the following: commit 8cb9129f2168944c0ee95a435ff737ef935f560d Author: Joel Cornett Date: Fri Oct 16 12:40:15 2015 -0400 created PerfProfilerManager interface to Perf profiling API commit dc6a72c40aef528619b32bec74281ea98ee710c1 Author: Joel Cornett Date: Fri Oct 16 12:12:39 2015 -0400 gcc-4.8 doesnt like braced initialization for reference types commit ef5c8bf4b71e4ce2759373a576b98dc31edbc598 Merge: 9d2b1cb 360f910 Author: Joel Cornett Date: Fri Oct 16 12:09:32 2015 -0400 Merge branch 'master' into perf_prof commit 9d2b1cb67d7374f29f378b165af37248b5544cd5 Author: Joel Cornett Date: Fri Oct 16 12:07:30 2015 -0400 added automake support for conditional perf profiling compilation commit e6ba4d617dbc16982aeb0604f9d932024c53eef8 Author: Joel Cornett Date: Thu Oct 15 18:20:18 2015 -0400 fixed semantic error with auto& assignment commit 357fdc43df16578a09be43b89f97067bcc7ebb13 Merge: 3e9a9a6 abf3f15 Author: Joel Cornett Date: Thu Oct 15 10:28:47 2015 -0400 Merge branch 'perf_prof' of https://stash-eng-rtp1.cisco.com/stash/scm/snort/snort3 into perf_prof commit 3e9a9a6df4bcf3da18ba8b3c29c8ec7badadbfe4 Author: Joel Cornett Date: Wed Oct 14 21:08:53 2015 -0400 formatting/comment cleanup commit e7b7ed041da08befffa1af1b7f353837c052dae3 Author: Joel Cornett Date: Wed Oct 14 19:00:13 2015 -0400 fixed perf profile format strings commit 70b5d5c9b6c400ae042d760fc457bb5942f93d53 Author: Joel Cornett Date: Wed Oct 14 18:45:18 2015 -0400 initialized eval_rtn_result to silence warning commit c9b0b19d3d532a39d9f19a4389d9942eca7beca4 Author: Joel Cornett Date: Wed Oct 14 16:20:36 2015 -0400 cleaned up code related to perf profiling refactor commit 18b0220b40faefe4d1f71a3d6ffa98e567d064b3 Author: Joel Cornett Date: Wed Oct 14 16:13:10 2015 -0400 moved perf_profile macro to top in arp_spoof commit 3b413223656f04b9d33640b782d4a924bde3b8a9 Author: Joel Cornett Date: Wed Oct 14 16:06:02 2015 -0400 refactored/fixed detection_options and tcp_reassembly commit e46117400804f4fd965caaba758d5878e7068912 Author: Joel Cornett Date: Wed Oct 14 14:55:43 2015 -0400 cleaned up code related to perf profiling refactor commit 230e646f9e4108d9a867ffa5f7100e436ac894cc Author: Joel Cornett Date: Wed Oct 14 14:40:14 2015 -0400 cleaned up code related to perf profiling refactor commit bbfc71b348fbdb2d658f2f7470b5564c27752a1d Author: Joel Cornett Date: Wed Oct 14 13:39:26 2015 -0400 moved PERF_PROFILE macro to start of functions commit 8bafe1017c329c7a9501892c459bb35d64cdffae Author: Joel Cornett Date: Tue Oct 13 13:52:16 2015 -0400 removed comments commit 9d31f599cef0b394f68d158ad1655dd3ae92d33a Author: Joel Cornett Date: Tue Oct 13 13:48:21 2015 -0400 cleaned up warnings and errors commit 9bd22d3f5afbdbd9893c5adac916de89cfb8cffb Author: Joel Cornett Date: Tue Oct 13 13:42:03 2015 -0400 refactored perf profilers and added more unit tests commit f461cadbf5ff8c9d20a7104a9aa684f264d38577 Author: Joel Cornett Date: Tue Oct 13 13:09:55 2015 -0400 deleted unused profiler macros commit 7746705b71730306ecbc4fc5440073dcacd3d1e3 Author: Joel Cornett Date: Tue Oct 13 12:55:03 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit df108376e6bf5b814ca95df4ccfb90b81bb131eb Author: Joel Cornett Date: Tue Oct 13 12:53:31 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 5e1530fc98312399d9212f28fa23a87151e7d3d2 Author: Joel Cornett Date: Tue Oct 13 12:45:45 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 2b1d77ec0a08a95004f1fe698dba49a7642d7b6a Author: Joel Cornett Date: Tue Oct 13 12:41:43 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 46dc1b47c92b167edb7bbc1fb7f9cc341d49ad63 Author: Joel Cornett Date: Tue Oct 13 12:38:01 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit f18795dad9d2b328769ae7f2770c5e79bd1d95f4 Author: Joel Cornett Date: Tue Oct 13 12:24:18 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit e91259d698c02cfa71b1636818ce61802cae5060 Author: Joel Cornett Date: Tue Oct 13 12:19:50 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit f5f8e77d1d7d3abb53ccc66833ce1ccc8b76c31a Author: Joel Cornett Date: Tue Oct 13 12:07:25 2015 -0400 added new macros commit e6819ed08854b9b3ec259daf9a2b9a35f6ab7dfa Author: Joel Cornett Date: Tue Oct 13 11:21:13 2015 -0400 added test cases and updated node profiling commit fdc139dc2573a5bfe26fae5beaa31f65f0e39cb3 Author: Joel Cornett Date: Tue Oct 13 02:19:48 2015 -0400 5th compile commit ddf99b4a58874b0dea2d9e54f5e2087554d9d287 Author: Joel Cornett Date: Tue Oct 13 00:18:48 2015 -0400 4th compile commit b2f7730bc79bf30b9d1cef51e016c0360a27f615 Author: Joel Cornett Date: Tue Oct 13 00:14:03 2015 -0400 3rd compile commit a7863c98cee2eafa29ada81e89715a79240040d3 Author: Joel Cornett Date: Mon Oct 12 23:57:46 2015 -0400 2nd stage compiles commit 4fb0b9dc158a2c026b32cf630485a40784329a8f Author: Joel Cornett Date: Mon Oct 12 23:20:23 2015 -0400 compiles, added RAII profiling context commit abf3f15c48dc7ddabcf1c60d052652a1108435c8 Author: Joel Cornett Date: Wed Oct 14 21:08:53 2015 -0400 formatting/comment cleanup commit 5b545960dce78a5d916b56f30730088af49273a5 Author: Joel Cornett Date: Wed Oct 14 19:00:13 2015 -0400 fixed perf profile format strings commit 8c951762b2c2b2e79fca03351cae8b29557ceaed Merge: 2af12fb e3555b6 Author: Joel Cornett Date: Wed Oct 14 18:49:58 2015 -0400 Merge branch 'perf_prof' of https://stash-eng-rtp1.cisco.com/stash/scm/snort/snort3 into perf_prof commit 2af12fbdd4d5c49546788b586af7eeeac48de170 Author: Joel Cornett Date: Wed Oct 14 18:45:18 2015 -0400 initialized eval_rtn_result to silence warning commit 97c526d6bd579cb0863dc2037f32b9656a2643dc Author: Joel Cornett Date: Wed Oct 14 16:20:36 2015 -0400 cleaned up code related to perf profiling refactor commit db6e6189416dfbc66a6256a8e2b59324472a6bda Author: Joel Cornett Date: Wed Oct 14 16:13:10 2015 -0400 moved perf_profile macro to top in arp_spoof commit 9e4dab7d7b885e39382ec616e5cc5bd185aa6fe6 Author: Joel Cornett Date: Wed Oct 14 16:06:02 2015 -0400 refactored/fixed detection_options and tcp_reassembly commit 1c548b1378c83cd4b88b0d3845fac765e4cfa031 Author: Joel Cornett Date: Wed Oct 14 14:55:43 2015 -0400 cleaned up code related to perf profiling refactor commit 231e6d70d5f3ed1f4eb9984d43223872f97222b7 Author: Joel Cornett Date: Wed Oct 14 14:40:14 2015 -0400 cleaned up code related to perf profiling refactor commit 70b03b20eef67364ace0711182e55624101afbee Author: Joel Cornett Date: Wed Oct 14 13:39:26 2015 -0400 moved PERF_PROFILE macro to start of functions commit b7b860d7d126ef4ecdd05243ea647247633fa360 Author: Joel Cornett Date: Tue Oct 13 13:52:16 2015 -0400 removed comments commit e9b29eb9ecd8ef5cdf5192e8af2174740b86f7ec Author: Joel Cornett Date: Tue Oct 13 13:48:21 2015 -0400 cleaned up warnings and errors commit 4ef96ebf8d27a335630cd90809688273369f18af Author: Joel Cornett Date: Tue Oct 13 13:42:03 2015 -0400 refactored perf profilers and added more unit tests commit 2bd9926a8986c5d82cf16972d29f81fd04a13491 Author: Joel Cornett Date: Tue Oct 13 13:09:55 2015 -0400 deleted unused profiler macros commit cc330b5b011207877a0953c8f299860a425a8048 Author: Joel Cornett Date: Tue Oct 13 12:55:03 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 5019c89baef3d87c66c7367b52dd9784da0dabad Author: Joel Cornett Date: Tue Oct 13 12:53:31 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit db2ee16f75b1cb781ac6dd7a0303daf25c8cbfbf Author: Joel Cornett Date: Tue Oct 13 12:45:45 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 435da53c30948a6a9a0f2c79d3fbc799a9649a29 Author: Joel Cornett Date: Tue Oct 13 12:41:43 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit fec3530e4e5d94eda90d64f30582539de9af84a1 Author: Joel Cornett Date: Tue Oct 13 12:38:01 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 6d10ab2151ff9f16a50d367837b4ab1138ef3173 Author: Joel Cornett Date: Tue Oct 13 12:24:18 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit ef73fa131be6d4fccc15cae7cfb8f868ed7e1e33 Author: Joel Cornett Date: Tue Oct 13 12:19:50 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit d1dcd1464ff1e84161619036df2f195b55397318 Author: Joel Cornett Date: Tue Oct 13 12:07:25 2015 -0400 added new macros commit 888fc6aadd13142c5054955a2be165296ef454e8 Author: Joel Cornett Date: Tue Oct 13 11:21:13 2015 -0400 added test cases and updated node profiling commit 22abc4c2e59639c72d2d1bef3b3855538da36be9 Author: Joel Cornett Date: Tue Oct 13 02:19:48 2015 -0400 5th compile commit 5649060a870c7adf33f80a5f4a5942d7442bfad6 Author: Joel Cornett Date: Tue Oct 13 00:18:48 2015 -0400 4th compile commit 1a7a9a9d74133918212b8173f6bbaefed3823c08 Author: Joel Cornett Date: Tue Oct 13 00:14:03 2015 -0400 3rd compile commit 33772ae0be4253bb5f5cc8a052c5f1623b2b0146 Author: Joel Cornett Date: Mon Oct 12 23:57:46 2015 -0400 2nd stage compiles commit 7ff60d56e526187012a7735ec2d07a975de95e83 Author: Joel Cornett Date: Mon Oct 12 23:20:23 2015 -0400 compiles, added RAII profiling context commit e3555b644d403a1588c4d607a43f298844b661f8 Author: Joel Cornett Date: Wed Oct 14 18:45:18 2015 -0400 initialized eval_rtn_result to silence warning commit d29b515e981b53f4b6b56f4357d3330c25d21c8d Author: Joel Cornett Date: Wed Oct 14 16:20:36 2015 -0400 cleaned up code related to perf profiling refactor commit c96b2324484072f64ec3496f69ae459c58c832ef Author: Joel Cornett Date: Wed Oct 14 16:13:10 2015 -0400 moved perf_profile macro to top in arp_spoof commit ff200752af83844c0289020dad7cebf10d488abe Author: Joel Cornett Date: Wed Oct 14 16:06:02 2015 -0400 refactored/fixed detection_options and tcp_reassembly commit f08c21c4171c7505dcd2dc28919ed55e9db4dde4 Author: Joel Cornett Date: Wed Oct 14 14:55:43 2015 -0400 cleaned up code related to perf profiling refactor commit 1e69e86faf3979b3855739ef9f80e0d6d9506b34 Author: Joel Cornett Date: Wed Oct 14 14:40:14 2015 -0400 cleaned up code related to perf profiling refactor commit 9808423b831394c6f791ee3a06938f8fb3bbe2af Author: Joel Cornett Date: Wed Oct 14 13:39:26 2015 -0400 moved PERF_PROFILE macro to start of functions commit 481030d04831b7a58a28679dc43d24879bb7f208 Merge: cf90106 ab48be3 Author: Joel Cornett Date: Wed Oct 14 12:33:02 2015 -0400 Merge branch 'perf_prof' of https://stash-eng-rtp1.cisco.com/stash/scm/snort/snort3 into perf_prof commit cf901064e092c90aad2e75ec826c907d4e0001cf Author: Joel Cornett Date: Tue Oct 13 13:52:16 2015 -0400 removed comments commit f046e14eaf998e1d8f22d82f1d5d330ef2371fcd Author: Joel Cornett Date: Tue Oct 13 13:48:21 2015 -0400 cleaned up warnings and errors commit 115a534521812e49684d74dbe78eb09e782d96fb Author: Joel Cornett Date: Tue Oct 13 13:42:03 2015 -0400 refactored perf profilers and added more unit tests commit 136a0d54b35a966ccfea19fa1a91c96ba40eb076 Author: Joel Cornett Date: Tue Oct 13 13:09:55 2015 -0400 deleted unused profiler macros commit e1065544e8a888ab3f7a1f8d83a222bb1cffc419 Author: Joel Cornett Date: Tue Oct 13 12:55:03 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 06b268131b344b5604151c31c30e88304ddf70f1 Author: Joel Cornett Date: Tue Oct 13 12:53:31 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 901b393393e73e3241163d1d8554da66bb9d5fbc Author: Joel Cornett Date: Tue Oct 13 12:45:45 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit b2f5f60e6aefba325a0f83eb322ffa6701842828 Author: Joel Cornett Date: Tue Oct 13 12:41:43 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit c2b3b0654894789956db49aac95710af809ef24a Author: Joel Cornett Date: Tue Oct 13 12:38:01 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 0a9c4e24d968e277b4e69fe8dcc9645874eae83f Author: Joel Cornett Date: Tue Oct 13 12:24:18 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 3536c9b469f9c13a29172339e95a903f06abad73 Author: Joel Cornett Date: Tue Oct 13 12:19:50 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit c24460fede9c3a42d78f01deb45d7548622ada39 Author: Joel Cornett Date: Tue Oct 13 12:07:25 2015 -0400 added new macros commit 716c35f974982c3167d3a43c337fbbc1dd1b546e Author: Joel Cornett Date: Tue Oct 13 11:21:13 2015 -0400 added test cases and updated node profiling commit 89bee5319a75a2bbd6b8a3d66da95db263730388 Author: Joel Cornett Date: Tue Oct 13 02:19:48 2015 -0400 5th compile commit e4d5161e0d5ea557a1d72ea0e0a4a138a27b3f22 Author: Joel Cornett Date: Tue Oct 13 00:18:48 2015 -0400 4th compile commit 607568b56bc016dfe8a7f761c30a893fe6d0a00d Author: Joel Cornett Date: Tue Oct 13 00:14:03 2015 -0400 3rd compile commit 3d9bb432f61d1e81b6cae3a6488495b23596ae0d Author: Joel Cornett Date: Mon Oct 12 23:57:46 2015 -0400 2nd stage compiles commit ae31effa3ebbc0383e0247a2b28e8d8670d8ea90 Author: Joel Cornett Date: Mon Oct 12 23:20:23 2015 -0400 compiles, added RAII profiling context commit ab48be3afcf3123a3307d2949a5481074da108f9 Author: Joel Cornett Date: Tue Oct 13 13:52:16 2015 -0400 removed comments commit db33180f5db10a063059e5665f68d81fe574e2be Author: Joel Cornett Date: Tue Oct 13 13:48:21 2015 -0400 cleaned up warnings and errors commit 31af7b38516cd303e3074dae7ff754635c08faea Author: Joel Cornett Date: Tue Oct 13 13:42:03 2015 -0400 refactored perf profilers and added more unit tests commit 26dfb34fa9bbb06c8481a1ad4ba9b643a9800653 Author: Joel Cornett Date: Tue Oct 13 13:09:55 2015 -0400 deleted unused profiler macros commit 2e544f87ec98d4753aa130121bb301f7ca866b93 Author: Joel Cornett Date: Tue Oct 13 12:55:03 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 7e5e310736cffbcf794b5dff5bef152b3097bf1c Author: Joel Cornett Date: Tue Oct 13 12:53:31 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 85ad2fbebaef362e10e8024b96f9777300306335 Author: Joel Cornett Date: Tue Oct 13 12:45:45 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 7ddb78cc4fcd769038d0f047c2ba7163f7e9f0e4 Author: Joel Cornett Date: Tue Oct 13 12:41:43 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 11f829a8d3ec2d9d2a86039024ca6d86ea6b7d74 Author: Joel Cornett Date: Tue Oct 13 12:38:01 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 7a3cfa6a1ab390685812a72ff1847f9a845d2116 Author: Joel Cornett Date: Tue Oct 13 12:24:18 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit dc4901267c0b21fa9ef72c2425b2c353148b95a4 Author: Joel Cornett Date: Tue Oct 13 12:19:50 2015 -0400 renamed USE_PROFILING -> PERF_PROFILE commit 41625aa49bc9c44a6fe6d8fbe07a0eb78a80561e Author: Joel Cornett Date: Tue Oct 13 12:07:25 2015 -0400 added new macros commit 53b31ffa6f3e7ac29a9b08ff7885e3083e1238c0 Author: Joel Cornett Date: Tue Oct 13 11:21:13 2015 -0400 added test cases and updated node profiling commit 29df2e65da6c17210b60df2631a023ac2fb4b202 Author: Joel Cornett Date: Tue Oct 13 02:19:48 2015 -0400 5th compile commit 85c43360d59938228df5660b3e152a8837501843 Author: Joel Cornett Date: Tue Oct 13 00:18:48 2015 -0400 4th compile commit d9e8423a3cb9e32a541649c239e30caac5ba8010 Author: Joel Cornett Date: Tue Oct 13 00:14:03 2015 -0400 3rd compile commit e85e3cc73023a980ee2ba4f6dbb9faf152bf5523 Author: Joel Cornett Date: Mon Oct 12 23:57:46 2015 -0400 2nd stage compiles commit 433a7d85864cb8f7000c5c872c8aa3f45e0bfb6d Author: Joel Cornett Date: Mon Oct 12 23:20:23 2015 -0400 compiles, added RAII profiling context --- diff --git a/configure.ac b/configure.ac index 1a51d19db..eb63de211 100644 --- a/configure.ac +++ b/configure.ac @@ -377,6 +377,8 @@ AC_ARG_ENABLE(perf-profiling, AC_HELP_STRING([--enable-perf-profiling],[enable module and rule performance profiling]), enable_perf_profiling="$enableval", enable_perf_profiling="no") +AM_CONDITIONAL(PERF_PROFILING, test "x$enable_perf_profiling" = "xyes") + if test "x$enable_perf_profiling" = "xyes"; then CPPFLAGS="$CPPFLAGS -DPERF_PROFILING" AC_DEFINE(PERF_PROFILING, [1], [enable perf profiling]) diff --git a/src/actions/act_react.cc b/src/actions/act_react.cc index 783a067e1..8506c14d3 100644 --- a/src/actions/act_react.cc +++ b/src/actions/act_react.cc @@ -141,13 +141,10 @@ ReactAction::~ReactAction() void ReactAction::exec(Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(reactPerfStats); + PERF_PROFILE(reactPerfStats); if ( Active::is_reset_candidate(p) ) send(p); - - MODULE_PROFILE_END(reactPerfStats); } void ReactAction::send(Packet* p) diff --git a/src/actions/act_reject.cc b/src/actions/act_reject.cc index 4d31c410e..e31eacf37 100644 --- a/src/actions/act_reject.cc +++ b/src/actions/act_reject.cc @@ -95,12 +95,8 @@ private: void RejectAction::exec(Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(rejPerfStats); - + PERF_PROFILE(rejPerfStats); send(p); - - MODULE_PROFILE_END(rejPerfStats); } void RejectAction::send(Packet* p) diff --git a/src/detection/detect.cc b/src/detection/detect.cc index 76b2f9a3d..631f4c568 100644 --- a/src/detection/detect.cc +++ b/src/detection/detect.cc @@ -84,8 +84,6 @@ void snort_ignore(Packet*) { } void snort_inspect(Packet* p) { - PROFILE_VARS; - #ifdef PPM_MGR uint64_t pktcnt=0; @@ -194,10 +192,10 @@ void snort_inspect(Packet* p) PPM_END_PKT_TIMER(); } #endif - MODULE_PROFILE_START(eventqPerfStats); + + PERF_PROFILE(eventqPerfStats); SnortEventqLog(p); SnortEventqReset(); - MODULE_PROFILE_END(eventqPerfStats); } void snort_log(Packet* p) @@ -338,8 +336,6 @@ bool snort_detect(Packet* p) case PktType::PDU: case PktType::FILE: { - PROFILE_VARS; - # ifdef PPM_MGR /* * Packet Performance Monitoring @@ -359,11 +355,8 @@ bool snort_detect(Packet* p) ** This is where we short circuit so ** that we can do IP checks. */ - MODULE_PROFILE_START(detectPerfStats); - int detected = fpEvalPacket(p); - MODULE_PROFILE_END(detectPerfStats); - - return detected; + PERF_PROFILE(detectPerfStats); + return fpEvalPacket(p); } default: diff --git a/src/detection/detection_options.cc b/src/detection/detection_options.cc index 307da1f8d..adac5a67c 100644 --- a/src/detection/detection_options.cc +++ b/src/detection/detection_options.cc @@ -65,6 +65,10 @@ typedef struct _detection_option_key #define HASH_RULE_OPTIONS 16384 #define HASH_RULE_TREE 8192 +// FIXIT-L find a better place for this +static inline bool operator==(const struct timeval& a, const struct timeval& b) +{ return a.tv_sec == b.tv_sec && a.tv_usec == b.tv_usec; } + uint32_t detection_option_hash_func(SFHASHFCN*, unsigned char* k, int) { detection_option_key_t* key = (detection_option_key_t*)k; @@ -377,7 +381,15 @@ int detection_option_node_evaluate( detection_option_tree_node_t* node, detection_option_eval_data_t* eval_data, Cursor& orig_cursor) { - int i, result = 0; + // need node->state to do perf profiling + if ( !node ) + return 0; + + dot_node_state_t* state = node->state + get_instance_id(); + auto& node_stats = *state; + NODE_PERF_PROFILE(node_stats); + + int result = 0; int rval = DETECTION_OPTION_NO_MATCH; char tmp_noalert_flag = 0; Cursor cursor = orig_cursor; @@ -387,206 +399,208 @@ int detection_option_node_evaluate( uint32_t tmp_byte_extract_vars[NUM_BYTE_EXTRACT_VARS]; uint64_t cur_eval_pkt_count = (rule_eval_pkt_count + (PacketManager::get_rebuilt_packet_count())); - NODE_PROFILE_VARS; // FIXIT-P these are initialized only to silence -O2 warnings // they are set before use below PatternMatchData* content_data = nullptr; PcreData* pcre_data = nullptr; - if (!node || !eval_data || !eval_data->p || !eval_data->pomd) + if ( !eval_data || !eval_data->p || !eval_data->pomd ) return 0; - dot_node_state_t* state = node->state + get_instance_id(); + auto p = eval_data->p; + auto pomd = eval_data->pomd; - /* see if evaluated it before ... */ - if (node->is_relative == 0) + // see if evaluated it before ... + if ( !node->is_relative ) { - /* Only matters if not relative... */ - if ((state->last_check.ts.tv_usec == eval_data->p->pkth->ts.tv_usec) && - (state->last_check.ts.tv_sec == eval_data->p->pkth->ts.tv_sec) && - (state->last_check.packet_number == cur_eval_pkt_count) && - (state->last_check.rebuild_flag == (eval_data->p->packet_flags & - PKT_REBUILT_STREAM)) && - (!(eval_data->p->packet_flags & PKT_ALLOW_MULTIPLE_DETECT))) + auto last_check = state->last_check; + + if ( last_check.ts == p->pkth->ts && + last_check.packet_number == cur_eval_pkt_count && + last_check.rebuild_flag == (p->packet_flags & PKT_REBUILT_STREAM) && + !(p->packet_flags & PKT_ALLOW_MULTIPLE_DETECT) ) { - /* eval'd this rule option before on this packet, - * use the cached result. */ - if ((state->last_check.flowbit_failed == 0) && - !(eval_data->p->packet_flags & PKT_IP_RULE_2ND) && - !(eval_data->p->proto_bits & (PROTO_BIT__TEREDO | PROTO_BIT__GTP ))) + if ( !last_check.flowbit_failed && + !(p->packet_flags & PKT_IP_RULE_2ND) && + !(p->packet_flags & (PROTO_BIT__TEREDO|PROTO_BIT__GTP)) ) { - return state->last_check.result; + return last_check.result; } } } - NODE_PROFILE_START(node); - - state->last_check.ts.tv_sec = eval_data->p->pkth->ts.tv_sec; - state->last_check.ts.tv_usec = eval_data->p->pkth->ts.tv_usec; + state->last_check.ts = eval_data->p->pkth->ts; state->last_check.packet_number = cur_eval_pkt_count; - state->last_check.rebuild_flag = (eval_data->p->packet_flags & PKT_REBUILT_STREAM); state->last_check.flowbit_failed = 0; + state->last_check.rebuild_flag = p->packet_flags & PKT_REBUILT_STREAM; - /* Save some stuff off for repeated pattern tests */ + // Save some stuff off for repeated pattern tests if ( node->option_type == RULE_OPTION_TYPE_CONTENT ) - { content_data = content_get_data(node->option_data); - } + else if (node->option_type == RULE_OPTION_TYPE_PCRE) - { pcre_data = pcre_get_data(node->option_data); - } - /* No, haven't evaluated this one before... Check it. */ + // No, haven't evaluated this one before... Check it. do { - switch (node->option_type) + switch ( node->option_type ) { case RULE_OPTION_TYPE_LEAF_NODE: - /* Add the match for this otn to the queue. */ + // Add the match for this otn to the queue. { OptTreeNode* otn = (OptTreeNode*)node->option_data; PatternMatchData* pmd = (PatternMatchData*)eval_data->pmd; int pattern_size = 0; - int check_ports = 1; - int eval_rtn_result; - unsigned int svc_idx; - int16_t app_proto = eval_data->p->get_application_protocol(); - - if (pmd) + if ( pmd ) pattern_size = pmd->pattern_size; - if ( app_proto and ((OTNX_MATCH_DATA*)(eval_data->pomd))->check_ports != 2 ) + int16_t app_proto = p->get_application_protocol(); + int check_ports = 1; + + if ( app_proto and ((OTNX_MATCH_DATA*)(pomd))->check_ports != 2 ) { - for (svc_idx = 0; svc_idx < otn->sigInfo.num_services; svc_idx++) + auto sig_info = otn->sigInfo; + + for ( unsigned svc_idx = 0; svc_idx < sig_info.num_services; ++svc_idx ) { - if ( app_proto == otn->sigInfo.services[svc_idx].service_ordinal ) + if ( app_proto == sig_info.services[svc_idx].service_ordinal ) { check_ports = 0; - break; /* out of for */ + break; // out of for } } - if (otn->sigInfo.num_services && check_ports) + if (sig_info.num_services && check_ports) { - /* none of the services match */ + // none of the services match DebugFormat(DEBUG_DETECT, "[**] SID %d not matched because of service mismatch (%d!=%d [**]\n", - otn->sigInfo.id, app_proto, otn->sigInfo.services[0].service_ordinal); - break; /* out of case */ + sig_info.id, app_proto, sig_info.services[0].service_ordinal); + + break; // out of case } } + + int eval_rtn_result = 0; + // Don't include RTN time - NODE_PROFILE_TMPEND(node); - eval_rtn_result = fpEvalRTN(getRuntimeRtnFromOtn(otn), eval_data->p, check_ports); - NODE_PROFILE_TMPSTART(node); + PERF_PAUSE_BLOCK(node_stats) + { + eval_rtn_result = fpEvalRTN(getRuntimeRtnFromOtn(otn), p, + check_ports); + } - if (eval_rtn_result) + if ( eval_rtn_result ) { - if ( !otn->detection_filter || - !detection_filter_test( - otn->detection_filter, - eval_data->p->ptrs.ip_api.get_src(), eval_data->p->ptrs.ip_api.get_dst(), - eval_data->p->pkth->ts.tv_sec) ) + bool f_result = true; + + if ( otn->detection_filter ) + f_result = detection_filter_test(otn->detection_filter, + p->ptrs.ip_api.get_src(), p->ptrs.ip_api.get_dst(), + p->pkth->ts.tv_sec); + + if ( f_result ) { #ifdef PERF_PROFILING if (PROFILING_RULES) otn->state[get_instance_id()].matches++; #endif - if (!eval_data->flowbit_noalert) - { - fpAddMatch((OTNX_MATCH_DATA*)eval_data->pomd, pattern_size, otn); - } + if ( !eval_data->flowbit_noalert ) + fpAddMatch((OTNX_MATCH_DATA*)pomd, pattern_size, otn); + result = rval = DETECTION_OPTION_MATCH; } } + + break; } - break; + case RULE_OPTION_TYPE_CONTENT: - if (node->evaluate) + if ( node->evaluate ) { - /* This will be set in the fast pattern matcher if we found - * a content and the rule option specifies not that - * content. Essentially we've already evaluated this rule - * option via the content option processing since only not - * contents that are not relative in any way will have this - * flag set */ - if (content_data->last_check) + // This will be set in the fast pattern matcher if we found + // a content and the rule option specifies not that + // content. Essentially we've already evaluated this rule + // option via the content option processing since only not + // contents that are not relative in any way will have this + // flag set + if ( content_data->last_check ) { - PmdLastCheck* last_check = - content_data->last_check + get_instance_id(); - - if ((last_check->ts.tv_sec == eval_data->p->pkth->ts.tv_sec) && - (last_check->ts.tv_usec == eval_data->p->pkth->ts.tv_usec) && - (last_check->packet_number == cur_eval_pkt_count) && - (last_check->rebuild_flag == (eval_data->p->packet_flags & - PKT_REBUILT_STREAM))) + auto last_check = content_data->last_check + get_instance_id(); + + if ( last_check->ts == p->pkth->ts && + last_check->packet_number == cur_eval_pkt_count && + last_check->rebuild_flag == (p->packet_flags & PKT_REBUILT_STREAM) ) { rval = DETECTION_OPTION_NO_MATCH; break; } } - rval = node->evaluate(node->option_data, cursor, eval_data->p); + + rval = node->evaluate(node->option_data, cursor, p); } + break; + case RULE_OPTION_TYPE_PCRE: - if (node->evaluate) - { - rval = node->evaluate(node->option_data, cursor, eval_data->p); - } + if ( node->evaluate ) + rval = node->evaluate(node->option_data, cursor, p); + break; + case RULE_OPTION_TYPE_FLOWBIT: - if (node->evaluate) + if ( node->evaluate ) { - flowbits_setoperation = FlowBits_SetOperation(node->option_data); - if (!flowbits_setoperation) - { - rval = node->evaluate(node->option_data, cursor, eval_data->p); - } - else - { - /* set to match so we don't bail early. */ + flowbits_setoperation = + FlowBits_SetOperation(node->option_data); + + if ( flowbits_setoperation ) + // set to match so we don't bail early rval = DETECTION_OPTION_MATCH; - } + + else + rval = node->evaluate(node->option_data, cursor, eval_data->p); } + break; + default: - if (node->evaluate) - rval = node->evaluate(node->option_data, cursor, eval_data->p); + if ( node->evaluate ) + rval = node->evaluate(node->option_data, cursor, p); + break; + } - if (rval == DETECTION_OPTION_NO_MATCH) + if ( rval == DETECTION_OPTION_NO_MATCH ) { state->last_check.result = result; - NODE_PROFILE_END_NOMATCH(node); return result; } - else if (rval == DETECTION_OPTION_FAILED_BIT) + + else if ( rval == DETECTION_OPTION_FAILED_BIT ) { eval_data->flowbit_failed = 1; - /* clear the timestamp so failed flowbit gets eval'd again */ + // clear the timestamp so failed flowbit gets eval'd again state->last_check.flowbit_failed = 1; state->last_check.result = result; - NODE_PROFILE_END_NOMATCH(node); return 0; } - else if (rval == DETECTION_OPTION_NO_ALERT) + + else if ( rval == DETECTION_OPTION_NO_ALERT ) { - /* Cache the current flowbit_noalert flag, and set it - * so nodes below this don't alert. */ + // Cache the current flowbit_noalert flag, and set it + // so nodes below this don't alert. tmp_noalert_flag = eval_data->flowbit_noalert; eval_data->flowbit_noalert = 1; } - /* Back up byte_extract vars so they don't get overwritten between rules */ - for (i = 0; i < NUM_BYTE_EXTRACT_VARS; i++) - { + // Back up byte_extract vars so they don't get overwritten between rules + for ( int i = 0; i < NUM_BYTE_EXTRACT_VARS; ++i ) GetByteExtractValue(&(tmp_byte_extract_vars[i]), (int8_t)i); - } #ifdef PPM_MGR if ( PPM_PKTS_ENABLED() ) @@ -595,193 +609,179 @@ int detection_option_node_evaluate( PPM_PACKET_TEST(); if ( PPM_PACKET_ABORT_FLAG() ) { - /* bail if we exceeded time */ - if (result == DETECTION_OPTION_NO_MATCH) - { - NODE_PROFILE_END_NOMATCH(node); - } - else - { - NODE_PROFILE_END_MATCH(node); - } + // bail if we exceeded time + + if ( result != DETECTION_OPTION_NO_MATCH ) + NODE_PERF_PROFILE_STOP_MATCH(node_stats); + state->last_check.result = result; return result; } } #endif - /* Don't include children's time in this node */ - NODE_PROFILE_TMPEND(node); - /* Passed, check the children. */ - if (node->num_children) + PERF_PAUSE_BLOCK(node_stats) { - for (i=0; inum_children; i++) + // Passed, check the children. + if ( node->num_children ) { - int j = 0; - detection_option_tree_node_t* child_node = node->children[i]; - dot_node_state_t* child_state = child_node->state + get_instance_id(); - - for (j = 0; j < NUM_BYTE_EXTRACT_VARS; j++) + for ( int i = 0; i < node->num_children; ++i ) { - SetByteExtractValue(tmp_byte_extract_vars[j], (int8_t)j); - } + detection_option_tree_node_t* child_node = + node->children[i]; - if (loop_count > 0) - { - if (child_state->result == DETECTION_OPTION_NO_MATCH) + dot_node_state_t* child_state = + child_node->state + get_instance_id(); + + for ( int j = 0; j < NUM_BYTE_EXTRACT_VARS; ++j ) + SetByteExtractValue(tmp_byte_extract_vars[j], (int8_t)j); + + if ( loop_count > 0 ) { - if (((child_node->option_type == RULE_OPTION_TYPE_CONTENT) - || (child_node->option_type == RULE_OPTION_TYPE_PCRE)) - && !child_node->is_relative) + if ( child_state->result == DETECTION_OPTION_NO_MATCH ) { - /* If it's a non-relative content or pcre, no reason - * to check again. Only increment result once. - * Should hit this condition on first loop iteration. */ - if (loop_count == 1) - result++; - continue; - } - else if ((child_node->option_type == RULE_OPTION_TYPE_CONTENT) - && child_node->is_relative) - { - /* Check for an unbounded relative search. If this - * failed before, it's going to fail again so don't - * go down this path again */ - if ( is_unbounded(child_node->option_data) ) + if ( (child_node->option_type == RULE_OPTION_TYPE_CONTENT || + child_node->option_type == RULE_OPTION_TYPE_PCRE) && + !child_node->is_relative ) { - /* Only increment result once. Should hit this - * condition on first loop iteration. */ - if (loop_count == 1) - result++; + // If it's a non-relative content or pcre, no reason + // to check again. Only increment result once. + // Should hit this condition on first loop iteration. + if ( loop_count == 1 ) + ++result; + continue; } + + else if ( child_node->option_type == RULE_OPTION_TYPE_CONTENT && + child_node->is_relative ) + { + // Check for an unbounded relative search. If this + // failed before, it's going to fail again so don't + // go down this path again + if ( is_unbounded(child_node->option_data) ) + { + // Only increment result once. Should hit this + // condition on first loop iteration + if (loop_count == 1) + ++result; + + continue; + } + } } + + else if ( child_node->option_type == RULE_OPTION_TYPE_LEAF_NODE ) + // Leaf node matched, don't eval again + continue; + + else if ( child_state->result == child_node->num_children ) + // This branch of the tree matched or has options that + // don't need to be evaluated again, so don't need to + // evaluate this option again + continue; } - else if (child_node->option_type == RULE_OPTION_TYPE_LEAF_NODE) - { - /* Leaf node matched, don't eval again */ - continue; - } - else if (child_state->result == child_node->num_children) - { - /* This branch of the tree matched or has options that - * don't need to be evaluated again, so don't need to - * evaluate this option again */ - continue; - } - } - child_state->result = detection_option_node_evaluate( - node->children[i], eval_data, cursor); + child_state->result = detection_option_node_evaluate( + node->children[i], eval_data, cursor); - if (child_node->option_type == RULE_OPTION_TYPE_LEAF_NODE) - { - /* Leaf node won't have any children but will return success - * or failure */ - result += child_state->result; - } - else if (child_state->result == child_node->num_children) - { - /* Indicate that the child's tree branches are done */ - result++; - } + if ( child_node->option_type == RULE_OPTION_TYPE_LEAF_NODE ) + // Leaf node won't have any children but will return success + // or failure + result += child_state->result; + + else if (child_state->result == child_node->num_children) + // Indicate that the child's tree branches are done + ++result; #ifdef PPM_MGR - if ( PPM_PKTS_ENABLED() ) - { - PPM_GET_TIME(); - PPM_PACKET_TEST(); - if ( PPM_PACKET_ABORT_FLAG() ) + if ( PPM_PKTS_ENABLED() ) { - /* bail if we exceeded time */ - state->last_check.result = result; - return result; + PPM_GET_TIME(); + PPM_PACKET_TEST(); + if ( PPM_PACKET_ABORT_FLAG() ) + { + // bail if we exceeded time + state->last_check.result = result; + return result; + } } - } #endif - } - - /* If all children branches matched, we don't need to reeval any of - * the children so don't need to reeval this content/pcre rule - * option at a new offset. - * Else, reset the DOE ptr to last eval for offset/depth, - * distance/within adjustments for this same content/pcre - * rule option */ - if (result == node->num_children) - continue_loop = 0; + } - /* Don't need to reset since it's only checked after we've gone - * through the loop at least once and the result will have - * been set again already */ - //for (i = 0; i < node->num_children; i++) - // node->children[i]->result; + // If all children branches matched, we don't need to reeval any of + // the children so don't need to reeval this content/pcre rule + // option at a new offset. + // Else, reset the DOE ptr to last eval for offset/depth, + // distance/within adjustments for this same content/pcre + // rule option + if ( result == node->num_children ) + continue_loop = 0; + + // Don't need to reset since it's only checked after we've gone + // through the loop at least once and the result will have + // been set again already + //for (i = 0; i < node->num_children; i++) + // node->children[i]->result; + } } - NODE_PROFILE_TMPSTART(node); - - if (rval == DETECTION_OPTION_NO_ALERT) + if ( rval == DETECTION_OPTION_NO_ALERT ) { - /* Reset the flowbit_noalert flag in eval data */ + // Reset the flowbit_noalert flag in eval data eval_data->flowbit_noalert = tmp_noalert_flag; } - if (continue_loop && (rval == DETECTION_OPTION_MATCH) && (node->relative_children)) + if ( continue_loop && + rval == DETECTION_OPTION_MATCH && + node->relative_children ) { if ( node->option_type == RULE_OPTION_TYPE_CONTENT ) - { continue_loop = content_next(content_data); - } + else if (node->option_type == RULE_OPTION_TYPE_PCRE) - { continue_loop = pcre_next(pcre_data); - } + else - { continue_loop = 0; - } } + else - { continue_loop = 0; - } #ifdef PERF_PROFILING - /* We're essentially checking this node again and it potentially - * might match again */ - if (continue_loop && PROFILING_RULES) + // We're essentially checking this node again and it potentially + // might match again + if ( continue_loop && PROFILING_RULES ) state->checks++; #endif loop_count++; } - while (continue_loop); - if (flowbits_setoperation && (result == DETECTION_OPTION_MATCH)) + // FIXIT-H What's the point of this? + // either it infinite loops, or effective no-op + while ( continue_loop ); + + if ( flowbits_setoperation && result == DETECTION_OPTION_MATCH ) { - /* Do any setting/clearing/resetting/toggling of flowbits here - * given that other rule options matched. */ - rval = node->evaluate(node->option_data, cursor, eval_data->p); - if (rval != DETECTION_OPTION_MATCH) - { + // Do any setting/clearing/resetting/toggling of flowbits here + // given that other rule options matched + rval = node->evaluate(node->option_data, cursor, p); + if ( rval != DETECTION_OPTION_MATCH ) result = rval; - } } - if (eval_data->flowbit_failed) + if ( eval_data->flowbit_failed ) { - /* something deeper in the tree failed a flowbit test, we may need to - * reeval this node. */ + // something deeper in the tree failed a flowbit test, we may need to + // reeval this node state->last_check.flowbit_failed = 1; } + state->last_check.result = result; - if (result == DETECTION_OPTION_NO_MATCH) - { - NODE_PROFILE_END_NOMATCH(node); - } - else - { - NODE_PROFILE_END_MATCH(node); - } + if ( result != DETECTION_OPTION_NO_MATCH ) + NODE_PERF_PROFILE_STOP_MATCH(node_stats); return result; } diff --git a/src/detection/detection_options.h b/src/detection/detection_options.h index 83bb1aae4..f0ad3b1d1 100644 --- a/src/detection/detection_options.h +++ b/src/detection/detection_options.h @@ -68,6 +68,20 @@ struct dot_node_state_t uint64_t ppm_disable_cnt; uint64_t ppm_enable_cnt; #endif + +#ifdef PERF_PROFILING + void update(uint64_t elapsed, bool match) + { + ticks += elapsed; + + if ( match ) + ticks_match += elapsed; + else + ticks_no_match += elapsed; + + ++checks; + } +#endif }; struct detection_option_tree_node_t diff --git a/src/detection/fp_detect.cc b/src/detection/fp_detect.cc index 234b9605e..70a1acaad 100644 --- a/src/detection/fp_detect.cc +++ b/src/detection/fp_detect.cc @@ -244,7 +244,10 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p) fpLogOther(p, rtn, otn, rtn->type); return 1; } - OTN_PROFILE_ALERT(otn); + +#ifdef PERF_PROFILING + otn->state[get_instance_id()].alerts++; +#endif event_id++; action_execute((RuleType)action, p, otn, event_id); @@ -368,17 +371,12 @@ int fpAddMatch(OTNX_MATCH_DATA* omd_local, int pLen, const OptTreeNode* otn) */ int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports) { - PROFILE_VARS; - - MODULE_PROFILE_START(ruleRTNEvalPerfStats); + PERF_PROFILE(ruleRTNEvalPerfStats); if ( !rtn ) - { - MODULE_PROFILE_END(ruleRTNEvalPerfStats); return 0; - } - /* FIXIT: maybe add a port test here ... */ + // FIXIT: maybe add a port test here ... DebugFormat(DEBUG_DETECT, "[*] Rule Head %p\n", rtn); @@ -388,7 +386,6 @@ int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports) " => Header check failed, checking next node\n"); DebugMessage(DEBUG_DETECT, " => returned from next node check\n"); - MODULE_PROFILE_END(ruleRTNEvalPerfStats); return 0; } @@ -401,7 +398,6 @@ int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports) ** Return that there is a rule match and log the event outside ** of this routine. */ - MODULE_PROFILE_END(ruleRTNEvalPerfStats); return 1; } @@ -409,13 +405,11 @@ static int detection_option_tree_evaluate( detection_option_tree_root_t* root, detection_option_eval_data_t* eval_data) { - int i, rval = 0; - PROFILE_VARS; + PERF_PROFILE(ruleOTNEvalPerfStats); if (!root) return 0; - MODULE_PROFILE_START(ruleOTNEvalPerfStats); /* Not really OTN, but close */ #ifdef PPM_MGR /* Start Rule Timer */ @@ -440,7 +434,8 @@ static int detection_option_tree_evaluate( Cursor c(eval_data->p); - for ( i = 0; i< root->num_children; i++) + int rval = 0; + for ( int i = 0; i< root->num_children; i++) { /* Increment number of events generated from that child */ rval += detection_option_node_evaluate(root->children[i], eval_data, c); @@ -464,7 +459,6 @@ static int detection_option_tree_evaluate( } #endif - MODULE_PROFILE_END(ruleOTNEvalPerfStats); return rval; } @@ -476,8 +470,6 @@ static int rule_tree_match(void* id, void* tree, int index, void* data, void* ne detection_option_tree_root_t* root = (detection_option_tree_root_t*)tree; detection_option_eval_data_t eval_data; NCListNode* ncl; - int rval=0; - PROFILE_VARS; eval_data.pomd = pomd; eval_data.p = pomd->p; @@ -485,47 +477,44 @@ static int rule_tree_match(void* id, void* tree, int index, void* data, void* ne eval_data.flowbit_failed = 0; eval_data.flowbit_noalert = 0; - MODULE_PROFILE_START(rulePerfStats); - - /* NOTE: The otn will be the first one in the match state. If there are - * multiple rules associated with a match state, mucking with the otn - * may muck with an unintended rule */ - - /* Set flag for not contents so they aren't evaluated */ - for (ncl = (NCListNode*)neg_list; ncl != nullptr; ncl = ncl->next) + PERF_PROFILE_BLOCK(rulePerfStats) { - PMX* neg_pmx = (PMX*)ncl->pmx; - PatternMatchData* neg_pmd = (PatternMatchData*)neg_pmx->PatternMatchData; + /* NOTE: The otn will be the first one in the match state. If there are + * multiple rules associated with a match state, mucking with the otn + * may muck with an unintended rule */ - assert(neg_pmd->last_check); + /* Set flag for not contents so they aren't evaluated */ + for (ncl = (NCListNode*)neg_list; ncl != nullptr; ncl = ncl->next) + { + PMX* neg_pmx = (PMX*)ncl->pmx; + PatternMatchData* neg_pmd = (PatternMatchData*)neg_pmx->PatternMatchData; - PmdLastCheck* last_check = - neg_pmd->last_check + get_instance_id(); + assert(neg_pmd->last_check); - last_check->ts.tv_sec = eval_data.p->pkth->ts.tv_sec; - last_check->ts.tv_usec = eval_data.p->pkth->ts.tv_usec; - last_check->packet_number = (rule_eval_pkt_count - + (PacketManager::get_rebuilt_packet_count())); - last_check->rebuild_flag = (eval_data.p->packet_flags & PKT_REBUILT_STREAM); - } + PmdLastCheck* last_check = + neg_pmd->last_check + get_instance_id(); - rval = detection_option_tree_evaluate(root, &eval_data); + last_check->ts.tv_sec = eval_data.p->pkth->ts.tv_sec; + last_check->ts.tv_usec = eval_data.p->pkth->ts.tv_usec; + last_check->packet_number = (rule_eval_pkt_count + + (PacketManager::get_rebuilt_packet_count())); + last_check->rebuild_flag = (eval_data.p->packet_flags & PKT_REBUILT_STREAM); + } - if (rval) - { - // We have a qualified event from this tree - pomd->pg->event_count++; - UpdateQEvents(&sfEvent); - } - else - { - // This means that the event is non-qualified. - pomd->pg->match_count++; - UpdateNQEvents(&sfEvent); + if ( detection_option_tree_evaluate(root, &eval_data) ) + { + // We have a qualified event from this tree + pomd->pg->event_count++; + UpdateQEvents(&sfEvent); + } + else + { + // This means that the event is non-qualified. + pomd->pg->match_count++; + UpdateNQEvents(&sfEvent); + } } - MODULE_PROFILE_END(rulePerfStats); - if (eval_data.flowbit_failed) return -1; @@ -980,7 +969,6 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p, bool repeat = false; uint16_t tmp_dsize; FastPatternConfig* fp = snort_conf->fast_pattern_config; - PROFILE_VARS; if (ip_rule) { @@ -1030,7 +1018,6 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p, LogMessage("NC-testing %u rules\n", port_group->nfp_rule_count); detection_option_eval_data_t eval_data; - int rval; eval_data.pomd = omd; eval_data.p = p; @@ -1038,10 +1025,14 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p, eval_data.flowbit_failed = 0; eval_data.flowbit_noalert = 0; - MODULE_PROFILE_START(ncrulePerfStats); - rval = detection_option_tree_evaluate( - (detection_option_tree_root_t*)port_group->nfp_tree, &eval_data); - MODULE_PROFILE_END(ncrulePerfStats); + int rval = 0; + + PERF_PROFILE_BLOCK(ncrulePerfStats) + { + rval = detection_option_tree_evaluate( + (detection_option_tree_root_t*)port_group->nfp_tree, + &eval_data); + } if (rval) { diff --git a/src/framework/mpse.cc b/src/framework/mpse.cc index 48d038d93..a5bf46965 100644 --- a/src/framework/mpse.cc +++ b/src/framework/mpse.cc @@ -50,15 +50,13 @@ int Mpse::search( const unsigned char* T, int n, MpseMatch match, void* data, int* current_state) { - PROFILE_VARS; - MODULE_PROFILE_START(mpsePerfStats); + PERF_PROFILE(mpsePerfStats); int ret = _search(T, n, match, data, current_state); if ( inc_global_counter ) s_bcnt += n; - MODULE_PROFILE_END(mpsePerfStats); return ret; } diff --git a/src/ips_options/ips_ack.cc b/src/ips_options/ips_ack.cc index b6735c4cc..e7b00b392 100644 --- a/src/ips_options/ips_ack.cc +++ b/src/ips_options/ips_ack.cc @@ -92,19 +92,12 @@ bool TcpAckOption::operator==(const IpsOption& ips) const int TcpAckOption::eval(Cursor&, Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(tcpAckPerfStats); - - int rval; + PERF_PROFILE(tcpAckPerfStats); if ( p->ptrs.tcph && config.eval(p->ptrs.tcph->th_ack) ) - rval = DETECTION_OPTION_MATCH; - - else - rval = DETECTION_OPTION_NO_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(tcpAckPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_asn1.cc b/src/ips_options/ips_asn1.cc index 35b1ea59f..43b9838f2 100644 --- a/src/ips_options/ips_asn1.cc +++ b/src/ips_options/ips_asn1.cc @@ -167,23 +167,16 @@ bool Asn1Option::operator==(const IpsOption& rhs) const int Asn1Option::eval(Cursor& c, Packet* p) { - PROFILE_VARS; + PERF_PROFILE(asn1PerfStats); - /* - ** Failed if there is no data to decode. - */ + // Failed if there is no data to decode. if (!p->data) return DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_START(asn1PerfStats); if ( Asn1DoDetect(c.buffer(), c.size(), &config, c.start()) ) - { - MODULE_PROFILE_END(asn1PerfStats); return DETECTION_OPTION_MATCH; - } - MODULE_PROFILE_END(asn1PerfStats); return DETECTION_OPTION_NO_MATCH; } diff --git a/src/ips_options/ips_base64.cc b/src/ips_options/ips_base64.cc index 7787498e3..46030762b 100644 --- a/src/ips_options/ips_base64.cc +++ b/src/ips_options/ips_base64.cc @@ -126,17 +126,15 @@ bool Base64DecodeOption::operator==(const IpsOption& ips) const int Base64DecodeOption::eval(Cursor& c, Packet*) { - int rval = DETECTION_OPTION_NO_MATCH; - const uint8_t* start_ptr; - unsigned size; - uint8_t base64_buf[DECODE_BLEN]; - uint32_t base64_size =0; + PERF_PROFILE(base64PerfStats); + - PROFILE_VARS; - MODULE_PROFILE_START(base64PerfStats); base64_decode_size = 0; + Base64DecodeData* idx = (Base64DecodeData*)&config; + const uint8_t* start_ptr = nullptr; + unsigned size = 0; if (idx->flags & BASE64DECODE_RELATIVE_FLAG) { @@ -150,18 +148,16 @@ int Base64DecodeOption::eval(Cursor& c, Packet*) } if ( idx->offset >= size ) - { - MODULE_PROFILE_END(base64PerfStats); - return rval; - } + return DETECTION_OPTION_NO_MATCH; + start_ptr += idx->offset; size -= idx->offset; + uint8_t base64_buf[DECODE_BLEN]; + uint32_t base64_size = 0; + if (sf_unfold_header(start_ptr, size, base64_buf, sizeof(base64_buf), &base64_size, 0, 0) != 0) - { - MODULE_PROFILE_END(base64PerfStats); - return rval; - } + return DETECTION_OPTION_NO_MATCH; if (idx->bytes_to_decode && (base64_size > idx->bytes_to_decode)) { @@ -170,12 +166,7 @@ int Base64DecodeOption::eval(Cursor& c, Packet*) if (sf_base64decode(base64_buf, base64_size, (uint8_t*)base64_decode_buf, sizeof(base64_decode_buf), &base64_decode_size) != 0) - { - MODULE_PROFILE_END(base64PerfStats); - return rval; - } - - MODULE_PROFILE_END(base64PerfStats); + return DETECTION_OPTION_NO_MATCH; return DETECTION_OPTION_MATCH; } @@ -305,22 +296,14 @@ public: int Base64DataOption::eval(Cursor& c, Packet*) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; - - MODULE_PROFILE_START(base64PerfStats); + PERF_PROFILE(base64PerfStats); if ( !base64_decode_size ) - { - MODULE_PROFILE_END(base64PerfStats); - return rval; - } + return DETECTION_OPTION_NO_MATCH; c.set(s_data_name, base64_decode_buf, base64_decode_size); - rval = DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(base64PerfStats); - return rval; + return DETECTION_OPTION_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_bufferlen.cc b/src/ips_options/ips_bufferlen.cc index b9139b5ed..81e055b13 100644 --- a/src/ips_options/ips_bufferlen.cc +++ b/src/ips_options/ips_bufferlen.cc @@ -87,16 +87,12 @@ bool LenOption::operator==(const IpsOption& ips) const int LenOption::eval(Cursor& c, Packet*) { - int rval = DETECTION_OPTION_NO_MATCH; - - PROFILE_VARS; - MODULE_PROFILE_START(lenCheckPerfStats); + PERF_PROFILE(lenCheckPerfStats); if ( config.eval(c.length()) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(lenCheckPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_byte_extract.cc b/src/ips_options/ips_byte_extract.cc index 5121937f6..8558a992b 100644 --- a/src/ips_options/ips_byte_extract.cc +++ b/src/ips_options/ips_byte_extract.cc @@ -144,18 +144,12 @@ bool ByteExtractOption::operator==(const IpsOption& ips) const int ByteExtractOption::eval(Cursor& c, Packet* p) { - ByteExtractData* data = &config; - int ret, bytes_read; - uint32_t* value; + PERF_PROFILE(byteExtractPerfStats); - PROFILE_VARS; - MODULE_PROFILE_START(byteExtractPerfStats); + ByteExtractData* data = &config; if (data == NULL || p == NULL) - { - MODULE_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; - } const uint8_t* start = c.buffer(); int dsize = c.size(); @@ -164,34 +158,30 @@ int ByteExtractOption::eval(Cursor& c, Packet* p) ptr += data->offset; const uint8_t* end = start + dsize; - value = &(extracted_values[data->var_number]); + uint32_t* value = &(extracted_values[data->var_number]); - /* check bounds */ + // check bounds if (ptr < start || ptr >= end) - { - MODULE_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; - } - /* do the extraction */ + // do the extraction + int ret = 0; + int bytes_read = 0; + if (data->data_string_convert_flag == 0) { ret = byte_extract(data->endianess, data->bytes_to_grab, ptr, start, end, value); if (ret < 0) - { - MODULE_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; - } + bytes_read = data->bytes_to_grab; } else { ret = string_extract(data->bytes_to_grab, data->base, ptr, start, end, value); if (ret < 0) - { - MODULE_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_NO_MATCH; - } + bytes_read = ret; } @@ -212,7 +202,6 @@ int ByteExtractOption::eval(Cursor& c, Packet* p) c.add_pos(bytes_read); /* this rule option always "matches" if the read is performed correctly */ - MODULE_PROFILE_END(byteExtractPerfStats); return DETECTION_OPTION_MATCH; } diff --git a/src/ips_options/ips_byte_jump.cc b/src/ips_options/ips_byte_jump.cc index c7391a875..b4450c20d 100644 --- a/src/ips_options/ips_byte_jump.cc +++ b/src/ips_options/ips_byte_jump.cc @@ -198,16 +198,13 @@ bool ByteJumpOption::operator==(const IpsOption& ips) const int ByteJumpOption::eval(Cursor& c, Packet*) { + PERF_PROFILE(byteJumpPerfStats); + ByteJumpData* bjd = (ByteJumpData*)&config; - int rval = DETECTION_OPTION_NO_MATCH; - uint32_t jump = 0; - uint32_t payload_bytes_grabbed = 0; - int32_t offset; - PROFILE_VARS; - MODULE_PROFILE_START(byteJumpPerfStats); + int32_t offset = 0; - /* Get values from byte_extract variables, if present. */ + // Get values from byte_extract variables, if present. if (bjd->offset_var >= 0 && bjd->offset_var < NUM_BYTE_EXTRACT_VARS) { uint32_t extract_offset; @@ -225,17 +222,17 @@ int ByteJumpOption::eval(Cursor& c, Packet*) const uint8_t* const base_ptr = offset + ((bjd->relative_flag) ? c.start() : start_ptr); - /* Both of the extraction functions contain checks to ensure the data - * is inbounds and will return no match if it isn't */ + uint32_t jump = 0; + uint32_t payload_bytes_grabbed = 0; + + // Both of the extraction functions contain checks to ensure the data + // is inbounds and will return no match if it isn't if ( !bjd->data_string_convert_flag ) { if ( byte_extract( bjd->endianess, bjd->bytes_to_grab, base_ptr, start_ptr, end_ptr, &jump) ) - { - MODULE_PROFILE_END(byteJumpPerfStats); - return rval; - } + return DETECTION_OPTION_NO_MATCH; payload_bytes_grabbed = bjd->bytes_to_grab; } @@ -246,10 +243,8 @@ int ByteJumpOption::eval(Cursor& c, Packet*) base_ptr, start_ptr, end_ptr, &jump); if (tmp < 0) - { - MODULE_PROFILE_END(byteJumpPerfStats); - return rval; - } + return DETECTION_OPTION_NO_MATCH; + payload_bytes_grabbed = tmp; } // Negative offsets that put us outside the buffer should have been caught @@ -280,17 +275,9 @@ int ByteJumpOption::eval(Cursor& c, Packet*) jump += bjd->post_offset; if ( !c.set_pos(jump) ) - { - MODULE_PROFILE_END(byteJumpPerfStats); - return rval; - } - else - { - rval = DETECTION_OPTION_MATCH; - } + return DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_END(byteJumpPerfStats); - return rval; + return DETECTION_OPTION_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_byte_test.cc b/src/ips_options/ips_byte_test.cc index e8400b01e..673a85079 100644 --- a/src/ips_options/ips_byte_test.cc +++ b/src/ips_options/ips_byte_test.cc @@ -138,6 +138,7 @@ typedef struct _ByteTestData { uint32_t bytes_to_compare; uint32_t cmp_value; + // FIXIT-L should be an enum uint32_t opcode; int32_t offset; uint8_t not_flag; @@ -149,6 +150,69 @@ typedef struct _ByteTestData int8_t offset_var; } ByteTestData; +// ----------------------------------------------------------------------------- +// static functions +// ----------------------------------------------------------------------------- + +static inline bool byte_test_check(uint32_t op, uint32_t val, uint32_t cmp, bool not_flag) +{ + bool success = false; + + switch ( op ) + { + case CHECK_LT: + success = (val < cmp); + break; + + case CHECK_EQ: + success = (val == cmp); + break; + + case CHECK_GT: + success = (val > cmp); + break; + + case CHECK_AND: + success = ((val & cmp) > 0); + break; + + case CHECK_XOR: + success = ((val ^ cmp) > 0); + break; + + case CHECK_GTE: + success = (val >= cmp); + break; + + case CHECK_LTE: + success = (val <= cmp); + break; + + case CHECK_ALL: + success = ((val & cmp) == cmp); + break; + + case CHECK_GT0: + success = ((val & cmp) != 0); + break; + + case CHECK_NONE: + success = ((val & cmp) == 0); + break; + } + + if ( not_flag ) + { + DebugMessage(DEBUG_PATTERN_MATCH, + "checking for not success...flag\n"); + + success = !success; + } + + return success; +} + + class ByteTestOption : public IpsOption { public: @@ -232,57 +296,46 @@ bool ByteTestOption::operator==(const IpsOption& ips) const int ByteTestOption::eval(Cursor& c, Packet*) { - ByteTestData* btd = (ByteTestData*)&config; - int rval = DETECTION_OPTION_NO_MATCH; - uint32_t value = 0; - int success = 0; - const uint8_t* start_ptr; - int payload_bytes_grabbed; - int offset; - uint32_t cmp_value; + PERF_PROFILE(byteTestPerfStats); - PROFILE_VARS; - MODULE_PROFILE_START(byteTestPerfStats); + ByteTestData* btd = (ByteTestData*)&config; + uint32_t cmp_value = 0; - /* Get values from byte_extract variables, if present. */ + // Get values from byte_extract variables, if present. if (btd->cmp_value_var >= 0 && btd->cmp_value_var < NUM_BYTE_EXTRACT_VARS) { uint32_t val; GetByteExtractValue(&val, btd->cmp_value_var); cmp_value = val; } + else cmp_value = btd->cmp_value; + int offset = 0; + if (btd->offset_var >= 0 && btd->offset_var < NUM_BYTE_EXTRACT_VARS) { uint32_t val; GetByteExtractValue(&val, btd->offset_var); offset = (int32_t)val; } - else - offset = btd->offset; - if ( btd->relative_flag ) - start_ptr = c.start(); else - start_ptr = c.buffer(); + offset = btd->offset; + const uint8_t* start_ptr = btd->relative_flag ? c.start() : c.buffer(); start_ptr += offset; - /* both of these functions below perform their own bounds checking within - * byte_extract.c - */ + uint32_t value = 0; + int payload_bytes_grabbed = 0; if (!btd->data_string_convert_flag) { if ( byte_extract( btd->endianess, btd->bytes_to_compare, start_ptr, c.buffer(), c.endo(), &value)) - { - MODULE_PROFILE_END(byteTestPerfStats); - return rval; - } + return DETECTION_OPTION_NO_MATCH; #ifdef DEBUG payload_bytes_grabbed = (int)btd->bytes_to_compare; #endif @@ -298,8 +351,7 @@ int ByteTestOption::eval(Cursor& c, Packet*) DebugMessage(DEBUG_PATTERN_MATCH, "String Extraction Failed\n"); - MODULE_PROFILE_END(byteTestPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } } @@ -307,66 +359,10 @@ int ByteTestOption::eval(Cursor& c, Packet*) "Grabbed %d bytes at offset %d, value = 0x%08X(%u)\n", payload_bytes_grabbed, btd->offset, value, value); - switch (btd->opcode) - { - case CHECK_LT: - success = (value < cmp_value); - break; - - case CHECK_EQ: - success = (value == cmp_value); - break; - - case CHECK_GT: - success = (value > cmp_value); - break; - - case CHECK_AND: - success = ((value & cmp_value) > 0); - break; - - case CHECK_XOR: - success = ((value ^ cmp_value) > 0); - break; - - case CHECK_GTE: - success = (value >= cmp_value); - break; - - case CHECK_LTE: - success = (value <= cmp_value); - break; - - case CHECK_ALL: - success = ((value & cmp_value) == cmp_value); - break; - - case CHECK_GT0: - success = ((value & cmp_value) != 0); - break; - - case CHECK_NONE: - success = ((value & cmp_value) == 0); - break; - } - - if (btd->not_flag) - { - DebugMessage(DEBUG_PATTERN_MATCH, - "checking for not success...flag\n"); - if (!success) - { - rval = DETECTION_OPTION_MATCH; - } - } - else if (success) - { - rval = DETECTION_OPTION_MATCH; - } + if ( byte_test_check(btd->opcode, value, cmp_value, btd->not_flag) ) + return DETECTION_OPTION_MATCH; - /* if the test isn't successful, this function *must* return 0 */ - MODULE_PROFILE_END(byteTestPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_content.cc b/src/ips_options/ips_content.cc index e4b70ac75..1c51f618c 100644 --- a/src/ips_options/ips_content.cc +++ b/src/ips_options/ips_content.cc @@ -401,15 +401,11 @@ static int uniSearchReal(PatternMatchData* pmd, Cursor& c) static int CheckANDPatternMatch(PatternMatchData* idx, Cursor& c) { - int rval = DETECTION_OPTION_NO_MATCH; - int found = 0; - - PROFILE_VARS; - MODULE_PROFILE_START(contentPerfStats); + PERF_PROFILE(contentPerfStats); DebugMessage(DEBUG_PATTERN_MATCH, "CheckPatternANDMatch: "); - found = uniSearchReal(idx, c); + int found = uniSearchReal(idx, c); if ( found == -1 ) { @@ -426,16 +422,15 @@ static int CheckANDPatternMatch(PatternMatchData* idx, Cursor& c) if ( found ) { - rval = DETECTION_OPTION_MATCH; DebugMessage(DEBUG_PATTERN_MATCH, "Pattern match found\n"); + return DETECTION_OPTION_MATCH; } + else { DebugMessage(DEBUG_PATTERN_MATCH, "Pattern match failed\n"); + return DETECTION_OPTION_NO_MATCH; } - - MODULE_PROFILE_END(contentPerfStats); - return rval; } PatternMatchData* content_get_data(void* pv) diff --git a/src/ips_options/ips_dsize.cc b/src/ips_options/ips_dsize.cc index 780c23339..878b82cd6 100644 --- a/src/ips_options/ips_dsize.cc +++ b/src/ips_options/ips_dsize.cc @@ -92,26 +92,17 @@ bool DsizeOption::operator==(const IpsOption& ips) const // Test the packet's payload size against the rule payload size value int DsizeOption::eval(Cursor&, Packet* p) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; - - MODULE_PROFILE_START(dsizePerfStats); + PERF_PROFILE(dsizePerfStats); /* fake packet dsizes are always wrong (unless they are PDUs) */ - if ( - (p->packet_flags & PKT_REBUILT_STREAM) && - !(p->packet_flags & PKT_PDU_HEAD) ) - { - MODULE_PROFILE_END(dsizePerfStats); - return rval; - } + if ((p->packet_flags & PKT_REBUILT_STREAM) && !p->is_pdu_start()) + return DETECTION_OPTION_NO_MATCH; if ( config.eval(p->dsize) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(dsizePerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_file_data.cc b/src/ips_options/ips_file_data.cc index bcb95e82d..eb99ac6ca 100644 --- a/src/ips_options/ips_file_data.cc +++ b/src/ips_options/ips_file_data.cc @@ -58,27 +58,17 @@ public: int FileDataOption::eval(Cursor& c, Packet*) { - int rval = DETECTION_OPTION_NO_MATCH; - uint8_t* data; - uint16_t len; + PERF_PROFILE(fileDataPerfStats); - PROFILE_VARS; - MODULE_PROFILE_START(fileDataPerfStats); + uint8_t* data = g_file_data.data; + uint16_t len = g_file_data.len; - data = g_file_data.data; - len = g_file_data.len; - - if ( (data == NULL)|| (len == 0) ) - { - MODULE_PROFILE_END(fileDataPerfStats); - return rval; - } + if ( !data || !len ) + return DETECTION_OPTION_NO_MATCH; c.set(s_name, data, len); - rval = DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(fileDataPerfStats); - return rval; + return DETECTION_OPTION_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_flags.cc b/src/ips_options/ips_flags.cc index 349e2fbc6..454c2c893 100644 --- a/src/ips_options/ips_flags.cc +++ b/src/ips_options/ips_flags.cc @@ -122,25 +122,18 @@ bool TcpFlagOption::operator==(const IpsOption& ips) const int TcpFlagOption::eval(Cursor&, Packet* p) { - TcpFlagCheckData* flagptr = &config; - int rval = DETECTION_OPTION_NO_MATCH; - u_char tcp_flags; - PROFILE_VARS; - - MODULE_PROFILE_START(tcpFlagsPerfStats); + PERF_PROFILE(tcpFlagsPerfStats); + // if error appeared when tcp header was processed, + // test fails automagically. if (!p->ptrs.tcph) - { - /* if error appeared when tcp header was processed, - * test fails automagically */ - MODULE_PROFILE_END(tcpFlagsPerfStats); - return rval; - } + return DETECTION_OPTION_NO_MATCH; /* the flags we really want to check are all the ones */ - tcp_flags = p->ptrs.tcph->th_flags & (0xFF ^ flagptr->tcp_mask); + TcpFlagCheckData* flagptr = &config; + u_char tcp_flags = p->ptrs.tcph->th_flags & (0xFF ^ flagptr->tcp_mask); DebugMessage(DEBUG_IPS_OPTION, " CheckTcpFlags: "); @@ -150,7 +143,7 @@ int TcpFlagOption::eval(Cursor&, Packet* p) if (flagptr->tcp_flags == tcp_flags) /* only these set */ { DebugMessage(DEBUG_IPS_OPTION,"Got TCP [default] flag match!\n"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } else { @@ -163,7 +156,7 @@ int TcpFlagOption::eval(Cursor&, Packet* p) if ((flagptr->tcp_flags & tcp_flags) == flagptr->tcp_flags) { DebugMessage(DEBUG_IPS_OPTION, "Got TCP [ALL] flag match!\n"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } else { @@ -175,7 +168,7 @@ int TcpFlagOption::eval(Cursor&, Packet* p) if ((flagptr->tcp_flags & tcp_flags) == 0) /* none set */ { DebugMessage(DEBUG_IPS_OPTION,"Got TCP [NOT] flag match!\n"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } else { @@ -187,7 +180,7 @@ int TcpFlagOption::eval(Cursor&, Packet* p) if ((flagptr->tcp_flags & tcp_flags) != 0) /* something set */ { DebugMessage(DEBUG_IPS_OPTION,"Got TCP [ANY] flag match!\n"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } else { @@ -201,8 +194,7 @@ int TcpFlagOption::eval(Cursor&, Packet* p) break; } - MODULE_PROFILE_END(tcpFlagsPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_flow.cc b/src/ips_options/ips_flow.cc index 81eb23968..75e697502 100644 --- a/src/ips_options/ips_flow.cc +++ b/src/ips_options/ips_flow.cc @@ -124,67 +124,55 @@ bool FlowCheckOption::operator==(const IpsOption& ips) const int FlowCheckOption::eval(Cursor&, Packet* p) { - FlowCheckData* fcd = &config; - PROFILE_VARS; + PERF_PROFILE(flowCheckPerfStats); - MODULE_PROFILE_START(flowCheckPerfStats); + FlowCheckData* fcd = &config; - /* Check established/unestablished first */ + // Check established/unestablished first { if ((fcd->established == 1) && !(p->packet_flags & PKT_STREAM_EST)) { - /* - ** This option requires an established connection and it isn't - ** in that state yet, so no match. - */ - MODULE_PROFILE_END(flowCheckPerfStats); + // This option requires an established connection and it isn't + // in that state yet, so no match. return DETECTION_OPTION_NO_MATCH; } else if ((fcd->unestablished == 1) && (p->packet_flags & PKT_STREAM_EST)) { - /* - ** We're looking for an unestablished stream, and this is - ** established, so don't continue processing. - */ - MODULE_PROFILE_END(flowCheckPerfStats); + // We're looking for an unestablished stream, and this is + // established, so don't continue processing. return DETECTION_OPTION_NO_MATCH; } } - /* Now check from client */ + // Now check from client if (fcd->from_client) { { - if (!(p->packet_flags & PKT_FROM_CLIENT) && - (p->packet_flags & PKT_FROM_SERVER)) + if (!p->from_client() && p->from_server()) { - /* No match on from_client */ - MODULE_PROFILE_END(flowCheckPerfStats); + // No match on from_client return DETECTION_OPTION_NO_MATCH; } } } - /* And from server */ + // And from server if (fcd->from_server) { { - if (!(p->packet_flags & PKT_FROM_SERVER) && - (p->packet_flags & PKT_FROM_CLIENT)) + if (!p->from_server() && p->from_client()) { - /* No match on from_server */ - MODULE_PROFILE_END(flowCheckPerfStats); + // No match on from_server return DETECTION_OPTION_NO_MATCH; } } } - /* ...ignore_reassembled */ + // ...ignore_reassembled if (fcd->ignore_reassembled & IGNORE_STREAM) { if (p->packet_flags & PKT_REBUILT_STREAM) { - MODULE_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } @@ -193,17 +181,15 @@ int FlowCheckOption::eval(Cursor&, Packet* p) { if (p->packet_flags & PKT_REBUILT_FRAG) { - MODULE_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } - /* ...only_reassembled */ + // ...only_reassembled if (fcd->only_reassembled & ONLY_STREAM) { if ( !(p->packet_flags & PKT_REBUILT_STREAM) && !p->is_full_pdu() ) { - MODULE_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } @@ -212,12 +198,10 @@ int FlowCheckOption::eval(Cursor&, Packet* p) { if (!(p->packet_flags & PKT_REBUILT_FRAG)) { - MODULE_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_NO_MATCH; } } - MODULE_PROFILE_END(flowCheckPerfStats); return DETECTION_OPTION_MATCH; } diff --git a/src/ips_options/ips_flowbits.cc b/src/ips_options/ips_flowbits.cc index 949bbe3e1..1fd63b8e4 100644 --- a/src/ips_options/ips_flowbits.cc +++ b/src/ips_options/ips_flowbits.cc @@ -256,21 +256,16 @@ bool FlowBitsOption::operator==(const IpsOption& ips) const int FlowBitsOption::eval(Cursor&, Packet* p) { - FLOWBITS_OP* flowbits = config; - int rval = DETECTION_OPTION_NO_MATCH; + PERF_PROFILE(flowBitsPerfStats); - PROFILE_VARS; + FLOWBITS_OP* flowbits = config; if (!flowbits) - return rval; + return DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_START(flowBitsPerfStats); - rval = check_flowbits(flowbits->type, (uint8_t)flowbits->eval, + return check_flowbits(flowbits->type, (uint8_t)flowbits->eval, flowbits->ids, flowbits->num_ids, flowbits->group, p); - - MODULE_PROFILE_END(flowBitsPerfStats); - return rval; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_fragbits.cc b/src/ips_options/ips_fragbits.cc index 62754a127..e990b6de6 100644 --- a/src/ips_options/ips_fragbits.cc +++ b/src/ips_options/ips_fragbits.cc @@ -143,17 +143,16 @@ bool FragBitsOption::operator==(const IpsOption& ips) const int FragBitsOption::eval(Cursor&, Packet* p) { + PERF_PROFILE(fragBitsPerfStats); + FragBitsData* fb = &config; - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; - if(!p->ptrs.ip_api.is_ip()) - { - return rval; - } + if ( !p->has_ip() ) + return DETECTION_OPTION_NO_MATCH; + const uint16_t frag_offset = p->ptrs.ip_api.off_w_flags(); - MODULE_PROFILE_START(fragBitsPerfStats); + DebugMessage(DEBUG_IPS_OPTION, " CheckFragBits: "); DebugFormat(DEBUG_IPS_OPTION, "[rule: 0x%X:%d pkt: 0x%X] ", @@ -166,12 +165,13 @@ int FragBitsOption::eval(Cursor&, Packet* p) if (fb->frag_bits == (frag_offset & bitmask)) { DebugMessage(DEBUG_IPS_OPTION,"Got Normal bits match\n"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } else { DebugMessage(DEBUG_IPS_OPTION,"Normal test failed\n"); } + break; case FB_NOT: @@ -179,7 +179,7 @@ int FragBitsOption::eval(Cursor&, Packet* p) if ((fb->frag_bits & (frag_offset & bitmask)) == 0) { DebugMessage(DEBUG_IPS_OPTION,"Got NOT bits match\n"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } else { @@ -192,7 +192,7 @@ int FragBitsOption::eval(Cursor&, Packet* p) if ((fb->frag_bits & (frag_offset & bitmask)) == fb->frag_bits) { DebugMessage(DEBUG_IPS_OPTION,"Got ALL bits match\n"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } else { @@ -205,20 +205,20 @@ int FragBitsOption::eval(Cursor&, Packet* p) if ((fb->frag_bits & (frag_offset & bitmask)) != 0) { DebugMessage(DEBUG_IPS_OPTION,"Got ANY bits match\n"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } else { DebugMessage(DEBUG_IPS_OPTION,"ANY test failed\n"); } break; + default: break; } /* if the test isn't successful, this function *must* return 0 */ - MODULE_PROFILE_END(fragBitsPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_fragoffset.cc b/src/ips_options/ips_fragoffset.cc index b1f467974..9056ff27b 100644 --- a/src/ips_options/ips_fragoffset.cc +++ b/src/ips_options/ips_fragoffset.cc @@ -88,22 +88,16 @@ bool FragOffsetOption::operator==(const IpsOption& ips) const int FragOffsetOption::eval(Cursor&, Packet* p) { - int p_offset = p->ptrs.ip_api.off(); - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; + PERF_PROFILE(fragOffsetPerfStats); if (!p->has_ip()) - { - return rval; - } + return DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_START(fragOffsetPerfStats); - if ( config.eval(p_offset) ) - rval = DETECTION_OPTION_MATCH; + if ( !config.eval(p->ptrs.ip_api.off()) ) + return DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_END(fragOffsetPerfStats); - return rval; + return DETECTION_OPTION_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_hash.cc b/src/ips_options/ips_hash.cc index 348b69e72..1f11229e1 100644 --- a/src/ips_options/ips_hash.cc +++ b/src/ips_options/ips_hash.cc @@ -199,10 +199,9 @@ int HashOption::match(Cursor& c) int HashOption::eval(Cursor& c, Packet*) { - PROFILE_VARS; - MODULE_PROFILE_START(hash_ps[idx]); + auto& hash_option_stats = hash_ps[idx]; + PERF_PROFILE(hash_option_stats); - int rval = DETECTION_OPTION_NO_MATCH; int found = match(c); if ( found == -1 ) @@ -213,18 +212,14 @@ int HashOption::eval(Cursor& c, Packet*) which is not what we want. */ found = 0; } + else - { found ^= config->negated; - } if ( found ) - { - rval = DETECTION_OPTION_MATCH; - } + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(hash_ps[idx]); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_http.cc b/src/ips_options/ips_http.cc index 89fca3b79..afc77b459 100644 --- a/src/ips_options/ips_http.cc +++ b/src/ips_options/ips_http.cc @@ -93,27 +93,21 @@ private: int HttpIpsOption::eval(Cursor& c, Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(http_ps[idx]); + auto& http_option_stats = http_ps[idx]; + PERF_PROFILE(http_option_stats); - int rval; InspectionBuffer hb; if ( !p->flow || !p->flow->gadget ) - rval = DETECTION_OPTION_NO_MATCH; + return DETECTION_OPTION_NO_MATCH; // FIXIT-P cache id at parse time for runtime use else if ( !p->flow->gadget->get_buf(key, p, hb) ) - rval = DETECTION_OPTION_NO_MATCH; + return DETECTION_OPTION_NO_MATCH; - else - { - c.set(key, hb.data, hb.len); - rval = DETECTION_OPTION_MATCH; - } + c.set(key, hb.data, hb.len); - MODULE_PROFILE_END(http_ps[idx]); - return rval; + return DETECTION_OPTION_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_http_header.cc b/src/ips_options/ips_http_header.cc index 0bfeeae36..3bba43a4a 100644 --- a/src/ips_options/ips_http_header.cc +++ b/src/ips_options/ips_http_header.cc @@ -162,32 +162,27 @@ static bool find( int HttpHeaderOption::eval(Cursor& c, Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(httpHeaderPerfStats); + PERF_PROFILE(httpHeaderPerfStats); - int rval; InspectionBuffer hb; if ( !p->flow || !p->flow->gadget ) - rval = DETECTION_OPTION_NO_MATCH; + return DETECTION_OPTION_NO_MATCH; // FIXIT-P cache id at parse time for runtime use - else if ( !p->flow->gadget->get_buf(s_name, p, hb) ) - rval = DETECTION_OPTION_NO_MATCH; + if ( !p->flow->gadget->get_buf(s_name, p, hb) ) + return DETECTION_OPTION_NO_MATCH; - else if ( !name.size() ) + if ( !name.size() ) { c.set(s_name, hb.data, hb.len); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } - else if ( find(name, hb, c) ) - rval = DETECTION_OPTION_MATCH; - else - rval = DETECTION_OPTION_NO_MATCH; + if ( find(name, hb, c) ) + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(httpHeaderPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_icmp_id.cc b/src/ips_options/ips_icmp_id.cc index 26862e732..395b53578 100644 --- a/src/ips_options/ips_icmp_id.cc +++ b/src/ips_options/ips_icmp_id.cc @@ -107,12 +107,11 @@ bool IcmpIdOption::operator==(const IpsOption& ips) const int IcmpIdOption::eval(Cursor&, Packet* p) { - PROFILE_VARS; + PERF_PROFILE(icmpIdPerfStats); if (!p->ptrs.icmph) return DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_START(icmpIdPerfStats); if ( (p->ptrs.icmph->type == ICMP_ECHO || p->ptrs.icmph->type == ICMP_ECHOREPLY) || @@ -120,12 +119,9 @@ int IcmpIdOption::eval(Cursor&, Packet* p) (uint16_t)p->ptrs.icmph->type == icmp::Icmp6Types::REPLY_6) ) { if ( config.eval(p->ptrs.icmph->s_icmp_id) ) - { - MODULE_PROFILE_END(icmpIdPerfStats); return DETECTION_OPTION_MATCH; - } } - MODULE_PROFILE_END(icmpIdPerfStats); + return DETECTION_OPTION_NO_MATCH; } diff --git a/src/ips_options/ips_icmp_seq.cc b/src/ips_options/ips_icmp_seq.cc index 36e282c7c..3caede13e 100644 --- a/src/ips_options/ips_icmp_seq.cc +++ b/src/ips_options/ips_icmp_seq.cc @@ -109,13 +109,11 @@ bool IcmpSeqOption::operator==(const IpsOption& ips) const int IcmpSeqOption::eval(Cursor&, Packet* p) { - PROFILE_VARS; + PERF_PROFILE(icmpSeqPerfStats); if (!p->ptrs.icmph) return DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_START(icmpSeqPerfStats); - if ( (p->ptrs.icmph->type == ICMP_ECHO || p->ptrs.icmph->type == ICMP_ECHOREPLY) || ((uint16_t)p->ptrs.icmph->type == icmp::Icmp6Types::ECHO_6 || @@ -123,11 +121,10 @@ int IcmpSeqOption::eval(Cursor&, Packet* p) { if ( config.eval(p->ptrs.icmph->s_icmp_seq) ) { - MODULE_PROFILE_END(icmpSeqPerfStats); return DETECTION_OPTION_MATCH; } } - MODULE_PROFILE_END(icmpSeqPerfStats); + return DETECTION_OPTION_NO_MATCH; } diff --git a/src/ips_options/ips_icode.cc b/src/ips_options/ips_icode.cc index 405d5a620..00fb6035d 100644 --- a/src/ips_options/ips_icode.cc +++ b/src/ips_options/ips_icode.cc @@ -86,20 +86,16 @@ bool IcodeOption::operator==(const IpsOption& ips) const int IcodeOption::eval(Cursor&, Packet* p) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; + PERF_PROFILE(icmpCodePerfStats); - /* return 0 if we don't have an icmp header */ + // return 0 if we don't have an icmp header if (!p->ptrs.icmph) - return rval; - - MODULE_PROFILE_START(icmpCodePerfStats); + return DETECTION_OPTION_NO_MATCH; if ( config.eval(p->ptrs.icmph->code) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(icmpCodePerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_id.cc b/src/ips_options/ips_id.cc index 965532dbb..f8f795df5 100644 --- a/src/ips_options/ips_id.cc +++ b/src/ips_options/ips_id.cc @@ -83,19 +83,15 @@ bool IpIdOption::operator==(const IpsOption& ips) const int IpIdOption::eval(Cursor&, Packet* p) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; + PERF_PROFILE(ipIdPerfStats); if (!p->has_ip()) - return rval; - - MODULE_PROFILE_START(ipIdPerfStats); + return DETECTION_OPTION_NO_MATCH; if ( config.eval(p->ptrs.ip_api.id()) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(ipIdPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_ip_proto.cc b/src/ips_options/ips_ip_proto.cc index c7a0cfb33..0d948fa65 100644 --- a/src/ips_options/ips_ip_proto.cc +++ b/src/ips_options/ips_ip_proto.cc @@ -112,40 +112,42 @@ bool IpProtoOption::operator==(const IpsOption& ips) const int IpProtoOption::eval(Cursor&, Packet* p) { + PERF_PROFILE(ipProtoPerfStats); + IpProtoData* ipd = &config; - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; if (!p->has_ip()) { DebugMessage(DEBUG_IPS_OPTION,"Not IP\n"); - return rval; + return DETECTION_OPTION_NO_MATCH; } - MODULE_PROFILE_START(ipProtoPerfStats); - const uint8_t ip_proto = p->get_ip_proto_next(); switch (ipd->comparison_flag) { case IP_PROTO__EQUAL: if (ip_proto == ipd->protocol) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; + break; case IP_PROTO__NOT_EQUAL: if (ip_proto != ipd->protocol) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; + break; case IP_PROTO__GREATER_THAN: if (ip_proto > ipd->protocol) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; + break; case IP_PROTO__LESS_THAN: if (ip_proto < ipd->protocol) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; + break; default: @@ -155,8 +157,7 @@ int IpProtoOption::eval(Cursor&, Packet* p) } /* if the test isn't successful, this function *must* return 0 */ - MODULE_PROFILE_END(ipProtoPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_ipopts.cc b/src/ips_options/ips_ipopts.cc index 09ecb7260..86301bb29 100644 --- a/src/ips_options/ips_ipopts.cc +++ b/src/ips_options/ips_ipopts.cc @@ -110,16 +110,16 @@ bool IpOptOption::operator==(const IpsOption& ips) const int IpOptOption::eval(Cursor&, Packet* p) { + PERF_PROFILE(ipOptionPerfStats); + IpOptionData* ipOptionData = &config; - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; DebugMessage(DEBUG_IPS_OPTION, "CheckIpOptions:"); - if (!p->ptrs.ip_api.is_ip4()) - return rval; /* if error occured while ip header - * was processed, return 0 automatically. */ - MODULE_PROFILE_START(ipOptionPerfStats); + if ( !p->is_ip4() ) + // if error occured while ip header + // was processed, return 0 automatically. + return DETECTION_OPTION_NO_MATCH; const ip::IP4Hdr* const ip4h = p->ptrs.ip_api.get_ip4h(); const uint8_t option_len = ip4h->get_opt_len(); @@ -127,9 +127,7 @@ int IpOptOption::eval(Cursor&, Packet* p) if ((ipOptionData->any_flag == 1) && (option_len > 0)) { DebugMessage(DEBUG_IPS_OPTION, "Matched any ip options!\n"); - rval = DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(ipOptionPerfStats); - return rval; + return DETECTION_OPTION_MATCH; } ip::IpOptionIterator iter(ip4h, p); @@ -140,16 +138,11 @@ int IpOptOption::eval(Cursor&, Packet* p) static_cast(opt.code)); if (ipOptionData->ip_option == opt.code) - { - rval = DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(ipOptionPerfStats); - return rval; - } + return DETECTION_OPTION_MATCH; + } - /* if the test isn't successful, return 0 */ - MODULE_PROFILE_END(ipOptionPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_isdataat.cc b/src/ips_options/ips_isdataat.cc index bc2df39f6..1b43ad314 100644 --- a/src/ips_options/ips_isdataat.cc +++ b/src/ips_options/ips_isdataat.cc @@ -137,15 +137,13 @@ bool IsDataAtOption::operator==(const IpsOption& ips) const int IsDataAtOption::eval(Cursor& c, Packet*) { + PERF_PROFILE(isDataAtPerfStats); + IsDataAtData* isdata = &config; - int rval = DETECTION_OPTION_NO_MATCH; - const uint8_t* start_ptr; - int offset; - PROFILE_VARS; - MODULE_PROFILE_START(isDataAtPerfStats); + int offset; - /* Get values from byte_extract variables, if present. */ + // Get values from byte_extract variables, if present. if (isdata->offset_var >= 0 && isdata->offset_var < NUM_BYTE_EXTRACT_VARS) { uint32_t value; @@ -155,6 +153,7 @@ int IsDataAtOption::eval(Cursor& c, Packet*) else offset = isdata->offset; + const uint8_t* start_ptr; if ( isdata->flags & ISDATAAT_RELATIVE_FLAG ) { start_ptr = c.start(); @@ -165,6 +164,7 @@ int IsDataAtOption::eval(Cursor& c, Packet*) } start_ptr += offset; + int rval = DETECTION_OPTION_NO_MATCH; if (inBounds(c.buffer(), c.endo(), start_ptr)) { DebugMessage(DEBUG_PATTERN_MATCH, @@ -177,8 +177,7 @@ int IsDataAtOption::eval(Cursor& c, Packet*) rval = !rval; } - /* otherwise dump */ - MODULE_PROFILE_END(isDataAtPerfStats); + // otherwise dump return rval; } diff --git a/src/ips_options/ips_itype.cc b/src/ips_options/ips_itype.cc index 5ec32492c..362a6f85a 100644 --- a/src/ips_options/ips_itype.cc +++ b/src/ips_options/ips_itype.cc @@ -83,20 +83,16 @@ bool IcmpTypeOption::operator==(const IpsOption& ips) const int IcmpTypeOption::eval(Cursor&, Packet* p) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; + PERF_PROFILE(icmpTypePerfStats); - /* return 0 if we don't have an icmp header */ + // return 0 if we don't have an icmp header if (!p->ptrs.icmph) - return rval; - - MODULE_PROFILE_START(icmpTypePerfStats); + return DETECTION_OPTION_NO_MATCH; if ( config.eval(p->ptrs.icmph->type) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(icmpTypePerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_luajit.cc b/src/ips_options/ips_luajit.cc index 64c8a291b..8ca2cd850 100644 --- a/src/ips_options/ips_luajit.cc +++ b/src/ips_options/ips_luajit.cc @@ -185,8 +185,7 @@ bool LuaJitOption::operator==(const IpsOption& ips) const int LuaJitOption::eval(Cursor& c, Packet*) { - PROFILE_VARS; - MODULE_PROFILE_START(luaIpsPerfStats); + PERF_PROFILE(luaIpsPerfStats); cursor = &c; @@ -201,16 +200,13 @@ int LuaJitOption::eval(Cursor& c, Packet*) { const char* err = lua_tostring(L, -1); ErrorMessage("%s\n", err); - MODULE_PROFILE_END(luaIpsPerfStats); return DETECTION_OPTION_NO_MATCH; } - bool result = lua_toboolean(L, -1); + if ( lua_toboolean(L, -1) ) + return DETECTION_OPTION_MATCH; - int ret = result ? DETECTION_OPTION_MATCH : DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_END(luaIpsPerfStats); - - return ret; + return DETECTION_OPTION_NO_MATCH; } } diff --git a/src/ips_options/ips_pcre.cc b/src/ips_options/ips_pcre.cc index a82808fd2..60566a3af 100644 --- a/src/ips_options/ips_pcre.cc +++ b/src/ips_options/ips_pcre.cc @@ -561,19 +561,13 @@ bool PcreOption::operator==(const IpsOption& ips) const int PcreOption::eval(Cursor& c, Packet*) { - PcreData* pcre_data = config; - int found_offset = -1; /* where is the ending location of the pattern */ - bool matched = false; + PERF_PROFILE(pcrePerfStats); - PROFILE_VARS; - MODULE_PROFILE_START(pcrePerfStats); + PcreData* pcre_data = config; // short circuit this for testing pcre performance impact if (SnortConfig::no_pcre()) - { - MODULE_PROFILE_END(pcrePerfStats); return DETECTION_OPTION_NO_MATCH; - } unsigned pos = c.get_delta(); @@ -583,7 +577,9 @@ int PcreOption::eval(Cursor& c, Packet*) if ( pos > c.size() ) return 0; - matched = pcre_search(pcre_data, c.buffer(), c.size(), pos, &found_offset); + int found_offset = -1; // where is the ending location of the pattern + bool matched = pcre_search(pcre_data, c.buffer(), c.size(), pos, + &found_offset); if (matched) { @@ -592,11 +588,10 @@ int PcreOption::eval(Cursor& c, Packet*) c.set_pos(found_offset); c.set_delta(found_offset); } - MODULE_PROFILE_END(pcrePerfStats); + return DETECTION_OPTION_MATCH; } - MODULE_PROFILE_END(pcrePerfStats); return DETECTION_OPTION_NO_MATCH; } diff --git a/src/ips_options/ips_pkt_data.cc b/src/ips_options/ips_pkt_data.cc index 6a0ce0653..9fb274f40 100644 --- a/src/ips_options/ips_pkt_data.cc +++ b/src/ips_options/ips_pkt_data.cc @@ -48,12 +48,9 @@ public: int PktDataOption::eval(Cursor& c, Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(pktDataPerfStats); + PERF_PROFILE(pktDataPerfStats); c.reset(p); - - MODULE_PROFILE_END(pktDataPerfStats); return DETECTION_OPTION_MATCH; } diff --git a/src/ips_options/ips_raw_data.cc b/src/ips_options/ips_raw_data.cc index 0ab292c38..b63133d3a 100644 --- a/src/ips_options/ips_raw_data.cc +++ b/src/ips_options/ips_raw_data.cc @@ -48,12 +48,9 @@ public: int RawDataOption::eval(Cursor& c, Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(rawDataPerfStats); + PERF_PROFILE(rawDataPerfStats); c.set(s_name, p->data, p->dsize); - - MODULE_PROFILE_END(rawDataPerfStats); return DETECTION_OPTION_MATCH; } diff --git a/src/ips_options/ips_replace.cc b/src/ips_options/ips_replace.cc index e51a19c70..661daa8d5 100644 --- a/src/ips_options/ips_replace.cc +++ b/src/ips_options/ips_replace.cc @@ -159,8 +159,7 @@ bool ReplaceOption::operator==(const IpsOption& ips) const int ReplaceOption::eval(Cursor& c, Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(replacePerfStats); + PERF_PROFILE(replacePerfStats); if ( p->is_cooked() ) return false; @@ -173,19 +172,15 @@ int ReplaceOption::eval(Cursor& c, Packet* p) store(c.get_pos() - repl.size()); - MODULE_PROFILE_END(replacePerfStats); return DETECTION_OPTION_MATCH; } void ReplaceOption::action(Packet*) { - PROFILE_VARS; - MODULE_PROFILE_START(replacePerfStats); + PERF_PROFILE(replacePerfStats); if ( pending() ) Replace_QueueChange(repl, (unsigned)pos()); - - MODULE_PROFILE_END(replacePerfStats); } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_rpc.cc b/src/ips_options/ips_rpc.cc index fd0b8aa8f..ab5fc6947 100644 --- a/src/ips_options/ips_rpc.cc +++ b/src/ips_options/ips_rpc.cc @@ -121,21 +121,14 @@ bool RpcOption::operator==(const IpsOption& ips) const int RpcOption::eval(Cursor&, Packet* p) { + PERF_PROFILE(rpcCheckPerfStats); + RpcCheckData* ds_ptr = &config; - unsigned char* c=(unsigned char*)p->data; - u_long rpcvers, prog, vers, proc; - enum msg_type direction; - int rval = DETECTION_OPTION_NO_MATCH; -#ifdef DEBUG_MSGS - int i; -#endif - PROFILE_VARS; if (!(p->is_tcp() || p->is_udp())) - return 0; /* if error occured while ip header - * was processed, return 0 automagically. */ + return DETECTION_OPTION_NO_MATCH; - MODULE_PROFILE_START(rpcCheckPerfStats); + auto c = p->data; if ( p->is_tcp() ) { @@ -145,8 +138,7 @@ int RpcOption::eval(Cursor&, Packet* p) if (p->dsize<28) { DebugMessage(DEBUG_IPS_OPTION, "RPC packet too small"); - MODULE_PROFILE_END(rpcCheckPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } } else @@ -155,18 +147,18 @@ int RpcOption::eval(Cursor&, Packet* p) if (p->dsize<24) { DebugMessage(DEBUG_IPS_OPTION, "RPC packet too small"); - MODULE_PROFILE_END(rpcCheckPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } } #ifdef DEBUG_MSGS DebugMessage(DEBUG_IPS_OPTION,"<---xid---> <---dir---> <---rpc--->" " <---prog--> <---vers--> <---proc-->\n"); - for (i=0; i<24; i++) + for (int i = 0; i < 24; i++) { DebugFormat(DEBUG_IPS_OPTION, "%02X ",c[i]); } + DebugMessage(DEBUG_IPS_OPTION,"\n"); #endif @@ -174,31 +166,29 @@ int RpcOption::eval(Cursor&, Packet* p) (void)IXDR_GET_LONG (c); /* Read direction : CALL or REPLY */ - direction = IXDR_GET_ENUM (c, enum msg_type); + enum msg_type direction = IXDR_GET_ENUM (c, enum msg_type); /* We only look at calls */ if (direction != CALL) { DebugMessage(DEBUG_IPS_OPTION, "RPC packet not a call"); - MODULE_PROFILE_END(rpcCheckPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } /* Read the RPC message version */ - rpcvers = IXDR_GET_LONG (c); + u_long rpcvers = IXDR_GET_LONG (c); /* Fail if it is not right */ if (rpcvers != RPC_MSG_VERSION) { DebugMessage(DEBUG_IPS_OPTION,"RPC msg version invalid"); - MODULE_PROFILE_END(rpcCheckPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } /* Read the program number, version, and procedure */ - prog = IXDR_GET_LONG (c); - vers = IXDR_GET_LONG (c); - proc = IXDR_GET_LONG (c); + u_long prog = IXDR_GET_LONG (c); + u_long vers = IXDR_GET_LONG (c); + u_long proc = IXDR_GET_LONG (c); DebugFormat(DEBUG_IPS_OPTION,"RPC decoded to: %lu %lu %lu\n", prog,vers,proc); @@ -220,7 +210,7 @@ int RpcOption::eval(Cursor&, Packet* p) { DebugMessage(DEBUG_IPS_OPTION,"RPC proc matches"); DebugMessage(DEBUG_IPS_OPTION, "Yippee! Found one!"); - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; } } } @@ -231,8 +221,7 @@ int RpcOption::eval(Cursor&, Packet* p) } /* if the test isn't successful, return 0 */ - MODULE_PROFILE_END(rpcCheckPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_seq.cc b/src/ips_options/ips_seq.cc index 6c007a51d..5e6948dad 100644 --- a/src/ips_options/ips_seq.cc +++ b/src/ips_options/ips_seq.cc @@ -82,19 +82,15 @@ bool TcpSeqOption::operator==(const IpsOption& ips) const int TcpSeqOption::eval(Cursor&, Packet* p) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; + PERF_PROFILE(tcpSeqPerfStats); if (!p->ptrs.tcph) - return rval; - - MODULE_PROFILE_START(tcpSeqPerfStats); + return DETECTION_OPTION_NO_MATCH; if ( config.eval(p->ptrs.tcph->th_seq) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(tcpSeqPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_session.cc b/src/ips_options/ips_session.cc index bdbc5ec47..bc6f8dac3 100644 --- a/src/ips_options/ips_session.cc +++ b/src/ips_options/ips_session.cc @@ -137,32 +137,27 @@ bool SessionOption::operator==(const IpsOption& ips) const int SessionOption::eval(Cursor&, Packet* p) { + PERF_PROFILE(sessionPerfStats); + SessionData* session_data = &config; - FILE* session; /* session file ptr */ - PROFILE_VARS; - MODULE_PROFILE_START(sessionPerfStats); + if ( !p || !p->dsize || !p->data ) + return DETECTION_OPTION_MATCH; - /* if there's data in this packet */ - if (p != NULL) - { - if ((p->dsize != 0 && p->data != NULL) || (!(p->ptrs.decode_flags & DECODE_FRAG))) - { - session = OpenSessionFile(p); + if ( p->is_fragment() ) + return DETECTION_OPTION_MATCH; - if (session == NULL) - { - MODULE_PROFILE_END(sessionPerfStats); - return DETECTION_OPTION_MATCH; - } + // FIXIT-M should wrap file open/close in a class to ensure cleanup + { + FILE* session = OpenSessionFile(p); + if ( !session ) + return DETECTION_OPTION_MATCH; - DumpSessionData(session, p, session_data); + DumpSessionData(session, p, session_data); - fclose(session); - } + fclose(session); } - MODULE_PROFILE_END(sessionPerfStats); return DETECTION_OPTION_MATCH; } diff --git a/src/ips_options/ips_so.cc b/src/ips_options/ips_so.cc index 4aca53db9..7a7f7db82 100644 --- a/src/ips_options/ips_so.cc +++ b/src/ips_options/ips_so.cc @@ -95,13 +95,8 @@ bool SoOption::operator==(const IpsOption& ips) const int SoOption::eval(Cursor& c, Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(soPerfStats); - - int ret = func(data, c, p); - - MODULE_PROFILE_END(soPerfStats); - return ret; + PERF_PROFILE(soPerfStats); + return func(data, c, p); } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_tos.cc b/src/ips_options/ips_tos.cc index 824b19802..48459a116 100644 --- a/src/ips_options/ips_tos.cc +++ b/src/ips_options/ips_tos.cc @@ -84,19 +84,15 @@ bool IpTosOption::operator==(const IpsOption& ips) const int IpTosOption::eval(Cursor&, Packet* p) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; + PERF_PROFILE(ipTosPerfStats); if(!p->ptrs.ip_api.is_ip()) - return rval; - - MODULE_PROFILE_START(ipTosPerfStats); + return DETECTION_OPTION_NO_MATCH; if ( config.eval(p->ptrs.ip_api.tos()) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(ipTosPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_ttl.cc b/src/ips_options/ips_ttl.cc index a89ebac70..6a84005ab 100644 --- a/src/ips_options/ips_ttl.cc +++ b/src/ips_options/ips_ttl.cc @@ -82,19 +82,15 @@ bool TtlOption::operator==(const IpsOption& ips) const int TtlOption::eval(Cursor&, Packet* p) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; + PERF_PROFILE(ttlCheckPerfStats); if(!p->ptrs.ip_api.is_ip()) - return rval; - - MODULE_PROFILE_START(ttlCheckPerfStats); + return DETECTION_OPTION_NO_MATCH; if ( config.eval(p->ptrs.ip_api.ttl()) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(ttlCheckPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/ips_options/ips_window.cc b/src/ips_options/ips_window.cc index 062ce0a56..51f043500 100644 --- a/src/ips_options/ips_window.cc +++ b/src/ips_options/ips_window.cc @@ -82,19 +82,15 @@ bool TcpWinOption::operator==(const IpsOption& ips) const int TcpWinOption::eval(Cursor&, Packet* p) { - int rval = DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; + PERF_PROFILE(tcpWinPerfStats); if (!p->ptrs.tcph) - return rval; - - MODULE_PROFILE_START(tcpWinPerfStats); + return DETECTION_OPTION_NO_MATCH; if ( config.eval(p->ptrs.tcph->th_win) ) - rval = DETECTION_OPTION_MATCH; + return DETECTION_OPTION_MATCH; - MODULE_PROFILE_END(tcpWinPerfStats); - return rval; + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/loggers/alert_luajit.cc b/src/loggers/alert_luajit.cc index acd6d283e..d3e5417e5 100644 --- a/src/loggers/alert_luajit.cc +++ b/src/loggers/alert_luajit.cc @@ -206,28 +206,21 @@ LuaJitLogger::~LuaJitLogger() void LuaJitLogger::alert(Packet* p, const char*, Event* e) { - PROFILE_VARS; - MODULE_PROFILE_START(luaLogPerfStats); + PERF_PROFILE(luaLogPerfStats); packet = p; event = e; lua_State* L = states[get_instance_id()]; - { - Lua::ManageStack ms(L, 1); - - lua_getglobal(L, "alert"); + Lua::ManageStack ms(L, 1); - if ( lua_pcall(L, 0, 1, 0) ) - { - const char* err = lua_tostring(L, -1); - ErrorMessage("%s\n", err); - MODULE_PROFILE_END(luaLogPerfStats); - } + lua_getglobal(L, "alert"); + if ( lua_pcall(L, 0, 1, 0) ) + { + const char* err = lua_tostring(L, -1); + ErrorMessage("%s\n", err); } - - MODULE_PROFILE_END(luaLogPerfStats); } //------------------------------------------------------------------------- diff --git a/src/main/snort.cc b/src/main/snort.cc index c261ccaf7..84dff7403 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -162,15 +162,15 @@ static ProfileStats* get_profile(const char* key) static void register_profiles() { #ifdef PERF_PROFILING - RegisterProfile("detect", nullptr, get_profile); - RegisterProfile("mpse", "detect", get_profile); - RegisterProfile("rule eval", "detect", get_profile); - RegisterProfile("rtn eval", "rule eval", get_profile); - RegisterProfile("rule tree eval", "rule eval", get_profile); - RegisterProfile("decode", nullptr, get_profile); - RegisterProfile("eventq", nullptr, get_profile); - RegisterProfile("total", nullptr, get_profile); - RegisterProfile("daq meta", nullptr, get_profile); + PerfProfilerManager::register_module("detect", nullptr, get_profile); + PerfProfilerManager::register_module("mpse", "detect", get_profile); + PerfProfilerManager::register_module("rule eval", "detect", get_profile); + PerfProfilerManager::register_module("rtn eval", "rule eval", get_profile); + PerfProfilerManager::register_module("rule tree eval", "rule eval", get_profile); + PerfProfilerManager::register_module("decode", nullptr, get_profile); + PerfProfilerManager::register_module("eventq", nullptr, get_profile); + PerfProfilerManager::register_module("total", nullptr, get_profile); + PerfProfilerManager::register_module("daq meta", nullptr, get_profile); #endif } @@ -405,7 +405,7 @@ void Snort::term() periodic_release(); #ifdef PERF_PROFILING - CleanupProfileStatsNodeList(); + PerfProfilerManager::term(); #endif /* free allocated memory */ @@ -671,7 +671,7 @@ void Snort::thread_term() DAQ_Delete(); #ifdef PERF_PROFILING - ReleaseProfileStats(); + PerfProfilerManager::consolidate_stats(); #endif otnx_match_data_term(); @@ -794,30 +794,28 @@ static DAQ_Verdict update_verdict(DAQ_Verdict verdict, int& inject) DAQ_Verdict Snort::packet_callback( void*, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt) { - int inject = 0; - PROFILE_VARS; + PERF_PROFILE(totalPerfStats); - MODULE_PROFILE_START(totalPerfStats); pc.total_from_daq++; rule_eval_pkt_count++; packet_time_update(&pkthdr->ts); if ( snort_conf->pkt_skip && pc.total_from_daq <= snort_conf->pkt_skip ) - { - MODULE_PROFILE_END(totalPerfStats); return DAQ_VERDICT_PASS; - } - MODULE_PROFILE_START(eventqPerfStats); - SnortEventqReset(); - MODULE_PROFILE_END(eventqPerfStats); + PERF_PROFILE_BLOCK(eventqPerfStats) + { + SnortEventqReset(); + } sfthreshold_reset(); ActionManager::reset_queue(); DAQ_Verdict verdict = process_packet(s_packet, pkthdr, pkt); ActionManager::execute(s_packet); + + int inject = 0; verdict = update_verdict(verdict, inject); UpdateWireStats(&sfBase, pkthdr->caplen, Active::packet_was_dropped(), inject); @@ -837,7 +835,6 @@ DAQ_Verdict Snort::packet_callback( else if ( break_time() ) DAQ_BreakLoop(0); - MODULE_PROFILE_END(totalPerfStats); return verdict; } diff --git a/src/managers/module_manager.cc b/src/managers/module_manager.cc index c8fe31cc1..44d95f727 100644 --- a/src/managers/module_manager.cc +++ b/src/managers/module_manager.cc @@ -785,7 +785,7 @@ void ModuleManager::add_module(Module* m, const BaseApi* b) s_modules.push_back(mh); #ifdef PERF_PROFILING - RegisterProfile(m); + PerfProfilerManager::register_module(m); #endif } diff --git a/src/network_inspectors/arp_spoof/arp_spoof.cc b/src/network_inspectors/arp_spoof/arp_spoof.cc index 86b1bf4c3..1d2c96219 100644 --- a/src/network_inspectors/arp_spoof/arp_spoof.cc +++ b/src/network_inspectors/arp_spoof/arp_spoof.cc @@ -176,24 +176,20 @@ void ArpSpoof::show(SnortConfig*) void ArpSpoof::eval(Packet* p) { - IPMacEntry* ipme; - PROFILE_VARS; - const arp::EtherARP* ah; - const eth::EtherHdr* eh; + PERF_PROFILE(arpPerfStats); // preconditions - what we registered for assert(p->type() == PktType::ARP); assert(p->proto_bits & PROTO_BIT__ETH); - ah = layer::get_arp_layer(p); - eh = layer::get_eth_layer(p); + const arp::EtherARP* ah = layer::get_arp_layer(p); + const eth::EtherHdr* eh = layer::get_eth_layer(p); /* is the ARP protocol type IP and the ARP hardware type Ethernet? */ if ((ntohs(ah->ea_hdr.ar_hrd) != 0x0001) || (ntohs(ah->ea_hdr.ar_pro) != ETHERNET_TYPE_IP)) return; - MODULE_PROFILE_START(arpPerfStats); ++asstats.total_packets; switch (ntohs(ah->ea_hdr.ar_op)) @@ -238,41 +234,34 @@ void ArpSpoof::eval(Packet* p) } break; } - MODULE_PROFILE_END(arpPerfStats); /* return if the overwrite list hasn't been initialized */ if (!config->check_overwrite) return; - if ((ipme = LookupIPMacEntryByIP(config->ipmel, - ah->arp_spa32)) == NULL) - { - DebugMessage(DEBUG_INSPECTOR, - "MODNAME: LookupIPMacEntryByIp returned NULL\n"); - return; - } - else + IPMacEntry* ipme = LookupIPMacEntryByIP(config->ipmel, ah->arp_spa32); + if ( ipme ) { DebugFormat(DEBUG_INSPECTOR, "MODNAME: LookupIPMacEntryByIP returned %p\n", ipme); - /* If the Ethernet source address or the ARP source hardware address - * in p doesn't match the MAC address in ipme, then generate an alert - */ - if ((memcmp((uint8_t*)eh->ether_src, - (uint8_t*)ipme->mac_addr, 6)) || - (memcmp((uint8_t*)ah->arp_sha, - (uint8_t*)ipme->mac_addr, 6))) + auto cmp_ether_src = memcmp(eh->ether_src, ipme->mac_addr, 6); + auto cmp_arp_sha = memcmp(ah->arp_sha, ipme->mac_addr, 6); + + // If the Ethernet source address or the ARP source hardware address + // in p doesn't match the MAC address in ipme, then generate an alert + if ( cmp_ether_src || cmp_arp_sha ) { - SnortEventqAdd(GID_ARP_SPOOF, - ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK); + SnortEventqAdd(GID_ARP_SPOOF, ARPSPOOF_ARP_CACHE_OVERWRITE_ATTACK); DebugMessage(DEBUG_INSPECTOR, "MODNAME: Attempted ARP cache overwrite attack\n"); - - return; } } + + else + DebugMessage(DEBUG_INSPECTOR, + "MODNAME: LookupIPMacEntryByIp returned NULL\n"); } //------------------------------------------------------------------------- diff --git a/src/network_inspectors/normalize/normalize.cc b/src/network_inspectors/normalize/normalize.cc index bfa2a7739..685493a8e 100644 --- a/src/network_inspectors/normalize/normalize.cc +++ b/src/network_inspectors/normalize/normalize.cc @@ -244,13 +244,10 @@ void Normalizer::show(SnortConfig* sc) void Normalizer::eval(Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(norm_perf_stats); + PERF_PROFILE(norm_perf_stats); if ( !p->is_rebuilt() && !Active::packet_was_dropped() ) Norm_Packet(&config, p); - - MODULE_PROFILE_END(norm_perf_stats); } //------------------------------------------------------------------------- diff --git a/src/network_inspectors/perf_monitor/perf_monitor.cc b/src/network_inspectors/perf_monitor/perf_monitor.cc index 9f36dba99..cd5ab6d7d 100644 --- a/src/network_inspectors/perf_monitor/perf_monitor.cc +++ b/src/network_inspectors/perf_monitor/perf_monitor.cc @@ -303,9 +303,10 @@ void PerfMonitor::tterm() void PerfMonitor::eval(Packet* p) { + PERF_PROFILE(perfmonStats); + static THREAD_LOCAL bool first = true; - PROFILE_VARS; - MODULE_PROFILE_START(perfmonStats); + if (first) { @@ -335,8 +336,6 @@ void PerfMonitor::eval(Packet* p) sfPerformanceStats(&config, p); ++pmstats.total_packets; - - MODULE_PROFILE_END(perfmonStats); } //------------------------------------------------------------------------- diff --git a/src/network_inspectors/port_scan/port_scan.cc b/src/network_inspectors/port_scan/port_scan.cc index 96b43fe5b..43ec3b1a7 100644 --- a/src/network_inspectors/port_scan/port_scan.cc +++ b/src/network_inspectors/port_scan/port_scan.cc @@ -912,17 +912,16 @@ void PortScan::show(SnortConfig*) void PortScan::eval(Packet* p) { - PS_PKT ps_pkt; - PROFILE_VARS; + PERF_PROFILE(psPerfStats); assert(p->ptrs.ip_api.is_ip()); if ( p->packet_flags & PKT_REBUILT_STREAM ) return; - MODULE_PROFILE_START(psPerfStats); ++spstats.total_packets; + PS_PKT ps_pkt; memset(&ps_pkt, 0x00, sizeof(PS_PKT)); // FIXIT-P don't zap unless necessary ps_pkt.pkt = (void*)p; @@ -940,8 +939,6 @@ void PortScan::eval(Packet* p) { PortscanAlert(&ps_pkt, &ps_pkt.scanned->proto, ps_pkt.proto); } - - MODULE_PROFILE_END(psPerfStats); } //------------------------------------------------------------------------- diff --git a/src/protocols/packet_manager.cc b/src/protocols/packet_manager.cc index 87603fc11..844190009 100644 --- a/src/protocols/packet_manager.cc +++ b/src/protocols/packet_manager.cc @@ -187,7 +187,8 @@ RawData::RawData(const DAQ_PktHdr_t* h, const uint8_t* p) void PacketManager::decode( Packet* p, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt, bool cooked) { - PROFILE_VARS; + PERF_PROFILE(decodePerfStats); + DecodeData unsure_encap_ptrs; uint8_t mapped_prot = CodecManager::grinder; @@ -206,7 +207,6 @@ void PacketManager::decode( p->ptrs.reset(); layer::set_packet_pointer(p); - MODULE_PROFILE_START(decodePerfStats); s_stats[total_processed]++; // loop until the protocol id is no longer valid @@ -343,8 +343,6 @@ void PacketManager::decode( if ( !p->proto_bits ) p->proto_bits = PROTO_BIT__OTHER; - - MODULE_PROFILE_END(decodePerfStats); } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/back_orifice/back_orifice.cc b/src/service_inspectors/back_orifice/back_orifice.cc index cf302abbc..647702fe8 100644 --- a/src/service_inspectors/back_orifice/back_orifice.cc +++ b/src/service_inspectors/back_orifice/back_orifice.cc @@ -321,7 +321,7 @@ static void PrecalcPrefix(void) * CRC 1 * */ -static int BoGetDirection(Packet* p, char* pkt_data) +static int BoGetDirection(Packet* p, const char* pkt_data) { uint32_t len = 0; uint32_t id = 0; @@ -465,105 +465,86 @@ void BackOrifice::show(SnortConfig*) void BackOrifice::eval(Packet* p) { - uint16_t cyphertext_referent; - uint16_t cyphertext_suffix; - uint16_t key; - const char* magic_cookie = "*!*QWTY?"; - char* pkt_data; - const char* magic_data; - char* end; - char plaintext; - int i; - int bo_direction = 0; - PROFILE_VARS; + PERF_PROFILE(boPerfStats); + + const char* const magic_cookie = "*!*QWTY?"; // preconditions - what we registered for assert(p->is_udp()); - /* make sure it's at least 19 bytes long */ + // make sure it's at least 19 bytes long if (p->dsize < BO_MIN_SIZE) - { return; - } - MODULE_PROFILE_START(boPerfStats); ++bostats.total_packets; - /* - * take the first two characters of the packet and generate the - * first reference that gives us a reference key - */ - cyphertext_referent = (uint16_t)(p->data[0] << 8) & 0xFF00; + // take the first two characters of the packet and generate the + // first reference that gives us a reference key + uint16_t cyphertext_referent = (uint16_t)(p->data[0] << 8) & 0xFF00; cyphertext_referent |= (uint16_t)(p->data[1]) & 0x00FF; - /* - * generate the second referent from the last two characters - * of the cyphertext - */ - cyphertext_suffix = (uint16_t)(p->data[6] << 8) & 0xFF00; + // generate the second referent from the last two characters + // of the cyphertext + uint16_t cyphertext_suffix = (uint16_t)(p->data[6] << 8) & 0xFF00; cyphertext_suffix |= (uint16_t)(p->data[7]) & 0x00FF; - for (i=0; i<3; i++) + for ( int i = 0; i < 3; ++i ) { - /* get the key from the cyphertext */ - key = lookup1[cyphertext_referent][i]; - - /* - * if the lookup from the proposed key matches the cyphertext reference - * then we've probably go the right key and can proceed to full - * decryption using the key - * - * moral of the story: don't use a lame keyspace - */ - if (lookup2[key] == cyphertext_suffix) + // get the key from the cyphertext + uint16_t key = lookup1[cyphertext_referent][i]; + + // if the lookup from the proposed key matches the cyphertext reference + // then we've probably go the right key and can proceed to full + // decryption using the key + // moral of the story: don't use a lame keyspace + if ( lookup2[key] == cyphertext_suffix ) { + auto pkt_data = reinterpret_cast(p->data); + auto end = pkt_data + BO_MAGIC_SIZE; + const char* magic_data = magic_cookie; + holdrand = key; - pkt_data = (char*)p->data; - end = (char*)p->data + BO_MAGIC_SIZE; - magic_data = magic_cookie; - while (pkt_datahas_tcp_data() ) { - /* If session picked up mid-stream, do not process further. - * Would be almost impossible to tell where we are in the - * data stream. */ + // If session picked up mid-stream, do not process further. + // Would be almost impossible to tell where we are in the + // data stream. if ( p->flow->get_session_flags() & SSNFLAG_MIDSTREAM ) { return; @@ -1015,49 +1013,39 @@ static void snort_dns(Packet* p) return; } - /* If we're waiting on stream reassembly, don't process this packet. */ + // If we're waiting on stream reassembly, don't process this packet. if ( p->packet_flags & PKT_STREAM_INSERT ) { return; } } - /* Get the direction of the packet. */ - direction = ( (p->packet_flags & PKT_FROM_SERVER ) ? + // Get the direction of the packet. + uint8_t direction = ( (p->packet_flags & PKT_FROM_SERVER ) ? DNS_DIR_FROM_SERVER : DNS_DIR_FROM_CLIENT ); - MODULE_PROFILE_START(dnsPerfStats); - /* Attempt to get a previously allocated DNS block. */ - dnsSessionData = get_dns_session_data(p); + // Attempt to get a previously allocated DNS block. + DNSData* dnsSessionData = get_dns_session_data(p); if (dnsSessionData == NULL) { - /* Check the stream session. If it does not currently - * have our DNS data-block attached, create one. - */ + // Check the stream session. If it does not currently + // have our DNS data-block attached, create one. dnsSessionData = SetNewDNSData(p); if ( !dnsSessionData ) - { - /* Could not get/create the session data for this packet. */ - MODULE_PROFILE_END(dnsPerfStats); + // Could not get/create the session data for this packet. return; - } } if (dnsSessionData->flags & DNS_FLAG_NOT_DNS) - { - MODULE_PROFILE_END(dnsPerfStats); return; - } if (direction == DNS_DIR_FROM_SERVER) { ParseDNSResponseMessage(p, dnsSessionData); } - - MODULE_PROFILE_END(dnsPerfStats); } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/ftp_telnet/ft_main.cc b/src/service_inspectors/ftp_telnet/ft_main.cc index 8ae560471..c0d3d15e8 100644 --- a/src/service_inspectors/ftp_telnet/ft_main.cc +++ b/src/service_inspectors/ftp_telnet/ft_main.cc @@ -248,24 +248,20 @@ int FTPCheckConfigs(SnortConfig* sc, void* pData) */ void do_detection(Packet* p) { - PROFILE_VARS; + PERF_PROFILE(ftppDetectPerfStats); - /* - * If we get here we either had a client or server request/response. - * We do the detection here, because we're starting a new paradigm - * about protocol decoders. - * - * Protocol decoders are now their own detection engine, since we are - * going to be moving protocol field detection from the generic - * detection engine into the protocol module. This idea scales much - * better than having all these Packet struct field checks in the - * main detection engine for each protocol field. - */ - MODULE_PROFILE_START(ftppDetectPerfStats); + // If we get here we either had a client or server request/response. + // We do the detection here, because we're starting a new paradigm + // about protocol decoders. + // + // Protocol decoders are now their own detection engine, since we are + // going to be moving protocol field detection from the generic + // detection engine into the protocol module. This idea scales much + // better than having all these Packet struct field checks in the + // main detection engine for each protocol field. get_data_bus().publish(PACKET_EVENT, p); DisableInspection(p); - MODULE_PROFILE_END(ftppDetectPerfStats); #ifdef PERF_PROFILING ftppDetectCalled = 1; #endif diff --git a/src/service_inspectors/ftp_telnet/ftp.cc b/src/service_inspectors/ftp_telnet/ftp.cc index 416835fb9..8454f1537 100644 --- a/src/service_inspectors/ftp_telnet/ftp.cc +++ b/src/service_inspectors/ftp_telnet/ftp.cc @@ -73,25 +73,19 @@ static inline int InspectClientPacket(Packet* p) static int SnortFTP( FTP_SESSION* FTPsession, Packet* p, int iInspectMode) { - int iRet; - PROFILE_VARS; + PERF_PROFILE(ftpPerfStats); - if (!FTPsession || - FTPsession->server_conf == NULL || - FTPsession->client_conf == NULL) - { + if ( !FTPsession || !FTPsession->server_conf || !FTPsession->client_conf ) return FTPP_INVALID_SESSION; - } - if (!FTPsession->server_conf->check_encrypted_data && - ((FTPsession->encr_state == AUTH_TLS_ENCRYPTED) || - (FTPsession->encr_state == AUTH_SSL_ENCRYPTED) || - (FTPsession->encr_state == AUTH_UNKNOWN_ENCRYPTED)) ) + if ( !FTPsession->server_conf->check_encrypted_data ) { - return FTPP_SUCCESS; - } + if ( FTPsession->encr_state == AUTH_TLS_ENCRYPTED || + FTPsession->encr_state == AUTH_SSL_ENCRYPTED || + FTPsession->encr_state == AUTH_UNKNOWN_ENCRYPTED ) - MODULE_PROFILE_START(ftpPerfStats); + return FTPP_SUCCESS; + } if (iInspectMode == FTPP_SI_SERVER_MODE) { @@ -109,7 +103,6 @@ static int SnortFTP( { DebugMessage(DEBUG_FTPTELNET, "Client packet will be reassembled\n"); - MODULE_PROFILE_END(ftpPerfStats); return FTPP_SUCCESS; } else @@ -121,32 +114,27 @@ static int SnortFTP( } } - iRet = initialize_ftp(FTPsession, p, iInspectMode); - if (iRet) - { - MODULE_PROFILE_END(ftpPerfStats); - return iRet; - } + int ret = initialize_ftp(FTPsession, p, iInspectMode); + if ( ret ) + return ret; - iRet = check_ftp(FTPsession, p, iInspectMode); - if (iRet == FTPP_SUCCESS) + ret = check_ftp(FTPsession, p, iInspectMode); + if ( ret == FTPP_SUCCESS ) { - /* Ideally, snort_detect(), called from do_detection, will look at - * the cmd & param buffers, or the rsp & msg buffers. Current - * architecture does not support this... - * So, we call do_detection() here. Otherwise, we'd call it - * from inside check_ftp -- each time we process a pipelined - * FTP command. - */ + // Ideally, snort_detect(), called from do_detection, will look at + // the cmd & param buffers, or the rsp & msg buffers. Current + // architecture does not support this... + // So, we call do_detection() here. Otherwise, we'd call it + // from inside check_ftp -- each time we process a pipelined + // FTP command. do_detection(p); } - MODULE_PROFILE_END(ftpPerfStats); #ifdef PERF_PROFILING ft_update_perf(ftpPerfStats); #endif - return iRet; + return ret; } static int snort_ftp(Packet* p) diff --git a/src/service_inspectors/ftp_telnet/ftp_data.cc b/src/service_inspectors/ftp_telnet/ftp_data.cc index 82ca6eb3f..5b18658ed 100644 --- a/src/service_inspectors/ftp_telnet/ftp_data.cc +++ b/src/service_inspectors/ftp_telnet/ftp_data.cc @@ -251,19 +251,16 @@ ProfileStats* FtpDataModule::get_profile() const void FtpData::eval(Packet* p) { + PERF_PROFILE(ftpdataPerfStats); + // precondition - what we registered for assert(p->has_tcp_data()); if ( FileService::get_max_file_depth() < 0 ) return; - PROFILE_VARS; - MODULE_PROFILE_START(ftpdataPerfStats); - SnortFTPData(p); ++fdstats.total_packets; - - MODULE_PROFILE_END(ftpdataPerfStats); } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/ftp_telnet/telnet.cc b/src/service_inspectors/ftp_telnet/telnet.cc index 07459d361..dda3f7fa1 100644 --- a/src/service_inspectors/ftp_telnet/telnet.cc +++ b/src/service_inspectors/ftp_telnet/telnet.cc @@ -76,36 +76,27 @@ static int TelnetCheckConfigs(SnortConfig*, void* pData) static int SnortTelnet(TELNET_PROTO_CONF* telnet_config, TELNET_SESSION* Telnetsession, Packet* p, int iInspectMode) { - int iRet; - PROFILE_VARS; + PERF_PROFILE(telnetPerfStats); - if (!Telnetsession) - { + if ( !Telnetsession ) return FTPP_NONFATAL_ERR; - } - if (Telnetsession->encr_state && !Telnetsession->telnet_conf->check_encrypted_data) - { + if ( Telnetsession->encr_state && + !Telnetsession->telnet_conf->check_encrypted_data ) return FTPP_SUCCESS; - } - MODULE_PROFILE_START(telnetPerfStats); - - if (!telnet_config->normalize) + if ( telnet_config->normalize ) { - do_detection(p); - } - else - { - iRet = normalize_telnet( - Telnetsession, p, iInspectMode, FTPP_APPLY_TNC_ERASE_CMDS); + int ret = normalize_telnet(Telnetsession, p, iInspectMode, + FTPP_APPLY_TNC_ERASE_CMDS); - if ((iRet == FTPP_SUCCESS) || (iRet == FTPP_NORMALIZED)) - { + if ( ret == FTPP_SUCCESS || ret == FTPP_NORMALIZED ) do_detection(p); - } } - MODULE_PROFILE_END(telnetPerfStats); + + else + do_detection(p); + #ifdef PERF_PROFILING ft_update_perf(telnetPerfStats); #endif diff --git a/src/service_inspectors/http_inspect/hi_main.cc b/src/service_inspectors/http_inspect/hi_main.cc index a79e848a2..0a6f04981 100644 --- a/src/service_inspectors/http_inspect/hi_main.cc +++ b/src/service_inspectors/http_inspect/hi_main.cc @@ -527,8 +527,6 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p) int iCallDetect = 1; HttpSessionData* hsd = NULL; - PROFILE_VARS; - hi_stats.total++; /* @@ -612,12 +610,14 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p) return 0; } // see comments on call to snort_detect() below - MODULE_PROFILE_START(hiDetectPerfStats); - get_data_bus().publish(PACKET_EVENT, p); + PERF_PROFILE_BLOCK(hiDetectPerfStats) + { + get_data_bus().publish(PACKET_EVENT, p); #ifdef PERF_PROFILING - hiDetectCalled = 1; + hiDetectCalled = 1; #endif - MODULE_PROFILE_END(hiDetectPerfStats); + } + return 0; } @@ -1105,12 +1105,13 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p) ** better than having all these Packet struct field checks in the ** main detection engine for each protocol field. */ - MODULE_PROFILE_START(hiDetectPerfStats); - snort_detect(p); + PERF_PROFILE_BLOCK(hiDetectPerfStats) + { + snort_detect(p); #ifdef PERF_PROFILING - hiDetectCalled = 1; + hiDetectCalled = 1; #endif - MODULE_PROFILE_END(hiDetectPerfStats); + } /* ** We set the global detection flag here so that if request pipelines diff --git a/src/service_inspectors/http_inspect/http_inspect.cc b/src/service_inspectors/http_inspect/http_inspect.cc index 015ea0da5..9dc8f36c4 100644 --- a/src/service_inspectors/http_inspect/http_inspect.cc +++ b/src/service_inspectors/http_inspect/http_inspect.cc @@ -321,12 +321,11 @@ void HttpInspect::show(SnortConfig*) void HttpInspect::eval(Packet* p) { - PROFILE_VARS; + PERF_PROFILE(hiPerfStats); // preconditions - what we registered for assert(p->has_tcp_data()); - MODULE_PROFILE_START(hiPerfStats); hi_clear_events(); HttpInspectMain(config, p); @@ -342,7 +341,6 @@ void HttpInspect::eval(Packet* p) * spent in snort_detect(). * Subtract the ticks from this if iCallDetect == 0 */ - MODULE_PROFILE_END(hiPerfStats); #ifdef PERF_PROFILING if (hiDetectCalled) { diff --git a/src/service_inspectors/imap/imap.cc b/src/service_inspectors/imap/imap.cc index 7c27b07a1..c5de238b8 100644 --- a/src/service_inspectors/imap/imap.cc +++ b/src/service_inspectors/imap/imap.cc @@ -761,18 +761,15 @@ void Imap::show(SnortConfig*) void Imap::eval(Packet* p) { - PROFILE_VARS; + PERF_PROFILE(imapPerfStats); + // precondition - what we registered for assert(p->has_tcp_data()); assert(p->flow); ++imapstats.total_packets; - MODULE_PROFILE_START(imapPerfStats); - snort_imap(config, p); - - MODULE_PROFILE_END(imapPerfStats); } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/pop/pop.cc b/src/service_inspectors/pop/pop.cc index 88f97b555..514d8f6f8 100644 --- a/src/service_inspectors/pop/pop.cc +++ b/src/service_inspectors/pop/pop.cc @@ -696,18 +696,15 @@ void Pop::show(SnortConfig*) void Pop::eval(Packet* p) { - PROFILE_VARS; + PERF_PROFILE(popPerfStats); + // precondition - what we registered for assert(p->has_tcp_data()); assert(p->flow); ++popstats.total_packets; - MODULE_PROFILE_START(popPerfStats); - snort_pop(config, p); - - MODULE_PROFILE_END(popPerfStats); } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/rpc_decode/rpc_decode.cc b/src/service_inspectors/rpc_decode/rpc_decode.cc index fe4ebe2f9..c9aa53dbc 100644 --- a/src/service_inspectors/rpc_decode/rpc_decode.cc +++ b/src/service_inspectors/rpc_decode/rpc_decode.cc @@ -988,51 +988,45 @@ void RpcDecode::show(SnortConfig*) */ void RpcDecode::eval(Packet* p) { - RpcSsnData* rsdata = NULL; - PROFILE_VARS; + PERF_PROFILE(rpcdecodePerfStats); // preconditions - what we registered for assert(p->has_tcp_data()); - /* If we're stateful that means stream has been configured. - * In this case we don't look at server packets. - * There is the case were stream configuration requires a 3 way handshake. - * If no 3 way, then the packet flags won't be set, so don't look at it - * since we won't be able to determeine who's the client and who's the server. */ - if ( !(p->packet_flags & PKT_FROM_CLIENT) ) - { + // If we're stateful that means stream has been configured. + // In this case we don't look at server packets. + // There is the case were stream configuration requires a 3 way handshake. + // If no 3 way, then the packet flags won't be set, so don't look at it + // since we won't be able to determeine who's the client and who's the + // server. + if ( !p->from_client() ) return; - } - if ( p->flow != NULL ) + RpcSsnData* rsdata = nullptr; + + if ( p->flow ) { RpcFlowData* fd = (RpcFlowData*)p->flow->get_application_data( RpcFlowData::flow_id); - rsdata = fd ? &fd->session : NULL; + if ( fd ) + rsdata = &fd->session; } - MODULE_PROFILE_START(rpcdecodePerfStats); ++rdstats.total_packets; - if ((rsdata == NULL) && (p->flow != NULL)) - { - if (!stream.is_midstream(p->flow)) - rsdata = RpcSsnDataNew(p); - } + if ( !rsdata && p->flow && !stream.is_midstream(p->flow) ) + rsdata = RpcSsnDataNew(p); if ( RpcSsnIsActive(rsdata) and (p->packet_flags & PKT_REBUILT_STREAM) ) { RpcStatus ret = RpcStatefulInspection(&config, rsdata, p); if (ret == RPC_STATUS__SUCCESS) - { - MODULE_PROFILE_END(rpcdecodePerfStats); return; - } - /* Something went wrong - deactivate session tracking - * and decode normally */ + // Something went wrong - deactivate session tracking + // and decode normally if (ret == RPC_STATUS__ERROR) RpcSsnSetInactive(rsdata, p); } @@ -1040,8 +1034,6 @@ void RpcDecode::eval(Packet* p) DebugMessage(DEBUG_RPC,"Stateless inspection\n"); RpcPreprocEvent(&config, rsdata, ConvertRPC(&config, rsdata, p)); - - MODULE_PROFILE_END(rpcdecodePerfStats); } bool RpcDecode::get_buf(InspectionBuffer::Type ibt, Packet*, InspectionBuffer& b) diff --git a/src/service_inspectors/sip/ips_sip.cc b/src/service_inspectors/sip/ips_sip.cc index 6b4a7ffa2..ee73b7f01 100644 --- a/src/service_inspectors/sip/ips_sip.cc +++ b/src/service_inspectors/sip/ips_sip.cc @@ -97,29 +97,22 @@ private: int SipIpsOption::eval(Cursor& c, Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(sip_ps[idx]); + auto& sip_stats = sip_ps[idx]; + PERF_PROFILE(sip_stats); - int rval; SIPData* sd; SIP_Roptions* ropts; const uint8_t* data = NULL; unsigned len = 0; if ((!p->is_tcp() && !p->is_udp()) || !p->flow || !p->dsize) - { - MODULE_PROFILE_END(sip_ps[idx]); return DETECTION_OPTION_NO_MATCH; - } // FIXIT-P cache id at parse time for runtime use sd = get_sip_session_data(p->flow); if (!sd) - { - MODULE_PROFILE_END(sip_ps[idx]); return DETECTION_OPTION_NO_MATCH; - } ropts = &sd->ropts; @@ -140,15 +133,11 @@ int SipIpsOption::eval(Cursor& c, Packet* p) if (data != NULL) { c.set(key, data, len); - rval = DETECTION_OPTION_MATCH; - } - else - { - rval = DETECTION_OPTION_NO_MATCH; + return DETECTION_OPTION_MATCH; } - MODULE_PROFILE_END(sip_ps[idx]); - return rval; + else + return DETECTION_OPTION_NO_MATCH; } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/sip/ips_sip_method.cc b/src/service_inspectors/sip/ips_sip_method.cc index 36d925aec..bb86b7095 100644 --- a/src/service_inspectors/sip/ips_sip_method.cc +++ b/src/service_inspectors/sip/ips_sip_method.cc @@ -99,39 +99,24 @@ bool SipMethodOption::operator==(const IpsOption& ips) const int SipMethodOption::eval(Cursor&, Packet* p) { - SIPData* sd; - SIP_Roptions* ropts; - uint32_t methodFlag; - - PROFILE_VARS; - MODULE_PROFILE_START(sipMethodRuleOptionPerfStats); + PERF_PROFILE(sipMethodRuleOptionPerfStats); if ((!p->is_tcp() && !p->is_udp()) || !p->flow || !p->dsize) - { - MODULE_PROFILE_END(sipMethodRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } - sd = get_sip_session_data(p->flow); + SIPData* sd = get_sip_session_data(p->flow); if (!sd) - { - MODULE_PROFILE_END(sipMethodRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } - ropts = &sd->ropts; + SIP_Roptions* ropts = &sd->ropts; // Not response - methodFlag = 1 << (ropts->methodFlag - 1); + uint32_t methodFlag = 1 << (ropts->methodFlag - 1); if (IsRequest(ropts) && ((smod.flags & methodFlag) ^ smod.mask)) - { - MODULE_PROFILE_END(sipMethodRuleOptionPerfStats); return DETECTION_OPTION_MATCH; - } - MODULE_PROFILE_END(sipMethodRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; } diff --git a/src/service_inspectors/sip/ips_sip_stat_code.cc b/src/service_inspectors/sip/ips_sip_stat_code.cc index c8d535f4d..71b6ac695 100644 --- a/src/service_inspectors/sip/ips_sip_stat_code.cc +++ b/src/service_inspectors/sip/ips_sip_stat_code.cc @@ -61,50 +61,30 @@ private: int SipStatCodeOption::eval(Cursor&, Packet* p) { - SIPData* sd; - SIP_Roptions* ropts; - uint16_t short_code; - int i_code; - - PROFILE_VARS; - MODULE_PROFILE_START(sipStatCodeRuleOptionPerfStats); + PERF_PROFILE(sipStatCodeRuleOptionPerfStats); if ((!p->is_tcp() && !p->is_udp()) || !p->flow || !p->dsize) - { - MODULE_PROFILE_END(sipStatCodeRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } - sd = get_sip_session_data(p->flow); + SIPData* sd = get_sip_session_data(p->flow); if (!sd) - { - MODULE_PROFILE_END(sipStatCodeRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } - ropts = &sd->ropts; + SIP_Roptions* ropts = &sd->ropts; if (0 == ropts->status_code) - { - MODULE_PROFILE_END(sipStatCodeRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } - /*Match the stat code*/ - short_code = ropts->status_code / 100; - for (i_code = 0; i_code < SIP_NUM_STAT_CODE_MAX; i_code++) + // Match the stat code + uint16_t short_code = ropts->status_code / 100; + for ( int i = 0; i < SIP_NUM_STAT_CODE_MAX; i++ ) { - if ((ssod.stat_codes[i_code] == short_code)|| - (ssod.stat_codes[i_code] == ropts->status_code)) - { - MODULE_PROFILE_END(sipStatCodeRuleOptionPerfStats); + auto stat_code = ssod.stat_codes[i]; + if ( stat_code == short_code || stat_code == ropts->status_code ) return DETECTION_OPTION_MATCH; - } } - MODULE_PROFILE_END(sipStatCodeRuleOptionPerfStats); - return DETECTION_OPTION_NO_MATCH; } diff --git a/src/service_inspectors/sip/sip.cc b/src/service_inspectors/sip/sip.cc index 7884852b7..f6d1babc8 100644 --- a/src/service_inspectors/sip/sip.cc +++ b/src/service_inspectors/sip/sip.cc @@ -244,13 +244,10 @@ static inline int SIP_Process(Packet* p, SIPData* sessp, SIP_PROTO_CONF* config) */ static void snort_sip(SIP_PROTO_CONF* config, Packet* p) { - SIPData* sessp = NULL; - PROFILE_VARS; - - MODULE_PROFILE_START(sipPerfStats); + PERF_PROFILE(sipPerfStats); /* Attempt to get a previously allocated SIP block. */ - sessp = get_sip_session_data(p->flow); + SIPData* sessp = get_sip_session_data(p->flow); if (sessp == NULL) { @@ -260,23 +257,15 @@ static void snort_sip(SIP_PROTO_CONF* config, Packet* p) sessp = SetNewSIPData(p, config); if ( !sessp ) - { - /* Could not get/create the session data for this packet. */ - MODULE_PROFILE_END(sipPerfStats); + // Could not get/create the session data for this packet. return; - } } /* Don't process if we've missed packets */ if (sessp->state_flags & SIP_FLG_MISSED_PACKETS) - { - MODULE_PROFILE_END(sipPerfStats); return; - } SIP_Process(p,sessp, config); - - MODULE_PROFILE_END(sipPerfStats); } //------------------------------------------------------------------------- diff --git a/src/service_inspectors/smtp/smtp.cc b/src/service_inspectors/smtp/smtp.cc index 1afe97308..81364a615 100644 --- a/src/service_inspectors/smtp/smtp.cc +++ b/src/service_inspectors/smtp/smtp.cc @@ -1524,18 +1524,15 @@ void Smtp::show(SnortConfig*) void Smtp::eval(Packet* p) { - PROFILE_VARS; + PERF_PROFILE(smtpPerfStats); + // precondition - what we registered for assert(p->has_tcp_data()); assert(p->flow); ++smtpstats.total_packets; - MODULE_PROFILE_START(smtpPerfStats); - snort_smtp(config, p); - - MODULE_PROFILE_END(smtpPerfStats); } bool Smtp::get_buf( diff --git a/src/service_inspectors/ssh/ssh.cc b/src/service_inspectors/ssh/ssh.cc index cf1df7573..35319d7ad 100644 --- a/src/service_inspectors/ssh/ssh.cc +++ b/src/service_inspectors/ssh/ssh.cc @@ -140,16 +140,10 @@ static unsigned int SSHPacket_GetLength(SSH2Packet* p, size_t buflen) */ static void snort_ssh(SSH_PROTO_CONF* config, Packet* p) { - SSHData* sessp = NULL; - uint8_t direction; - unsigned int offset = 0; - uint32_t search_dir_ver, search_dir_keyinit; - PROFILE_VARS; - - MODULE_PROFILE_START(sshPerfStats); + PERF_PROFILE(sshPerfStats); - /* Attempt to get a previously allocated SSH block. */ - sessp = get_session_data(p->flow); + // Attempt to get a previously allocated SSH block. + SSHData* sessp = get_session_data(p->flow); if (sessp == NULL) { @@ -159,47 +153,39 @@ static void snort_ssh(SSH_PROTO_CONF* config, Packet* p) sessp = SetNewSSHData(p); if ( !sessp ) - { - /* Could not get/create the session data for this packet. */ - MODULE_PROFILE_END(sshPerfStats); + // Could not get/create the session data for this packet. return; - } } - - /* Don't process if we've missed packets */ + // Don't process if we've missed packets if (sessp->state_flags & SSH_FLG_MISSED_PACKETS) - { - MODULE_PROFILE_END(sshPerfStats); return; - } - /* Make sure this preprocessor should run. - check if we're waiting on stream reassembly */ + // Make sure this preprocessor should run. + // check if we're waiting on stream reassembly if ( p->packet_flags & PKT_STREAM_INSERT ) - { - MODULE_PROFILE_END(sshPerfStats); return; - } - /* If we picked up mid-stream or missed any packets (midstream pick up - * * means we've already missed packets) set missed packets flag and make - * * sure we don't do any more reassembly on this session */ + // If we picked up mid-stream or missed any packets (midstream pick up + // means we've already missed packets) set missed packets flag and make + // sure we don't do any more reassembly on this session if ((p->flow->get_session_flags() & SSNFLAG_MIDSTREAM) || stream.missed_packets(p->flow, SSN_DIR_BOTH)) { - /* Order only matters if the packets are not encrypted */ + // Order only matters if the packets are not encrypted if ( !(sessp->state_flags & SSH_FLG_SESS_ENCRYPTED )) { sessp->state_flags |= SSH_FLG_MISSED_PACKETS; - - MODULE_PROFILE_END(sshPerfStats); return; } } - /* Get the direction of the packet. */ + uint8_t direction; + uint32_t search_dir_ver; + uint32_t search_dir_keyinit; + + // Get the direction of the packet. if ( p->packet_flags & PKT_FROM_SERVER ) { direction = SSH_DIR_FROM_SERVER; @@ -212,28 +198,28 @@ static void snort_ssh(SSH_PROTO_CONF* config, Packet* p) search_dir_ver = SSH_FLG_CLIENT_IDSTRING_SEEN; search_dir_keyinit = SSH_FLG_CLIENT_SKEY_SEEN | SSH_FLG_CLIENT_KEXINIT_SEEN; } + + unsigned int offset = 0; + if ( !(sessp->state_flags & SSH_FLG_SESS_ENCRYPTED )) { - /* If server and client have not performed the protocol - * version exchange yet, must look for version strings. - */ + // If server and client have not performed the protocol + // version exchange yet, must look for version strings. if ( !(sessp->state_flags & search_dir_ver) ) { offset = ProcessSSHProtocolVersionExchange(config, sessp, p, direction); if (!offset) - { - /*Error processing protovers exchange msg */ - MODULE_PROFILE_END(sshPerfStats); + // Error processing protovers exchange msg return; - } - /* found protocol version. Stream reassembly might have appended an ssh packet, - * such as the key exchange init. Thus call ProcessSSHKeyInitExchange() too. - */ + + // found protocol version. + // Stream reassembly might have appended an ssh packet, + // such as the key exchange init. + // Thus call ProcessSSHKeyInitExchange() too. } - /* Expecting to see the key init exchange at this point - * (in SSH2) or the actual key exchange if SSH1 - */ + // Expecting to see the key init exchange at this point + // (in SSH2) or the actual key exchange if SSH1 if ( !(sessp->state_flags & search_dir_keyinit) ) { offset = ProcessSSHKeyInitExchange(sessp, p, direction, offset); @@ -241,33 +227,26 @@ static void snort_ssh(SSH_PROTO_CONF* config, Packet* p) if (!offset) { if ( !(sessp->state_flags & SSH_FLG_SESS_ENCRYPTED )) - { - MODULE_PROFILE_END(sshPerfStats); return; - } } } - /* If SSH2, need to process the actual key exchange msgs. - * The actual key exchange type was negotiated in the - * key exchange init msgs. SSH1 won't arrive here. - */ + // If SSH2, need to process the actual key exchange msgs. + // The actual key exchange type was negotiated in the + // key exchange init msgs. SSH1 won't arrive here. offset = ProcessSSHKeyExchange(sessp, p, direction, offset); if (!offset) - { - MODULE_PROFILE_END(sshPerfStats); return; - } } + if ( (sessp->state_flags & SSH_FLG_SESS_ENCRYPTED )) { - /* Traffic on this session is currently encrypted. - * Two of the major SSH exploits, SSH1 CRC-32 and - * the Challenge-Response Overflow attack occur within - * the encrypted portion of the SSH session. Therefore, - * the only way to detect these attacks is by examining - * amounts of data exchanged for anomalies. - */ + // Traffic on this session is currently encrypted. + // Two of the major SSH exploits, SSH1 CRC-32 and + // the Challenge-Response Overflow attack occur within + // the encrypted portion of the SSH session. Therefore, + // the only way to detect these attacks is by examining + // amounts of data exchanged for anomalies. sessp->num_enc_pkts++; if ( sessp->num_enc_pkts <= config->MaxEncryptedPackets ) @@ -275,58 +254,43 @@ static void snort_ssh(SSH_PROTO_CONF* config, Packet* p) if ( direction == SSH_DIR_FROM_CLIENT ) { if (!offset) - { sessp->num_client_bytes += p->dsize; - } + else - { sessp->num_client_bytes += (p->dsize - offset); - } if ( sessp->num_client_bytes >= config->MaxClientBytes ) { - /* Probable exploit in progress.*/ + // Probable exploit in progress. if (sessp->version == SSH_VERSION_1) - { - { - SnortEventqAdd(GID_SSH, SSH_EVENT_CRC32); + SnortEventqAdd(GID_SSH, SSH_EVENT_CRC32); - stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0); - } - } else - { - { - SnortEventqAdd(GID_SSH, SSH_EVENT_RESPOVERFLOW); + SnortEventqAdd(GID_SSH, SSH_EVENT_RESPOVERFLOW); - stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0); - } - } + stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0); } } + else { - /* - * Have seen a server response, so - * this appears to be a valid exchange. - * Reset suspicious byte count to zero. - */ + // Have seen a server response, so this appears to be a valid + // exchange. Reset suspicious byte count to zero sessp->num_client_bytes = 0; } } + else { - /* Have already examined more than the limit - * of encrypted packets. Both the Gobbles and - * the CRC32 attacks occur during authentication - * and therefore cannot be used late in an - * encrypted session. For performance purposes, - * stop examining this session. - */ + // Have already examined more than the limit + // of encrypted packets. Both the Gobbles and + // the CRC32 attacks occur during authentication + // and therefore cannot be used late in an + // encrypted session. For performance purposes, + // stop examining this session. stream.stop_inspection(p->flow, p, SSN_DIR_BOTH, -1, 0); } } - MODULE_PROFILE_END(sshPerfStats); } /* Checks if the string 'str' is 'max' bytes long or longer. diff --git a/src/service_inspectors/ssl/ips_ssl_state.cc b/src/service_inspectors/ssl/ips_ssl_state.cc index e682404cb..b3c950de6 100644 --- a/src/service_inspectors/ssl/ips_ssl_state.cc +++ b/src/service_inspectors/ssl/ips_ssl_state.cc @@ -98,38 +98,21 @@ bool SslStateOption::operator==(const IpsOption& ips) const int SslStateOption::eval(Cursor&, Packet* pkt) { - SSLData* sd; - - PROFILE_VARS; - MODULE_PROFILE_START(sslStateRuleOptionPerfStats); + PERF_PROFILE(sslStateRuleOptionPerfStats); if ( !(pkt->packet_flags & PKT_REBUILT_STREAM) && !pkt->is_full_pdu() ) - { - MODULE_PROFILE_END(sslStateRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } if (!pkt->flow) - { - MODULE_PROFILE_END(sslStateRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } - sd = get_ssl_session_data(pkt->flow); + SSLData* sd = get_ssl_session_data(pkt->flow); if (!sd) - { - MODULE_PROFILE_END(sslStateRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } if ((ssod.flags & sd->ssn_flags) ^ ssod.mask) - { - MODULE_PROFILE_END(sslStateRuleOptionPerfStats); return DETECTION_OPTION_MATCH; - } - - MODULE_PROFILE_END(sslStateRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; } diff --git a/src/service_inspectors/ssl/ips_ssl_version.cc b/src/service_inspectors/ssl/ips_ssl_version.cc index 536110165..156d5247c 100644 --- a/src/service_inspectors/ssl/ips_ssl_version.cc +++ b/src/service_inspectors/ssl/ips_ssl_version.cc @@ -98,38 +98,21 @@ bool SslVersionOption::operator==(const IpsOption& ips) const int SslVersionOption::eval(Cursor&, Packet* pkt) { - SSLData* sd; - - PROFILE_VARS; - MODULE_PROFILE_START(sslVersionRuleOptionPerfStats); + PERF_PROFILE(sslVersionRuleOptionPerfStats); if ( !(pkt->packet_flags & PKT_REBUILT_STREAM) && !pkt->is_full_pdu() ) - { - MODULE_PROFILE_END(sslVersionRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } if (!pkt->flow) - { - MODULE_PROFILE_END(sslVersionRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } - sd = get_ssl_session_data(pkt->flow); + SSLData* sd = get_ssl_session_data(pkt->flow); if (!sd) - { - MODULE_PROFILE_END(sslVersionRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; - } if ((svod.flags & sd->ssn_flags) ^ svod.mask) - { - MODULE_PROFILE_END(sslVersionRuleOptionPerfStats); return DETECTION_OPTION_MATCH; - } - - MODULE_PROFILE_END(sslVersionRuleOptionPerfStats); return DETECTION_OPTION_NO_MATCH; } diff --git a/src/service_inspectors/ssl/ssl_inspector.cc b/src/service_inspectors/ssl/ssl_inspector.cc index fd5ec07ce..fb2a398b3 100644 --- a/src/service_inspectors/ssl/ssl_inspector.cc +++ b/src/service_inspectors/ssl/ssl_inspector.cc @@ -296,17 +296,10 @@ static inline void SSLPP_process_other(SSL_PROTO_CONF* config, SSLData* sd, uint */ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p) { - SSLData* sd = NULL; - uint8_t dir; - uint8_t index; - uint32_t new_flags; - uint8_t heartbleed_type = 0; - PROFILE_VARS; - - MODULE_PROFILE_START(sslPerfStats); + PERF_PROFILE(sslPerfStats); /* Attempt to get a previously allocated SSL block. */ - sd = get_ssl_session_data(p->flow); + SSLData* sd = get_ssl_session_data(p->flow); if (sd == NULL) { @@ -316,17 +309,17 @@ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p) sd = SetNewSSLData(p); if ( !sd ) - { - /* Could not get/create the session data for this packet. */ - MODULE_PROFILE_END(sslPerfStats); + // Could not get/create the session data for this packet. return; - } } + SSL_CLEAR_TEMPORARY_FLAGS(sd->ssn_flags); - dir = (p->packet_flags & PKT_FROM_SERVER) ? 1 : 0; - index = (p->packet_flags & PKT_REBUILT_STREAM) ? 2 : 0; - new_flags = SSL_decode(p->data, (int)p->dsize, p->packet_flags, sd->ssn_flags, + uint8_t dir = (p->packet_flags & PKT_FROM_SERVER) ? 1 : 0; + uint8_t index = (p->packet_flags & PKT_REBUILT_STREAM) ? 2 : 0; + + uint8_t heartbleed_type = 0; + uint32_t new_flags = SSL_decode(p->data, (int)p->dsize, p->packet_flags, sd->ssn_flags, &heartbleed_type, &(sd->partial_rec_len[dir+index]), config->max_heartbeat_len); if (heartbleed_type & SSL_HEARTBLEED_REQUEST) @@ -361,7 +354,6 @@ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p) sd->ssn_flags |= new_flags; - MODULE_PROFILE_END(sslPerfStats); return; } @@ -416,13 +408,10 @@ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p) /* Application data is updated inside of SSLPP_process_other */ - MODULE_PROFILE_END(sslPerfStats); return; } sd->ssn_flags |= new_flags; - - MODULE_PROFILE_END(sslPerfStats); } //------------------------------------------------------------------------- diff --git a/src/stream/base/stream_base.cc b/src/stream/base/stream_base.cc index 62451db61..344e9a365 100644 --- a/src/stream/base/stream_base.cc +++ b/src/stream/base/stream_base.cc @@ -243,13 +243,11 @@ void StreamBase::show(SnortConfig*) void StreamBase::eval(Packet* p) { - PROFILE_VARS; + PERF_PROFILE(s5PerfStats); if ( !is_eligible(p) ) return; - MODULE_PROFILE_START(s5PerfStats); - switch ( p->type() ) { case PktType::IP: @@ -286,8 +284,6 @@ void StreamBase::eval(Packet* p) default: break; } - - MODULE_PROFILE_END(s5PerfStats); } #if 0 diff --git a/src/stream/file/file_session.cc b/src/stream/file/file_session.cc index 48cf57a51..891b09310 100644 --- a/src/stream/file/file_session.cc +++ b/src/stream/file/file_session.cc @@ -72,8 +72,7 @@ static FilePosition position(Packet* p) int FileSession::process(Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(file_ssn_stats); + PERF_PROFILE(file_ssn_stats); p->flow->ssn_state.application_protocol = SNORT_PROTO_USER; StreamFileConfig* c = get_file_cfg(p->flow->ssn_server); @@ -84,7 +83,6 @@ int FileSession::process(Packet* p) file_flows->file_process((uint8_t*)p->data, p->dsize, position(p), c->upload); set_file_data((uint8_t*)p->data, p->dsize); - MODULE_PROFILE_END(file_ssn_stats); return 0; } diff --git a/src/stream/ip/ip_defrag.cc b/src/stream/ip/ip_defrag.cc index 6a6972e3a..141a9d2d7 100644 --- a/src/stream/ip/ip_defrag.cc +++ b/src/stream/ip/ip_defrag.cc @@ -776,18 +776,17 @@ static inline int FragIsComplete(FragTracker* ft) */ static void FragRebuild(FragTracker* ft, Packet* p) { + PERF_PROFILE(fragRebuildPerfStats); + static THREAD_LOCAL uint8_t encap_frag_cnt = 0; uint8_t* rebuild_ptr = NULL; /* ptr to the start of the reassembly buffer */ const uint8_t* rebuild_end; /* ptr to the end of the reassembly buffer */ Fragment* frag; /* frag pointer for managing fragments */ int ret = 0; Packet* dpkt; - PROFILE_VARS; // XXX NOT YET IMPLEMENTED - debugging - MODULE_PROFILE_START(fragRebuildPerfStats); - if (!defrag_pkts[encap_frag_cnt]) defrag_pkts[encap_frag_cnt] = PacketManager::encode_new(); @@ -929,7 +928,6 @@ static void FragRebuild(FragTracker* ft, Packet* p) sfBase.iFragFlushes++; /* Rebuild is complete */ - MODULE_PROFILE_END(fragRebuildPerfStats); /* * process the packet through the detection engine @@ -1159,7 +1157,6 @@ void Defrag::process(Packet* p, FragTracker* ft) { FragEngine* fe = &engine; int insert_return = 0; /* return value from the insert function */ - PROFILE_VARS; // preconditions - what we registered for assert(p->has_ip() && !(p->ptrs.decode_flags & DECODE_ERR_CKSUM_IP)); @@ -1218,14 +1215,13 @@ void Defrag::process(Packet* p, FragTracker* ft) ip_stats.total++; UpdateIPFragStats(&sfBase, p->pkth->caplen); - MODULE_PROFILE_START(fragPerfStats); + PERF_PROFILE(fragPerfStats); pkttime = (struct timeval*)&p->pkth->ts; if (!ft->engine ) { new_tracker(p, ft); - MODULE_PROFILE_END(fragPerfStats); return; } else if (expire(p, ft, fe) == FRAG_TRACKER_TIMEOUT) @@ -1270,7 +1266,6 @@ void Defrag::process(Packet* p, FragTracker* ft) LogMessage("WARNING: Insert into Fraglist failed, " "(offset: %u).\n", frag_offset); #endif - MODULE_PROFILE_END(fragPerfStats); return; case FRAG_INSERT_TTL: @@ -1288,19 +1283,16 @@ void Defrag::process(Packet* p, FragTracker* ft) } #endif ip_stats.discards++; - MODULE_PROFILE_END(fragPerfStats); return; case FRAG_INSERT_ATTACK: case FRAG_INSERT_ANOMALY: ip_stats.discards++; - MODULE_PROFILE_END(fragPerfStats); return; case FRAG_INSERT_TIMEOUT: #ifdef DEBUG LogMessage("WARNING: Insert into Fraglist failed due to timeout, " "(offset: %u).\n", frag_offset); #endif - MODULE_PROFILE_END(fragPerfStats); return; case FRAG_INSERT_OVERLAP_LIMIT: #ifdef DEBUG @@ -1310,7 +1302,6 @@ void Defrag::process(Packet* p, FragTracker* ft) (frag_offset << 3), p->dsize); #endif ip_stats.discards++; - MODULE_PROFILE_END(fragPerfStats); return; default: break; @@ -1354,8 +1345,6 @@ void Defrag::process(Packet* p, FragTracker* ft) release_tracker(ft); } } - - MODULE_PROFILE_END(fragPerfStats); } /** @@ -1397,12 +1386,11 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) Fragment* dump_me = NULL; /* frag ptr for complete overlaps to dump */ const uint8_t* fragStart; int16_t fragLength; - PROFILE_VARS; const uint16_t net_frag_offset = p->ptrs.ip_api.off(); sfBase.iFragInserts++; - MODULE_PROFILE_START(fragInsertPerfStats); + PERF_PROFILE(fragInsertPerfStats); if (p->is_ip6() && (net_frag_offset == 0)) { @@ -1491,7 +1479,6 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) EventAnomOversize(fe); - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_ANOMALY; } ft->calculated_size = frag_end; @@ -1508,7 +1495,6 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) EventAnomZeroFrag(fe); - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_ANOMALY; } @@ -1524,7 +1510,6 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) ft->frag_flags |= FRAG_BAD; - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_ANOMALY; } @@ -1608,7 +1593,6 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) ft->frag_flags |= FRAG_BAD; - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_ATTACK; } } @@ -1646,7 +1630,6 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) EventAnomZeroFrag(fe); - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_ANOMALY; } @@ -1688,7 +1671,6 @@ int Defrag::insert(Packet* p, FragTracker* ft, FragEngine* fe) { /* Some warning here, * no, its done in add_frag_node */ - MODULE_PROFILE_END(fragInsertPerfStats); return ret; } left->size -= (int16_t)overlap; @@ -1736,7 +1718,6 @@ left_overlap_last: EventAnomBadsizeSm(fe); - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_ANOMALY; } } @@ -1752,7 +1733,6 @@ left_overlap_last: "Overly large fragment %d 0x%x 0x%x %d\n", fragLength, p->ptrs.ip_api.dgram_len(), p->ptrs.ip_api.off(), net_frag_offset); - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_FAILED; } @@ -1789,7 +1769,6 @@ left_overlap_last: ft->frag_flags |= FRAG_BAD; - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_ATTACK; } } @@ -1973,7 +1952,6 @@ left_overlap_last: ip_stats.discards++; - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_ANOMALY; } @@ -1992,7 +1970,6 @@ left_overlap_last: { /* Some warning here, * no, its done in add_frag_node */ - MODULE_PROFILE_END(fragInsertPerfStats); return ret; } @@ -2080,7 +2057,6 @@ right_overlap_last: EventExcessiveOverlap(fe); - MODULE_PROFILE_END(fragInsertPerfStats); return FRAG_INSERT_OVERLAP_LIMIT; } @@ -2098,7 +2074,6 @@ right_overlap_last: DebugMessage(DEBUG_FRAG, "insert(): returning normally\n"); - MODULE_PROFILE_END(fragInsertPerfStats); return ret; } diff --git a/src/stream/ip/ip_session.cc b/src/stream/ip/ip_session.cc index c66d1e700..ca78b2108 100644 --- a/src/stream/ip/ip_session.cc +++ b/src/stream/ip/ip_session.cc @@ -132,18 +132,14 @@ bool IpSession::setup(Packet*) #ifdef ENABLE_EXPECTED_IP if ( flow_con->expected_session(flow, p)) - { - MODULE_PROFILE_END(ip_perf_stats); return false; - } #endif return true; } int IpSession::process(Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(ip_perf_stats); + PERF_PROFILE(ip_perf_stats); if ( stream.expired_session(flow, p) ) { @@ -152,18 +148,12 @@ int IpSession::process(Packet* p) #ifdef ENABLE_EXPECTED_IP if ( flow_con->expected_session(flow, p)) - { - MODULE_PROFILE_END(ip_perf_stats); return 0; - } #endif } if ( stream.blocked_session(flow, p) || stream.ignored_session(flow, p) ) - { - MODULE_PROFILE_END(ip_perf_stats); return 0; - } if ( p->ptrs.decode_flags & DECODE_FRAG ) { @@ -173,7 +163,6 @@ int IpSession::process(Packet* p) UpdateSession(p, flow); - MODULE_PROFILE_END(ip_perf_stats); return 0; } diff --git a/src/stream/tcp/ips_stream_reassemble.cc b/src/stream/tcp/ips_stream_reassemble.cc index 1036ebcdb..65933cdd6 100644 --- a/src/stream/tcp/ips_stream_reassemble.cc +++ b/src/stream/tcp/ips_stream_reassemble.cc @@ -112,53 +112,52 @@ int ReassembleOption::eval(Cursor&, Packet* pkt) if (!pkt->flow || !pkt->ptrs.tcph) return 0; - PROFILE_VARS; - MODULE_PROFILE_START(streamReassembleRuleOptionPerfStats); - - Flow* lwssn = (Flow*)pkt->flow; - TcpSession* tcpssn = (TcpSession*)lwssn->session; - - if ( !srod.enable ) /* Turn it off */ + PERF_PROFILE_BLOCK(streamReassembleRuleOptionPerfStats) { - if ( srod.direction & SSN_DIR_FROM_SERVER ) - { - tcpssn->server.flush_policy = STREAM_FLPOLICY_IGNORE; - stream.set_splitter(lwssn, true); - } + Flow* lwssn = (Flow*)pkt->flow; + TcpSession* tcpssn = (TcpSession*)lwssn->session; - if ( srod.direction & SSN_DIR_FROM_CLIENT ) + if ( !srod.enable ) /* Turn it off */ { - tcpssn->client.flush_policy = STREAM_FLPOLICY_IGNORE; - stream.set_splitter(lwssn, false); + if ( srod.direction & SSN_DIR_FROM_SERVER ) + { + tcpssn->server.flush_policy = STREAM_FLPOLICY_IGNORE; + stream.set_splitter(lwssn, true); + } + + if ( srod.direction & SSN_DIR_FROM_CLIENT ) + { + tcpssn->client.flush_policy = STREAM_FLPOLICY_IGNORE; + stream.set_splitter(lwssn, false); + } } - } - else - { - // FIXIT-M PAF need to instantiate service splitter? - // FIXIT-M PAF need to check for ips / on-data - if ( srod.direction & SSN_DIR_FROM_SERVER ) + else { - tcpssn->server.flush_policy = STREAM_FLPOLICY_ON_ACK; - stream.set_splitter(lwssn, true, new AtomSplitter(true)); + // FIXIT-M PAF need to instantiate service splitter? + // FIXIT-M PAF need to check for ips / on-data + if ( srod.direction & SSN_DIR_FROM_SERVER ) + { + tcpssn->server.flush_policy = STREAM_FLPOLICY_ON_ACK; + stream.set_splitter(lwssn, true, new AtomSplitter(true)); + } + + if ( srod.direction & SSN_DIR_FROM_CLIENT ) + { + tcpssn->client.flush_policy = STREAM_FLPOLICY_ON_ACK; + stream.set_splitter(lwssn, false, new AtomSplitter(false)); + } } - if ( srod.direction & SSN_DIR_FROM_CLIENT ) + if (srod.fastpath) { - tcpssn->client.flush_policy = STREAM_FLPOLICY_ON_ACK; - stream.set_splitter(lwssn, false, new AtomSplitter(false)); - } - } + /* Turn off inspection */ + lwssn->ssn_state.ignore_direction |= srod.direction; + DisableInspection(pkt); - if (srod.fastpath) - { - /* Turn off inspection */ - lwssn->ssn_state.ignore_direction |= srod.direction; - DisableInspection(pkt); - - /* TBD: Set TF_FORCE_FLUSH ? */ + /* TBD: Set TF_FORCE_FLUSH ? */ + } } - MODULE_PROFILE_END(streamReassembleRuleOptionPerfStats); if (srod.alert) return DETECTION_OPTION_MATCH; diff --git a/src/stream/tcp/ips_stream_size.cc b/src/stream/tcp/ips_stream_size.cc index 4289b2fcd..77a713691 100644 --- a/src/stream/tcp/ips_stream_size.cc +++ b/src/stream/tcp/ips_stream_size.cc @@ -96,12 +96,11 @@ bool SizeOption::operator==(const IpsOption& ips) const int SizeOption::eval(Cursor&, Packet* pkt) { + PERF_PROFILE(streamSizePerfStats); + if (!pkt->flow || !pkt->ptrs.tcph) return DETECTION_OPTION_NO_MATCH; - PROFILE_VARS; - MODULE_PROFILE_START(streamSizePerfStats); - Flow* lwssn = (Flow*)pkt->flow; TcpSession* tcpssn = (TcpSession*)lwssn->session; @@ -157,7 +156,7 @@ int SizeOption::eval(Cursor&, Packet* pkt) default: break; } - MODULE_PROFILE_END(streamSizePerfStats); + return result; } diff --git a/src/stream/tcp/tcp_reassembly.cc b/src/stream/tcp/tcp_reassembly.cc index 7640b72f6..e8d40b0eb 100644 --- a/src/stream/tcp/tcp_reassembly.cc +++ b/src/stream/tcp/tcp_reassembly.cc @@ -681,13 +681,14 @@ static inline unsigned int getSegmentFlushSize(TcpTracker* st, TcpSegment *ss, static int FlushStream(Packet* p, TcpTracker *st, uint32_t toSeq, uint8_t *flushbuf, const uint8_t *flushbuf_end) { + PERF_PROFILE(s5TcpBuildPacketPerfStats); + uint16_t bytes_flushed = 0; DEBUG_WRAP(uint32_t bytes_queued = st->seg_bytes_logical; ); uint32_t segs = 0; uint32_t flags = PKT_PDU_HEAD; - PROFILE_VARS; - assert(st->seglist_next); MODULE_PROFILE_START(s5TcpBuildPacketPerfStats); + assert(st->seglist_next); uint32_t total = toSeq - st->seglist_next->seq; @@ -771,7 +772,6 @@ static int FlushStream(Packet* p, TcpTracker *st, uint32_t toSeq, DebugFormat(DEBUG_STREAM_STATE, "flushed %d bytes / %d segs on stream, %d still queued\n", bytes_flushed, segs, bytes_queued); - MODULE_PROFILE_END(s5TcpBuildPacketPerfStats); return bytes_flushed; } @@ -826,14 +826,13 @@ static void prep_s5_pkt(Flow* flow, Packet* p, uint32_t pkt_flags) static inline int _flush_to_seq(TcpSession *tcpssn, TcpTracker *st, uint32_t bytes, Packet *p, uint32_t pkt_flags) { + PERF_PROFILE(s5TcpFlushPerfStats); + uint32_t stop_seq; uint32_t footprint; uint32_t bytes_processed = 0; int32_t flushed_bytes; EncodeFlags enc_flags = 0; - PROFILE_VARS; - - MODULE_PROFILE_START(s5TcpFlushPerfStats); #ifdef HAVE_DAQ_ADDRESS_SPACE_ID DAQ_PktHdr_t pkth; @@ -861,7 +860,6 @@ static inline int _flush_to_seq(TcpSession *tcpssn, TcpTracker *st, { DebugFormat(DEBUG_STREAM_STATE, "Negative footprint, bailing %d (0x%X - 0x%X)\n", footprint, stop_seq, st->seglist_base_seq); - MODULE_PROFILE_END(s5TcpFlushPerfStats); return bytes_processed; } @@ -914,14 +912,11 @@ static inline int _flush_to_seq(TcpSession *tcpssn, TcpTracker *st, tcpStats.rebuilt_packets++; UpdateStreamReassStats(&sfBase, flushed_bytes); - MODULE_PROFILE_TMPEND(s5TcpFlushPerfStats); + PERF_PAUSE_BLOCK(s5TcpFlushPerfStats) + PERF_PROFILE_BLOCK(s5TcpProcessRebuiltPerfStats) { - PROFILE_VARS; MODULE_PROFILE_START(s5TcpProcessRebuiltPerfStats); - Snort::detect_rebuilt_packet(s5_pkt); - - MODULE_PROFILE_END(s5TcpProcessRebuiltPerfStats); - } MODULE_PROFILE_TMPSTART(s5TcpFlushPerfStats); + } } st->seglist_base_seq += flushed_bytes; @@ -946,7 +941,6 @@ static inline int _flush_to_seq(TcpSession *tcpssn, TcpTracker *st, } while (st->seglist_next and DataToFlush(st)); /* tell them how many bytes we processed */ - MODULE_PROFILE_END(s5TcpFlushPerfStats); return bytes_processed; } @@ -1167,15 +1161,14 @@ static inline uint32_t GetForwardDir(const Packet* p) // because we don't wait until it is acknowledged static inline uint32_t flush_pdu_ips(TcpSession* ssn, TcpTracker* trk, uint32_t* flags) { - uint32_t total = 0, avail; - TcpSegment* seg; - PROFILE_VARS; + PERF_PROFILE(s5TcpPAFPerfStats); - MODULE_PROFILE_START(s5TcpPAFPerfStats); - avail = get_q_sequenced(trk); - seg = trk->seglist_next; + TcpSegment* seg = trk->seglist_next; - // * must stop if gap (checked in paf_check) + uint32_t total = 0; + uint32_t avail = get_q_sequenced(trk); + + // must stop if gap (checked in paf_check) while (seg && *flags && (total < avail)) { int32_t flush_pt; @@ -1196,8 +1189,6 @@ static inline uint32_t flush_pdu_ips(TcpSession* ssn, TcpTracker* trk, uint32_t* if (flush_pt >= 0) { - MODULE_PROFILE_END(s5TcpPAFPerfStats); - // see flush_pdu_ackd() if (!trk->splitter->is_paf() && avail > (unsigned) flush_pt) { @@ -1209,7 +1200,6 @@ static inline uint32_t flush_pdu_ips(TcpSession* ssn, TcpTracker* trk, uint32_t* seg = seg->next; } - MODULE_PROFILE_END(s5TcpPAFPerfStats); return -1; } @@ -1241,12 +1231,15 @@ static inline void fallback(TcpTracker* a) static inline uint32_t flush_pdu_ackd(TcpSession* ssn, TcpTracker* trk, uint32_t* flags) { - uint32_t total = 0; + PERF_PROFILE(s5TcpPAFPerfStats); + TcpSegment* seg; - PROFILE_VARS; + if ( SEQ_LT(trk->seglist_base_seq, trk->r_win_base) ) + seg = trk->seglist; + else + seg = nullptr; - MODULE_PROFILE_START(s5TcpPAFPerfStats); - seg = SEQ_LT(trk->seglist_base_seq, trk->r_win_base) ? trk->seglist : NULL; + uint32_t total = 0; // * must stop if not acked // * must use adjusted size of seg if not fully acked @@ -1274,8 +1267,6 @@ static inline uint32_t flush_pdu_ackd(TcpSession* ssn, TcpTracker* trk, if (flush_pt >= 0) { - MODULE_PROFILE_END(s5TcpPAFPerfStats); - // for non-paf splitters, flush_pt > 0 means we reached // the minimum required, but we flush what is available // instead of creating more, but smaller, packets @@ -1296,9 +1287,9 @@ static inline uint32_t flush_pdu_ackd(TcpSession* ssn, TcpTracker* trk, seg = seg->next; } - MODULE_PROFILE_END(s5TcpPAFPerfStats); return -1; } + int CheckFlushPolicyOnData(TcpSession *tcpssn, TcpTracker *talker, TcpTracker *listener, Packet *p) { uint32_t flushed = 0; @@ -1481,7 +1472,6 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) const uint8_t* rdata = tdb->pkt->data; uint16_t rsize = tdb->pkt->dsize; uint32_t rseq = tdb->seq; - PROFILE_VARS; DEBUG_WRAP( TcpSegment *lastptr = NULL; uint32_t base_seq = st->seglist_base_seq; @@ -1503,7 +1493,7 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) DebugMessage(DEBUG_STREAM_STATE, "!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+\n"); DebugMessage(DEBUG_STREAM_STATE, "!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+\n"); - MODULE_PROFILE_START(s5TcpInsertPerfStats); + PERF_PROFILE(s5TcpInsertPerfStats); // NORM fast tracks are in sequence - no norms if (st->seglist_tail && SegmentFastTrack(st->seglist_tail, tdb)) @@ -1518,7 +1508,6 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) // BLOCK add to existing block and/or allocate new block ret = AddStreamNode(st, tdb, len, slide /* 0 */, trunc /* 0 */, seq, left /* tail */); - MODULE_PROFILE_END(s5TcpInsertPerfStats); return ret; } @@ -1673,7 +1662,6 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) /* flag an anomaly */ EventBadSegment(); inc_tcp_discards(); - MODULE_PROFILE_END(s5TcpInsertPerfStats); return STREAM_INSERT_ANOMALY; } break; @@ -1697,7 +1685,6 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) /* flag an anomaly */ EventBadSegment(); inc_tcp_discards(); - MODULE_PROFILE_END(s5TcpInsertPerfStats); return STREAM_INSERT_ANOMALY; } } @@ -1725,7 +1712,6 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) if (ret != STREAM_INSERT_OK) { /* No warning, its done in StreamSeglistAddNode */ - MODULE_PROFILE_END(s5TcpInsertPerfStats); return ret; } left->size -= (int16_t) overlap; @@ -1756,7 +1742,6 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) /* flag an anomaly */ EventBadSegment(); inc_tcp_discards(); - MODULE_PROFILE_END(s5TcpInsertPerfStats); return STREAM_INSERT_ANOMALY; } } @@ -1947,7 +1932,6 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) "(seq: %X seq_end: %X overlap: %lu\n", seq, seq_end, overlap); EventBadSegment(); inc_tcp_discards(); - MODULE_PROFILE_END(s5TcpInsertPerfStats); return STREAM_INSERT_ANOMALY; } @@ -1967,11 +1951,8 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) slide = seq - tdb->seq; ret = AddStreamNode(st, tdb, len, slide, trunc, seq, left); if (ret != STREAM_INSERT_OK) - { - /* no warning, already done above */ - MODULE_PROFILE_END(s5TcpInsertPerfStats); + // no warning, already done above return ret; - } /* Set seq to end of right since overlap was greater than * or equal to right->size and inserted seq has been @@ -2002,7 +1983,6 @@ int StreamQueue(TcpTracker *st, TcpDataBlock *tdb, TcpSession *tcpssn) seq, seq_end, overlap); EventBadSegment(); inc_tcp_discards(); - MODULE_PROFILE_END(s5TcpInsertPerfStats); return STREAM_INSERT_ANOMALY; } break; @@ -2033,7 +2013,6 @@ right_overlap_last: DebugMessage(DEBUG_STREAM_STATE, "StreamQueue returning normally\n"); - MODULE_PROFILE_END(s5TcpInsertPerfStats); return ret; } diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index dbfe3728c..5f6c2d85a 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -857,9 +857,9 @@ static inline void EndOfFileHandle(Packet* p, TcpSession* tcpssn) static void NewQueue(TcpTracker *st, TcpDataBlock *tdb) { - const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; + PERF_PROFILE(s5TcpInsertPerfStats); - PROFILE_VARS; MODULE_PROFILE_START(s5TcpInsertPerfStats); + const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; DebugMessage(DEBUG_STREAM_STATE, "In NewQueue\n"); @@ -878,7 +878,6 @@ static void NewQueue(TcpTracker *st, TcpDataBlock *tdb) if (overlap >= tdb->pkt->dsize) { DebugMessage(DEBUG_STREAM_STATE, "full overlap on ack'd data, dropping segment\n"); - MODULE_PROFILE_END(s5TcpInsertPerfStats); return; } } @@ -888,8 +887,6 @@ static void NewQueue(TcpTracker *st, TcpDataBlock *tdb) DebugFormat(DEBUG_STREAM_STATE, "Attached new queue to seglist, %d bytes queued, base_seq 0x%X\n", tdb->pkt->dsize-overlap, st->seglist_base_seq); - - MODULE_PROFILE_END(s5TcpInsertPerfStats); } @@ -986,10 +983,9 @@ static void ProcessTcpStream(TcpTracker *rcv, TcpSession *tcpssn, TcpDataBlock * static int ProcessTcpData(TcpTracker *listener, TcpSession *tcpssn, TcpDataBlock *tdb, StreamTcpConfig *config) { - const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; - - PROFILE_VARS; MODULE_PROFILE_START(s5TcpDataPerfStats); + PERF_PROFILE(s5TcpDataPerfStats); + const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; uint32_t seq = tdb->seq; if( tcph->is_syn() ) @@ -1001,7 +997,6 @@ static int ProcessTcpData(TcpTracker *listener, TcpSession *tcpssn, { DebugMessage(DEBUG_STREAM_STATE, "Bailing, data on SYN, not MAC Policy!\n"); listener->normalizer->trim_syn_payload( tdb ); - MODULE_PROFILE_END(s5TcpDataPerfStats); return STREAM_UNALIGNED; } } @@ -1015,7 +1010,6 @@ static int ProcessTcpData(TcpTracker *listener, TcpSession *tcpssn, { DebugMessage(DEBUG_STREAM_STATE, "Bailing, we're out of the window!\n"); listener->normalizer->trim_win_payload( tdb ); - MODULE_PROFILE_END(s5TcpDataPerfStats); return STREAM_UNALIGNED; } @@ -1032,7 +1026,6 @@ static int ProcessTcpData(TcpTracker *listener, TcpSession *tcpssn, ProcessTcpStream(listener, tcpssn, tdb, config); /* set flags to session flags */ - MODULE_PROFILE_END(s5TcpDataPerfStats); return STREAM_ALIGNED; } } @@ -1059,7 +1052,6 @@ static int ProcessTcpData(TcpTracker *listener, TcpSession *tcpssn, { DebugMessage(DEBUG_STREAM_STATE, "Bailing, we're out of the window!\n"); listener->normalizer->trim_win_payload( tdb ); - MODULE_PROFILE_END(s5TcpDataPerfStats); return STREAM_UNALIGNED; } @@ -1087,7 +1079,6 @@ static int ProcessTcpData(TcpTracker *listener, TcpSession *tcpssn, } } - MODULE_PROFILE_END(s5TcpDataPerfStats); return STREAM_UNALIGNED; } @@ -1280,9 +1271,9 @@ static void NewTcpSession(Packet* p, Flow* flow, StreamTcpConfig* dstPolicy, Tcp static void NewTcpSessionOnSyn(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* dstPolicy) { - const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; + PERF_PROFILE(s5TcpNewSessPerfStats); - PROFILE_VARS; MODULE_PROFILE_START(s5TcpNewSessPerfStats); + const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; TcpSession* tss; /****************************************************************** @@ -1331,14 +1322,13 @@ static void NewTcpSessionOnSyn(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* d tcpStats.sessions_on_syn++; NewTcpSession(tdb->pkt, flow, dstPolicy, tss); - MODULE_PROFILE_END(s5TcpNewSessPerfStats); } static void NewTcpSessionOnSynAck(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* dstPolicy) { - const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; + PERF_PROFILE(s5TcpNewSessPerfStats); - PROFILE_VARS; MODULE_PROFILE_START(s5TcpNewSessPerfStats); + const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; TcpSession* tss; tss = (TcpSession*) flow->session; @@ -1385,15 +1375,14 @@ static void NewTcpSessionOnSynAck(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig tcpStats.sessions_on_syn_ack++; NewTcpSession(tdb->pkt, flow, dstPolicy, tss); - MODULE_PROFILE_END(s5TcpNewSessPerfStats); } static void NewTcpSessionOn3Way(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* dstPolicy) { - const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; + PERF_PROFILE(s5TcpNewSessPerfStats); - PROFILE_VARS; MODULE_PROFILE_START(s5TcpNewSessPerfStats); + const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; TcpSession* tss; /****************************************************************** @@ -1439,14 +1428,13 @@ static void NewTcpSessionOn3Way(Flow* flow, TcpDataBlock* tdb, tcpStats.sessions_on_3way++; NewTcpSession(tdb->pkt, flow, dstPolicy, tss); - MODULE_PROFILE_END(s5TcpNewSessPerfStats); } static void NewTcpSessionOnData(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* dstPolicy) { - const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; + PERF_PROFILE(s5TcpNewSessPerfStats); - PROFILE_VARS; MODULE_PROFILE_START(s5TcpNewSessPerfStats); + const tcp::TCPHdr* tcph = tdb->pkt->ptrs.tcph; TcpSession* tss; tss = (TcpSession*) flow->session; @@ -1537,11 +1525,12 @@ static void NewTcpSessionOnData(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* tcpStats.sessions_on_data++; NewTcpSession(tdb->pkt, flow, dstPolicy, tss); - MODULE_PROFILE_END(s5TcpNewSessPerfStats); } static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) { + PERF_PROFILE(s5TcpStatePerfStats); + int retcode = ACTION_NOTHING; int eventcode = 0; int got_ts = 0; @@ -1552,7 +1541,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) TcpTracker* talker = NULL; TcpTracker* listener = NULL; DEBUG_WRAP( const char* t = NULL; const char* l = NULL; ); - PROFILE_VARS; if (flow->protocol != PktType::TCP) { @@ -1562,8 +1550,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) tcpssn = ( TcpSession* ) flow->session; - MODULE_PROFILE_START(s5TcpStatePerfStats); - if (!tcpssn->tcp_init) { // FIXIT-L expected flow should be checked by flow_con before we @@ -1653,11 +1639,8 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) StreamUpdatePerfBaseState(&sfBase, flow, TCP_STATE_ESTABLISHED); } else if (!tdb->pkt->dsize) - { - /* Do nothing. */ - MODULE_PROFILE_END(s5TcpStatePerfStats); + // Do nothing. return retcode; - } } else { @@ -1782,7 +1765,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) /* Got SYN/RST. We're done. */ listener->normalizer->trim_syn_payload( tdb ); listener->normalizer->trim_rst_payload( tdb ); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_RST; } else if (tcph->is_syn_only()) @@ -1864,7 +1846,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) if (!tcpssn->tcp_init) { LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode; } @@ -1893,7 +1874,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) inc_tcp_discards(); listener->normalizer->trim_win_payload( tdb ); LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_BAD_PKT; } } @@ -1927,7 +1907,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) StreamUpdatePerfBaseState(&sfBase, flow, TCP_STATE_CLOSING); /* Leave listener open, data may be in transit */ LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_RST; } /* Reset not valid. */ @@ -1936,7 +1915,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) eventcode |= EVENT_BAD_RST; listener->normalizer->packet_dropper(tdb, NORM_TCP_BLOCK); LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode; } @@ -1966,7 +1944,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) listener->s_mgr.state = TCP_STATE_SYN_SENT; DebugMessage(DEBUG_STREAM_STATE, "Accepted SYN ACK\n"); LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode; } @@ -2021,7 +1998,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) leave listener open, data may be in transit */ LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_RST; } /* Reset not valid. */ @@ -2030,7 +2006,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) eventcode |= EVENT_BAD_RST; listener->normalizer->packet_dropper(tdb, NORM_TCP_BLOCK); LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ts_action; } else @@ -2044,7 +2019,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) inc_tcp_discards(); listener->normalizer->trim_win_payload( tdb ); LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ts_action; } } @@ -2055,7 +2029,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) inc_tcp_discards(); // this packet was normalized elsewhere LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ts_action; } @@ -2096,7 +2069,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) /* got a bad SYN on the session, alert! */ eventcode |= EVENT_SYN_ON_EST; LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | action; } } @@ -2114,7 +2086,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) inc_tcp_discards(); listener->normalizer->packet_dropper(tdb, NORM_TCP_BLOCK); LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_BAD_PKT; } else if ((tdb->pkt->packet_flags & PKT_FROM_CLIENT) && (tdb->win <= SLAM_MAX) @@ -2130,7 +2101,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) if (listener->normalizer->packet_dropper(tdb, NORM_TCP_BLOCK)) { LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_BAD_PKT; } } @@ -2203,7 +2173,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) if (listener->normalizer->packet_dropper(tdb, NORM_TCP_BLOCK)) { LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_BAD_PKT; } } @@ -2246,7 +2215,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) eventcode |= EVENT_BAD_ACK; LogTcpEvents(eventcode); listener->normalizer->packet_dropper(tdb, NORM_TCP_BLOCK); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_BAD_PKT; } break; @@ -2431,7 +2399,6 @@ static int ProcessTcp(Flow* flow, TcpDataBlock* tdb, StreamTcpConfig* config) eventcode |= EVENT_BAD_FIN; LogTcpEvents(eventcode); listener->normalizer->packet_dropper(tdb, NORM_TCP_BLOCK); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_BAD_PKT; } } @@ -2473,7 +2440,6 @@ dupfin: LogTcpEvents(eventcode); TcpSessionCleanup(flow, 0, tdb->pkt); flow->session_state |= STREAM_STATE_CLOSED; - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode | ACTION_LWSSN_CLOSED; } else if( listener->s_mgr.state == TCP_STATE_CLOSED @@ -2484,7 +2450,6 @@ dupfin: } LogTcpEvents(eventcode); - MODULE_PROFILE_END(s5TcpStatePerfStats); return retcode; } @@ -2964,9 +2929,10 @@ void TcpSession::update_direction(char dir, const sfip_t* ip, uint16_t port) */ int TcpSession::process(Packet* p) { + PERF_PROFILE(s5TcpPerfStats); + TcpDataBlock tdb; int status; - PROFILE_VARS; DEBUG_WRAP( char flagbuf[9]; @@ -2977,14 +2943,10 @@ int TcpSession::process(Packet* p) ntohl(p->ptrs.tcph->th_seq), ntohl(p->ptrs.tcph->th_ack), p->dsize); ); - MODULE_PROFILE_START(s5TcpPerfStats); - if (stream.blocked_session(flow, p) || (flow->session_state & STREAM_STATE_IGNORE)) - { - MODULE_PROFILE_END(s5TcpPerfStats); return ACTION_NOTHING; - } + SetupTcpDataBlock(&tdb, p); StreamTcpConfig* config = get_tcp_cfg(flow->ssn_server); @@ -3019,7 +2981,6 @@ int TcpSession::process(Packet* p) event_mask |= EVENT_NO_3WHS; } - MODULE_PROFILE_END(s5TcpPerfStats); #ifdef REG_TEST S5TraceTCP(p, flow, &tdb, 1); #endif @@ -3031,7 +2992,6 @@ int TcpSession::process(Packet* p) midstream_pickup_allowed: if (!p->ptrs.tcph->is_syn_ack() && !p->dsize && !(StreamPacketHasWscale(p) & TF_WSCALE)) { - MODULE_PROFILE_END(s5TcpPerfStats); #ifdef REG_TEST S5TraceTCP(p, flow, &tdb, 1); #endif @@ -3082,7 +3042,6 @@ midstream_pickup_allowed: if (!p->ptrs.tcph->is_syn_ack() p->packet_flags & PKT_FROM_SERVER ? "server" : "client"); } - MODULE_PROFILE_END(s5TcpPerfStats); S5TraceTCP(p, flow, &tdb, 0); return 0; } diff --git a/src/stream/udp/udp_session.cc b/src/stream/udp/udp_session.cc index d583e8a41..18a1ee7d4 100644 --- a/src/stream/udp/udp_session.cc +++ b/src/stream/udp/udp_session.cc @@ -203,15 +203,11 @@ void UdpSession::update_direction( int UdpSession::process(Packet* p) { + PERF_PROFILE(udp_perf_stats); + StreamUdpConfig* pc = get_udp_cfg(flow->ssn_server); - SFXHASH_NODE* hash_node = NULL; - - PROFILE_VARS; - MODULE_PROFILE_START(udp_perf_stats); - /* - * Check if the session is expired. - * Should be done before we do something with the packet... - */ + // Check if the session is expired. + // Should be done before we do something with the packet... if ( stream.expired_session(flow, p) ) { UdpSessionCleanup(flow); @@ -220,11 +216,11 @@ int UdpSession::process(Packet* p) udpStats.created++; udpStats.timeouts++; } - ProcessUdp(flow, p, pc, hash_node); + + ProcessUdp(flow, p, pc, nullptr); flow->markup_packet_flags(p); flow->set_expire(p, pc->session_timeout); - MODULE_PROFILE_END(udp_perf_stats); return 0; } diff --git a/src/stream/user/user_session.cc b/src/stream/user/user_session.cc index 5a11370d8..c10ba0273 100644 --- a/src/stream/user/user_session.cc +++ b/src/stream/user/user_session.cc @@ -431,10 +431,7 @@ bool UserSession::setup(Packet*) #ifdef ENABLE_EXPECTED_USER if ( flow_con->expected_session(flow, p)) - { - MODULE_PROFILE_END(user_perf_stats); return false; - } #endif return true; } @@ -467,8 +464,7 @@ StreamSplitter* UserSession::get_splitter(bool c2s) int UserSession::process(Packet* p) { - PROFILE_VARS; - MODULE_PROFILE_START(user_perf_stats); + PERF_PROFILE(user_perf_stats); if ( stream.expired_session(flow, p) ) { @@ -477,20 +473,14 @@ int UserSession::process(Packet* p) #ifdef ENABLE_EXPECTED_USER if ( flow_con->expected_session(flow, p)) - { - MODULE_PROFILE_END(user_perf_stats); return 0; - } #endif } flow->set_direction(p); if ( stream.blocked_session(flow, p) || stream.ignored_session(flow, p) ) - { - MODULE_PROFILE_END(user_perf_stats); return 0; - } update(p, flow); @@ -505,7 +495,6 @@ int UserSession::process(Packet* p) if ( p->ptrs.decode_flags & DECODE_EOF ) end(p, flow); - MODULE_PROFILE_END(user_perf_stats); return 0; } diff --git a/src/time/CMakeLists.txt b/src/time/CMakeLists.txt index 59abc148f..3e1a7c432 100644 --- a/src/time/CMakeLists.txt +++ b/src/time/CMakeLists.txt @@ -1,4 +1,8 @@ +if ( ENABLE_PERFPROFILING ) + set ( PERFPROFILING_SOURCES profiler.cc ) +endif ( ENABLE_PERFPROFILING ) + set (TIME_INCLUDES cpuclock.h profiler.h @@ -12,7 +16,7 @@ add_library( time STATIC ppm.h ppm_module.cc ppm_module.h - profiler.cc + ${PERFPROFILING_SOURCES} periodic.cc periodic.h timersub.h diff --git a/src/time/Makefile.am b/src/time/Makefile.am index d93abdf0c..27c7aedb2 100644 --- a/src/time/Makefile.am +++ b/src/time/Makefile.am @@ -14,8 +14,10 @@ packet_time.h \ ppm.cc \ ppm_module.cc \ ppm_module.h \ -profiler.cc \ periodic.cc \ periodic.h \ timersub.h +if PERF_PROFILING +libtime_a_SOURCES += profiler.cc +endif diff --git a/src/time/profiler.cc b/src/time/profiler.cc index 710109644..487c9ae92 100644 --- a/src/time/profiler.cc +++ b/src/time/profiler.cc @@ -31,8 +31,8 @@ #include #include -using namespace std; +#include "time/cpuclock.h" #include "detection/fp_detect.h" #include "detection/treenodes.h" #include "detection/rules.h" @@ -43,10 +43,27 @@ using namespace std; #include "framework/module.h" #include "hash/sfghash.h" -// FIXIT-M: Instead of using preprocessor directives, use the build system -// to control compilation of this module -#ifdef PERF_PROFILING +#ifdef UNIT_TEST +#include "test/catch.hpp" +#endif + +using namespace std; + +#define TOTAL "total" +// ----------------------------------------------------------------------------- +// types +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// static variables +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// static functions +// ----------------------------------------------------------------------------- + +// FIXIT-L legacy stuff (to be cleaned up) typedef struct _ProfileStatsNode { ProfileStats stats; @@ -94,7 +111,6 @@ static int max_layers = 0; static ProfileStatsNode* get_node(const char*); -#define TOTAL "total" static ProfileStatsNode* get_root(ProfileStatsNode* idx) { @@ -572,11 +588,10 @@ void PrintPreprocPerformance(int num, Preproc_WorstPerformer* idx) if (num != 0) { indent += 2; - LogMessage("%*d%*s%*d" FMTu64("*") FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n", + LogMessage("%*d%*s%*d" FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n", indent, num, 28 - indent, idx->node->name, 6, idx->node->layer, 11, idx->node->stats.checks, - 11, idx->node->stats.exits, 20, (uint64_t)(idx->node->stats.ticks/ticks_per_microsec), 11, idx->ticks_per_check/ticks_per_microsec, 14, idx->pct_of_parent, @@ -587,11 +602,10 @@ void PrintPreprocPerformance(int num, Preproc_WorstPerformer* idx) /* The totals */ indent += strlen(idx->node->name); - LogMessage("%*s%*s%*d" FMTu64("*") FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n", + LogMessage("%*s%*s%*d" FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n", indent, idx->node->name, 28 - indent, idx->node->name, 6, idx->node->layer, 11, idx->node->stats.checks, - 11, idx->node->stats.exits, 20, (uint64_t)(idx->node->stats.ticks/ticks_per_microsec), 11, idx->ticks_per_check/ticks_per_microsec, 14, idx->pct_of_parent, @@ -646,9 +660,7 @@ void ReleaseProfileStats(void) assert(ps); node->stats.ticks += ps->ticks; - node->stats.ticks_start += ps->ticks_start; node->stats.checks += ps->checks; - node->stats.exits += ps->exits; node = node->next; } @@ -689,23 +701,21 @@ void PrintWorstPreprocs(int numToPrint) else LogMessage("Module Profile Statistics (all)\n"); - LogMessage("%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", + LogMessage("%*s%*s%*s%*s%*s%*s%*s%*s\n", 4, "Num", 24, "Module", 6, "Layer", 11, "Checks", - 11, "Exits", 20, "Microsecs", 11, "Avg/Check", 14, "Pct of Caller", 13, "Pct of Total"); - LogMessage("%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", + LogMessage("%*s%*s%*s%*s%*s%*s%*s%*s\n", 4, "===", 24, "======", 6, "=====", 11, "======", - 11, "=====", 20, "=========", 11, "=========", 14, "=============", @@ -770,9 +780,7 @@ void ResetPreprocProfiling(void) for (idx = gProfileStatsNodeList; idx != NULL; idx = idx->next) { idx->stats.ticks = 0; - idx->stats.ticks_start = 0; idx->stats.checks = 0; - idx->stats.exits = 0; } } @@ -916,5 +924,371 @@ void ShowPreprocProfiles(void) CleanupProfileStatsNodeList(); } -#endif +// ----------------------------------------------------------------------------- +// non-static implementation +// ----------------------------------------------------------------------------- + +void NodePerfProfiler::update(bool match) +{ stats.update(get_delta(), match); } + +// ----------------------------------------------------------------------------- +// public API +// ----------------------------------------------------------------------------- + +void PerfProfilerManager::register_module(Module* m) +{ RegisterProfile(m); } + +void PerfProfilerManager::register_module(const char* name, const char* pname, Module* m) +{ RegisterProfile(name, pname, nullptr, m); } + +void PerfProfilerManager::register_module(const char* name, const char* pname, + get_profile_func getter) +{ RegisterProfile(name, pname, getter, nullptr); } + +// thread local +void PerfProfilerManager::consolidate_stats() +{ ReleaseProfileStats(); } + +void PerfProfilerManager::show_module_stats() +{ ShowPreprocProfiles(); } + +void PerfProfilerManager::reset_module_stats() +{ } + +void PerfProfilerManager::show_rule_stats() +{ ShowRuleProfiles(); } + +void PerfProfilerManager::reset_rule_stats() +{ } + +void PerfProfilerManager::show_all_stats() +{ + if ( SnortConfig::get_profile_modules() ) + show_module_stats(); + + if ( SnortConfig::get_profile_rules() ) + show_rule_stats(); +} + +void PerfProfilerManager::reset_all_stats() +{ } + +void PerfProfilerManager::init() +{ } + +void PerfProfilerManager::term() +{ CleanupProfileStatsNodeList(); } + +// ----------------------------------------------------------------------------- +// unit tests +// ----------------------------------------------------------------------------- + +#ifdef UNIT_TEST + +struct ProfilePauseObserver +{ + void start() + { + start_called = true; + if ( pause_called ) + pause_called_before_start = true; + } + + void pause() + { pause_called = true; } + + bool pause_called = false; + bool start_called = false; + bool pause_called_before_start = false; +}; + +TEST_CASE( "stopwatch", "[profiler]" ) +{ + Stopwatch sw; + + REQUIRE_FALSE( sw.alive() ); + REQUIRE( sw.get() == 0 ); + + SECTION( "start" ) + { + sw.start(); + + SECTION( "sets clock to alive" ) + { + CHECK( sw.alive() ); + } + SECTION( "running elapsed time should be non-zero" ) + { + CHECK( sw.get() > 0 ); + } + + SECTION( "start on running clock has no effect" ) + { + auto val = sw.get(); + sw.start(); + CHECK( sw.alive() ); + CHECK( sw.get() > val ); + } + } + + SECTION( "stop" ) + { + sw.start(); + sw.stop(); + + SECTION( "sets clock to be dead" ) + { + CHECK_FALSE( sw.alive() ); + } + + SECTION( "ticks should not increase after death" ) + { + auto val = sw.get(); + CHECK( val == sw.get() ); + } + + SECTION( "stop on stopped clock has no effect" ) + { + auto val = sw.get(); + sw.stop(); + CHECK_FALSE( sw.alive() ); + CHECK( val == sw.get() ); + } + } + + SECTION( "reset" ) + { + sw.start(); + + SECTION( "reset on running clock" ) + { + sw.reset(); + CHECK_FALSE( sw.alive() ); + CHECK( sw.get() == 0 ); + } + + SECTION( "reset on stopped clock" ) + { + sw.stop(); + sw.reset(); + CHECK_FALSE( sw.alive() ); + CHECK( sw.get() == 0 ); + } + } + + SECTION( "cancel" ) + { + sw.start(); + SECTION( "cancel on running clock that has no lap time" ) + { + sw.cancel(); + CHECK_FALSE( sw.alive() ); + CHECK( sw.get() == 0 ); + } + + SECTION( "cancel on stopped clock that has lap time" ) + { + sw.stop(); + auto val = sw.get(); + sw.cancel(); + + CHECK_FALSE( sw.alive() ); + CHECK( val == sw.get() ); + } + } +} + +TEST_CASE( "perf profiler base", "[profiler]" ) +{ + SECTION( "profiler is started on instantiation" ) + { + PerfProfilerBase prof; + CHECK( prof.get_delta() > 0 ); + } + + SECTION( "profiler evaluates to true" ) + { + PerfProfilerBase prof; + CHECK( prof ); + } +} + +TEST_CASE( "perf profiler", "[profiler]" ) +{ + ProfileStats stats = { 0, 0 }; + + REQUIRE( stats.ticks == 0 ); + REQUIRE( stats.checks == 0 ); + + SECTION( "going out of scope causes profiler to update stats" ) + { + { + PerfProfiler prof(stats); + } + + CHECK( stats.ticks > 0 ); + CHECK( stats.checks == 1 ); + } + + SECTION( "stopping profiler is only done once" ) + { + PerfProfiler prof(stats); + prof.stop(); + ProfileStats saved = stats; + prof.stop(); + + CHECK( saved.ticks == stats.ticks ); + CHECK( saved.checks == stats.checks ); + } + + SECTION( "profiler can be stopped while paused" ) + { + PerfProfiler prof(stats); + prof.pause(); + prof.stop(); + + CHECK( stats.ticks > 0 ); + CHECK( stats.checks == 1 ); + } + + SECTION( "profiler can be pause and restarted" ) + { + PerfProfiler prof(stats); + prof.pause(); + prof.start(); + + CHECK( stats.ticks == 0 ); + CHECK( stats.checks == 0 ); + + prof.stop(); + + CHECK( stats.ticks > 0 ); + CHECK( stats.checks == 1 ); + } + + SECTION( "profiler correctly handles exceptions" ) + { + try + { + PerfProfiler prof(stats); + throw int(1); + } + + catch( int& ) + { } + + CHECK( stats.ticks > 0 ); + CHECK( stats.checks == 1 ); + } +} + +TEST_CASE( "node perf profiler", "[profiler]" ) +{ + dot_node_state_t stats; + + stats.ticks = 0; + stats.ticks_match = 0; + stats.ticks_no_match = 0; + stats.checks = 0; + + SECTION( "going out of scope causes profiler to update stats" ) + { + { + NodePerfProfiler prof(stats); + } + + CHECK( stats.ticks > 0 ); + CHECK( stats.checks == 1 ); + + SECTION( "evaluates to NO MATCH by default" ) + { + CHECK( stats.ticks_no_match > 0 ); + } + } + + SECTION( "stopping profiler is only done once" ) + { + NodePerfProfiler prof(stats); + prof.stop(false); + dot_node_state_t saved = stats; + prof.stop(true); + + CHECK( saved.ticks == stats.ticks ); + CHECK( saved.checks == stats.checks ); + + SECTION( "only one of match or no match is updated" ) + { + CHECK( stats.ticks_no_match > 0 ); + CHECK( stats.ticks_match == 0 ); + } + } + + SECTION( "profiler can be stopped while paused" ) + { + NodePerfProfiler prof(stats); + prof.pause(); + prof.stop(false); + + CHECK( stats.ticks > 0 ); + CHECK( stats.checks == 1 ); + } + + SECTION( "profiler can be pause and restarted" ) + { + NodePerfProfiler prof(stats); + prof.pause(); + prof.start(); + + CHECK( stats.ticks == 0 ); + CHECK( stats.checks == 0 ); + + prof.stop(false); + + CHECK( stats.ticks > 0 ); + CHECK( stats.checks == 1 ); + } + + SECTION( "profiler uses MATCH when stop(true) is called" ) + { + NodePerfProfiler prof(stats); + prof.stop(true); + + CHECK( stats.ticks_match > 0 ); + + SECTION( "and doesn't update NO MATCH" ) + { + CHECK( stats.ticks_no_match == 0 ); + } + } + + SECTION( "profiler correctly handles exceptions" ) + { + try + { + NodePerfProfiler prof(stats); + throw int(1); + } + + catch( int& ) + { } + + CHECK( stats.ticks > 0 ); + CHECK( stats.checks == 1 ); + } +} + +TEST_CASE( "perf profiler pause", "[profiler]" ) +{ + ProfilePauseObserver observer; + + { + ProfilerPause pause(observer); + } + + CHECK( observer.pause_called ); + CHECK( observer.start_called ); + CHECK( observer.pause_called_before_start ); +} + +#endif diff --git a/src/time/profiler.h b/src/time/profiler.h index 11709aac5..cbfe1101d 100644 --- a/src/time/profiler.h +++ b/src/time/profiler.h @@ -35,130 +35,235 @@ struct ProfileStats { uint64_t ticks; - uint64_t ticks_start; uint64_t checks; - uint64_t exits; + + void update(uint64_t elapsed) + { ++checks; ticks += elapsed; } }; -#ifdef PERF_PROFILING #include "main/thread.h" #include "time/cpuclock.h" -// Sort preferences for rule profiling -#define PROFILE_SORT_CHECKS 1 -#define PROFILE_SORT_AVG_TICKS 2 -#define PROFILE_SORT_TOTAL_TICKS 3 -#define PROFILE_SORT_MATCHES 4 -#define PROFILE_SORT_NOMATCHES 5 -#define PROFILE_SORT_AVG_TICKS_PER_MATCH 6 -#define PROFILE_SORT_AVG_TICKS_PER_NOMATCH 7 - -// MACROS that handle profiling of rules and preprocessors -#define PROFILE_VARS_NAMED(name) uint64_t name ## _ticks_start, name ## _ticks_end -#define PROFILE_VARS PROFILE_VARS_NAMED(snort) +// FIXIT-L should go in its own module +class Stopwatch +{ +public: + Stopwatch() : + elapsed { 0 }, running { false } { } -#define PROFILE_START_NAMED(name) \ - get_clockticks(name ## _ticks_start) + void start() + { + if ( running ) + return; -#define PROFILE_END_NAMED(name) \ - get_clockticks(name ## _ticks_end) + get_clockticks(ticks_start); + running = true; + } -#define NODE_PROFILE_END \ - PROFILE_END_NAMED(node); \ - node_ticks_delta = node_ticks_end - node_ticks_start + void stop() + { + if ( !running ) + return; -#ifndef PROFILING_RULES -#define PROFILING_RULES SnortConfig::get_profile_rules() -#endif + elapsed += get_delta(); + running = false; + } -#define NODE_PROFILE_VARS \ - uint64_t node_ticks_start = 0, node_ticks_end, node_ticks_delta, node_deltas = 0 + uint64_t get() const + { + if ( running ) + return elapsed + get_delta(); -#define NODE_PROFILE_START(node) \ - if (PROFILING_RULES) { \ - unsigned id = get_instance_id(); \ - node->state[id].checks++; \ - PROFILE_START_NAMED(node); \ + return elapsed; } -#define NODE_PROFILE_END_MATCH(node) \ - if (PROFILING_RULES) { \ - NODE_PROFILE_END; \ - unsigned id = get_instance_id(); \ - node->state[id].ticks += node_ticks_delta + node_deltas; \ - node->state[id].ticks_match += node_ticks_delta + node_deltas; \ - } + bool alive() const + { return running; } + + void reset() + { running = false; elapsed = 0; } -#define NODE_PROFILE_END_NOMATCH(node) \ - if (PROFILING_RULES) { \ - NODE_PROFILE_END; \ - unsigned id = get_instance_id(); \ - node->state[id].ticks += node_ticks_delta + node_deltas; \ - node->state[id].ticks_no_match += node_ticks_delta + node_deltas; \ + void cancel() + { running = false; } + +private: + uint64_t get_delta() const + { + uint64_t ticks_stop; + get_clockticks(ticks_stop); + return ticks_stop - ticks_start; } -#define NODE_PROFILE_TMPSTART(node) \ - if (PROFILING_RULES) { \ - PROFILE_START_NAMED(node); \ + uint64_t elapsed; + bool running; + uint64_t ticks_start; +}; + +class PerfProfilerBase +{ +public: + PerfProfilerBase() + { start(); } + + void start() + { sw.start(); } + + void pause() + { sw.stop(); } + + // for macro block + operator bool() const + { return true; } + + uint64_t get_delta() const + { return sw.get(); } + +private: + Stopwatch sw; +}; + +class PerfProfiler : public PerfProfilerBase +{ +public: + PerfProfiler(ProfileStats& ps) : + PerfProfilerBase(), stats(ps), closed { false } { } + + ~PerfProfiler() + { stop(); } + + // Once a profiler is stopped, it cannot be restarted + void stop() + { + if ( closed ) + return; + + stats.update(get_delta()); + closed = true; } -#define NODE_PROFILE_TMPEND(node) \ - if (PROFILING_RULES) { \ - NODE_PROFILE_END; \ - node_deltas += node_ticks_delta; \ +private: + ProfileStats& stats; + bool closed; +}; + +struct dot_node_state_t; + +class NodePerfProfiler : public PerfProfilerBase +{ +public: + NodePerfProfiler(dot_node_state_t& dns) : + PerfProfilerBase(), stats(dns), closed { false } { } + + // If no stop is explicitly specified, assume no match + ~NodePerfProfiler() + { stop(false); } + + void stop(bool match) + { + if ( closed ) + return; + + update(match); + closed = true; } -#define OTN_PROFILE_ALERT(otn) otn->state[get_instance_id()].alerts++; +private: + void update(bool); + dot_node_state_t& stats; + bool closed; +}; + +template +struct ProfilerPause +{ + ProfilerPause(Profiler& prof) : + profiler(prof) + { profiler.pause(); } + + ~ProfilerPause() + { profiler.start(); } + + // for macro block + operator bool() const + { return true; } + + Profiler& profiler; +}; + +#ifdef PERF_PROFILING #ifndef PROFILING_MODULES #define PROFILING_MODULES SnortConfig::get_profile_modules() #endif -#define MODULE_PROFILE_START_NAMED(name, ppstat) \ - if (PROFILING_MODULES) { \ - ppstat.checks++; \ - PROFILE_START_NAMED(name); \ - ppstat.ticks_start = name ## _ticks_start; \ - } -#define MODULE_PROFILE_START(ppstat) MODULE_PROFILE_START_NAMED(snort, ppstat) +#ifndef PROFILING_RULES +#define PROFILING_RULES SnortConfig::get_profile_rules() +#endif -#define MODULE_PROFILE_REENTER_START_NAMED(name, ppstat) \ - if (PROFILING_MODULES) { \ - PROFILE_START_NAMED(name); \ - ppstat.ticks_start = name ## _ticks_start; \ - } -#define MODULE_PROFILE_REENTER_START(ppstat) MODULE_PROFILE_REENTER_START_NAMED(snort, ppstat) +#define PERF_PROFILER_NAME(stats) \ + stats ## _perf_profiler -#define MODULE_PROFILE_TMPSTART_NAMED(name, ppstat) \ - if (PROFILING_MODULES) { \ - PROFILE_START_NAMED(name); \ - ppstat.ticks_start = name ## _ticks_start; \ - } -#define MODULE_PROFILE_TMPSTART(ppstat) MODULE_PROFILE_TMPSTART_NAMED(snort, ppstat) +#define PERF_PAUSE_NAME(stats) \ + stats ## _perf_pause -#define MODULE_PROFILE_END_NAMED(name, ppstat) \ - if (PROFILING_MODULES) { \ - PROFILE_END_NAMED(name); \ - ppstat.exits++; \ - ppstat.ticks += name ## _ticks_end - ppstat.ticks_start; \ - } -#define MODULE_PROFILE_END(ppstat) MODULE_PROFILE_END_NAMED(snort, ppstat) +#define PERF_PROFILE(stats) \ + PerfProfiler PERF_PROFILER_NAME(stats) { stats } -#define MODULE_PROFILE_REENTER_END_NAMED(name, ppstat) \ - if (PROFILING_MODULES) { \ - PROFILE_END_NAMED(name); \ - ppstat.ticks += name ## _ticks_end - ppstat.ticks_start; \ - } -#define MODULE_PROFILE_REENTER_END(ppstat) MODULE_PROFILE_REENTER_END_NAMED(snort, ppstat) +#define PERF_PROFILE_BLOCK(stats) \ + if ( PERF_PROFILE(stats) ) -#define MODULE_PROFILE_TMPEND_NAMED(name, ppstat) \ - if (PROFILING_MODULES) { \ - PROFILE_END_NAMED(name); \ - ppstat.ticks += name ## _ticks_end - ppstat.ticks_start; \ - } -#define MODULE_PROFILE_TMPEND(ppstat) MODULE_PROFILE_TMPEND_NAMED(snort, ppstat) +#define NODE_PERF_PROFILE(stats) \ + NodePerfProfiler PERF_PROFILER_NAME(stats) { stats } + +#define NODE_PERF_PROFILE_BLOCK(stats) \ + if ( NODE_PERF_PROFILE(stats) ) + +#define NODE_PERF_PROFILE_STOP_MATCH(stats) \ + PERF_PROFILER_NAME(stats) .stop(true) + +#define NODE_PERF_PROFILE_STOP_NO_MATCH(stats) \ + PERF_PROFILER_NAME(stats) .stop(false) + +#define PERF_PAUSE_BLOCK(stats) \ + if ( ProfilerPause \ + PERF_PAUSE_NAME(stats) { PERF_PROFILER_NAME(stats) } ) +// thread local access method +using get_profile_func = ProfileStats* (*)(const char*); + +class PerfProfilerManager +{ +public: + static void register_module(Module*); + static void register_module(const char*, const char*, Module*); + static void register_module(const char*, const char*, get_profile_func); + + // thread local + static void consolidate_stats(); + + static void show_module_stats(); + static void reset_module_stats(); + + static void show_rule_stats(); + static void reset_rule_stats(); + + static void show_all_stats(); + static void reset_all_stats(); + + static void init(); + static void term(); +}; + +// Sort preferences for rule profiling +#define PROFILE_SORT_CHECKS 1 +#define PROFILE_SORT_AVG_TICKS 2 +#define PROFILE_SORT_TOTAL_TICKS 3 +#define PROFILE_SORT_MATCHES 4 +#define PROFILE_SORT_NOMATCHES 5 +#define PROFILE_SORT_AVG_TICKS_PER_MATCH 6 +#define PROFILE_SORT_AVG_TICKS_PER_NOMATCH 7 + // ----------------------------------------------------------------------------- // Profiling API // ----------------------------------------------------------------------------- @@ -169,64 +274,20 @@ struct ProfileConfig int sort; }; -void ShowRuleProfiles(void); -void ResetRuleProfiling(void); - -// thread local access method -using get_profile_func = ProfileStats* (*)(const char*); - -void RegisterProfile( - const char* keyword, const char* parent, - get_profile_func, class Module* owner = nullptr); - -void RegisterProfile(class Module*); - -void ShowPreprocProfiles(void); -void ResetPreprocProfiling(void); -void ReleaseProfileStats(void); -void CleanupProfileStatsNodeList(void); - extern THREAD_LOCAL ProfileStats totalPerfStats; extern THREAD_LOCAL ProfileStats metaPerfStats; -#else -#define PROFILE_VARS -#define PROFILE_VARS_NAMED(name) -#define NODE_PROFILE_VARS -#define NODE_PROFILE_START(node) -#define NODE_PROFILE_END_MATCH(node) -#define NODE_PROFILE_END_NOMATCH(node) -#define NODE_PROFILE_TMPSTART(node) -#define NODE_PROFILE_TMPEND(node) -#define OTN_PROFILE_ALERT(otn) -#define MODULE_PROFILE_START(ppstat) -#define MODULE_PROFILE_START_NAMED(name, ppstat) -#define MODULE_PROFILE_REENTER_START(ppstat) -#define MODULE_PROFILE_REENTER_START_NAMED(name, ppstat) -#define MODULE_PROFILE_TMPSTART(ppstat) -#define MODULE_PROFILE_TMPSTART_NAMED(name, ppstat) -#define MODULE_PROFILE_END(ppstat) -#define MODULE_PROFILE_END_NAMED(name, ppstat) -#define MODULE_PROFILE_REENTER_END(ppstat) -#define MODULE_PROFILE_REENTER_END_NAMED(name, ppstat) -#define MODULE_PROFILE_TMPEND(ppstat) -#define MODULE_PROFILE_TMPEND_NAMED(name, ppstat) -#endif // PERF_PROFILING - -static inline void ShowAllProfiles() -{ -#ifdef PERF_PROFILING - ShowPreprocProfiles(); - ShowRuleProfiles(); -#endif -} -static inline void ResetAllProfiles() -{ -#ifdef PERF_PROFILING - ResetPreprocProfiling(); - ResetRuleProfiling(); -#endif -} +#else +#define PERF_PROFILER_NAME(stats) +#define PERF_PAUSE_NAME(stats) +#define PERF_PROFILE(stats) +#define PERF_PROFILE_BLOCK(stats) +#define NODE_PERF_PROFILE(stats) +#define NODE_PERF_PROFILE_BLOCK(stats) +#define NODE_PERF_PROFILE_STOP_MATCH(stats) +#define NODE_PERF_PROFILE_STOP_NO_MATCH(stats) +#define PERF_PAUSE_BLOCK(stats) +#endif // PERF_PROFILING #endif diff --git a/src/utils/stats.cc b/src/utils/stats.cc index fe24db283..05e69f6f4 100644 --- a/src/utils/stats.cc +++ b/src/utils/stats.cc @@ -356,7 +356,7 @@ void PrintStatistics(void) snort_conf->logging_flags &= ~LOGGING_FLAG__QUIET; - ShowAllProfiles(); + PerfProfilerManager::show_all_stats(); snort_conf->logging_flags |= save_quiet_flag; }