Clean way to pass events from Bro to C++

Hi,

I'm looking for a clean way to pass an event from Bro
to C++. The idea is to have a function, one of whose
parameters is an event. Bro associates some condition
to the event, and eventually calls it.

An example: I want to write a function that does DNS
resolutions. The user should be able to do something like
this:

# Bro lang (start)
event my_event (a: addr)
  {
  printf fmt ("there is a resolution for %s", a);
  }
my_address = 1.2.3.4;
resolve_dns (my_address, my_event);
# end

And when the resolution is finished, Bro will queue the event
my_event with the parameter 1.2.3.4.

I can think of 2 implementations consisting on adding a
new function to bro.bif:

- The first implementation is to add resolve_dns with the
event parameter set of type "any". The parameter is a
Val* that encloses the local function of the event, so
I can call the function using the following:

#bro.bif
function resolve_dns%(a: addr, e: any%) : bool
  %{
  ...
  e->AsFunc()->Call(a_val_list);
  ...
  %}

This works, but has the inconvenient that I only have access
to the EventHandler::local Func. In other words, I can call the
event's function, but not queue the event in the EventManager.

- A second implementation consists of asking the user for
the name of the event, instead of the event itself, and then
lookup for it in the event registry:

#bro.bif
resolve_dns ("my_address", my_event); # note the quotes on my_address
function resolve_dns%(a_name: string, e: any%) : bool
  %{
  ...
  EventHandler* handler = event_registry->Lookup(a_name->CheckString());
  ...
  %}

Now I have my EventHandler, but it seems weird to request
the user to quote the event name.

I was wondering whether somebody has an idea on what's
the best way to do this.

-Chema

One way to solve this would be to remember the corresponding EventHandler's in BroFunc's. This can be done in ID::SetVal(), where we add BroFunc's to EventHandlers.

On the other hand, would it be possible to do the job without passing events? In the example below, we can instead have a predefined event (say, dns_result_ready). This is not as powerful as passing events, but does that give you what you want?

Ruoming

One way to solve this would be to remember the corresponding
EventHandler's in BroFunc's. This can be done in ID::SetVal(), where we
add BroFunc's to EventHandlers.

That sounds good, but, if we have two events with the
exact same body, won't they share the BroFunc?

On the other hand, would it be possible to do the job without passing
events? In the example below, we can instead have a predefined event
(say, dns_result_ready). This is not as powerful as passing events, but
does that give you what you want?

That's what I have now, but I'm not sure it's going to be
flexible enough.

-Chema