Fix the way that child analyzers are added.

Bro contains functionality to add child analyzers delayed, so that an
just added analyzer does not influence the list of current analyzers
(which, in some combinations of mostly UDP and traffic replay by PIA can
lead to duplicate packets sent to the analyzer).

Sadly, this feature was broken sometime in the past, leading to the
aforementioned duplicate packets. Re-enabling this also necessitated
some changes in the analyzer manager, which immediately timed out all
connections when that feature was re-enabled.

There currently is no testcase (this is a bit hard to trigger); however,
I will add one with a later fix for DTLS.
This commit is contained in:
Johanna Amann 2016-05-17 16:13:33 -07:00
parent 4851cbc7cc
commit bc868d72a1
3 changed files with 19 additions and 9 deletions

View file

@ -395,7 +395,7 @@ bool Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
// the list. // the list.
analyzer->parent = this; analyzer->parent = this;
children.push_back(analyzer); new_children.push_back(analyzer);
if ( init ) if ( init )
analyzer->Init(); analyzer->Init();
@ -474,6 +474,13 @@ Analyzer* Analyzer::FindChild(ID arg_id)
return child; return child;
} }
LOOP_OVER_GIVEN_CHILDREN(i, new_children)
{
Analyzer* child = (*i)->FindChild(arg_id);
if ( child )
return child;
}
return 0; return 0;
} }
@ -489,6 +496,13 @@ Analyzer* Analyzer::FindChild(Tag arg_tag)
return child; return child;
} }
LOOP_OVER_GIVEN_CHILDREN(i, new_children)
{
Analyzer* child = (*i)->FindChild(arg_tag);
if ( child )
return child;
}
return 0; return 0;
} }

View file

@ -427,6 +427,10 @@ public:
/** /**
* Returns a list of all direct child analyzers. * Returns a list of all direct child analyzers.
*
* Note that this does not include the list of analyzers that are
* currently queued up to be added. If you just added an analyzer,
* it will not immediately be in this list.
*/ */
const analyzer_list& GetChildren() { return children; } const analyzer_list& GetChildren() { return children; }

View file

@ -361,7 +361,6 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
icmp::ICMP_Analyzer* icmp = 0; icmp::ICMP_Analyzer* icmp = 0;
TransportLayerAnalyzer* root = 0; TransportLayerAnalyzer* root = 0;
pia::PIA* pia = 0; pia::PIA* pia = 0;
bool analyzed = false;
bool check_port = false; bool check_port = false;
switch ( conn->ConnTransport() ) { switch ( conn->ConnTransport() ) {
@ -383,7 +382,6 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
case TRANSPORT_ICMP: { case TRANSPORT_ICMP: {
root = icmp = new icmp::ICMP_Analyzer(conn); root = icmp = new icmp::ICMP_Analyzer(conn);
DBG_ANALYZER(conn, "activated ICMP analyzer"); DBG_ANALYZER(conn, "activated ICMP analyzer");
analyzed = true;
break; break;
} }
@ -495,16 +493,10 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
if ( pia ) if ( pia )
root->AddChildAnalyzer(pia->AsAnalyzer()); root->AddChildAnalyzer(pia->AsAnalyzer());
if ( root->GetChildren().size() )
analyzed = true;
conn->SetRootAnalyzer(root, pia); conn->SetRootAnalyzer(root, pia);
root->Init(); root->Init();
root->InitChildren(); root->InitChildren();
if ( ! analyzed )
conn->SetLifetime(non_analyzed_lifetime);
PLUGIN_HOOK_VOID(HOOK_SETUP_ANALYZER_TREE, HookSetupAnalyzerTree(conn)); PLUGIN_HOOK_VOID(HOOK_SETUP_ANALYZER_TREE, HookSetupAnalyzerTree(conn));
return true; return true;