From 6489b54debafeb4c6b10780992b385c9c37cc78a Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 31 May 2018 08:58:34 -0500 Subject: [PATCH 1/3] Remove dead code in broker data/val conversion function --- src/broker/Data.cc | 10 +++------- src/broker/Data.h | 4 +--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 3d4bcf27e9..60d9093df4 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -48,7 +48,6 @@ struct val_converter { using result_type = Val*; BroType* type; - bool require_log_attr; result_type operator()(broker::none) { @@ -379,9 +378,6 @@ struct val_converter { for ( auto i = 0u; i < static_cast(rt->NumFields()); ++i ) { - if ( require_log_attr && ! rt->FieldDecl(i)->FindAttr(ATTR_LOG) ) - continue; - if ( idx >= a.size() ) { Unref(rval); @@ -774,9 +770,9 @@ struct type_checker { } }; -Val* bro_broker::data_to_val(broker::data d, BroType* type, bool require_log_attr) +Val* bro_broker::data_to_val(broker::data d, BroType* type) { - return broker::visit(val_converter{type, require_log_attr}, std::move(d)); + return broker::visit(val_converter{type}, std::move(d)); } broker::expected bro_broker::val_to_data(Val* v) @@ -1137,7 +1133,7 @@ bool bro_broker::DataVal::canCastTo(BroType* t) const Val* bro_broker::DataVal::castTo(BroType* t) { - return data_to_val(data, t, false); + return data_to_val(data, t); } IMPLEMENT_SERIAL(bro_broker::DataVal, SER_COMM_DATA_VAL); diff --git a/src/broker/Data.h b/src/broker/Data.h index 8a636bb7db..525faba5f6 100644 --- a/src/broker/Data.h +++ b/src/broker/Data.h @@ -54,12 +54,10 @@ broker::expected val_to_data(Val* v); * Convert a Broker data value to a Bro value. * @param d a Broker data value. * @param type the expected type of the value to return. - * @param require_log_attr if true, skip over record fields that don't have the - * &log attribute. * @return a pointer to a new Bro value or a nullptr if the conversion was not * possible. */ -Val* data_to_val(broker::data d, BroType* type, bool require_log_attr = false); +Val* data_to_val(broker::data d, BroType* type); /** * Convert a Bro threading::Value to a Broker data value. From bd3c16c6d71117eeb2344e6ffccdfc323ea836fa Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 31 May 2018 10:05:18 -0500 Subject: [PATCH 2/3] Fix a bug in broker data type-casting check --- src/broker/Data.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 60d9093df4..90b30ef3aa 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -1128,7 +1128,7 @@ broker::data& bro_broker::opaque_field_to_data(RecordVal* v, Frame* f) bool bro_broker::DataVal::canCastTo(BroType* t) const { - return broker::visit(type_checker{type}, data); + return broker::visit(type_checker{t}, data); } Val* bro_broker::DataVal::castTo(BroType* t) From d873acc9e394c51c06260f4785063f8212a3b46b Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 31 May 2018 10:39:40 -0500 Subject: [PATCH 3/3] Support unserializing broker data into type 'any' The receiver side will wrap the data as a Broker::Data value, which can then be type-checked/cast via 'is' or 'as' operators to a specific Bro type. For example: Sender: Broker::publish("topic", my_event, "hello") Receiver: event my_event(arg: any) { if ( arg is string ) print arg as string; } --- src/broker/Data.cc | 3 + .../broker.remote_event_any/recv.recv.out | 12 ++ .../broker.remote_event_any/send.send.out | 11 ++ testing/btest/broker/remote_event_any.bro | 107 ++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 testing/btest/Baseline/broker.remote_event_any/recv.recv.out create mode 100644 testing/btest/Baseline/broker.remote_event_any/send.send.out create mode 100644 testing/btest/broker/remote_event_any.bro diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 90b30ef3aa..99c6e3ebef 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -772,6 +772,9 @@ struct type_checker { Val* bro_broker::data_to_val(broker::data d, BroType* type) { + if ( type->Tag() == TYPE_ANY ) + return bro_broker::make_data_val(move(d)); + return broker::visit(val_converter{type}, std::move(d)); } diff --git a/testing/btest/Baseline/broker.remote_event_any/recv.recv.out b/testing/btest/Baseline/broker.remote_event_any/recv.recv.out new file mode 100644 index 0000000000..54b7d375fb --- /dev/null +++ b/testing/btest/Baseline/broker.remote_event_any/recv.recv.out @@ -0,0 +1,12 @@ +receiver added peer: endpoint=127.0.0.1 msg=handshake successful +is_remote should be T, and is, T +receiver got ping: my-message, 1 +is_remote should be T, and is, T +receiver got ping: my-message, 2 +is_remote should be T, and is, T +receiver got ping: my-message, 3 +is_remote should be T, and is, T +receiver got ping: my-message, 4 +is_remote should be T, and is, T +receiver got ping: my-message, 5 +[num_peers=1, num_stores=0, num_pending_queries=0, num_events_incoming=5, num_events_outgoing=4, num_logs_incoming=0, num_logs_outgoing=1, num_ids_incoming=0, num_ids_outgoing=0] diff --git a/testing/btest/Baseline/broker.remote_event_any/send.send.out b/testing/btest/Baseline/broker.remote_event_any/send.send.out new file mode 100644 index 0000000000..b8be473e40 --- /dev/null +++ b/testing/btest/Baseline/broker.remote_event_any/send.send.out @@ -0,0 +1,11 @@ +is_remote should be F, and is, F +sender added peer: endpoint=127.0.0.1 msg=received handshake from remote core +is_remote should be T, and is, T +sender got pong: my-message, 1 +is_remote should be T, and is, T +sender got pong: my-message, 2 +is_remote should be T, and is, T +sender got pong: my-message, 3 +is_remote should be T, and is, T +sender got pong: my-message, 4 +sender lost peer: endpoint=127.0.0.1 msg=lost remote peer diff --git a/testing/btest/broker/remote_event_any.bro b/testing/btest/broker/remote_event_any.bro new file mode 100644 index 0000000000..153056c456 --- /dev/null +++ b/testing/btest/broker/remote_event_any.bro @@ -0,0 +1,107 @@ +# @TEST-SERIALIZE: comm +# +# @TEST-EXEC: btest-bg-run recv "bro -B broker -b ../recv.bro >recv.out" +# @TEST-EXEC: btest-bg-run send "bro -B broker -b ../send.bro >send.out" +# +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff recv/recv.out +# @TEST-EXEC: btest-diff send/send.out + +@TEST-START-FILE send.bro + +redef Broker::default_connect_retry=1secs; +redef Broker::default_listen_retry=1secs; +redef exit_only_after_terminate = T; + +global event_count = 0; + +global ping: event(msg: string, c: any); + +event bro_init() + { + Broker::subscribe("bro/event/my_topic"); + Broker::peer("127.0.0.1"); + print "is_remote should be F, and is", is_remote_event(); + } + +function send_event() + { + ++event_count; + local e = Broker::make_event(ping, "my-message", event_count); + Broker::publish("bro/event/my_topic", e); + } + +event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string) + { + print fmt("sender added peer: endpoint=%s msg=%s", + endpoint$network$address, msg); + send_event(); + } + +event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string) + { + print fmt("sender lost peer: endpoint=%s msg=%s", + endpoint$network$address, msg); + terminate(); + } + +event pong(msg: string, n: any) + { + print "is_remote should be T, and is", is_remote_event(); + + if ( n is count ) + print fmt("sender got pong: %s, %s", msg, n as count); + + send_event(); + } + +@TEST-END-FILE + + +@TEST-START-FILE recv.bro + +redef Broker::default_connect_retry=1secs; +redef Broker::default_listen_retry=1secs; +redef exit_only_after_terminate = T; + +const events_to_recv = 5; + +global handler: event(msg: string, c: count); +global auto_handler: event(msg: string, c: count); + +global pong: event(msg: string, c: count); + +event bro_init() + { + Broker::subscribe("bro/event/my_topic"); + Broker::listen("127.0.0.1"); + } + +event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string) + { + print fmt("receiver added peer: endpoint=%s msg=%s", endpoint$network$address, msg); + } + +event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string) + { + print fmt("receiver lost peer: endpoint=%s msg=%s", endpoint$network$address, msg); + } + +event ping(msg: string, n: any) + { + print "is_remote should be T, and is", is_remote_event(); + + if ( n is count ) + print fmt("receiver got ping: %s, %s", msg, n as count); + + if ( (n as count) == events_to_recv ) + { + print get_broker_stats(); + terminate(); + return; + } + + Broker::publish("bro/event/my_topic", pong, msg, n as count); + } + +@TEST-END-FILE