]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1917 in SNORT/snort3 from ~MASHASAN/snort3:port_scan_rrt to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 7 Jan 2020 15:18:41 +0000 (15:18 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 7 Jan 2020 15:18:41 +0000 (15:18 +0000)
Squashed commit of the following:

commit 3c72a2cc66a715b931ad2a07dea63d50503acd70
Author: Masud Hasan <mashasan@cisco.com>
Date:   Sat Jan 4 18:40:53 2020 -0500

    port_scan: Supporting reload config when memcap changes

src/hash/xhash.cc
src/hash/xhash.h
src/network_inspectors/appid/service_state.cc
src/network_inspectors/perf_monitor/perf_monitor.cc
src/network_inspectors/port_scan/port_scan.cc
src/network_inspectors/port_scan/ps_detect.cc
src/network_inspectors/port_scan/ps_detect.h
src/network_inspectors/port_scan/ps_module.cc
src/network_inspectors/port_scan/ps_module.h
src/network_inspectors/port_scan/ps_pegs.h [new file with mode: 0644]

index 72338cbb7a0ffd8e941f73b7fcf428bb5b3d72a5..55c42f5bae3f3b89a02f294daa7fe5a977e5a16d 100644 (file)
@@ -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;
 }
 
 /*!
index ff530e383159eb716468812f8d893d0575309a83..d5ec8b8d4aafffe0a0f8a67897f38d10055fb8dc 100644 (file)
@@ -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);
index 723a945762562a86a7fb70a1837995707c061a3d..ef3889b67643ac79944b99b04ae04fd3788192a6 100644 (file)
@@ -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;
 }
index 0b5e913d09d96d6197d979aabe4bb7ac41154f4e..df2425a16a4b7ff23c2985e311cc35be9006f74a 100644 (file)
@@ -277,9 +277,7 @@ bool PerfMonReloadTuner::tune_resources(unsigned work_limit)
         return (result == XHASH_OK);
     }
     else
-    {
-        return false;
-    }
+        return true;
 }
 
 void PerfMonitor::tterm()
index bd3f4de69cf8d306775e98b7ac6428aac8ca1d66..e9b47e59e73941d841c49658cb2a186d3967cecf 100644 (file)
@@ -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);
index e2f48a07380192c7b87b76598e4d11b374e2cdf1..9d7587762ae1d0462a117712586250f711a2734a 100644 (file)
@@ -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 )
index 9a972e5683c1988bc9bae38d654b20f1cfd228e2..587ddcd5d79bbb4394e2f3e9831adebbbc9a1f89 100644 (file)
@@ -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
index b78f9d017f944e0f63905d22dd0a49ed3c6ac1b9..fca3746f041c7810e3bd40ac5cfe655fdd769f86 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "ps_module.h"
 #include "log/messages.h"
+#include "main/snort.h"
 
 #include <cassert>
 
@@ -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;
 }
-
index e3f95f578dd8d52002b45493a8ff6e345413af56..76cb79b6d0f13b561d32068c26f1cd82920de8ca 100644 (file)
@@ -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"
     "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 (file)
index 0000000..0b607b9
--- /dev/null
@@ -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 <mashasan@cisco.com>
+
+#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