mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Preventing the event processing from looping endlessly when an event
reraised itself during execution of its handlers.
This commit is contained in:
parent
ddabd13097
commit
2335a62a07
6 changed files with 67 additions and 25 deletions
6
CHANGES
6
CHANGES
|
@ -1,4 +1,10 @@
|
|||
|
||||
2.4-613 | 2016-06-14 18:10:37 -0700
|
||||
|
||||
* Preventing the event processing from looping endlessly when an
|
||||
event reraised itself during execution of its handlers. (Robin
|
||||
Sommer)
|
||||
|
||||
2.4-612 | 2016-06-14 17:42:52 -0700
|
||||
|
||||
* Improved handling of 802.11 headers. (Jan Grashoefer)
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.4-612
|
||||
2.4-613
|
||||
|
|
50
src/Event.cc
50
src/Event.cc
|
@ -94,26 +94,6 @@ void EventMgr::QueueEvent(Event* event)
|
|||
++num_events_queued;
|
||||
}
|
||||
|
||||
void EventMgr::Dispatch()
|
||||
{
|
||||
if ( ! head )
|
||||
reporter->InternalError("EventMgr::Dispatch underflow");
|
||||
|
||||
Event* current = head;
|
||||
|
||||
head = head->NextEvent();
|
||||
if ( ! head )
|
||||
tail = head;
|
||||
|
||||
current_src = current->Source();
|
||||
current_mgr = current->Mgr();
|
||||
current_aid = current->Analyzer();
|
||||
current->Dispatch();
|
||||
Unref(current);
|
||||
|
||||
++num_events_dispatched;
|
||||
}
|
||||
|
||||
void EventMgr::Drain()
|
||||
{
|
||||
if ( event_queue_flush_point )
|
||||
|
@ -124,8 +104,34 @@ void EventMgr::Drain()
|
|||
PLUGIN_HOOK_VOID(HOOK_DRAIN_EVENTS, HookDrainEvents());
|
||||
|
||||
draining = true;
|
||||
while ( head )
|
||||
Dispatch();
|
||||
|
||||
// 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.
|
||||
|
|
|
@ -90,8 +90,6 @@ public:
|
|||
delete_vals(vl);
|
||||
}
|
||||
|
||||
void Dispatch();
|
||||
|
||||
void Dispatch(Event* event, bool no_remote = false)
|
||||
{
|
||||
current_src = event->Source();
|
||||
|
|
1
testing/btest/Baseline/core.recursive-event/output
Normal file
1
testing/btest/Baseline/core.recursive-event/output
Normal file
|
@ -0,0 +1 @@
|
|||
10
|
31
testing/btest/core/recursive-event.bro
Normal file
31
testing/btest/core/recursive-event.bro
Normal file
|
@ -0,0 +1,31 @@
|
|||
# @TEST-EXEC: bro %INPUT 2>&1 | grep -v termination | sort | uniq | wc -l >output
|
||||
# @TEST-EXEC: btest-diff output
|
||||
|
||||
# In old version, the event would keep triggering endlessely, with the network
|
||||
# time not moving forward and Bro not terminating.
|
||||
#
|
||||
# Note that the output will be 10 (not 20) because we still execute two rounds
|
||||
# of events every time we drain.
|
||||
|
||||
redef exit_only_after_terminate=T;
|
||||
|
||||
global c = 0;
|
||||
|
||||
event test()
|
||||
{
|
||||
c += 1;
|
||||
|
||||
if ( c == 20 )
|
||||
{
|
||||
terminate();
|
||||
return;
|
||||
}
|
||||
|
||||
print network_time();
|
||||
event test();
|
||||
}
|
||||
|
||||
event bro_init()
|
||||
{
|
||||
event test();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue