Use better data structure for storing BPF filters.

This commit is contained in:
Robin Sommer 2015-11-23 19:55:02 -08:00
parent 17bc615467
commit c22a6f67d2
3 changed files with 22 additions and 16 deletions

View file

@ -36,9 +36,7 @@ PktSrc::PktSrc()
PktSrc::~PktSrc()
{
BPF_Program* code;
IterCookie* cookie = filters.InitForIteration();
while ( (code = filters.NextEntry(cookie)) )
for ( auto code : filters )
delete code;
}
@ -335,16 +333,16 @@ bool PktSrc::PrecompileBPFFilter(int index, const std::string& filter)
return 0;
}
// Store it in hash.
HashKey* hash = new HashKey(HashKey(bro_int_t(index)));
BPF_Program* oldcode = filters.Lookup(hash);
if ( oldcode )
delete oldcode;
// Store it in vector.
if ( index >= static_cast<int>(filters.size()) )
filters.resize(index + 1);
filters.Insert(hash, code);
delete hash;
if ( auto old = filters[index] )
delete old;
return 1;
filters[index] = code;
return true;
}
BPF_Program* PktSrc::GetBPFFilter(int index)
@ -352,10 +350,7 @@ BPF_Program* PktSrc::GetBPFFilter(int index)
if ( index < 0 )
return 0;
HashKey* hash = new HashKey(HashKey(bro_int_t(index)));
BPF_Program* code = filters.Lookup(hash);
delete hash;
return code;
return (static_cast<int>(filters.size()) > index ? filters[index] : 0);
}
bool PktSrc::ApplyBPFFilter(int index, const struct pcap_pkthdr *hdr, const u_char *pkt)

View file

@ -3,6 +3,8 @@
#ifndef IOSOURCE_PKTSRC_PKTSRC_H
#define IOSOURCE_PKTSRC_PKTSRC_H
#include <vector>
#include "IOSource.h"
#include "BPF_Program.h"
#include "Dict.h"
@ -362,7 +364,7 @@ private:
Packet current_packet;
// For BPF filtering support.
PDict(BPF_Program) filters;
std::vector<BPF_Program *> filters;
// Only set in pseudo-realtime mode.
double first_timestamp;

View file

@ -21,6 +21,15 @@ module Pcap;
## pcap_error
function precompile_pcap_filter%(id: PcapFilterID, s: string%): bool
%{
if ( id->AsEnum() >= 100 )
{
// We use a vector as underlying data structure for fast
// lookups and limit the ID space so that that doesn't grow too
// large.
builtin_error(fmt("PCAP filter ids must remain below 100 (is %ld)", id->AsInt()));
return new Val(false, TYPE_BOOL);
}
bool success = true;
const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs());