[Bro] Clarification needed

Clark, Gilbert gc355804 at ohio.edu
Sat Sep 20 12:48:39 PDT 2014


I went and double-checked what I wrote about triggers (again), and found that they don't seem to work quite how I thought they did.  There seems to be a lot *less* overhead than I was expecting there to be [1].  

So, rather than trying to correct myself again and possibly putting more FUD on the list:  would someone (e.g. Robin, Seth) mind offering the Right Explanation (tm) here?  It looks like I don't understand triggers quite as well as I originally thought I did, so time to retract and punt the question!

Cheers,
Gilbert

[1] Script I used to test the overhead introduced by a set of triggers

redef exit_only_after_terminate = T;

module Counters;

global conn_count:int;
global exec_count:int;
global eval_count:int;
global pending_count:int;
global shared_var:int;
global target_count:int;

event bro_init() {
    Counters::conn_count = 0;
    Counters::exec_count = 0;
    Counters::eval_count = 0;
    Counters::pending_count = 0;
    Counters::shared_var = 0;
    Counters::target_count = 0;
}

function evalfunction() :bool {
    eval_count = eval_count + 1;
    return shared_var > target_count;
}

event new_packet(c: connection, p: pkt_hdr) {
    pending_count = pending_count + Instrumentation::GetPendingTriggerCount();
}

event connection_established(c: connection) {
    conn_count = conn_count + 1;
    shared_var = shared_var + 1;
    when ( evalfunction() ) {
        exec_count = exec_count + 1;
        target_count += 100;
        print("New target count:");
        print target_count;
    }
}

event bro_done() {
    print("Counters:");
    print("Executed");
    print(exec_count);
    print("Number of connections");
    print(conn_count);
    print("Number of evaluations");
    print(eval_count);
    print("Total pending");
    print(pending_count);
    print("Shared value");
    print(shared_var);
    print("Next target count");
    print(target_count);
}
________________________________________
From: bro-bounces at bro.org <bro-bounces at bro.org> on behalf of Clark, Gilbert <gc355804 at ohio.edu>
Sent: Saturday, September 20, 2014 12:28 AM
To: PeLo; Seth Hall
Cc: bro at bro.org
Subject: Re: [Bro] Clarification needed

In hindsight, that triggers paragraph was poorly written.  Let me try again:

Triggers operate in a similar fashion to timers, except that the conditions for *every* trigger are evaluated at least once / every packet bro observes.  Note, however, that bro is actually pretty intelligent about the way it evaluates the condition for a trigger.   Bro actually keeps track of which values a when() depends on, and will actually only *re-execute* the code in the when() if one of these values has been changed.  Thus, the actual total overhead per trigger per packet should actually work out to be a function of *not only* how many active triggers there are, *but also* what exactly those triggers have defined in their when().

More experienced bro folks can feel free to correct / refine the above if desired :)

Regardless, I'm afraid the last e-mail I sent may have come across more strongly than I intended.  The point I was trying to make there wasn't that "defining triggers is terribly expensive and no one should ever do it", but instead that the cost of maintaining a trigger could be relatively more expensive than maintaining a timer, and that their use should therefore be considered more carefully.

Cheers,
Gilbert
________________________________________
From: bro-bounces at bro.org <bro-bounces at bro.org> on behalf of Clark, Gilbert <gc355804 at ohio.edu>
Sent: Friday, September 19, 2014 8:12 PM
To: PeLo; Seth Hall
Cc: bro at bro.org
Subject: Re: [Bro] Clarification needed

Neither timers (schedule blocks) nor triggers block execution.  Instead, when bro sees a timer / trigger, it just makes a note of it and moves on to the next line of code it sees.  In the case of the timer described below, bro would keep doing other stuff for 1 second before eventually coming back to execute the code in the { }.  In the case of the typo, bro would keep doing other stuff for 10 seconds before eventually coming back to execute the code in the { }.

Triggers operate in a similar fashion to timers, except that the conditions for *every* trigger are evaluated at least once / every packet bro observes.  In general, this means that *every registered trigger* is going to add per-packet overhead, so there's a pretty good argument to be made that relatively few triggers should be active at once.

Also, as far as I know, exit_only_after_terminate is a global flag that will simply request that bro wait to exit until there's an explicit request to do so [1].  It shouldn't really have any impact on bro's execution otherwise: it's only there to allow operations with longer execution times to complete before bro actually exits.

As a note, there are actually relatively few blocking calls supported by bro just because blocking script execution for any reason is going to eat through queue space *incredibly* quickly (and likely lead to burst losses).

HTH,
Gilbert

[1] http://comments.gmane.org/gmane.comp.security.detection.bro/5998

From: bro-bounces at bro.org <bro-bounces at bro.org> on behalf of PeLo <phrackmod at gmail.com>
Sent: Friday, September 19, 2014 4:44 PM
To: Seth Hall
Cc: bro at bro.org
Subject: Re: [Bro] Clarification needed





​​
Regarding the Schedule statement used in the code, I see that the execution is halted until the specified time expires. Since Bro executes all the event handlers in a FIFO style, if by mistake I wrote a schedule statement with a time interval of say 10 sec, will this  then block the execution all the event handlers in the queue thereby delaying the whole process??



​- Pelo​

On Sat, Sep 20, 2014 at 1:49 AM, Seth Hall  <seth at icir.org> wrote:

On Sep 19, 2014, at 3:43 PM, PeLo <phrackmod at gmail.com> wrote:

>       ### Error occurs here
>       ### Error Output
>       ### ============
>       ### error : type clash (addr and {74.125.236.213,2404:6800:4007:803::1015})
>       ### error : type mismatch ({74.125.236.213,2404:6800:4007:803::1015} and addr)
>
>       local google_ips: set[addr] = {  mail.google.com, maps.google.com, youtube.com };
>       for (i in google_ips)   print(i);

Ugh, I suspect this has something to do with using the "{ }" constructor syntax somewhere that it shouldn't be used.  I.e., you've encountered a wart.

>       ### No errors and output here
>       ### Anything wrong with the code???

You have an issue where you are trying to synchronously access data from asynchronous operations. :)

When statements return immediately and the body only executes after the condition becomes true.  You are printing before you've actually gotten a response from the DNS server.  Let me try restructuring your code a bit...

         http://try.bro.org/#/trybro/saved/89b6a856-c785-4cea-bfc3-206947bc054a

Does that explain it a bit better?



  .Seth

--
Seth Hall
International Computer Science Institute
(Bro) because everyone has a network
http://www.bro.org/




_______________________________________________
Bro mailing list
bro at bro-ids.org
http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/bro

_______________________________________________
Bro mailing list
bro at bro-ids.org
http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/bro




More information about the Bro mailing list