]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3090: Memory Update
authorRuss Combs (rucombs) <rucombs@cisco.com>
Wed, 1 Dec 2021 00:51:04 +0000 (00:51 +0000)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Wed, 1 Dec 2021 00:51:04 +0000 (00:51 +0000)
Merge in SNORT/snort3 from ~RUCOMBS/snort3:memory_update to master

Squashed commit of the following:

commit e73251f15db58127483e40965607a4e6979c762b
Author: russ <rucombs@cisco.com>
Date:   Wed Oct 27 12:11:15 2021 -0400

    framework: update base API version to 11

commit 062ffceeb9c4a07e489d27df0441dafa902d5264
Author: russ <rucombs@cisco.com>
Date:   Mon Oct 25 10:02:43 2021 -0400

    dev_notes.txt: fix miscellaneous typos

commit 8b260d2acd412de1c8ab81425d92d28a5a299295
Author: russ <rucombs@cisco.com>
Date:   Fri Sep 24 16:01:14 2021 -0400

    perf_monitor: allow constraint seconds = 0

commit 28f796f0bfa37c1f7615fcec1f7b9e7ba160afc2
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 15 15:51:39 2021 -0400

    doc: remove mention of Automake

commit 400f023d9b32f41da626e8395e04fd3f84b12b0a
Author: russ <rucombs@cisco.com>
Date:   Thu Sep 16 15:38:31 2021 -0400

    hyperscan: disable bogus unit test leak warnings

commit 12d481d4fffa17863cf71062ada9c48a3ced20d1
Author: russ <rucombs@cisco.com>
Date:   Thu Sep 16 15:37:58 2021 -0400

    memory: update dev notes

commit 681bc7b114ca8f43b40f3fc80f765fb7d099aacc
Author: russ <rucombs@cisco.com>
Date:   Tue Sep 28 13:16:36 2021 -0400

    memory: add max rss to verbose memory output

commit 6f84a31028243b06dcfbefc0bfa1148874ae5045
Author: russ <rucombs@cisco.com>
Date:   Sun Sep 26 09:02:21 2021 -0400

    memory: add support for jemalloc

commit 56dec3b93254e6e2d9418f9ee289679cf7c099f7
Author: russ <rucombs@cisco.com>
Date:   Fri Jul 16 09:29:57 2021 -0400

    memory: refactoring

commit e6831dcfd9c3ad5f84263e5e0a2880e2c700b3ee
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 15 10:15:13 2021 -0400

    memory: remove explicit allocation tracking

commit 368f41fcf637f6cd1a6802ea98986c1d8b78d467
Author: russ <rucombs@cisco.com>
Date:   Thu Jul 8 15:00:38 2021 -0400

    memory: fix accounting issues

    1. Ensure that all memory stats are accumulated last so stats are not
    skewed by later accumulations.

    2. Delete the start up swappers in the main thread so packet allocation
    tracking is consistent.

commit 371947cc47592f616705c868c33d3f4b4606c35c
Author: russ <rucombs@cisco.com>
Date:   Thu Jul 8 15:00:15 2021 -0400

    memory: refactor pruning and update unit tests

commit b69c623ea64629f61f3e656b1d37f400546b5a4d
Author: russ <rucombs@cisco.com>
Date:   Wed Jul 7 15:42:54 2021 -0400

    memory: free space per DAQ message, not per allocation

commit afe9ae7cb5cfd16fcf5ad16293655a8d895615bc
Author: russ <rucombs@cisco.com>
Date:   Wed Jul 7 11:53:47 2021 -0400

    memory: move mem_stats to MemoryCap

commit 074a491ea51029fef7d613ff7170b1318836437a
Author: russ <rucombs@cisco.com>
Date:   Tue Jul 6 23:31:07 2021 -0400

    build: update configure options

    Replace --disable-memory-manager with --enable-memory-overloads.
    Add --enable-memory-profiler to track memory use by modules.
    Add --enable-rule-profiler to profile rule option as with other modules.
    Add --enable-deep-profiling for multi-level profile buckets.

commit 06d367bc9dabbd25eb8a9f1e060aaf91256adfd6
Author: russ <rucombs@cisco.com>
Date:   Wed Sep 15 10:02:41 2021 -0400

    memory: add original overload manager

commit 327de6f23af8ada2786f9f286cee06528967e217
Author: russ <rucombs@cisco.com>
Date:   Thu Jul 1 12:10:25 2021 -0400

    memory: expand profile report field widths

150 files changed:
CMakeLists.txt
cmake/FindJEMalloc.cmake [new file with mode: 0644]
cmake/configure_options.cmake
cmake/create_options.cmake
cmake/create_pkg_config.cmake
config.cmake.h.in
configure_cmake.sh
doc/upgrade/overview.txt
doc/user/overview.txt
snort.pc.in
src/CMakeLists.txt
src/actions/dev_notes.txt
src/detection/regex_offload.cc
src/file_api/file_flows.h
src/flow/dev_notes.txt
src/flow/flow.cc
src/flow/flow_cache.cc
src/flow/flow_control.cc
src/flow/flow_control.h
src/flow/flow_data.cc
src/flow/flow_data.h
src/flow/prune_stats.h
src/flow/stash_item.h
src/flow/test/flow_cache_test.cc
src/flow/test/flow_control_test.cc
src/flow/test/flow_stash_test.cc
src/flow/test/flow_test.cc
src/framework/base_api.h
src/helpers/test/hyper_search_test.cc
src/ips_options/test/ips_regex_test.cc
src/log/dev_notes.txt
src/main.cc
src/main/analyzer.cc
src/main/snort.cc
src/main/swapper.cc
src/main/test/distill_verdict_test.cc
src/managers/module_manager.cc
src/managers/module_manager.h
src/memory/CMakeLists.txt
src/memory/dev_notes.txt
src/memory/memory_allocator.cc [new file with mode: 0644]
src/memory/memory_allocator.h [new file with mode: 0644]
src/memory/memory_cap.cc
src/memory/memory_cap.h
src/memory/memory_manager.cc [new file with mode: 0644]
src/memory/memory_module.cc
src/memory/memory_module.h
src/memory/prune_handler.cc
src/memory/prune_handler.h
src/mime/file_mime_log.h
src/mime/file_mime_process.cc
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_dns_session.h
src/network_inspectors/appid/appid_ha.cc
src/network_inspectors/appid/appid_http_session.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_session_api.h
src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc
src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc
src/network_inspectors/appid/dev_notes.txt
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_debug_test.cc
src/network_inspectors/appid/test/appid_detector_test.cc
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_efp_process_event_handler_test.cc
src/network_inspectors/appid/test/appid_http_event_test.cc
src/network_inspectors/appid/test/appid_http_session_test.cc
src/network_inspectors/appid/test/appid_session_api_test.cc
src/network_inspectors/appid/test/service_state_test.cc
src/network_inspectors/appid/test/tp_mock.cc
src/network_inspectors/appid/tp_appid_session_api.h
src/network_inspectors/appid/tp_appid_utils.cc
src/network_inspectors/arp_spoof/dev_notes.txt
src/network_inspectors/perf_monitor/perf_module.cc
src/network_inspectors/rna/dev_notes.txt
src/network_inspectors/rna/rna_fingerprint_tcp.cc
src/network_inspectors/rna/rna_flow.h
src/payload_injector/test/payload_injector_test.cc
src/profiler/memory_profiler.cc
src/profiler/profiler.cc
src/profiler/profiler_defs.h
src/service_inspectors/cip/cip.h
src/service_inspectors/cip/dev_notes.txt
src/service_inspectors/dce_rpc/dce_smb1.cc
src/service_inspectors/dce_rpc/dce_smb2.cc
src/service_inspectors/dce_rpc/dce_smb_common.h
src/service_inspectors/dce_rpc/dce_tcp.h
src/service_inspectors/dce_rpc/dce_udp.h
src/service_inspectors/dev_notes.txt
src/service_inspectors/dnp3/dnp3.h
src/service_inspectors/dns/dns.h
src/service_inspectors/ftp_telnet/ftpp_si.h
src/service_inspectors/gtp/gtp_inspect.h
src/service_inspectors/http2_inspect/http2_flow_data.cc
src/service_inspectors/http2_inspect/http2_flow_data.h
src/service_inspectors/http2_inspect/http2_hpack_dynamic_table.cc
src/service_inspectors/http2_inspect/http2_hpack_dynamic_table.h
src/service_inspectors/http2_inspect/http2_hpack_table.h
src/service_inspectors/http2_inspect/http2_stream.cc
src/service_inspectors/http_inspect/http_cutter.cc
src/service_inspectors/http_inspect/http_cutter.h
src/service_inspectors/http_inspect/http_field.cc
src/service_inspectors/http_inspect/http_field.h
src/service_inspectors/http_inspect/http_flow_data.cc
src/service_inspectors/http_inspect/http_flow_data.h
src/service_inspectors/http_inspect/http_msg_body.cc
src/service_inspectors/http_inspect/http_msg_head_shared.cc
src/service_inspectors/http_inspect/http_msg_head_shared.h
src/service_inspectors/http_inspect/http_msg_header.cc
src/service_inspectors/http_inspect/http_msg_request.cc
src/service_inspectors/http_inspect/http_msg_start.cc
src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc
src/service_inspectors/http_inspect/http_stream_splitter_scan.cc
src/service_inspectors/http_inspect/http_transaction.cc
src/service_inspectors/http_inspect/http_uri.cc
src/service_inspectors/http_inspect/http_uri.h
src/service_inspectors/http_inspect/test/http_module_test.cc
src/service_inspectors/http_inspect/test/http_msg_head_shared_util_test.cc
src/service_inspectors/http_inspect/test/http_normalizers_test.cc
src/service_inspectors/http_inspect/test/http_transaction_test.cc
src/service_inspectors/http_inspect/test/http_uri_norm_test.cc
src/service_inspectors/iec104/iec104.h
src/service_inspectors/imap/imap.h
src/service_inspectors/modbus/dev_notes.txt
src/service_inspectors/modbus/modbus.h
src/service_inspectors/pop/pop.h
src/service_inspectors/rpc_decode/rpc_decode.cc
src/service_inspectors/s7commplus/s7comm.h
src/service_inspectors/sip/sip.cc
src/service_inspectors/sip/sip.h
src/service_inspectors/sip/sip_dialog.cc
src/service_inspectors/sip/sip_parser.cc
src/service_inspectors/smtp/smtp.h
src/service_inspectors/ssh/ssh.h
src/service_inspectors/ssl/ssl_inspector.h
src/stream/base/stream_base.cc
src/stream/file/file_session.cc
src/stream/icmp/icmp_session.cc
src/stream/ip/ip_defrag.cc
src/stream/ip/ip_session.cc
src/stream/stream.cc
src/stream/stream.h
src/stream/tcp/tcp_segment_node.cc
src/stream/tcp/tcp_session.cc
src/stream/tcp/tcp_stream_tracker.cc
src/stream/udp/udp_session.cc
src/stream/user/dev_notes.txt
src/stream/user/user_session.cc
src/utils/stats.cc

index a60b2f3aa4ea037528fdeae7660379fa87a1a8f9..5d76bc3c685abdae4b31dcb573503f4cdb43d4b5 100644 (file)
@@ -48,9 +48,6 @@ string(APPEND CMAKE_C_FLAGS " ${EXTRA_C_FLAGS}")
 string(APPEND CMAKE_CXX_FLAGS " ${EXTRA_CXX_FLAGS}")
 string(APPEND CMAKE_EXE_LINKER_FLAGS " ${EXTRA_LINKER_FLAGS}")
 string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${EXTRA_LINKER_FLAGS}")
-foreach (EXTRA_LIBRARY IN LISTS EXTRA_LIBRARIES)
-    link_libraries(${EXTRA_LIBRARY})
-endforeach (EXTRA_LIBRARY)
 
 include_directories (${PROJECT_BINARY_DIR})
 include_directories (${PROJECT_SOURCE_DIR})
@@ -183,6 +180,14 @@ else ()
     TCMalloc:       OFF")
 endif ()
 
+if (HAVE_JEMALLOC)
+    message("\
+    JEMalloc:       ON")
+else ()
+    message("\
+    JEMalloc:       OFF")
+endif ()
+
 if (HAVE_UUID)
     message("\
     UUID:           ON")
diff --git a/cmake/FindJEMalloc.cmake b/cmake/FindJEMalloc.cmake
new file mode 100644 (file)
index 0000000..d7ad001
--- /dev/null
@@ -0,0 +1,49 @@
+# - Try to find jemalloc
+# Once done this will define
+#  JEMALLOC_FOUND        - System has jemalloc
+#  JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
+#  JEMALLOC_LIBRARIES    - The libraries needed to use jemalloc
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
+
+find_path(JEMALLOC_INCLUDE_DIR
+  NAMES jemalloc/jemalloc.h
+  HINTS ${PC_JEMALLOC_INCLUDE_DIRS}
+)
+
+if ( STATIC_JEMALLOC )
+  find_library(JEMALLOC_LIBRARY
+    NAMES libjemalloc.a jemalloc
+    HINTS ${PC_JEMALLOC_LIBRARY_DIRS}
+)
+else()
+  find_library(JEMALLOC_LIBRARY
+    NAMES jemalloc
+    HINTS ${PC_JEMALLOC_LIBRARY_DIRS}
+)
+endif()
+
+if(JEMALLOC_INCLUDE_DIR)
+  set(_version_regex "^#define[ \t]+JEMALLOC_VERSION[ \t]+\"([^\"]+)\".*")
+  file(STRINGS "${JEMALLOC_INCLUDE_DIR}/jemalloc/jemalloc.h"
+    JEMALLOC_VERSION REGEX "${_version_regex}")
+  string(REGEX REPLACE "${_version_regex}" "\\1"
+    JEMALLOC_VERSION "${JEMALLOC_VERSION}")
+  unset(_version_regex)
+endif()
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
+# if all listed variables are TRUE and the requested version matches.
+find_package_handle_standard_args(Jemalloc REQUIRED_VARS
+                                  JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR
+                                  VERSION_VAR JEMALLOC_VERSION)
+
+if(JEMALLOC_FOUND)
+  set(JEMALLOC_LIBRARIES    ${JEMALLOC_LIBRARY})
+  set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)
+
index 8a7a3aebd68f0e7854ebc6c03d1c868845f15423..4b3cd306be35b36e9aacb28982d9a5e6becfbe4d 100644 (file)
@@ -21,7 +21,9 @@ set ( USE_STDLOG ${ENABLE_STDLOG} )
 set ( USE_TSC_CLOCK ${ENABLE_TSC_CLOCK} )
 set ( NO_PROFILER ${DISABLE_SNORT_PROFILER} )
 set ( DEEP_PROFILING ${ENABLE_DEEP_PROFILING} )
-set ( NO_MEM_MGR ${DISABLE_MEMORY_MANAGER} )
+set ( ENABLE_MEMORY_OVERLOADS ${ENABLE_MEMORY_OVERLOADS} )
+set ( ENABLE_MEMORY_PROFILER ${ENABLE_MEMORY_PROFILER} )
+set ( ENABLE_RULE_PROFILER ${ENABLE_RULE_PROFILER} )
 
 if ( ENABLE_LARGE_PCAP )
     set ( _FILE_OFFSET_BITS 64 )
@@ -170,6 +172,15 @@ if ( ENABLE_TCMALLOC )
     set ( HAVE_TCMALLOC "1" )
 endif ( ENABLE_TCMALLOC )
 
+if ( ENABLE_JEMALLOC )
+    if ( ENABLE_ADDRESS_SANITIZER )
+        message ( SEND_ERROR "JEMalloc cannot be used at the same time as address sanitizer!" )
+    endif ()
+    find_package ( JEMalloc REQUIRED )
+    set ( JEMALLOC_C_FLAGS "-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" )
+    set ( HAVE_JEMALLOC "1" )
+endif ( ENABLE_JEMALLOC )
+
 if ( ENABLE_CODE_COVERAGE )
     include(${CMAKE_MODULE_PATH}/CodeCoverage.cmake)
 endif ( ENABLE_CODE_COVERAGE )
@@ -193,6 +204,6 @@ message("
 set ( EXTRA_C_FLAGS "${EXTRA_C_FLAGS} ${HARDENED_CXX_FLAGS} ${DEBUGGING_C_FLAGS} ${SANITIZER_CXX_FLAGS} ${TCMALLOC_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" )
 set ( EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} ${HARDENED_CXX_FLAGS} ${DEBUGGING_C_FLAGS} ${SANITIZER_CXX_FLAGS} ${TCMALLOC_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" )
 set ( EXTRA_LINKER_FLAGS "${EXTRA_LINKER_FLAGS} ${HARDENED_LINKER_FLAGS} ${SANITIZER_LINKER_FLAGS} ${COVERAGE_LINKER_FLAGS}" )
-foreach (EXTRA_LIBRARY IN LISTS COVERAGE_LIBRARIES TCMALLOC_LIBRARIES )
+foreach (EXTRA_LIBRARY IN LISTS COVERAGE_LIBRARIES TCMALLOC_LIBRARIES JEMALLOC_LIBRARY )
     list ( APPEND EXTRA_LIBRARIES ${EXTRA_LIBRARY} )
 endforeach ()
index 090a76240fad9f848d28d69397c26404d950810c..c5eb025a3248dbc0e0acac264dcd8368b8d56ae3 100644 (file)
@@ -43,11 +43,14 @@ option ( ENABLE_GDB "Enable gdb debugging information" ON )
 option ( ENABLE_PROFILE "Enable profiling options (developers only)" OFF )
 option ( DISABLE_SNORT_PROFILER "Disable snort Profiler (developers only)" OFF )
 option ( ENABLE_DEEP_PROFILING "Enable deep profiling of snort functions (developers only)" OFF )
-option ( DISABLE_MEMORY_MANAGER "Disable snort memory manager (developers only)" OFF )
+option ( ENABLE_MEMORY_OVERLOADS "Use new / delete overloads for profiling (developers only)" OFF )
+option ( ENABLE_MEMORY_PROFILER "Enable memory profiler (developers only)" OFF )
+option ( ENABLE_RULE_PROFILER "Enable rule keyword profiler (developers only)" OFF )
 option ( ENABLE_ADDRESS_SANITIZER "enable address sanitizer support" OFF )
 option ( ENABLE_THREAD_SANITIZER "enable thread sanitizer support" OFF )
 option ( ENABLE_UB_SANITIZER "enable undefined behavior sanitizer support" OFF )
 option ( ENABLE_TCMALLOC "enable using tcmalloc for dynamic memory management" OFF )
+option ( ENABLE_JEMALLOC "enable using jemalloc for dynamic memory management" OFF )
 option ( ENABLE_CODE_COVERAGE "Whether to enable code coverage support" OFF )
 
 # signals
index 9808275e16c43e7f69ef75baf472b4103652bc6b..583990836d881bf5fc4c0d0cd7c33c4066822e5c 100644 (file)
@@ -16,8 +16,16 @@ if(DAQ_INCLUDE_DIR)
     set(DAQ_CPPFLAGS "-I${DAQ_INCLUDE_DIR}")
 endif()
 
-if(DISABLE_MEMORY_MANAGER)
-    set(NO_MEM_MGR_CPPFLAGS "-DNO_MEM_MGR")
+if(ENABLE_MEMORY_OVERLOADS)
+    set(MEMORY_OVERLOADS_CPPFLAGS "-DENABLE_MEMORY_OVERLOADS")
+endif()
+
+if(ENABLE_MEMORY_PROFILER)
+    set(MEMORY_PROFILER_CPPFLAGS "-DENABLE_MEMORY_PROFILER")
+endif()
+
+if(ENABLE_RULE_PROFILER)
+    set(RULE_PROFILER_CPPFLAGS "-DENABLE_RULE_PROFILER")
 endif()
 
 if(DISABLE_SNORT_PROFILER)
index d50c6cff194ff470ff654d90957ae01d0dda74a9..6e1655634af6e4b8f8d4348cfbcb26db8aba0206 100644 (file)
 /* disable snort profiler */
 #cmakedefine NO_PROFILER 1
 
-/* disable snort memory manager */
-#cmakedefine NO_MEM_MGR 1
+/* enable memory profiler */
+#cmakedefine ENABLE_MEMORY_PROFILER 1
+
+/* enable rule profiler */
+#cmakedefine ENABLE_RULE_PROFILER 1
+
+/* enable deep profiling */
+#cmakedefine DEEP_PROFILING 1
+
+/* enable new and delete overloads for profiling */
+#cmakedefine ENABLE_MEMORY_OVERLOADS 1
 
 /* signal to dump stats  */
 #cmakedefine SIGNAL_SNORT_DUMP_STATS @SIGNAL_SNORT_DUMP_STATS@
 /* safec available */
 #cmakedefine HAVE_SAFEC 1
 
+/* jemalloc available */
+#cmakedefine HAVE_JEMALLOC 1
+
 /* uuid available */
 #cmakedefine HAVE_UUID 1
 
index e2275cfcf1de19172d000c15645352b1c115fd3b..8c2d2b147167439ed0a536c789638056d5c21d8c 100755 (executable)
@@ -54,17 +54,22 @@ Optional Features:
     --enable-gprof-profile  enable gprof profiling options (developers only)
     --disable-snort-profiler
                             disable snort performance profiling (cpu and memory) (developers only)
-    --disable-memory-manager
-                            disable snort memory manager (developers only)
+    --enable-memory-overloads
+                            overload new and delete
+    --enable-memory-profiler
+                            enable memory profiler
+    --enable-rule-profiler  enable rule keyword profiler (developers only)
+    --enable-deep-profiling enable deep (multi-level) profiling (developers only)
     --disable-corefiles     prevent Snort from generating core files
     --enable-address-sanitizer
                             enable address sanitizer support
     --enable-thread-sanitizer
                             enable thread sanitizer support
-    --enable-ub-sanitizer
-                            enable undefined behavior sanitizer support
-    --enable-tcmalloc
-                            enable using tcmalloc for dynamic memory management
+    --enable-ub-sanitizer   enable undefined behavior sanitizer support
+    --enable-tcmalloc       enable using tcmalloc for dynamic memory management
+    --enable-jemalloc       enable using jemalloc for dynamic memory management
+    --enable-jemalloc-static
+                            same as --enable-jemalloc but linked statically
     --enable-appid-third-party
                             enable third party appid
     --enable-unit-tests     build unit tests
@@ -255,10 +260,19 @@ while [ $# -ne 0 ]; do
             append_cache_entry ENABLE_TSC_CLOCK         BOOL true
             ;;
         --disable-snort-profiler)
-            append_cache_entry DISABLE_SNORT_PROFILER   BOOL true
+            append_cache_entry DISABLE_SNORT_PROFILER   BOOL false
             ;;
-        --disable-memory-manager)
-            append_cache_entry DISABLE_MEMORY_MANAGER   BOOL true
+        --enable-memory-overloads)
+            append_cache_entry ENABLE_MEMORY_OVERLOADS  BOOL true
+            ;;
+        --enable-memory-profiler)
+            append_cache_entry ENABLE_MEMORY_PROFILER   BOOL true
+            ;;
+        --enable-rule-profiler)
+            append_cache_entry ENABLE_RULE_PROFILER     BOOL true
+            ;;
+        --enable-deep-profiling)
+            append_cache_entry DEEP_PROFILING           BOOL true
             ;;
         --disable-large-pcap)
             append_cache_entry ENABLE_LARGE_PCAP        BOOL false
@@ -317,6 +331,20 @@ while [ $# -ne 0 ]; do
         --disable-tcmalloc)
             append_cache_entry ENABLE_TCMALLOC          BOOL false
             ;;
+        --enable-jemalloc)
+            append_cache_entry ENABLE_JEMALLOC          BOOL true
+            append_cache_entry STATIC_JEMALLOC          BOOL false
+            ;;
+        --disable-jemalloc)
+            append_cache_entry ENABLE_JEMALLOC          BOOL false
+            ;;
+        --enable-jemalloc-static)
+            append_cache_entry ENABLE_JEMALLOC          BOOL true
+            append_cache_entry STATIC_JEMALLOC          BOOL true
+            ;;
+        --disable-jemalloc-static)
+            append_cache_entry ENABLE_JEMALLOC          BOOL false
+            ;;
         --enable-appid-third-party)
             ;;
         --enable-unit-tests)
index 732c2a82480b900e5bdde02616016086cc304c88..005950f02787784bb961d627484ba8110112929c 100644 (file)
@@ -22,7 +22,6 @@ scalability, usability, and extensibility.  Some of the key features of Snort 3.
 * New latency monitoring and enforcement
 * Piglets to facilitate component testing
 * Inspection Events
-* Automake and Cmake
 * Autogenerate reference documentation
 
 === Efficacy
index 05a5f67dcf94af9218c873a666d8cfc9ecf5d949..63c5782eee83f5d36cee1d2c19eec1bf4981f0e8 100644 (file)
@@ -22,7 +22,6 @@ usability.  Some of the key features of Snort 3.0 are:
 * New latency monitoring and enforcement
 * Piglets to facilitate component testing
 * Inspection Events
-* Automake and Cmake
 * Autogenerate reference documentation
 
 Additional features are on the road map:
index 973dcb1f52ae211d32356598ba3a554007bdfafd..ee35ec924004f9eb4e87d168a572af3176d36521 100644 (file)
@@ -29,5 +29,5 @@ Description: Snort 3.0 Project
 URL: www.snort.org
 Version: @VERSION@
 Libs: -L${libdir}/snort
-Cflags: -I${includedir}/snort @DEEP_PROFILING_CPPFLAGS@ @NO_MEM_MGR_CPPFLAGS@ @NO_PROFILER_CPPFLAGS@ @TP_APPID_CPPFLAGS@ @TSC_CPPFLAGS@
+Cflags: -I${includedir}/snort @DEEP_PROFILING_CPPFLAGS@ @MEMORY_OVERLOADS_CPPFLAGS@ @MEMORY_PROFILER_CPPFLAGS@ @RULE_PROFILER_CPPFLAGS@ @NO_PROFILER_CPPFLAGS@ @TP_APPID_CPPFLAGS@ @TSC_CPPFLAGS@
 
index e795441ddec915a94a44b64e45f0071ea0fc69ff..756be158933aa10786150592baba86a35ecda5a4 100644 (file)
@@ -211,6 +211,7 @@ message("
 
 target_link_libraries( snort
     ${EXTERNAL_LIBRARIES}
+    ${EXTRA_LIBRARIES}
 )
 
 # Solaris requires libnsl and libsocket for various network-related library functions
index 8baae9c432fd996629087851c478a80de225a90d..97212d39e719c3a9571b25969fbb91e3dfeefee9 100644 (file)
@@ -14,7 +14,7 @@ Reject performs active response to shutdown hostile network session by injecting
 TCP resets (TCP connections) or ICMP unreachable packets.
 
 React sends an HTML page to the client, a RST to the server and blocks the flow.
-It is using payload_injector utilty. payload_injector should be configured when
+It is using payload_injector utility. payload_injector should be configured when
 react is used.
 
 Rewrite enables overwrite packet contents based on "replace" option in the
index cb57917d3852b678a6401001eb2830af7c49463d..950fd340586ab099cf37b1ff38000ce6197138f5 100644 (file)
@@ -321,8 +321,8 @@ void ThreadRegexOffload::worker(
         }
 #endif
     }
-    ModuleManager::accumulate_offload("search_engine");
-    ModuleManager::accumulate_offload("detection");
+    ModuleManager::accumulate_module("search_engine");
+    ModuleManager::accumulate_module("detection");
 
     // FIXIT-M break this over-coupling. In reality we shouldn't be evaluating latency in offload.
     PacketLatency::tterm();
index 0e28cfdadba24e1faeed80ead92989cf04ee870b..6816453c10434c605948ac0efa630fd5c5a247f2 100644 (file)
@@ -106,9 +106,6 @@ public:
     void set_file_policy(FilePolicyBase* fp) { file_policy = fp; }
     FilePolicyBase* get_file_policy() { return file_policy; }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 private:
     void init_file_context(FileDirection, FileContext*);
     FileContext* find_main_file_context(FilePosition, FileDirection, size_t id = 0);
index 4abbe959a4736d0a1f6599a28888b2706c94aaa3..d6ae957b848e5ed73314710a3ef54396889fe2c2 100644 (file)
@@ -38,7 +38,7 @@ flow creation when the appropriate DAQ packet message flag has been set on the
 initiating packet.
 
 The HA subsystem exchanges two high level message types:
-  - DELETE: Indicate to the partner that a session has neen removed.  No
+  - DELETE: Indicate to the partner that a session has been removed.  No
 additional HA client status will be exchanged.  (Not used for DAQ-backed
 storage.)
   - UPDATE: Indicate all other state changes.  The message always includes
index 58e4e0c1945faba465a74164a1679f63ddeb5dc7..99e49ff8751817d6279d07c69590d283dfc42235 100644 (file)
@@ -40,7 +40,6 @@ using namespace snort;
 
 Flow::Flow()
 {
-    memory::MemoryCap::update_allocations(sizeof(*this) + sizeof(FlowStash));
     constexpr size_t offset = offsetof(Flow, key);
     // FIXIT-L need a struct to zero here to make future proof
     memset((uint8_t*)this+offset, 0, sizeof(*this)-offset);
@@ -48,7 +47,6 @@ Flow::Flow()
 
 Flow::~Flow()
 {
-    memory::MemoryCap::update_deallocations(sizeof(*this) + sizeof(FlowStash));
     term();
 }
 
@@ -280,12 +278,6 @@ int Flow::set_flow_data(FlowData* fd)
         flow_data->prev = fd;
 
     flow_data = fd;
-
-    // this is after actual allocation so we can't prune beforehand
-    // but if we are that close to the edge we are in trouble anyway
-    // large allocations can be accounted for directly
-    fd->update_allocations(fd->size_of());
-
     return 0;
 }
 
@@ -321,7 +313,6 @@ void Flow::free_flow_data(FlowData* fd)
         fd->prev->next = fd->next;
         fd->next->prev = fd->prev;
     }
-    fd->update_deallocations(fd->size_of());
     delete fd;
 }
 
@@ -339,7 +330,6 @@ void Flow::free_flow_data()
     {
         FlowData* tmp = flow_data;
         flow_data = flow_data->next;
-        tmp->update_deallocations(tmp->size_of());
         delete tmp;
     }
 }
index 669405e888cf2a057206d75e1e35365d180bff83..f899b893999dd54f8cb4661b51a65436158ff283 100644 (file)
@@ -162,7 +162,6 @@ Flow* FlowCache::allocate(const FlowKey* key)
         {
             Flow* new_flow = new Flow();
             push(new_flow);
-            memory::MemoryCap::update_allocations(sizeof(HashNode) + sizeof(FlowKey));
         }
         else if ( !prune_stale(timestamp, nullptr) )
         {
@@ -183,7 +182,6 @@ Flow* FlowCache::allocate(const FlowKey* key)
     if ( flow->session && flow->pkt_type != key->pkt_type )
         flow->term();
 
-    memory::MemoryCap::update_allocations(config.proto[to_utype(key->pkt_type)].cap_weight);
     flow->last_data_seen = timestamp;
 
     return flow;
@@ -193,11 +191,7 @@ void FlowCache::remove(Flow* flow)
 {
     unlink_uni(flow);
 
-    // FIXIT-M This check is added for offload case where both Flow::reset
-    // and Flow::retire try remove the flow from hash. Flow::reset should
-    // just mark the flow as pending instead of trying to remove it.
-    if ( !hash_table->release_node(flow->key) )
-        memory::MemoryCap::update_deallocations(config.proto[to_utype(flow->key->pkt_type)].cap_weight);
+    hash_table->release_node(flow->key);
 }
 
 bool FlowCache::release(Flow* flow, PruneReason reason, bool do_cleanup)
@@ -462,7 +456,6 @@ unsigned FlowCache::delete_active_flows(unsigned mode, unsigned num_to_delete, u
         //The flow should not be removed from the hash before reset
         hash_table->remove();
         delete flow;
-        memory::MemoryCap::update_deallocations(sizeof(HashNode) + sizeof(FlowKey));
         --flows_allocated;
         ++deleted;
         --num_to_delete;
@@ -489,7 +482,6 @@ unsigned FlowCache::delete_flows(unsigned num_to_delete)
 
             delete flow;
             delete_stats.update(FlowDeleteState::FREELIST);
-            memory::MemoryCap::update_deallocations(sizeof(HashNode) + sizeof(FlowKey));
 
             --flows_allocated;
             ++deleted;
@@ -526,7 +518,6 @@ unsigned FlowCache::purge()
     while ( Flow* flow = (Flow*)hash_table->pop() )
     {
         delete flow;
-        memory::MemoryCap::update_deallocations(sizeof(HashNode) + sizeof(FlowKey));
         --flows_allocated;
     }
 
index 53e6961de4b64a320dbed3112bfcf6af6b5d6e60..a09b8ee2f756c66240d497fa689e5d14dafb2918 100644 (file)
@@ -27,7 +27,6 @@
 #include "detection/detection_engine.h"
 #include "main/snort_config.h"
 #include "managers/inspector_manager.h"
-#include "memory/memory_cap.h"
 #include "packet_io/active.h"
 #include "packet_tracer/packet_tracer.h"
 #include "protocols/icmp4.h"
@@ -123,16 +122,6 @@ void FlowControl::timeout_flows(time_t cur_time)
     cache->timeout(1, cur_time);
 }
 
-void FlowControl::preemptive_cleanup()
-{
-    // FIXIT-RC is there a possibility of this looping forever?
-    while ( memory::MemoryCap::over_threshold() )
-    {
-        if ( !prune_one(PruneReason::PREEMPTIVE, true) )
-            break;
-    }
-}
-
 Flow* FlowControl::stale_flow_cleanup(FlowCache* cache, Flow* flow, Packet* p)
 {
     if ( p->pkth->flags & DAQ_PKT_FLAG_NEW_FLOW )
@@ -432,7 +421,6 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
     p->disable_inspect = flow->is_inspection_disabled();
 
     last_pkt_type = p->type();
-    preemptive_cleanup();
 
     // If this code is executed on a flow in SETUP state, it will result in a packet from both
     // client and server on packets from 0.0.0.0 or ::
index 006931440d343a0b302a31ca654a51ea49569b7e..28d1c4fe7f62158085f21976097e466553ab819c 100644 (file)
@@ -97,7 +97,6 @@ public:
 private:
     void set_key(snort::FlowKey*, snort::Packet*);
     unsigned process(snort::Flow*, snort::Packet*);
-    void preemptive_cleanup();
     void update_stats(snort::Flow*, snort::Packet*);
 
 private:
index b14d008487fced1d81d0abe6bf898291843450a5..1d221c1a8226076d3e5bb0b429746ac1d009ec39 100644 (file)
@@ -48,33 +48,6 @@ FlowData::~FlowData()
 {
     if ( handler )
         handler->rem_ref();
-
-    assert(mem_in_use == 0);
-    assert(net_allocation_calls == 0);
-}
-
-void FlowData::update_allocations(size_t n)
-{
-    memory::MemoryCap::update_allocations(n);
-
-    if (n > 0)
-    {
-        mem_in_use += n;
-        net_allocation_calls++;
-    }
-}
-
-void FlowData::update_deallocations(size_t n)
-{
-    memory::MemoryCap::update_deallocations(n);
-
-    if (n > 0)
-    {
-        assert(mem_in_use >= n);
-        mem_in_use -= n;
-        assert(net_allocation_calls > 0);
-        net_allocation_calls--;
-    }
 }
 
 RuleFlowData::RuleFlowData(unsigned u) :
index 0b883a5120f74afa5b63dd6a9363724f85e00e96..f1ac3eda5eff1c5b478f5b27eaefeb695da89107 100644 (file)
@@ -39,17 +39,10 @@ public:
     static unsigned create_flow_data_id()
     { return ++flow_data_id; }
 
-    // Allocations and deallocations must balance. It is not enough that the total number of bytes
-    // allocated and deallocated are equal. They must be allocated and deallocated in the same
-    // increments or roundoffs done inside the functions may not balance.
-    void update_allocations(size_t);
-    void update_deallocations(size_t);
     Inspector* get_handler() { return handler; }
 
-    // return fixed size (could be an approx avg)
-    // this must be fixed for life of flow data instance
-    // track significant supplemental allocations with the above updaters
-    virtual size_t size_of() = 0;
+    // deprecated - do not implement
+    virtual size_t size_of() { return 0; }
 
     virtual void handle_expected(Packet*) { }
     virtual void handle_retransmit(Packet*) { }
@@ -62,8 +55,6 @@ public:  // FIXIT-L privatize
 private:
     static unsigned flow_data_id;
     Inspector* handler;
-    size_t mem_in_use = 0;
-    unsigned net_allocation_calls = 0;
     unsigned id;
 };
 
index e46c79a6200bcaaa878b809a3463dbe27f8dfd6d..735530571ece48fe8923a5524f04de063fa5ce38 100644 (file)
@@ -31,7 +31,6 @@ enum class PruneReason : uint8_t
     IDLE,
     EXCESS,
     UNI,
-    PREEMPTIVE,
     MEMCAP,
     HA,
     STALE,
index ef36fb693b1cc4fffd0063c55b46a2c06a7aceea..95882d680041be3498cc8c4815071c5c2deb0268 100644 (file)
@@ -38,15 +38,12 @@ class StashGenericObject
 {
 public:
     StashGenericObject(int type) : object_type(type)
-    {
+    { }
 
-    }
     virtual ~StashGenericObject() = default;
+
     int get_object_type() const
-    {
-        return object_type;
-    }
-    virtual size_t size_of() const = 0;
+    { return object_type; }
 
 private:
     int object_type;
@@ -99,7 +96,6 @@ public:
     {
         type = STASH_ITEM_TYPE_GENERIC_OBJECT;
         val.generic_obj_val = obj;
-        memory::MemoryCap::update_allocations(sizeof(*this) + obj->size_of());
     }
 
     ~StashItem()
@@ -110,7 +106,6 @@ public:
             delete val.str_val;
             break;
         case STASH_ITEM_TYPE_GENERIC_OBJECT:
-            memory::MemoryCap::update_deallocations(sizeof(*this) + val.generic_obj_val->size_of());
             delete val.generic_obj_val;
         default:
             break;
index 2ad995ce89de1740ecac0752cf53f81979dc924a..df3cf6cebc45bd90b31d45156d551ec0f3260ead 100644 (file)
@@ -30,7 +30,6 @@
 #include "main/snort_config.h"
 #include "main/snort_debug.h"
 #include "managers/inspector_manager.h"
-#include "memory/memory_cap.h"
 #include "packet_io/active.h"
 #include "packet_tracer/packet_tracer.h"
 #include "protocols/icmp4.h"
@@ -99,12 +98,6 @@ SfIpRet SfIp::set(void const*, int) { return SFIP_SUCCESS; }
 void snort::trace_vprintf(const char*, TraceLevel, const char*, const Packet*, const char*, va_list) {}
 uint8_t snort::TraceApi::get_constraints_generation() { return 0; }
 void snort::TraceApi::filter(const Packet&) {}
-namespace memory
-{
-void MemoryCap::update_allocations(size_t) { }
-void MemoryCap::update_deallocations(size_t) { }
-bool MemoryCap::over_threshold() { return true; }
-}
 
 namespace snort
 {
index 5f3ae5ee05ef0978b0a3d50ac6edaed31b824ad3..4527fddee50909ac2730d387bafc86d2a78b28d0 100644 (file)
@@ -29,7 +29,6 @@
 #include "detection/detection_engine.h"
 #include "main/snort_config.h"
 #include "managers/inspector_manager.h"
-#include "memory/memory_cap.h"
 #include "packet_io/active.h"
 #include "packet_tracer/packet_tracer.h"
 #include "protocols/icmp4.h"
@@ -100,11 +99,6 @@ bool ExpectCache::check(Packet*, Flow*) { return true; }
 bool ExpectCache::is_expected(Packet*) { return true; }
 Flow* HighAvailabilityManager::import(Packet&, FlowKey&) { return nullptr; }
 
-namespace memory
-{
-bool MemoryCap::over_threshold() { return true; }
-}
-
 namespace snort
 {
 namespace layer
index 855c7272b41a2cc92183799e9192d226c1dbfe39..2e4f11807812c235f78c27a7afe754965ec51cd1 100644 (file)
 using namespace snort;
 using namespace std;
 
-
 static DataBus* DB = nullptr;
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
-class TestStashObject : public StashGenericObject
-{
-public:
-    TestStashObject(int type) : StashGenericObject(type)
-    {
-
-    }
-
-    size_t size_of() const override
-    { return sizeof(*this); }
-};
-
-
 template<class Type>
 class DBConsumer : public DataHandler
 {
@@ -310,23 +293,23 @@ TEST(stash_tests, non_existent_item)
 TEST(stash_tests, new_generic_object)
 {
     FlowStash stash;
-    TestStashObject *test_object = new TestStashObject(111);
+    StashGenericObject *test_object = new StashGenericObject(111);
 
     stash.store("item_1", test_object);
 
     StashGenericObject *retrieved_object;
     CHECK(stash.get("item_1", retrieved_object));
     POINTERS_EQUAL(test_object, retrieved_object);
-    CHECK_EQUAL(test_object->get_object_type(), ((TestStashObject*)retrieved_object)->get_object_type());
+    CHECK_EQUAL(test_object->get_object_type(), ((StashGenericObject*)retrieved_object)->get_object_type());
 }
 
 TEST(stash_tests, update_generic_object)
 {
     FlowStash stash;
-    TestStashObject *test_object = new TestStashObject(111);
+    StashGenericObject *test_object = new StashGenericObject(111);
     stash.store("item_1", test_object);
 
-    TestStashObject *new_test_object = new TestStashObject(111);
+    StashGenericObject *new_test_object = new StashGenericObject(111);
     stash.store("item_1", new_test_object);
 
     StashGenericObject *retrieved_object;
@@ -344,7 +327,7 @@ TEST(stash_tests, non_existent_generic_object)
 TEST(stash_tests, mixed_items)
 {
     FlowStash stash;
-    TestStashObject *test_object = new TestStashObject(111);
+    StashGenericObject *test_object = new StashGenericObject(111);
 
     stash.store("item_1", 10);
     stash.store("item_2", "value_2");
@@ -364,7 +347,7 @@ TEST(stash_tests, mixed_items)
     StashGenericObject *retrieved_object;
     CHECK(stash.get("item_4", retrieved_object));
     POINTERS_EQUAL(test_object, retrieved_object);
-    CHECK_EQUAL(test_object->get_object_type(), ((TestStashObject*)retrieved_object)->get_object_type());
+    CHECK_EQUAL(test_object->get_object_type(), ((StashGenericObject*)retrieved_object)->get_object_type());
 }
 
 TEST(stash_tests, store_ip)
index a8e8bfb1a7c98943f808bd3da24ed0d010b89d4a..872cd642d6dfcee21c87c20189e1cdf506bd0251 100644 (file)
@@ -30,7 +30,6 @@
 #include "framework/inspector.h"
 #include "framework/data_bus.h"
 #include "main/snort_config.h"
-#include "memory/memory_cap.h"
 #include "protocols/ip.h"
 #include "protocols/layer.h"
 #include "protocols/packet.h"
@@ -47,12 +46,6 @@ void Inspector::rem_ref() {}
 
 void Inspector::add_ref() {}
 
-void memory::MemoryCap::update_allocations(size_t) {}
-
-void memory::MemoryCap::update_deallocations(size_t) {}
-
-void memory::MemoryCap::free_space(size_t) { }
-
 bool HighAvailabilityManager::active() { return false; }
 
 FlowHAState::FlowHAState() = default;
index 3186b06bac301a89590d8ac0e2e5679a68b22b6f..d65d337e31167052628eb90c1208dea657233824 100644 (file)
@@ -29,7 +29,7 @@
 
 // this is the current version of the base api
 // must be prefixed to subtype version
-#define BASE_API_VERSION 10
+#define BASE_API_VERSION 11
 
 // set options to API_OPTIONS to ensure compatibility
 #ifndef API_OPTIONS
index 0e6b77c13b2131696dcda962a8c7907173439b69..68662998fb8808c894d16643994464664ec205b6 100644 (file)
@@ -257,6 +257,7 @@ TEST(hyper_search_test_group, not_found4)
 
 int main(int argc, char** argv)
 {
+    MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
     return CommandLineTestRunner::RunAllTests(argc, argv);
 }
 
index 76e7ef53068952bf540ccc464678dcfd9c8db896..a6b1236b6dad989028ea9f621fad10a256703f54 100644 (file)
@@ -369,6 +369,7 @@ TEST(ips_regex_option_relative, no_match)
 
 int main(int argc, char** argv)
 {
+    MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
     return CommandLineTestRunner::RunAllTests(argc, argv);
 }
 
index 2f4366bdda980aeb5d7f87cfebcfe978f6a420fa..481698bacc832888eb6224acca6efc73a1001ca6 100644 (file)
@@ -13,7 +13,7 @@ Text output logging facilities are located here:
   data.
 
   class Obfuscator is implemented with a std::set to provide in order
-  access for pottentialy out-of-order insertions.
+  access for potentially out-of-order insertions.
 
   Currently does not support streaming mode.  It should be possible to
   iterate over contiguous chunks of data, alternating between obfuscated
index 8a0192dce7fcfa52aebee2828ef1bb6ece8a0489..2530b874d2492487f6e5e6af5c64da14ea909ede 100644 (file)
@@ -137,6 +137,13 @@ public:
 private:
     void reap_command(AnalyzerCommand* ac);
 
+    // we could just let the analyzer own this pointer and delete
+    // immediately after getting the data but that creates memory
+    // count mismatches between main and packet threads. since the
+    // startup swapper has no old config to delete only 32 bytes
+    // after held.
+    Swapper* swapper = nullptr;
+
     std::thread* athread = nullptr;
     unsigned idx = (unsigned)-1;
 };
@@ -166,8 +173,8 @@ void Pig::start()
     assert(!athread);
     LogMessage("++ [%u] %s\n", idx, analyzer->get_source());
 
-    Swapper* ps = new Swapper(SnortConfig::get_main_conf());
-    athread = new std::thread(std::ref(*analyzer), ps, ++run_num);
+    swapper = new Swapper(SnortConfig::get_main_conf());
+    athread = new std::thread(std::ref(*analyzer), swapper, ++run_num);
 }
 
 void Pig::stop()
@@ -175,6 +182,9 @@ void Pig::stop()
     assert(analyzer);
     assert(athread);
 
+    delete swapper;
+    swapper = nullptr;
+
     athread->join();
     delete athread;
     athread = nullptr;
index 08b810c6594ce42afd576f908951a241d78d494b..8a08e503f03d6edb054a1a109530f39fed73bc70 100644 (file)
@@ -286,9 +286,6 @@ static DAQ_Verdict distill_verdict(Packet* p)
 
 void Analyzer::add_to_retry_queue(DAQ_Msg_h daq_msg)
 {
-    // Temporarily increase memcap until message is finalized in case
-    // DAQ makes a copy of the data buffer.
-    memory::MemoryCap::update_allocations(daq_msg_get_data_len(daq_msg));
     retry_queue->put(daq_msg);
 }
 
@@ -404,6 +401,8 @@ void Analyzer::process_daq_pkt_msg(DAQ_Msg_h msg, bool retry)
 void Analyzer::process_daq_msg(DAQ_Msg_h msg, bool retry)
 {
     oops_handler->set_current_message(msg);
+    memory::MemoryCap::free_space();
+
     DAQ_Verdict verdict = DAQ_VERDICT_PASS;
     switch (daq_msg_get_type(msg))
     {
@@ -437,13 +436,11 @@ void Analyzer::process_retry_queue()
         struct timeval now;
         packet_gettimeofday(&now);
         DAQ_Msg_h msg;
+
         while ((msg = retry_queue->get(&now)) != nullptr)
         {
             process_daq_msg(msg, true);
             daq_stats.retries_processed++;
-
-            // Decrease memcap now that msg has been finalized.
-            memory::MemoryCap::update_deallocations(daq_msg_get_data_len(msg));
         }
     }
 }
@@ -678,6 +675,8 @@ void Analyzer::term()
     RateFilter_Cleanup();
 
     TraceApi::thread_term();
+
+    ModuleManager::accumulate_module("memory");
 }
 
 Analyzer::Analyzer(SFDAQInstance* instance, unsigned i, const char* s, uint64_t msg_cnt)
@@ -708,7 +707,6 @@ void Analyzer::operator()(Swapper* ps, uint16_t run_num)
     local_analyzer = this;
 
     ps->apply(*this);
-    delete ps;
 
     if (SnortConfig::get_conf()->pcap_show())
         show_source();
index 2fdea0fbe89fc9ae70220f24ba50947d6ada4462..10e5daac6869cb495e20be753718c4ee4425af16 100644 (file)
@@ -322,8 +322,6 @@ void Snort::term()
 
     const SnortConfig* sc = SnortConfig::get_conf();
 
-    memory::MemoryCap::print();
-
     IpsManager::global_term(sc);
     HostAttributesManager::term();
 
@@ -370,6 +368,8 @@ void Snort::term()
     ModuleManager::term();
     PluginManager::release_plugins();
     ScriptManager::release_scripts();
+    memory::MemoryCap::cleanup();
+
     term_signals();
 }
 
@@ -414,8 +414,9 @@ void Snort::setup(int argc, char* argv[])
 
     set_quick_exit(false);
 
-    memory::MemoryCap::calculate();
-    memory::MemoryCap::print();
+    memory::MemoryCap::setup(*sc->memory, sc->thread_config->get_instance_max());
+    memory::MemoryCap::print(SnortConfig::log_verbose());
+
     host_cache.print_config();
 
     TimeStart();
index 9325445f65da827176baa4fb4b1ffca4cc281e1a..db69b8e051caa0d4adc25c7d27e842ca7739fdad 100644 (file)
@@ -51,8 +51,10 @@ Swapper::Swapper()
 
 Swapper::~Swapper()
 {
-    if ( new_conf )
+    if ( new_conf and old_conf )
+        // don't do this to startup configs
         InspectorManager::clear_removed_inspectors(new_conf);
+
     if ( old_conf )
         delete old_conf;
 }
index cf57a8796976217e406a16ffb545a2ca4990f28b..377bf90eb9d22a6dec09abce7b2680db1a2d24cd 100644 (file)
@@ -51,9 +51,6 @@ void Flow::trust() { }
 SFDAQInstance* SFDAQ::get_local_instance() { return nullptr; }
 }
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 using namespace snort;
 
 //--------------------------------------------------------------------------
index 069d3dd4de16b8d9403a78f108b7bf171e1f7ba2..b0efb5b0a2ba4879821b2474fb3dc76c6e8de719 100644 (file)
@@ -1389,13 +1389,16 @@ void ModuleManager::accumulate()
 
     for ( auto* mh : mod_hooks )
     {
+        if ( !strcmp(mh->mod->name, "memory") )
+            continue;
+
         lock_guard<mutex> lock(stats_mutex);
         mh->mod->prep_counts();
         mh->mod->sum_stats(true);
     }
 }
 
-void ModuleManager::accumulate_offload(const char* name)
+void ModuleManager::accumulate_module(const char* name)
 {
     ModHook* mh = get_hook(name);
     if ( mh )
index 4bb78b325294a48f9193d38e941f4815e80057d3..9c4386c501d523fe3578218233f527b947a8fd21 100644 (file)
@@ -86,7 +86,7 @@ public:
     static void dump_stats(const char* skip = nullptr, bool dynamic = false);
 
     static void accumulate();
-    static void accumulate_offload(const char* name);
+    static void accumulate_module(const char* name);
     static void reset_stats(SnortConfig*);
     static void reset_stats(clear_counter_type_t);
 
index 3b60f8142592e2e4517e1a903f4a314939cf69a8..4d2c563c5f6446e0c033401553a2467cee6e4dc0 100644 (file)
@@ -4,10 +4,13 @@ set (MEMCAP_INCLUDES
 
 set ( MEMORY_SOURCES
     ${MEMCAP_INCLUDES}
+    memory_allocator.cc
+    memory_allocator.h
     memory_cap.cc
+    memory_config.h
+    memory_manager.cc
     memory_module.cc
     memory_module.h
-    memory_config.h
     prune_handler.cc
     prune_handler.h
 )
index 740f87968ab16a8a18711d87201ea8222089094e..7bb872eff5bd1e2b40e69c7fca390d637feaa5a1 100644 (file)
@@ -1,12 +1,79 @@
-This directory provides a simple mechanism for implementing a memory cap.
-Modules can use the MemoryCap::update_allocations() and
-update_deallocations() calls to self-report when they allocate or free
-heap memory. If the total memory allocations exceed the configured memory
-cap, flow pruning is done to free up additional memory.
+Snort memory management monitors memory usage and prunes flows as needed to keep the total process
+usage below the configured limit, if any. There are two ways to build memory management: build with
+jemalloc (--enable-jemalloc) or enable the new / delete overloads (--enable-memory-overloads). The
+latter option is required to support memory profiling (--enable-memory-profiler). Profiling is not
+enabled by default due to performance concerns and is viewed as a developer tool: apart from cache
+memcaps, users should not have to care about how Snort allocates memory, only that it doesn't
+exceed the configured limit if any.
 
-This mechanism is approximate and does not directly reflect the activities
-of the memory allocator or the OOM killer.
+tcmalloc builds (--enable-tcmalloc) do not support memory management.  A process total is available
+from the tcmalloc extensions but it is too expensive to call per packet. Checking every N packets
+would also mean potentially freeing K > 1 flows after each exceeded event. Also, a process total
+does not allow pruning only the threads that are over limit. tcmalloc does provide a performance
+advantage over glibc so that may be preferred for deployments that don't need memory management.
 
-TODO:
+jemalloc is preferred because it is quicker and uses less memory since the implementation does not
+require memory tracking. jemalloc provides access to the current thread allocated total (which is
+between the number that Snort requests and what the system footprint is).
+
+memory_module.* - provides parameters and peg counts. The key parameters are the process_cap,
+thread_cap, and threshold. The caps are in bytes, and the threshold is a percentage of the caps
+specified.
+
+memory_manager.cc - when enabled with --enable-memory-overloads, overloads new and delete operators
+to provide support memory tracking. Metadata is allocated in front of the requested memory to store
+the sized allocated so the deallocation can be tracked. Due to the drag on performance, this is
+disabled by default.
+
+memory_allocator.* - implements the malloc and free calls used by the operator new and delete
+overloads.
+
+memory_config.h - provides MemoryConfig used by MemoryCap and stored in SnortConfig.
+
+memory_cap.* - provides the logic to enforce the thread cap by calling the prune handler. Tracks
+thread usage in pegs and updates the memory profiler if built. To avoid confusion, thread_cap
+refers to the configured maximums, while thread_limit refer to the configured percentage of the
+caps (memory.cap * memory.threshold / 100). The jemalloc specific code is here.
+
+prune_handler.* - implements the call to stream to prune.
+
+The current iteration of the memory manager is exclusively preemptive.  MemoryCap::free_space is
+called by the analyzer before each DAQ message is processed. If thread_usage > thread_limit, a
+single flow will be pruned. Demand-based pruning, ie enforcing that each allocation stays below
+limit, is both not necessary and bug prone (due to reentrancy when pruning causes flushing causes
+more allocations).
+
+This implementation has the following limitations:
+
+* If the overload manager is built, it only tracks memory allocated with C++ new.  Specifically,
+  direct calls to malloc or calloc which may be made by libraries are not tracked.
+
+* Packet thread tracking does not include heap overhead, which can be substantial.
+
+* Non-packet threads are assumed to have bounded memory usage, eg via a cache.
+
+* Heap managers tend to acquire memory from the system quickly and release back much more slowly,
+  if ever. It is also relatively expensive to force a release.
+
+* Therefore, pruning a single flow almost certainly won't release memory back to the system.
+
+For these reasons, the goal of the memory manager is to prevent allocation past the limit rather
+than try to reclaim memory allocated past the limit. This means that the configured limit must be
+well enough below the actual hard limit, for example the limit enforced by cgroups, such that the
+processing of a single packet will not push us over. It must also allow for additional heap
+overhead.
+
+Future work:
+
+* Support simplified configuration of a process cap instead of a thread cap.  Implement a MemoryCap
+  method that can be called to inform the memory module of various cache related memcaps.  Deduct
+  the startup ru_maxrss and the sum of memcaps from the configured process cap and then divide by
+  --max-packet-threads to get the effective thread cap.
+
+* Compensate for heap fragmentation and other overhead by using the current process footprint
+  (process_total below) as feedback to adjust the current packet thread limits:
+
+  thread_limit = [(cap - (process_total - sum_thread_usage)) / num_threads] * threshold
+
+* Recognize when a memory leak drives excessive pruning.
 
-- possibly add eventing
diff --git a/src/memory/memory_allocator.cc b/src/memory/memory_allocator.cc
new file mode 100644 (file)
index 0000000..5029620
--- /dev/null
@@ -0,0 +1,39 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2021 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// memory_allocator.cc author Joel Cornett <jocornet@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "memory_allocator.h"
+
+#include <cstdlib>
+
+namespace memory
+{
+
+// FIXIT-L (de)allocate() could be inlined if defined in memory_manager.cc
+void* MemoryAllocator::allocate(size_t n)
+{ return malloc(n); }
+
+void MemoryAllocator::deallocate(void* p)
+{ free(p); }
+
+} // namespace memory
diff --git a/src/memory/memory_allocator.h b/src/memory/memory_allocator.h
new file mode 100644 (file)
index 0000000..10c4a85
--- /dev/null
@@ -0,0 +1,37 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2021 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// memory_allocator.h author Joel Cornett <jocornet@cisco.com>
+
+#ifndef MEMORY_ALLOCATOR_H
+#define MEMORY_ALLOCATOR_H
+
+#include <cstddef>
+
+namespace memory
+{
+
+struct MemoryAllocator
+{
+    static void* allocate(size_t);
+    static void deallocate(void*);
+};
+
+} // namespace memory
+
+#endif
index 63b43a44764561c642e88a63b78fbdb835aea899..684f90a05ee29ac3b9f6a8775cfe4cbb05838155 100644 (file)
 #include "config.h"
 #endif
 
+#include <malloc.h>
+#include <sys/resource.h>
+
 #include <cassert>
+#include <vector>
+
+#ifdef HAVE_JEMALLOC
+#include <jemalloc/jemalloc.h>
+#endif
 
 #include "memory_cap.h"
 
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "main/snort_types.h"
+#include "main/thread.h"
 #include "profiler/memory_profiler_active_context.h"
 #include "utils/stats.h"
 
 #include "memory_module.h"
 #include "prune_handler.h"
 
-#ifdef UNIT_TEST
-#include "catch/snort_catch.h"
-#endif
-
 using namespace snort;
 
 namespace memory
 {
 
+static MemoryCounts ctl_mem_stats;
+static std::vector<MemoryCounts> pkt_mem_stats;
+
 namespace
 {
 
-struct Tracker
+// -----------------------------------------------------------------------------
+// helpers
+// -----------------------------------------------------------------------------
+
+#ifdef HAVE_JEMALLOC
+static size_t get_usage(MemoryCounts& mc)
 {
-    void allocate(size_t n)
-    { mem_stats.allocated += n; ++mem_stats.allocations; }
+    static THREAD_LOCAL uint64_t* alloc_ptr = nullptr, * dealloc_ptr = nullptr;
 
-    void deallocate(size_t n)
+    if ( !alloc_ptr )
     {
-        mem_stats.deallocated += n; ++mem_stats.deallocations;
-        assert(mem_stats.deallocated <= mem_stats.allocated);
-        assert(mem_stats.deallocations <= mem_stats.allocations);
-        assert(mem_stats.allocated or !mem_stats.allocations);
+        size_t sz = sizeof(alloc_ptr);
+        // __STRDUMP_DISABLE__
+        mallctl("thread.allocatedp", (void*)&alloc_ptr, &sz, nullptr, 0);
+        mallctl("thread.deallocatedp", (void*)&dealloc_ptr, &sz, nullptr, 0);
+        // __STRDUMP_ENABLE__
     }
+    mc.allocated = *alloc_ptr;
+    mc.deallocated = *dealloc_ptr;
 
-    size_t used() const
+    if ( mc.allocated > mc.deallocated )
     {
-        if ( mem_stats.allocated < mem_stats.deallocated )
-        {
-            assert(false);
-            return 0;
-        }
-        return mem_stats.allocated - mem_stats.deallocated;
-    }
-};
+        size_t usage =  mc.allocated - mc.deallocated;
 
-static Tracker s_tracker;
+        if ( usage > mc.max_in_use )
+            mc.max_in_use = usage;
 
-// -----------------------------------------------------------------------------
-// helpers
-// -----------------------------------------------------------------------------
+        return usage;
+    }
+    return 0;
+}
+#else
+static size_t get_usage(const MemoryCounts& mc)
+{
+#ifdef ENABLE_MEMORY_OVERLOADS
+    assert(mc.allocated >= mc.deallocated);
+    return mc.allocated - mc.deallocated;
 
-template<typename Tracker, typename Handler>
-inline bool free_space(size_t requested, size_t cap, Tracker& trk, Handler& handler)
+#else
+    UNUSED(mc);
+    return 0;
+#endif
+}
+#endif
+
+template<typename Handler>
+inline void free_space(size_t cap, Handler& handler)
 {
-    if ( requested > cap )
-    {
-        return false;
-    }
+    MemoryCounts& mc = memory::MemoryCap::get_mem_stats();
+    size_t usage = get_usage(mc);
 
-    auto used = trk.used();
+    if ( usage < cap )
+        return;
 
-    if ( used + requested <= cap )
-        return true;
+    ++mc.reap_attempts;
 
-    ++mem_stats.reap_attempts;
+    if ( handler() )
+        return;
 
-    while ( used + requested > cap )
-    {
-        handler();
-        auto tmp = trk.used();
-
-        if ( tmp >= used )
-        {
-            ++mem_stats.reap_failures;
-            return false;
-        }
-        used = tmp;
-    }
-    return true;
+    ++mc.reap_failures;
 }
 
 inline size_t calculate_threshold(size_t cap, size_t threshold)
@@ -117,190 +127,111 @@ inline size_t calculate_threshold(size_t cap, size_t threshold)
 // per-thread configuration
 // -----------------------------------------------------------------------------
 
-size_t MemoryCap::thread_cap = 0;
-size_t MemoryCap::preemptive_threshold = 0;
+size_t MemoryCap::limit = 0;
 
 // -----------------------------------------------------------------------------
 // public interface
 // -----------------------------------------------------------------------------
 
-void MemoryCap::free_space(size_t n)
+void MemoryCap::setup(const MemoryConfig& config, unsigned n)
 {
-    if ( !is_packet_thread() )
-        return;
-
-    if ( !thread_cap )
-        return;
-
-    static THREAD_LOCAL bool entered = false;
-
-    if ( entered )
-        return;
-
-    entered = true;
-    memory::free_space(n, thread_cap, s_tracker, prune_handler);
-    entered = false;
+    assert(!is_packet_thread());
+    limit = memory::calculate_threshold(config.cap, config.threshold);
+    pkt_mem_stats.resize(n);
 }
 
-static size_t fudge_it(size_t n)
+void MemoryCap::cleanup()
 {
-    return ((n >> 7) + 1) << 7;
+    pkt_mem_stats.resize(0);
 }
 
-void MemoryCap::update_allocations(size_t n)
+MemoryCounts& MemoryCap::get_mem_stats()
 {
-    if (n == 0)
-        return;
-
-    size_t k = n;
-    n = fudge_it(n);
-    free_space(n);
-    mem_stats.total_fudge += (n - k);
-    s_tracker.allocate(n);
-    auto in_use = s_tracker.used();
-    if ( in_use > mem_stats.max_in_use )
-        mem_stats.max_in_use = in_use;
-    mp_active_context.update_allocs(n);
-}
-
-void MemoryCap::update_deallocations(size_t n)
-{
-    if (n == 0)
-      return;
+    if ( !is_packet_thread() )
+        return ctl_mem_stats;
 
-    n = fudge_it(n);
-    s_tracker.deallocate(n);
-    mp_active_context.update_deallocs(n);
+    auto id = get_instance_id();
+    return pkt_mem_stats[id];
 }
 
-bool MemoryCap::over_threshold()
+void MemoryCap::free_space()
 {
-    if ( !preemptive_threshold )
-        return false;
-
-    return s_tracker.used() >= preemptive_threshold;
-}
+    assert(is_packet_thread());
 
-// FIXIT-L this should not be called while the packet threads are running.
-// once reload is implemented for the memory manager, the configuration
-// model will need to be updated
-
-void MemoryCap::calculate()
-{
-    assert(!is_packet_thread());
-    const MemoryConfig& config = *SnortConfig::get_conf()->memory;
+    if ( !limit )
+        return;
 
-    thread_cap = config.cap;
-    preemptive_threshold = memory::calculate_threshold(thread_cap, config.threshold);
+    memory::free_space(limit, prune_handler);
 }
 
-void MemoryCap::print()
+#ifdef ENABLE_MEMORY_OVERLOADS
+void MemoryCap::allocate(size_t n)
 {
-    if ( !MemoryModule::is_active() )
-        return;
+    MemoryCounts& mc = memory::MemoryCap::get_mem_stats();
 
-    bool verbose = SnortConfig::log_verbose();
+    mc.allocated += n;
+    ++mc.allocations;
 
-    if ( verbose or mem_stats.allocations )
-        LogLabel("memory (heap)");
+    assert(mc.allocated >= mc.deallocated);
+    auto in_use = mc.allocated - mc.deallocated;
 
-    if ( verbose )
-    {
-        LogMessage("    thread cap: %zu\n", thread_cap);
-        LogMessage("    thread preemptive threshold: %zu\n", preemptive_threshold);
-    }
+    if ( in_use > mc.max_in_use )
+        mc.max_in_use = in_use;
 
-    if ( mem_stats.allocations )
-    {
-        LogMessage("    main thread usage: %zu\n", s_tracker.used());
-        LogMessage("    allocations: %" PRIu64 "\n", mem_stats.allocations);
-        LogMessage("    deallocations: %" PRIu64 "\n", mem_stats.deallocations);
-    }
+#ifdef ENABLE_MEMORY_PROFILER
+    mp_active_context.update_allocs(n);
+#endif
 }
 
-} // namespace memory
-
-#ifdef UNIT_TEST
-
-namespace t_memory_cap
+void MemoryCap::deallocate(size_t n)
 {
+    MemoryCounts& mc = memory::MemoryCap::get_mem_stats();
 
-struct MockTracker
-{
-    size_t result = 0;
-    size_t used() const
-    { return result; }
-
-    MockTracker(size_t r) : result { r } { }
-    MockTracker() = default;
-};
-
-struct HandlerSpy
-{
-    size_t calls = 0;
-    ssize_t modifier;
-    MockTracker* tracker;
-
-    void operator()()
+    // std::thread causes an extra deallocation in packet
+    // threads so the below asserts don't hold
+    if ( mc.allocated >= mc.deallocated + n )
     {
-        ++calls;
-        if ( modifier && tracker )
-            tracker->result += modifier;
+        mc.deallocated += n;
+        ++mc.deallocations;
     }
 
-    HandlerSpy(ssize_t n, MockTracker& trk) :
-        modifier(n), tracker(&trk) { }
-};
+#if 0
+    assert(mc.deallocated <= mc.allocated);
+    assert(mc.deallocations <= mc.allocations);
+    assert(mc.allocated or !mc.allocations);
+#endif
 
-} // namespace t_memory_cap
+#ifdef ENABLE_MEMORY_PROFILER
+    mp_active_context.update_deallocs(n);
+#endif
+}
+#endif
 
-TEST_CASE( "memory cap free space", "[memory]" )
+void MemoryCap::print(bool verbose, bool print_all)
 {
-    using namespace t_memory_cap;
-
-    SECTION( "no handler call required" )
-    {
-        MockTracker tracker;
-        HandlerSpy handler { 0, tracker };
-
-        CHECK( memory::free_space(1, 1024, tracker, handler) );
-        CHECK( handler.calls == 0 );
-    }
-
-    SECTION( "handler frees enough space the first time" )
-    {
-        MockTracker tracker { 1024 };
-        HandlerSpy handler { -5, tracker };
-
-        CHECK( memory::free_space(1, 1024, tracker, handler) );
-        CHECK( handler.calls == 1 );
-    }
+    if ( !MemoryModule::is_active() )
+        return;
 
-    SECTION( "handler needs to be called multiple times to free up space" )
-    {
-        MockTracker tracker { 1024 };
-        HandlerSpy handler { -1, tracker };
+    MemoryCounts& mc = get_mem_stats();
+    uint64_t usage = get_usage(mc);
 
-        CHECK( memory::free_space(2, 1024, tracker, handler) );
-        CHECK( (handler.calls == 2) );
-    }
+    if ( verbose or usage )
+        LogLabel("memory (heap)");
 
-    SECTION( "handler fails to free enough space" )
-    {
-        MockTracker tracker { 1024 };
-        HandlerSpy handler { 0, tracker };
+    if ( verbose and print_all )
+        LogCount("pruning threshold", limit);
 
-        CHECK_FALSE( memory::free_space(1, 1024, tracker, handler) );
-        CHECK( handler.calls == 1 );
-    }
+    LogCount("main thread usage", usage);
+    LogCount("allocations", mc.allocations);
+    LogCount("deallocations", mc.deallocations);
 
-    SECTION( "handler actually uses more space" )
+    if ( verbose )
     {
-        MockTracker tracker { 1024 };
-        HandlerSpy handler { 5, tracker };
-        CHECK_FALSE( memory::free_space(1, 1024, tracker, handler) );
-        CHECK( handler.calls == 1 );
+        struct rusage ru;
+        getrusage(RUSAGE_SELF, &ru);
+        LogCount("max_rss", ru.ru_maxrss * 1024);
     }
 }
 
-#endif
+} // namespace memory
+
index b28bb47e70fb6b17136ad14806769393a1e46473..1f7ece0932015ec51275940a848d3d6d494ea0ce 100644 (file)
 
 #include <cstddef>
 
-#include "main/thread.h"
+#include "framework/counts.h"
+#include "main/snort_types.h"
+
+struct MemoryConfig;
 
 namespace memory
 {
 
+struct MemoryCounts
+{
+    PegCount allocations;
+    PegCount deallocations;
+    PegCount allocated;
+    PegCount deallocated;
+    PegCount reap_attempts;
+    PegCount reap_failures;
+    PegCount max_in_use;
+};
+
 class SO_PUBLIC MemoryCap
 {
 public:
-    static void free_space(size_t);
-    // The following functions perform internal rounding. Allocations and deallocations must be
-    // performed in identical increments or leakage may occur.
-    static void update_allocations(size_t);
-    static void update_deallocations(size_t);
+    static void setup(const MemoryConfig&, unsigned);
+    static void cleanup();
 
-    static bool over_threshold();
+    static void free_space();
 
     // call from main thread
-    static void calculate();
+    static void print(bool verbose, bool print_all = true);
 
-    // call from main thread
-    static void print();
+    static MemoryCounts& get_mem_stats();
+
+#ifdef ENABLE_MEMORY_OVERLOADS
+    static void allocate(size_t);
+    static void deallocate(size_t);
+#endif
 
 private:
-    static size_t thread_cap;
-    static size_t preemptive_threshold;
+    static size_t limit;
 };
 
 } // namespace memory
diff --git a/src/memory/memory_manager.cc b/src/memory/memory_manager.cc
new file mode 100644 (file)
index 0000000..070c9fb
--- /dev/null
@@ -0,0 +1,414 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2021 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// memory_manager.cc author Joel Cornett <jocornet@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cassert>
+#include <new>
+
+#include "main/thread.h"
+
+#include "memory_allocator.h"
+#include "memory_cap.h"
+
+#ifdef UNIT_TEST
+#include "catch/snort_catch.h"
+#endif
+
+namespace memory
+{
+
+// -----------------------------------------------------------------------------
+// metadata
+// -----------------------------------------------------------------------------
+
+// This structure must be aligned to max_align_t as long as we are prefixing
+// it to memory allocations so that the returned memory is also aligned.
+struct alignas(max_align_t) Metadata
+{
+#if defined(REG_TEST) || defined(UNIT_TEST)
+    static constexpr size_t SANITY_CHECK_VALUE = 0xabcdef;
+    size_t sanity;
+#endif
+
+    // number of requested bytes
+    size_t payload_size;
+
+    // total number of bytes allocated, including Metadata header
+    size_t total_size() const;
+    void* payload_offset();
+
+#if defined(REG_TEST) || defined(UNIT_TEST)
+    bool valid() const
+    { return sanity == SANITY_CHECK_VALUE; }
+#endif
+
+    Metadata(size_t = 0);
+
+    static size_t calculate_total_size(size_t);
+
+    template<typename Allocator>
+    static Metadata* create(size_t);
+
+    static Metadata* extract(void*);
+};
+
+inline size_t Metadata::total_size() const
+{ return calculate_total_size(payload_size); }
+
+inline void* Metadata::payload_offset()
+{ return this + 1; }
+
+inline Metadata::Metadata(size_t n) :
+#if defined(REG_TEST) || defined(UNIT_TEST)
+    sanity(SANITY_CHECK_VALUE),
+#endif
+    payload_size(n)
+{ }
+
+inline size_t Metadata::calculate_total_size(size_t n)
+{ return sizeof(Metadata) + n; }
+
+template<typename Allocator>
+Metadata* Metadata::create(size_t n)
+{
+    auto meta =
+        static_cast<Metadata*>(Allocator::allocate(calculate_total_size(n)));
+
+    if ( !meta )
+        return nullptr;
+
+    // Trigger metadata ctor
+    *meta = Metadata(n);
+
+#if defined(REG_TEST) || defined(UNIT_TEST)
+    assert(meta->valid());
+#endif
+
+    return meta;
+}
+
+Metadata* Metadata::extract(void* p)
+{
+    assert(p);
+
+    auto meta = static_cast<Metadata*>(p) - 1;
+
+#if defined(REG_TEST) || defined(UNIT_TEST)
+    assert(meta->valid());
+#endif
+
+    return meta;
+}
+
+// -----------------------------------------------------------------------------
+// the meat
+// -----------------------------------------------------------------------------
+
+class ReentryContext
+{
+public:
+    ReentryContext(bool& flag) :
+        already_entered(flag), flag(flag)
+    { flag = true; }
+
+    ~ReentryContext()
+    { flag = false; }
+
+    bool is_reentry() const
+    { return already_entered; }
+
+private:
+    const bool already_entered;
+    bool& flag;
+};
+
+template<typename Allocator = MemoryAllocator, typename Cap = MemoryCap>
+struct Interface
+{
+    static void* allocate(size_t);
+    static void deallocate(void*);
+
+    static THREAD_LOCAL bool in_allocation_call;
+};
+
+template<typename Allocator, typename Cap>
+void* Interface<Allocator, Cap>::allocate(size_t n)
+{
+    // prevent allocation reentry
+    ReentryContext reentry_context(in_allocation_call);
+    assert(!reentry_context.is_reentry());
+
+    auto meta = Metadata::create<Allocator>(n);
+
+    if ( !meta )
+        return nullptr;
+
+    Cap::allocate(meta->total_size());
+    return meta->payload_offset();
+}
+
+template<typename Allocator, typename Cap>
+void Interface<Allocator, Cap>::deallocate(void* p)
+{
+    if ( !p )
+        return;
+
+    auto meta = Metadata::extract(p);
+    assert(meta);
+
+    Cap::deallocate(meta->total_size());
+    Allocator::deallocate(meta);
+}
+
+template<typename Allocator, typename Cap>
+THREAD_LOCAL bool Interface<Allocator, Cap>::in_allocation_call = false;
+
+} //namespace memory
+
+// -----------------------------------------------------------------------------
+// new /delete replacements
+// -----------------------------------------------------------------------------
+
+// these don't have to be visible to operate as replacements
+
+#ifdef ENABLE_MEMORY_OVERLOADS
+void* operator new(size_t n)
+{
+    auto p = memory::Interface<>::allocate(n);
+    if ( !p )
+        throw std::bad_alloc();
+
+    return p;
+}
+
+void* operator new[](size_t n)
+{ return ::operator new(n); }
+
+void* operator new(size_t n, const std::nothrow_t&) noexcept
+{ return memory::Interface<>::allocate(n); }
+
+void* operator new[](size_t n, const std::nothrow_t&) noexcept
+{ return memory::Interface<>::allocate(n); }
+
+void operator delete(void* p) noexcept
+{ memory::Interface<>::deallocate(p); }
+
+void operator delete[](void* p) noexcept
+{ ::operator delete(p); }
+
+void operator delete(void* p, const std::nothrow_t&) noexcept
+{ ::operator delete(p); }
+
+void operator delete[](void* p, const std::nothrow_t&) noexcept
+{ ::operator delete[](p); }
+
+void operator delete(void* p, size_t) noexcept
+{ ::operator delete(p); }
+
+void operator delete[](void* p, size_t) noexcept
+{ ::operator delete[](p); }
+#endif
+
+// -----------------------------------------------------------------------------
+// unit tests
+// -----------------------------------------------------------------------------
+
+#ifdef UNIT_TEST
+
+namespace t_memory
+{
+
+struct AllocatorSpy
+{
+    static void* allocate(size_t n)
+    { allocate_called = true; allocate_arg = n; return pool; }
+
+    static void deallocate(void* p)
+    { deallocate_called = true; deallocate_arg = p; }
+
+    static void reset()
+    {
+        pool = nullptr;
+        allocate_called = false;
+        allocate_arg = 0;
+        deallocate_called = false;
+        deallocate_arg = nullptr;
+    }
+
+    static void* pool;
+    static bool allocate_called;
+    static size_t allocate_arg;
+    static bool deallocate_called;
+    static void* deallocate_arg;
+};
+
+void* AllocatorSpy::pool = nullptr;
+bool AllocatorSpy::allocate_called = false;
+size_t AllocatorSpy::allocate_arg = 0;
+bool AllocatorSpy::deallocate_called = false;
+void* AllocatorSpy::deallocate_arg = nullptr;
+
+struct CapSpy
+{
+    static void allocate(size_t n)
+    {
+        update_allocations_called = true;
+        update_allocations_arg = n;
+    }
+
+    static void deallocate(size_t n)
+    {
+        update_deallocations_called = true;
+        update_deallocations_arg = n;
+    }
+
+    static void reset()
+    {
+        update_allocations_called = false;
+        update_allocations_arg = 0;
+
+        update_deallocations_called = false;
+        update_deallocations_arg = 0;
+    }
+
+    static bool update_allocations_called;
+    static size_t update_allocations_arg;
+
+    static bool update_deallocations_called;
+    static size_t update_deallocations_arg;
+};
+
+bool CapSpy::update_allocations_called = false;
+size_t CapSpy::update_allocations_arg = 0;
+
+bool CapSpy::update_deallocations_called = false;
+size_t CapSpy::update_deallocations_arg = 0;
+
+} // namespace t_memory
+
+TEST_CASE( "memory metadata", "[memory]" )
+{
+    using namespace t_memory;
+
+    AllocatorSpy::reset();
+    constexpr size_t n = 1;
+    char pool[sizeof(memory::Metadata) + n];
+
+    SECTION( "create" )
+    {
+        AllocatorSpy::pool = pool;
+
+        auto meta = memory::Metadata::create<AllocatorSpy>(n);
+
+        CHECK( (void*)meta == (void*)pool );
+        CHECK( meta->valid() );
+        CHECK( meta->payload_size == n );
+    }
+
+    SECTION( "extract" )
+    {
+        auto meta_pool = reinterpret_cast<memory::Metadata*>(pool);
+        meta_pool[0] = memory::Metadata(n);
+
+        void* p = &meta_pool[1];
+
+        auto meta = memory::Metadata::extract(p);
+
+        CHECK( (void*)meta == (void*)pool );
+        CHECK( meta->payload_offset() == p );
+    }
+}
+
+TEST_CASE( "memory manager interface", "[memory]" )
+{
+    using namespace t_memory;
+
+    AllocatorSpy::reset();
+    CapSpy::reset();
+
+    constexpr size_t n = 1;
+    char pool[sizeof(memory::Metadata) + n];
+
+    using Interface = memory::Interface<AllocatorSpy, CapSpy>;
+
+    SECTION( "allocation" )
+    {
+        SECTION( "allocation failure" )
+        {
+            auto p = Interface::allocate(n);
+
+            CHECK( p == nullptr );
+
+            CHECK( AllocatorSpy::allocate_called );
+            CHECK( AllocatorSpy::allocate_arg == memory::Metadata::calculate_total_size(n) );
+
+            CHECK_FALSE( CapSpy::update_allocations_called );
+        }
+
+        SECTION( "success" )
+        {
+            AllocatorSpy::pool = pool;
+
+            auto p = Interface::allocate(n);
+
+            CHECK( p > (void*)pool );
+
+            CHECK( AllocatorSpy::allocate_called );
+            CHECK( AllocatorSpy::allocate_arg == memory::Metadata::calculate_total_size(n) );
+
+            CHECK( CapSpy::update_allocations_called );
+            CHECK( CapSpy::update_allocations_arg == memory::Metadata::calculate_total_size(n) );
+        }
+    }
+
+    SECTION( "deallocation" )
+    {
+        SECTION( "nullptr" )
+        {
+            Interface::deallocate(nullptr);
+
+            CHECK_FALSE( AllocatorSpy::deallocate_called );
+            CHECK_FALSE( CapSpy::update_deallocations_called );
+        }
+
+        SECTION( "success" )
+        {
+            auto meta_pool = reinterpret_cast<memory::Metadata*>(pool);
+            meta_pool[0] = memory::Metadata(n);
+
+            auto p = meta_pool[0].payload_offset();
+
+            Interface::deallocate(p);
+
+            CHECK( AllocatorSpy::deallocate_called );
+            CHECK( AllocatorSpy::deallocate_arg == (void*)pool );
+            CHECK( CapSpy::update_deallocations_called );
+            CHECK( CapSpy::update_deallocations_arg == memory::Metadata::calculate_total_size(n) );
+        }
+    }
+    AllocatorSpy::pool = nullptr;
+    AllocatorSpy::deallocate_arg = nullptr;
+}
+
+#endif
+
index b1a3da9c734f3deea2c58406d8893885a88d753a..31152168a6162d232c0980c015a727ea491e7da0 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "main/snort_config.h"
 
+#include "memory_cap.h"
 #include "memory_config.h"
 
 using namespace snort;
@@ -43,15 +44,13 @@ static const Parameter s_params[] =
     { "cap", Parameter::PT_INT, "0:maxSZ", "0",
         "set the per-packet-thread cap on memory (bytes, 0 to disable)" },
 
-    { "threshold", Parameter::PT_INT, "0:100", "0",
-        "set the per-packet-thread threshold for preemptive cleanup actions "
-        "(percent, 0 to disable)" },
+    { "threshold", Parameter::PT_INT, "1:100", "100",
+        "scale cap to account for heap overhead" },
 
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
-THREAD_LOCAL MemoryCounts mem_stats;
-static MemoryCounts zero_stats = { };
+static memory::MemoryCounts zero_stats = { };
 
 const PegInfo mem_pegs[] =
 {
@@ -62,7 +61,6 @@ const PegInfo mem_pegs[] =
     { CountType::NOW, "reap_attempts", "attempts to reclaim memory" },
     { CountType::NOW, "reap_failures", "failures to reclaim memory" },
     { CountType::MAX, "max_in_use", "highest allocated - deallocated" },
-    { CountType::NOW, "total_fudge", "sum of all adjustments" },
     { CountType::END, nullptr, nullptr }
 };
 
@@ -100,5 +98,10 @@ const PegInfo* MemoryModule::get_pegs() const
 { return mem_pegs; }
 
 PegCount* MemoryModule::get_counts() const
-{ return is_active() ? (PegCount*)&mem_stats : (PegCount*)&zero_stats; }
+{
+    if ( !is_active() )
+        return (PegCount*)&zero_stats;
+
+    return (PegCount*)&memory::MemoryCap::get_mem_stats();
+}
 
index 4563e9c5381e9a97d0e0fde734b68c91caca4ea2..456f23241e4e8376adc4369ff53a9960978ccd49 100644 (file)
 
 #include "framework/module.h"
 
-struct MemoryCounts
-{
-    PegCount allocations;
-    PegCount deallocations;
-    PegCount allocated;
-    PegCount deallocated;
-    PegCount reap_attempts;
-    PegCount reap_failures;
-    PegCount max_in_use;
-    PegCount total_fudge;
-};
-
-extern THREAD_LOCAL MemoryCounts mem_stats;
-
 class MemoryModule : public snort::Module
 {
 public:
index 61a8ad78f70f717f246ce9d6df3e3e2d7eec7282..c8b949a8786f2e8fc3bcae111d8904a7f54ae648 100644 (file)
@@ -31,9 +31,9 @@ using namespace snort;
 namespace memory
 {
 
-void prune_handler()
+bool prune_handler()
 {
-    Stream::prune_flows();
+    return Stream::prune_flows();
 }
 
 } // namespace memory
index 6e1b418ac93e09b2d5990ba2a84698131adfbee1..2bde83b3c8caa31957e5f966621d2dbe3e4d0303 100644 (file)
@@ -24,7 +24,7 @@
 namespace memory
 {
 
-void prune_handler();
+bool prune_handler();
 
 }
 
index 019a36ff838fa0a2ff7613fe22e7fc571882a4b1..f514a47768e6f3a5133124922e67a9303e9bbcae 100644 (file)
@@ -68,8 +68,6 @@ public:
     bool is_email_hdrs_present() const;
     bool is_email_from_present() const;
     bool is_email_to_present() const;
-    size_t size_of() const override
-    { return sizeof(*this); }
 
 private:
     int log_flags = 0;
index a2cd6df19f415ddbb8944547355ad06af0553ad2..5db1b712058f8109d6a5b6103d1fa1fff68288ab 100644 (file)
@@ -815,12 +815,10 @@ MimeSession::MimeSession(Packet* p, DecodeConfig* dconf, MailLogConfig* lconf, u
 {
     p->flow->stash->store(STASH_EXTRADATA_MIME, log_state);
     reset_mime_paf_state(&mime_boundary);
-    memory::MemoryCap::update_allocations(sizeof(*this));
 }
 
 MimeSession::~MimeSession()
 {
-    memory::MemoryCap::update_deallocations(sizeof(*this));
     if ( decode_state )
         delete(decode_state);
 }
index fdb5ab51e6db4a6bfb86b1b7491f4fdd6db4c6af..110e99a3df015b6d8a07840b41d12338e126923a 100644 (file)
@@ -601,7 +601,6 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
         if (asd.tpsession and asd.tpsession->get_ctxt_version() != tp_appid_ctxt->get_version())
         {
             bool is_tp_done = asd.is_tp_processing_done();
-            memory::MemoryCap::update_deallocations(asd.tpsession->size_of());
             delete asd.tpsession;
             asd.tpsession = nullptr;
             if (!is_tp_done)
index 5b71f300a47d4c0b46edaf9b1b6a9be054ee856b..512b38bcfd287e0b55472f33e748e161df479ed6 100644 (file)
 class AppIdDnsSession
 {
 public:
-    AppIdDnsSession()
-    {
-        memory::MemoryCap::update_allocations(sizeof(*this));
-    }
-
-    ~AppIdDnsSession()
-    {
-        memory::MemoryCap::update_deallocations(sizeof(*this));
-    }
+    AppIdDnsSession() { }
+    ~AppIdDnsSession() { }
 
     void reset()
     {
index dcf69d7501e2a1ea70600a616139f253cb359920..9f2fbd14da89a0215c80b9e401a8df4ea8141b64 100644 (file)
@@ -113,7 +113,6 @@ bool AppIdHAAppsClient::consume(Flow*& flow, const FlowKey* key, HAMessage& msg,
                 ErrorMessage("appid: Could not allocate asd.tpsession data in consume");
             else
             {
-                memory::MemoryCap::update_allocations(asd->tpsession->size_of());
                 asd->tpsession->set_state(TP_STATE_HA);
             }
         }
index 92a4083e9ad85f9f08cda5317b146d0b9576441b..dcbc15576652f286a25faf65e89f5ab95cc1e253 100644 (file)
@@ -41,9 +41,7 @@ using namespace snort;
 
 AppIdHttpSession::AppIdHttpSession(AppIdSession& asd, uint32_t http2_stream_id)
     : asd(asd), http2_stream_id(http2_stream_id)
-{
-    memory::MemoryCap::update_allocations(sizeof(AppIdHttpSession));
-}
+{ }
 
 AppIdHttpSession::~AppIdHttpSession()
 {
@@ -51,7 +49,6 @@ AppIdHttpSession::~AppIdHttpSession()
         delete meta_data[i];
     if (tun_dest)
         delete tun_dest;
-    memory::MemoryCap::update_deallocations(sizeof(AppIdHttpSession));
 }
 
 void AppIdHttpSession::free_chp_matches(ChpMatchDescriptor& cmd, unsigned num_matches)
index 904b9ee4573024122a0f31e3287aa2fb4e0d39ac..fb3e752ce83a1e3aa6f25411ff0c2cf3c0e823ff 100644 (file)
@@ -165,7 +165,6 @@ AppIdSession::~AppIdSession()
 
     if (tpsession)
     {
-        memory::MemoryCap::update_deallocations(tpsession->size_of());
         if (pkt_thread_tp_appid_ctxt and
             ((tpsession->get_ctxt_version() == pkt_thread_tp_appid_ctxt->get_version()) and
             !ThirdPartyAppIdContext::get_tp_reload_in_progress()))
index eca17b2b3cd23f2df0912076413cffe3da87ac84..a0494e8fcf53ec1f53465e3cc9eb4e853730103b 100644 (file)
@@ -106,13 +106,10 @@ class TlsSession
 {
 public:
     TlsSession()
-    {
-        memory::MemoryCap::update_allocations(sizeof(*this));
-    }
+    { }
 
     ~TlsSession()
     {
-        memory::MemoryCap::update_deallocations(sizeof(*this));
         if (tls_host)
             snort_free(tls_host);
         if (tls_first_alt_name)
@@ -239,9 +236,6 @@ public:
         bool bidirectional=false);
     void initialize_future_session(AppIdSession&, uint64_t);
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
     snort::Flow* flow = nullptr;
     AppIdConfig& config;
     std::unordered_map<unsigned, AppIdFlowData*> flow_data;
index 159d3dbaa7fdff3b12fbf361adf11f43effa1574..c5a96cdf1085b0b46f09542beb499de0ef630c7b 100644 (file)
@@ -153,9 +153,6 @@ public:
 
     void clear_user_logged_in() { user_logged_in = false; }
 
-    size_t size_of() const override
-    { return sizeof(*this); }
-
 protected:
     AppIdSessionApi(const AppIdSession* asd, const SfIp& ip);
 
index 77cafe1c63df366764c237fda3053df95346e5c0..fe73596935126a3ae0faf62c7e03ab560c44c031 100644 (file)
@@ -168,7 +168,6 @@ void AppIdDetector::add_user(AppIdSession&, char const*, int, bool, AppidChangeB
 void AppIdDetector::add_payload(AppIdSession&, int) { }
 void AppIdDetector::add_app(snort::Packet const&, AppIdSession&, AppidSessionDirection, int,
     int, char const*, AppidChangeBits&) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
 // LCOV_EXCL_STOP
 
 SipEvent::SipEvent(snort::Packet const* p, SIPMsg const*, SIP_DialogData const*) { this->p = p; }
index cc18cbdc6c6ed0060207d78959dc2774ca087538..ac3cfce5d858f8a47952cdbad0d062d67a0ec784 100644 (file)
@@ -56,9 +56,6 @@ static AppId service_id = APP_ID_NONE;
 static AppId client_id = APP_ID_NONE;
 static DetectorHTTPPattern mpattern;
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 namespace snort
 {
 AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
index 89e6a2d968feba3ef6f134f2367df0d2e2f65887..7b64cca790fdd83dcf20522f7402b1e5dd36e247 100644 (file)
@@ -14,7 +14,7 @@ provide the logic to plug this inspector into the snort framework.  AppIdModule
 configuration for AppId and AppIdInspector provides the packet processing context.  An AppId
 inspector is instantiated for each packet thread created by the framework.
 
-AppId registers to recieve any IP packet, it does not process rebuilt packets.
+AppId registers to receive any IP packet, it does not process rebuilt packets.
 
 AppIdModule contains all the logic to process the AppId inspector Lua configuration which is identified
 by the 'appid' keyword.  This configuration includes settings for logging, statistics, etc. and also
index f16d04b2e1fd62d9b0e6a0fa55b9b36500f45486..fb610d982bb9e46407b664a495b130509981e52a 100644 (file)
@@ -48,9 +48,6 @@ using namespace snort;
 
 static SnortProtocolId dummy_http2_protocol_id = 1;
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 namespace snort
 {
 
index c5024f00b6e749e36000b321cd3a18fa9ff23129..cef3da949c8b42055073d8df79c4ec9ddb5af6db 100644 (file)
@@ -37,9 +37,6 @@
 
 // Mocks
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 namespace snort
 {
 unsigned get_instance_id() { return 3; }
index 85aaffffafe22b7b2b272f1f13d6a1697fe2aae7..9a9edfe7d4893169c9f6186f7e15cdcd7206db18 100644 (file)
@@ -36,9 +36,6 @@
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 namespace snort
 {
 AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
index 3cc3eb3cf48385793c37a21339da2fd103f022c7..a5ce3b4320b504cdfbc9b71e5a547c3b258ab691 100644 (file)
@@ -43,9 +43,6 @@
 
 uint32_t ThirdPartyAppIdContext::next_version = 0;
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 namespace snort
 {
 // Stubs for appid api
index 6cb7db5dc4a945735177684e2cdc84dff220d825..63ed44503b395bd5fe10895a8343c77d38997faf 100644 (file)
@@ -54,9 +54,6 @@ Packet::Packet(bool) { }
 Packet::~Packet() = default;
 }
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection,
     AppId, AppidChangeBits&) { }
 void AppIdModule::reset_stats() { }
index cdb1de7405f880f1d3e1a45a753b66f5291d87b3..220c75fe9e331e853e4c7ede2a70fbc4a3697d46 100644 (file)
@@ -49,9 +49,6 @@ void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDir
 
 using namespace snort;
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 namespace snort
 {
 AppIdApi appid_api;
index 0be59c7c80929cc425af9d79cb22d8ea11735cfb..525b0817026e55db26d35dcbd2520975fa1036e9 100644 (file)
@@ -165,9 +165,6 @@ void Profiler::consolidate_stats() { }
 void Profiler::reset_stats() { }
 void Profiler::show_stats() { }
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { }
 
 AppIdConfig::~AppIdConfig() = default;
index b0053459546b5fa0799e61de960c681a8b886b76..a82f9634688439b8290fbf204f6383203ceb48ca 100644 (file)
@@ -36,9 +36,6 @@ static AppIdConfig config;
 static OdpContext odpctxt(config, nullptr);
 static Flow flow;
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
 void AppIdModule::reset_stats() {}
 
index e1d9ce23af2be9d4bbbfdb5340969ca47e5d492a..eb0ffcf63567e06250145a1ff386fd04769d6aa5 100644 (file)
@@ -28,9 +28,6 @@
 
 #include <vector>
 
-void memory::MemoryCap::update_allocations(size_t) { }
-void memory::MemoryCap::update_deallocations(size_t) { }
-
 namespace snort
 {
 // Stubs for logs
index 4427d362d17c1d7ff63127e10e818c8a2caae343..29db0b6920bced1df6af5126efa28ea3c5064a74 100644 (file)
@@ -80,7 +80,6 @@ public:
     void clear_attr(TPSessionAttr attr) override { flags &= ~attr; }
     void set_attr(TPSessionAttr attr) override { flags |= attr; }
     unsigned get_attr(TPSessionAttr attr) override { return flags & attr; }
-    size_t size_of() const override { return sizeof(*this); }
 
 private:
     unsigned flags = 0;
index f7a3c944384b6699cdfce1486b835f85106a2b43..1c12e5b457b591b4eed15e1fbc655d24b2037138 100644 (file)
@@ -58,7 +58,6 @@ public:
     virtual void clear_attr(TPSessionAttr) = 0;
     virtual void set_attr(TPSessionAttr) = 0;
     virtual unsigned get_attr(TPSessionAttr) = 0;
-    virtual size_t size_of() const = 0;
     virtual AppId get_appid(int& conf) { conf=confidence; return appid; }
     virtual const ThirdPartyAppIdContext& get_ctxt() const
     { return ctxt; }
index 3b3158ea3f3b1592f92621c79caabf3f58f36e0e..debf211ff5ce1175838e5f34b549b23ee4db691b 100644 (file)
@@ -556,7 +556,6 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I
             ErrorMessage("Could not allocate asd.tpsession data");
             return false;
         }
-        memory::MemoryCap::update_allocations(asd.tpsession->size_of());
     }
 
     int tp_confidence;
index 17f31481d9b8d8cbc36c2a25d03df9d0d42742d4..e53deb98ef610a7d1b345486e0be78c172b1f284 100644 (file)
@@ -3,7 +3,7 @@ protocol violations.  This network inspector looks at all ARP ethernet
 frames and attempts to locate ARP spoofing attacks.
 
 It alerts on source or destination address mismatch.  It also alerts on an
-ARP request ocuring on a uni-cast frame (needs to be multi-cast).
+ARP request occurring on a uni-cast frame (needs to be multi-cast).
 
 A network inspector module as it needs to examine all ethernet frames with
 packet type of ARP.
index f3286daa750a13068745a847e23823b6896c50f0..4c685c58baef15a35f701c037cc5aa0626851dd7 100644 (file)
@@ -76,7 +76,7 @@ static const Parameter s_params[] =
     { "packets", Parameter::PT_INT, "0:max32", "10000",
       "minimum packets to report" },
 
-    { "seconds", Parameter::PT_INT, "1:max32", "60",
+    { "seconds", Parameter::PT_INT, "0:max32", "60",
       "report interval" },
 
     { "flow_ip_memcap", Parameter::PT_INT, "236:maxSZ", "52428800",
@@ -274,8 +274,6 @@ bool PerfMonModule::set(const char*, Value& v, SnortConfig*)
     else if ( v.is("seconds") )
     {
         config->sample_interval = v.get_uint32();
-        if ( config->sample_interval == 0 )
-            config->perf_flags |= PERF_SUMMARY;
     }
     else if ( v.is("flow_ip_memcap") )
     {
index de7c2cbe2a08f999010b350ab3eaf4fc63886bf8..7a58d64c162624e82e3909f2f7b553283f96abad 100644 (file)
@@ -179,12 +179,12 @@ mss:   maximum segment size
                       FpElementType::SYN_MATCH, FpElementType::SYNTS
 
        Examples:
-       fptype = 2, mss = "12-34" -- client traffic (fptype = 2) with mss beween 12 and 34
+       fptype = 2, mss = "12-34" -- client traffic (fptype = 2) with mss between 12 and 34
        fptype = 2, mss = "X"     -- don't use mss for matching, so match anything from cient
        fptype = 2, mss = "SYN"   -- error: client traffic (fptype = 2) but mss of type SYN_MATCH
                                     only accepted for server traffic (fptyp1 = 1 or 10)
        fptype = 1, mss = "TS"    -- OK: server traffic (fptype = 1) and mss of type SYNTS
-       mss = "+5"                -- eror: mss cannot be an INCREMENT type
+       mss = "+5"                -- error: mss cannot be an INCREMENT type
 
 id:    ip id
        FpElementType::RANGE
@@ -199,7 +199,7 @@ topts: tcp options
        FpElementType::RANGE
 
        These are defined by TcpOptCode in src/protocols/tcp_options.h.
-       The ones we use for fingerprint matcing are
+       The ones we use for fingerprint matching are
 
        - MAXSEG (2)
        - WSCALE (3)
index b0e4a636b43f1f8af0d338828ab5f64d467c180b..49d7fa0fa708196c179a11b890a51fd1c99916de 100644 (file)
@@ -454,11 +454,6 @@ void RNAFlow::init()
     inspector_id = snort::FlowData::create_flow_data_id();
 }
 
-size_t RNAFlow::size_of()
-{
-    return sizeof(*this);
-}
-
 bool FpFingerprintState::set(const Packet* p)
 {
     int pos = 0;
index 8af1e8d8a0803afe80f9d0d51716fdbd1cc91801..7c7d3b1194551bdd5c6c7417f849f0d70ffbc455 100644 (file)
@@ -48,7 +48,6 @@ public:
     ~RNAFlow() override;
 
     static void init();
-    size_t size_of() override;
 
     void clear_ht(snort::HostTracker& ht);
 
index 626ccf6449ee36fce06d2c4750524d85edc2a50b..4e60e1ceec9c2a8fc1953d586081a0906df68f67 100644 (file)
@@ -132,8 +132,6 @@ InjectionReturnStatus PayloadInjector::get_http2_payload(InjectionControl,
 
 unsigned Http2FlowData::inspector_id = 0;
 Http2Stream::~Http2Stream() = default;
-HpackDynamicTable::HpackDynamicTable(Http2FlowData* flow_data) :
-    session_data(flow_data) {}
 HpackDynamicTable::~HpackDynamicTable() = default;
 Http2DataCutter::Http2DataCutter(Http2FlowData* _session_data, HttpCommon::SourceId src_id) :
     session_data(_session_data), source_id(src_id) { }
@@ -149,7 +147,6 @@ Http2FlowData::Http2FlowData(snort::Flow*) :
     data_cutter {Http2DataCutter(this, SRC_CLIENT), Http2DataCutter(this, SRC_SERVER)}
 { }
 Http2FlowData::~Http2FlowData() = default;
-size_t Http2FlowData::size_of() { return 1; }
 Http2FlowData http2_flow_data(nullptr);
 void Http2FlowData::set_mid_frame(bool val) { continuation_expected[SRC_SERVER] = val; }
 bool Http2FlowData::is_mid_frame() const { return continuation_expected[SRC_SERVER]; }
index 0d9034b79af70e43f5ee0b631ae19b6a24d5cc60..ef45b555b76fb5edc4801f10897c972e9ad9a98f 100644 (file)
@@ -46,13 +46,13 @@ namespace memory_stats
 static const StatsTable::Field fields[] =
 {
     { "#", 5, ' ', 0, std::ios_base::left },
-    { "module", 20, ' ', 0, std::ios_base::fmtflags() },
+    { "module", 24, ' ', 0, std::ios_base::fmtflags() },
     { "layer", 6, ' ', 0, std::ios_base::fmtflags() },
-    { "allocs", 9, ' ', 0, std::ios_base::fmtflags() },
-    { "used (kb)", 12, ' ', 2, std::ios_base::fmtflags() },
-    { "avg/allocation", 15, ' ', 1, std::ios_base::fmtflags() },
+    { "allocs", 12, ' ', 0, std::ios_base::fmtflags() },
+    { "used (kb)", 15, ' ', 2, std::ios_base::fmtflags() },
+    { "avg/alloc", 12, ' ', 1, std::ios_base::fmtflags() },
     { "%/caller", 10, ' ', 2, std::ios_base::fmtflags() },
-    { "%/total", 9, ' ', 2, std::ios_base::fmtflags() },
+    { "%/total", 10, ' ', 2, std::ios_base::fmtflags() },
     { nullptr, 0, '\0', 0, std::ios_base::fmtflags() }
 };
 
index 792f113657cc2f83151aecd34a51217352338eef..6cc8edd39b57c42b8d7dc26ec0bb478879b3ec40 100644 (file)
@@ -120,7 +120,9 @@ void Profiler::show_stats()
     assert(config);
 
     show_time_profiler_stats(s_profiler_nodes, config->time);
+#ifdef ENABLE_MEMORY_PROFILER
     show_memory_profiler_stats(s_profiler_nodes, config->memory);
+#endif
     show_rule_profiler_stats(config->rule);
 }
 
index 6871894fd7929300e9b2ea0d97d4f753edb225b0..f5318ce09ee206b625f5307a99d0dae9eaa4f8b3 100644 (file)
@@ -120,16 +120,18 @@ public:
 #ifdef NO_PROFILER
 using Profile = ProfileDisabled;
 #else
-#ifdef NO_MEM_MGR
+#ifndef ENABLE_MEMORY_PROFILER
 using Profile = NoMemContext;
 #else
 using Profile = ProfileContext;
 #endif
 #endif
 
-// developer enable for profiling rule options
-//using RuleProfile = ProfileContext;
+#ifndef ENABLE_RULE_PROFILER
 using RuleProfile = ProfileDisabled;
+#else
+using RuleProfile = ProfileContext;
+#endif
 
 }
 #endif
index 514b8163dedfeb52e1c6b9a864b37e1fc387789e..5c87741d7ca315a00d9a54f02c4638cb871d7663 100644 (file)
@@ -90,9 +90,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     CipSessionData session;
index c314b674c0a4660a41bff3ac6c4e36e07ddd20d0..d27915e687474b5ea5aaf753931554eb24e392ae 100644 (file)
@@ -6,7 +6,7 @@ access certain protocol fields. This allows a user to write rules for CIP
 packets without decoding the protocol with a series of ”content” and ”byte 
 test” options.
 
-The preprocessor only evaluates PAF-flushed PDUs. If the rule options don't
+The inspector only evaluates PAF-flushed PDUs. If the rule options don't
 check for this, they'll fire on stale session data when the original packet
 goes through before flushing.
 
index 1265cf8f82622c8adf0879b2c7ecb3b56426a628..623405f95dc52715644148e3f5bb1f70ff567141 100644 (file)
@@ -314,13 +314,11 @@ Dce2Smb1SessionData::Dce2Smb1SessionData(const Packet* p,
     ssd.sd = sd;
     ssd.policy = policy;
     SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, p, "smb1 session created\n");
-    memory::MemoryCap::update_allocations(sizeof(*this));
 }
 
 Dce2Smb1SessionData::~Dce2Smb1SessionData()
 {
     DCE2_SmbDataFree(&ssd);
-    memory::MemoryCap::update_deallocations(sizeof(*this));
 }
 
 void Dce2Smb1SessionData::process()
index 05ae281c92267168cdc3cc1e4aac1cc422e9fb7d..3306bf8db4754244d4113afdfd097d0ce0fbc954 100644 (file)
@@ -106,7 +106,6 @@ Dce2Smb2SessionData::Dce2Smb2SessionData(const Packet* p,
     tcp_file_tracker = nullptr;
     flow_key = get_smb2_flow_key(tcp_flow->key);
     SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, p, "smb2 session created\n");
-    memory::MemoryCap::update_allocations(sizeof(*this));
 }
 
 Dce2Smb2SessionData::~Dce2Smb2SessionData()
@@ -117,7 +116,6 @@ Dce2Smb2SessionData::~Dce2Smb2SessionData()
         it_session.second->detach_flow(flow_key);
     }
     session_data_mutex.unlock();
-    memory::MemoryCap::update_deallocations(sizeof(*this));
 }
 
 void Dce2Smb2SessionData::reset_matching_tcp_file_tracker(
index f0a8bdb329c448220879becf48aca872f0b16a28..905c9df7808c564288eb0a04ae7f27508d714316 100644 (file)
@@ -283,9 +283,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
     Dce2SmbSessionData* get_smb_session_data()
     { return ssd; }
 
index 3c473547678699ec645ff0c1c0e02653fde209eb..527ac4eb5e3e1fc708e29028ba4c2e97a9dac546 100644 (file)
@@ -125,9 +125,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     DCE2_TcpSsnData dce2_tcp_session;
index fd642124e80484dcc5e96935b7fb5b3fd1c474f6..53a7d454f0b58b3003a770bb4f37be6f6f495b68 100644 (file)
@@ -197,9 +197,6 @@ public:
 
     static unsigned inspector_id;
     DCE2_UdpSsnData dce2_udp_session;
-
-    size_t size_of() override
-    { return sizeof(*this); }
 };
 
 DCE2_UdpSsnData* get_dce2_udp_session_data(snort::Flow*);
index 07ff45bf3fab207d4a847c959c23e9017be3d8b2..bcba8aefde75e6207bf56f59616271478d1c39a1 100644 (file)
@@ -9,7 +9,3 @@ PDUs.
 The wizard is a special service inspector that examines the beginning of a
 data stream and decides what application protocol is present.
 
-http_inspect is the legacy Snort HTTP preprocessor ported to Snort\++ .
-nhttp_inspect is the complete rewrite being developed specifically for
-Snort++.
-
index 09c71576255baa2789be3bff5526f417382b5b0a..b641c3c5217f480a572c6014cc7543ec8087ce0d 100644 (file)
@@ -176,9 +176,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     dnp3_session_data_t dnp3_session;
index 3beebf2519c9851c28b1a6c6632cc2e70684bbdb..03cf5e9e7685c346b8ba67ca660454830badedf4 100644 (file)
@@ -175,9 +175,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     DNSData session;
index 9b10ba100d057e2a43cbd97e261c107d33f9b656..9df76aa2931fdb21e336a90dffbdd051168872da 100644 (file)
@@ -105,9 +105,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     TELNET_SESSION session;
index 57f95fdea8442112e8a868e2d13e4ce17433d5ad..4a94a61b480c9fef6881ecb3e22dbd6b88ade6fd 100644 (file)
@@ -43,9 +43,6 @@ public:
 
     static void init();
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     GTP_Roptions ropts;
index ad2bf3c99454ee5243d3126de6c15e7cc4ea1381..7da83070406e629e7abcae681f2dd7158911bd8b 100644 (file)
@@ -43,12 +43,6 @@ unsigned Http2FlowData::inspector_id = 0;
 uint64_t Http2FlowData::instance_count = 0;
 #endif
 
-// Each stream will have class Http2Stream allocated and a node in streams list
-const size_t Http2FlowData::stream_memory_size = sizeof(class Http2Stream) +
-    stream_extra_memory;
-const size_t Http2FlowData::stream_increment_memory_size = stream_memory_size *
-    STREAM_MEMORY_TRACKING_INCREMENT;
-
 Http2FlowData::Http2FlowData(Flow* flow_) :
     FlowData(inspector_id),
     flow(flow_),
@@ -103,10 +97,6 @@ Http2FlowData::~Http2FlowData()
 
     for (Http2Stream* stream : streams)
         delete stream;
-    // Since stream memory is allocated in blocks of 25, must also deallocate in blocks of 25 to
-    // ensure consistent rounding.
-    while (stream_memory_allocations_tracked > STREAM_MEMORY_TRACKING_INCREMENT)
-        update_stream_memory_deallocations();
 }
 
 HttpFlowData* Http2FlowData::get_hi_flow_data() const
@@ -123,28 +113,6 @@ void Http2FlowData::set_hi_flow_data(HttpFlowData* flow)
     stream->set_hi_flow_data(flow);
 }
 
-size_t Http2FlowData::size_of()
-{
-    // Account for memory for 25 concurrent streams up front, plus 1 stream for stream id 0.
-    return sizeof(*this) + stream_increment_memory_size + stream_memory_size +
-        (2 * sizeof(Http2EventGen)) + (2 * sizeof(Http2Infractions));
-}
-
-void Http2FlowData::update_stream_memory_allocations()
-{
-    assert(concurrent_streams > stream_memory_allocations_tracked);
-    assert(concurrent_streams % stream_memory_allocations_tracked == 1);
-    update_allocations(stream_increment_memory_size);
-    stream_memory_allocations_tracked += STREAM_MEMORY_TRACKING_INCREMENT;
-}
-
-void Http2FlowData::update_stream_memory_deallocations()
-{
-    assert(stream_memory_allocations_tracked >= STREAM_MEMORY_TRACKING_INCREMENT);
-    update_deallocations(stream_increment_memory_size);
-    stream_memory_allocations_tracked -= STREAM_MEMORY_TRACKING_INCREMENT;
-}
-
 Http2Stream* Http2FlowData::find_stream(const uint32_t key) const
 {
     for (Http2Stream* stream : streams)
@@ -215,8 +183,6 @@ Http2Stream* Http2FlowData::get_processing_stream(const SourceId source_id, uint
             concurrent_streams += 1;
             if (concurrent_streams > Http2Module::get_peg_counts(PEG_MAX_CONCURRENT_STREAMS))
                 Http2Module::increment_peg_counts(PEG_MAX_CONCURRENT_STREAMS);
-            if (concurrent_streams > stream_memory_allocations_tracked)
-                update_stream_memory_allocations();
         }
     }
     return stream;
@@ -278,16 +244,6 @@ uint32_t Http2FlowData::get_current_stream_id(const SourceId source_id) const
     return current_stream[source_id];
 }
 
-void Http2FlowData::allocate_hi_memory(HttpFlowData* hi_flow_data)
-{
-    update_allocations(hi_flow_data->size_of());
-}
-
-void Http2FlowData::deallocate_hi_memory(HttpFlowData* hi_flow_data)
-{
-    update_deallocations(hi_flow_data->size_of());
-}
-
 bool Http2FlowData::is_mid_frame() const
 {
     return (header_octets_seen[SRC_SERVER] != 0) || (remaining_data_padding[SRC_SERVER] != 0) ||
index fee0d104f48ff2efb91d937f0f07e0bc988a4eef..2fc6f244d99996c43041050cba6506122f4cf5e7 100644 (file)
@@ -84,8 +84,6 @@ public:
     friend class Http2WindowUpdateFrame;
     friend void finish_msg_body(Http2FlowData* session_data, HttpCommon::SourceId source_id);
 
-    size_t size_of() override;
-
     Http2Stream* find_current_stream(const HttpCommon::SourceId source_id) const;
     uint32_t get_current_stream_id(const HttpCommon::SourceId source_id) const;
     Http2Stream* get_processing_stream(const HttpCommon::SourceId source_id, uint32_t concurrent_streams_limit);
@@ -202,19 +200,6 @@ private:
     Http2Stream* get_hi_stream() const;
     Http2Stream* find_stream(const uint32_t key) const;
     void delete_processing_stream();
-
-    // When H2I allocates http_inspect flows, it bypasses the usual FlowData memory allocation
-    // bookkeeping. So H2I needs to update memory allocations and deallocations itself.
-    void allocate_hi_memory(HttpFlowData* hi_flow_data);
-    void deallocate_hi_memory(HttpFlowData* hi_flow_data);
-    // Memory for streams is tracked in increments of 25 to minimize tracking overhead
-    void update_stream_memory_allocations();
-    void update_stream_memory_deallocations();
-    static const size_t stream_memory_size;
-    static const size_t stream_increment_memory_size;
-    // Per-stream extra memory estimate to account for the std::list streams. Actual memory usage
-    // is implementation dependent
-    static const size_t stream_extra_memory = 24;
 };
 
 #endif
index dc291995f8cc3380360abc010fde7ad765095755..ec441ff3c5380a130e00aa5ebd4b91dccd27c90c 100644 (file)
 #endif
 
 #include "http2_hpack_dynamic_table.h"
+#include "http2_module.h"
 
 #include <cstring>
 
-#include "http2_flow_data.h"
 #include "http2_hpack_table.h"
-#include "http2_module.h"
 
 using namespace Http2Enums;
 
-HpackDynamicTable::HpackDynamicTable(Http2FlowData* flow_data) :
-    session_data(flow_data)
-{
-    session_data->update_allocations( ARRAY_CAPACITY * sizeof(HpackTableEntry*) +
-        TABLE_MEMORY_TRACKING_INCREMENT);
-    table_memory_allocated = TABLE_MEMORY_TRACKING_INCREMENT;
-}
-
-
 HpackDynamicTable::~HpackDynamicTable()
 {
-    for (uint32_t i = 0, indx = start; i < num_entries; i++)
+    for (std::vector<HpackTableEntry*>::iterator it = circular_buf.begin();
+        it != circular_buf.end(); ++it)
     {
-        delete circular_buf[indx];
-        indx = (indx + 1) % ARRAY_CAPACITY;
-    }
-    session_data->update_deallocations( ARRAY_CAPACITY * sizeof(HpackTableEntry*) +
-        TABLE_MEMORY_TRACKING_INCREMENT );
-
-    while (table_memory_allocated > TABLE_MEMORY_TRACKING_INCREMENT)
-    {
-        session_data->update_deallocations(TABLE_MEMORY_TRACKING_INCREMENT);
-        table_memory_allocated -= TABLE_MEMORY_TRACKING_INCREMENT;
+        delete *it;
     }
 }
 
@@ -89,12 +71,6 @@ bool HpackDynamicTable::add_entry(const Field& name, const Field& value)
         Http2Module::increment_peg_counts(PEG_MAX_TABLE_ENTRIES);
 
     rfc_table_size += new_entry_size;
-    while (rfc_table_size > table_memory_allocated)
-    {
-        session_data->update_allocations(TABLE_MEMORY_TRACKING_INCREMENT);
-        table_memory_allocated += TABLE_MEMORY_TRACKING_INCREMENT;
-    }
-
     return true;
 }
 
index 43e13178c2f859374b1035d38e0ee611bf44cca6..2636a2d9a0088adc1b54ace02337ac45674a54bb 100644 (file)
@@ -34,7 +34,7 @@ class HpackDynamicTable
 {
 public:
     // FIXIT-P This array can be optimized to start smaller and grow on demand
-    HpackDynamicTable(Http2FlowData* flow_data);
+    HpackDynamicTable() : circular_buf(ARRAY_CAPACITY, nullptr) {}
     ~HpackDynamicTable();
     const HpackTableEntry* get_entry(uint32_t index) const;
     bool add_entry(const Field& name, const Field& value);
@@ -46,15 +46,12 @@ private:
 
     const static uint32_t DEFAULT_MAX_SIZE = 4096;
     const static uint32_t ARRAY_CAPACITY = 512;
-    const static uint32_t TABLE_MEMORY_TRACKING_INCREMENT = 500;
     uint32_t max_size = DEFAULT_MAX_SIZE;
 
     uint32_t start = 0;
     uint32_t num_entries = 0;
     uint32_t rfc_table_size = 0;
-    HpackTableEntry* circular_buf[ARRAY_CAPACITY] = {0};
-    Http2FlowData* const session_data;
-    uint32_t table_memory_allocated;
+    std::vector<HpackTableEntry*> circular_buf;
 
     void prune_to_size(uint32_t new_max_size);
 };
index 579253ef251632bfa31139bf0ed8347c510d62a6..44b57c53f8b355d4a9fd624a96774c9e9178cd1e 100644 (file)
@@ -40,7 +40,7 @@ struct HpackTableEntry
 class HpackIndexTable
 {
 public:
-    HpackIndexTable(Http2FlowData* flow_data) : dynamic_table(flow_data) { }
+    HpackIndexTable(Http2FlowData*) { }
     const HpackTableEntry* lookup(uint64_t index) const;
     bool add_index(const Field& name, const Field& value);
     HpackDynamicTable& get_dynamic_table() { return dynamic_table; }
index 3ab143105f11bf4500bd16d5dce9c1539a6ce847..1aeab5241832e8d844aa759e88e09d1c7a727f74 100644 (file)
@@ -45,8 +45,6 @@ Http2Stream::Http2Stream(uint32_t stream_id_, Http2FlowData* session_data_) :
 Http2Stream::~Http2Stream()
 {
     delete current_frame;
-    if (hi_flow_data)
-        session_data->deallocate_hi_memory(hi_flow_data);
     delete hi_flow_data;
 }
 
@@ -77,7 +75,6 @@ void Http2Stream::check_and_cleanup_completed()
     {
         if (hi_flow_data != nullptr)
         {
-            session_data->deallocate_hi_memory(hi_flow_data);
             delete hi_flow_data;
             hi_flow_data = nullptr;
         }
@@ -108,7 +105,6 @@ void Http2Stream::set_hi_flow_data(HttpFlowData* flow_data)
 {
     assert(hi_flow_data == nullptr);
     hi_flow_data = flow_data;
-    session_data->allocate_hi_memory(hi_flow_data);
 }
 
 const Field& Http2Stream::get_buf(unsigned id)
index 4455dcf705a63c9c0642149036a0b0607345f247..5922d340c2a319458a2cc82988c50f9ddf18de30 100644 (file)
@@ -280,9 +280,8 @@ ScanResult HttpHeaderCutter::cut(const uint8_t* buffer, uint32_t length,
 }
 
 HttpBodyCutter::HttpBodyCutter(bool accelerated_blocking_, ScriptFinder* finder_,
-    CompressId compression_, HttpFlowData* ssn_data)
-    : accelerated_blocking(accelerated_blocking_), compression(compression_), finder(finder_),
-    session_data(ssn_data)
+    CompressId compression_)
+    : accelerated_blocking(accelerated_blocking_), compression(compression_), finder(finder_)
 {
     if (accelerated_blocking)
     {
@@ -302,9 +301,6 @@ HttpBodyCutter::HttpBodyCutter(bool accelerated_blocking_, ScriptFinder* finder_
                 delete compress_stream;
                 compress_stream = nullptr;
             }
-            else
-                session_data->update_allocations(session_data->zlib_inflate_memory);
-
         }
 
         static const uint8_t inspect_string[] = { '<', '/', 's', 'c', 'r', 'i', 'p', 't', '>' };
@@ -322,7 +318,6 @@ HttpBodyCutter::~HttpBodyCutter()
     {
         inflateEnd(compress_stream);
         delete compress_stream;
-        session_data->update_deallocations(session_data->zlib_inflate_memory);
     }
 }
 
index 2a6fe1f08db0199c96e85ebe70bf1e4e266dcae4..04e33305f523b6daa8826506ee44b40e4a9eb295 100644 (file)
@@ -104,7 +104,7 @@ class HttpBodyCutter : public HttpCutter
 {
 public:
     HttpBodyCutter(bool accelerated_blocking_, ScriptFinder* finder,
-        HttpEnums::CompressId compression_, HttpFlowData* ssn_data);
+        HttpEnums::CompressId compression_);
     ~HttpBodyCutter() override;
     void soft_reset() override { octets_seen = 0; }
 
@@ -124,7 +124,6 @@ private:
     const uint8_t* match_string;
     const uint8_t* match_string_upper;
     uint8_t string_length;
-    HttpFlowData* const session_data;
 };
 
 class HttpBodyClCutter : public HttpBodyCutter
@@ -133,9 +132,8 @@ public:
     HttpBodyClCutter(int64_t expected_length,
         bool accelerated_blocking,
         ScriptFinder* finder,
-        HttpEnums::CompressId compression,
-        HttpFlowData* ssn_data) :
-        HttpBodyCutter(accelerated_blocking, finder, compression, ssn_data),
+        HttpEnums::CompressId compression) :
+        HttpBodyCutter(accelerated_blocking, finder, compression),
         remaining(expected_length)
         { assert(remaining > 0); }
     HttpEnums::ScanResult cut(const uint8_t*, uint32_t length, HttpInfractions*, HttpEventGen*,
@@ -149,8 +147,8 @@ class HttpBodyOldCutter : public HttpBodyCutter
 {
 public:
     HttpBodyOldCutter(bool accelerated_blocking, ScriptFinder* finder,
-        HttpEnums::CompressId compression, HttpFlowData* ssn_data) :
-        HttpBodyCutter(accelerated_blocking, finder, compression, ssn_data)
+        HttpEnums::CompressId compression) :
+        HttpBodyCutter(accelerated_blocking, finder, compression)
         {}
     HttpEnums::ScanResult cut(const uint8_t*, uint32_t, HttpInfractions*, HttpEventGen*,
         uint32_t flow_target, bool stretch, HttpEnums::H2BodyState) override;
@@ -160,8 +158,8 @@ class HttpBodyChunkCutter : public HttpBodyCutter
 {
 public:
     HttpBodyChunkCutter(int64_t maximum_chunk_length_, bool accelerated_blocking,
-        ScriptFinder* finder, HttpEnums::CompressId compression, HttpFlowData* ssn_data) :
-        HttpBodyCutter(accelerated_blocking, finder, compression, ssn_data),
+        ScriptFinder* finder, HttpEnums::CompressId compression) :
+        HttpBodyCutter(accelerated_blocking, finder, compression),
         maximum_chunk_length(maximum_chunk_length_)
         {}
     HttpEnums::ScanResult cut(const uint8_t* buffer, uint32_t length,
@@ -190,8 +188,8 @@ class HttpBodyH2Cutter : public HttpBodyCutter
 {
 public:
     HttpBodyH2Cutter(int64_t expected_length, bool accelerated_blocking, ScriptFinder* finder,
-        HttpEnums::CompressId compression, HttpFlowData* ssn_data) :
-        HttpBodyCutter(accelerated_blocking, finder, compression, ssn_data),
+        HttpEnums::CompressId compression) :
+        HttpBodyCutter(accelerated_blocking, finder, compression),
             expected_body_length(expected_length)
         {}
     HttpEnums::ScanResult cut(const uint8_t* buffer, uint32_t length, HttpInfractions*,
index c9761bd82d23b439b575e3c2636155a7c2f2381b..cf2a34982a97a5ed62a6bfd0313cee4c7a215d0b 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "http_field.h"
 
-#include "flow/flow_data.h"
 #include "http_common.h"
 #include "http_enum.h"
 #include "http_test_manager.h"
@@ -78,18 +77,6 @@ void Field::set(const Field& f)
     // Both Fields cannot be responsible for deleting the buffer so do not copy own_the_buffer
 }
 
-void Field::update_allocations(snort::FlowData* flow_data)
-{
-    if (own_the_buffer && (len > 0))
-        flow_data->update_allocations(len);
-}
-
-void Field::update_deallocations(snort::FlowData* flow_data)
-{
-    if (own_the_buffer && (len > 0))
-        flow_data->update_deallocations(len);
-}
-
 #ifdef REG_TEST
 void Field::print(FILE* output, const char* name) const
 {
index 2356bc2aea8ffa1adf868f6b32479f776cffb423..0246ee3315f032e330d801b12bb20ce11f4ba7b4 100644 (file)
 #include "http_common.h"
 #include "http_enum.h"
 
-namespace snort
-{
-class FlowData;
-}
-
 // Individual pieces of the message found during parsing.
 // Length values <= 0 are StatusCode values and imply that the start pointer is meaningless.
 // Never use the start pointer without verifying that length > 0.
@@ -51,8 +46,6 @@ public:
     void set(const Field& f);
     void set(HttpCommon::StatusCode stat_code);
     void set(int32_t length) { set(static_cast<HttpCommon::StatusCode>(length)); }
-    void update_allocations(snort::FlowData* flow_data);
-    void update_deallocations(snort::FlowData* flow_data);
 
 #ifdef REG_TEST
     void print(FILE* output, const char* name) const;
index d058c56e17bdb5955d1c889dd42219ee10fce6e5..ce3875c85cc34a22965ec40217857afa0db04635 100644 (file)
@@ -95,7 +95,6 @@ HttpFlowData::~HttpFlowData()
 #ifndef UNIT_TEST_BUILD
     if (js_ident_ctx)
     {
-        update_deallocations(js_ident_ctx->size());
         delete js_ident_ctx;
 
         debug_log(4, http_trace, TRACE_JS_PROC, nullptr,
@@ -103,7 +102,6 @@ HttpFlowData::~HttpFlowData()
     }
     if (js_normalizer)
     {
-        update_deallocations(JSNormalizer::size());
         delete js_normalizer;
 
         debug_log(4, http_trace, TRACE_JS_PROC, nullptr,
@@ -117,16 +115,13 @@ HttpFlowData::~HttpFlowData()
         delete events[k];
         delete[] section_buffer[k];
         delete[] partial_buffer[k];
-        update_deallocations(partial_buffer_length[k]);
         delete[] partial_detect_buffer[k];
-        update_deallocations(partial_detect_length[k]);
         HttpTransaction::delete_transaction(transaction[k], nullptr);
         delete cutter[k];
         if (compress_stream[k] != nullptr)
         {
             inflateEnd(compress_stream[k]);
             delete compress_stream[k];
-            update_deallocations(zlib_inflate_memory);
         }
         if (mime_state[k] != nullptr)
         {
@@ -147,11 +142,6 @@ HttpFlowData::~HttpFlowData()
     }
 }
 
-size_t HttpFlowData::size_of()
-{
-    return sizeof(HttpFlowData) + (2 * sizeof(HttpEventGen));
-}
-
 void HttpFlowData::half_reset(SourceId source_id)
 {
     assert((source_id == SRC_CLIENT) || (source_id == SRC_SERVER));
@@ -176,7 +166,6 @@ void HttpFlowData::half_reset(SourceId source_id)
         inflateEnd(compress_stream[source_id]);
         delete compress_stream[source_id];
         compress_stream[source_id] = nullptr;
-        update_deallocations(zlib_inflate_memory);
     }
     if (mime_state[source_id] != nullptr)
     {
@@ -220,7 +209,6 @@ void HttpFlowData::trailer_prep(SourceId source_id)
         inflateEnd(compress_stream[source_id]);
         delete compress_stream[source_id];
         compress_stream[source_id] = nullptr;
-        update_deallocations(zlib_inflate_memory);
     }
     detection_status[source_id] = DET_REACTIVATING;
 }
@@ -268,7 +256,6 @@ snort::JSNormalizer& HttpFlowData::acquire_js_ctx(int32_t ident_depth, size_t no
     if (!js_ident_ctx)
     {
         js_ident_ctx = new JSIdentifierCtx(ident_depth, max_scope_depth, built_in_ident);
-        update_allocations(js_ident_ctx->size());
 
         debug_logf(4, http_trace, TRACE_JS_PROC, nullptr,
             "js_ident_ctx created (ident_depth %d)\n", ident_depth);
@@ -276,7 +263,6 @@ snort::JSNormalizer& HttpFlowData::acquire_js_ctx(int32_t ident_depth, size_t no
 
     js_normalizer = new JSNormalizer(*js_ident_ctx, norm_depth,
         max_template_nesting, max_bracket_depth);
-    update_allocations(JSNormalizer::size());
 
     debug_logf(4, http_trace, TRACE_JS_PROC, nullptr,
         "js_normalizer created (norm_depth %zd, max_template_nesting %d)\n",
@@ -299,7 +285,6 @@ void HttpFlowData::release_js_ctx()
     if (!js_normalizer)
         return;
 
-    update_deallocations(JSNormalizer::size());
     delete js_normalizer;
     js_normalizer = nullptr;
 
@@ -320,7 +305,6 @@ bool HttpFlowData::add_to_pipeline(HttpTransaction* latest)
     {
         pipeline = new HttpTransaction*[MAX_PIPELINE];
         HttpModule::increment_peg_counts(PEG_PIPELINED_FLOWS);
-        update_allocations(sizeof(HttpTransaction*) * MAX_PIPELINE);
     }
     assert(!pipeline_overflow && !pipeline_underflow);
     int new_back = (pipeline_back+1) % MAX_PIPELINE;
@@ -353,8 +337,6 @@ void HttpFlowData::delete_pipeline()
     {
         delete pipeline[k];
     }
-    if (pipeline != nullptr)
-        update_deallocations(sizeof(HttpTransaction*) * MAX_PIPELINE);
     delete[] pipeline;
 }
 
@@ -378,12 +360,10 @@ void HttpFlowData::finish_h2_body(HttpCommon::SourceId source_id, HttpEnums::H2B
     {
         // We've already sent all data through detection so no need to reinspect. Just need to
         // prep for trailers
-        update_deallocations(partial_buffer_length[source_id]);
         partial_buffer_length[source_id] = 0;
         delete[] partial_buffer[source_id];
         partial_buffer[source_id] = nullptr;
 
-        update_deallocations(partial_detect_length[source_id]);
         partial_detect_length[source_id] = 0;
         delete[] partial_detect_buffer[source_id];
         partial_detect_buffer[source_id] = nullptr;
index 7adef81589dfa14dd2d40fcf42cec6b8cb3d923a..2b39678f1087b294360525a7faacf2679eeb8167 100644 (file)
@@ -52,7 +52,6 @@ public:
     ~HttpFlowData() override;
     static unsigned inspector_id;
     static void init() { inspector_id = snort::FlowData::create_flow_data_id(); }
-    size_t size_of() override;
 
     friend class HttpBodyCutter;
     friend class HttpInspect;
index a86830c9cf666e307ca0d2bd9b9146ac30860b85..f2df2ae97329401d63eda27b78a768ff84e116de 100644 (file)
@@ -100,7 +100,6 @@ void HttpMsgBody::clean_partial(uint32_t& partial_inspected_octets, uint32_t& pa
     if (session_data->detect_depth_remaining[source_id] > 0)
     {
         delete[] partial_detect_buffer;
-        session_data->update_deallocations(partial_detect_length);
         assert(detect_length <= session_data->detect_depth_remaining[source_id]);
         bookkeeping_regular_flush(partial_detect_length, partial_detect_buffer,
             partial_js_detect_length, detect_length);
@@ -190,7 +189,6 @@ void HttpMsgBody::analyze()
             detect_data.set(detect_length, js_norm_body.start());
 
             delete[] partial_detect_buffer;
-            session_data->update_deallocations(partial_detect_length);
 
             if (!session_data->partial_flush[source_id])
             {
@@ -206,7 +204,6 @@ void HttpMsgBody::analyze()
                 partial_detect_buffer = save_partial;
                 partial_detect_length = decompressed->length();
                 partial_js_detect_length = js_norm_body.length();
-                session_data->update_allocations(partial_detect_length);
             }
 
             set_file_data(const_cast<uint8_t*>(detect_data.start()),
@@ -367,7 +364,6 @@ void HttpMsgBody::do_enhanced_js_normalization(const Field& input, Field& output
     {
         *infractions += INF_JS_PDU_MISS;
         session_data->events[HttpCommon::SRC_SERVER]->create_event(EVENT_JS_PDU_MISS);
-
         session_data->js_data_lost_once = true;
         return;
     }
index 65293e50ebea9186086c7c35f32806a7590d71a5..167a4c09fe7b0ebff3d6696193f62604798c8503 100755 (executable)
@@ -34,35 +34,11 @@ using namespace HttpCommon;
 using namespace HttpEnums;
 using namespace snort;
 
-// Memory calculation:
-// Approximations based on assumptions:
-// - there will be a cookie
-// - http_header and http_cookie rule options will be required
-// - classic normalization on the headers will not be trivial
-// - individual normalized headers won't be a lot and 500 bytes will cover them
-//
-// Header infrastructure (header_line, header_name, header_name_id, header_value):
-// session_data_->num_head_lines[source_id_] * (3 * sizeof(Field) + sizeof(HeaderId))
-//
-// The entire headers consist of http_raw_header and http_raw_cookie. Because there is
-// a cookie it will be necessary to write out the full msg_text into these two buffers,
-// resulting in allocations totaling approximately msg_text.length(). These raw buffers
-// in turn will need to be normalized, requiring another msg_text.length().
-// Total cost: 2 * msg_text.length().
-//
-// Plus 500 bytes for normalized headers.
 HttpMsgHeadShared::HttpMsgHeadShared(const uint8_t* buffer, const uint16_t buf_size, HttpFlowData* session_data_,
     HttpCommon::SourceId source_id_, bool buf_owner, snort::Flow* flow_,
     const HttpParaList* params_): HttpMsgSection(buffer, buf_size, session_data_, source_id_,
-    buf_owner, flow_, params_), own_msg_buffer(buf_owner),
-    extra_memory_allocations(session_data_->num_head_lines[source_id_] *
-                            (3 * sizeof(Field) + sizeof(HeaderId)) + 2 * msg_text.length() + 500)
-{
-    if (own_msg_buffer)
-        session_data->update_allocations(msg_text.length());
-
-    session_data->update_allocations(extra_memory_allocations);
-}
+    buf_owner, flow_, params_), own_msg_buffer(buf_owner)
+{ }
 
 HttpMsgHeadShared::~HttpMsgHeadShared()
 {
@@ -77,11 +53,6 @@ HttpMsgHeadShared::~HttpMsgHeadShared()
         list_ptr = list_ptr->next;
         delete temp_ptr;
     }
-
-    if (own_msg_buffer)
-        session_data->update_deallocations(msg_text.length());
-
-    session_data->update_deallocations(extra_memory_allocations);
 }
 
 bool HttpMsgHeadShared::is_external_js()
index f0f791a68ce12bfc36df506c4cf14abf457681bb..4bdcfb61a3397a1f5038c8f904f8afe640edfd86 100755 (executable)
@@ -109,7 +109,6 @@ private:
     bool file_cache_index_computed = false;
 
     bool own_msg_buffer;
-    const uint32_t extra_memory_allocations;
     int js_external = HttpCommon::STAT_NOT_COMPUTE;
 };
 
index e896de26b9d52d8957f2959a9af4d971d3f7d6d0..c8234c9deb216ceb794640c78af18a16a94c1553 100755 (executable)
@@ -605,8 +605,6 @@ void HttpMsgHeader::setup_encoding_decompression()
         delete session_data->compress_stream[source_id];
         session_data->compress_stream[source_id] = nullptr;
     }
-    else
-        session_data->update_allocations(session_data->zlib_inflate_memory);
 }
 
 void HttpMsgHeader::setup_utf_decoding()
index bc1a57d4cc15ec2c75f40142b04768770cbe251e..95d1e03fb2bd41978decca67cdd951cf19905ab5 100644 (file)
@@ -120,7 +120,7 @@ void HttpMsgRequest::parse_start_line()
     {
         uri = new HttpUri(start_line.start() + first_end + 1, last_begin - first_end - 1,
             method_id, params->uri_param, transaction->get_infractions(source_id),
-            session_data->events[source_id], session_data);
+            session_data->events[source_id]);
     }
     else
     {
@@ -165,7 +165,7 @@ bool HttpMsgRequest::handle_zero_nine()
                 uri_end--);
             uri = new HttpUri(start_line.start() + uri_begin, uri_end - uri_begin + 1, method_id,
                 params->uri_param, transaction->get_infractions(source_id),
-                session_data->events[source_id], session_data);
+                session_data->events[source_id]);
         }
         else
         {
index af60e9d13da73ec15e9bae0dbef7e62e36ccac19..685221863350e66eaec6af338b91a7fb19e35b5f 100644 (file)
@@ -31,16 +31,10 @@ HttpMsgStart::HttpMsgStart(const uint8_t* buffer, const uint16_t buf_size, HttpF
     HttpCommon::SourceId source_id_, bool buf_owner, snort::Flow* flow_,
     const HttpParaList* params_) : HttpMsgSection(buffer, buf_size, session_data_, source_id_,
     buf_owner, flow_, params_), own_msg_buffer(buf_owner)
-{
-    if (own_msg_buffer)
-        session_data->update_allocations(msg_text.length());
-}
+{ }
 
 HttpMsgStart::~HttpMsgStart()
-{
-    if (own_msg_buffer)
-        session_data->update_deallocations(msg_text.length());
-}
+{ }
 
 void HttpMsgStart::analyze()
 {
index 21e75fcac9f2bab742ebe805d7caac0300cd9605..238db9471e62913e69041cc5609401e3a59b3494 100644 (file)
@@ -179,7 +179,6 @@ void HttpStreamSplitter::decompress_copy(uint8_t* buffer, uint32_t& offset, cons
                 inflateEnd(compress_stream);
                 delete compress_stream;
                 compress_stream = nullptr;
-                session_data->update_deallocations(session_data->zlib_inflate_memory);
             }
             return;
         }
@@ -207,7 +206,6 @@ void HttpStreamSplitter::decompress_copy(uint8_t* buffer, uint32_t& offset, cons
             inflateEnd(compress_stream);
             delete compress_stream;
             compress_stream = nullptr;
-            session_data->update_deallocations(session_data->zlib_inflate_memory);
             // Since we failed to uncompress the data, fall through
         }
     }
@@ -384,7 +382,6 @@ const StreamBuffer HttpStreamSplitter::reassemble(Flow* flow, unsigned total,
         memcpy(buffer, partial_buffer, partial_buffer_length);
         session_data->section_offset[source_id] = partial_buffer_length;
         delete[] partial_buffer;
-        session_data->update_deallocations(partial_buffer_length);
         partial_buffer_length = 0;
         partial_buffer = nullptr;
     }
@@ -428,7 +425,6 @@ const StreamBuffer HttpStreamSplitter::reassemble(Flow* flow, unsigned total,
                 partial_buffer = new uint8_t[buf_size];
                 memcpy(partial_buffer, buffer, buf_size);
                 partial_buffer_length = buf_size;
-                session_data->update_allocations(partial_buffer_length);
             }
             partial_raw_bytes += total;
         }
index b5623e6bc8431b1695333822d64740b9d467d4e7..dd4c28f41dd4a1112dc3bc35cc51b895d546f466 100644 (file)
@@ -77,24 +77,24 @@ HttpCutter* HttpStreamSplitter::get_cutter(SectionType type,
             session_data->data_length[source_id],
             session_data->accelerated_blocking[source_id],
             my_inspector->script_finder,
-            session_data->compression[source_id], session_data);
+            session_data->compression[source_id]);
     case SEC_BODY_CHUNK:
         return (HttpCutter*)new HttpBodyChunkCutter(
             my_inspector->params->maximum_chunk_length,
             session_data->accelerated_blocking[source_id],
             my_inspector->script_finder,
-            session_data->compression[source_id], session_data);
+            session_data->compression[source_id]);
     case SEC_BODY_OLD:
         return (HttpCutter*)new HttpBodyOldCutter(
             session_data->accelerated_blocking[source_id],
             my_inspector->script_finder,
-            session_data->compression[source_id], session_data);
+            session_data->compression[source_id]);
     case SEC_BODY_H2:
         return (HttpCutter*)new HttpBodyH2Cutter(
             session_data->data_length[source_id],
             session_data->accelerated_blocking[source_id],
             my_inspector->script_finder,
-            session_data->compression[source_id], session_data);
+            session_data->compression[source_id]);
     default:
         assert(false);
         return nullptr;
index ab940a0ddad2a7f88edd927c06238ed25de155d4..84ff5577634557a6e97004afdc2d6a19cf2b145c 100644 (file)
@@ -54,7 +54,6 @@ HttpTransaction::HttpTransaction(HttpFlowData* session_data_): session_data(sess
 {
     infractions[0] = nullptr;
     infractions[1] = nullptr;
-    session_data->update_allocations(transaction_memory_usage_estimate);
 }
 
 HttpTransaction::~HttpTransaction()
@@ -69,7 +68,6 @@ HttpTransaction::~HttpTransaction()
     }
     delete_section_list(body_list);
     delete_section_list(discard_list);
-    session_data->update_deallocations(transaction_memory_usage_estimate);
 }
 
 HttpTransaction* HttpTransaction::attach_my_transaction(HttpFlowData* session_data, SourceId
index 8b929d4c9942ee5572040737897dbb82cf3fca4e..79fb0f83540d829b8795e7e53e8601fa4dc046fc 100644 (file)
 
 #include "http_common.h"
 #include "http_enum.h"
-#include "http_flow_data.h"
 #include "hash/hash_key_operations.h"
 
 using namespace HttpCommon;
 using namespace HttpEnums;
 using namespace snort;
 
-HttpUri::HttpUri(const uint8_t* start, int32_t length, HttpEnums::MethodId method_id_,
-    const HttpParaList::UriParam& uri_param_, HttpInfractions* infractions_,
-    HttpEventGen* events_, HttpFlowData* session_data_) :
-    uri(length, start), infractions(infractions_), events(events_), method_id(method_id_),
-    uri_param(uri_param_), session_data(session_data_)
-{
-    normalize();
-    classic_norm.update_allocations(session_data);
-}
-
-HttpUri::~HttpUri()
-{
-    classic_norm.update_deallocations(session_data);
-}
-
 void HttpUri::parse_uri()
 {
     // Four basic types of HTTP URI
@@ -426,4 +410,3 @@ const Field& HttpUri::get_norm_host()
 
     return host_norm;
 }
-
index 5c1bd91df9c8bf21ae24ce4b83fd8e6123d79bad..5f5e26c8186e872105bdc025189a055af8552c44 100644 (file)
 #ifndef HTTP_URI_H
 #define HTTP_URI_H
 
-#include "http_event.h"
-#include "http_field.h"
-#include "http_module.h"
 #include "http_str_to_code.h"
+#include "http_module.h"
 #include "http_uri_norm.h"
-
-class HttpFlowData;
+#include "http_field.h"
+#include "http_event.h"
 
 static const int MAX_SCHEME_LENGTH = 36; // schemes longer than 36 characters are malformed
 static const int LONG_SCHEME_LENGTH = 10; // schemes longer than 10 characters will alert
@@ -40,8 +38,10 @@ class HttpUri
 public:
     HttpUri(const uint8_t* start, int32_t length, HttpEnums::MethodId method_id_,
         const HttpParaList::UriParam& uri_param_, HttpInfractions* infractions_,
-        HttpEventGen* events_, HttpFlowData* session_data_);
-    ~HttpUri();
+        HttpEventGen* events_) :
+        uri(length, start), infractions(infractions_), events(events_), method_id(method_id_),
+        uri_param(uri_param_)
+        { normalize(); }
     const Field& get_uri() const { return uri; }
     HttpEnums::UriType get_uri_type() { return uri_type; }
     const Field& get_scheme() { return scheme; }
@@ -85,7 +85,6 @@ private:
     HttpEnums::UriType uri_type = HttpEnums::URI__NOT_COMPUTE;
     const HttpEnums::MethodId method_id;
     const HttpParaList::UriParam& uri_param;
-    HttpFlowData* const session_data;
 
     void normalize();
     void parse_uri();
index 587bf9ce521b052888b46482b8b4988030a72591..175fea15fae38eec6299e04b08d45bc6fbb69179 100755 (executable)
@@ -74,8 +74,6 @@ HttpJsNorm::HttpJsNorm(const HttpParaList::UriParam& uri_param_, int64_t normali
 HttpJsNorm::~HttpJsNorm() = default;
 void HttpJsNorm::configure(){}
 int64_t Parameter::get_int(char const*) { return 0; }
-void FlowData::update_allocations(size_t) {}
-void FlowData::update_deallocations(size_t) {}
 
 TEST_GROUP(http_peg_count_test)
 {
index edc2e837901c4bff360961625a1d7d495291dcc9..e57e5957edd8edd6fa7a84376b2a14843e5abff8 100644 (file)
@@ -37,8 +37,6 @@ using namespace snort;
 // Stubs whose sole purpose is to make the test code link
 long HttpTestManager::print_amount {};
 bool HttpTestManager::print_hex {};
-void FlowData::update_allocations(size_t) {}
-void FlowData::update_deallocations(size_t) {}
 
 // Tests for get_next_code()
 TEST_GROUP(get_next_code)
index 57258726d41a4a0a4d3fa4c801ba4996f72e18ef..9dfb54b79bea331b66330fcd8191ddac278b9f8e 100644 (file)
@@ -40,8 +40,6 @@ const bool HttpEnums::is_sp_tab[256] {};
 const bool HttpEnums::is_sp_tab_quote_dquote[256] {};
 long HttpTestManager::print_amount {};
 bool HttpTestManager::print_hex {};
-void FlowData::update_allocations(size_t) {}
-void FlowData::update_deallocations(size_t) {}
 
 TEST_GROUP(norm_decimal_integer_test) {};
 
index a9b8acc576092051624b14b17f2386bd345ba9e8..b235ad4f39c6b282acebd9895393bc297f58b808 100644 (file)
@@ -47,8 +47,6 @@ FlowData::~FlowData() = default;
 int DetectionEngine::queue_event(unsigned int, unsigned int) { return 0; }
 fd_status_t File_Decomp_StopFree(fd_session_t*) { return File_Decomp_OK; }
 uint32_t str_to_hash(const uint8_t *, size_t) { return 0; }
-void FlowData::update_allocations(size_t) {}
-void FlowData::update_deallocations(size_t) {}
 FlowData* Flow::get_flow_data(uint32_t) const { return nullptr; }
 }
 
index 0e58086bfcd7e4c720d29ab9256d0470ae0d5ffe..219330fe54ddba640d8f8cf9cbdf5f18a113cb7f 100755 (executable)
@@ -63,8 +63,6 @@ HttpJsNorm::HttpJsNorm(const HttpParaList::UriParam& uri_param_, int64_t normali
 HttpJsNorm::~HttpJsNorm() = default;
 void HttpJsNorm::configure() {}
 int64_t Parameter::get_int(char const*) { return 0; }
-void FlowData::update_allocations(size_t) {}
-void FlowData::update_deallocations(size_t) {}
 
 TEST_GROUP(http_inspect_uri_norm)
 {
index cce2fb34a36320a58f9c2cdde06f840752b5e33f..38cb35849dbf25f864a874bcabab335528a3f93d 100644 (file)
@@ -57,14 +57,7 @@ public:
     static void init();
 
     void reset()
-    {
-        ssn_data.session_data_reset();
-    }
-
-    size_t size_of() override
-    {
-        return sizeof(*this);
-    }
+    { ssn_data.session_data_reset(); }
 
 public:
     static unsigned inspector_id;
index b99403e7e979c115734ef2d33e1e1fa0e087c3ae..c1d1324b5abf03b9facf7aa1567984601b4f82e7 100644 (file)
@@ -175,9 +175,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     IMAPData session;
index c6ee14d4c95e9494134399c5b5c7f9ecd17c9fbb..a4355aa6058fbf2f5f80431934d96c00acd18dac 100644 (file)
@@ -6,7 +6,7 @@ to access certain protocol fields. This allows a user to write rules for
 Modbus packets without decoding the protocol with a series of ”content” and
 ”byte test” options.
 
-The preprocessor only evaluates PAF-flushed PDUs. If the rule options don't
+The inspector only evaluates PAF-flushed PDUs. If the rule options don't
 check for this, they'll fire on stale session data when the original packet
 goes through before flushing.
 
index 6f18a1bd10a0aab803029437e76779797ceb5fdf..542a550b3aa2dbf986ab7e7c8f502e7ec37ab371 100644 (file)
@@ -54,9 +54,6 @@ public:
         ssn_data.flags = 0;
     }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     modbus_session_data_t ssn_data;
index 10b6f59a505d9e54bc75d12655b32243f653bddf..f07fb92ab3f07e6ab6fca658aef2e1790311b528 100644 (file)
@@ -129,9 +129,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     POPData session;
index 7d1ffca449033129677553365359f2f247366baa..458bc102f534f19664724034792519a63bf8c209 100644 (file)
@@ -84,9 +84,6 @@ public:
     static void init()
     { inspector_id = FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     RpcSsnData session;
index 762be6e73534e8d529a170aa95f1de9070cdb19f..e6ce598843aa91151a9d080bfedc3deac1aae18a 100644 (file)
@@ -64,9 +64,6 @@ public:
         ssn_data.session_data_reset();
     }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     S7commplusSessionData ssn_data;
index cd995c0901760b7b7c1836a90a073840304ad25e..c4e23768d22fce57ba9d7c6c12fa0790864e6b25 100644 (file)
@@ -59,13 +59,11 @@ SipFlowData::~SipFlowData()
     FreeSipData(&session);
     assert(sip_stats.concurrent_sessions > 0);
     sip_stats.concurrent_sessions--;
-    memory::MemoryCap::update_deallocations(sizeof(SipFlowData));
 }
 
 static SIPData* SetNewSIPData(Packet* p)
 {
     SipFlowData* fd = new SipFlowData;
-    memory::MemoryCap::update_allocations(sizeof(SipFlowData));
     p->flow->set_flow_data(fd);
     return &fd->session;
 }
index 68b6c8947e221d9b7dc5d16938fcc93c1615ce8d..255e3e8c489fef39288c0d4c32dd54d125d8ff05 100644 (file)
@@ -45,9 +45,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     SIPData session;
index fa65fc4bd4b2611dee9958c8d492465d190aa7fe..594b8fdaefabc8774e1c881c5e01e8932dd2e622 100644 (file)
@@ -410,7 +410,6 @@ static int SIP_ignoreChannels(SIP_DialogData* dialog, Packet* p, SIP_PROTO_CONF*
         {
             Stream::ignore_flow(p, p->flow->pkt_type, p->get_ip_proto_next(), &mdataA->maddress,
                 mdataA->mport, &mdataB->maddress, mdataB->mport, SSN_DIR_BOTH, (new SipFlowData));
-            memory::MemoryCap::update_allocations(sizeof(SipFlowData));
         }
         sip_stats.ignoreChannels++;
         mdataA = mdataA->nextM;
@@ -529,7 +528,6 @@ static SIP_DialogData* SIP_addDialog(SIPMsg* sipMsg, SIP_DialogData* currDialog,
 
     sip_stats.dialogs++;
     dialog = (SIP_DialogData*)snort_calloc(sizeof(SIP_DialogData));
-    memory::MemoryCap::update_allocations(sizeof(SIP_DialogData));
 
     // Add to the head
     dialog->nextD = currDialog;
@@ -589,9 +587,10 @@ static int SIP_deleteDialog(SIP_DialogData* currDialog, SIP_DialogList* dList)
     }
     sip_freeMediaList(currDialog->mediaSessions);
     snort_free(currDialog);
-    memory::MemoryCap::update_deallocations(sizeof(SIP_DialogData));
+
     if ( dList->num_dialogs > 0)
         dList->num_dialogs--;
+
     return true;
 }
 
@@ -686,7 +685,6 @@ void sip_freeDialogs(SIP_DialogList* list)
         nextNode = curNode->nextD;
         sip_freeMediaList(curNode->mediaSessions);
         snort_free(curNode);
-        memory::MemoryCap::update_deallocations(sizeof(SIP_DialogData));
         curNode = nextNode;
     }
 }
index 4c33094065cda3d917438d4316cab78771f21db0..a78f4f42a4a409d7d03a6cb43b630eb0ffc6aebb 100644 (file)
@@ -505,7 +505,6 @@ static bool sip_body_parse(SIPMsg* msg, const char* buff, const char* end, const
 
     // Create a media session
     msg->mediaSession = (SIP_MediaSession*)snort_calloc(sizeof(SIP_MediaSession));
-    memory::MemoryCap::update_allocations(sizeof(SIP_MediaSession));
     const char* start = buff;
 
     /*
@@ -1130,7 +1129,6 @@ static int sip_parse_sdp_m(SIPMsg* msg, const char* start, const char* end)
         return SIP_PARSE_ERROR;
 
     mdata = (SIP_MediaData*)snort_calloc(sizeof(SIP_MediaData));
-    memory::MemoryCap::update_allocations(sizeof(SIP_MediaData));
     mdata->mport = (uint16_t)SnortStrtoul(spaceIndex + 1, &next, 10);
 
     if ((nullptr != next)&&('/'==next[0]))
@@ -1256,13 +1254,11 @@ void sip_freeMediaSession(SIP_MediaSession* mediaSession)
     {
         nextNode = curNode->nextM;
         snort_free(curNode);
-        memory::MemoryCap::update_deallocations(sizeof(SIP_MediaData));
         curNode = nextNode;
     }
     if (nullptr != mediaSession)
     {
         snort_free(mediaSession);
-        memory::MemoryCap::update_deallocations(sizeof(SIP_MediaSession));
     }
 }
 
index c032f34d9da517c8204e25ffb897177c1b420922..d5d4195038bcc94a4a70c0a0c4b7f736a2b2d507 100644 (file)
@@ -174,9 +174,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     SMTPData session;
index ff3e0b895ad8eb95f2eaee8c73b8ede68e8e2058..6753d0ef14bbaaf71a3a0f083aca373f693a3f5f 100644 (file)
@@ -106,9 +106,6 @@ public:
     static void init()
     { inspector_id = snort::FlowData::create_flow_data_id(); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
 public:
     static unsigned inspector_id;
     SSHData session;
index 5e56996152f799ba43b8525b976ec9eb4448bce0..3207e422bdcd3646ca5277dd42a246172a48a724 100644 (file)
@@ -33,9 +33,6 @@ public:
     static void init()
     { assign_ssl_inspector_id(snort::FlowData::create_flow_data_id()); }
 
-    size_t size_of() override
-    { return sizeof(*this); }
-
     SSLData& get_session() override
     { return session; }
 
index 14a9c55a0c16e2dd990601c9110f7e9774132a0d..6e5340baa89003098e525406ca8d1ab99014eaaf 100644 (file)
@@ -60,7 +60,7 @@ const PegInfo base_pegs[] =
     { CountType::SUM, "idle_prunes", " sessions pruned due to timeout" },
     { CountType::SUM, "excess_prunes", "sessions pruned due to excess" },
     { CountType::SUM, "uni_prunes", "uni sessions pruned" },
-    { CountType::SUM, "preemptive_prunes", "sessions pruned during preemptive pruning" },
+    { CountType::SUM, "preemptive_prunes", "sessions pruned during preemptive pruning (deprecated)" },
     { CountType::SUM, "memcap_prunes", "sessions pruned due to memcap" },
     { CountType::SUM, "ha_prunes", "sessions pruned by high availability sync" },
     { CountType::SUM, "stale_prunes", "sessions pruned due to stale connection" },
@@ -90,7 +90,7 @@ void base_prep()
     stream_base_stats.timeout_prunes = flow_con->get_prunes(PruneReason::IDLE);
     stream_base_stats.excess_prunes = flow_con->get_prunes(PruneReason::EXCESS);
     stream_base_stats.uni_prunes = flow_con->get_prunes(PruneReason::UNI);
-    stream_base_stats.preemptive_prunes = flow_con->get_prunes(PruneReason::PREEMPTIVE);
+    stream_base_stats.preemptive_prunes = flow_con->get_prunes(PruneReason::MEMCAP);
     stream_base_stats.memcap_prunes = flow_con->get_prunes(PruneReason::MEMCAP);
     stream_base_stats.ha_prunes = flow_con->get_prunes(PruneReason::HA);
     stream_base_stats.stale_prunes = flow_con->get_prunes(PruneReason::STALE);
index 14a909dbf14a4399ba98464569358198112e55c5..1cfd81c7d249fbe47cb8beea6c5cb49956377d54 100644 (file)
@@ -44,10 +44,10 @@ static THREAD_LOCAL ProfileStats file_ssn_stats;
 //-------------------------------------------------------------------------
 
 FileSession::FileSession(Flow* f) : Session(f)
-{ memory::MemoryCap::update_allocations(sizeof(*this)); }
+{ }
 
 FileSession::~FileSession()
-{ memory::MemoryCap::update_deallocations(sizeof(*this)); }
+{ }
 
 bool FileSession::setup(Packet*)
 {
index 235fcf02c404f4b3c9bb88e789b3fb37fa6080da..8900b3cfd051b91c6740649ab4d71b3ebc1abc37 100644 (file)
@@ -185,10 +185,10 @@ static int ProcessIcmpUnreach(Packet* p)
 //-------------------------------------------------------------------------
 
 IcmpSession::IcmpSession(Flow* f) : Session(f)
-{ memory::MemoryCap::update_allocations(sizeof(*this)); }
+{ }
 
 IcmpSession::~IcmpSession()
-{ memory::MemoryCap::update_deallocations(sizeof(*this)); }
+{ }
 
 bool IcmpSession::setup(Packet*)
 {
index b5c2eb5de448e41f8845b7bd8d00c0549cbb7174..e2322e7c31d00ec998df938e9cf8414757b1a44c 100644 (file)
@@ -137,7 +137,6 @@ struct Fragment
     {
         delete[] fptr;
         ip_stats.nodes_released++;
-        memory::MemoryCap::update_deallocations(sizeof(*this) + flen);
     }
 
     uint8_t* data = nullptr;    /* ptr to adjusted start position */
@@ -157,7 +156,6 @@ private:
     inline void init(uint16_t flen, const uint8_t* fptr, int ord)
     {
         assert(flen > 0);
-        memory::MemoryCap::update_allocations(sizeof(*this) + flen);
 
         this->flen = flen;
         this->fptr = new uint8_t[flen];
index 61a203987c50b908fedede91c77bd04d54bab2e1..988c25d5278d2307d12b0aeb2a43346524f6cfb2 100644 (file)
@@ -130,10 +130,10 @@ static inline void update_session(Packet* p, Flow* lws)
 //-------------------------------------------------------------------------
 
 IpSession::IpSession(Flow* f) : Session(f)
-{ memory::MemoryCap::update_allocations(sizeof(*this)); }
+{ }
 
 IpSession::~IpSession()
-{ memory::MemoryCap::update_deallocations(sizeof(*this)); }
+{ }
 
 void IpSession::clear()
 {
index 70e715500b3b5b0cc760bf9195f22a95d126b3bc..23f820cfbd654e230308dd26858342b6bf75ebe4 100644 (file)
@@ -373,10 +373,12 @@ void Stream::handle_timeouts(bool idle)
     TcpStreamTracker::release_held_packets(cur_time, max_remove);
 }
 
-void Stream::prune_flows()
+bool Stream::prune_flows()
 {
-    if ( flow_con && !FlowCache::is_pruning_in_progress())
-        flow_con->prune_one(PruneReason::MEMCAP, false);
+    if ( !flow_con )
+        return false;
+
+    return flow_con->prune_one(PruneReason::MEMCAP, false);
 }
 
 //-------------------------------------------------------------------------
index e99007a929822308946304daee938ab30320c4ca..f16b5c05de08c95dcb7a3be684b69832b49ea632 100644 (file)
@@ -77,7 +77,7 @@ public:
     static void purge_flows();
 
     static void handle_timeouts(bool idle);
-    static void prune_flows();
+    static bool prune_flows();
     static bool expected_flow(Flow*, Packet*);
 
     // Looks in the flow cache for flow session with specified key and returns
index 67f4b43d667777741710ffd34daadec750acfad2..c4d9110fb8ffcf66e2b12123f18f7f1e1672599b 100644 (file)
@@ -57,7 +57,6 @@ void TcpSegmentNode::clear()
     {
         TcpSegmentNode* tsn = reserved;
         reserved = reserved->next;
-        memory::MemoryCap::update_deallocations(sizeof(*tsn) + tsn->size);
         tcpStats.mem_in_use -= tsn->size;
         snort_free(tsn);
     }
@@ -85,7 +84,6 @@ TcpSegmentNode* TcpSegmentNode::create(
 #endif
     {
         size_t size = sizeof(*tsn) + len;
-        memory::MemoryCap::update_allocations(size);
         tsn = (TcpSegmentNode*)snort_alloc(size);
         tsn->size = len;
         tcpStats.mem_in_use += len;
@@ -124,7 +122,6 @@ void TcpSegmentNode::term()
     else
 #endif
     {
-        memory::MemoryCap::update_deallocations(sizeof(*this) + size);
         tcpStats.mem_in_use -= size;
         snort_free(this);
     }
index 38133f6db74ac807181749d85ccb8468f903aa02..2eadf2d145e0a1e30f25e7bae488a839e04310ef 100644 (file)
@@ -86,14 +86,11 @@ TcpSession::TcpSession(Flow* f) : TcpStreamSession(f)
     client.session = this;
     server.session = this;
     tcpStats.instantiated++;
-
-    memory::MemoryCap::update_allocations(sizeof(*this));
 }
 
 TcpSession::~TcpSession()
 {
     clear_session(true, false, false);
-    memory::MemoryCap::update_deallocations(sizeof(*this));
 }
 
 bool TcpSession::setup(Packet*)
index 1bde9321ba326d7b4e0428991c7970a14a446f9a..d370b008a74926b673834e17c5ebd9aa1b64ba47 100644 (file)
@@ -634,10 +634,6 @@ bool TcpStreamTracker::set_held_packet(Packet* p)
     if ( held_packet != null_iterator )
         return false;
 
-    // Temporarily increase memcap until message is finalized in case
-    // DAQ makes a copy of the data buffer.
-    memory::MemoryCap::update_allocations(daq_msg_get_data_len(p->daq_msg));
-
     held_packet = hpq->append(p->daq_msg, p->ptrs.tcph->seq(), *this);
     held_pkt_seq = p->ptrs.tcph->seq();
 
@@ -684,7 +680,6 @@ void TcpStreamTracker::finalize_held_packet(Packet* cp)
     if ( held_packet != null_iterator )
     {
         DAQ_Msg_h msg = held_packet->get_daq_msg();
-        uint32_t msglen = daq_msg_get_data_len(msg);
 
         if ( cp->active->packet_was_dropped() )
         {
@@ -709,8 +704,6 @@ void TcpStreamTracker::finalize_held_packet(Packet* cp)
             tcp_session->held_packet_dir = SSN_DIR_NONE;
         }
 
-        memory::MemoryCap::update_deallocations(msglen);
-
         hpq->erase(held_packet);
         held_packet = null_iterator;
         tcpStats.current_packets_held--;
@@ -725,7 +718,6 @@ void TcpStreamTracker::finalize_held_packet(Flow* flow)
     if ( held_packet != null_iterator )
     {
         DAQ_Msg_h msg = held_packet->get_daq_msg();
-        uint32_t msglen = daq_msg_get_data_len(msg);
 
         if ( (flow->session_state & STREAM_STATE_BLOCK_PENDING) ||
              (flow->ssn_state.session_flags & SSNFLAG_BLOCK) )
@@ -742,8 +734,6 @@ void TcpStreamTracker::finalize_held_packet(Flow* flow)
             tcpStats.held_packets_passed++;
         }
 
-        memory::MemoryCap::update_deallocations(msglen);
-
         hpq->erase(held_packet);
         held_packet = null_iterator;
         tcpStats.current_packets_held--;
index 1b60005a8b615583e3c26efe1fac3b8b194fbe21..968fbbf6b84bc0354b597477b9c5f6ba9bafd29b 100644 (file)
@@ -104,10 +104,10 @@ static int ProcessUdp(Flow* lwssn, Packet* p, StreamUdpConfig*)
 //-------------------------------------------------------------------------
 
 UdpSession::UdpSession(Flow* f) : Session(f)
-{ memory::MemoryCap::update_allocations(sizeof(*this)); }
+{ }
 
 UdpSession::~UdpSession()
-{ memory::MemoryCap::update_deallocations(sizeof(*this)); }
+{ }
 
 bool UdpSession::setup(Packet* p)
 {
index e49a66f4274a42e0f0c7c02f2d013efeca2292d9..731fa16b31fa193218e4e93c8faebc1c05cd05dc 100644 (file)
@@ -1,6 +1,6 @@
 This directory contains the implementation of user session tracking and
 processing functions.  When the source for a flow provides a TCP payload,
-e.g. a socket connection, then the base Stream preprocessor delegates
+e.g. a socket connection, then the base Stream inspector delegates
 handling of the packets on that flow to this module.
 
 The StreamUser class is implemented as a subclass of Inspector and provides
index cf53e6314691ab644d554c28fb925b932edbe42a..a5af591127f54b61abca0dc9ad341757085e3819 100644 (file)
@@ -57,7 +57,6 @@ UserSegment* UserSegment::init(const uint8_t* p, unsigned n)
     unsigned bucket = (n > BUCKET) ? n : BUCKET;
     unsigned size = sizeof(UserSegment) + bucket -1;
 
-    memory::MemoryCap::update_allocations(size);
     UserSegment* us = (UserSegment*)snort_alloc(size);
 
     us->size = size;
@@ -71,7 +70,6 @@ UserSegment* UserSegment::init(const uint8_t* p, unsigned n)
 
 void UserSegment::term(UserSegment* us)
 {
-    memory::MemoryCap::update_deallocations(us->size);
     snort_free(us);
 }
 
@@ -423,10 +421,10 @@ void UserSession::restart(Packet* p)
 //-------------------------------------------------------------------------
 
 UserSession::UserSession(Flow* f) : Session(f)
-{ memory::MemoryCap::update_allocations(sizeof(*this)); }
+{ }
 
 UserSession::~UserSession()
-{ memory::MemoryCap::update_deallocations(sizeof(*this)); }
+{ }
 
 bool UserSession::setup(Packet*)
 {
index 047ccbd0ae861be2eb2a103a05f56f7e474bd3ff..fafba6708ecd6591f9cdd9608ee31b7968ee8052 100644 (file)
@@ -33,6 +33,7 @@
 #include "helpers/process.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
+#include "memory/memory_cap.h"
 #include "managers/module_manager.h"
 #include "packet_io/active.h"
 #include "packet_io/sfdaq.h"
@@ -265,6 +266,7 @@ void DropStats(ControlConn* ctrlcon)
 void PrintStatistics()
 {
     DropStats();
+    memory::MemoryCap::print(SnortConfig::log_verbose(), false);
     timing_stats();
 
     // FIXIT-L can do flag saving with RAII (much cleaner)