Add script wrapper functions for broker BIFs

Also renamed the "print" function to "send_print" and the "event"
function to "send_event" because Bro shows a syntax error when a
Bro script function is named "event" or "print".
This commit is contained in:
Daniel Thayer 2016-04-26 16:24:10 -05:00
parent e9a87566ef
commit f44bb4d9b8
17 changed files with 747 additions and 407 deletions

View file

@ -1,5 +1,14 @@
##! Various data structure definitions for use with Bro's communication system.
module Log;
export {
type Log::ID: enum {
## Dummy place-holder.
UNKNOWN
};
}
module Broker;
export {
@ -52,4 +61,312 @@ export {
key: Broker::Data;
val: Broker::Data;
};
## Enable use of communication.
##
## flags: used to tune the local Broker endpoint behavior.
##
## Returns: true if communication is successfully initialized.
global enable: function(flags: EndpointFlags &default = EndpointFlags()): bool;
## Changes endpoint flags originally supplied to :bro:see:`Broker::enable`.
##
## flags: the new endpoint behavior flags to use.
##
## Returns: true if flags were changed.
global set_endpoint_flags: function(flags: EndpointFlags &default = EndpointFlags()): bool;
## Allow sending messages to peers if associated with the given topic.
## This has no effect if auto publication behavior is enabled via the flags
## supplied to :bro:see:`Broker::enable` or :bro:see:`Broker::set_endpoint_flags`.
##
## topic: a topic to allow messages to be published under.
##
## Returns: true if successful.
global publish_topic: function(topic: string): bool;
## Disallow sending messages to peers if associated with the given topic.
## This has no effect if auto publication behavior is enabled via the flags
## supplied to :bro:see:`Broker::enable` or :bro:see:`Broker::set_endpoint_flags`.
##
## topic: a topic to disallow messages to be published under.
##
## Returns: true if successful.
global unpublish_topic: function(topic: string): bool;
## Listen for remote connections.
##
## p: the TCP port to listen on.
##
## a: an address string on which to accept connections, e.g.
## "127.0.0.1". An empty string refers to @p INADDR_ANY.
##
## reuse: equivalent to behavior of SO_REUSEADDR.
##
## Returns: true if the local endpoint is now listening for connections.
##
## .. bro:see:: Broker::incoming_connection_established
global listen: function(p: port, a: string &default = "", reuse: bool &default = T): bool;
## Initiate a remote connection.
##
## a: an address to connect to, e.g. "localhost" or "127.0.0.1".
##
## p: the TCP port on which the remote side is listening.
##
## retry: an interval at which to retry establishing the
## connection with the remote peer if it cannot be made initially, or
## if it ever becomes disconnected.
##
## Returns: true if it's possible to try connecting with the peer and
## it's a new peer. The actual connection may not be established
## until a later point in time.
##
## .. bro:see:: Broker::outgoing_connection_established
global connect: function(a: string, p: port, retry: interval): bool;
## Remove a remote connection.
##
## a: the address used in previous successful call to :bro:see:`Broker::connect`.
##
## p: the port used in previous successful call to :bro:see:`Broker::connect`.
##
## Returns: true if the arguments match a previously successful call to
## :bro:see:`Broker::connect`.
global disconnect: function(a: string, p: port): bool;
## Print a simple message to any interested peers. The receiver can use
## :bro:see:`Broker::print_handler` to handle messages.
##
## topic: a topic associated with the printed message.
##
## msg: the print message to send to peers.
##
## flags: tune the behavior of how the message is sent.
##
## Returns: true if the message is sent.
global send_print: function(topic: string, msg: string, flags: SendFlags &default = SendFlags()): bool;
## Register interest in all peer print messages that use a certain topic
## prefix. Use :bro:see:`Broker::print_handler` to handle received
## messages.
##
## topic_prefix: a prefix to match against remote message topics.
## e.g. an empty prefix matches everything and "a" matches
## "alice" and "amy" but not "bob".
##
## Returns: true if it's a new print subscription and it is now registered.
global subscribe_to_prints: function(topic_prefix: string): bool;
## Unregister interest in all peer print messages that use a topic prefix.
##
## topic_prefix: a prefix previously supplied to a successful call to
## :bro:see:`Broker::subscribe_to_prints`.
##
## Returns: true if interest in the topic prefix is no longer advertised.
global unsubscribe_to_prints: function(topic_prefix: string): bool;
## Send an event to any interested peers.
##
## topic: a topic associated with the event message.
##
## args: event arguments as made by :bro:see:`Broker::event_args`.
##
## flags: tune the behavior of how the message is sent.
##
## Returns: true if the message is sent.
global send_event: function(topic: string, args: EventArgs, flags: SendFlags &default = SendFlags()): bool;
## Automatically send an event to any interested peers whenever it is
## locally dispatched (e.g. using "event my_event(...);" in a script).
##
## topic: a topic string associated with the event message.
## Peers advertise interest by registering a subscription to some
## prefix of this topic name.
##
## ev: a Bro event value.
##
## flags: tune the behavior of how the message is sent.
##
## Returns: true if automatic event sending is now enabled.
global auto_event: function(topic: string, ev: any, flags: SendFlags &default = SendFlags()): bool;
## Stop automatically sending an event to peers upon local dispatch.
##
## topic: a topic originally given to :bro:see:`Broker::auto_event`.
##
## ev: an event originally given to :bro:see:`Broker::auto_event`.
##
## Returns: true if automatic events will not occur for the topic/event
## pair.
global auto_event_stop: function(topic: string, ev: any): bool;
## Register interest in all peer event messages that use a certain topic
## prefix.
##
## topic_prefix: a prefix to match against remote message topics.
## e.g. an empty prefix matches everything and "a" matches
## "alice" and "amy" but not "bob".
##
## Returns: true if it's a new event subscription and it is now registered.
global subscribe_to_events: function(topic_prefix: string): bool;
## Unregister interest in all peer event messages that use a topic prefix.
##
## topic_prefix: a prefix previously supplied to a successful call to
## :bro:see:`Broker::subscribe_to_events`.
##
## Returns: true if interest in the topic prefix is no longer advertised.
global unsubscribe_to_events: function(topic_prefix: string): bool;
## Enable remote logs for a given log stream.
##
## id: the log stream to enable remote logs for.
##
## flags: tune the behavior of how log entry messages are sent.
##
## Returns: true if remote logs are enabled for the stream.
global enable_remote_logs: function(id: Log::ID, flags: SendFlags &default = SendFlags()): bool;
## Disable remote logs for a given log stream.
##
## id: the log stream to disable remote logs for.
##
## Returns: true if remote logs are disabled for the stream.
global disable_remote_logs: function(id: Log::ID): bool;
## Check if remote logs are enabled for a given log stream.
##
## id: the log stream to check.
##
## Returns: true if remote logs are enabled for the given stream.
global remote_logs_enabled: function(id: Log::ID): bool;
## Register interest in all peer log messages that use a certain topic
## prefix. Logs are implicitly sent with topic "bro/log/<stream-name>" and
## the receiving side processes them through the logging framework as usual.
##
## topic_prefix: a prefix to match against remote message topics.
## e.g. an empty prefix matches everything and "a" matches
## "alice" and "amy" but not "bob".
##
## Returns: true if it's a new log subscription and it is now registered.
global subscribe_to_logs: function(topic_prefix: string): bool;
## Unregister interest in all peer log messages that use a topic prefix.
## Logs are implicitly sent with topic "bro/log/<stream-name>" and the
## receiving side processes them through the logging framework as usual.
##
## topic_prefix: a prefix previously supplied to a successful call to
## :bro:see:`Broker::subscribe_to_logs`.
##
## Returns: true if interest in the topic prefix is no longer advertised.
global unsubscribe_to_logs: function(topic_prefix: string): bool;
}
@load base/bif/comm.bif
@load base/bif/messaging.bif
module Broker;
function enable(flags: EndpointFlags &default = EndpointFlags()) : bool
{
return __enable(flags);
}
function set_endpoint_flags(flags: EndpointFlags &default = EndpointFlags()): bool
{
return __set_endpoint_flags(flags);
}
function publish_topic(topic: string): bool
{
return __publish_topic(topic);
}
function unpublish_topic(topic: string): bool
{
return __unpublish_topic(topic);
}
function listen(p: port, a: string &default = "", reuse: bool &default = T): bool
{
return __listen(p, a, reuse);
}
function connect(a: string, p: port, retry: interval): bool
{
return __connect(a, p, retry);
}
function disconnect(a: string, p: port): bool
{
return __disconnect(a, p);
}
function send_print(topic: string, msg: string, flags: SendFlags &default = SendFlags()): bool
{
return __send_print(topic, msg, flags);
}
function subscribe_to_prints(topic_prefix: string): bool
{
return __subscribe_to_prints(topic_prefix);
}
function unsubscribe_to_prints(topic_prefix: string): bool
{
return __unsubscribe_to_prints(topic_prefix);
}
function send_event(topic: string, args: EventArgs, flags: SendFlags &default = SendFlags()): bool
{
return __event(topic, args, flags);
}
function auto_event(topic: string, ev: any, flags: SendFlags &default = SendFlags()): bool
{
return __auto_event(topic, ev, flags);
}
function auto_event_stop(topic: string, ev: any): bool
{
return __auto_event_stop(topic, ev);
}
function subscribe_to_events(topic_prefix: string): bool
{
return __subscribe_to_events(topic_prefix);
}
function unsubscribe_to_events(topic_prefix: string): bool
{
return __unsubscribe_to_events(topic_prefix);
}
function enable_remote_logs(id: Log::ID, flags: SendFlags &default = SendFlags()): bool
{
return __enable_remote_logs(id, flags);
}
function disable_remote_logs(id: Log::ID): bool
{
return __disable_remote_logs(id);
}
function remote_logs_enabled(id: Log::ID): bool
{
return __remote_logs_enabled(id);
}
function subscribe_to_logs(topic_prefix: string): bool
{
return __subscribe_to_logs(topic_prefix);
}
function unsubscribe_to_logs(topic_prefix: string): bool
{
return __unsubscribe_to_logs(topic_prefix);
}

View file

@ -31,6 +31,13 @@ export {
result: Broker::Data;
};
## Enumerates the possible storage backends.
type BackendType: enum {
MEMORY,
SQLITE,
ROCKSDB,
};
## Options to tune the SQLite storage backend.
type SQLiteOptions: record {
## File system path of the database.
@ -48,4 +55,341 @@ export {
sqlite: SQLiteOptions &default = SQLiteOptions();
rocksdb: RocksDBOptions &default = RocksDBOptions();
};
## Create a master data store which contains key-value pairs.
##
## id: a unique name for the data store.
##
## b: the storage backend to use.
##
## options: tunes how some storage backends operate.
##
## Returns: a handle to the data store.
global create_master: function(id: string, b: BackendType &default = MEMORY,
options: BackendOptions &default = BackendOptions()): opaque of Broker::Handle;
## Create a clone of a master data store which may live with a remote peer.
## A clone automatically synchronizes to the master by automatically
## receiving modifications and applying them locally. Direct modifications
## are not possible, they must be sent through the master store, which then
## automatically broadcasts the changes out to clones. But queries may be
## made directly against the local cloned copy, which may be resolved
## quicker than reaching out to a remote master store.
##
## id: the unique name which identifies the master data store.
##
## b: the storage backend to use.
##
## options: tunes how some storage backends operate.
##
## resync: the interval at which to re-attempt synchronizing with the master
## store should the connection be lost. If the clone has not yet
## synchronized for the first time, updates and queries queue up
## until the synchronization completes. After, if the connection
## to the master store is lost, queries continue to use the clone's
## version, but updates will be lost until the master is once again
## available.
##
## Returns: a handle to the data store.
global create_clone: function(id: string, b: BackendType &default = MEMORY,
options: BackendOptions &default = BackendOptions(),
resync: interval &default = 1sec): opaque of Broker::Handle;
## Create a frontend interface to an existing master data store that allows
## querying and updating its contents.
##
## id: the unique name which identifies the master data store.
##
## Returns: a handle to the data store.
global create_frontend: function(id: string): opaque of Broker::Handle;
## Close a data store.
##
## h: a data store handle.
##
## Returns: true if store was valid and is now closed. The handle can no
## longer be used for data store operations.
global close_by_handle: function(h: opaque of Broker::Handle): bool;
###########################
# non-blocking update API #
###########################
## Insert a key-value pair in to the store.
##
## h: the handle of the store to modify.
##
## k: the key to insert.
##
## v: the value to insert.
##
## e: the expiration time of the key-value pair.
##
## Returns: false if the store handle was not valid.
global insert: function(h: opaque of Broker::Handle,
k: Broker::Data, v: Broker::Data,
e: Broker::ExpiryTime &default = Broker::ExpiryTime()): bool;
## Remove a key-value pair from the store.
##
## h: the handle of the store to modify.
##
## k: the key to remove.
##
## Returns: false if the store handle was not valid.
global erase: function(h: opaque of Broker::Handle, k: Broker::Data): bool;
## Remove all key-value pairs from the store.
##
## h: the handle of the store to modify.
##
## Returns: false if the store handle was not valid.
global clear: function(h: opaque of Broker::Handle): bool;
## Increment an integer value in a data store.
##
## h: the handle of the store to modify.
##
## k: the key whose associated value is to be modified.
##
## by: the amount to increment the value by. A non-existent key will first
## create it with an implicit value of zero before incrementing.
##
## Returns: false if the store handle was not valid.
global increment: function(h: opaque of Broker::Handle,
k: Broker::Data, by: int &default = +1): bool;
## Decrement an integer value in a data store.
##
## h: the handle of the store to modify.
##
## k: the key whose associated value is to be modified.
##
## by: the amount to decrement the value by. A non-existent key will first
## create it with an implicit value of zero before decrementing.
##
## Returns: false if the store handle was not valid.
global decrement: function(h: opaque of Broker::Handle,
k: Broker::Data, by: int &default = +1): bool;
## Add an element to a set value in a data store.
##
## h: the handle of the store to modify.
##
## k: the key whose associated value is to be modified.
##
## element: the element to add to the set. A non-existent key will first
## create it with an implicit empty set value before modifying.
##
## Returns: false if the store handle was not valid.
global add_to_set: function(h: opaque of Broker::Handle,
k: Broker::Data, element: Broker::Data): bool;
## Remove an element from a set value in a data store.
##
## h: the handle of the store to modify.
##
## k: the key whose associated value is to be modified.
##
## element: the element to remove from the set. A non-existent key will
## implicitly create an empty set value associated with the key.
##
## Returns: false if the store handle was not valid.
global remove_from_set: function(h: opaque of Broker::Handle,
k: Broker::Data, element: Broker::Data): bool;
## Add a new item to the head of a vector value in a data store.
##
## h: the handle of store to modify.
##
## k: the key whose associated value is to be modified.
##
## items: the element to insert in to the vector. A non-existent key will
## first create an empty vector value before modifying.
##
## Returns: false if the store handle was not valid.
global push_left: function(h: opaque of Broker::Handle, k: Broker::Data,
items: Broker::DataVector): bool;
## Add a new item to the tail of a vector value in a data store.
##
## h: the handle of store to modify.
##
## k: the key whose associated value is to be modified.
##
## items: the element to insert in to the vector. A non-existent key will
## first create an empty vector value before modifying.
##
## Returns: false if the store handle was not valid.
global push_right: function(h: opaque of Broker::Handle, k: Broker::Data,
items: Broker::DataVector): bool;
##########################
# non-blocking query API #
##########################
## Pop the head of a data store vector value.
##
## h: the handle of the store to query.
##
## k: the key associated with the vector to modify.
##
## Returns: the result of the query.
global pop_left: function(h: opaque of Broker::Handle,
k: Broker::Data): QueryResult;
## Pop the tail of a data store vector value.
##
## h: the handle of the store to query.
##
## k: the key associated with the vector to modify.
##
## Returns: the result of the query.
global pop_right: function(h: opaque of Broker::Handle,
k: Broker::Data): QueryResult;
## Lookup the value associated with a key in a data store.
##
## h: the handle of the store to query.
##
## k: the key to lookup.
##
## Returns: the result of the query.
global lookup: function(h: opaque of Broker::Handle,
k: Broker::Data): QueryResult;
## Check if a data store contains a given key.
##
## h: the handle of the store to query.
##
## k: the key to check for existence.
##
## Returns: the result of the query (uses :bro:see:`Broker::BOOL`).
global exists: function(h: opaque of Broker::Handle,
k: Broker::Data): QueryResult;
## Retrieve all keys in a data store.
##
## h: the handle of the store to query.
##
## Returns: the result of the query (uses :bro:see:`Broker::VECTOR`).
global keys: function(h: opaque of Broker::Handle): QueryResult;
## Get the number of key-value pairs in a data store.
##
## h: the handle of the store to query.
##
## Returns: the result of the query (uses :bro:see:`Broker::COUNT`).
global size: function(h: opaque of Broker::Handle): QueryResult;
}
@load base/bif/store.bif
module Broker;
function create_master(id: string, b: BackendType &default = MEMORY,
options: BackendOptions &default = BackendOptions()): opaque of Broker::Handle
{
return __create_master(id, b, options);
}
function create_clone(id: string, b: BackendType &default = MEMORY,
options: BackendOptions &default = BackendOptions(),
resync: interval &default = 1sec): opaque of Broker::Handle
{
return __create_clone(id, b, options, resync);
}
function create_frontend(id: string): opaque of Broker::Handle
{
return __create_frontend(id);
}
function close_by_handle(h: opaque of Broker::Handle): bool
{
return __close_by_handle(h);
}
function insert(h: opaque of Broker::Handle, k: Broker::Data, v: Broker::Data,
e: Broker::ExpiryTime &default = Broker::ExpiryTime()): bool
{
return __insert(h, k, v, e);
}
function erase(h: opaque of Broker::Handle, k: Broker::Data): bool
{
return __erase(h, k);
}
function clear(h: opaque of Broker::Handle): bool
{
return __clear(h);
}
function increment(h: opaque of Broker::Handle,
k: Broker::Data, by: int &default = +1): bool
{
return __increment(h, k, by);
}
function decrement(h: opaque of Broker::Handle,
k: Broker::Data, by: int &default = +1): bool
{
return __decrement(h, k, by);
}
function add_to_set(h: opaque of Broker::Handle,
k: Broker::Data, element: Broker::Data): bool
{
return __add_to_set(h, k, element);
}
function remove_from_set(h: opaque of Broker::Handle,
k: Broker::Data, element: Broker::Data): bool
{
return __remove_from_set(h, k, element);
}
function push_left(h: opaque of Broker::Handle, k: Broker::Data,
items: Broker::DataVector): bool
{
return __push_left(h, k, items);
}
function push_right(h: opaque of Broker::Handle, k: Broker::Data,
items: Broker::DataVector): bool
{
return __push_right(h, k, items);
}
function pop_left(h: opaque of Broker::Handle, k: Broker::Data): QueryResult
{
return __pop_left(h, k);
}
function pop_right(h: opaque of Broker::Handle, k: Broker::Data): QueryResult
{
return __pop_right(h, k);
}
function lookup(h: opaque of Broker::Handle, k: Broker::Data): QueryResult
{
return __lookup(h, k);
}
function exists(h: opaque of Broker::Handle, k: Broker::Data): QueryResult
{
return __exists(h, k);
}
function keys(h: opaque of Broker::Handle): QueryResult
{
return __keys(h);
}
function size(h: opaque of Broker::Handle): QueryResult
{
return __size(h);
}

View file

@ -227,7 +227,7 @@ function acld_add_rule_fun(p: PluginState, r: Rule) : bool
if ( ar$command == "" )
return F;
Broker::event(p$acld_config$acld_topic, Broker::event_args(acld_add_rule, p$acld_id, r, ar));
Broker::send_event(p$acld_config$acld_topic, Broker::event_args(acld_add_rule, p$acld_id, r, ar));
return T;
}
@ -242,7 +242,7 @@ function acld_remove_rule_fun(p: PluginState, r: Rule) : bool
else
return F;
Broker::event(p$acld_config$acld_topic, Broker::event_args(acld_remove_rule, p$acld_id, r, ar));
Broker::send_event(p$acld_config$acld_topic, Broker::event_args(acld_remove_rule, p$acld_id, r, ar));
return T;
}

View file

@ -96,13 +96,13 @@ function broker_name(p: PluginState) : string
function broker_add_rule_fun(p: PluginState, r: Rule) : bool
{
Broker::event(p$broker_topic, Broker::event_args(broker_add_rule, p$broker_id, r));
Broker::send_event(p$broker_topic, Broker::event_args(broker_add_rule, p$broker_id, r));
return T;
}
function broker_remove_rule_fun(p: PluginState, r: Rule) : bool
{
Broker::event(p$broker_topic, Broker::event_args(broker_remove_rule, p$broker_id, r));
Broker::send_event(p$broker_topic, Broker::event_args(broker_remove_rule, p$broker_id, r));
return T;
}

View file

@ -47,14 +47,14 @@ function broker_describe(state: ControllerState): string
function broker_flow_mod_fun(state: ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool
{
Broker::event(state$broker_topic, Broker::event_args(broker_flow_mod, state$_name, state$broker_dpid, match, flow_mod));
Broker::send_event(state$broker_topic, Broker::event_args(broker_flow_mod, state$_name, state$broker_dpid, match, flow_mod));
return T;
}
function broker_flow_clear_fun(state: OpenFlow::ControllerState): bool
{
Broker::event(state$broker_topic, Broker::event_args(broker_flow_clear, state$_name, state$broker_dpid));
Broker::send_event(state$broker_topic, Broker::event_args(broker_flow_clear, state$_name, state$broker_dpid));
return T;
}