mirror of
https://github.com/zeek/zeek.git
synced 2025-10-15 21:18:20 +00:00
185 lines
3.6 KiB
C++
185 lines
3.6 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#include "zeek-config.h"
|
|
|
|
#include "Event.h"
|
|
#include "Func.h"
|
|
#include "NetVar.h"
|
|
#include "Trigger.h"
|
|
#include "plugin/Manager.h"
|
|
|
|
EventMgr mgr;
|
|
|
|
uint64_t num_events_queued = 0;
|
|
uint64_t num_events_dispatched = 0;
|
|
|
|
Event::Event(EventHandlerPtr arg_handler, val_list arg_args,
|
|
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
|
BroObj* arg_obj)
|
|
: handler(arg_handler),
|
|
args(std::move(arg_args)),
|
|
src(arg_src),
|
|
aid(arg_aid),
|
|
mgr(arg_mgr ? arg_mgr : timer_mgr),
|
|
obj(arg_obj),
|
|
next_event(nullptr)
|
|
{
|
|
if ( obj )
|
|
Ref(obj);
|
|
}
|
|
|
|
Event::Event(EventHandlerPtr arg_handler, val_list* arg_args,
|
|
SourceID arg_src, analyzer::ID arg_aid, TimerMgr* arg_mgr,
|
|
BroObj* arg_obj)
|
|
: Event(arg_handler, std::move(*arg_args), arg_src, arg_aid, arg_mgr, arg_obj)
|
|
{
|
|
delete arg_args;
|
|
}
|
|
|
|
void Event::Describe(ODesc* d) const
|
|
{
|
|
if ( d->IsReadable() )
|
|
d->AddSP("event");
|
|
|
|
int s = d->IsShort();
|
|
d->SetShort();
|
|
// handler->Describe(d);
|
|
d->SetShort(s);
|
|
|
|
if ( ! d->IsBinary() )
|
|
d->Add("(");
|
|
describe_vals(&args, d);
|
|
if ( ! d->IsBinary() )
|
|
d->Add("(");
|
|
}
|
|
|
|
void Event::Dispatch(bool no_remote)
|
|
{
|
|
if ( src == SOURCE_BROKER )
|
|
no_remote = true;
|
|
|
|
if ( handler->ErrorHandler() )
|
|
reporter->BeginErrorHandler();
|
|
|
|
try
|
|
{
|
|
handler->Call(&args, no_remote);
|
|
}
|
|
|
|
catch ( InterpreterException& e )
|
|
{
|
|
// Already reported.
|
|
}
|
|
|
|
if ( obj )
|
|
// obj->EventDone();
|
|
Unref(obj);
|
|
|
|
if ( handler->ErrorHandler() )
|
|
reporter->EndErrorHandler();
|
|
}
|
|
|
|
EventMgr::EventMgr()
|
|
{
|
|
head = tail = 0;
|
|
current_src = SOURCE_LOCAL;
|
|
current_mgr = timer_mgr;
|
|
current_aid = 0;
|
|
src_val = 0;
|
|
draining = 0;
|
|
}
|
|
|
|
EventMgr::~EventMgr()
|
|
{
|
|
while ( head )
|
|
{
|
|
Event* n = head->NextEvent();
|
|
Unref(head);
|
|
head = n;
|
|
}
|
|
|
|
Unref(src_val);
|
|
}
|
|
|
|
void EventMgr::QueueEvent(Event* event)
|
|
{
|
|
bool done = PLUGIN_HOOK_WITH_RESULT(HOOK_QUEUE_EVENT, HookQueueEvent(event), false);
|
|
|
|
if ( done )
|
|
return;
|
|
|
|
if ( ! head )
|
|
head = tail = event;
|
|
else
|
|
{
|
|
tail->SetNext(event);
|
|
tail = event;
|
|
}
|
|
|
|
++num_events_queued;
|
|
}
|
|
|
|
void EventMgr::Drain()
|
|
{
|
|
if ( event_queue_flush_point )
|
|
QueueEventFast(event_queue_flush_point, val_list{});
|
|
|
|
SegmentProfiler(segment_logger, "draining-events");
|
|
|
|
PLUGIN_HOOK_VOID(HOOK_DRAIN_EVENTS, HookDrainEvents());
|
|
|
|
draining = true;
|
|
|
|
// Past Bro versions drained as long as there events, including when
|
|
// a handler queued new events during its execution. This could lead
|
|
// to endless loops in case a handler kept triggering its own event.
|
|
// We now limit this to just a couple of rounds. We do more than
|
|
// just one round to make it less likley to break existing scripts
|
|
// that expect the old behavior to trigger something quickly.
|
|
|
|
for ( int round = 0; head && round < 2; round++ )
|
|
{
|
|
Event* current = head;
|
|
head = 0;
|
|
tail = 0;
|
|
|
|
while ( current )
|
|
{
|
|
Event* next = current->NextEvent();
|
|
|
|
current_src = current->Source();
|
|
current_mgr = current->Mgr();
|
|
current_aid = current->Analyzer();
|
|
current->Dispatch();
|
|
Unref(current);
|
|
|
|
++num_events_dispatched;
|
|
current = next;
|
|
}
|
|
}
|
|
|
|
// Note: we might eventually need a general way to specify things to
|
|
// do after draining events.
|
|
draining = false;
|
|
|
|
// We evaluate Triggers here. While this is somewhat unrelated to event
|
|
// processing, we ensure that it's done at a regular basis by checking
|
|
// them here.
|
|
Trigger::EvaluatePending();
|
|
}
|
|
|
|
void EventMgr::Describe(ODesc* d) const
|
|
{
|
|
int n = 0;
|
|
Event* e;
|
|
for ( e = head; e; e = e->NextEvent() )
|
|
++n;
|
|
|
|
d->AddCount(n);
|
|
|
|
for ( e = head; e; e = e->NextEvent() )
|
|
{
|
|
e->Describe(d);
|
|
d->NL();
|
|
}
|
|
}
|