Use shared_ptr instead of raw pointers in packet_analysis for analyzers and dispatchers

This commit is contained in:
Tim Wojtulewicz 2020-07-14 10:26:53 -07:00
parent 07b7a3be40
commit f39d6bb4c4
26 changed files with 89 additions and 98 deletions

View file

@ -86,4 +86,6 @@ private:
void Init(const Tag& tag);
};
using AnalyzerPtr = std::shared_ptr<Analyzer>;
}

View file

@ -12,11 +12,12 @@
namespace zeek::packet_analysis {
class Analyzer;
using AnalyzerPtr = std::shared_ptr<Analyzer>;
class Component : public plugin::Component,
public plugin::TaggedComponent<packet_analysis::Tag> {
public:
typedef Analyzer* (*factory_callback)();
typedef AnalyzerPtr (*factory_callback)();
Component(const std::string& name, factory_callback factory, Tag::subtype_t subtype = 0, bool enabled = true);
~Component() override = default;

View file

@ -20,17 +20,6 @@ Manager::Manager()
Manager::~Manager()
{
bool delete_default = default_analyzer != nullptr;
for ( const auto& current : analyzers )
{
if ( current.second == default_analyzer )
delete_default = false;
delete current.second;
}
if ( delete_default )
delete default_analyzer;
}
void Manager::InitPostScript()
@ -65,7 +54,7 @@ void Manager::InitPostScript()
continue;
// Check if analyzer exists
if ( Analyzer* newAnalyzer = InstantiateAnalyzer(current_mapping.second) )
if ( AnalyzerPtr newAnalyzer = InstantiateAnalyzer(current_mapping.second) )
analyzers.emplace(current_mapping.second, newAnalyzer);
}
}
@ -105,7 +94,7 @@ void Manager::DumpDebug()
DBG_LOG(DBG_PACKET_ANALYSIS, "ProtocolAnalyzerSet FSM:");
for ( const auto& current : dispatchers )
{
DBG_LOG(DBG_PACKET_ANALYSIS, " Dispatcher (%p): %s", current.second, current.first.c_str());
DBG_LOG(DBG_PACKET_ANALYSIS, " Dispatcher (%p): %s", current.second.get(), current.first.c_str());
current.second->DumpDebug();
}
#endif
@ -192,7 +181,7 @@ bool Manager::IsEnabled(EnumVal* val)
return false;
}
Analyzer* Manager::InstantiateAnalyzer(const Tag& tag)
AnalyzerPtr Manager::InstantiateAnalyzer(const Tag& tag)
{
Component* c = Lookup(tag);
@ -211,7 +200,7 @@ Analyzer* Manager::InstantiateAnalyzer(const Tag& tag)
return nullptr;
}
Analyzer* a = c->Factory()();
AnalyzerPtr a = c->Factory()();
if ( ! a )
{
@ -229,7 +218,7 @@ Analyzer* Manager::InstantiateAnalyzer(const Tag& tag)
return a;
}
Analyzer* Manager::InstantiateAnalyzer(const std::string& name)
AnalyzerPtr Manager::InstantiateAnalyzer(const std::string& name)
{
Tag tag = GetComponentTag(name);
return tag ? InstantiateAnalyzer(tag) : nullptr;
@ -319,12 +308,12 @@ void Manager::CustomEncapsulationSkip(Packet* packet)
}
}
Analyzer* Manager::Dispatch(identifier_t identifier)
AnalyzerPtr Manager::Dispatch(identifier_t identifier)
{
// Because leaf nodes (aka no more dispatching) can still have an existing analyzer that returns more identifiers,
// current_state needs to be checked to be not null. In this case there would have been an analyzer dispatched
// in the last layer, but no dispatcher for it (end of FSM)
const Value* result = nullptr;
ValuePtr result = nullptr;
if ( current_state )
result = current_state->Lookup(identifier);
@ -350,7 +339,7 @@ void Manager::Reset()
current_state = root_dispatcher;
}
Dispatcher* Manager::GetDispatcher(Config& configuration, const std::string& dispatcher_name)
DispatcherPtr Manager::GetDispatcher(Config& configuration, const std::string& dispatcher_name)
{
// Is it already created?
if ( dispatchers.count(dispatcher_name) != 0 )
@ -366,7 +355,7 @@ Dispatcher* Manager::GetDispatcher(Config& configuration, const std::string& dis
const auto& mappings = dispatcher_config->get().GetMappings();
Dispatcher* dispatcher = new VectorDispatcher();
DispatcherPtr dispatcher = std::make_shared<VectorDispatcher>();
dispatchers.emplace(dispatcher_name, dispatcher);
for ( const auto& current_mapping : mappings )

View file

@ -17,6 +17,8 @@ namespace zeek::packet_analysis {
class Analyzer;
class Dispatcher;
using AnalyzerPtr = std::shared_ptr<Analyzer>;
using DispatcherPtr = std::shared_ptr<Dispatcher>;
class Manager : public plugin::ComponentManager<Tag, Component> {
public:
@ -127,7 +129,7 @@ public:
* null if tag is invalid, the requested analyzer is disabled, or the
* analyzer can't be instantiated.
*/
Analyzer* InstantiateAnalyzer(const Tag& tag);
AnalyzerPtr InstantiateAnalyzer(const Tag& tag);
/**
* Instantiates a new analyzer.
@ -138,7 +140,7 @@ public:
* null if the name is not known or if the requested analyzer that is
* disabled.
*/
Analyzer* InstantiateAnalyzer(const std::string& name);
AnalyzerPtr InstantiateAnalyzer(const std::string& name);
/**
* Processes a packet by applying the configured packet analyzers.
@ -157,18 +159,18 @@ private:
*/
void CustomEncapsulationSkip(Packet* packet);
Analyzer* Dispatch(identifier_t identifier);
AnalyzerPtr Dispatch(identifier_t identifier);
void Reset();
Dispatcher* GetDispatcher(Config& configuration, const std::string& dispatcher_name);
DispatcherPtr GetDispatcher(Config& configuration, const std::string& dispatcher_name);
std::map<std::string, Analyzer*> analyzers;
std::map<std::string, Dispatcher*> dispatchers;
Dispatcher* root_dispatcher = nullptr;
Dispatcher* default_dispatcher = nullptr;
Dispatcher* current_state = nullptr;
Analyzer* default_analyzer = nullptr;
std::map<std::string, AnalyzerPtr> analyzers;
std::map<std::string, DispatcherPtr> dispatchers;
DispatcherPtr root_dispatcher = nullptr;
DispatcherPtr default_dispatcher = nullptr;
DispatcherPtr current_state = nullptr;
AnalyzerPtr default_analyzer = nullptr;
};
}

View file

@ -11,32 +11,36 @@
namespace zeek::packet_analysis {
class Dispatcher; // Forward decl for Value
using register_pair = std::pair<identifier_t, std::pair<Analyzer*, Dispatcher*>>;
using register_map = std::map<identifier_t, std::pair<Analyzer*, Dispatcher*>>;
using DispatcherPtr = std::shared_ptr<Dispatcher>;
using register_pair = std::pair<identifier_t, std::pair<AnalyzerPtr, DispatcherPtr>>;
using register_map = std::map<identifier_t, std::pair<AnalyzerPtr, DispatcherPtr>>;
class Value {
public:
Analyzer* analyzer;
Dispatcher* dispatcher;
AnalyzerPtr analyzer;
DispatcherPtr dispatcher;
Value(Analyzer* analyzer, Dispatcher* dispatcher)
Value(AnalyzerPtr analyzer, DispatcherPtr dispatcher)
: analyzer(analyzer), dispatcher(dispatcher)
{
}
};
using ValuePtr = std::shared_ptr<Value>;
class Dispatcher {
public:
virtual ~Dispatcher() = default;
virtual bool Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher) = 0;
virtual bool Register(identifier_t identifier, AnalyzerPtr analyzer, DispatcherPtr dispatcher) = 0;
virtual void Register(const register_map& data)
{
for ( auto& current : data )
Register(current.first, current.second.first, current.second.second);
}
virtual const Value* Lookup(identifier_t identifier) const = 0;
virtual ValuePtr Lookup(identifier_t identifier) const = 0;
virtual size_t Size() const = 0;
virtual void Clear() = 0;

View file

@ -23,7 +23,7 @@ UniversalDispatcher::~UniversalDispatcher()
FreeValues();
}
bool UniversalDispatcher::Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher)
bool UniversalDispatcher::Register(identifier_t identifier, AnalyzerPtr analyzer, DispatcherPtr dispatcher)
{
#if DEBUG > 1
std::shared_ptr<void> deferred(nullptr, [=](...) {
@ -35,7 +35,7 @@ bool UniversalDispatcher::Register(identifier_t identifier, Analyzer* analyzer,
if ( table[hashed_id].second == nullptr )
{
// Free bin, insert the value
table[hashed_id] = std::make_pair(identifier, new Value(analyzer, dispatcher));
table[hashed_id] = std::make_pair(identifier, std::make_shared<Value>(analyzer, dispatcher));
return true;
}
else if ( table[hashed_id].first != identifier )
@ -44,7 +44,7 @@ bool UniversalDispatcher::Register(identifier_t identifier, Analyzer* analyzer,
// Create intermediate representation with the new element in it, then rehash with that data
std::vector<pair_t> intermediate = CreateIntermediate();
intermediate.emplace_back(identifier, new Value(analyzer, dispatcher));
intermediate.emplace_back(identifier, std::make_shared<Value>(analyzer, dispatcher));
// Try increasing the #bins until it works or it can't get any larger.
Rehash(intermediate);
@ -67,12 +67,12 @@ void UniversalDispatcher::Register(const register_map& data)
// Create intermediate representation of current analyzer set, then add all new ones
std::vector<pair_t> intermediate = CreateIntermediate();
for ( const auto& current : data )
intermediate.emplace_back(current.first, new Value(current.second.first, current.second.second));
intermediate.emplace_back(current.first, std::make_shared<Value>(current.second.first, current.second.second));
Rehash(intermediate);
}
Value* UniversalDispatcher::Lookup(identifier_t identifier) const
ValuePtr UniversalDispatcher::Lookup(identifier_t identifier) const
{
uint64_t hashed_id = Hash(identifier);
@ -125,7 +125,7 @@ void UniversalDispatcher::DumpDebug() const
for ( size_t i = 0; i < table.size(); i++ )
{
if ( table[i].second != nullptr )
DBG_LOG(DBG_PACKET_ANALYSIS, " %#8x => %s, %p", table[i].first, table[i].second->analyzer->GetAnalyzerName(), table[i].second->dispatcher);
DBG_LOG(DBG_PACKET_ANALYSIS, " %#8x => %s, %p", table[i].first, table[i].second->analyzer->GetAnalyzerName(), table[i].second->dispatcher.get());
}
#endif
}
@ -137,11 +137,8 @@ void UniversalDispatcher::DumpDebug() const
void UniversalDispatcher::FreeValues()
{
for ( auto& current : table )
{
delete current.second;
current.second = nullptr;
}
}
void UniversalDispatcher::Rehash(const std::vector<pair_t>& intermediate)
{

View file

@ -12,9 +12,9 @@ public:
UniversalDispatcher();
~UniversalDispatcher() override;
bool Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher) override;
bool Register(identifier_t identifier, AnalyzerPtr analyzer, DispatcherPtr dispatcher) override;
void Register(const register_map& data) override;
Value* Lookup(identifier_t identifier) const override;
ValuePtr Lookup(identifier_t identifier) const override;
size_t Size() const override;
void Clear() override;
@ -25,7 +25,7 @@ public:
void Rehash();
private:
using pair_t = std::pair<identifier_t, Value*>;
using pair_t = std::pair<identifier_t, ValuePtr>;
static const uint64_t ONE = 1u;
// Chosen random constants for the currently selected collision free random hash function

View file

@ -11,12 +11,12 @@ VectorDispatcher::~VectorDispatcher()
FreeValues();
}
bool VectorDispatcher::Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher)
bool VectorDispatcher::Register(identifier_t identifier, AnalyzerPtr analyzer, DispatcherPtr dispatcher)
{
// If the table has size 1 and the entry is nullptr, there was nothing added yet. Just add it.
if ( table.size() == 1 && table[0] == nullptr )
{
table[0] = new Value(analyzer, dispatcher);
table[0] = std::make_shared<Value>(analyzer, dispatcher);
lowest_identifier = identifier;
return true;
}
@ -48,7 +48,7 @@ bool VectorDispatcher::Register(identifier_t identifier, Analyzer* analyzer, Dis
int64_t index = identifier - lowest_identifier;
if ( table[index] == nullptr )
{
table[index] = new Value(analyzer, dispatcher);
table[index] = std::make_shared<Value>(analyzer, dispatcher);
return true;
}
@ -77,7 +77,7 @@ void VectorDispatcher::Register(const register_map& data)
}
}
const Value* VectorDispatcher::Lookup(identifier_t identifier) const
ValuePtr VectorDispatcher::Lookup(identifier_t identifier) const
{
int64_t index = identifier - lowest_identifier;
if ( index >= 0 && index < static_cast<int64_t>(table.size()) && table[index] != nullptr )
@ -88,7 +88,7 @@ const Value* VectorDispatcher::Lookup(identifier_t identifier) const
size_t VectorDispatcher::Size() const
{
return std::count_if(table.begin(), table.end(), [](const auto* v) { return v != nullptr; });
return std::count_if(table.begin(), table.end(), [](ValuePtr v) { return v != nullptr; });
}
void VectorDispatcher::Clear()
@ -100,11 +100,8 @@ void VectorDispatcher::Clear()
void VectorDispatcher::FreeValues()
{
for ( auto& current : table )
{
delete current;
current = nullptr;
}
}
void VectorDispatcher::DumpDebug() const
{
@ -114,7 +111,7 @@ void VectorDispatcher::DumpDebug() const
for ( size_t i = 0; i < table.size(); i++ )
{
if ( table[i] != nullptr )
DBG_LOG(DBG_PACKET_ANALYSIS, " %#8lx => %s, %p", i+lowest_identifier, table[i]->analyzer->GetAnalyzerName(), table[i]->dispatcher);
DBG_LOG(DBG_PACKET_ANALYSIS, " %#8lx => %s, %p", i+lowest_identifier, table[i]->analyzer->GetAnalyzerName(), table[i]->dispatcher.get());
}
#endif
}

View file

@ -10,15 +10,15 @@ namespace zeek::packet_analysis {
class VectorDispatcher : public Dispatcher {
public:
VectorDispatcher()
: table(std::vector<Value*>(1, nullptr))
: table(std::vector<ValuePtr>(1, nullptr))
{ }
~VectorDispatcher() override;
bool Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher) override;
bool Register(identifier_t identifier, AnalyzerPtr analyzer, DispatcherPtr dispatcher) override;
void Register(const register_map& data) override;
const Value* Lookup(identifier_t identifier) const override;
ValuePtr Lookup(identifier_t identifier) const override;
size_t Size() const override;
void Clear() override;
@ -28,7 +28,7 @@ protected:
private:
identifier_t lowest_identifier = 0;
std::vector<Value*> table;
std::vector<ValuePtr> table;
void FreeValues();

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new ARPAnalyzer();
return std::make_shared<ARPAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new DefaultAnalyzer();
return std::make_shared<DefaultAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new EthernetAnalyzer();
return std::make_shared<EthernetAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static zeek::packet_analysis::Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new FDDIAnalyzer();
return std::make_shared<FDDIAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new IEEE802_11Analyzer();
return std::make_shared<IEEE802_11Analyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new IEEE802_11_RadioAnalyzer();
return std::make_shared<IEEE802_11_RadioAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new IPv4Analyzer();
return std::make_shared<IPv4Analyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static AnalyzerPtr Instantiate()
{
return new IPv6Analyzer();
return std::make_shared<IPv6Analyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new LinuxSLLAnalyzer();
return std::make_shared<LinuxSLLAnalyzer>();
}
private:

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static zeek::packet_analysis::Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new MPLSAnalyzer();
return std::make_shared<MPLSAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static AnalyzerPtr Instantiate()
{
return new NFLogAnalyzer();
return std::make_shared<NFLogAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new NullAnalyzer();
return std::make_shared<NullAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new PPPSerialAnalyzer();
return std::make_shared<PPPSerialAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new PPPoEAnalyzer();
return std::make_shared<PPPoEAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new VLANAnalyzer();
return std::make_shared<VLANAnalyzer>();
}
};

View file

@ -14,9 +14,9 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static zeek::packet_analysis::AnalyzerPtr Instantiate()
{
return new WrapperAnalyzer();
return std::make_shared<WrapperAnalyzer>();
}
};

View file

@ -12,11 +12,10 @@ public:
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
static Analyzer* Instantiate()
static AnalyzerPtr Instantiate()
{
return new Bar();
return std::make_shared<Bar>();
}
};
}