Merge remote-tracking branch 'origin/master' into topic/robin/reader-writer-plugins

This commit is contained in:
Robin Sommer 2014-07-31 14:45:38 -07:00
commit 0ba4b768cd
12 changed files with 107 additions and 60 deletions

84
CHANGES
View file

@ -1,71 +1,69 @@
2.3-86 | 2014-07-31 14:19:58 -0700
* Fix for redefining built-in constants. (Robin Sommer)
* Adding missing check that a plugin's API version matches what Bro
defines. (Robin Sommer)
* Adding NEWS entry for plugins. (Robin Sommer)
2.3-83 | 2014-07-30 16:26:11 -0500
* Minor adjustments to plugin code/docs. (Jon Siwek)
* Dynamic plugin support. (Robin Sommer)
* Dynamic plugin support. (Rpbin Sommer)
- An overview of main functionality is in doc/devel/plugins.rst.
Bro now supports extending core functionality, like protocol and
file analysis, dynamically with external plugins in the form of
shared libraries. See doc/devel/plugins.rst for an overview of the
main functionality. Changes coming with this:
- This removes the old Plugin macro magic, and hence touches all the
existing analyzers to move them to the new API.
- Replacing the old Plugin macro magic with a new API.
- The plugin API changed to generally use std::strings instead of
const char*.
- The plugin API changed to generally use std::strings instead
of const char*.
- There are a number of invocations of PLUGIN_HOOK_
{VOID,WITH_RESULT} across the code base, which allow plugins to
hook into the processing at those locations. These are macros to
make sure the overhead remains as low as possible when no plugin
actually defines a hook (i.e., the normal case). See
src/plugin/Manager.h for the macros' definition.
{VOID,WITH_RESULT} across the code base, which allow plugins
to hook into the processing at those locations.
- There's one hook which could be potentially expensive: plugins can
be notified if a BroObj they are interested in gets destroyed. But
I didn't see a performance impact in my tests (with no such hook
defined), and the memory usage doesn't change due to field
alignment.
- Adds a few new accessor methods to various classes to allow
- A few new accessor methods to various classes to allow
plugins to get to that information.
- network_time cannot be just assigned to anymore, there's now
function net_update_time() for that.
- Redos how builtin variables are initialized, so that it
works for plugins as well. No more init_net_var(), but instead
bifcl-generated code that registers them.
- Redoing how builtin variables are initialized, so that it
works for plugins as well. No more init_net_var(), but
instead bifcl-generated code that registers them.
- Various changes for adjusting to the now dynamic generation
of analyzer instances.
- same_type() gets an optional extra argument allowing record type
comparision to ignore if field names don't match.
comparision to ignore if field names don't match. (Robin Sommer)
- There are various changes for adjusting to the now dynamic
generation of analyzer instances.
- Further unify file analysis API with the protocol analyzer API
(assigning IDs to analyzers; adding Init()/Done() methods;
adding subtypes). (Robin Sommer)
- The file analysis API gets unified further with the protocol
analyzer API (assigning IDs to analyzers; adding Init()/Done()
methods; adding subtypes).
- A new command line option -Q that prints some basic execution
time stats. (Robin Sommer)
- Adding a new command line option -Q that prints some basic
execution time stats. Seems generally useful, and I'm planing
to provide a plugin hook for measuring custom stuff.
- Add support to the file analysis for activating analyzers by
MIME type. (Robin Sommer)
- I'm not yet happy with the current conventions for the C++
namespaces that plugins are in. I'm planing to clean that up later
though, as I have some more branches relying on the current scheme
and it will be easier to clean things up once everything is in.
- File::register_for_mime_type(tag: Analyzer::Tag, mt:
string): Associates a file analyzer with a MIME type.
- There's a new piece of functionality for the file analysis
framework: activate analyzers by MIME type. Pieces going in there:
- File::register_for_mime_type(tag: Analyzer::Tag, mt: string):
Associates a file analyzer with a MIME type.
- File::add_analyzers_for_mime_type(f: fa_file, mtype: string):
Activates all analyzers registered for a MIME type for the file.
- File::add_analyzers_for_mime_type(f: fa_file, mtype:
string): Activates all analyzers registered for a MIME
type for the file.
- The default file_new() handler calls
File::add_analyzers_for_mime_type() with the file's MIME type.
File::add_analyzers_for_mime_type() with the file's MIME
type.
2.3-20 | 2014-07-22 17:41:02 -0700

25
NEWS
View file

@ -4,6 +4,31 @@ release. For an exhaustive list of changes, see the ``CHANGES`` file
(note that submodules, such as BroControl and Broccoli, come with
their own ``CHANGES``.)
Bro 2.4 (in progress)
=====================
Dependencies
------------
New Functionality
-----------------
- Bro now has support for external plugins that can extend its core
functionality, like protocol/file analysis, via shared libraries.
Plugins can be developed and distributed externally, and will be
pulled in dynamically at startup. Currently, a plugin can provide
custom protocol analyzers, file analyzers, log writers[TODO], input
readers[TODO], packet sources[TODO], and new built-in functions. A
plugin can furthermore hook into Bro's processing a number of places
to add custom logic.
See http://www.bro.org/sphinx-git/devel/plugins.html for more
information on writing plugins.
Changed Functionality
---------------------
Bro 2.3
=======

View file

@ -1 +1 @@
2.3-83
2.3-86

View file

@ -628,11 +628,14 @@ void init_builtin_funcs()
#include "reporter.bif.func_init"
#include "strings.bif.func_init"
#include "__all__.bif.init.cc" // Autogenerated for compiling in the bif_target() code.
did_builtin_init = true;
}
void init_builtin_funcs_subdirs()
{
#include "__all__.bif.init.cc" // Autogenerated for compiling in the bif_target() code.
}
bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
{
if ( f->TheFunc() != BifFunc::bro_fmt )

View file

@ -134,6 +134,7 @@ protected:
extern void builtin_error(const char* msg, BroObj* arg = 0);
extern void init_builtin_funcs();
extern void init_builtin_funcs_subdirs();
extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call);

View file

@ -55,6 +55,7 @@ Tag& Tag::operator=(const Tag& other)
{
type = other.type;
subtype = other.subtype;
Unref(val);
val = other.val;
if ( val )

View file

@ -898,6 +898,7 @@ int main(int argc, char** argv)
init_general_global_var();
init_net_var();
init_builtin_funcs_subdirs();
plugin_mgr->InitBifs();

View file

@ -219,6 +219,10 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_
current_plugin->SetDynamic(true);
current_plugin->DoConfigure();
if ( current_plugin->APIVersion() != BRO_PLUGIN_API_VERSION )
reporter->FatalError("plugin's API version does not match Bro (expected %d, got %d in %s)",
BRO_PLUGIN_API_VERSION, current_plugin->APIVersion(), path);
// We execute the pre-script initialization here; this in
// fact could be *during* script initialization if we got
// triggered via @load-plugin.

View file

@ -33,13 +33,6 @@ 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;

View file

@ -10,7 +10,10 @@
#include "analyzer/Component.h"
#include "file_analysis/Component.h"
static const int BRO_PLUGIN_API_VERSION = 2;
// We allow to override this externally for testing purposes.
#ifndef BRO_PLUGIN_API_VERSION
#define BRO_PLUGIN_API_VERSION 2
#endif
class ODesc;
class Func;
@ -75,13 +78,23 @@ public:
std::string description; //< A short textual description of the plugin. Mandatory.
VersionNumber version; //< THe plugin's version. Optional.
Configuration();
// We force this to inline so that the API version gets hardcoded
// into the external plugin. (Technically, it's not a "force", just a
// strong hint.). The attribute seems generally available.
inline Configuration() __attribute__((always_inline));
private:
friend class Plugin;
int api_version; // Current BRO_PLUGIN_API_VERSION. Automatically set.
};
inline Configuration::Configuration()
{
name = "";
description = "";
api_version = BRO_PLUGIN_API_VERSION;
}
/**
* A class describing an item defined in \c *.bif file.
*/

View file

@ -0,0 +1 @@
fatal error in /home/robin/bro/master/scripts/base/init-bare.bro, line 1: plugin's API version does not match Bro (expected 2, got 42 in /home/robin/bro/master/testing/btest/.tmp/plugins.api-version-mismatch//lib/Demo-Foo.linux-x86_64.so)

View file

@ -0,0 +1,7 @@
# @TEST-EXEC: ${DIST}/aux/bro-aux/plugin-support/init-plugin Demo Foo
# @TEST-EXEC: bash %INPUT
# @TEST-EXEC: make BRO=${DIST}
# @TEST-EXEC-FAIL: BRO_PLUGIN_PATH=`pwd` bro -NN Demo::Foo >>output 2>&1
# @TEST-EXEC: btest-diff output
( echo '#define BRO_PLUGIN_API_VERSION 42'; cat src/Plugin.cc; ) >src/Plugin.cc.tmp && mv src/Plugin.cc.tmp src/Plugin.cc