mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
241 lines
6.7 KiB
C++
241 lines
6.7 KiB
C++
|
|
##! Functions for peering and various messaging patterns.
|
|
|
|
%%{
|
|
#include "broker/Manager.h"
|
|
#include "logging/Manager.h"
|
|
#include <set>
|
|
#include <string>
|
|
|
|
static bool is_string_set(const zeek::Type* type)
|
|
{
|
|
if ( ! type->IsSet() )
|
|
return false;
|
|
|
|
const auto& index_types = type->AsSetType()->GetIndexTypes();
|
|
|
|
if ( index_types.size() != 1 )
|
|
return false;
|
|
|
|
return index_types[0]->Tag() == zeek::TYPE_STRING;
|
|
}
|
|
|
|
std::set<std::string> val_to_topic_set(zeek::Val* val)
|
|
{
|
|
std::set<std::string> rval;
|
|
|
|
if ( val->GetType()->Tag() == zeek::TYPE_STRING )
|
|
rval.emplace(val->AsString()->CheckString());
|
|
else
|
|
{
|
|
const zeek::PDict<zeek::TableEntryVal>* tbl = val->AsTable();
|
|
|
|
if ( tbl->Length() == 0 )
|
|
return rval;
|
|
|
|
zeek::IterCookie* c = tbl->InitForIteration();
|
|
zeek::detail::HashKey* k;
|
|
|
|
while ( tbl->NextEntry(k, c) )
|
|
{
|
|
auto index = val->AsTableVal()->RecreateIndex(*k);
|
|
rval.emplace(index->Idx(0)->AsString()->CheckString());
|
|
delete k;
|
|
}
|
|
}
|
|
|
|
return rval;
|
|
}
|
|
|
|
static bool publish_event_args(val_list& args, const zeek::String* topic,
|
|
zeek::detail::Frame* frame)
|
|
{
|
|
zeek::Broker::Manager::ScriptScopeGuard ssg;
|
|
auto rval = false;
|
|
|
|
if ( args[0]->GetType()->Tag() == zeek::TYPE_RECORD )
|
|
rval = zeek::broker_mgr->PublishEvent(topic->CheckString(),
|
|
args[0]->AsRecordVal());
|
|
else
|
|
{
|
|
auto ev = zeek::broker_mgr->MakeEvent(&args, frame);
|
|
rval = zeek::broker_mgr->PublishEvent(topic->CheckString(), ev);
|
|
Unref(ev);
|
|
}
|
|
|
|
return rval;
|
|
}
|
|
|
|
%%}
|
|
|
|
module Broker;
|
|
|
|
type Broker::Event: record;
|
|
|
|
## Create a data structure that may be used to send a remote event via
|
|
## :zeek:see:`Broker::publish`.
|
|
##
|
|
## args: an event, followed by a list of argument values that may be used
|
|
## to call it.
|
|
##
|
|
## Returns: opaque communication data that may be used to send a remote
|
|
## event.
|
|
function Broker::make_event%(...%): Broker::Event
|
|
%{
|
|
zeek::Broker::Manager::ScriptScopeGuard ssg;
|
|
const auto& bif_args = @ARGS@;
|
|
val_list args(bif_args->size());
|
|
|
|
for ( auto i = 0u; i < bif_args->size(); ++i )
|
|
args.push_back((*bif_args)[i].get());
|
|
|
|
return RecordValPtr{zeek::AdoptRef{}, zeek::broker_mgr->MakeEvent(&args, frame)};
|
|
%}
|
|
|
|
## Publishes an event at a given topic.
|
|
##
|
|
## topic: a topic associated with the event message.
|
|
##
|
|
## args: Either the event arguments as already made by
|
|
## :zeek:see:`Broker::make_event` or the argument list to pass along
|
|
## to it.
|
|
##
|
|
## Returns: true if the message is sent.
|
|
function Broker::publish%(topic: string, ...%): bool
|
|
%{
|
|
const auto& bif_args = @ARGS@;
|
|
val_list args(bif_args->size() - 1);
|
|
|
|
for ( auto i = 1u; i < bif_args->size(); ++i )
|
|
args.push_back((*bif_args)[i].get());
|
|
|
|
auto rval = publish_event_args(args, topic->AsString(), frame);
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|
|
|
|
function Broker::__flush_logs%(%): count
|
|
%{
|
|
auto rval = zeek::broker_mgr->FlushLogBuffers();
|
|
return zeek::val_mgr->Count(static_cast<uint64_t>(rval));
|
|
%}
|
|
|
|
function Broker::__publish_id%(topic: string, id: string%): bool
|
|
%{
|
|
zeek::Broker::Manager::ScriptScopeGuard ssg;
|
|
auto rval = zeek::broker_mgr->PublishIdentifier(topic->CheckString(),
|
|
id->CheckString());
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|
|
|
|
function Broker::__auto_publish%(topic: string, ev: any%): bool
|
|
%{
|
|
zeek::Broker::Manager::ScriptScopeGuard ssg;
|
|
auto rval = zeek::broker_mgr->AutoPublishEvent(topic->CheckString(), ev);
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|
|
|
|
function Broker::__auto_unpublish%(topic: string, ev: any%): bool
|
|
%{
|
|
zeek::Broker::Manager::ScriptScopeGuard ssg;
|
|
auto rval = zeek::broker_mgr->AutoUnpublishEvent(topic->CheckString(), ev);
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|
|
|
|
function Broker::__subscribe%(topic_prefix: string%): bool
|
|
%{
|
|
zeek::Broker::Manager::ScriptScopeGuard ssg;
|
|
auto rval = zeek::broker_mgr->Subscribe(topic_prefix->CheckString());
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|
|
|
|
function Broker::__forward%(topic_prefix: string%): bool
|
|
%{
|
|
zeek::Broker::Manager::ScriptScopeGuard ssg;
|
|
auto rval = zeek::broker_mgr->Forward(topic_prefix->CheckString());
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|
|
|
|
function Broker::__unsubscribe%(topic_prefix: string%): bool
|
|
%{
|
|
zeek::Broker::Manager::ScriptScopeGuard ssg;
|
|
auto rval = zeek::broker_mgr->Unsubscribe(topic_prefix->CheckString());
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|
|
|
|
module Cluster;
|
|
|
|
type Cluster::Pool: record;
|
|
|
|
## Publishes an event to a node within a pool according to Round-Robin
|
|
## distribution strategy.
|
|
##
|
|
## pool: the pool of nodes that are eligible to receive the event.
|
|
##
|
|
## key: an arbitrary string to identify the purpose for which you're
|
|
## distributing the event. e.g. consider using namespacing of your
|
|
## script like "Intel::cluster_rr_key".
|
|
##
|
|
## args: Either the event arguments as already made by
|
|
## :zeek:see:`Broker::make_event` or the argument list to pass along
|
|
## to it.
|
|
##
|
|
## Returns: true if the message is sent.
|
|
function Cluster::publish_rr%(pool: Pool, key: string, ...%): bool
|
|
%{
|
|
static zeek::Func* topic_func = nullptr;
|
|
|
|
if ( ! topic_func )
|
|
topic_func = zeek::detail::global_scope()->Find("Cluster::rr_topic")->GetVal()->AsFunc();
|
|
|
|
zeek::Args vl{{zeek::NewRef{}, pool}, {zeek::NewRef{}, key}};
|
|
auto topic = topic_func->Invoke(&vl);
|
|
|
|
if ( ! topic->AsString()->Len() )
|
|
return zeek::val_mgr->False();
|
|
|
|
const auto& bif_args = @ARGS@;
|
|
val_list args(bif_args->size() - 2);
|
|
|
|
for ( auto i = 2u; i < bif_args->size(); ++i )
|
|
args.push_back((*bif_args)[i].get());
|
|
|
|
auto rval = publish_event_args(args, topic->AsString(), frame);
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|
|
|
|
|
|
## Publishes an event to a node within a pool according to Rendezvous
|
|
## (Highest Random Weight) hashing strategy.
|
|
##
|
|
## pool: the pool of nodes that are eligible to receive the event.
|
|
##
|
|
## key: data used for input to the hashing function that will uniformly
|
|
## distribute keys among available nodes.
|
|
##
|
|
## args: Either the event arguments as already made by
|
|
## :zeek:see:`Broker::make_event` or the argument list to pass along
|
|
## to it.
|
|
##
|
|
## Returns: true if the message is sent.
|
|
function Cluster::publish_hrw%(pool: Pool, key: any, ...%): bool
|
|
%{
|
|
static zeek::Func* topic_func = nullptr;
|
|
|
|
if ( ! topic_func )
|
|
topic_func = zeek::detail::global_scope()->Find("Cluster::hrw_topic")->GetVal()->AsFunc();
|
|
|
|
zeek::Args vl{{zeek::NewRef{}, pool}, {zeek::NewRef{}, key}};
|
|
auto topic = topic_func->Invoke(&vl);
|
|
|
|
if ( ! topic->AsString()->Len() )
|
|
return zeek::val_mgr->False();
|
|
|
|
const auto& bif_args = @ARGS@;
|
|
val_list args(bif_args->size() - 2);
|
|
|
|
for ( auto i = 2u; i < bif_args->size(); ++i )
|
|
args.push_back((*bif_args)[i].get());
|
|
|
|
auto rval = publish_event_args(args, topic->AsString(), frame);
|
|
return zeek::val_mgr->Bool(rval);
|
|
%}
|