zeek/src/packet_analysis/Dispatcher.cc
Robin Sommer a84d06a2c3 Suppress warning on an existing packet analyzer being remapped.
There was a check generating an internal warning if a new packet
analyzer mapping overwrote an existing one. However, replacing
an existing analyzer with a new one seems a legitimate use case (and
will be supported by Spicy soon). So removing that warning.
2022-10-10 08:25:51 +02:00

102 lines
2.3 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#include "zeek/packet_analysis/Dispatcher.h"
#include <algorithm>
#include "zeek/DebugLogger.h"
#include "zeek/Reporter.h"
#include "zeek/packet_analysis/Analyzer.h"
namespace zeek::packet_analysis
{
Dispatcher::~Dispatcher()
{
FreeValues();
}
void Dispatcher::Register(uint32_t identifier, AnalyzerPtr analyzer)
{
// 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] = std::move(analyzer);
lowest_identifier = identifier;
return;
}
// If highestIdentifier == identifier, overwrite would happen -> no check needed, will return
// false
if ( GetHighestIdentifier() < identifier )
{
table.resize(table.size() + (identifier - GetHighestIdentifier()), nullptr);
}
else if ( identifier < lowest_identifier )
{
// Lower than the lowest registered identifier. Shift up by lowerBound - identifier
uint32_t distance = lowest_identifier - identifier;
table.resize(table.size() + distance, nullptr);
// Shift values
for ( ssize_t i = table.size() - 1; i >= 0; i-- )
{
if ( table[i] != nullptr )
{
table.at(i + distance) = std::move(table.at(i));
table.at(i) = nullptr;
}
}
lowest_identifier = identifier;
}
int64_t index = identifier - lowest_identifier;
table[index] = std::move(analyzer);
}
AnalyzerPtr Dispatcher::Lookup(uint32_t identifier) const
{
int64_t index = identifier - lowest_identifier;
if ( index >= 0 && index < static_cast<int64_t>(table.size()) && table[index] != nullptr )
return table[index];
return nullptr;
}
size_t Dispatcher::Count() const
{
return std::count_if(table.begin(), table.end(),
[](AnalyzerPtr a)
{
return a != nullptr;
});
}
void Dispatcher::Clear()
{
FreeValues();
table.clear();
}
void Dispatcher::FreeValues()
{
for ( auto& current : table )
current = nullptr;
}
void Dispatcher::DumpDebug() const
{
#ifdef DEBUG
DBG_LOG(DBG_PACKET_ANALYSIS, "Dispatcher elements (used/total): %lu/%lu", Count(),
table.size());
for ( size_t i = 0; i < table.size(); i++ )
{
if ( table[i] != nullptr )
DBG_LOG(DBG_PACKET_ANALYSIS, "%#8lx => %s", i + lowest_identifier,
table[i]->GetAnalyzerName());
}
#endif
}
}