From: Masud Hasan (mashasan) Date: Tue, 26 Jan 2021 21:40:51 +0000 (+0000) Subject: Merge pull request #2693 in SNORT/snort3 from ~SMINUT/snort3:host_cache_rna to master X-Git-Tag: 3.1.1.0~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=37907c5b34f261e878a6d6318c96678d732868dc;p=thirdparty%2Fsnort3.git Merge pull request #2693 in SNORT/snort3 from ~SMINUT/snort3:host_cache_rna to master Squashed commit of the following: commit ec7f9504910ba29d2899c7669f833195b29fd6dd Author: Silviu Minut Date: Fri Jan 8 10:55:59 2021 -0500 rna: Minimize synchronization overhead Avoid some locks during network discovery in order to increase speed, by caching the host trackers locally in the RNAFlow, in a way in which the cached host trackers do not spill memory into the host cache during pruning. --- diff --git a/src/hash/lru_cache_shared.h b/src/hash/lru_cache_shared.h index 8e7c03c6e..905da594c 100644 --- a/src/hash/lru_cache_shared.h +++ b/src/hash/lru_cache_shared.h @@ -48,7 +48,8 @@ struct LruCacheSharedStats PegCount replaced = 0; // found entry and replaced it }; -template> +template, + typename Purgatory = std::vector>> class LruCacheShared { public: @@ -67,6 +68,7 @@ public: using Data = std::shared_ptr; using ValueType = Value; + using KeyType = Key; // Return data entry associated with key. If doesn't exist, return nullptr. Data find(const Key& key); @@ -108,12 +110,12 @@ public: // Remove entry associated with Key. // Returns true if entry existed, false otherwise. - bool remove(const Key& key); + virtual bool remove(const Key& key); // Remove entry associated with key and return removed data. // Returns true and copy of data if entry existed. Returns false if // entry did not exist. - bool remove(const Key& key, Data& data); + virtual bool remove(const Key& key, Data& data); const PegInfo* get_pegs() const { return lru_cache_shared_peg_names; } @@ -166,7 +168,7 @@ protected: // Caller must lock and unlock. Don't use this during snort reload for which // we need gradual pruning and size reduction via reload resource tuner. - void prune(std::vector& data) + void prune(Purgatory& data) { LruListIter list_iter; assert(data.empty()); @@ -182,8 +184,8 @@ protected: } }; -template -bool LruCacheShared::set_max_size(size_t newsize) +template +bool LruCacheShared::set_max_size(size_t newsize) { if (newsize == 0) return false; // Not allowed to set size to zero. @@ -191,7 +193,7 @@ bool LruCacheShared::set_max_size(size_t newsize) // Like with remove(), we need local temporary references to data being // deleted, to avoid race condition. This data needs to self-destruct // after the cache_lock does. - std::vector data; + Purgatory data; std::lock_guard cache_lock(cache_mutex); @@ -203,8 +205,8 @@ bool LruCacheShared::set_max_size(size_t newsize) return true; } -template -std::shared_ptr LruCacheShared::find(const Key& key) +template +std::shared_ptr LruCacheShared::find(const Key& key) { LruMapIter map_iter; std::lock_guard cache_lock(cache_mutex); @@ -222,14 +224,14 @@ std::shared_ptr LruCacheShared::find(const Key& key return map_iter->second->second; } -template -std::shared_ptr LruCacheShared::operator[](const Key& key) +template +std::shared_ptr LruCacheShared::operator[](const Key& key) { return find_else_create(key, nullptr); } -template -std::shared_ptr LruCacheShared:: +template +std::shared_ptr LruCacheShared:: find_else_create(const Key& key, bool* new_data) { LruMapIter map_iter; @@ -240,7 +242,7 @@ find_else_create(const Key& key, bool* new_data) // unlocking the cache_mutex, because the cache must be locked when we // return the data pointer (below), or else, some other thread might // delete it before we got a chance to return it. - std::vector tmp_data; + Purgatory tmp_data; std::lock_guard cache_lock(cache_mutex); @@ -270,13 +272,13 @@ find_else_create(const Key& key, bool* new_data) return data; } -template -bool LruCacheShared:: +template +bool LruCacheShared:: find_else_insert(const Key& key, std::shared_ptr& data, bool replace) { LruMapIter map_iter; - std::vector tmp_data; + Purgatory tmp_data; std::lock_guard cache_lock(cache_mutex); map_iter = map.find(key); @@ -311,9 +313,9 @@ find_else_insert(const Key& key, std::shared_ptr& data, bool replace) return false; } -template +template std::vector< std::pair> > -LruCacheShared::get_all_data() +LruCacheShared::get_all_data() { std::vector > vec; std::lock_guard cache_lock(cache_mutex); @@ -326,8 +328,8 @@ LruCacheShared::get_all_data() return vec; } -template -bool LruCacheShared::remove(const Key& key) +template +bool LruCacheShared::remove(const Key& key) { LruMapIter map_iter; @@ -367,8 +369,9 @@ bool LruCacheShared::remove(const Key& key) return true; } -template -bool LruCacheShared::remove(const Key& key, std::shared_ptr& data) +template +bool LruCacheShared::remove(const Key& key, + std::shared_ptr& data) { LruMapIter map_iter; diff --git a/src/host_tracker/host_cache.h b/src/host_tracker/host_cache.h index 9f4541cc7..4bc1508da 100644 --- a/src/host_tracker/host_cache.h +++ b/src/host_tracker/host_cache.h @@ -58,11 +58,13 @@ struct IpEqualTo } }; -template> -class LruCacheSharedMemcap : public LruCacheShared, public HostCacheInterface +template, + typename Purgatory = std::vector>> +class LruCacheSharedMemcap : public LruCacheShared, + public HostCacheInterface { public: - using LruBase = LruCacheShared; + using LruBase = LruCacheShared; using LruBase::cache_mutex; using LruBase::current_size; using LruBase::list; @@ -78,7 +80,7 @@ public: LruCacheSharedMemcap(const LruCacheSharedMemcap& arg) = delete; LruCacheSharedMemcap& operator=(const LruCacheSharedMemcap& arg) = delete; - LruCacheSharedMemcap(const size_t initial_size) : LruCacheShared(initial_size), + LruCacheSharedMemcap(const size_t sz) : LruCacheShared(sz), valid_id(invalid_id+1) {} size_t mem_size() override @@ -203,7 +205,7 @@ private: // to hold the pruned data until after the cache is unlocked. // Do not change the order of data and cache_lock, as the data must // self destruct after cache_lock. - std::vector data; + Purgatory data; std::lock_guard cache_lock(cache_mutex); LruBase::prune(data); } @@ -228,7 +230,55 @@ private: friend class TEST_host_cache_module_misc_Test; // for unit test }; -typedef LruCacheSharedMemcap HostCacheIp; + +class HTPurgatory +{ +public: + + ~HTPurgatory() + { + for (auto& ht : data) + { + ht->remove_flows(); + } + } + + bool empty() const { + return data.empty(); + } + + void emplace_back(std::shared_ptr& ht) + { + data.emplace_back(ht); + } + + std::vector> data; +}; + +typedef LruCacheSharedMemcap + HostCacheIpSpec; + +// Since the LruCacheShared and LruCacheSharedMemcap templates make no +// assumptions about the item, we have to derive our host cache +// from the specialization, if we want to make use of things within the item. +class HostCacheIp : public HostCacheIpSpec +{ +public: + HostCacheIp(const size_t initial_size) : HostCacheIpSpec(initial_size) { } + + bool remove(const KeyType& key) + { + LruBase::Data data; + return remove(key, data); + } + + bool remove(const KeyType& key, LruBase::Data& data) + { + bool out = LruBase::remove(key, data); + data->remove_flows(); + return out; + } +}; extern SO_PUBLIC HostCacheIp host_cache; diff --git a/src/host_tracker/host_tracker.cc b/src/host_tracker/host_tracker.cc index a887d5ef1..74ee2941b 100644 --- a/src/host_tracker/host_tracker.cc +++ b/src/host_tracker/host_tracker.cc @@ -24,10 +24,13 @@ #include +#include "flow/flow.h" +#include "network_inspectors/rna/rna_flow.h" +#include "utils/util.h" + #include "host_cache.h" #include "host_cache_allocator.cc" #include "host_tracker.h" -#include "utils/util.h" using namespace snort; using namespace std; @@ -1025,6 +1028,52 @@ HostClient HostTracker::find_or_add_client(AppId id, const char* version, AppId return clients.back(); } +void HostTracker::add_flow(RNAFlow* fd) +{ + lock_guard lck(flows_lock); + flows.insert(fd); +} + +void HostTracker::remove_flow(RNAFlow* fd) +{ + lock_guard lck(flows_lock); + flows.erase(fd); +} + +void HostTracker::remove_flows() +{ + // To lock, or not to lock? That is the question! + // + // The only way we get here is from LRU::update(), called by the allocator. + // That is, we only get here from a HT::add_<> operation. All of those + // operations lock the HT, so the HT is already locked when we get here. + // Also, none of those operations modify the HT::flows set. So we should + // not lock the HT (because we'd cause a deadlock), nor do we need to + // (because there's no contention on HT::flows from those adds). + // + // However, this HT could be part of a different rna flow, which could + // go out of existence exactly at the time when this thread modifies + // the HT::flows set. The rna flow destructor calls on this + // HT::remove_flow(), which does modify HT::flows. The for loop itself + // does not modify the HT::flows set, but flows.clear() does - whether + // or not we call it here explicitly. We, therefore, need to protect the + // HT::flows() array with a lock on this host_tracker_lock. + // + // We have identified two situations with opposite requirements: + // one requires locking, the other requires not locking. + // + // Now, note that the thread contention is not on the host tracker itself, + // but on the HT::flows set. This means we may not lock the HT here, + // to avoid the deadlock from the first case, but we SHOULD lock on + // a different mutex to protect the HT::flows set. + lock_guard lck(flows_lock); + for (auto& rna_flow : flows) + { + rna_flow->clear_ht(*this); + } + flows.clear(); +} + HostApplicationInfo::HostApplicationInfo(const char *ver, const char *ven) { if ( ver ) diff --git a/src/host_tracker/host_tracker.h b/src/host_tracker/host_tracker.h index 026f63080..bfee92dcd 100644 --- a/src/host_tracker/host_tracker.h +++ b/src/host_tracker/host_tracker.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "framework/counts.h" @@ -48,6 +49,8 @@ struct HostTrackerStats extern THREAD_LOCAL struct HostTrackerStats host_tracker_stats; +class RNAFlow; + namespace snort { #define INFO_SIZE 32 @@ -79,7 +82,6 @@ struct HostApplicationInfo friend class HostTracker; private: bool visibility = true; - }; typedef HostCacheAllocIp HostAppInfoAllocator; @@ -407,8 +409,14 @@ public: } #endif + void add_flow(RNAFlow*); + void remove_flows(); + void remove_flow(RNAFlow*); + private: + mutable std::mutex host_tracker_lock; // ensure that updates to a shared object are safe + mutable std::mutex flows_lock; // protect the flows set separately uint8_t hops; // hops from the snort inspector, e.g., zero for ARP uint32_t last_seen; // the last time this host was seen uint32_t last_event; // the last time an event was generated @@ -423,6 +431,9 @@ private: std::set, HostCacheAllocIp> udp_fpids; std::vector ua_fps; + // flows that we belong to + std::unordered_set flows; + bool vlan_tag_present = false; vlan::VlanTagHdr vlan_tag; HostType host_type = HOST_TYPE_HOST; diff --git a/src/host_tracker/test/CMakeLists.txt b/src/host_tracker/test/CMakeLists.txt index a32afdf28..5e1279733 100644 --- a/src/host_tracker/test/CMakeLists.txt +++ b/src/host_tracker/test/CMakeLists.txt @@ -3,6 +3,7 @@ add_cpputest( host_cache_test SOURCES ../host_cache.cc ../host_tracker.cc + ../../network_inspectors/rna/test/rna_flow_mock.cc ../../sfip/sf_ip.cc ) @@ -14,6 +15,7 @@ add_cpputest( host_cache_module_test ../../framework/module.cc ../../framework/value.cc ../../hash/lru_cache_shared.cc + ../../network_inspectors/rna/test/rna_flow_mock.cc ../../sfip/sf_ip.cc $ LIBS @@ -23,6 +25,7 @@ add_cpputest( host_cache_module_test add_cpputest( host_tracker_test SOURCES ../host_tracker.cc + ../../network_inspectors/rna/test/rna_flow_mock.cc ../../sfip/sf_ip.cc ) @@ -34,6 +37,7 @@ add_cpputest( host_tracker_module_test ../../framework/module.cc ../../framework/parameter.cc ../../framework/value.cc + ../../network_inspectors/rna/test/rna_flow_mock.cc ../../sfip/sf_ip.cc $ LIBS @@ -43,10 +47,12 @@ add_cpputest( host_tracker_module_test add_cpputest( host_cache_allocator_ht_test SOURCES ../host_tracker.cc + ../../network_inspectors/rna/test/rna_flow_mock.cc ../../sfip/sf_ip.cc ) add_cpputest( host_cache_allocator_test SOURCES ../host_tracker.cc + ../../network_inspectors/rna/test/rna_flow_mock.cc ) diff --git a/src/host_tracker/test/host_cache_allocator_ht_test.cc b/src/host_tracker/test/host_cache_allocator_ht_test.cc index d7746ca36..299abae43 100644 --- a/src/host_tracker/test/host_cache_allocator_ht_test.cc +++ b/src/host_tracker/test/host_cache_allocator_ht_test.cc @@ -25,6 +25,7 @@ #include "host_tracker/host_cache.h" #include "host_tracker/host_cache_allocator.cc" +#include "network_inspectors/rna/rna_flow.h" #include diff --git a/src/host_tracker/test/host_cache_allocator_test.cc b/src/host_tracker/test/host_cache_allocator_test.cc index 22614e9fc..fa2d327a2 100644 --- a/src/host_tracker/test/host_cache_allocator_test.cc +++ b/src/host_tracker/test/host_cache_allocator_test.cc @@ -24,6 +24,7 @@ #include "host_tracker/host_cache.h" #include "host_tracker/host_cache_allocator.cc" +#include "network_inspectors/rna/rna_flow.h" #include diff --git a/src/host_tracker/test/host_tracker_test.cc b/src/host_tracker/test/host_tracker_test.cc index b85208493..51d80ea0e 100644 --- a/src/host_tracker/test/host_tracker_test.cc +++ b/src/host_tracker/test/host_tracker_test.cc @@ -27,6 +27,7 @@ #include "host_tracker/host_cache.h" #include "host_tracker/host_cache_allocator.cc" +#include "network_inspectors/rna/rna_flow.h" #include #include diff --git a/src/network_inspectors/appid/test/CMakeLists.txt b/src/network_inspectors/appid/test/CMakeLists.txt index e7b7d63c7..35a260a6e 100644 --- a/src/network_inspectors/appid/test/CMakeLists.txt +++ b/src/network_inspectors/appid/test/CMakeLists.txt @@ -44,6 +44,7 @@ add_cpputest( appid_http_session_test add_cpputest( tp_lib_handler_test SOURCES tp_lib_handler_test.cc + ../../../network_inspectors/rna/test/rna_flow_mock.cc ../tp_lib_handler.cc LIBS dl diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index eff65cbf2..6bed3a5df 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -245,6 +245,8 @@ AppId HostTracker::get_appid(Port, IpProtocol, bool, bool) return APP_ID_NONE; } +void HostTracker::remove_flows() {} + // Stubs for ClientDiscovery void ClientDiscovery::initialize() {} void ClientDiscovery::reload() {} diff --git a/src/network_inspectors/rna/CMakeLists.txt b/src/network_inspectors/rna/CMakeLists.txt index 85bae0cb3..548543814 100644 --- a/src/network_inspectors/rna/CMakeLists.txt +++ b/src/network_inspectors/rna/CMakeLists.txt @@ -3,6 +3,7 @@ set (RNA_INCLUDES rna_fingerprint_tcp.h rna_fingerprint_ua.h rna_fingerprint_udp.h + rna_flow.h rna_inspector.h rna_logger.h rna_name.h @@ -17,12 +18,11 @@ set ( RNA_SOURCES rna_event_handler.cc rna_event_handler.h rna_fingerprint.cc - rna_fingerprint.h rna_fingerprint_tcp.cc rna_fingerprint_ua.cc rna_fingerprint_udp.cc rna_inspector.cc - rna_inspector.h + rna_flow.cc rna_logger.cc rna_logger_common.h rna_mac_cache.cc diff --git a/src/network_inspectors/rna/rna_app_discovery.cc b/src/network_inspectors/rna/rna_app_discovery.cc index 18151a49d..0e2580a0d 100644 --- a/src/network_inspectors/rna/rna_app_discovery.cc +++ b/src/network_inspectors/rna/rna_app_discovery.cc @@ -27,18 +27,19 @@ #include "detection/detection_engine.h" #include "network_inspectors/appid/appid_session_api.h" +#include "rna_flow.h" #include "rna_logger_common.h" using namespace snort; -RnaTracker RnaAppDiscovery::get_server_rna_tracker(const Packet* p, RNAFlow*) +RnaTracker RnaAppDiscovery::get_server_rna_tracker(const Packet* p, RNAFlow* rna_flow) { - return host_cache.find(p->flow->server_ip); + return rna_flow->get_server(p->flow->server_ip); } -RnaTracker RnaAppDiscovery::get_client_rna_tracker(const Packet* p, RNAFlow*) +RnaTracker RnaAppDiscovery::get_client_rna_tracker(const Packet* p, RNAFlow* rna_flow) { - return host_cache.find(p->flow->client_ip); + return rna_flow->get_client(p->flow->client_ip); } void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, RnaConfig* conf, @@ -223,7 +224,7 @@ void RnaAppDiscovery::discover_payload(const Packet* p, DiscoveryFilter& filter, if ( !srt or !srt->is_visible() ) return; - + srt->update_last_seen(); if ( conf and conf->max_payloads ) max_payloads = conf->max_payloads; @@ -407,7 +408,7 @@ void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, DiscoveryF RNAFlow* rna_flow, const char* host, const char* uagent, RnaLogger& logger, UaFpProcessor& processor) { - if ( !host or !uagent or + if ( !host or !uagent or !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT)) return; @@ -424,7 +425,7 @@ void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, DiscoveryF if ( uafp and rt->add_ua_fingerprint(uafp->fpid, uafp->fp_type, jail_broken, device_info, MAX_USER_AGENT_DEVICES) ) { - logger.log(RNA_EVENT_NEW, NEW_OS, p, &rt, + logger.log(RNA_EVENT_NEW, NEW_OS, p, &rt, (const struct in6_addr*)p->flow->client_ip.get_ip6_ptr(), rt->get_last_seen_mac(), (FpFingerprint*)uafp, packet_time(), device_info, jail_broken); } diff --git a/src/network_inspectors/rna/rna_fingerprint_tcp.cc b/src/network_inspectors/rna/rna_fingerprint_tcp.cc index 389151915..9a723212c 100644 --- a/src/network_inspectors/rna/rna_fingerprint_tcp.cc +++ b/src/network_inspectors/rna/rna_fingerprint_tcp.cc @@ -36,6 +36,8 @@ #include "protocols/tcp.h" #include "protocols/tcp_options.h" +#include "rna_flow.h" + using namespace snort; using namespace std; diff --git a/src/network_inspectors/rna/rna_fingerprint_tcp.h b/src/network_inspectors/rna/rna_fingerprint_tcp.h index 47d15f133..0307fcc18 100644 --- a/src/network_inspectors/rna/rna_fingerprint_tcp.h +++ b/src/network_inspectors/rna/rna_fingerprint_tcp.h @@ -21,15 +21,16 @@ #ifndef RNA_FINGERPRINT_TCP_H #define RNA_FINGERPRINT_TCP_H +#include #include #include #include "main/snort_types.h" #include "protocols/packet.h" #include "protocols/tcp.h" +#include "sfip/sf_ip.h" #include "rna_fingerprint.h" -#include "rna_logger.h" class RNAFlow; @@ -137,21 +138,4 @@ struct FpFingerprintState bool set(const snort::Packet*); }; -class RNAFlow : public snort::FlowData -{ -public: - FpFingerprintState state; - - - RNAFlow() : FlowData(inspector_id) { } - ~RNAFlow() override { } - - static void init(); - size_t size_of() override; - - static unsigned inspector_id; - RnaTracker serverht = nullptr; - RnaTracker clientht = nullptr; -}; - #endif diff --git a/src/network_inspectors/rna/rna_flow.cc b/src/network_inspectors/rna/rna_flow.cc new file mode 100644 index 000000000..f155f298d --- /dev/null +++ b/src/network_inspectors/rna/rna_flow.cc @@ -0,0 +1,95 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2021-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. +//-------------------------------------------------------------------------- + +// rna_flow.cc author Silviu Minut + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rna_flow.h" + +#include "host_tracker/host_cache.h" + +using namespace snort; +using namespace std; + +RNAFlow::~RNAFlow() +{ + // Do not call remove_flow() directly on our own server and client + // because those might be set to 0 between the null check and remove_flow(). + // Use temporaries. We still need to lock the rna flow though, but + // this won't lead to a deadlock. + rna_mutex.lock(); + auto serverht_loc = serverht; + auto clientht_loc = clientht; + rna_mutex.unlock(); + + if (serverht_loc) + serverht_loc->remove_flow(this); + + if (clientht_loc) + clientht_loc->remove_flow(this); +} + +void RNAFlow::clear_ht(HostTracker& ht) +{ + lock_guard lck(rna_mutex); + if (&ht == clientht.get()) + clientht = nullptr; + else if (&ht == serverht.get()) + serverht = nullptr; +} + +RnaTracker RNAFlow::get_server(const SfIp& ip) +{ + rna_mutex.lock(); + auto loc_ht = serverht; + rna_mutex.unlock(); + + if ( !loc_ht ) + loc_ht = host_cache.find(ip); + + return loc_ht; +} + +RnaTracker RNAFlow::get_client(const SfIp& ip) +{ + rna_mutex.lock(); + auto loc_ht = clientht; + rna_mutex.unlock(); + + if ( !loc_ht ) + loc_ht = host_cache.find(ip); + + return loc_ht; +} + +void RNAFlow::set_server(RnaTracker& ht) +{ + rna_mutex.lock(); + serverht = ht; + rna_mutex.unlock(); +} + +void RNAFlow::set_client(RnaTracker& ht) +{ + rna_mutex.lock(); + clientht = ht; + rna_mutex.unlock(); +} diff --git a/src/network_inspectors/rna/rna_flow.h b/src/network_inspectors/rna/rna_flow.h new file mode 100644 index 000000000..4bfd0373f --- /dev/null +++ b/src/network_inspectors/rna/rna_flow.h @@ -0,0 +1,62 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2021-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. +//-------------------------------------------------------------------------- + +// rna_flow.h author Silviu Minut + +#ifndef RNA_FLOW_H +#define RNA_FLOW_H + +#include +#include + +#include "flow/flow_data.h" +#include "host_tracker/host_tracker.h" +#include "sfip/sf_ip.h" + +#include "rna_fingerprint_tcp.h" + +using RnaTracker = std::shared_ptr; + +class RNAFlow : public snort::FlowData +{ +public: + FpFingerprintState state; + + RNAFlow() : FlowData(inspector_id) { } + ~RNAFlow() override; + + static void init(); + size_t size_of() override; + + void clear_ht(snort::HostTracker& ht); + + static unsigned inspector_id; + RnaTracker serverht = nullptr; + RnaTracker clientht = nullptr; + + std::mutex rna_mutex; + + RnaTracker get_server(const snort::SfIp&); + RnaTracker get_client(const snort::SfIp&); + + void set_server(RnaTracker& ht); + void set_client(RnaTracker& ht); + +}; + +#endif diff --git a/src/network_inspectors/rna/rna_inspector.cc b/src/network_inspectors/rna/rna_inspector.cc index d227d0bef..2c64ca8de 100644 --- a/src/network_inspectors/rna/rna_inspector.cc +++ b/src/network_inspectors/rna/rna_inspector.cc @@ -39,6 +39,7 @@ #include "rna_fingerprint_tcp.h" #include "rna_fingerprint_ua.h" #include "rna_fingerprint_udp.h" +#include "rna_flow.h" #include "rna_mac_cache.h" #include "rna_module.h" #include "rna_pnd.h" diff --git a/src/network_inspectors/rna/rna_logger.h b/src/network_inspectors/rna/rna_logger.h index ec6827254..29c31c2c3 100644 --- a/src/network_inspectors/rna/rna_logger.h +++ b/src/network_inspectors/rna/rna_logger.h @@ -24,6 +24,8 @@ #include "host_tracker/host_cache.h" #include "host_tracker/host_tracker.h" +#include "rna_flow.h" + namespace snort { class Flow; @@ -31,8 +33,6 @@ struct Packet; class FpFingerprint; } -using RnaTracker = std::shared_ptr; - struct RnaLoggerEvent : public Event { RnaLoggerEvent (uint16_t t, uint16_t st, const uint8_t* mc, const RnaTracker* rt, diff --git a/src/network_inspectors/rna/rna_pnd.cc b/src/network_inspectors/rna/rna_pnd.cc index c2be2efe0..5da304a27 100644 --- a/src/network_inspectors/rna/rna_pnd.cc +++ b/src/network_inspectors/rna/rna_pnd.cc @@ -39,6 +39,7 @@ #include "rna_app_discovery.h" #include "rna_fingerprint_tcp.h" #include "rna_fingerprint_udp.h" +#include "rna_flow.h" #include "rna_logger_common.h" #ifdef UNIT_TEST @@ -199,6 +200,12 @@ void RnaPnd::discover_network(const Packet* p, uint8_t ttl) rna_flow = new RNAFlow(); p->flow->set_flow_data(rna_flow); } + ht->add_flow(rna_flow); + + if ( p->is_from_client() ) + rna_flow->set_client(ht); + else + rna_flow->set_server(ht); } if ( new_host ) diff --git a/src/network_inspectors/rna/test/rna_flow_mock.cc b/src/network_inspectors/rna/test/rna_flow_mock.cc new file mode 100644 index 000000000..8521aeb2e --- /dev/null +++ b/src/network_inspectors/rna/test/rna_flow_mock.cc @@ -0,0 +1,34 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2021-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. +//-------------------------------------------------------------------------- + +// rna_flow_mock.h author Silviu Minut + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "network_inspectors/rna/rna_flow.h" + +#include "sfip/sf_ip.h" + +using namespace std; +using namespace snort; + +void RNAFlow::clear_ht(HostTracker& ht) { UNUSED(ht); } +RnaTracker RNAFlow::get_server(const SfIp& ) { return nullptr; } +RnaTracker RNAFlow::get_client(const SfIp&) { return nullptr; } diff --git a/src/network_inspectors/rna/test/rna_module_mock.h b/src/network_inspectors/rna/test/rna_module_mock.h index 918368f12..69b5eb469 100644 --- a/src/network_inspectors/rna/test/rna_module_mock.h +++ b/src/network_inspectors/rna/test/rna_module_mock.h @@ -126,4 +126,7 @@ Inspector* InspectorManager::get_inspector(const char*, bool, const SnortConfig* { return nullptr; } + +void HostTracker::remove_flows() { } + #endif