From: Mike Stepanek (mstepane) Date: Tue, 7 Jan 2020 15:18:41 +0000 (+0000) Subject: Merge pull request #1917 in SNORT/snort3 from ~MASHASAN/snort3:port_scan_rrt to master X-Git-Tag: 3.0.0-268~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e907b987285b6902ccdff723ad29701d1b3bb933;p=thirdparty%2Fsnort3.git Merge pull request #1917 in SNORT/snort3 from ~MASHASAN/snort3:port_scan_rrt to master Squashed commit of the following: commit 3c72a2cc66a715b931ad2a07dea63d50503acd70 Author: Masud Hasan Date: Sat Jan 4 18:40:53 2020 -0500 port_scan: Supporting reload config when memcap changes --- diff --git a/src/hash/xhash.cc b/src/hash/xhash.cc index 72338cbb7..55c42f5ba 100644 --- a/src/hash/xhash.cc +++ b/src/hash/xhash.cc @@ -1057,7 +1057,7 @@ static inline int xhash_delete_free_node(XHash *t) /*! * Unlink and free an ANR node or the oldest node, if ANR is empty - * behavior is undefined if t->usrfree is set + * behavior is undefined if either t->anrfree or t->usrfree is set * * t XHash table pointer * @@ -1118,7 +1118,7 @@ int xhash_free_overallocations(XHash* t, unsigned work_limit, unsigned* num_free ++*num_freed; } - return (t->mc.memcap > t->mc.memused) ? XHASH_OK : XHASH_PENDING; + return (t->mc.memcap >= t->mc.memused) ? XHASH_OK : XHASH_PENDING; } /*! diff --git a/src/hash/xhash.h b/src/hash/xhash.h index ff530e383..d5ec8b8d4 100644 --- a/src/hash/xhash.h +++ b/src/hash/xhash.h @@ -139,8 +139,8 @@ inline unsigned xhash_overhead_blocks(XHash* t) { return t->overhead_blocks; } // Get the amount of space required to allocate a new node in the xhash t. -inline size_t xhash_required_mem(XHash *t) -{ return sizeof(XHashNode) + t->pad + t->keysize + t->datasize; } +constexpr size_t xhash_required_mem(XHash *t) +{ return sizeof(XHashNode) + t->pad + t->keysize + t->datasize + sizeof(long); } SO_PUBLIC int xhash_free_anr_lru(XHash* t); SO_PUBLIC void* xhash_mru(XHash* t); diff --git a/src/network_inspectors/appid/service_state.cc b/src/network_inspectors/appid/service_state.cc index 723a94576..ef3889b67 100644 --- a/src/network_inspectors/appid/service_state.cc +++ b/src/network_inspectors/appid/service_state.cc @@ -278,8 +278,7 @@ void AppIdServiceState::dump_stats() bool AppIdServiceState::prune(size_t max_memory, size_t num_items) { - bool done = false; if ( service_state_cache ) - done = service_state_cache->prune(max_memory, num_items); - return done; + return service_state_cache->prune(max_memory, num_items); + return true; } diff --git a/src/network_inspectors/perf_monitor/perf_monitor.cc b/src/network_inspectors/perf_monitor/perf_monitor.cc index 0b5e913d0..df2425a16 100644 --- a/src/network_inspectors/perf_monitor/perf_monitor.cc +++ b/src/network_inspectors/perf_monitor/perf_monitor.cc @@ -277,9 +277,7 @@ bool PerfMonReloadTuner::tune_resources(unsigned work_limit) return (result == XHASH_OK); } else - { - return false; - } + return true; } void PerfMonitor::tterm() diff --git a/src/network_inspectors/port_scan/port_scan.cc b/src/network_inspectors/port_scan/port_scan.cc index bd3f4de69..e9b47e59e 100644 --- a/src/network_inspectors/port_scan/port_scan.cc +++ b/src/network_inspectors/port_scan/port_scan.cc @@ -36,7 +36,7 @@ using namespace snort; -THREAD_LOCAL SimpleStats spstats; +THREAD_LOCAL PsPegStats spstats; THREAD_LOCAL ProfileStats psPerfStats; static void make_port_scan_info(Packet* p, PS_PROTO* proto) @@ -441,7 +441,7 @@ void PortScan::eval(Packet* p) if ( p->packet_flags & PKT_REBUILT_STREAM ) return; - ++spstats.total_packets; + ++spstats.packets; PS_PKT ps_pkt(p); ps_detect(&ps_pkt); diff --git a/src/network_inspectors/port_scan/ps_detect.cc b/src/network_inspectors/port_scan/ps_detect.cc index e2f48a073..9d7587762 100644 --- a/src/network_inspectors/port_scan/ps_detect.cc +++ b/src/network_inspectors/port_scan/ps_detect.cc @@ -44,6 +44,7 @@ #include "utils/stats.h" #include "ps_inspect.h" +#include "ps_pegs.h" using namespace snort; @@ -57,6 +58,7 @@ struct PS_HASH_KEY PADDING_GUARD_END static THREAD_LOCAL XHash* portscan_hash = nullptr; +extern THREAD_LOCAL PsPegStats spstats; PS_PKT::PS_PKT(Packet* p) { @@ -120,10 +122,14 @@ void ps_cleanup() unsigned ps_node_size() { return sizeof(PS_HASH_KEY) + sizeof(PS_TRACKER); } -void ps_init_hash(unsigned long memcap) +bool ps_init_hash(unsigned long memcap) { if ( portscan_hash ) - return; + { + bool need_pruning = (memcap < portscan_hash->mc.memused); + portscan_hash->mc.memcap = memcap; + return need_pruning; + } int rows = memcap / ps_node_size(); @@ -132,6 +138,19 @@ void ps_init_hash(unsigned long memcap) if ( !portscan_hash ) FatalError("Failed to initialize portscan hash table.\n"); + + return false; +} + +bool ps_prune_hash(unsigned work_limit) +{ + if ( !portscan_hash ) + return true; + + unsigned num_pruned = 0; + int result = xhash_free_overallocations(portscan_hash, work_limit, &num_pruned); + spstats.reload_prunes += num_pruned; + return result != XHASH_PENDING; } void ps_reset() @@ -282,9 +301,14 @@ static PS_TRACKER* ps_tracker_get(PS_HASH_KEY* key) if ( ht ) return ht; + auto prev_count = portscan_hash->count; if ( xhash_add(portscan_hash, (void*)key, nullptr) != XHASH_OK ) return nullptr; + ++spstats.trackers; + if ( prev_count == portscan_hash->count ) + ++spstats.alloc_prunes; + ht = (PS_TRACKER*)xhash_mru(portscan_hash); if ( ht ) diff --git a/src/network_inspectors/port_scan/ps_detect.h b/src/network_inspectors/port_scan/ps_detect.h index 9a972e568..587ddcd5d 100644 --- a/src/network_inspectors/port_scan/ps_detect.h +++ b/src/network_inspectors/port_scan/ps_detect.h @@ -164,7 +164,8 @@ void ps_cleanup(); void ps_reset(); unsigned ps_node_size(); -void ps_init_hash(unsigned long); +bool ps_init_hash(unsigned long); +bool ps_prune_hash(unsigned); int ps_detect(PS_PKT*); #endif diff --git a/src/network_inspectors/port_scan/ps_module.cc b/src/network_inspectors/port_scan/ps_module.cc index b78f9d017..fca3746f0 100644 --- a/src/network_inspectors/port_scan/ps_module.cc +++ b/src/network_inspectors/port_scan/ps_module.cc @@ -24,6 +24,7 @@ #include "ps_module.h" #include "log/messages.h" +#include "main/snort.h" #include @@ -199,7 +200,7 @@ ProfileStats* PortScanModule::get_profile() const { return &psPerfStats; } const PegInfo* PortScanModule::get_pegs() const -{ return simple_pegs; } +{ return ps_module_pegs; } PegCount* PortScanModule::get_counts() const { return (PegCount*)&spstats; } @@ -325,25 +326,14 @@ bool PortScanModule::set(const char* fqn, Value& v, SnortConfig*) return true; } -bool PortScanModule::end(const char* fqn, int, SnortConfig*) +bool PortScanModule::end(const char* fqn, int, SnortConfig* sc) { - if (strcmp(fqn, "port_scan") == 0) + if ( strcmp(fqn, "port_scan") == 0 ) { - static size_t saved_memcap = 0; - - if (saved_memcap != 0 ) - { - if (config->memcap != saved_memcap) - { - ReloadError("Changing port_scan.memcap requires a restart\n"); - } - } - else - { - saved_memcap = config->memcap; - } + ps_rrt.memcap = config->memcap; + if ( Snort::is_reloading() ) + sc->register_reload_resource_tuner(ps_rrt); } - return true; } @@ -397,4 +387,3 @@ PortscanConfig* PortScanModule::get_data() config = nullptr; return tmp; } - diff --git a/src/network_inspectors/port_scan/ps_module.h b/src/network_inspectors/port_scan/ps_module.h index e3f95f578..76cb79b6d 100644 --- a/src/network_inspectors/port_scan/ps_module.h +++ b/src/network_inspectors/port_scan/ps_module.h @@ -22,7 +22,9 @@ #define PS_MODULE_H #include "framework/module.h" +#include "main/snort_config.h" #include "ps_detect.h" +#include "ps_pegs.h" #define PS_NAME "port_scan" #define PS_HELP "detect various ip, icmp, tcp, and udp port or protocol scans" @@ -129,8 +131,27 @@ "open port" //------------------------------------------------------------------------- +// Reload resource tuning +//------------------------------------------------------------------------- + +class PortScanReloadTuner : public snort::ReloadResourceTuner +{ +public: + bool tinit() override + { return ps_init_hash(memcap); } + + bool tune_idle_context() override + { return ps_prune_hash(max_work_idle); } + + bool tune_packet_context() override + { return ps_prune_hash(max_work); } -extern THREAD_LOCAL SimpleStats spstats; + size_t memcap = 0; +}; + +//------------------------------------------------------------------------- + +extern THREAD_LOCAL PsPegStats spstats; extern THREAD_LOCAL snort::ProfileStats psPerfStats; struct PortscanConfig; @@ -162,9 +183,8 @@ public: private: PS_ALERT_CONF* get_alert_conf(const char* fqn); - -private: PortscanConfig* config; + PortScanReloadTuner ps_rrt; }; #endif diff --git a/src/network_inspectors/port_scan/ps_pegs.h b/src/network_inspectors/port_scan/ps_pegs.h new file mode 100644 index 000000000..0b607b944 --- /dev/null +++ b/src/network_inspectors/port_scan/ps_pegs.h @@ -0,0 +1,44 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// ps_pegs.h author Masud Hasan + +#ifndef PS_PEGS_H +#define PS_PEGS_H + +#include "framework/counts.h" +#include "main/snort_types.h" + +static const PegInfo ps_module_pegs[] = +{ + { CountType::SUM, "packets", "number of packets processed by port scan" }, + { CountType::SUM, "trackers", "number of trackers allocated by port scan" }, + { CountType::SUM, "alloc_prunes", "number of trackers pruned on allocation of new tracking" }, + { CountType::SUM, "reload_prunes", "number of trackers pruned on reload due to reduced memcap" }, + { CountType::END, nullptr, nullptr }, +}; + +struct PsPegStats +{ + PegCount packets; + PegCount trackers; + PegCount alloc_prunes; + PegCount reload_prunes; +}; + +#endif