mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
Extending plugin interface.
This is for feature parity with the older interface, and remains experimental for now.
This commit is contained in:
parent
aec61e9ea4
commit
421120e12c
8 changed files with 145 additions and 14 deletions
|
@ -13,6 +13,7 @@ EventHandler::EventHandler(const char* arg_name)
|
|||
type = 0;
|
||||
error_handler = false;
|
||||
enabled = true;
|
||||
generate_always = false;
|
||||
}
|
||||
|
||||
EventHandler::~EventHandler()
|
||||
|
@ -23,7 +24,9 @@ EventHandler::~EventHandler()
|
|||
|
||||
EventHandler::operator bool() const
|
||||
{
|
||||
return enabled && ((local && local->HasBodies()) || receivers.length());
|
||||
return enabled && ((local && local->HasBodies())
|
||||
|| receivers.length()
|
||||
|| generate_always);
|
||||
}
|
||||
|
||||
FuncType* EventHandler::FType()
|
||||
|
|
|
@ -43,6 +43,11 @@ public:
|
|||
|
||||
void SetEnable(bool arg_enable) { enabled = arg_enable; }
|
||||
|
||||
// Flags the event as interesting even if there is no body defined. In
|
||||
// particular, this will then still pass the event on to plugins.
|
||||
void SetGenerateAlways() { generate_always = true; }
|
||||
bool GenerateAlways() { return generate_always; }
|
||||
|
||||
// We don't serialize the handler(s) itself here, but
|
||||
// just the reference to it.
|
||||
bool Serialize(SerialInfo* info) const;
|
||||
|
@ -57,6 +62,7 @@ private:
|
|||
bool used; // this handler is indeed used somewhere
|
||||
bool enabled;
|
||||
bool error_handler; // this handler reports error messages.
|
||||
bool generate_always;
|
||||
|
||||
declare(List, SourceID);
|
||||
typedef List(SourceID) receiver_list;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "Obj.h"
|
||||
#include "Serializer.h"
|
||||
#include "File.h"
|
||||
#include "plugin/Manager.h"
|
||||
|
||||
Location no_location("<no location>", 0, 0, 0, 0);
|
||||
Location start_location("<start uninitialized>", 0, 0, 0, 0);
|
||||
|
@ -92,6 +93,11 @@ int BroObj::suppress_errors = 0;
|
|||
|
||||
BroObj::~BroObj()
|
||||
{
|
||||
if ( notify_plugins )
|
||||
{
|
||||
PLUGIN_HOOK_VOID(HOOK_BRO_OBJ_DTOR, HookBroObjDtor(this));
|
||||
}
|
||||
|
||||
delete location;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ public:
|
|||
{
|
||||
ref_cnt = 1;
|
||||
in_ser_cache = false;
|
||||
notify_plugins = false;
|
||||
|
||||
// A bit of a hack. We'd like to associate location
|
||||
// information with every object created when parsing,
|
||||
|
@ -151,6 +152,9 @@ public:
|
|||
// extend compound objects such as statement lists.
|
||||
virtual void UpdateLocationEndInfo(const Location& end);
|
||||
|
||||
// Enable notification of plugins when this objects gets destroyed.
|
||||
void NotifyPluginsOnDtor() { notify_plugins = true; }
|
||||
|
||||
int RefCnt() const { return ref_cnt; }
|
||||
|
||||
// Helper class to temporarily suppress errors
|
||||
|
@ -181,6 +185,7 @@ private:
|
|||
friend inline void Ref(BroObj* o);
|
||||
friend inline void Unref(BroObj* o);
|
||||
|
||||
bool notify_plugins;
|
||||
int ref_cnt;
|
||||
|
||||
// If non-zero, do not print runtime errors. Useful for
|
||||
|
|
|
@ -443,6 +443,16 @@ void Manager::DisableHook(HookType hook, Plugin* plugin)
|
|||
}
|
||||
}
|
||||
|
||||
void Manager::RequestEvent(EventHandlerPtr handler, Plugin* plugin)
|
||||
{
|
||||
DBG_LOG(DBG_PLUGINS, "Plugin %s requested event %s", Name(), handler->Name());
|
||||
handler->GenerateAlways();
|
||||
}
|
||||
|
||||
void Manager::RequestBroObjDtor(BroObj* obj, Plugin* plugin)
|
||||
{
|
||||
}
|
||||
|
||||
int Manager::HookLoadFile(const string& file)
|
||||
{
|
||||
HookArgumentList args;
|
||||
|
@ -577,6 +587,29 @@ void Manager::HookUpdateNetworkTime(double network_time) const
|
|||
MetaHookPost(HOOK_UPDATE_NETWORK_TIME, args, HookArgument());
|
||||
}
|
||||
|
||||
void Manager::HookBroObjDtor(void* obj) const
|
||||
{
|
||||
HookArgumentList args;
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
args.push_back(obj);
|
||||
MetaHookPre(HOOK_BRO_OBJ_DTOR, args);
|
||||
}
|
||||
|
||||
hook_list* l = hooks[HOOK_BRO_OBJ_DTOR];
|
||||
|
||||
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->HookBroObjDtor(obj);
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_BRO_OBJ_DTOR, args, HookArgument());
|
||||
|
||||
}
|
||||
|
||||
void Manager::MetaHookPre(HookType hook, const HookArgumentList& args) const
|
||||
{
|
||||
hook_list* l = hooks[HOOK_CALL_FUNCTION];
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace plugin {
|
|||
// Macros that trigger a plugin hook. We put this into macros to short-cut
|
||||
// the code for the most common case that no plugin defines the hook.
|
||||
#define PLUGIN_HOOK_WITH_RESULT(hook, method_call, default_result) \
|
||||
(plugin_mgr->HavePluginForHook(plugin::hook) ? plugin_mgr->method_call : (default_result))
|
||||
(plugin_mgr->HavePluginForHook(::plugin::hook) ? plugin_mgr->method_call : (default_result))
|
||||
|
||||
#define PLUGIN_HOOK_VOID(hook, method_call) \
|
||||
if ( plugin_mgr->HavePluginForHook(plugin::hook) ) plugin_mgr->method_call;
|
||||
|
@ -160,6 +160,27 @@ public:
|
|||
*/
|
||||
void DisableHook(HookType hook, Plugin* plugin);
|
||||
|
||||
/**
|
||||
* Register interest in an event. The event will then be raised, and
|
||||
* hence passed to the plugin, even if there no handler defined.
|
||||
*
|
||||
* @param handler The event being interested in.
|
||||
*
|
||||
* @param plugin The plugin expressing interest.
|
||||
*/
|
||||
void RequestEvent(EventHandlerPtr handler, Plugin* plugin);
|
||||
|
||||
/**
|
||||
* Register interest in the destruction of a BroObj instance. When
|
||||
* Bro's reference counting triggers the objects destructor to run,
|
||||
* the \a HookBroObjDtor will be called.
|
||||
*
|
||||
* @param handler The object being interested in.
|
||||
*
|
||||
* @param plugin The plugin expressing interest.
|
||||
*/
|
||||
void RequestBroObjDtor(BroObj* obj, Plugin* plugin);
|
||||
|
||||
// Hook entry functions.
|
||||
|
||||
/**
|
||||
|
@ -208,10 +229,16 @@ public:
|
|||
void HookUpdateNetworkTime(double network_time) const;
|
||||
|
||||
/**
|
||||
* Hooks that informs plugins that the event queue is being drained.
|
||||
* Hook that informs plugins that the event queue is being drained.
|
||||
*/
|
||||
void HookDrainEvents() const;
|
||||
|
||||
/**
|
||||
* Hook that informs plugins that an BroObj is being destroyed. Will be
|
||||
* called only for objects that a plugin has expressed interest in.
|
||||
*/
|
||||
void HookBroObjDtor(void* obj) const;
|
||||
|
||||
/**
|
||||
* Internal method that registers a freshly instantiated plugin with
|
||||
* the manager.
|
||||
|
|
|
@ -22,6 +22,7 @@ const char* plugin::hook_name(HookType h)
|
|||
"QueueEvent",
|
||||
"DrainEvents",
|
||||
"UpdateNetworkTime",
|
||||
"BroObjDtor",
|
||||
// MetaHooks
|
||||
"MetaHookPre",
|
||||
"MetaHookPost",
|
||||
|
@ -32,6 +33,13 @@ const char* plugin::hook_name(HookType h)
|
|||
return hook_names[int(h)];
|
||||
}
|
||||
|
||||
Configuration::Configuration()
|
||||
{
|
||||
name = "";
|
||||
description = "";
|
||||
api_version = BRO_PLUGIN_API_VERSION;
|
||||
}
|
||||
|
||||
BifItem::BifItem(const std::string& arg_id, Type arg_type)
|
||||
{
|
||||
id = arg_id;
|
||||
|
@ -119,6 +127,10 @@ void HookArgument::Describe(ODesc* d) const
|
|||
case VOID:
|
||||
d->Add("<void>");
|
||||
break;
|
||||
|
||||
case VOIDP:
|
||||
d->Add("<void ptr>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,6 +274,16 @@ void Plugin::DisableHook(HookType hook)
|
|||
plugin_mgr->DisableHook(hook, this);
|
||||
}
|
||||
|
||||
void Plugin::RequestEvent(EventHandlerPtr handler)
|
||||
{
|
||||
plugin_mgr->RequestEvent(handler, this);
|
||||
}
|
||||
|
||||
void Plugin::RequestBroObjDtor(BroObj* obj)
|
||||
{
|
||||
plugin_mgr->RequestBroObjDtor(obj, this);
|
||||
}
|
||||
|
||||
int Plugin::HookLoadFile(const std::string& file)
|
||||
{
|
||||
return -1;
|
||||
|
@ -285,6 +307,10 @@ void Plugin::HookUpdateNetworkTime(double network_time)
|
|||
{
|
||||
}
|
||||
|
||||
void Plugin::HookBroObjDtor(void* obj)
|
||||
{
|
||||
}
|
||||
|
||||
void Plugin::MetaHookPre(HookType hook, const HookArgumentList& args)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ enum HookType {
|
|||
HOOK_QUEUE_EVENT,
|
||||
HOOK_DRAIN_EVENTS,
|
||||
HOOK_UPDATE_NETWORK_TIME,
|
||||
HOOK_BRO_OBJ_DTOR,
|
||||
|
||||
// Meta hooks.
|
||||
META_HOOK_PRE,
|
||||
|
@ -69,19 +70,11 @@ public:
|
|||
std::string description; //< A short textual description of the plugin. Mandatory.
|
||||
VersionNumber version; //< THe plugin's version. Optional.
|
||||
|
||||
Configuration()
|
||||
{
|
||||
// Note we inline this method here so that when plugins create an instance,
|
||||
// *their* defaults will be used for the internal fields.
|
||||
name = "";
|
||||
description = "";
|
||||
api_version = BRO_PLUGIN_API_VERSION;
|
||||
}
|
||||
Configuration();
|
||||
|
||||
private:
|
||||
friend class Plugin;
|
||||
int api_version; // Current BRO_PLUGIN_API_VERSION. Automatically set.
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -141,7 +134,7 @@ class HookArgument
|
|||
{
|
||||
public:
|
||||
enum Type {
|
||||
BOOL, DOUBLE, EVENT, FUNC, INT, STRING, VAL, VAL_LIST, VOID
|
||||
BOOL, DOUBLE, EVENT, FUNC, INT, STRING, VAL, VAL_LIST, VOID, VOIDP,
|
||||
};
|
||||
|
||||
HookArgument() { type = VOID; }
|
||||
|
@ -153,6 +146,7 @@ public:
|
|||
HookArgument(const std::string& a) { type = STRING; arg_string = a; }
|
||||
HookArgument(const Val* a) { type = VAL; arg.val = a; }
|
||||
HookArgument(const val_list* a) { type = VAL_LIST; arg.vals = a; }
|
||||
HookArgument(void* p) { type = VOIDP; arg.voidp = p; }
|
||||
|
||||
bool AsBool() const { assert(type == BOOL); return arg.bool_; }
|
||||
double AsDouble() const { assert(type == DOUBLE); return arg.double_; }
|
||||
|
@ -162,6 +156,7 @@ public:
|
|||
const std::string& AsString() const { assert(type == STRING); return arg_string; }
|
||||
const Val* AsVal() const { assert(type == VAL); return arg.val; }
|
||||
const val_list* AsValList() const { assert(type == VAL_LIST); return arg.vals; }
|
||||
const void* AsVoidPtr() const { assert(type == VOIDP); return arg.voidp; }
|
||||
|
||||
Type GetType() const { return type; }
|
||||
void Describe(ODesc* d) const;
|
||||
|
@ -176,6 +171,7 @@ private:
|
|||
int int_;
|
||||
const Val* val;
|
||||
const val_list* vals;
|
||||
const void* voidp;
|
||||
} arg;
|
||||
|
||||
std::string arg_string; // Outside union because it has dtor.
|
||||
|
@ -406,6 +402,23 @@ protected:
|
|||
*/
|
||||
hook_list EnabledHooks() const;
|
||||
|
||||
/**
|
||||
* Register interest in an event. The event will then be raised, and
|
||||
* hence passed to the plugin, even if there no handler defined.
|
||||
*
|
||||
* @param handler The object being interested in.
|
||||
*/
|
||||
void RequestEvent(EventHandlerPtr handler);
|
||||
|
||||
/**
|
||||
* Register interest in the destruction of a BroObj instance. When
|
||||
* Bro's reference counting triggers the objects destructor to run,
|
||||
* the \a HookBroObjDtor will be called.
|
||||
*
|
||||
* @param handler The object being interested in.
|
||||
*/
|
||||
void RequestBroObjDtor(BroObj* obj);
|
||||
|
||||
/**
|
||||
* Virtual method that can be overriden by derived class to provide
|
||||
* information about further script-level elements that the plugin
|
||||
|
@ -496,6 +509,18 @@ protected:
|
|||
*/
|
||||
virtual void HookUpdateNetworkTime(double network_time);
|
||||
|
||||
/**
|
||||
* Hook for destruction of objects registerd with
|
||||
* RequestBroObjDtor(). When Bro's reference counting triggers the
|
||||
* objects destructor to run, this method will be run. It may also
|
||||
* run for other objects that this plugin has not registered for.
|
||||
*
|
||||
* @param obj A pointer to the object being destroyed. Note that the
|
||||
* object is already considered invalid and the pointer must not be
|
||||
* dereferenced.
|
||||
*/
|
||||
virtual void HookBroObjDtor(void* obj);
|
||||
|
||||
// Meta hooks.
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue