appid_inspector.h
appid_module.cc
appid_module.h
+ appid_pegs.h
appid_stats.cc
appid_stats.h
app_info_table.cc
#include "log/messages.h"
#include "main/analyzer_command.h"
+#include "main/snort.h"
#include "profiler/profiler.h"
#include "utils/util.h"
#include "app_info_table.h"
#include "appid_debug.h"
#include "appid_peg_counts.h"
+#include "service_state.h"
using namespace snort;
using namespace std;
{ CountType::SUM, "ignored_packets", "count of packets ignored" },
{ CountType::SUM, "total_sessions", "count of sessions created" },
{ CountType::SUM, "appid_unknown", "count of sessions where appid could not be determined" },
- { CountType::END, nullptr, nullptr},
+ { CountType::SUM, "service_cache_prunes", "number of times the service cache was pruned" },
+ { CountType::SUM, "service_cache_adds", "number of times an entry was added to the service cache" },
+ { CountType::SUM, "service_cache_removes", "number of times an item was removed from the service cache" },
+ { CountType::END, nullptr, nullptr },
};
AppIdModule::AppIdModule() :
return true;
}
-bool AppIdModule::end(const char*, int, SnortConfig*)
+bool AppIdModule::end(const char*, int, SnortConfig* sc)
{
assert(config);
+ appid_rrt.memcap = config->memcap;
+ if ( Snort::is_reloading() )
+ sc->register_reload_resource_tuner(appid_rrt);
+
if ( !config->app_detector_dir )
{
ParseWarning(WARN_CONF,
{
AppIdPegCounts::print();
}
+
+bool AppIdReloadTuner::tinit()
+{
+ return AppIdServiceState::initialize(memcap);
+}
+
+bool AppIdReloadTuner::tune_resources(unsigned work_limit)
+{
+ return AppIdServiceState::prune(memcap, work_limit);
+}
#include <vector>
#include "appid_config.h"
+#include "appid_pegs.h"
#include "framework/module.h"
extern THREAD_LOCAL snort::ProfileStats appid_perf_stats;
#define MOD_NAME "appid"
#define MOD_HELP "application and service identification"
-struct AppIdStats
+
+class AppIdReloadTuner : public snort::ReloadResourceTuner
{
- PegCount packets;
- PegCount processed_packets;
- PegCount ignored_packets;
- PegCount total_sessions;
- PegCount appid_unknown;
+public:
+ AppIdReloadTuner() = default;
+
+ bool tinit() override;
+ bool tune_packet_context() override
+ {
+ return tune_resources( max_work );
+ }
+ bool tune_idle_context() override
+ {
+ return tune_resources( max_work_idle );
+ }
+
+ friend class AppIdModule;
+
+private:
+ size_t memcap = 0;
+
+ bool tune_resources(unsigned work_limit);
};
extern THREAD_LOCAL AppIdStats appid_stats;
private:
AppIdModuleConfig* config;
+ AppIdReloadTuner appid_rrt;
};
#endif
-
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2019-2019 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.
+//--------------------------------------------------------------------------
+
+// appid_pegs.h author Silviu Minut <sminut@cisco.com>
+
+#ifndef APPID_PEGS_H
+#define APPID_PEGS_H
+
+#include "framework/counts.h"
+
+struct AppIdStats
+{
+ PegCount packets;
+ PegCount processed_packets;
+ PegCount ignored_packets;
+ PegCount total_sessions;
+ PegCount appid_unknown;
+ PegCount service_cache_prunes;
+ PegCount service_cache_adds;
+ PegCount service_cache_removes;
+};
+
+#endif
return nullptr;
}
-#endif
+bool AppIdReloadTuner::tinit() { return false; }
+bool AppIdReloadTuner::tune_resources(unsigned int)
+{
+ return true;
+}
+
+#endif
}
-void AppIdServiceState::initialize(size_t memcap)
+bool AppIdServiceState::initialize(size_t memcap)
{
- service_state_cache = new MapList(memcap);
+ if ( !service_state_cache )
+ service_state_cache = new MapList(memcap);
+ else
+ {
+ bool have_work = memcap < service_state_cache->memcap;
+ service_state_cache->memcap = memcap;
+ return have_work;
+ }
+ return false;
}
void AppIdServiceState::clean()
}
#endif
}
+
+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;
+}
#include "utils/cpp_macros.h"
#include "utils/util.h"
+#include "appid_pegs.h"
#include "service_plugins/service_discovery.h"
class ServiceDetector;
class AppIdServiceState
{
public:
- static void initialize(size_t memcap = 0);
+ static bool initialize(size_t memcap);
static void clean();
static ServiceDiscoveryState* add(const snort::SfIp*, IpProtocol, uint16_t port, bool decrypted, bool do_touch = false);
static ServiceDiscoveryState* get(const snort::SfIp*, IpProtocol, uint16_t port, bool decrypted, bool do_touch = false);
static void check_reset(AppIdSession& asd, const snort::SfIp* ip, uint16_t port);
static void dump_stats();
+
+ static bool prune(size_t max_memory = 0, size_t num_items = -1u);
};
PADDING_GUARD_END
+extern THREAD_LOCAL AppIdStats appid_stats;
+
class MapList
{
public:
q.emplace_back(it);
mem_used += sz;
ss->qptr = --q.end(); // remember our place in the queue
+ appid_stats.service_cache_adds++;
if ( mem_used > memcap )
remove( q.front() );
bool remove(Map_t::iterator it)
{
- if ( it != m.end() )
+ if ( it != m.end() && !m.empty() )
{
+ assert( mem_used >= sz );
mem_used -= sz;
q.erase(it->second->qptr); // remove from queue
delete it->second;
m.erase(it); // then from cache
+ appid_stats.service_cache_removes++;
+
return true;
}
return false;
}
+ bool prune(size_t max_memory = 0, size_t num_items = -1u)
+ {
+ if ( max_memory == 0 )
+ max_memory = memcap;
+
+ size_t i=0;
+ while ( mem_used > max_memory && i++ < num_items )
+ remove( q.front() );
+
+ appid_stats.service_cache_prunes++;
+
+ return mem_used <= max_memory;
+ }
+
Map_t::iterator find(const Key_t& k)
{
return m.find(k);
// how much memory we add when we put an SDS in the cache:
static const size_t sz;
+ friend class AppIdServiceState;
+
private:
Map_t m;
Queue_t q;
return APP_ID_UNKNOWN;
}
+bool AppIdReloadTuner::tinit() { return false; }
+
+bool AppIdReloadTuner::tune_resources(unsigned int)
+{
+ return true;
+}
+
TEST_GROUP(appid_discovery_tests)
{
void setup() override
return nullptr;
}
+bool AppIdServiceState::prune(size_t, size_t)
+{
+ return true;
+}
+
+bool AppIdReloadTuner::tinit() { return false; }
+
+bool AppIdReloadTuner::tune_resources(unsigned int)
+{
+ return true;
+}
+
void ServiceDiscoveryState::set_service_id_valid(ServiceDetector*) { }
// Stubs for service_plugins/service_discovery.h