mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
183 lines
3.8 KiB
C++
183 lines
3.8 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#include "AnalyzerSet.h"
|
|
#include "File.h"
|
|
#include "Analyzer.h"
|
|
#include "Manager.h"
|
|
|
|
using namespace file_analysis;
|
|
|
|
static void analyzer_del_func(void* v)
|
|
{
|
|
delete (file_analysis::Analyzer*) v;
|
|
}
|
|
|
|
AnalyzerSet::AnalyzerSet(File* arg_file) : file(arg_file)
|
|
{
|
|
TypeList* t = new TypeList();
|
|
t->Append(BifType::Record::FileAnalysis::AnalyzerArgs->Ref());
|
|
analyzer_hash = new CompositeHash(t);
|
|
Unref(t);
|
|
analyzer_map.SetDeleteFunc(analyzer_del_func);
|
|
}
|
|
|
|
AnalyzerSet::~AnalyzerSet()
|
|
{
|
|
while ( ! mod_queue.empty() )
|
|
{
|
|
Modification* mod = mod_queue.front();
|
|
mod->Abort();
|
|
delete mod;
|
|
mod_queue.pop();
|
|
}
|
|
|
|
delete analyzer_hash;
|
|
}
|
|
|
|
bool AnalyzerSet::Add(RecordVal* args)
|
|
{
|
|
HashKey* key = GetKey(args);
|
|
|
|
if ( analyzer_map.Lookup(key) )
|
|
{
|
|
DBG_LOG(DBG_FILE_ANALYSIS, "Instantiate analyzer %d skipped for file id"
|
|
" %s: already exists", file_analysis::Analyzer::ArgsTag(args),
|
|
file->GetID().c_str());
|
|
delete key;
|
|
return true;
|
|
}
|
|
|
|
file_analysis::Analyzer* a = InstantiateAnalyzer(args);
|
|
|
|
if ( ! a )
|
|
{
|
|
delete key;
|
|
return false;
|
|
}
|
|
|
|
Insert(a, key);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool AnalyzerSet::QueueAdd(RecordVal* args)
|
|
{
|
|
HashKey* key = GetKey(args);
|
|
file_analysis::Analyzer* a = InstantiateAnalyzer(args);
|
|
|
|
if ( ! a )
|
|
{
|
|
delete key;
|
|
return false;
|
|
}
|
|
|
|
mod_queue.push(new AddMod(a, key));
|
|
|
|
return true;
|
|
}
|
|
|
|
bool AnalyzerSet::AddMod::Perform(AnalyzerSet* set)
|
|
{
|
|
if ( set->analyzer_map.Lookup(key) )
|
|
{
|
|
DBG_LOG(DBG_FILE_ANALYSIS, "Add analyzer %d skipped for file id"
|
|
" %s: already exists", a->Tag(), a->GetFile()->GetID().c_str());
|
|
|
|
Abort();
|
|
return true;
|
|
}
|
|
|
|
set->Insert(a, key);
|
|
return true;
|
|
}
|
|
|
|
bool AnalyzerSet::Remove(const RecordVal* args)
|
|
{
|
|
return Remove(file_analysis::Analyzer::ArgsTag(args), GetKey(args));
|
|
}
|
|
|
|
bool AnalyzerSet::Remove(FA_Tag tag, HashKey* key)
|
|
{
|
|
file_analysis::Analyzer* a =
|
|
(file_analysis::Analyzer*) analyzer_map.Remove(key);
|
|
|
|
delete key;
|
|
|
|
if ( ! a )
|
|
{
|
|
DBG_LOG(DBG_FILE_ANALYSIS, "Skip remove analyzer %d for file id %s",
|
|
tag, file->GetID().c_str());
|
|
return false;
|
|
}
|
|
|
|
DBG_LOG(DBG_FILE_ANALYSIS, "Remove analyzer %d for file id %s", a->Tag(),
|
|
file->GetID().c_str());
|
|
|
|
delete a;
|
|
return true;
|
|
}
|
|
|
|
bool AnalyzerSet::QueueRemove(const RecordVal* args)
|
|
{
|
|
HashKey* key = GetKey(args);
|
|
FA_Tag tag = file_analysis::Analyzer::ArgsTag(args);
|
|
|
|
mod_queue.push(new RemoveMod(tag, key));
|
|
|
|
return analyzer_map.Lookup(key);
|
|
}
|
|
|
|
bool AnalyzerSet::RemoveMod::Perform(AnalyzerSet* set)
|
|
{
|
|
return set->Remove(tag, key);
|
|
}
|
|
|
|
HashKey* AnalyzerSet::GetKey(const RecordVal* args) const
|
|
{
|
|
HashKey* key = analyzer_hash->ComputeHash(args, 1);
|
|
if ( ! key )
|
|
reporter->InternalError("AnalyzerArgs type mismatch");
|
|
|
|
return key;
|
|
}
|
|
|
|
file_analysis::Analyzer* AnalyzerSet::InstantiateAnalyzer(RecordVal* args) const
|
|
{
|
|
FA_Tag tag = file_analysis::Analyzer::ArgsTag(args);
|
|
file_analysis::Analyzer* a = file_mgr->InstantiateAnalyzer(tag, args, file);
|
|
|
|
if ( ! a )
|
|
{
|
|
reporter->Error("Failed file analyzer %s instantiation for file id %s",
|
|
file_mgr->GetAnalyzerName(tag), file->GetID().c_str());
|
|
return 0;
|
|
}
|
|
|
|
return a;
|
|
}
|
|
|
|
void AnalyzerSet::Insert(file_analysis::Analyzer* a, HashKey* key)
|
|
{
|
|
DBG_LOG(DBG_FILE_ANALYSIS, "Add analyzer %d for file id %s", a->Tag(),
|
|
file->GetID().c_str());
|
|
analyzer_map.Insert(key, a);
|
|
delete key;
|
|
}
|
|
|
|
void AnalyzerSet::DrainModifications()
|
|
{
|
|
if ( mod_queue.empty() )
|
|
return;
|
|
|
|
DBG_LOG(DBG_FILE_ANALYSIS, "Start analyzer mod queue flush of file id %s",
|
|
file->GetID().c_str());
|
|
do
|
|
{
|
|
Modification* mod = mod_queue.front();
|
|
mod->Perform(this);
|
|
delete mod;
|
|
mod_queue.pop();
|
|
} while ( ! mod_queue.empty() );
|
|
DBG_LOG(DBG_FILE_ANALYSIS, "End flushing analyzer mod queue of file id %s",
|
|
file->GetID().c_str());
|
|
}
|