zeek/src/broker/messaging.bif
2025-07-29 07:51:29 +02:00

188 lines
5.2 KiB
C++

##! Functions for peering and various messaging patterns.
%%{
#include <set>
#include <span>
#include <string>
#include "zeek/broker/Manager.h"
#include "zeek/logging/Manager.h"
namespace {
using ArgsSpan = std::span<const zeek::ValPtr>;
}
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;
for ( const auto& te : *tbl )
{
auto k = te.GetHashKey();
auto index = val->AsTableVal()->RecreateIndex(*k);
rval.emplace(index->Idx(0)->AsString()->CheckString());
}
}
return rval;
}
static bool publish_event_args(ArgsSpan args, const zeek::String* topic,
zeek::detail::Frame* frame)
{
zeek::Broker::Manager::ScriptScopeGuard ssg;
zeek::ScriptLocationScope scope{frame};
auto rval = false;
if ( zeek::broker_mgr != zeek::cluster::backend && ! zeek::broker_mgr->Active() )
zeek::reporter->Warning("Non-broker cluster backend configured and Broker manager inactive. "
"Did you mean to use Cluster::publish() instead of Broker::publish()?");
if ( args[0]->GetType()->Tag() == zeek::TYPE_RECORD )
{
auto* rv = args[0]->AsRecordVal();
// same_type() should be fast if it's the type pointers are the same.
if ( ! zeek::same_type(rv->GetType(), zeek::BifType::Record::Broker::Event) )
{
zeek::emit_builtin_error(zeek::util::fmt("expected Broker::Event, got %s",
zeek::obj_desc_short(rv->GetType()).c_str()));
return false;
}
return zeek::broker_mgr->PublishEvent(topic->CheckString(), rv);
}
auto ev = zeek::broker_mgr->MakeEvent(args, frame);
return zeek::broker_mgr->PublishEvent(topic->CheckString(), ev->AsRecordVal());
}
static bool is_cluster_pool(zeek::Val* pool)
{
static zeek::RecordTypePtr pool_type = nullptr;
if ( ! pool_type )
pool_type = zeek::id::find_type<zeek::RecordType>("Cluster::Pool");
return pool->GetType() == pool_type;
}
%%}
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;
auto ev = zeek::broker_mgr->MakeEvent(ArgsSpan{*@ARGS@}, frame);
return zeek::cast_intrusive<RecordVal>(ev);
%}
## 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
%{
auto rval = publish_event_args(ArgsSpan{*@ARGS@}.subspan(1),
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;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
auto rval = zeek::broker_mgr->AutoPublishEvent(topic->CheckString(), ev);
#pragma GCC diagnostic pop
return zeek::val_mgr->Bool(rval);
%}
function Broker::__auto_unpublish%(topic: string, ev: any%): bool
%{
zeek::Broker::Manager::ScriptScopeGuard ssg;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
auto rval = zeek::broker_mgr->AutoUnpublishEvent(topic->CheckString(), ev);
#pragma GCC diagnostic pop
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);
%}