mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
Teach Option::set to unwrap Broker::Data values
This commit is contained in:
parent
5bb72d2972
commit
3679b0d963
5 changed files with 81 additions and 29 deletions
|
@ -5,6 +5,36 @@ module Option;
|
|||
|
||||
%%{
|
||||
#include "NetVar.h"
|
||||
#include "broker/Data.h"
|
||||
|
||||
static bool call_option_handlers_and_set_value(StringVal* name, ID* i, Val* val,
|
||||
StringVal* location)
|
||||
{
|
||||
val->Ref();
|
||||
if ( i->HasOptionHandlers() )
|
||||
{
|
||||
for ( auto handler_function : i->GetOptionHandlers() )
|
||||
{
|
||||
val_list vl(2);
|
||||
vl.append(name->Ref());
|
||||
vl.append(val);
|
||||
if ( handler_function->FType()->AsFuncType()->ArgTypes()->Types()->length() == 3 )
|
||||
vl.append(location->Ref());
|
||||
|
||||
val = handler_function->Call(&vl); // consumed by next call.
|
||||
if ( ! val )
|
||||
{
|
||||
// Someone messed up, don't change value and just return
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clone to prevent changes
|
||||
i->SetVal(val->Clone());
|
||||
Unref(val); // Either ref'd once or function call result.
|
||||
return true;
|
||||
}
|
||||
%%}
|
||||
|
||||
## Set an option to a new value. This change will also cause the option change
|
||||
|
@ -41,36 +71,32 @@ function Option::set%(ID: string, val: any, location: string &default=""%): bool
|
|||
return new Val(0, TYPE_BOOL);
|
||||
}
|
||||
|
||||
if ( same_type(val->Type(), bro_broker::DataVal::ScriptDataType()) )
|
||||
{
|
||||
auto dv = static_cast<bro_broker::DataVal*>(val->AsRecordVal()->Lookup(0));
|
||||
auto val_from_data = dv->castTo(i->Type());
|
||||
|
||||
if ( ! val_from_data )
|
||||
{
|
||||
builtin_error(fmt("Incompatible type for set of ID '%s': got broker data '%s', need '%s'",
|
||||
ID->CheckString(), dv->data.get_type_name(), type_name(i->Type()->Tag())));
|
||||
return new Val(0, TYPE_BOOL);
|
||||
}
|
||||
|
||||
auto rval = call_option_handlers_and_set_value(ID, i, val_from_data, location);
|
||||
Unref(val_from_data);
|
||||
return new Val(rval, TYPE_BOOL);
|
||||
}
|
||||
|
||||
if ( ! same_type(i->Type(), val->Type()) )
|
||||
{
|
||||
builtin_error(fmt("Incompatible type for set of ID '%s': got '%s', need '%s'",
|
||||
ID->CheckString(), type_name(val->Type()->Tag()), type_name(i->Type()->Tag())));
|
||||
}
|
||||
|
||||
val->Ref();
|
||||
if ( i->HasOptionHandlers() )
|
||||
{
|
||||
for ( auto handler_function : i->GetOptionHandlers() )
|
||||
{
|
||||
val_list vl(2);
|
||||
vl.append(ID->Ref());
|
||||
vl.append(val);
|
||||
if ( handler_function->FType()->AsFuncType()->ArgTypes()->Types()->length() == 3 )
|
||||
vl.append(location->Ref());
|
||||
|
||||
val = handler_function->Call(&vl); // consumed by next call.
|
||||
if ( ! val )
|
||||
{
|
||||
// Someone messed up, don't change value and just return
|
||||
return new Val(0, TYPE_BOOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clone to prevent changes
|
||||
i->SetVal(val->Clone());
|
||||
Unref(val); // Either ref'd once or function call result.
|
||||
return new Val(1, TYPE_BOOL);
|
||||
auto rval = call_option_handlers_and_set_value(ID, i, val, location);
|
||||
return new Val(rval, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
## Set a change handler for an option. The change handler will be
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
option changed, testport, 44/tcp,
|
||||
option changed, teststring, b, comment
|
|
@ -0,0 +1,4 @@
|
|||
option changed, testport, 44/tcp,
|
||||
option changed, teststring, b, comment
|
||||
option changed, testport, 44/tcp,
|
||||
option changed, teststring, b, comment
|
|
@ -0,0 +1,2 @@
|
|||
option changed, testport, 44/tcp,
|
||||
option changed, teststring, b, comment
|
|
@ -2,7 +2,10 @@
|
|||
# @TEST-EXEC: sleep 1
|
||||
# @TEST-EXEC: btest-bg-run worker-1 BROPATH=$BROPATH:.. CLUSTER_NODE=worker-1 bro %INPUT
|
||||
# @TEST-EXEC: btest-bg-run worker-2 BROPATH=$BROPATH:.. CLUSTER_NODE=worker-2 bro %INPUT
|
||||
# @TEST-EXEC: btest-bg-wait 10
|
||||
# @TEST-EXEC: btest-bg-wait 15
|
||||
# @TEST-EXEC: btest-diff manager-1/.stdout
|
||||
# @TEST-EXEC: btest-diff worker-1/.stdout
|
||||
# @TEST-EXEC: btest-diff worker-2/.stdout
|
||||
|
||||
@load base/frameworks/config
|
||||
|
||||
|
@ -24,10 +27,6 @@ export {
|
|||
|
||||
global n = 0;
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
}
|
||||
|
||||
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
|
||||
{
|
||||
terminate();
|
||||
|
@ -46,8 +45,27 @@ event ready_for_data()
|
|||
Config::set_value("testport", 44/tcp);
|
||||
Config::set_value("teststring", "b", "comment");
|
||||
}
|
||||
|
||||
@endif
|
||||
|
||||
event die()
|
||||
{
|
||||
terminate();
|
||||
}
|
||||
|
||||
function option_changed(ID: string, new_value: any, location: string): any
|
||||
{
|
||||
print "option changed", ID, new_value, location;
|
||||
schedule 5sec { die() };
|
||||
return new_value;
|
||||
}
|
||||
|
||||
event bro_init() &priority=5
|
||||
{
|
||||
Option::set_change_handler("testport", option_changed, -100);
|
||||
Option::set_change_handler("teststring", option_changed, -100);
|
||||
}
|
||||
|
||||
@if ( Cluster::local_node_type() == Cluster::MANAGER )
|
||||
|
||||
global peer_count = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue