mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 23:58:20 +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 "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
|
## 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);
|
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()) )
|
if ( ! same_type(i->Type(), val->Type()) )
|
||||||
{
|
{
|
||||||
builtin_error(fmt("Incompatible type for set of ID '%s': got '%s', need '%s'",
|
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())));
|
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);
|
return new Val(0, TYPE_BOOL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clone to prevent changes
|
auto rval = call_option_handlers_and_set_value(ID, i, val, location);
|
||||||
i->SetVal(val->Clone());
|
return new Val(rval, TYPE_BOOL);
|
||||||
Unref(val); // Either ref'd once or function call result.
|
|
||||||
return new Val(1, TYPE_BOOL);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
## Set a change handler for an option. The change handler will be
|
## 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: sleep 1
|
||||||
# @TEST-EXEC: btest-bg-run worker-1 BROPATH=$BROPATH:.. CLUSTER_NODE=worker-1 bro %INPUT
|
# @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-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
|
@load base/frameworks/config
|
||||||
|
|
||||||
|
@ -24,10 +27,6 @@ export {
|
||||||
|
|
||||||
global n = 0;
|
global n = 0;
|
||||||
|
|
||||||
event bro_init() &priority=5
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
|
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
|
||||||
{
|
{
|
||||||
terminate();
|
terminate();
|
||||||
|
@ -46,8 +45,27 @@ event ready_for_data()
|
||||||
Config::set_value("testport", 44/tcp);
|
Config::set_value("testport", 44/tcp);
|
||||||
Config::set_value("teststring", "b", "comment");
|
Config::set_value("teststring", "b", "comment");
|
||||||
}
|
}
|
||||||
|
|
||||||
@endif
|
@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 )
|
@if ( Cluster::local_node_type() == Cluster::MANAGER )
|
||||||
|
|
||||||
global peer_count = 0;
|
global peer_count = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue