mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +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;
|
type = 0;
|
||||||
error_handler = false;
|
error_handler = false;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
generate_always = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandler::~EventHandler()
|
EventHandler::~EventHandler()
|
||||||
|
@ -23,7 +24,9 @@ EventHandler::~EventHandler()
|
||||||
|
|
||||||
EventHandler::operator bool() const
|
EventHandler::operator bool() const
|
||||||
{
|
{
|
||||||
return enabled && ((local && local->HasBodies()) || receivers.length());
|
return enabled && ((local && local->HasBodies())
|
||||||
|
|| receivers.length()
|
||||||
|
|| generate_always);
|
||||||
}
|
}
|
||||||
|
|
||||||
FuncType* EventHandler::FType()
|
FuncType* EventHandler::FType()
|
||||||
|
|
|
@ -43,6 +43,11 @@ public:
|
||||||
|
|
||||||
void SetEnable(bool arg_enable) { enabled = arg_enable; }
|
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
|
// We don't serialize the handler(s) itself here, but
|
||||||
// just the reference to it.
|
// just the reference to it.
|
||||||
bool Serialize(SerialInfo* info) const;
|
bool Serialize(SerialInfo* info) const;
|
||||||
|
@ -57,6 +62,7 @@ private:
|
||||||
bool used; // this handler is indeed used somewhere
|
bool used; // this handler is indeed used somewhere
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool error_handler; // this handler reports error messages.
|
bool error_handler; // this handler reports error messages.
|
||||||
|
bool generate_always;
|
||||||
|
|
||||||
declare(List, SourceID);
|
declare(List, SourceID);
|
||||||
typedef List(SourceID) receiver_list;
|
typedef List(SourceID) receiver_list;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Obj.h"
|
#include "Obj.h"
|
||||||
#include "Serializer.h"
|
#include "Serializer.h"
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
|
#include "plugin/Manager.h"
|
||||||
|
|
||||||
Location no_location("<no location>", 0, 0, 0, 0);
|
Location no_location("<no location>", 0, 0, 0, 0);
|
||||||
Location start_location("<start uninitialized>", 0, 0, 0, 0);
|
Location start_location("<start uninitialized>", 0, 0, 0, 0);
|
||||||
|
@ -92,6 +93,11 @@ int BroObj::suppress_errors = 0;
|
||||||
|
|
||||||
BroObj::~BroObj()
|
BroObj::~BroObj()
|
||||||
{
|
{
|
||||||
|
if ( notify_plugins )
|
||||||
|
{
|
||||||
|
PLUGIN_HOOK_VOID(HOOK_BRO_OBJ_DTOR, HookBroObjDtor(this));
|
||||||
|
}
|
||||||
|
|
||||||
delete location;
|
delete location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ public:
|
||||||
{
|
{
|
||||||
ref_cnt = 1;
|
ref_cnt = 1;
|
||||||
in_ser_cache = false;
|
in_ser_cache = false;
|
||||||
|
notify_plugins = false;
|
||||||
|
|
||||||
// A bit of a hack. We'd like to associate location
|
// A bit of a hack. We'd like to associate location
|
||||||
// information with every object created when parsing,
|
// information with every object created when parsing,
|
||||||
|
@ -151,6 +152,9 @@ public:
|
||||||
// extend compound objects such as statement lists.
|
// extend compound objects such as statement lists.
|
||||||
virtual void UpdateLocationEndInfo(const Location& end);
|
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; }
|
int RefCnt() const { return ref_cnt; }
|
||||||
|
|
||||||
// Helper class to temporarily suppress errors
|
// Helper class to temporarily suppress errors
|
||||||
|
@ -181,6 +185,7 @@ private:
|
||||||
friend inline void Ref(BroObj* o);
|
friend inline void Ref(BroObj* o);
|
||||||
friend inline void Unref(BroObj* o);
|
friend inline void Unref(BroObj* o);
|
||||||
|
|
||||||
|
bool notify_plugins;
|
||||||
int ref_cnt;
|
int ref_cnt;
|
||||||
|
|
||||||
// If non-zero, do not print runtime errors. Useful for
|
// 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)
|
int Manager::HookLoadFile(const string& file)
|
||||||
{
|
{
|
||||||
HookArgumentList args;
|
HookArgumentList args;
|
||||||
|
@ -522,7 +532,7 @@ bool Manager::HookQueueEvent(Event* event) const
|
||||||
{
|
{
|
||||||
Plugin* p = (*i).second;
|
Plugin* p = (*i).second;
|
||||||
|
|
||||||
if ( p->HookQueueEvent(event) )
|
if ( p->HookQueueEvent(event) )
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
|
@ -577,6 +587,29 @@ void Manager::HookUpdateNetworkTime(double network_time) const
|
||||||
MetaHookPost(HOOK_UPDATE_NETWORK_TIME, args, HookArgument());
|
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
|
void Manager::MetaHookPre(HookType hook, const HookArgumentList& args) const
|
||||||
{
|
{
|
||||||
hook_list* l = hooks[HOOK_CALL_FUNCTION];
|
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
|
// 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.
|
// the code for the most common case that no plugin defines the hook.
|
||||||
#define PLUGIN_HOOK_WITH_RESULT(hook, method_call, default_result) \
|
#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) \
|
#define PLUGIN_HOOK_VOID(hook, method_call) \
|
||||||
if ( plugin_mgr->HavePluginForHook(plugin::hook) ) plugin_mgr->method_call;
|
if ( plugin_mgr->HavePluginForHook(plugin::hook) ) plugin_mgr->method_call;
|
||||||
|
@ -160,6 +160,27 @@ public:
|
||||||
*/
|
*/
|
||||||
void DisableHook(HookType hook, Plugin* plugin);
|
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.
|
// Hook entry functions.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,10 +229,16 @@ public:
|
||||||
void HookUpdateNetworkTime(double network_time) const;
|
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;
|
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
|
* Internal method that registers a freshly instantiated plugin with
|
||||||
* the manager.
|
* the manager.
|
||||||
|
|
|
@ -22,6 +22,7 @@ const char* plugin::hook_name(HookType h)
|
||||||
"QueueEvent",
|
"QueueEvent",
|
||||||
"DrainEvents",
|
"DrainEvents",
|
||||||
"UpdateNetworkTime",
|
"UpdateNetworkTime",
|
||||||
|
"BroObjDtor",
|
||||||
// MetaHooks
|
// MetaHooks
|
||||||
"MetaHookPre",
|
"MetaHookPre",
|
||||||
"MetaHookPost",
|
"MetaHookPost",
|
||||||
|
@ -32,6 +33,13 @@ const char* plugin::hook_name(HookType h)
|
||||||
return hook_names[int(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)
|
BifItem::BifItem(const std::string& arg_id, Type arg_type)
|
||||||
{
|
{
|
||||||
id = arg_id;
|
id = arg_id;
|
||||||
|
@ -119,6 +127,10 @@ void HookArgument::Describe(ODesc* d) const
|
||||||
case VOID:
|
case VOID:
|
||||||
d->Add("<void>");
|
d->Add("<void>");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VOIDP:
|
||||||
|
d->Add("<void ptr>");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +274,16 @@ void Plugin::DisableHook(HookType hook)
|
||||||
plugin_mgr->DisableHook(hook, this);
|
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)
|
int Plugin::HookLoadFile(const std::string& file)
|
||||||
{
|
{
|
||||||
return -1;
|
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)
|
void Plugin::MetaHookPre(HookType hook, const HookArgumentList& args)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ enum HookType {
|
||||||
HOOK_QUEUE_EVENT,
|
HOOK_QUEUE_EVENT,
|
||||||
HOOK_DRAIN_EVENTS,
|
HOOK_DRAIN_EVENTS,
|
||||||
HOOK_UPDATE_NETWORK_TIME,
|
HOOK_UPDATE_NETWORK_TIME,
|
||||||
|
HOOK_BRO_OBJ_DTOR,
|
||||||
|
|
||||||
// Meta hooks.
|
// Meta hooks.
|
||||||
META_HOOK_PRE,
|
META_HOOK_PRE,
|
||||||
|
@ -69,19 +70,11 @@ public:
|
||||||
std::string description; //< A short textual description of the plugin. Mandatory.
|
std::string description; //< A short textual description of the plugin. Mandatory.
|
||||||
VersionNumber version; //< THe plugin's version. Optional.
|
VersionNumber version; //< THe plugin's version. Optional.
|
||||||
|
|
||||||
Configuration()
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Plugin;
|
friend class Plugin;
|
||||||
int api_version; // Current BRO_PLUGIN_API_VERSION. Automatically set.
|
int api_version; // Current BRO_PLUGIN_API_VERSION. Automatically set.
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,7 +134,7 @@ class HookArgument
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type {
|
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; }
|
HookArgument() { type = VOID; }
|
||||||
|
@ -153,6 +146,7 @@ public:
|
||||||
HookArgument(const std::string& a) { type = STRING; arg_string = a; }
|
HookArgument(const std::string& a) { type = STRING; arg_string = a; }
|
||||||
HookArgument(const Val* a) { type = VAL; arg.val = a; }
|
HookArgument(const Val* a) { type = VAL; arg.val = a; }
|
||||||
HookArgument(const val_list* a) { type = VAL_LIST; arg.vals = 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_; }
|
bool AsBool() const { assert(type == BOOL); return arg.bool_; }
|
||||||
double AsDouble() const { assert(type == DOUBLE); return arg.double_; }
|
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 std::string& AsString() const { assert(type == STRING); return arg_string; }
|
||||||
const Val* AsVal() const { assert(type == VAL); return arg.val; }
|
const Val* AsVal() const { assert(type == VAL); return arg.val; }
|
||||||
const val_list* AsValList() const { assert(type == VAL_LIST); return arg.vals; }
|
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; }
|
Type GetType() const { return type; }
|
||||||
void Describe(ODesc* d) const;
|
void Describe(ODesc* d) const;
|
||||||
|
@ -176,6 +171,7 @@ private:
|
||||||
int int_;
|
int int_;
|
||||||
const Val* val;
|
const Val* val;
|
||||||
const val_list* vals;
|
const val_list* vals;
|
||||||
|
const void* voidp;
|
||||||
} arg;
|
} arg;
|
||||||
|
|
||||||
std::string arg_string; // Outside union because it has dtor.
|
std::string arg_string; // Outside union because it has dtor.
|
||||||
|
@ -406,6 +402,23 @@ protected:
|
||||||
*/
|
*/
|
||||||
hook_list EnabledHooks() const;
|
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
|
* Virtual method that can be overriden by derived class to provide
|
||||||
* information about further script-level elements that the plugin
|
* information about further script-level elements that the plugin
|
||||||
|
@ -496,6 +509,18 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void HookUpdateNetworkTime(double network_time);
|
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.
|
// Meta hooks.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue