diff --git a/src/analyzer/Component.cc b/src/analyzer/Component.cc index 9f12759640..2630db84df 100644 --- a/src/analyzer/Component.cc +++ b/src/analyzer/Component.cc @@ -15,7 +15,11 @@ Component::Component(const std::string& name, factory_callback arg_factory, Tag: factory = arg_factory; enabled = arg_enabled; partial = arg_partial; + } +void Component::Initialize() + { + InitializeTag(); analyzer_mgr->RegisterComponent(this, "ANALYZER_"); } diff --git a/src/analyzer/Component.h b/src/analyzer/Component.h index 0704852145..cff79c2774 100644 --- a/src/analyzer/Component.h +++ b/src/analyzer/Component.h @@ -63,6 +63,13 @@ public: */ ~Component(); + /** + * Initialization function. This function has to be called before any + * plugin component functionality is used; it is used to add the + * plugin component to the list of components and to initialize tags + */ + void Initialize() override; + /** * Returns the analyzer's factory function. */ @@ -93,7 +100,7 @@ protected: /** * Overriden from plugin::Component. */ - virtual void DoDescribe(ODesc* d) const; + void DoDescribe(ODesc* d) const override; private: factory_callback factory; // The analyzer's factory callback. diff --git a/src/file_analysis/Component.cc b/src/file_analysis/Component.cc index 7869116392..3ed707313e 100644 --- a/src/file_analysis/Component.cc +++ b/src/file_analysis/Component.cc @@ -13,7 +13,11 @@ Component::Component(const std::string& name, factory_callback arg_factory, Tag: plugin::TaggedComponent(subtype) { factory = arg_factory; + } +void Component::Initialize() + { + InitializeTag(); file_mgr->RegisterComponent(this, "ANALYZER_"); } diff --git a/src/file_analysis/Component.h b/src/file_analysis/Component.h index 6e282da205..1a4d8a2fb6 100644 --- a/src/file_analysis/Component.h +++ b/src/file_analysis/Component.h @@ -54,6 +54,13 @@ public: */ ~Component(); + /** + * Initialization function. This function has to be called before any + * plugin component functionality is used; it is used to add the + * plugin component to the list of components and to initialize tags + */ + void Initialize() override; + /** * Returns the analyzer's factory function. */ @@ -63,7 +70,7 @@ protected: /** * Overriden from plugin::Component. */ - virtual void DoDescribe(ODesc* d) const; + void DoDescribe(ODesc* d) const override; private: factory_callback factory; // The analyzer's factory callback. diff --git a/src/input/Component.cc b/src/input/Component.cc index b7c5d5e30b..dbca5a2cf3 100644 --- a/src/input/Component.cc +++ b/src/input/Component.cc @@ -12,7 +12,11 @@ Component::Component(const std::string& name, factory_callback arg_factory) : plugin::Component(plugin::component::READER, name) { factory = arg_factory; + } +void Component::Initialize() + { + InitializeTag(); input_mgr->RegisterComponent(this, "READER_"); } diff --git a/src/input/Component.h b/src/input/Component.h index 0812aa63cf..ce24d447e5 100644 --- a/src/input/Component.h +++ b/src/input/Component.h @@ -39,6 +39,13 @@ public: */ ~Component(); + /** + * Initialization function. This function has to be called before any + * plugin component functionality is used; it is used to add the + * plugin component to the list of components and to initialize tags + */ + void Initialize() override; + /** * Returns the reader's factory function. */ @@ -48,7 +55,7 @@ protected: /** * Overriden from plugin::Component. */ - virtual void DoDescribe(ODesc* d) const; + void DoDescribe(ODesc* d) const override; private: factory_callback factory; diff --git a/src/logging/Component.cc b/src/logging/Component.cc index 3af29fd96f..570cccb8d7 100644 --- a/src/logging/Component.cc +++ b/src/logging/Component.cc @@ -11,7 +11,11 @@ Component::Component(const std::string& name, factory_callback arg_factory) : plugin::Component(plugin::component::WRITER, name) { factory = arg_factory; + } +void Component::Initialize() + { + InitializeTag(); log_mgr->RegisterComponent(this, "WRITER_"); } diff --git a/src/logging/Component.h b/src/logging/Component.h index 21e114b36c..a7ef2a0c31 100644 --- a/src/logging/Component.h +++ b/src/logging/Component.h @@ -39,6 +39,13 @@ public: */ ~Component(); + /** + * Initialization function. This function has to be called before any + * plugin component functionality is used; it is used to add the + * plugin component to the list of components and to initialize tags + */ + void Initialize() override; + /** * Returns the writer's factory function. */ @@ -48,7 +55,7 @@ protected: /** * Overriden from plugin::Component. */ - virtual void DoDescribe(ODesc* d) const; + void DoDescribe(ODesc* d) const override; private: factory_callback factory; diff --git a/src/plugin/Component.h b/src/plugin/Component.h index de24a7dbde..63ca66c8ef 100644 --- a/src/plugin/Component.h +++ b/src/plugin/Component.h @@ -48,6 +48,13 @@ public: */ virtual ~Component(); + /** + * Initialization function. This function has to be called before any + * plugin component functionality is used; it commonly is used to add the + * plugin component to the list of components and to initialize tags + */ + virtual void Initialize() {} + /** * Returns the compoment's type. */ diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index a449fb34e4..9ce7fb27dd 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -238,6 +238,7 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_ current_plugin->SetDynamic(true); current_plugin->DoConfigure(); + current_plugin->InitializeComponents(); if ( current_plugin->APIVersion() != BRO_PLUGIN_API_VERSION ) reporter->FatalError("plugin's API version does not match Bro (expected %d, got %d in %s)", @@ -328,9 +329,6 @@ void Manager::RegisterPlugin(Plugin *plugin) // A dynamic plugin, record its location. plugin->SetPluginLocation(current_dir, current_sopath); - // Sort plugins by name to make sure we have a deterministic order. - ActivePluginsInternal()->sort(plugin_cmp); - current_plugin = plugin; } @@ -354,9 +352,21 @@ void Manager::InitPreScript() for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin(); i != Manager::ActivePluginsInternal()->end(); i++ ) { - Plugin* plugin = *i; - plugin->DoConfigure(); - plugin->InitPreScript(); + (*i)->DoConfigure(); + } + + // Sort plugins by name to make sure we have a deterministic order. + // We cannot do this before, because the plugin name (used for plugin_cmp) is only + // set in DoConfigure. + // We need things sorted to generate the tags (in InitializeComponents) in a deterministic + // order. + ActivePluginsInternal()->sort(plugin_cmp); + + for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin(); + i != Manager::ActivePluginsInternal()->end(); i++ ) + { + (*i)->InitializeComponents(); + (*i)->InitPreScript(); } init = true; diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 190ae02cde..b0eb19a628 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -327,6 +327,12 @@ void Plugin::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgum { } +void Plugin::InitializeComponents() + { + for ( component_list::const_iterator i = components.begin(); i != components.end(); i++ ) + (*i)->Initialize(); + } + void Plugin::Describe(ODesc* d) const { d->Add(config.name); diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index e23173f726..adf1855e27 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -492,12 +492,14 @@ protected: virtual void Done(); /** - * Registers and activates a component. + * Registers a component. * * @param c The component. The method takes ownership. */ void AddComponent(Component* c); + void InitializeComponents(); + /** * Enables a hook. The corresponding virtual method will now be * called as Bro's processing proceeds. Note that enabling hooks can diff --git a/src/plugin/TaggedComponent.h b/src/plugin/TaggedComponent.h index 7e3ee24bdf..600a25aac7 100644 --- a/src/plugin/TaggedComponent.h +++ b/src/plugin/TaggedComponent.h @@ -23,6 +23,8 @@ public: */ TaggedComponent(typename T::subtype_t subtype = 0); + void InitializeTag(); + /** * @return The component's tag. */ @@ -30,6 +32,8 @@ public: private: T tag; /**< The automatically assigned analyzer tag. */ + typename T::subtype_t subtype; + bool initialized; static typename T::type_t type_counter; /**< Used to generate globally unique tags. */ }; @@ -37,12 +41,23 @@ private: template TaggedComponent::TaggedComponent(typename T::subtype_t subtype) { + tag = T(1,0); + this->subtype = subtype; + initialized = false; + } + +template +void TaggedComponent::InitializeTag() + { + assert( initialized == false ); + initialized = true; tag = T(++type_counter, subtype); } template T TaggedComponent::Tag() const { + assert( initialized ); return tag; }