Merge remote-tracking branch 'origin/master' into topic/johanna/tls-more-data

This commit is contained in:
Johanna Amann 2018-08-17 11:52:00 -07:00
commit b1dbd757a6
1468 changed files with 41493 additions and 19065 deletions

@ -1 +1 @@
Subproject commit 5d03436d9db8a6cbaee1f459d654f977ce722467
Subproject commit 6cdefdd1d45465ca09aba9e05c7ca12e1484ccc0

View file

@ -82,7 +82,8 @@ int AnonymizeIPAddr::PreserveNet(ipaddr32_t input)
ipaddr32_t AnonymizeIPAddr_Seq::anonymize(ipaddr32_t /* input */)
{
return htonl(seq++);
++seq;
return htonl(seq);
}
ipaddr32_t AnonymizeIPAddr_RandomMD5::anonymize(ipaddr32_t input)

View file

@ -66,7 +66,7 @@ protected:
class AnonymizeIPAddr_Seq : public AnonymizeIPAddr {
public:
AnonymizeIPAddr_Seq() { seq = 1; }
ipaddr32_t anonymize(ipaddr32_t addr);
ipaddr32_t anonymize(ipaddr32_t addr) override;
protected:
ipaddr32_t seq;
@ -74,12 +74,12 @@ protected:
class AnonymizeIPAddr_RandomMD5 : public AnonymizeIPAddr {
public:
ipaddr32_t anonymize(ipaddr32_t addr);
ipaddr32_t anonymize(ipaddr32_t addr) override;
};
class AnonymizeIPAddr_PrefixMD5 : public AnonymizeIPAddr {
public:
ipaddr32_t anonymize(ipaddr32_t addr);
ipaddr32_t anonymize(ipaddr32_t addr) override;
protected:
struct anon_prefix {
@ -91,10 +91,10 @@ protected:
class AnonymizeIPAddr_A50 : public AnonymizeIPAddr {
public:
AnonymizeIPAddr_A50() { init(); }
~AnonymizeIPAddr_A50();
~AnonymizeIPAddr_A50() override;
ipaddr32_t anonymize(ipaddr32_t addr);
int PreservePrefix(ipaddr32_t input, int num_bits);
ipaddr32_t anonymize(ipaddr32_t addr) override;
int PreservePrefix(ipaddr32_t input, int num_bits) override;
protected:
struct Node {

View file

@ -40,8 +40,8 @@ typedef enum {
class Attr : public BroObj {
public:
Attr(attr_tag t, Expr* e = 0);
~Attr();
explicit Attr(attr_tag t, Expr* e = 0);
~Attr() override;
attr_tag Tag() const { return tag; }
Expr* AttrExpr() const { return expr; }
@ -56,7 +56,7 @@ public:
int RedundantAttrOkay() const
{ return tag == ATTR_REDEF || tag == ATTR_OPTIONAL; }
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
void DescribeReST(ODesc* d) const;
bool operator==(const Attr& other) const
@ -84,7 +84,7 @@ protected:
class Attributes : public BroObj {
public:
Attributes(attr_list* a, BroType* t, bool in_record);
~Attributes();
~Attributes() override;
void AddAttr(Attr* a);
void AddAttrs(Attributes* a); // Unref's 'a' when done

View file

@ -18,7 +18,7 @@ public:
// encode_base64()), encoding-errors will go to Reporter instead of
// Weird. Usage errors go to Reporter in any case. Empty alphabet
// indicates the default base64 alphabet.
Base64Converter(Connection* conn, const string& alphabet = "");
explicit Base64Converter(Connection* conn, const string& alphabet = "");
~Base64Converter();
// A note on Decode():

View file

@ -166,17 +166,19 @@ void BroString::Set(const BroString& str)
const char* BroString::CheckString() const
{
void *nulTerm;
if ( n == 0 )
return "";
if ( memchr(b, '\0', n + final_NUL) != &b[n] )
nulTerm = memchr(b, '\0', n + final_NUL);
if ( nulTerm != &b[n] )
{
// Either an embedded NUL, or no final NUL.
char* exp_s = Render();
if ( b[n-1] != '\0' )
reporter->Error("string without NUL terminator: \"%s\"", exp_s);
else
if ( nulTerm )
reporter->Error("string with embedded NUL: \"%s\"", exp_s);
else
reporter->Error("string without NUL terminator: \"%s\"", exp_s);
delete [] exp_s;
return "<string-with-NUL>";

View file

@ -36,8 +36,8 @@ public:
// Constructors creating internal copies of the data passed in.
BroString(const u_char* str, int arg_n, int add_NUL);
BroString(const char* str);
BroString(const string& str);
explicit BroString(const char* str);
explicit BroString(const string& str);
BroString(const BroString& bs);
// Constructor that takes owernship of the vector passed in.
@ -158,7 +158,7 @@ protected:
//
class BroStringLenCmp {
public:
BroStringLenCmp(bool increasing = true) { _increasing = increasing; }
explicit BroStringLenCmp(bool increasing = true) { _increasing = increasing; }
bool operator()(BroString*const& bst1, BroString*const& bst2);
private:

View file

@ -50,10 +50,18 @@ bool Brofiler::WriteStats()
char* bf = getenv("BRO_PROFILER_FILE");
if ( ! bf ) return false;
FILE* f;
const char* p = strstr(bf, ".XXXXXX");
SafeDirname dirname{bf};
if ( p && ! p[7] )
if ( ! ensure_intermediate_dirs(dirname.result.data()) )
{
reporter->Error("Failed to open BRO_PROFILER_FILE destination '%s' for writing", bf);
return false;
}
FILE* f;
const char* p = strstr(bf, "XXXXXX");
if ( p && ! p[6] )
{
mode_t old_umask = umask(S_IXUSR | S_IRWXO | S_IRWXG);
int fd = mkstemp(bf);

View file

@ -52,6 +52,7 @@ bison_target(BIFParser builtin-func.y
COMPILE_FLAGS "${BISON_FLAGS}")
flex_target(BIFScanner builtin-func.l ${CMAKE_CURRENT_BINARY_DIR}/bif_lex.cc)
add_flex_bison_dependency(BIFScanner BIFParser)
set_property(SOURCE bif_lex.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
# Rule parser/scanner
bison_target(RuleParser rule-parse.y
@ -67,6 +68,7 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rup.h
rules_ rules_)
flex_target(RuleScanner rule-scan.l ${CMAKE_CURRENT_BINARY_DIR}/rule-scan.cc
COMPILE_FLAGS "-Prules_")
set_property(SOURCE rule-scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
# RE parser/scanner
bison_target(REParser re-parse.y
@ -80,6 +82,7 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rep.cc
flex_target(REScanner re-scan.l ${CMAKE_CURRENT_BINARY_DIR}/re-scan.cc
COMPILE_FLAGS "-Pre_")
add_flex_bison_dependency(REScanner REParser)
set_property(SOURCE re-scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
# Parser/Scanner
bison_target(Parser parse.y
@ -92,24 +95,7 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/p.cc
bro yy)
flex_target(Scanner scan.l ${CMAKE_CURRENT_BINARY_DIR}/scan.cc
COMPILE_FLAGS "-Pbro")
########################################################################
## bifcl (BIF compiler) target
set(bifcl_SRCS
${BISON_BIFParser_INPUT}
${FLEX_BIFScanner_INPUT}
${BISON_BIFParser_OUTPUTS}
${FLEX_BIFScanner_OUTPUTS}
bif_arg.cc
module_util.cc
bif_arg.h
module_util.h
)
add_executable(bifcl ${bifcl_SRCS})
target_link_libraries(bifcl)
set_property(SOURCE scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
########################################################################
## bifcl-dependent targets
@ -124,6 +110,7 @@ set(BIF_SRCS
types.bif
strings.bif
reporter.bif
option.bif
)
foreach (bift ${BIF_SRCS})
@ -155,6 +142,7 @@ set(bro_SUBDIR_LIBS CACHE INTERNAL "subdir libraries" FORCE)
set(bro_PLUGIN_LIBS CACHE INTERNAL "plugin libraries" FORCE)
add_subdirectory(analyzer)
add_subdirectory(broker)
add_subdirectory(broxygen)
add_subdirectory(file_analysis)
add_subdirectory(input)
@ -162,14 +150,6 @@ add_subdirectory(iosource)
add_subdirectory(logging)
add_subdirectory(probabilistic)
if ( ENABLE_BROKER )
add_subdirectory(broker)
else ()
# Just to satisfy coverage unit tests until new Broker-based
# communication is enabled by default.
add_subdirectory(broker-dummy)
endif ()
set(bro_SUBDIRS
# Order is important here.
${bro_PLUGIN_LIBS}
@ -433,3 +413,24 @@ install(CODE "
${BRO_SCRIPT_INSTALL_PATH}/policy/tuning/logs-to-elasticsearch.bro
)
")
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
DESTINATION include/bro
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.pac"
PATTERN "3rdparty/*" EXCLUDE
)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/
DESTINATION include/bro
FILES_MATCHING
PATTERN "*.bif.func_h"
PATTERN "*.bif.netvar_h"
PATTERN "*.bif.h"
PATTERN "CMakeFiles" EXCLUDE
)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/sqlite3.h
DESTINATION include/bro/3rdparty
)

View file

@ -167,21 +167,21 @@ public:
// messages, and pid gives a pid to monitor (if the process dies, we
// return EOF).
ChunkedIOFd(int fd, const char* tag, pid_t pid = 0);
virtual ~ChunkedIOFd();
~ChunkedIOFd() override;
virtual bool Read(Chunk** chunk, bool may_block = false);
virtual bool Write(Chunk* chunk);
virtual bool Flush();
virtual const char* Error();
virtual bool CanRead();
virtual bool CanWrite();
virtual bool IsIdle();
virtual bool IsFillingUp();
virtual void Clear();
virtual bool Eof() { return eof; }
virtual int Fd() { return fd; }
virtual iosource::FD_Set ExtraReadFDs() const;
virtual void Stats(char* buffer, int length);
bool Read(Chunk** chunk, bool may_block = false) override;
bool Write(Chunk* chunk) override;
bool Flush() override;
const char* Error() override;
bool CanRead() override;
bool CanWrite() override;
bool IsIdle() override;
bool IsFillingUp() override;
void Clear() override;
bool Eof() override { return eof; }
int Fd() override { return fd; }
iosource::FD_Set ExtraReadFDs() const override;
void Stats(char* buffer, int length) override;
private:
@ -252,22 +252,22 @@ public:
// Argument is an open socket and a flag indicating whether we are the
// server side of the connection.
ChunkedIOSSL(int socket, bool server);
virtual ~ChunkedIOSSL();
~ChunkedIOSSL() override;
virtual bool Init();
virtual bool Read(Chunk** chunk, bool mayblock = false);
virtual bool Write(Chunk* chunk);
virtual bool Flush();
virtual const char* Error();
virtual bool CanRead();
virtual bool CanWrite();
virtual bool IsIdle();
virtual bool IsFillingUp();
virtual void Clear();
virtual bool Eof() { return eof; }
virtual int Fd() { return socket; }
virtual iosource::FD_Set ExtraReadFDs() const;
virtual void Stats(char* buffer, int length);
bool Init() override;
bool Read(Chunk** chunk, bool mayblock = false) override;
bool Write(Chunk* chunk) override;
bool Flush() override;
const char* Error() override;
bool CanRead() override;
bool CanWrite() override;
bool IsIdle() override;
bool IsFillingUp() override;
void Clear() override;
bool Eof() override { return eof; }
int Fd() override { return socket; }
iosource::FD_Set ExtraReadFDs() const override;
void Stats(char* buffer, int length) override;
private:
@ -315,27 +315,27 @@ private:
// Wrapper class around a another ChunkedIO which the (un-)compresses data.
class CompressedChunkedIO : public ChunkedIO {
public:
CompressedChunkedIO(ChunkedIO* arg_io) // takes ownership
explicit CompressedChunkedIO(ChunkedIO* arg_io) // takes ownership
: io(arg_io), zin(), zout(), error(), compress(), uncompress(),
uncompressed_bytes_read(), uncompressed_bytes_written() {}
virtual ~CompressedChunkedIO() { delete io; }
~CompressedChunkedIO() override { delete io; }
virtual bool Init(); // does *not* call arg_io->Init()
virtual bool Read(Chunk** chunk, bool may_block = false);
virtual bool Write(Chunk* chunk);
virtual bool Flush() { return io->Flush(); }
virtual const char* Error() { return error ? error : io->Error(); }
virtual bool CanRead() { return io->CanRead(); }
virtual bool CanWrite() { return io->CanWrite(); }
virtual bool IsIdle() { return io->IsIdle(); }
virtual bool IsFillingUp() { return io->IsFillingUp(); }
virtual void Clear() { return io->Clear(); }
bool Init() override; // does *not* call arg_io->Init()
bool Read(Chunk** chunk, bool may_block = false) override;
bool Write(Chunk* chunk) override;
bool Flush() override { return io->Flush(); }
const char* Error() override { return error ? error : io->Error(); }
bool CanRead() override { return io->CanRead(); }
bool CanWrite() override { return io->CanWrite(); }
bool IsIdle() override { return io->IsIdle(); }
bool IsFillingUp() override { return io->IsFillingUp(); }
void Clear() override { return io->Clear(); }
bool Eof() override { return io->Eof(); }
virtual bool Eof() { return io->Eof(); }
virtual int Fd() { return io->Fd(); }
virtual iosource::FD_Set ExtraReadFDs() const
int Fd() override { return io->Fd(); }
iosource::FD_Set ExtraReadFDs() const override
{ return io->ExtraReadFDs(); }
virtual void Stats(char* buffer, int length);
void Stats(char* buffer, int length) override;
void EnableCompression(int level)
{ deflateInit(&zout, level); compress = true; }

View file

@ -703,7 +703,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
break;
case TYPE_PORT:
pval = new PortVal(*kp);
pval = port_mgr->Get(*kp);
break;
default:

View file

@ -10,7 +10,7 @@ class ListVal;
class CompositeHash {
public:
CompositeHash(TypeList* composite_type);
explicit CompositeHash(TypeList* composite_type);
~CompositeHash();
// Compute the hash corresponding to the given index val,

View file

@ -289,6 +289,50 @@ bool Connection::IsReuse(double t, const u_char* pkt)
return root_analyzer && root_analyzer->IsReuse(t, pkt);
}
bool Connection::ScaledHistoryEntry(char code, uint32& counter,
uint32& scaling_threshold,
uint32 scaling_base)
{
if ( ++counter == scaling_threshold )
{
AddHistory(code);
auto new_threshold = scaling_threshold * scaling_base;
if ( new_threshold <= scaling_threshold )
// This can happen due to wrap-around. In that
// case, reset the counter but leave the threshold
// unchanged.
counter = 0;
else
scaling_threshold = new_threshold;
return true;
}
return false;
}
void Connection::HistoryThresholdEvent(EventHandlerPtr e, bool is_orig,
uint32 threshold)
{
if ( ! e )
return;
if ( threshold == 1 )
// This will be far and away the most common case,
// and at this stage it's not a *multiple* instance.
return;
val_list* vl = new val_list;
vl->append(BuildConnVal());
vl->append(new Val(is_orig, TYPE_BOOL));
vl->append(new Val(threshold, TYPE_COUNT));
ConnectionEvent(e, 0, vl);
}
void Connection::DeleteTimer(double /* t */)
{
if ( is_active )
@ -364,9 +408,9 @@ RecordVal* Connection::BuildConnVal()
RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal(orig_addr));
id_val->Assign(1, new PortVal(ntohs(orig_port), prot_type));
id_val->Assign(1, port_mgr->Get(ntohs(orig_port), prot_type));
id_val->Assign(2, new AddrVal(resp_addr));
id_val->Assign(3, new PortVal(ntohs(resp_port), prot_type));
id_val->Assign(3, port_mgr->Get(ntohs(resp_port), prot_type));
RecordVal *orig_endp = new RecordVal(endpoint);
orig_endp->Assign(0, new Val(0, TYPE_COUNT));

View file

@ -57,7 +57,7 @@ class Connection : public BroObj {
public:
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
uint32 flow, const Packet* pkt, const EncapsulationStack* arg_encap);
virtual ~Connection();
~Connection() override;
// Invoked when an encapsulation is discovered. It records the
// encapsulation with the connection and raises a "tunnel_changed"
@ -240,6 +240,17 @@ public:
return true;
}
// Increments the passed counter and adds it as a history
// code if it has crossed the next scaling threshold. Scaling
// is done in terms of powers of the third argument.
// Returns true if the threshold was crossed, false otherwise.
bool ScaledHistoryEntry(char code, uint32& counter,
uint32& scaling_threshold,
uint32 scaling_base = 10);
void HistoryThresholdEvent(EventHandlerPtr e, bool is_orig,
uint32 threshold);
void AddHistory(char code) { history += code; }
void DeleteTimer(double t);
@ -252,7 +263,7 @@ public:
// Sets the transport protocol in use.
void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
void SetUID(Bro::UID arg_uid) { uid = arg_uid; }
void SetUID(const Bro::UID &arg_uid) { uid = arg_uid; }
Bro::UID GetUID() const { return uid; }
@ -336,7 +347,7 @@ public:
double arg_t, int arg_do_expire, TimerType arg_type)
: Timer(arg_t, arg_type)
{ Init(arg_conn, arg_timer, arg_do_expire); }
virtual ~ConnectionTimer();
~ConnectionTimer() override;
void Dispatch(double t, int is_expire) override;

View file

@ -23,7 +23,7 @@ class DFA_State : public BroObj {
public:
DFA_State(int state_num, const EquivClass* ec,
NFA_state_list* nfa_states, AcceptingSet* accept);
~DFA_State();
~DFA_State() override;
int StateNum() const { return state_num; }
int NFAStateNum() const { return nfa_states->length(); }
@ -44,7 +44,7 @@ public:
// Returns the equivalence classes of ec's corresponding to this state.
const EquivClass* MetaECs() const { return meta_ec; }
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
void Dump(FILE* f, DFA_Machine* m);
void Stats(unsigned int* computed, unsigned int* uncomputed);
unsigned int Size();
@ -117,9 +117,7 @@ typedef PList(DFA_State) DFA_state_list;
class DFA_Machine : public BroObj {
public:
DFA_Machine(NFA_Machine* n, EquivClass* ec);
DFA_Machine(int** xtion_ptrs, int num_states, int num_ecs,
int* acc_array);
~DFA_Machine();
~DFA_Machine() override;
DFA_State* StartState() const { return start_state; }
@ -129,7 +127,7 @@ public:
int Rep(int sym);
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
void Dump(FILE* f);
unsigned int MemoryAllocation() const;

View file

@ -112,7 +112,7 @@ public:
IPAddr ReqAddr() const { return req_addr; }
string ReqStr() const
{
return req_host ? req_host : req_addr;
return req_host ? req_host : req_addr.AsString();
}
ListVal* Addrs();

View file

@ -42,8 +42,8 @@ enum DNS_MgrMode {
class DNS_Mgr : public iosource::IOSource {
public:
DNS_Mgr(DNS_MgrMode mode);
virtual ~DNS_Mgr();
explicit DNS_Mgr(DNS_MgrMode mode);
~DNS_Mgr() override;
void InitPostScript();
void Flush();
@ -132,11 +132,11 @@ protected:
void DoProcess(bool flush);
// IOSource interface.
virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except);
virtual double NextTimestamp(double* network_time);
virtual void Process();
virtual const char* Tag() { return "DNS_Mgr"; }
void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except) override;
double NextTimestamp(double* network_time) override;
void Process() override;
const char* Tag() override { return "DNS_Mgr"; }
DNS_MgrMode mode;

View file

@ -7,8 +7,8 @@
class DbgWatch {
public:
DbgWatch(BroObj* var_to_watch);
DbgWatch(Expr* expr_to_watch);
explicit DbgWatch(BroObj* var_to_watch);
explicit DbgWatch(Expr* expr_to_watch);
~DbgWatch();
protected:

View file

@ -19,7 +19,8 @@ DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = {
{ "logging", 0, false }, {"input", 0, false },
{ "threading", 0, false }, { "file_analysis", 0, false },
{ "plugins", 0, false }, { "broxygen", 0, false },
{ "pktio", 0, false }, { "broker", 0, false }
{ "pktio", 0, false }, { "broker", 0, false },
{ "scripts", 0, false}
};
DebugLogger::DebugLogger()

View file

@ -33,6 +33,7 @@ enum DebugStream {
DBG_BROXYGEN, // Broxygen
DBG_PKTIO, // Packet sources and dumpers.
DBG_BROKER, // Broker communication
DBG_SCRIPTS, // Script initialization
NUM_DBGS // Has to be last
};

View file

@ -145,7 +145,9 @@ void ODesc::Add(double d, bool no_exp)
AddBytes(&d, sizeof(d));
else
{
char tmp[256];
// Buffer needs enough chars to store max. possible "double" value
// of 1.79e308 without using scientific notation.
char tmp[350];
if ( no_exp )
modp_dtoa3(d, tmp, sizeof(tmp), IsReadable() ? 6 : 8);

View file

@ -27,7 +27,7 @@ class BroType;
class ODesc {
public:
ODesc(desc_type t=DESC_READABLE, BroFile* f=0);
explicit ODesc(desc_type t=DESC_READABLE, BroFile* f=0);
~ODesc();

View file

@ -29,7 +29,7 @@ extern void generic_delete_func(void*);
class Dictionary {
public:
Dictionary(dict_order ordering = UNORDERED,
explicit Dictionary(dict_order ordering = UNORDERED,
int initial_size = DEFAULT_DICT_SIZE);
virtual ~Dictionary();
@ -109,8 +109,6 @@ public:
// which should be delete'd when no longer needed.
IterCookie* InitForIteration() const;
void* NextEntry(HashKey*& h, IterCookie*& cookie, int return_hash) const;
void* NextEntry(const void*& key, int& key_len, IterCookie*& cookie)
const;
void StopIteration(IterCookie* cookie) const;
void SetDeleteFunc(dict_delete_func f) { delete_func = f; }
@ -143,8 +141,8 @@ private:
int NextPrime(int n) const;
int IsPrime(int n) const;
void StartChangeSize(int new_size);
void FinishChangeSize(void);
void MoveChains(void);
void FinishChangeSize();
void MoveChains();
// The following get and set the "density" threshold - if the
// average hash chain length exceeds this threshold, the
@ -197,7 +195,7 @@ private:
#define PDictdeclare(type) \
class PDict(type) : public Dictionary { \
public: \
PDict(type)(dict_order ordering = UNORDERED, \
explicit PDict(type)(dict_order ordering = UNORDERED, \
int initial_size = DEFAULT_DICT_SIZE) : \
Dictionary(ordering, initial_size) {} \
type* Lookup(const char* key) const \

View file

@ -9,7 +9,7 @@
class EquivClass {
public:
EquivClass(int size);
explicit EquivClass(int size);
~EquivClass();
void UniqueChar(int sym);

View file

@ -54,6 +54,38 @@ void Event::Describe(ODesc* d) const
d->Add("(");
}
void Event::Dispatch(bool no_remote)
{
if ( src == SOURCE_BROKER )
no_remote = true;
if ( event_serializer )
{
SerialInfo info(event_serializer);
event_serializer->Serialize(&info, handler->Name(), args);
}
if ( handler->ErrorHandler() )
reporter->BeginErrorHandler();
try
{
handler->Call(args, no_remote);
}
catch ( InterpreterException& e )
{
// Already reported.
}
if ( obj )
// obj->EventDone();
Unref(obj);
if ( handler->ErrorHandler() )
reporter->EndErrorHandler();
}
EventMgr::EventMgr()
{
head = tail = 0;
@ -166,7 +198,7 @@ RecordVal* EventMgr::GetLocalPeerVal()
src_val = new RecordVal(peer);
src_val->Assign(0, new Val(0, TYPE_COUNT));
src_val->Assign(1, new AddrVal("127.0.0.1"));
src_val->Assign(2, new PortVal(0));
src_val->Assign(2, port_mgr->Get(0));
src_val->Assign(3, new Val(true, TYPE_BOOL));
Ref(peer_description);

View file

@ -16,7 +16,7 @@ public:
Event(EventHandlerPtr handler, val_list* args,
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
TimerMgr* mgr = 0, BroObj* obj = 0);
~Event();
~Event() override;
void SetNext(Event* n) { next_event = n; }
Event* NextEvent() const { return next_event; }
@ -27,41 +27,14 @@ public:
EventHandlerPtr Handler() const { return handler; }
val_list* Args() const { return args; }
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
protected:
friend class EventMgr;
// This method is protected to make sure that everybody goes through
// EventMgr::Dispatch().
void Dispatch(bool no_remote = false)
{
if ( event_serializer )
{
SerialInfo info(event_serializer);
event_serializer->Serialize(&info, handler->Name(), args);
}
if ( handler->ErrorHandler() )
reporter->BeginErrorHandler();
try
{
handler->Call(args, no_remote);
}
catch ( InterpreterException& e )
{
// Already reported.
}
if ( obj )
// obj->EventDone();
Unref(obj);
if ( handler->ErrorHandler() )
reporter->EndErrorHandler();
}
void Dispatch(bool no_remote = false);
EventHandlerPtr handler;
val_list* args;
@ -78,9 +51,9 @@ extern uint64 num_events_dispatched;
class EventMgr : public BroObj {
public:
EventMgr();
~EventMgr();
~EventMgr() override;
void QueueEvent(EventHandlerPtr h, val_list* vl,
void QueueEvent(const EventHandlerPtr &h, val_list* vl,
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
TimerMgr* mgr = 0, BroObj* obj = 0)
{
@ -118,7 +91,7 @@ public:
// Returns a peer record describing the local Bro.
RecordVal* GetLocalPeerVal();
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
protected:
void QueueEvent(Event* event);

View file

@ -5,10 +5,8 @@
#include "RemoteSerializer.h"
#include "NetVar.h"
#ifdef ENABLE_BROKER
#include "broker/Manager.h"
#include "broker/Data.h"
#endif
EventHandler::EventHandler(const char* arg_name)
{
@ -32,19 +30,16 @@ EventHandler::operator bool() const
return enabled && ((local && local->HasBodies())
|| receivers.length()
|| generate_always
#ifdef ENABLE_BROKER
|| ! auto_remote_send.empty()
// TODO: and require a subscriber interested in a topic or unsolicited flags?
#endif
);
|| ! auto_publish.empty());
}
FuncType* EventHandler::FType()
FuncType* EventHandler::FType(bool check_export)
{
if ( type )
return type;
ID* id = lookup_ID(name, current_module.c_str());
ID* id = lookup_ID(name, current_module.c_str(), false, false,
check_export);
if ( ! id )
return 0;
@ -84,14 +79,11 @@ void EventHandler::Call(val_list* vl, bool no_remote)
remote_serializer->SendCall(&info, receivers[i], name, vl);
}
#ifdef ENABLE_BROKER
if ( ! auto_remote_send.empty() )
if ( ! auto_publish.empty() )
{
// TODO: also short-circuit based on interested subscribers/flags?
broker::message msg;
msg.reserve(vl->length() + 1);
msg.emplace_back(Name());
// Send event in form [name, xs...] where xs represent the arguments.
broker::vector xs;
xs.reserve(vl->length());
bool valid_args = true;
for ( auto i = 0; i < vl->length(); ++i )
@ -99,30 +91,33 @@ void EventHandler::Call(val_list* vl, bool no_remote)
auto opt_data = bro_broker::val_to_data((*vl)[i]);
if ( opt_data )
msg.emplace_back(move(*opt_data));
xs.emplace_back(move(*opt_data));
else
{
valid_args = false;
auto_remote_send.clear();
reporter->Error("failed auto-remote event '%s', disabled",
Name());
auto_publish.clear();
reporter->Error("failed auto-remote event '%s', disabled", Name());
break;
}
}
if ( valid_args )
{
for ( auto it = auto_remote_send.begin();
it != auto_remote_send.end(); ++it )
for ( auto it = auto_publish.begin(); ; )
{
if ( std::next(it) == auto_remote_send.end() )
broker_mgr->Event(it->first, move(msg), it->second);
const auto& topic = *it;
++it;
if ( it != auto_publish.end() )
broker_mgr->PublishEvent(topic, Name(), xs);
else
broker_mgr->Event(it->first, msg, it->second);
{
broker_mgr->PublishEvent(topic, Name(), std::move(xs));
break;
}
}
}
}
#endif
}
if ( local )

View file

@ -4,7 +4,7 @@
#define EVENTHANDLER
#include <assert.h>
#include <map>
#include <unordered_set>
#include <string>
#include "List.h"
#include "BroList.h"
@ -17,34 +17,32 @@ class UnserialInfo;
class EventHandler {
public:
EventHandler(const char* name);
explicit EventHandler(const char* name);
~EventHandler();
const char* Name() { return name; }
Func* LocalHandler() { return local; }
FuncType* FType();
FuncType* FType(bool check_export = true);
void SetLocalHandler(Func* f);
void AddRemoteHandler(SourceID peer);
void RemoveRemoteHandler(SourceID peer);
#ifdef ENABLE_BROKER
void AutoRemote(std::string topic, int flags)
void AutoPublish(std::string topic)
{
auto_remote_send[std::move(topic)] = flags;
auto_publish.insert(std::move(topic));
}
void AutoRemoteStop(const std::string& topic)
void AutoUnpublish(const std::string& topic)
{
auto_remote_send.erase(topic);
auto_publish.erase(topic);
}
#endif
void Call(val_list* vl, bool no_remote = false);
// Returns true if there is at least one local or remote handler.
operator bool() const;
explicit operator bool() const;
void SetUsed() { used = true; }
bool Used() { return used; }
@ -81,9 +79,7 @@ private:
typedef List(SourceID) receiver_list;
receiver_list receivers;
#ifdef ENABLE_BROKER
std::map<std::string, int> auto_remote_send; // topic -> flags
#endif
std::unordered_set<std::string> auto_publish;
};
// Encapsulates a ptr to an event handler to overload the boolean operator.
@ -102,7 +98,7 @@ public:
EventHandler* Ptr() { return handler; }
operator bool() const { return handler && *handler; }
explicit operator bool() const { return handler && *handler; }
EventHandler* operator->() { return handler; }
const EventHandler* operator->() const { return handler; }

View file

@ -16,22 +16,24 @@
#include "Trigger.h"
#include "IPAddr.h"
#include "broker/Data.h"
const char* expr_name(BroExprTag t)
{
static char errbuf[512];
static const char* expr_names[int(NUM_EXPRS)] = {
"name", "const",
"(*)",
"++", "--", "!", "+", "-",
"+", "-", "+=", "-=", "*", "/", "%", "&&", "||",
"++", "--", "!", "~", "+", "-",
"+", "-", "+=", "-=", "*", "/", "%",
"&", "|", "^",
"&&", "||",
"<", "<=", "==", "!=", ">=", ">", "?:", "ref",
"=", "~", "[]", "$", "?$", "[=]",
"table()", "set()", "vector()",
"$=", "in", "<<>>",
"()", "event", "schedule",
"coerce", "record_coerce", "table_coerce",
"sizeof", "flatten"
"sizeof", "flatten", "cast", "is"
};
if ( int(t) >= NUM_EXPRS )
@ -283,6 +285,9 @@ Expr* NameExpr::MakeLvalue()
if ( id->IsConst() && ! in_const_init )
ExprError("const is not a modifiable lvalue");
if ( id->IsOption() && ! in_const_init )
ExprError("option is not a modifiable lvalue");
return new RefExpr(this);
}
@ -453,7 +458,13 @@ Val* UnaryExpr::Eval(Frame* f) const
if ( is_vector(v) )
{
VectorVal* v_op = v->AsVectorVal();
VectorVal* result = new VectorVal(Type()->AsVectorType());
VectorType* out_t;
if ( Type()->Tag() == TYPE_ANY )
out_t = v->Type()->AsVectorType();
else
out_t = Type()->AsVectorType();
VectorVal* result = new VectorVal(out_t);
for ( unsigned int i = 0; i < v_op->Size(); ++i )
{
@ -660,6 +671,12 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const
if ( it == TYPE_INTERNAL_STRING )
return StringFold(v1, v2);
if ( v1->Type()->Tag() == TYPE_PATTERN )
return PatternFold(v1, v2);
if ( v1->Type()->IsSet() )
return SetFold(v1, v2);
if ( it == TYPE_INTERNAL_ADDR )
return AddrFold(v1, v2);
@ -701,6 +718,12 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const
else \
Internal("bad type in BinaryExpr::Fold");
#define DO_UINT_FOLD(op) \
if ( is_unsigned ) \
u3 = u1 op u2; \
else \
Internal("bad type in BinaryExpr::Fold");
#define DO_FOLD(op) \
if ( is_integral ) \
i3 = i1 op i2; \
@ -774,8 +797,12 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const
break;
case EXPR_AND: DO_INT_FOLD(&&); break;
case EXPR_OR: DO_INT_FOLD(||); break;
case EXPR_AND: DO_UINT_FOLD(&); break;
case EXPR_OR: DO_UINT_FOLD(|); break;
case EXPR_XOR: DO_UINT_FOLD(^); break;
case EXPR_AND_AND: DO_INT_FOLD(&&); break;
case EXPR_OR_OR: DO_INT_FOLD(||); break;
case EXPR_LT: DO_INT_VAL_FOLD(<); break;
case EXPR_LE: DO_INT_VAL_FOLD(<=); break;
@ -836,6 +863,77 @@ Val* BinaryExpr::StringFold(Val* v1, Val* v2) const
return new Val(result, TYPE_BOOL);
}
Val* BinaryExpr::PatternFold(Val* v1, Val* v2) const
{
const RE_Matcher* re1 = v1->AsPattern();
const RE_Matcher* re2 = v2->AsPattern();
if ( tag != EXPR_AND && tag != EXPR_OR )
BadTag("BinaryExpr::PatternFold");
RE_Matcher* res = tag == EXPR_AND ?
RE_Matcher_conjunction(re1, re2) :
RE_Matcher_disjunction(re1, re2);
return new PatternVal(res);
}
Val* BinaryExpr::SetFold(Val* v1, Val* v2) const
{
TableVal* tv1 = v1->AsTableVal();
TableVal* tv2 = v2->AsTableVal();
TableVal* result;
bool res = false;
switch ( tag ) {
case EXPR_AND:
return tv1->Intersect(tv2);
case EXPR_OR:
result = v1->Clone()->AsTableVal();
if ( ! tv2->AddTo(result, false, false) )
reporter->InternalError("set union failed to type check");
return result;
case EXPR_SUB:
result = v1->Clone()->AsTableVal();
if ( ! tv2->RemoveFrom(result) )
reporter->InternalError("set difference failed to type check");
return result;
case EXPR_EQ:
res = tv1->EqualTo(tv2);
break;
case EXPR_NE:
res = ! tv1->EqualTo(tv2);
break;
case EXPR_LT:
res = tv1->IsSubsetOf(tv2) && tv1->Size() < tv2->Size();
break;
case EXPR_LE:
res = tv1->IsSubsetOf(tv2);
break;
case EXPR_GE:
case EXPR_GT:
// These should't happen due to canonicalization.
reporter->InternalError("confusion over canonicalization in set comparison");
break;
default:
BadTag("BinaryExpr::SetFold", expr_name(tag));
return 0;
}
return new Val(res, TYPE_BOOL);
}
Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const
{
IPAddr a1 = v1->AsAddr();
@ -896,11 +994,17 @@ void BinaryExpr::PromoteOps(TypeTag t)
TypeTag bt1 = op1->Type()->Tag();
TypeTag bt2 = op2->Type()->Tag();
if ( IsVector(bt1) )
bool is_vec1 = IsVector(bt1);
bool is_vec2 = IsVector(bt2);
if ( is_vec1 )
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
if ( IsVector(bt2) )
if ( is_vec2 )
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
if ( (is_vec1 || is_vec2) && ! (is_vec1 && is_vec2) )
reporter->Warning("mixing vector and scalar operands is deprecated");
if ( bt1 != t )
op1 = new ArithCoerceExpr(op1, t);
if ( bt2 != t )
@ -990,7 +1094,10 @@ IncrExpr::IncrExpr(BroExprTag arg_tag, Expr* arg_op)
if ( ! IsIntegral(t->AsVectorType()->YieldType()->Tag()) )
ExprError("vector elements must be integral for increment operator");
else
{
reporter->Warning("increment/decrement operations for vectors deprecated");
SetType(t->Ref());
}
}
else
{
@ -1076,6 +1183,39 @@ bool IncrExpr::DoUnserialize(UnserialInfo* info)
return true;
}
ComplementExpr::ComplementExpr(Expr* arg_op) : UnaryExpr(EXPR_COMPLEMENT, arg_op)
{
if ( IsError() )
return;
BroType* t = op->Type();
TypeTag bt = t->Tag();
if ( bt != TYPE_COUNT )
ExprError("requires \"count\" operand");
else
SetType(base_type(TYPE_COUNT));
}
Val* ComplementExpr::Fold(Val* v) const
{
return new Val(~ v->InternalUnsigned(), type->Tag());
}
IMPLEMENT_SERIAL(ComplementExpr, SER_COMPLEMENT_EXPR);
bool ComplementExpr::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_COMPLEMENT_EXPR, UnaryExpr);
return true;
}
bool ComplementExpr::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(UnaryExpr);
return true;
}
NotExpr::NotExpr(Expr* arg_op) : UnaryExpr(EXPR_NOT, arg_op)
{
if ( IsError() )
@ -1311,7 +1451,8 @@ bool AddExpr::DoUnserialize(UnserialInfo* info)
}
AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2)
: BinaryExpr(EXPR_ADD_TO, arg_op1->MakeLvalue(), arg_op2)
: BinaryExpr(EXPR_ADD_TO,
is_vector(arg_op1) ? arg_op1 : arg_op1->MakeLvalue(), arg_op2)
{
if ( IsError() )
return;
@ -1325,6 +1466,32 @@ AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2)
SetType(base_type(bt1));
else if ( BothInterval(bt1, bt2) )
SetType(base_type(bt1));
else if ( IsVector(bt1) )
{
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
if ( IsArithmetic(bt1) )
{
if ( IsArithmetic(bt2) )
{
if ( bt2 != bt1 )
op2 = new ArithCoerceExpr(op2, bt1);
SetType(op1->Type()->Ref());
}
else
ExprError("appending non-arithmetic to arithmetic vector");
}
else if ( bt1 != bt2 )
ExprError("incompatible vector append");
else
SetType(op1->Type()->Ref());
}
else
ExprError("requires two arithmetic or two string operands");
}
@ -1342,6 +1509,14 @@ Val* AddToExpr::Eval(Frame* f) const
return 0;
}
if ( is_vector(v1) )
{
VectorVal* vv = v1->AsVectorVal();
if ( ! vv->Assign(vv->Size(), v2) )
reporter->Error("type-checking failed in vector append");
return v1;
}
Val* result = Fold(v1, v2);
Unref(v1);
Unref(v2);
@ -1375,24 +1550,39 @@ SubExpr::SubExpr(Expr* arg_op1, Expr* arg_op2)
if ( IsError() )
return;
TypeTag bt1 = op1->Type()->Tag();
if ( IsVector(bt1) )
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
const BroType* t1 = op1->Type();
const BroType* t2 = op2->Type();
TypeTag bt2 = op2->Type()->Tag();
TypeTag bt1 = t1->Tag();
if ( IsVector(bt1) )
bt1 = t1->AsVectorType()->YieldType()->Tag();
TypeTag bt2 = t2->Tag();
if ( IsVector(bt2) )
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
bt2 = t2->AsVectorType()->YieldType()->Tag();
BroType* base_result_type = 0;
if ( bt1 == TYPE_TIME && bt2 == TYPE_INTERVAL )
base_result_type = base_type(bt1);
else if ( bt1 == TYPE_TIME && bt2 == TYPE_TIME )
SetType(base_type(TYPE_INTERVAL));
else if ( bt1 == TYPE_INTERVAL && bt2 == TYPE_INTERVAL )
base_result_type = base_type(bt1);
else if ( t1->IsSet() && t2->IsSet() )
{
if ( same_type(t1, t2) )
SetType(op1->Type()->Ref());
else
ExprError("incompatible \"set\" operands");
}
else if ( BothArithmetic(bt1, bt2) )
PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2));
else
ExprError("requires arithmetic operands");
@ -1643,13 +1833,20 @@ BoolExpr::BoolExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
if ( BothBool(bt1, bt2) )
{
if ( is_vector(op1) || is_vector(op2) )
{
if ( ! (is_vector(op1) && is_vector(op2)) )
reporter->Warning("mixing vector and scalar operands is deprecated");
SetType(new VectorType(base_type(TYPE_BOOL)));
}
else
SetType(base_type(TYPE_BOOL));
}
else if ( bt1 == TYPE_PATTERN && bt2 == bt1 )
{
reporter->Warning("&& and || operators deprecated for pattern operands");
SetType(base_type(TYPE_PATTERN));
}
else
ExprError("requires boolean operands");
@ -1660,23 +1857,7 @@ Val* BoolExpr::DoSingleEval(Frame* f, Val* v1, Expr* op2) const
if ( ! v1 )
return 0;
if ( Type()->Tag() == TYPE_PATTERN )
{
Val* v2 = op2->Eval(f);
if ( ! v2 )
return 0;
RE_Matcher* re1 = v1->AsPattern();
RE_Matcher* re2 = v2->AsPattern();
RE_Matcher* res = tag == EXPR_AND ?
RE_Matcher_conjunction(re1, re2) :
RE_Matcher_disjunction(re1, re2);
return new PatternVal(res);
}
if ( tag == EXPR_AND )
if ( tag == EXPR_AND_AND )
{
if ( v1->IsZero() )
return v1;
@ -1740,8 +1921,8 @@ Val* BoolExpr::Eval(Frame* f) const
VectorVal* result = 0;
// It's either and EXPR_AND or an EXPR_OR.
bool is_and = (tag == EXPR_AND);
// It's either an EXPR_AND_AND or an EXPR_OR_OR.
bool is_and = (tag == EXPR_AND_AND);
if ( scalar_v->IsZero() == is_and )
{
@ -1782,7 +1963,7 @@ Val* BoolExpr::Eval(Frame* f) const
Val* op2 = vec_v2->Lookup(i);
if ( op1 && op2 )
{
bool local_result = (tag == EXPR_AND) ?
bool local_result = (tag == EXPR_AND_AND) ?
(! op1->IsZero() && ! op2->IsZero()) :
(! op1->IsZero() || ! op2->IsZero());
@ -1812,6 +1993,70 @@ bool BoolExpr::DoUnserialize(UnserialInfo* info)
return true;
}
BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
: BinaryExpr(arg_tag, arg_op1, arg_op2)
{
if ( IsError() )
return;
const BroType* t1 = op1->Type();
const BroType* t2 = op2->Type();
TypeTag bt1 = t1->Tag();
if ( IsVector(bt1) )
bt1 = t1->AsVectorType()->YieldType()->Tag();
TypeTag bt2 = t2->Tag();
if ( IsVector(bt2) )
bt2 = t2->AsVectorType()->YieldType()->Tag();
if ( (bt1 == TYPE_COUNT || bt1 == TYPE_COUNTER) &&
(bt2 == TYPE_COUNT || bt2 == TYPE_COUNTER) )
{
if ( bt1 == TYPE_COUNTER && bt2 == TYPE_COUNTER )
ExprError("cannot apply a bitwise operator to two \"counter\" operands");
else if ( is_vector(op1) || is_vector(op2) )
SetType(new VectorType(base_type(TYPE_COUNT)));
else
SetType(base_type(TYPE_COUNT));
}
else if ( bt1 == TYPE_PATTERN )
{
if ( bt2 != TYPE_PATTERN )
ExprError("cannot mix pattern and non-pattern operands");
else if ( tag == EXPR_XOR )
ExprError("'^' operator does not apply to patterns");
else
SetType(base_type(TYPE_PATTERN));
}
else if ( t1->IsSet() && t2->IsSet() )
{
if ( same_type(t1, t2) )
SetType(op1->Type()->Ref());
else
ExprError("incompatible \"set\" operands");
}
else
ExprError("requires \"count\" or compatible \"set\" operands");
}
IMPLEMENT_SERIAL(BitExpr, SER_BIT_EXPR);
bool BitExpr::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_BIT_EXPR, BinaryExpr);
return true;
}
bool BitExpr::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(BinaryExpr);
return true;
}
EqExpr::EqExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
: BinaryExpr(arg_tag, arg_op1, arg_op2)
{
@ -1820,13 +2065,16 @@ EqExpr::EqExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
Canonicize();
TypeTag bt1 = op1->Type()->Tag();
if ( IsVector(bt1) )
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
const BroType* t1 = op1->Type();
const BroType* t2 = op2->Type();
TypeTag bt2 = op2->Type()->Tag();
TypeTag bt1 = t1->Tag();
if ( IsVector(bt1) )
bt1 = t1->AsVectorType()->YieldType()->Tag();
TypeTag bt2 = t2->Tag();
if ( IsVector(bt2) )
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
bt2 = t2->AsVectorType()->YieldType()->Tag();
if ( is_vector(op1) || is_vector(op2) )
SetType(new VectorType(base_type(TYPE_BOOL)));
@ -1856,10 +2104,20 @@ EqExpr::EqExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
break;
case TYPE_ENUM:
if ( ! same_type(op1->Type(), op2->Type()) )
if ( ! same_type(t1, t2) )
ExprError("illegal enum comparison");
break;
case TYPE_TABLE:
if ( t1->IsSet() && t2->IsSet() )
{
if ( ! same_type(t1, t2) )
ExprError("incompatible sets in comparison");
break;
}
// FALL THROUGH
default:
ExprError("illegal comparison");
}
@ -1922,13 +2180,16 @@ RelExpr::RelExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
Canonicize();
TypeTag bt1 = op1->Type()->Tag();
if ( IsVector(bt1) )
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
const BroType* t1 = op1->Type();
const BroType* t2 = op2->Type();
TypeTag bt2 = op2->Type()->Tag();
TypeTag bt1 = t1->Tag();
if ( IsVector(bt1) )
bt1 = t1->AsVectorType()->YieldType()->Tag();
TypeTag bt2 = t2->Tag();
if ( IsVector(bt2) )
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
bt2 = t2->AsVectorType()->YieldType()->Tag();
if ( is_vector(op1) || is_vector(op2) )
SetType(new VectorType(base_type(TYPE_BOOL)));
@ -1938,6 +2199,12 @@ RelExpr::RelExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
if ( BothArithmetic(bt1, bt2) )
PromoteOps(max_type(bt1, bt2));
else if ( t1->IsSet() && t2->IsSet() )
{
if ( ! same_type(t1, t2) )
ExprError("incompatible sets in comparison");
}
else if ( bt1 != bt2 )
ExprError("operands must be of the same type");
@ -4351,9 +4618,8 @@ Val* InExpr::Fold(Val* v1, Val* v2) const
const BroString* s1 = v1->AsString();
const BroString* s2 = v2->AsString();
// Could do better here - either roll our own, to deal with
// NULs, and/or Boyer-Moore if done repeatedly.
return new Val(strstr(s2->CheckString(), s1->CheckString()) != 0, TYPE_BOOL);
// Could do better here e.g. Boyer-Moore if done repeatedly.
return new Val(strstr_n(s2->Len(), s2->Bytes(), s1->Len(), reinterpret_cast<const unsigned char*>(s1->CheckString())) != -1, TYPE_BOOL);
}
if ( v1->Type()->Tag() == TYPE_ADDR &&
@ -4535,13 +4801,21 @@ Val* CallExpr::Eval(Frame* f) const
if ( func_val && v )
{
const ::Func* func = func_val->AsFunc();
calling_expr = this;
const CallExpr* current_call = f ? f->GetCall() : 0;
call_stack.emplace_back(CallInfo{this, func});
if ( f )
f->SetCall(this);
ret = func->Call(v, f); // No try/catch here; we pass exceptions upstream.
try
{
ret = func->Call(v, f);
}
catch ( ... )
{
call_stack.pop_back();
throw;
}
if ( f )
f->SetCall(current_call);
@ -4549,7 +4823,7 @@ Val* CallExpr::Eval(Frame* f) const
// Don't Unref() the arguments, as Func::Call already did that.
delete v;
calling_expr = 0;
call_stack.pop_back();
}
else
delete_vals(v);
@ -4870,7 +5144,7 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const
Unref(v);
return 0;
}
v->Append(vi);
}
return v;
@ -5201,6 +5475,117 @@ bool RecordAssignExpr::DoUnserialize(UnserialInfo* info)
return true;
}
CastExpr::CastExpr(Expr* arg_op, BroType* t) : UnaryExpr(EXPR_CAST, arg_op)
{
auto stype = Op()->Type();
::Ref(t);
SetType(t);
if ( ! can_cast_value_to_type(stype, t) )
ExprError("cast not supported");
}
Val* CastExpr::Eval(Frame* f) const
{
if ( IsError() )
return 0;
Val* v = op->Eval(f);
if ( ! v )
return 0;
Val* nv = cast_value_to_type(v, Type());
if ( nv )
{
Unref(v);
return nv;
}
ODesc d;
d.Add("invalid cast of value with type '");
v->Type()->Describe(&d);
d.Add("' to type '");
Type()->Describe(&d);
d.Add("'");
if ( same_type(v->Type(), bro_broker::DataVal::ScriptDataType()) &&
! v->AsRecordVal()->Lookup(0) )
d.Add(" (nil $data field)");
Unref(v);
reporter->ExprRuntimeError(this, "%s", d.Description());
return 0; // not reached.
}
void CastExpr::ExprDescribe(ODesc* d) const
{
Op()->Describe(d);
d->Add(" as ");
Type()->Describe(d);
}
IMPLEMENT_SERIAL(CastExpr, SER_CAST_EXPR);
bool CastExpr::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_CAST_EXPR, UnaryExpr);
return true;
}
bool CastExpr::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(UnaryExpr);
return true;
}
IsExpr::IsExpr(Expr* arg_op, BroType* arg_t) : UnaryExpr(EXPR_IS, arg_op)
{
t = arg_t;
::Ref(t);
SetType(base_type(TYPE_BOOL));
}
IsExpr::~IsExpr()
{
Unref(t);
}
Val* IsExpr::Fold(Val* v) const
{
if ( IsError() )
return 0;
if ( can_cast_value_to_type(v, t) )
return new Val(1, TYPE_BOOL);
else
return new Val(0, TYPE_BOOL);
}
void IsExpr::ExprDescribe(ODesc* d) const
{
Op()->Describe(d);
d->Add(" is ");
t->Describe(d);
}
IMPLEMENT_SERIAL(IsExpr, SER_IS_EXPR_ /* sic */);
bool IsExpr::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_IS_EXPR_, UnaryExpr);
return true;
}
bool IsExpr::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(UnaryExpr);
return true;
}
Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init)
{
if ( op1->Type()->Tag() == TYPE_RECORD &&
@ -5210,7 +5595,6 @@ Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init)
return new AssignExpr(op1, op2, is_init);
}
int check_and_promote_expr(Expr*& e, BroType* t)
{
BroType* et = e->Type();

View file

@ -17,10 +17,13 @@ typedef enum {
EXPR_ANY = -1,
EXPR_NAME, EXPR_CONST,
EXPR_CLONE,
EXPR_INCR, EXPR_DECR, EXPR_NOT, EXPR_POSITIVE, EXPR_NEGATE,
EXPR_INCR, EXPR_DECR,
EXPR_NOT, EXPR_COMPLEMENT,
EXPR_POSITIVE, EXPR_NEGATE,
EXPR_ADD, EXPR_SUB, EXPR_ADD_TO, EXPR_REMOVE_FROM,
EXPR_TIMES, EXPR_DIVIDE, EXPR_MOD,
EXPR_AND, EXPR_OR,
EXPR_AND, EXPR_OR, EXPR_XOR,
EXPR_AND_AND, EXPR_OR_OR,
EXPR_LT, EXPR_LE, EXPR_EQ, EXPR_NE, EXPR_GE, EXPR_GT,
EXPR_COND,
EXPR_REF,
@ -44,7 +47,9 @@ typedef enum {
EXPR_VECTOR_COERCE,
EXPR_SIZE,
EXPR_FLATTEN,
#define NUM_EXPRS (int(EXPR_FLATTEN) + 1)
EXPR_CAST,
EXPR_IS,
#define NUM_EXPRS (int(EXPR_IS) + 1)
} BroExprTag;
extern const char* expr_name(BroExprTag t);
@ -63,7 +68,7 @@ public:
BroType* Type() const { return type; }
BroExprTag Tag() const { return tag; }
virtual ~Expr();
~Expr() override;
Expr* Ref() { ::Ref(this); return this; }
@ -182,7 +187,7 @@ public:
return (AssignExpr*) this;
}
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
bool Serialize(SerialInfo* info) const;
static Expr* Unserialize(UnserialInfo* info, BroExprTag want = EXPR_ANY);
@ -191,7 +196,7 @@ public:
protected:
Expr() { type = 0; }
Expr(BroExprTag arg_tag);
explicit Expr(BroExprTag arg_tag);
virtual void ExprDescribe(ODesc* d) const = 0;
void AddTag(ODesc* d) const;
@ -215,8 +220,8 @@ protected:
class NameExpr : public Expr {
public:
NameExpr(ID* id, bool const_init = false);
~NameExpr();
explicit NameExpr(ID* id, bool const_init = false);
~NameExpr() override;
ID* Id() const { return id; }
@ -241,8 +246,8 @@ protected:
class ConstExpr : public Expr {
public:
ConstExpr(Val* val);
~ConstExpr();
explicit ConstExpr(Val* val);
~ConstExpr() override;
Val* Value() const { return val; }
@ -278,7 +283,7 @@ protected:
UnaryExpr() { op = 0; }
UnaryExpr(BroExprTag arg_tag, Expr* arg_op);
virtual ~UnaryExpr();
~UnaryExpr() override;
void ExprDescribe(ODesc* d) const override;
@ -316,7 +321,7 @@ protected:
if ( op1->IsError() || op2->IsError() )
SetError();
}
virtual ~BinaryExpr();
~BinaryExpr() override;
// Returns the expression folded using the given constants.
virtual Val* Fold(Val* v1, Val* v2) const;
@ -324,6 +329,12 @@ protected:
// Same for when the constants are strings.
virtual Val* StringFold(Val* v1, Val* v2) const;
// Same for when the constants are patterns.
virtual Val* PatternFold(Val* v1, Val* v2) const;
// Same for when the constants are sets.
virtual Val* SetFold(Val* v1, Val* v2) const;
// Same for when the constants are addresses or subnets.
virtual Val* AddrFold(Val* v1, Val* v2) const;
virtual Val* SubNetFold(Val* v1, Val* v2) const;
@ -350,7 +361,7 @@ protected:
class CloneExpr : public UnaryExpr {
public:
CloneExpr(Expr* op);
explicit CloneExpr(Expr* op);
Val* Eval(Frame* f) const override;
protected:
@ -377,9 +388,22 @@ protected:
DECLARE_SERIAL(IncrExpr);
};
class ComplementExpr : public UnaryExpr {
public:
explicit ComplementExpr(Expr* op);
protected:
friend class Expr;
ComplementExpr() { }
Val* Fold(Val* v) const override;
DECLARE_SERIAL(ComplementExpr);
};
class NotExpr : public UnaryExpr {
public:
NotExpr(Expr* op);
explicit NotExpr(Expr* op);
protected:
friend class Expr;
@ -392,7 +416,7 @@ protected:
class PosExpr : public UnaryExpr {
public:
PosExpr(Expr* op);
explicit PosExpr(Expr* op);
protected:
friend class Expr;
@ -405,7 +429,7 @@ protected:
class NegExpr : public UnaryExpr {
public:
NegExpr(Expr* op);
explicit NegExpr(Expr* op);
protected:
friend class Expr;
@ -418,7 +442,7 @@ protected:
class SizeExpr : public UnaryExpr {
public:
SizeExpr(Expr* op);
explicit SizeExpr(Expr* op);
Val* Eval(Frame* f) const override;
protected:
@ -530,6 +554,17 @@ protected:
DECLARE_SERIAL(BoolExpr);
};
class BitExpr : public BinaryExpr {
public:
BitExpr(BroExprTag tag, Expr* op1, Expr* op2);
protected:
friend class Expr;
BitExpr() { }
DECLARE_SERIAL(BitExpr);
};
class EqExpr : public BinaryExpr {
public:
EqExpr(BroExprTag tag, Expr* op1, Expr* op2);
@ -559,7 +594,7 @@ protected:
class CondExpr : public Expr {
public:
CondExpr(Expr* op1, Expr* op2, Expr* op3);
~CondExpr();
~CondExpr() override;
const Expr* Op1() const { return op1; }
const Expr* Op2() const { return op2; }
@ -585,7 +620,7 @@ protected:
class RefExpr : public UnaryExpr {
public:
RefExpr(Expr* op);
explicit RefExpr(Expr* op);
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN) override;
Expr* MakeLvalue() override;
@ -602,7 +637,7 @@ public:
// If val is given, evaluating this expression will always yield the val
// yet still perform the assignment. Used for triggers.
AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0);
virtual ~AssignExpr() { Unref(val); }
~AssignExpr() override { Unref(val); }
Val* Eval(Frame* f) const override;
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
@ -657,7 +692,7 @@ protected:
class FieldExpr : public UnaryExpr {
public:
FieldExpr(Expr* op, const char* field_name);
~FieldExpr();
~FieldExpr() override;
int Field() const { return field; }
const char* FieldName() const { return field_name; }
@ -689,7 +724,7 @@ protected:
class HasFieldExpr : public UnaryExpr {
public:
HasFieldExpr(Expr* op, const char* field_name);
~HasFieldExpr();
~HasFieldExpr() override;
const char* FieldName() const { return field_name; }
@ -709,8 +744,8 @@ protected:
class RecordConstructorExpr : public UnaryExpr {
public:
RecordConstructorExpr(ListExpr* constructor_list);
~RecordConstructorExpr();
explicit RecordConstructorExpr(ListExpr* constructor_list);
~RecordConstructorExpr() override;
protected:
friend class Expr;
@ -728,7 +763,7 @@ class TableConstructorExpr : public UnaryExpr {
public:
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
BroType* arg_type = 0);
~TableConstructorExpr() { Unref(attrs); }
~TableConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; }
@ -751,7 +786,7 @@ class SetConstructorExpr : public UnaryExpr {
public:
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
BroType* arg_type = 0);
~SetConstructorExpr() { Unref(attrs); }
~SetConstructorExpr() override { Unref(attrs); }
Attributes* Attrs() { return attrs; }
@ -772,7 +807,7 @@ protected:
class VectorConstructorExpr : public UnaryExpr {
public:
VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
explicit VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
Val* Eval(Frame* f) const override;
@ -824,7 +859,7 @@ protected:
class RecordCoerceExpr : public UnaryExpr {
public:
RecordCoerceExpr(Expr* op, RecordType* r);
~RecordCoerceExpr();
~RecordCoerceExpr() override;
protected:
friend class Expr;
@ -844,7 +879,7 @@ protected:
class TableCoerceExpr : public UnaryExpr {
public:
TableCoerceExpr(Expr* op, TableType* r);
~TableCoerceExpr();
~TableCoerceExpr() override;
protected:
friend class Expr;
@ -858,7 +893,7 @@ protected:
class VectorCoerceExpr : public UnaryExpr {
public:
VectorCoerceExpr(Expr* op, VectorType* v);
~VectorCoerceExpr();
~VectorCoerceExpr() override;
protected:
friend class Expr;
@ -873,7 +908,7 @@ protected:
// into a list of individual values.
class FlattenExpr : public UnaryExpr {
public:
FlattenExpr(Expr* op);
explicit FlattenExpr(Expr* op);
protected:
friend class Expr;
@ -892,9 +927,9 @@ class ScheduleTimer : public Timer {
public:
ScheduleTimer(EventHandlerPtr event, val_list* args, double t,
TimerMgr* tmgr);
~ScheduleTimer();
~ScheduleTimer() override;
void Dispatch(double t, int is_expire);
void Dispatch(double t, int is_expire) override;
protected:
EventHandlerPtr event;
@ -905,7 +940,7 @@ protected:
class ScheduleExpr : public Expr {
public:
ScheduleExpr(Expr* when, EventExpr* event);
~ScheduleExpr();
~ScheduleExpr() override;
int IsPure() const override;
@ -945,7 +980,7 @@ protected:
class CallExpr : public Expr {
public:
CallExpr(Expr* func, ListExpr* args, bool in_hook = false);
~CallExpr();
~CallExpr() override;
Expr* Func() const { return func; }
ListExpr* Args() const { return args; }
@ -971,7 +1006,7 @@ protected:
class EventExpr : public Expr {
public:
EventExpr(const char* name, ListExpr* args);
~EventExpr();
~EventExpr() override;
const char* Name() const { return name.c_str(); }
ListExpr* Args() const { return args; }
@ -997,8 +1032,8 @@ protected:
class ListExpr : public Expr {
public:
ListExpr();
ListExpr(Expr* e);
~ListExpr();
explicit ListExpr(Expr* e);
~ListExpr() override;
void Append(Expr* e);
@ -1044,6 +1079,37 @@ protected:
DECLARE_SERIAL(RecordAssignExpr);
};
class CastExpr : public UnaryExpr {
public:
CastExpr(Expr* op, BroType* t);
protected:
friend class Expr;
CastExpr() { }
Val* Eval(Frame* f) const override;
void ExprDescribe(ODesc* d) const override;
DECLARE_SERIAL(CastExpr);
};
class IsExpr : public UnaryExpr {
public:
IsExpr(Expr* op, BroType* t);
virtual ~IsExpr();
protected:
friend class Expr;
IsExpr() { }
Val* Fold(Val* v) const override;
void ExprDescribe(ODesc* d) const override;
DECLARE_SERIAL(IsExpr);
private:
BroType* t;
};
inline Val* Expr::ExprVal() const
{
if ( ! IsConst() )

View file

@ -302,7 +302,7 @@ FILE* BroFile::BringIntoCache()
if ( ! f )
{
strerror_r(errno, buf, sizeof(buf));
bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("can't open %s: %s", name, buf);
f = fopen("/dev/null", "w");
@ -313,7 +313,7 @@ FILE* BroFile::BringIntoCache()
return f;
}
strerror_r(errno, buf, sizeof(buf));
bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("can't open /dev/null: %s", buf);
return 0;
}
@ -323,7 +323,7 @@ FILE* BroFile::BringIntoCache()
if ( fseek(f, position, SEEK_SET) < 0 )
{
strerror_r(errno, buf, sizeof(buf));
bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("reopen seek failed: %s", buf);
}
@ -413,7 +413,7 @@ void BroFile::Suspend()
if ( (position = ftell(f)) < 0 )
{
char buf[256];
strerror_r(errno, buf, sizeof(buf));
bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("ftell failed: %s", buf);
position = 0;
}
@ -692,7 +692,7 @@ void BroFile::InitEncrypt(const char* keyfile)
// Depending on the OpenSSL version, EVP_*_cbc()
// returns a const or a non-const.
EVP_CIPHER* cipher_type = (EVP_CIPHER*) EVP_bf_cbc();
cipher_ctx = new EVP_CIPHER_CTX;
cipher_ctx = EVP_CIPHER_CTX_new();
unsigned char secret[EVP_PKEY_size(pub_key)];
unsigned char* psecret = secret;
@ -747,7 +747,7 @@ void BroFile::FinishEncrypt()
return;
}
delete cipher_ctx;
EVP_CIPHER_CTX_free(cipher_ctx);
cipher_ctx = 0;
}
}

View file

@ -22,10 +22,10 @@ class RotateTimer;
class BroFile : public BroObj {
public:
BroFile(FILE* arg_f);
explicit BroFile(FILE* arg_f);
BroFile(FILE* arg_f, const char* filename, const char* access);
BroFile(const char* filename, const char* access, BroType* arg_t = 0);
virtual ~BroFile();
~BroFile() override;
const char* Name() const;

View file

@ -16,7 +16,7 @@ Flare::Flare()
static void bad_pipe_op(const char* which)
{
char buf[256];
strerror_r(errno, buf, sizeof(buf));
bro_strerror_r(errno, buf, sizeof(buf));
reporter->FatalErrorWithCore("unexpected pipe %s failure: %s", which, buf);
}

View file

@ -21,7 +21,7 @@ class FragReassembler : public Reassembler {
public:
FragReassembler(NetSessions* s, const IP_Hdr* ip, const u_char* pkt,
HashKey* k, double t);
~FragReassembler();
~FragReassembler() override;
void AddFragment(double t, const IP_Hdr* ip, const u_char* pkt);
@ -33,8 +33,8 @@ public:
HashKey* Key() const { return key; }
protected:
void BlockInserted(DataBlock* start_block);
void Overlap(const u_char* b1, const u_char* b2, uint64 n);
void BlockInserted(DataBlock* start_block) override;
void Overlap(const u_char* b1, const u_char* b2, uint64 n) override;
void Weird(const char* name) const;
u_char* proto_hdr;
@ -53,9 +53,9 @@ public:
FragTimer(FragReassembler* arg_f, double arg_t)
: Timer(arg_t, TIMER_FRAG)
{ f = arg_f; }
~FragTimer();
~FragTimer() override;
void Dispatch(double t, int is_expire);
void Dispatch(double t, int is_expire) override;
// Break the association between this timer and its creator.
void ClearReassembler() { f = 0; }

View file

@ -33,6 +33,15 @@ Frame::~Frame()
Release();
}
void Frame::Reset(int startIdx)
{
for ( int i = startIdx; i < size; ++i )
{
Unref(frame[i]);
frame[i] = 0;
}
}
void Frame::Release()
{
for ( int i = 0; i < size; ++i )

View file

@ -15,7 +15,7 @@ class CallExpr;
class Frame : public BroObj {
public:
Frame(int size, const BroFunc* func, const val_list *fn_args);
~Frame();
~Frame() override;
Val* NthElement(int n) { return frame[n]; }
void SetElement(int n, Val* v)
@ -24,9 +24,10 @@ public:
frame[n] = v;
}
void Reset(int startIdx);
void Release();
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
// For which function is this stack frame.
const BroFunc* GetFunction() const { return function; }

View file

@ -50,7 +50,7 @@
extern RETSIGTYPE sig_handler(int signo);
const Expr* calling_expr = 0;
vector<CallInfo> call_stack;
bool did_builtin_init = false;
vector<Func*> Func::unique_ids;
@ -383,11 +383,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
FType()->FlavorString().c_str(), d.Description());
}
loop_over_list(*args, i)
f->SetElement(i, (*args)[i]);
stmt_flow_type flow = FLOW_NEXT;
Val* result = 0;
for ( size_t i = 0; i < bodies.size(); ++i )
@ -398,6 +394,21 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
Unref(result);
loop_over_list(*args, j)
{
Val* arg = (*args)[j];
if ( f->NthElement(j) != arg )
{
// Either not yet set, or somebody reassigned
// the frame slot.
Ref(arg);
f->SetElement(j, arg);
}
}
f->Reset(args->length());
try
{
result = bodies[i].stmts->Exec(f, flow);
@ -433,6 +444,11 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
}
}
// We have an extra Ref for each argument (so that they don't get
// deleted between bodies), release that.
loop_over_list(*args, k)
Unref((*args)[k]);
if ( Flavor() == FUNC_FLAVOR_HOOK )
{
if ( ! result )
@ -621,21 +637,73 @@ bool BuiltinFunc::DoUnserialize(UnserialInfo* info)
void builtin_error(const char* msg, BroObj* arg)
{
if ( calling_expr )
calling_expr->Error(msg, arg);
else
if ( call_stack.empty() )
{
reporter->Error(msg, arg);
return;
}
auto last_call = call_stack.back();
if ( call_stack.size() < 2 )
{
// Don't need to check for wrapper function like "<module>::__<func>"
last_call.call->Error(msg, arg);
return;
}
auto starts_with_double_underscore = [](const std::string& name) -> bool
{ return name.size() > 2 && name[0] == '_' && name[1] == '_'; };
auto last_loc = last_call.call->GetLocationInfo();
std::string last_func = last_call.func->Name();
auto pos = last_func.find_first_of("::");
std::string wrapper_func;
if ( pos == std::string::npos )
{
if ( ! starts_with_double_underscore(last_func) )
{
last_call.call->Error(msg, arg);
return;
}
wrapper_func = last_func.substr(2);
}
else
{
auto module_name = last_func.substr(0, pos);
auto func_name = last_func.substr(pos + 2);
if ( ! starts_with_double_underscore(func_name) )
{
last_call.call->Error(msg, arg);
return;
}
wrapper_func = module_name + "::" + func_name.substr(2);
}
auto parent_call = call_stack[call_stack.size() - 2];
auto parent_func = parent_call.func->Name();
if ( wrapper_func == parent_func )
parent_call.call->Error(msg, arg);
else
last_call.call->Error(msg, arg);
}
#include "bro.bif.func_h"
#include "stats.bif.func_h"
#include "reporter.bif.func_h"
#include "strings.bif.func_h"
#include "option.bif.func_h"
#include "bro.bif.func_def"
#include "stats.bif.func_def"
#include "reporter.bif.func_def"
#include "strings.bif.func_def"
#include "option.bif.func_def"
#include "__all__.bif.cc" // Autogenerated for compiling in the bif_target() code.
#include "__all__.bif.register.cc" // Autogenerated for compiling in the bif_target() code.
@ -653,6 +721,7 @@ void init_builtin_funcs()
TimerStats = internal_type("TimerStats")->AsRecordType();
FileAnalysisStats = internal_type("FileAnalysisStats")->AsRecordType();
ThreadStats = internal_type("ThreadStats")->AsRecordType();
BrokerStats = internal_type("BrokerStats")->AsRecordType();
var_sizes = internal_type("var_sizes")->AsTableType();
@ -660,6 +729,7 @@ void init_builtin_funcs()
#include "stats.bif.func_init"
#include "reporter.bif.func_init"
#include "strings.bif.func_init"
#include "option.bif.func_init"
did_builtin_init = true;
}

View file

@ -22,9 +22,9 @@ public:
enum Kind { BRO_FUNC, BUILTIN_FUNC };
Func(Kind arg_kind);
explicit Func(Kind arg_kind);
virtual ~Func();
~Func() override;
virtual int IsPure() const = 0;
function_flavor Flavor() const { return FType()->Flavor(); }
@ -56,7 +56,7 @@ public:
const char* Name() const { return name.c_str(); }
void SetName(const char* arg_name) { name = arg_name; }
virtual void Describe(ODesc* d) const = 0;
void Describe(ODesc* d) const override = 0;
virtual void DescribeDebug(ODesc* d, const val_list* args) const;
// This (un-)serializes only a single body (as given in SerialInfo).
@ -90,7 +90,7 @@ protected:
class BroFunc : public Func {
public:
BroFunc(ID* id, Stmt* body, id_list* inits, int frame_size, int priority);
~BroFunc();
~BroFunc() override;
int IsPure() const override;
Val* Call(val_list* args, Frame* parent) const override;
@ -116,7 +116,7 @@ typedef Val* (*built_in_func)(Frame* frame, val_list* args);
class BuiltinFunc : public Func {
public:
BuiltinFunc(built_in_func func, const char* name, int is_pure);
~BuiltinFunc();
~BuiltinFunc() override;
int IsPure() const override;
Val* Call(val_list* args, Frame* parent) const override;
@ -140,10 +140,12 @@ extern void init_builtin_funcs_subdirs();
extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call);
// This global is set prior to the interpreter making a function call.
// It's there so that built-in functions can access the location information
// associated with a call when reporting error messages.
extern const Expr* calling_expr;
struct CallInfo {
const CallExpr* call;
const Func* func;
};
extern vector<CallInfo> call_stack;
// This is set to true after the built-in functions have been initialized.
extern bool did_builtin_init;

View file

@ -20,14 +20,14 @@ typedef enum {
class HashKey {
public:
HashKey(bro_int_t i);
HashKey(bro_uint_t u);
HashKey(uint32 u);
explicit HashKey(bro_int_t i);
explicit HashKey(bro_uint_t u);
explicit HashKey(uint32 u);
HashKey(const uint32 u[], int n);
HashKey(double d);
HashKey(const void* p);
HashKey(const char* s);
HashKey(const BroString* s);
explicit HashKey(double d);
explicit HashKey(const void* p);
explicit HashKey(const char* s);
explicit HashKey(const BroString* s);
~HashKey()
{
if ( is_our_dynamic )

View file

@ -21,12 +21,13 @@ ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export)
name = copy_string(arg_name);
scope = arg_scope;
is_export = arg_is_export;
is_option = false;
type = 0;
val = 0;
attrs = 0;
is_const = 0;
is_enum_const = 0;
is_type = 0;
is_const = false;
is_enum_const = false;
is_type = false;
offset = 0;
infer_return_type = false;
@ -41,6 +42,9 @@ ID::~ID()
Unref(type);
Unref(attrs);
for ( auto element : option_handlers )
Unref(element.second);
if ( ! weak_ref )
Unref(val);
}
@ -290,6 +294,22 @@ void ID::RemoveAttr(attr_tag a)
}
}
void ID::SetOption()
{
if ( is_option )
return;
is_option = true;
// option implied redefinable
if ( ! IsRedefinable() )
{
attr_list* attr = new attr_list;
attr->append(new Attr(ATTR_REDEF));
AddAttrs(new Attributes(attr, Type(), false));
}
}
void ID::EvalFunc(Expr* ef, Expr* ev)
{
Expr* arg1 = new ConstExpr(val->Ref());
@ -772,3 +792,18 @@ void ID::UpdateValID()
}
#endif
void ID::AddOptionHandler(Func* callback, int priority)
{
option_handlers.insert({priority, callback});
}
vector<Func*> ID::GetOptionHandlers() const
{
// multimap is sorted
// It might be worth caching this if we expect it to be called
// a lot...
vector<Func*> v;
for ( auto& element : option_handlers )
v.push_back(element.second);
return v;
}

View file

@ -11,6 +11,7 @@
class Val;
class SerialInfo;
class Func;
typedef enum { INIT_NONE, INIT_FULL, INIT_EXTRA, INIT_REMOVE, } init_class;
typedef enum { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL } IDScope;
@ -18,7 +19,7 @@ typedef enum { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL } IDScope;
class ID : public BroObj {
public:
ID(const char* name, IDScope arg_scope, bool arg_is_export);
~ID();
~ID() override;
const char* Name() const { return name; }
@ -34,7 +35,7 @@ public:
BroType* Type() { return type; }
const BroType* Type() const { return type; }
void MakeType() { is_type = 1; }
void MakeType() { is_type = true; }
BroType* AsType() { return is_type ? Type() : 0; }
const BroType* AsType() const { return is_type ? Type() : 0; }
@ -51,21 +52,24 @@ public:
void SetVal(Val* v, init_class c);
void SetVal(Expr* ev, init_class c);
int HasVal() const { return val != 0; }
bool HasVal() const { return val != 0; }
Val* ID_Val() { return val; }
const Val* ID_Val() const { return val; }
void ClearVal();
void SetConst() { is_const = 1; }
int IsConst() const { return is_const; }
void SetConst() { is_const = true; }
bool IsConst() const { return is_const; }
void SetEnumConst() { is_enum_const = 1; }
int IsEnumConst() const { return is_enum_const; }
void SetOption();
bool IsOption() const { return is_option; }
void SetEnumConst() { is_enum_const = true; }
bool IsEnumConst() const { return is_enum_const; }
void SetOffset(int arg_offset) { offset = arg_offset; }
int Offset() const { return offset; }
int IsRedefinable() const { return FindAttr(ATTR_REDEF) != 0; }
bool IsRedefinable() const { return FindAttr(ATTR_REDEF) != 0; }
// Returns true if ID is one of those internal globally unique IDs
// to which MutableVals are bound (there name start with a '#').
@ -97,16 +101,23 @@ public:
bool Serialize(SerialInfo* info) const;
static ID* Unserialize(UnserialInfo* info);
bool DoInferReturnType() { return infer_return_type; }
bool DoInferReturnType() const
{ return infer_return_type; }
void SetInferReturnType(bool infer)
{ infer_return_type = infer; }
{ infer_return_type = infer; }
virtual TraversalCode Traverse(TraversalCallback* cb) const;
bool HasOptionHandlers() const
{ return !option_handlers.empty(); }
// Takes ownership of callback.
void AddOptionHandler(Func* callback, int priority);
vector<Func*> GetOptionHandlers() const;
protected:
ID() { name = 0; type = 0; val = 0; attrs = 0; }
void CheckAttr(Attr* attr);
void EvalFunc(Expr* ef, Expr* ev);
#ifdef DEBUG
@ -119,10 +130,12 @@ protected:
IDScope scope;
bool is_export;
BroType* type;
int is_const, is_enum_const, is_type;
bool is_const, is_enum_const, is_type, is_option;
int offset;
Val* val;
Attributes* attrs;
// contains list of functions that are called when an option changes
std::multimap<int, Func*> option_handlers;
bool infer_return_type;
bool weak_ref;

View file

@ -370,8 +370,8 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
int tcp_hdr_len = tp->th_off * 4;
int data_len = PayloadLen() - tcp_hdr_len;
tcp_hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP));
tcp_hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP));
tcp_hdr->Assign(0, port_mgr->Get(ntohs(tp->th_sport), TRANSPORT_TCP));
tcp_hdr->Assign(1, port_mgr->Get(ntohs(tp->th_dport), TRANSPORT_TCP));
tcp_hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT));
tcp_hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT));
tcp_hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT));
@ -388,8 +388,8 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
const struct udphdr* up = (const struct udphdr*) data;
RecordVal* udp_hdr = new RecordVal(udp_hdr_type);
udp_hdr->Assign(0, new PortVal(ntohs(up->uh_sport), TRANSPORT_UDP));
udp_hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP));
udp_hdr->Assign(0, port_mgr->Get(ntohs(up->uh_sport), TRANSPORT_UDP));
udp_hdr->Assign(1, port_mgr->Get(ntohs(up->uh_dport), TRANSPORT_UDP));
udp_hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT));
pkt_hdr->Assign(sindex + 3, udp_hdr);

View file

@ -88,7 +88,7 @@ public:
* @param s String containing an IP address as either a dotted IPv4
* address or a hex IPv6 address.
*/
IPAddr(const BroString& s)
explicit IPAddr(const BroString& s)
{
Init(s.CheckString());
}

View file

@ -12,7 +12,7 @@
class IntSet {
public:
// n is a hint for the value of the largest integer.
IntSet(unsigned int n = 1);
explicit IntSet(unsigned int n = 1);
~IntSet();
void Insert(unsigned int i);

View file

@ -42,7 +42,7 @@ public:
{ return padded_sizeof(*this) + pad_size(max_entries * sizeof(ent)); }
protected:
BaseList(int = 0);
explicit BaseList(int = 0);
BaseList(BaseList&);
void insert(ent); // add at head of list
@ -102,9 +102,9 @@ protected:
#define Listdeclare(type) \
struct List(type) : BaseList \
{ \
List(type)(type ...); \
explicit List(type)(type ...); \
List(type)() : BaseList(0) {} \
List(type)(int sz) : BaseList(sz) {} \
explicit List(type)(int sz) : BaseList(sz) {} \
List(type)(List(type)& l) : BaseList((BaseList&)l) {} \
\
void operator=(List(type)& l) \
@ -143,9 +143,9 @@ List(type)::List(type)(type e1 ...) : BaseList() \
#define PListdeclare(type) \
struct PList(type) : BaseList \
{ \
PList(type)(type* ...); \
explicit PList(type)(type* ...); \
PList(type)() : BaseList(0) {} \
PList(type)(int sz) : BaseList(sz) {} \
explicit PList(type)(int sz) : BaseList(sz) {} \
PList(type)(PList(type)& l) : BaseList((BaseList&)l) {} \
\
void operator=(PList(type)& l) \

View file

@ -12,6 +12,7 @@ NFA_State::NFA_State(int arg_sym, EquivClass* ec)
sym = arg_sym;
ccl = 0;
accept = NO_ACCEPT;
first_trans_is_back_ref = false;
mark = 0;
epsclosure = 0;
id = ++nfa_state_id;
@ -33,6 +34,7 @@ NFA_State::NFA_State(CCL* arg_ccl)
sym = SYM_CCL;
ccl = arg_ccl;
accept = NO_ACCEPT;
first_trans_is_back_ref = false;
mark = 0;
id = ++nfa_state_id;
epsclosure = 0;
@ -41,7 +43,8 @@ NFA_State::NFA_State(CCL* arg_ccl)
NFA_State::~NFA_State()
{
for ( int i = 0; i < xtions.length(); ++i )
Unref(xtions[i]);
if ( i > 0 || ! first_trans_is_back_ref )
Unref(xtions[i]);
delete epsclosure;
}
@ -55,7 +58,10 @@ void NFA_State::AddXtionsTo(NFA_state_list* ns)
NFA_State* NFA_State::DeepCopy()
{
if ( mark )
{
Ref(mark);
return mark;
}
NFA_State* copy = ccl ? new NFA_State(ccl) : new NFA_State(sym, 0);
SetMark(copy);
@ -244,7 +250,10 @@ void NFA_Machine::MakePositiveClosure()
{
AppendEpsilon();
final_state->AddXtion(first_state);
Ref(first_state);
// Don't Ref the state the final epsilon points to, otherwise we'll
// have reference cycles that lead to leaks.
final_state->SetFirstTransIsBackRef();
}
void NFA_Machine::MakeRepl(int lower, int upper)
@ -304,6 +313,13 @@ NFA_Machine* make_alternate(NFA_Machine* m1, NFA_Machine* m2)
m2->AppendState(last);
Ref(last);
// Keep these around.
Ref(m1->FirstState());
Ref(m2->FirstState());
Unref(m1);
Unref(m2);
return new NFA_Machine(first, last);
}

View file

@ -27,8 +27,8 @@ typedef PList(NFA_State) NFA_state_list;
class NFA_State : public BroObj {
public:
NFA_State(int sym, EquivClass* ec);
NFA_State(CCL* ccl);
~NFA_State();
explicit NFA_State(CCL* ccl);
~NFA_State() override;
void AddXtion(NFA_State* next_state) { xtions.append(next_state); }
NFA_state_list* Transitions() { return &xtions; }
@ -46,13 +46,15 @@ public:
NFA_State* Mark() const { return mark; }
void ClearMarks();
void SetFirstTransIsBackRef() { first_trans_is_back_ref = true; }
int TransSym() const { return sym; }
CCL* TransCCL() const { return ccl; }
int ID() const { return id; }
NFA_state_list* EpsilonClosure();
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
void Dump(FILE* f);
// Recursivly count all the reachable states.
@ -62,7 +64,13 @@ protected:
int sym; // if SYM_CCL, then use ccl
CCL* ccl; // if nil, then use sym
int accept;
// Whether the first transition points backwards. Used
// to avoid reference-counting loops.
bool first_trans_is_back_ref;
int id; // number that uniquely identifies this state
NFA_state_list xtions;
NFA_state_list* epsclosure;
NFA_State* mark;
@ -75,8 +83,8 @@ public:
class NFA_Machine : public BroObj {
public:
NFA_Machine(NFA_State* first, NFA_State* final = 0);
~NFA_Machine();
explicit NFA_Machine(NFA_State* first, NFA_State* final = 0);
~NFA_Machine() override;
NFA_State* FirstState() const { return first_state; }
@ -103,7 +111,7 @@ public:
void AppendState(NFA_State* new_state);
void AppendMachine(NFA_Machine* new_mach);
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
void Dump(FILE* f);
unsigned int MemoryAllocation() const

View file

@ -33,10 +33,7 @@
#include "iosource/PktSrc.h"
#include "iosource/PktDumper.h"
#include "plugin/Manager.h"
#ifdef ENABLE_BROKER
#include "broker/Manager.h"
#endif
extern "C" {
#include "setsignal.h"
@ -61,6 +58,7 @@ double bro_start_time = 0.0; // time Bro started.
double bro_start_network_time; // timestamp of first packet
double last_watchdog_proc_time = 0.0; // value of above during last watchdog
bool terminating = false; // whether we're done reading and finishing up
bool is_parsing = false;
const Packet *current_pkt = 0;
int current_dispatched = 0;
@ -311,11 +309,7 @@ void net_run()
}
#endif
current_iosrc = src;
bool communication_enabled = using_communication;
#ifdef ENABLE_BROKER
communication_enabled |= broker_mgr->Enabled();
#endif
auto communication_enabled = using_communication || broker_mgr->Active();
if ( src )
src->Process(); // which will call net_packet_dispatch()
@ -333,7 +327,8 @@ void net_run()
}
}
else if ( (have_pending_timers || communication_enabled) &&
else if ( (have_pending_timers || communication_enabled ||
BifConst::exit_only_after_terminate) &&
! pseudo_realtime )
{
// Take advantage of the lull to get up to
@ -386,6 +381,24 @@ void net_run()
// Check whether we have timers scheduled for
// the future on which we need to wait.
have_pending_timers = timer_mgr->Size() > 0;
if ( pseudo_realtime && communication_enabled )
{
auto have_active_packet_source = false;
for ( auto& ps : iosource_mgr->GetPktSrcs() )
{
if ( ps->IsOpen() )
{
have_active_packet_source = true;
break;
}
}
if ( ! have_active_packet_source )
// Can turn off pseudo realtime now
pseudo_realtime = 0;
}
}
// Get the final statistics now, and not when net_finish() is

View file

@ -70,6 +70,9 @@ extern bool terminating;
// True if the remote serializer is to be activated.
extern bool using_communication;
// True if Bro is currently parsing scripts.
extern bool is_parsing;
extern const Packet* current_pkt;
extern int current_dispatched;
extern double current_timestamp;
@ -80,6 +83,8 @@ extern iosource::PktDumper* pkt_dumper; // where to save packets
extern char* writefile;
extern int old_comm_usage_count;
// Script file we have already scanned (or are in the process of scanning).
// They are identified by inode number.
struct ScannedFile {

View file

@ -110,9 +110,6 @@ RecordType* geo_location;
RecordType* entropy_test_result;
TableType* dhcp_router_list;
RecordType* dhcp_msg;
RecordType* dns_msg;
RecordType* dns_answer;
RecordType* dns_soa;
@ -426,9 +423,6 @@ void init_net_var()
entropy_test_result = internal_type("entropy_test_result")->AsRecordType();
dhcp_router_list = internal_type("dhcp_router_list")->AsTableType();
dhcp_msg = internal_type("dhcp_msg")->AsRecordType();
dns_msg = internal_type("dns_msg")->AsRecordType();
dns_answer = internal_type("dns_answer")->AsRecordType();
dns_soa = internal_type("dns_soa")->AsRecordType();

View file

@ -113,9 +113,6 @@ extern RecordType* geo_location;
extern RecordType* entropy_test_result;
extern TableType* dhcp_router_list;
extern RecordType* dhcp_msg;
extern RecordType* dns_msg;
extern RecordType* dns_answer;
extern RecordType* dns_soa;

View file

@ -81,7 +81,7 @@ enum FingerprintMode {
class OSFingerprint {
public:
OSFingerprint(FingerprintMode mode);
explicit OSFingerprint(FingerprintMode mode);
~OSFingerprint() {}
bool Error() const { return err; }
@ -90,13 +90,6 @@ public:
uint8 TTL, uint16 WSS, uint8 ocnt, uint8* op, uint16 MSS,
uint8 win_scale, uint32 tstamp, uint32 quirks, uint8 ECN) const;
bool CacheMatch(const IPAddr& addr, int id);
int Get_OS_From_SYN(struct os_type* retval,
uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS,
uint8 ocnt, uint8* op, uint16 MSS, uint8 win_scale,
uint32 tstamp, /* uint8 TOS, */ uint32 quirks,
uint8 ecn) const;
void load_config(const char* file);
protected:

View file

@ -36,7 +36,7 @@ public:
text = 0;
}
virtual ~Location()
~Location() override
{
if ( delete_data )
delete [] filename;
@ -112,7 +112,7 @@ public:
SetLocationInfo(&start_location, &end_location);
}
virtual ~BroObj();
~BroObj() override;
// Report user warnings/errors. If obj2 is given, then it's
// included in the message, though if pinpoint_only is non-zero,

View file

@ -23,7 +23,8 @@ public:
protected:
HashVal() { };
HashVal(OpaqueType* t);
explicit HashVal(OpaqueType* t);
virtual bool DoInit();
virtual bool DoFeed(const void* data, size_t size);
virtual StringVal* DoGet();
@ -48,9 +49,9 @@ public:
protected:
friend class Val;
virtual bool DoInit() override;
virtual bool DoFeed(const void* data, size_t size) override;
virtual StringVal* DoGet() override;
bool DoInit() override;
bool DoFeed(const void* data, size_t size) override;
StringVal* DoGet() override;
DECLARE_SERIAL(MD5Val);
@ -67,9 +68,9 @@ public:
protected:
friend class Val;
virtual bool DoInit() override;
virtual bool DoFeed(const void* data, size_t size) override;
virtual StringVal* DoGet() override;
bool DoInit() override;
bool DoFeed(const void* data, size_t size) override;
StringVal* DoGet() override;
DECLARE_SERIAL(SHA1Val);
@ -86,9 +87,9 @@ public:
protected:
friend class Val;
virtual bool DoInit() override;
virtual bool DoFeed(const void* data, size_t size) override;
virtual StringVal* DoGet() override;
bool DoInit() override;
bool DoFeed(const void* data, size_t size) override;
StringVal* DoGet() override;
DECLARE_SERIAL(SHA256Val);
@ -106,7 +107,6 @@ public:
protected:
friend class Val;
EntropyVal(OpaqueType* t);
DECLARE_SERIAL(EntropyVal);
@ -117,7 +117,7 @@ private:
class BloomFilterVal : public OpaqueVal {
public:
explicit BloomFilterVal(probabilistic::BloomFilter* bf);
virtual ~BloomFilterVal();
~BloomFilterVal() override;
BroType* Type() const;
bool Typify(BroType* type);
@ -134,7 +134,7 @@ public:
protected:
friend class Val;
BloomFilterVal();
BloomFilterVal(OpaqueType* t);
explicit BloomFilterVal(OpaqueType* t);
DECLARE_SERIAL(BloomFilterVal);
@ -152,7 +152,7 @@ private:
class CardinalityVal: public OpaqueVal {
public:
explicit CardinalityVal(probabilistic::CardinalityCounter*);
virtual ~CardinalityVal();
~CardinalityVal() override;
void Add(const Val* val);

View file

@ -12,7 +12,7 @@ using namespace std;
class PacketDumper {
public:
PacketDumper(pcap_dumper_t* pkt_dump);
explicit PacketDumper(pcap_dumper_t* pkt_dump);
void DumpPacket(const struct pcap_pkthdr* hdr,
const u_char* pkt, int len);

View file

@ -8,7 +8,7 @@
class PacketFilter {
public:
PacketFilter(bool arg_default) { default_match = arg_default; }
explicit PacketFilter(bool arg_default) { default_match = arg_default; }
~PacketFilter() {}
// Drops all packets from a particular source (which may be given

View file

@ -191,7 +191,7 @@ void PersistenceSerializer::RaiseFinishedSendState()
{
val_list* vl = new val_list;
vl->append(new AddrVal(htonl(remote_host)));
vl->append(new PortVal(remote_port));
vl->append(port_mgr->Get(remote_port));
mgr.QueueEvent(finished_send_state, vl);
reporter->Log("Serialization done.");

View file

@ -11,7 +11,8 @@ class StateAccess;
class PersistenceSerializer : public FileSerializer {
public:
PersistenceSerializer();
virtual ~PersistenceSerializer();
~PersistenceSerializer() override;
// Define the directory where to store the data.
void SetDir(const char* arg_dir) { dir = copy_string(arg_dir); }
@ -59,15 +60,15 @@ protected:
friend class RemoteSerializer;
friend class IncrementalWriteTimer;
virtual void GotID(ID* id, Val* val);
virtual void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args);
virtual void GotFunctionCall(const char* name, double time,
Func* func, val_list* args) ;
virtual void GotStateAccess(StateAccess* s);
virtual void GotTimer(Timer* t);
virtual void GotConnection(Connection* c);
virtual void GotPacket(Packet* packet);
void GotID(ID* id, Val* val) override;
void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args) override;
void GotFunctionCall(const char* name, double time,
Func* func, val_list* args) override;
void GotStateAccess(StateAccess* s) override;
void GotTimer(Timer* t) override;
void GotConnection(Connection* c) override;
void GotPacket(Packet* packet) override;
// If file has changed since last check, read it.
bool CheckForFile(UnserialInfo* info, const char* file,

View file

@ -12,7 +12,7 @@ using namespace bro;
static void pipe_fail(int eno)
{
char tmp[256];
strerror_r(eno, tmp, sizeof(tmp));
bro_strerror_r(eno, tmp, sizeof(tmp));
reporter->FatalError("Pipe failure: %s", tmp);
}

View file

@ -15,7 +15,7 @@ public:
* @param status_flags0 descriptor status flags to set on read end of pipe.
* @param status_flags1 descriptor status flags to set on write end of pipe.
*/
Pipe(int flags0 = 0, int flags1 = 0, int status_flags0 = 0,
explicit Pipe(int flags0 = 0, int flags1 = 0, int status_flags0 = 0,
int status_flags1 = 0);
/**

View file

@ -84,7 +84,7 @@ bool LoadPolicyFileText(const char* policy_filename)
if ( fstat(fileno(f), &st) != 0 )
{
char buf[256];
strerror_r(errno, buf, sizeof(buf));
bro_strerror_r(errno, buf, sizeof(buf));
reporter->Error("fstat failed on %s: %s", policy_filename, buf);
fclose(f);
return false;

View file

@ -10,7 +10,7 @@ class PriorityQueue;
class PQ_Element {
public:
PQ_Element(double t) { time = t; offset = -1; }
explicit PQ_Element(double t) { time = t; offset = -1; }
virtual ~PQ_Element() { }
double Time() const { return time; }
@ -28,7 +28,7 @@ protected:
class PriorityQueue {
public:
PriorityQueue(int initial_size = 16);
explicit PriorityQueue(int initial_size = 16);
~PriorityQueue();
// Returns the top of queue, or nil if the queue is empty.

View file

@ -39,7 +39,7 @@ public:
void incr(int& index) { index < max_entries ? ++index : index = 0; }
protected:
BaseQueue(int = 0);
explicit BaseQueue(int = 0);
void push_front(ent); // add in front of queue
void push_back(ent); // add at end of queue
@ -73,7 +73,7 @@ protected:
struct Queue(type) : BaseQueue \
{ \
Queue(type)() : BaseQueue(0) {} \
Queue(type)(int sz) : BaseQueue(sz) {} \
explicit Queue(type)(int sz) : BaseQueue(sz) {} \
\
void push_front(type a) { BaseQueue::push_front(ent(a)); } \
void push_back(type a) { BaseQueue::push_back(ent(a)); } \
@ -88,7 +88,7 @@ struct Queue(type) : BaseQueue \
struct PQueue(type) : BaseQueue \
{ \
PQueue(type)() : BaseQueue(0) {} \
PQueue(type)(int sz) : BaseQueue(sz) {} \
explicit PQueue(type)(int sz) : BaseQueue(sz) {} \
\
void push_front(type* a){ BaseQueue::push_front(ent(a)); } \
void push_back(type* a) { BaseQueue::push_back(ent(a)); } \

View file

@ -19,6 +19,7 @@ int case_insensitive = 0;
extern int RE_parse(void);
extern void RE_set_input(const char* str);
extern void RE_done_with_scan();
Specific_RE_Matcher::Specific_RE_Matcher(match_type arg_mt, int arg_multiline)
: equiv_class(NUM_SYM)
@ -101,6 +102,19 @@ void Specific_RE_Matcher::AddPat(const char* new_pat,
pattern_text = s;
}
void Specific_RE_Matcher::MakeCaseInsensitive()
{
const char fmt[] = "(?i:%s)";
int n = strlen(pattern_text) + strlen(fmt);
char* s = new char[n + 5 /* slop */];
safe_snprintf(s, n + 5, fmt, pattern_text);
delete [] pattern_text;
pattern_text = s;
}
int Specific_RE_Matcher::Compile(int lazy)
{
if ( ! pattern_text )
@ -108,9 +122,15 @@ int Specific_RE_Matcher::Compile(int lazy)
rem = this;
RE_set_input(pattern_text);
if ( RE_parse() )
int parse_status = RE_parse();
RE_done_with_scan();
if ( parse_status )
{
reporter->Error("error compiling pattern /%s/", pattern_text);
Unref(nfa);
nfa = 0;
return 0;
}
@ -139,9 +159,19 @@ int Specific_RE_Matcher::CompileSet(const string_list& set, const int_list& idx)
loop_over_list(set, i)
{
RE_set_input(set[i]);
if ( RE_parse() )
int parse_status = RE_parse();
RE_done_with_scan();
if ( parse_status )
{
reporter->Error("error compiling pattern /%s/", set[i]);
if ( set_nfa && set_nfa != nfa )
Unref(set_nfa);
else
Unref(nfa);
nfa = 0;
return 0;
}
@ -408,6 +438,14 @@ RE_Matcher::RE_Matcher(const char* pat)
AddPat(pat);
}
RE_Matcher::RE_Matcher(const char* exact_pat, const char* anywhere_pat)
{
re_anywhere = new Specific_RE_Matcher(MATCH_ANYWHERE);
re_anywhere->SetPat(anywhere_pat);
re_exact = new Specific_RE_Matcher(MATCH_EXACTLY);
re_exact->SetPat(exact_pat);
}
RE_Matcher::~RE_Matcher()
{
delete re_anywhere;
@ -420,6 +458,12 @@ void RE_Matcher::AddPat(const char* new_pat)
re_exact->AddPat(new_pat);
}
void RE_Matcher::MakeCaseInsensitive()
{
re_anywhere->MakeCaseInsensitive();
re_exact->MakeCaseInsensitive();
}
int RE_Matcher::Compile(int lazy)
{
return re_anywhere->Compile(lazy) && re_exact->Compile(lazy);

View file

@ -49,11 +49,13 @@ typedef enum { MATCH_ANYWHERE, MATCH_EXACTLY, } match_type;
class Specific_RE_Matcher {
public:
Specific_RE_Matcher(match_type mt, int multiline=0);
explicit Specific_RE_Matcher(match_type mt, int multiline=0);
~Specific_RE_Matcher();
void AddPat(const char* pat);
void MakeCaseInsensitive();
void SetPat(const char* pat) { pattern_text = copy_string(pat); }
int Compile(int lazy = 0);
@ -133,7 +135,7 @@ protected:
class RE_Match_State {
public:
RE_Match_State(Specific_RE_Matcher* matcher)
explicit RE_Match_State(Specific_RE_Matcher* matcher)
{
dfa = matcher->DFA() ? matcher->DFA() : 0;
ecs = matcher->EC()->EquivClasses();
@ -172,12 +174,15 @@ protected:
class RE_Matcher : SerialObj {
public:
RE_Matcher();
RE_Matcher(const char* pat);
virtual ~RE_Matcher();
explicit RE_Matcher(const char* pat);
RE_Matcher(const char* exact_pat, const char* anywhere_pat);
virtual ~RE_Matcher() override;
void AddDef(const char* defn_name, const char* defn_val);
void AddPat(const char* pat);
// Makes the matcher as specified to date case-insensitive.
void MakeCaseInsensitive();
int Compile(int lazy = 0);
// Returns true if s exactly matches the pattern, false otherwise.

View file

@ -10,9 +10,9 @@
static const bool DEBUG_reassem = false;
DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq,
DataBlock* arg_prev, DataBlock* arg_next,
ReassemblerType reassem_type)
DataBlock::DataBlock(Reassembler* reass, const u_char* data,
uint64 size, uint64 arg_seq, DataBlock* arg_prev,
DataBlock* arg_next, ReassemblerType reassem_type)
{
seq = arg_seq;
upper = seq + size;
@ -28,6 +28,9 @@ DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq,
if ( next )
next->prev = this;
reassembler = reass;
reassembler->size_of_all_blocks += size;
rtype = reassem_type;
Reassembler::sizes[rtype] += pad_size(size) + padded_sizeof(DataBlock);
Reassembler::total_size += pad_size(size) + padded_sizeof(DataBlock);
@ -37,12 +40,11 @@ uint64 Reassembler::total_size = 0;
uint64 Reassembler::sizes[REASSEM_NUM];
Reassembler::Reassembler(uint64 init_seq, ReassemblerType reassem_type)
: blocks(), last_block(), old_blocks(), last_old_block(),
last_reassem_seq(init_seq), trim_seq(init_seq),
max_old_blocks(0), total_old_blocks(0), size_of_all_blocks(0),
rtype(reassem_type)
{
blocks = last_block = 0;
old_blocks = last_old_block = 0;
total_old_blocks = max_old_blocks = 0;
trim_seq = last_reassem_seq = init_seq;
rtype = reassem_type;
}
Reassembler::~Reassembler()
@ -57,6 +59,10 @@ void Reassembler::CheckOverlap(DataBlock *head, DataBlock *tail,
if ( ! head || ! tail )
return;
if ( seq == tail->upper )
// Special case check for common case of appending to the end.
return;
uint64 upper = (seq + len);
for ( DataBlock* b = head; b; b = b->next )
@ -116,7 +122,7 @@ void Reassembler::NewBlock(double t, uint64 seq, uint64 len, const u_char* data)
if ( ! blocks )
blocks = last_block = start_block =
new DataBlock(data, len, seq, 0, 0, rtype);
new DataBlock(this, data, len, seq, 0, 0, rtype);
else
start_block = AddAndCheck(blocks, seq, upper_seq, data);
@ -249,12 +255,7 @@ void Reassembler::ClearOldBlocks()
uint64 Reassembler::TotalSize() const
{
uint64 size = 0;
for ( DataBlock* b = blocks; b; b = b->next )
size += b->Size();
return size;
return size_of_all_blocks;
}
void Reassembler::Describe(ODesc* d) const
@ -280,8 +281,8 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
// Special check for the common case of appending to the end.
if ( last_block && seq == last_block->upper )
{
last_block = new DataBlock(data, upper - seq, seq,
last_block, 0, rtype);
last_block = new DataBlock(this, data, upper - seq,
seq, last_block, 0, rtype);
return last_block;
}
@ -294,7 +295,8 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
{
// b is the last block, and it comes completely before
// the new block.
last_block = new DataBlock(data, upper - seq, seq, b, 0, rtype);
last_block = new DataBlock(this, data, upper - seq,
seq, b, 0, rtype);
return last_block;
}
@ -303,7 +305,8 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
if ( upper <= b->seq )
{
// The new block comes completely before b.
new_b = new DataBlock(data, upper - seq, seq, b->prev, b, rtype);
new_b = new DataBlock(this, data, upper - seq, seq,
b->prev, b, rtype);
if ( b == blocks )
blocks = new_b;
return new_b;
@ -314,7 +317,8 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
{
// The new block has a prefix that comes before b.
uint64 prefix_len = b->seq - seq;
new_b = new DataBlock(data, prefix_len, seq, b->prev, b, rtype);
new_b = new DataBlock(this, data, prefix_len, seq,
b->prev, b, rtype);
if ( b == blocks )
blocks = new_b;

View file

@ -18,11 +18,14 @@ enum ReassemblerType {
REASSEM_NUM,
};
class Reassembler;
class DataBlock {
public:
DataBlock(const u_char* data, uint64 size, uint64 seq,
DataBlock* prev, DataBlock* next,
ReassemblerType reassem_type = REASSEM_UNKNOWN);
DataBlock(Reassembler* reass, const u_char* data,
uint64 size, uint64 seq,
DataBlock* prev, DataBlock* next,
ReassemblerType reassem_type = REASSEM_UNKNOWN);
~DataBlock();
@ -33,12 +36,14 @@ public:
uint64 seq, upper;
u_char* block;
ReassemblerType rtype;
Reassembler* reassembler; // Non-owning pointer back to parent.
};
class Reassembler : public BroObj {
public:
Reassembler(uint64 init_seq, ReassemblerType reassem_type = REASSEM_UNKNOWN);
virtual ~Reassembler();
~Reassembler() override;
void NewBlock(double t, uint64 seq, uint64 len, const u_char* data);
@ -55,7 +60,7 @@ public:
uint64 TotalSize() const; // number of bytes buffered up
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
bool Serialize(SerialInfo* info) const;
static Reassembler* Unserialize(UnserialInfo* info);
@ -96,6 +101,7 @@ protected:
uint64 trim_seq; // how far we've trimmed
uint32 max_old_blocks;
uint32 total_old_blocks;
uint64 size_of_all_blocks;
ReassemblerType rtype;
@ -105,6 +111,7 @@ protected:
inline DataBlock::~DataBlock()
{
reassembler->size_of_all_blocks -= Size();
Reassembler::total_size -= pad_size(upper - seq) + padded_sizeof(DataBlock);
Reassembler::sizes[rtype] -= pad_size(upper - seq) + padded_sizeof(DataBlock);
delete [] block;

View file

@ -255,7 +255,7 @@ struct ping_args {
# define DEBUG_COMM(msg)
#endif
#define READ_CHUNK(i, c, do_if_eof) \
#define READ_CHUNK(i, c, do_if_eof, kill_me) \
{ \
if ( ! i->Read(&c) ) \
{ \
@ -264,7 +264,7 @@ struct ping_args {
do_if_eof; \
} \
else \
Error(fmt("can't read data chunk: %s", io->Error()), i == io); \
Error(fmt("can't read data chunk: %s", io->Error()), kill_me); \
return false; \
} \
\
@ -1809,7 +1809,7 @@ RecordVal* RemoteSerializer::MakePeerVal(Peer* peer)
v->Assign(0, new Val(uint32(peer->id), TYPE_COUNT));
// Sic! Network order for AddrVal, host order for PortVal.
v->Assign(1, new AddrVal(peer->ip));
v->Assign(2, new PortVal(peer->port, TRANSPORT_TCP));
v->Assign(2, port_mgr->Get(peer->port, TRANSPORT_TCP));
v->Assign(3, new Val(false, TYPE_BOOL));
v->Assign(4, new StringVal("")); // set when received
v->Assign(5, peer->peer_class.size() ?
@ -2730,10 +2730,10 @@ bool RemoteSerializer::ProcessLogCreateWriter()
id_val = new EnumVal(id, internal_type("Log::ID")->AsEnumType());
writer_val = new EnumVal(writer, internal_type("Log::Writer")->AsEnumType());
if ( ! log_mgr->CreateWriter(id_val, writer_val, info, num_fields, fields,
true, false, true) )
if ( ! log_mgr->CreateWriterForRemoteLog(id_val, writer_val, info, num_fields, fields) )
{
delete_fields_up_to = num_fields;
info = 0;
fields = 0;
goto error;
}
@ -2803,7 +2803,7 @@ bool RemoteSerializer::ProcessLogWrite()
id_val = new EnumVal(id, internal_type("Log::ID")->AsEnumType());
writer_val = new EnumVal(writer, internal_type("Log::Writer")->AsEnumType());
success = log_mgr->Write(id_val, writer_val, path, num_fields, vals);
success = log_mgr->WriteFromRemote(id_val, writer_val, path, num_fields, vals);
Unref(id_val);
Unref(writer_val);
@ -3586,7 +3586,7 @@ bool SocketComm::ProcessParentMessage()
{
// Argument chunk follows.
ChunkedIO::Chunk* c = 0;
READ_CHUNK(io, c, Error("parent died", true));
READ_CHUNK(io, c, Error("parent died", true), true);
parent_args = c;
parent_msgstate = TYPE;
bool result = DoParentMessage();
@ -3872,7 +3872,7 @@ bool SocketComm::ProcessRemoteMessage(SocketComm::Peer* peer)
{ // CMsg follows
ChunkedIO::Chunk* c;
READ_CHUNK(peer->io, c,
(CloseConnection(peer, true), peer))
(CloseConnection(peer, true), peer), false)
CMsg* msg = (CMsg*) c->data;
@ -3907,7 +3907,7 @@ bool SocketComm::ProcessRemoteMessage(SocketComm::Peer* peer)
// forward to our parent.
ChunkedIO::Chunk* c;
READ_CHUNK(peer->io, c,
(CloseConnection(peer, true), peer))
(CloseConnection(peer, true), peer), false)
// Set time3.
ping_args* args = (ping_args*) c->data;
@ -3921,7 +3921,7 @@ bool SocketComm::ProcessRemoteMessage(SocketComm::Peer* peer)
// forward to our parent.
ChunkedIO::Chunk* c;
READ_CHUNK(peer->io, c,
(CloseConnection(peer, true), peer))
(CloseConnection(peer, true), peer), false)
// Calculate time delta.
ping_args* args = (ping_args*) c->data;
@ -3944,7 +3944,7 @@ bool SocketComm::ProcessRemoteMessage(SocketComm::Peer* peer)
// forward to our parent.
ChunkedIO::Chunk* c;
READ_CHUNK(peer->io, c,
(CloseConnection(peer, true), peer))
(CloseConnection(peer, true), peer), false)
return ForwardChunkToParent(peer, c);
}

View file

@ -25,7 +25,7 @@ namespace threading {
class RemoteSerializer : public Serializer, public iosource::IOSource {
public:
RemoteSerializer();
virtual ~RemoteSerializer();
~RemoteSerializer() override;
// Initialize the remote serializer (calling this will fork).
void Enable();
@ -140,12 +140,12 @@ public:
void Finish();
// Overidden from IOSource:
virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except);
virtual double NextTimestamp(double* local_network_time);
virtual void Process();
virtual TimerMgr::Tag* GetCurrentTag();
virtual const char* Tag() { return "RemoteSerializer"; }
void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except) override;
double NextTimestamp(double* local_network_time) override;
void Process() override;
TimerMgr::Tag* GetCurrentTag() override;
const char* Tag() override { return "RemoteSerializer"; }
// Gracefully finishes communication by first making sure that all
// remaining data (parent & child) has been sent out.
@ -246,17 +246,17 @@ protected:
static void Log(LogLevel level, const char* msg, Peer* peer, LogSrc src = LogParent);
virtual void ReportError(const char* msg);
void ReportError(const char* msg) override;
virtual void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args);
virtual void GotFunctionCall(const char* name, double time,
Func* func, val_list* args);
virtual void GotID(ID* id, Val* val);
virtual void GotStateAccess(StateAccess* s);
virtual void GotTimer(Timer* t);
virtual void GotConnection(Connection* c);
virtual void GotPacket(Packet* packet);
void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args) override;
void GotFunctionCall(const char* name, double time,
Func* func, val_list* args) override;
void GotID(ID* id, Val* val) override;
void GotStateAccess(StateAccess* s) override;
void GotTimer(Timer* t) override;
void GotConnection(Connection* c) override;
void GotPacket(Packet* packet) override;
void Fork();

View file

@ -10,6 +10,8 @@
#include "NetVar.h"
#include "Net.h"
#include "Conn.h"
#include "plugin/Plugin.h"
#include "plugin/Manager.h"
#ifdef SYSLOG_INT
extern "C" {
@ -323,7 +325,24 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
// buffer size above.
safe_snprintf(buffer + strlen(buffer), size - strlen(buffer), " [%s]", postfix);
if ( event && via_events && ! in_error_handler )
bool raise_event = true;
if ( via_events && ! in_error_handler )
{
if ( locations.size() )
{
auto locs = locations.back();
raise_event = PLUGIN_HOOK_WITH_RESULT(HOOK_REPORTER,
HookReporter(prefix, event, conn, addl, location,
locs.first, locs.second, time, buffer), true);
}
else
raise_event = PLUGIN_HOOK_WITH_RESULT(HOOK_REPORTER,
HookReporter(prefix, event, conn, addl, location,
nullptr, nullptr, time, buffer), true);
}
if ( raise_event && event && via_events && ! in_error_handler )
{
val_list* vl = new val_list;

View file

@ -66,11 +66,11 @@ public:
// Report a runtime error in evaluating a Bro script expression. This
// function will not return but raise an InterpreterException.
void ExprRuntimeError(const Expr* expr, const char* fmt, ...);
void ExprRuntimeError(const Expr* expr, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
// Report a runtime error in evaluating a Bro script expression. This
// function will not return but raise an InterpreterException.
void RuntimeError(const Location* location, const char* fmt, ...);
void RuntimeError(const Location* location, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
// Report a traffic weirdness, i.e., an unexpected protocol situation
// that may lead to incorrectly processing a connnection.
@ -123,7 +123,7 @@ public:
private:
void DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
Connection* conn, val_list* addl, bool location, bool time,
const char* postfix, const char* fmt, va_list ap);
const char* postfix, const char* fmt, va_list ap) __attribute__((format(printf, 10, 0)));
// The order if addl, name needs to be like that since fmt_name can
// contain format specifiers

View file

@ -24,13 +24,13 @@ public:
// Implements the "event" keyword.
class RuleActionEvent : public RuleAction {
public:
RuleActionEvent(const char* arg_msg) { msg = copy_string(arg_msg); }
virtual ~RuleActionEvent() { delete [] msg; }
explicit RuleActionEvent(const char* arg_msg) { msg = copy_string(arg_msg); }
~RuleActionEvent() override { delete [] msg; }
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len);
void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len) override;
virtual void PrintDebug();
void PrintDebug() override;
private:
const char* msg;
@ -38,17 +38,17 @@ private:
class RuleActionMIME : public RuleAction {
public:
RuleActionMIME(const char* arg_mime, int arg_strength = 0)
explicit RuleActionMIME(const char* arg_mime, int arg_strength = 0)
{ mime = copy_string(arg_mime); strength = arg_strength; }
virtual ~RuleActionMIME()
~RuleActionMIME() override
{ delete [] mime; }
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len)
void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len) override
{ }
virtual void PrintDebug();
void PrintDebug() override;
string GetMIME() const
{ return mime; }
@ -64,12 +64,12 @@ private:
// Base class for enable/disable actions.
class RuleActionAnalyzer : public RuleAction {
public:
RuleActionAnalyzer(const char* analyzer);
explicit RuleActionAnalyzer(const char* analyzer);
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len) = 0;
void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len) override = 0;
virtual void PrintDebug();
void PrintDebug() override;
analyzer::Tag Analyzer() const { return analyzer; }
analyzer::Tag ChildAnalyzer() const { return child_analyzer; }
@ -81,22 +81,22 @@ private:
class RuleActionEnable : public RuleActionAnalyzer {
public:
RuleActionEnable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
explicit RuleActionEnable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len);
void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len) override;
virtual void PrintDebug();
void PrintDebug() override;
};
class RuleActionDisable : public RuleActionAnalyzer {
public:
RuleActionDisable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
explicit RuleActionDisable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len);
void DoAction(const Rule* parent, RuleEndpointState* state,
const u_char* data, int len) override;
virtual void PrintDebug();
void PrintDebug() override;
};
#endif

View file

@ -175,8 +175,14 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state,
try
{
Val* val = id->ID_Val()->AsFunc()->Call(&args);
result = val->AsBool();
Unref(val);
if ( val )
{
result = val->AsBool();
Unref(val);
}
else
result = false;
}
catch ( InterpreterException& e )

View file

@ -31,15 +31,15 @@ public:
STATE_STATELESS = 8
};
RuleConditionTCPState(int arg_tcpstates)
explicit RuleConditionTCPState(int arg_tcpstates)
{ tcpstates = arg_tcpstates; }
virtual ~RuleConditionTCPState() { }
~RuleConditionTCPState() override { }
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len);
bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len) override;
virtual void PrintDebug();
void PrintDebug() override;
private:
int tcpstates;
@ -56,13 +56,15 @@ public:
OPT_SSRR = 8,
};
RuleConditionIPOptions(int arg_options) { options = arg_options; }
virtual ~RuleConditionIPOptions() { }
explicit RuleConditionIPOptions(int arg_options) { options = arg_options; }
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len);
~RuleConditionIPOptions() override
{ }
virtual void PrintDebug();
bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len) override;
void PrintDebug() override;
private:
int options;
@ -72,12 +74,12 @@ private:
class RuleConditionSameIP : public RuleCondition {
public:
RuleConditionSameIP() { }
virtual ~RuleConditionSameIP() {}
~RuleConditionSameIP() override {}
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len);
bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len) override;
virtual void PrintDebug();
void PrintDebug() override;
};
// Implements "payload-size".
@ -88,12 +90,12 @@ public:
RuleConditionPayloadSize(uint32 arg_val, Comp arg_comp)
{ val = arg_val; comp = arg_comp; }
virtual ~RuleConditionPayloadSize() {}
~RuleConditionPayloadSize() override {}
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len);
bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len) override;
virtual void PrintDebug();
void PrintDebug() override;
private:
uint32 val;
@ -103,13 +105,13 @@ private:
// Implements "eval" which evaluates the given Bro identifier.
class RuleConditionEval : public RuleCondition {
public:
RuleConditionEval(const char* func);
virtual ~RuleConditionEval() {}
explicit RuleConditionEval(const char* func);
~RuleConditionEval() override {}
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len);
bool DoMatch(Rule* rule, RuleEndpointState* state,
const u_char* data, int len) override;
virtual void PrintDebug();
void PrintDebug() override;
private:
ID* id;
};

View file

@ -113,13 +113,13 @@ TraversalCode Scope::Traverse(TraversalCallback* cb) const
ID* lookup_ID(const char* name, const char* curr_module, bool no_global,
bool same_module_only)
bool same_module_only, bool check_export)
{
string fullname = make_full_var_name(curr_module, name);
string ID_module = extract_module_name(fullname.c_str());
bool need_export = ID_module != GLOBAL_MODULE_NAME &&
ID_module != curr_module;
bool need_export = check_export && (ID_module != GLOBAL_MODULE_NAME &&
ID_module != curr_module);
for ( int i = scopes.length() - 1; i >= 0; --i )
{

View file

@ -19,8 +19,8 @@ declare(PDict,ID);
class Scope : public BroObj {
public:
Scope(ID* id);
~Scope();
explicit Scope(ID* id);
~Scope() override;
ID* Lookup(const char* name) const { return local->Lookup(name); }
void Insert(const char* name, ID* id) { local->Insert(name, id); }
@ -47,7 +47,7 @@ public:
// Adds a variable to the list.
void AddInit(ID* id) { inits->append(id); }
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
TraversalCode Traverse(TraversalCallback* cb) const;
@ -64,7 +64,8 @@ extern bool in_debug;
// If no_global is true, don't search in the default "global" namespace.
// This passed ownership of a ref'ed ID to the caller.
extern ID* lookup_ID(const char* name, const char* module,
bool no_global = false, bool same_module_only=false);
bool no_global = false, bool same_module_only = false,
bool check_export = true);
extern ID* install_ID(const char* name, const char* module_name,
bool is_global, bool is_export);

View file

@ -3,7 +3,7 @@
// How to make objects of class Foo serializable:
//
// 1. Derive Foo (directly or indirectly) from SerialObj.
// 2. Add a SER_FOO constant to SerialTypes below.
// 2. Add a SER_FOO constant to SerialTypes in SerialTypes.h.
// 3. Add DECLARE_SERIAL(Foo) into class definition.
// 4. Add a (preferably protected) default ctor if it doesn't already exist.
// 5. For non-abstract classes, add IMPLEMENT_SERIAL(Foo, SER_FOO) to *.cc
@ -163,16 +163,16 @@ public:
// Macro helpers.
#define DECLARE_ABSTRACT_SERIAL(classname) \
virtual bool DoSerialize(SerialInfo*) const; \
virtual bool DoUnserialize(UnserialInfo*); \
bool DoSerialize(SerialInfo*) const override; \
bool DoUnserialize(UnserialInfo*) override; \
#define DECLARE_SERIAL(classname) \
static classname* Instantiate(); \
static SerialTypeRegistrator register_type; \
virtual bool DoSerialize(SerialInfo*) const override; \
virtual bool DoUnserialize(UnserialInfo*) override; \
virtual const TransientID* GetTID() const override { return &tid; } \
virtual SerialType GetSerialType() const override; \
bool DoSerialize(SerialInfo*) const override; \
bool DoUnserialize(UnserialInfo*) override; \
const TransientID* GetTID() const override { return &tid; } \
SerialType GetSerialType() const override; \
TransientID tid;
// Only needed (and usable) for non-abstract classes.

View file

@ -115,6 +115,7 @@ SERIAL_VAL(CARDINALITY_VAL, 22)
SERIAL_VAL(X509_VAL, 23)
SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24)
SERIAL_VAL(COMM_DATA_VAL, 25)
SERIAL_VAL(OCSP_RESP_VAL, 26)
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
SERIAL_EXPR(EXPR, 1)
@ -161,6 +162,10 @@ SERIAL_EXPR(SET_CONSTRUCTOR_EXPR, 41)
SERIAL_EXPR(VECTOR_CONSTRUCTOR_EXPR, 42)
SERIAL_EXPR(TABLE_COERCE_EXPR, 43)
SERIAL_EXPR(VECTOR_COERCE_EXPR, 44)
SERIAL_EXPR(CAST_EXPR, 45)
SERIAL_EXPR(IS_EXPR_, 46) // Name conflict with internal SER_IS_EXPR constant.
SERIAL_EXPR(BIT_EXPR, 47)
SERIAL_EXPR(COMPLEMENT_EXPR, 48)
#define SERIAL_STMT(name, val) SERIAL_CONST(name, val, STMT)
SERIAL_STMT(STMT, 1)

View file

@ -18,7 +18,7 @@ SerializationFormat::~SerializationFormat()
free(output);
}
void SerializationFormat::StartRead(char* data, uint32 arg_len)
void SerializationFormat::StartRead(const char* data, uint32 arg_len)
{
input = data;
input_len = arg_len;

View file

@ -19,7 +19,7 @@ public:
virtual ~SerializationFormat();
// Unserialization.
virtual void StartRead(char* data, uint32 len);
virtual void StartRead(const char* data, uint32 len);
virtual void EndRead();
virtual bool Read(int* v, const char* tag) = 0;
@ -87,7 +87,7 @@ protected:
uint32 output_size;
uint32 output_pos;
char* input;
const char* input;
uint32 input_len;
uint32 input_pos;
@ -98,40 +98,40 @@ protected:
class BinarySerializationFormat : public SerializationFormat {
public:
BinarySerializationFormat();
virtual ~BinarySerializationFormat();
~BinarySerializationFormat() override;
virtual bool Read(int* v, const char* tag);
virtual bool Read(uint16* v, const char* tag);
virtual bool Read(uint32* v, const char* tag);
virtual bool Read(int64* v, const char* tag);
virtual bool Read(uint64* v, const char* tag);
virtual bool Read(char* v, const char* tag);
virtual bool Read(bool* v, const char* tag);
virtual bool Read(double* d, const char* tag);
virtual bool Read(char** str, int* len, const char* tag);
virtual bool Read(string* s, const char* tag);
virtual bool Read(IPAddr* addr, const char* tag);
virtual bool Read(IPPrefix* prefix, const char* tag);
virtual bool Read(struct in_addr* addr, const char* tag);
virtual bool Read(struct in6_addr* addr, const char* tag);
virtual bool Write(int v, const char* tag);
virtual bool Write(uint16 v, const char* tag);
virtual bool Write(uint32 v, const char* tag);
virtual bool Write(int64 v, const char* tag);
virtual bool Write(uint64 v, const char* tag);
virtual bool Write(char v, const char* tag);
virtual bool Write(bool v, const char* tag);
virtual bool Write(double d, const char* tag);
virtual bool Write(const char* s, const char* tag);
virtual bool Write(const char* buf, int len, const char* tag);
virtual bool Write(const string& s, const char* tag);
virtual bool Write(const IPAddr& addr, const char* tag);
virtual bool Write(const IPPrefix& prefix, const char* tag);
virtual bool Write(const struct in_addr& addr, const char* tag);
virtual bool Write(const struct in6_addr& addr, const char* tag);
virtual bool WriteOpenTag(const char* tag);
virtual bool WriteCloseTag(const char* tag);
virtual bool WriteSeparator();
bool Read(int* v, const char* tag) override;
bool Read(uint16* v, const char* tag) override;
bool Read(uint32* v, const char* tag) override;
bool Read(int64* v, const char* tag) override;
bool Read(uint64* v, const char* tag) override;
bool Read(char* v, const char* tag) override;
bool Read(bool* v, const char* tag) override;
bool Read(double* d, const char* tag) override;
bool Read(char** str, int* len, const char* tag) override;
bool Read(string* s, const char* tag) override;
bool Read(IPAddr* addr, const char* tag) override;
bool Read(IPPrefix* prefix, const char* tag) override;
bool Read(struct in_addr* addr, const char* tag) override;
bool Read(struct in6_addr* addr, const char* tag) override;
bool Write(int v, const char* tag) override;
bool Write(uint16 v, const char* tag) override;
bool Write(uint32 v, const char* tag) override;
bool Write(int64 v, const char* tag) override;
bool Write(uint64 v, const char* tag) override;
bool Write(char v, const char* tag) override;
bool Write(bool v, const char* tag) override;
bool Write(double d, const char* tag) override;
bool Write(const char* s, const char* tag) override;
bool Write(const char* buf, int len, const char* tag) override;
bool Write(const string& s, const char* tag) override;
bool Write(const IPAddr& addr, const char* tag) override;
bool Write(const IPPrefix& prefix, const char* tag) override;
bool Write(const struct in_addr& addr, const char* tag) override;
bool Write(const struct in6_addr& addr, const char* tag) override;
bool WriteOpenTag(const char* tag) override;
bool WriteCloseTag(const char* tag) override;
bool WriteSeparator() override;
};
#endif

View file

@ -1017,7 +1017,7 @@ double EventPlayer::NextTimestamp(double* local_network_time)
return ne_time;
if ( ! io )
return 0;
return -1;
// Read next event if we don't have one waiting.
if ( ! ne_time )
@ -1028,7 +1028,7 @@ double EventPlayer::NextTimestamp(double* local_network_time)
}
if ( ! ne_time )
return 0;
return -1;
if ( ! network_time )
{

View file

@ -96,7 +96,7 @@ public:
protected:
// Format defaults to binary serialization.
Serializer(SerializationFormat* format = 0);
explicit Serializer(SerializationFormat* format = 0);
virtual ~Serializer();
// Reads next object.
@ -159,7 +159,7 @@ public:
// If max_cache_size is greater than zero, we'll remove old entries
// automatically if limit is reached (LRU expiration).
SerializationCache(unsigned int max_cache_size = 0);
explicit SerializationCache(unsigned int max_cache_size = 0);
~SerializationCache();
PermanentID Register(const SerialObj* obj, PermanentID pid,
@ -261,27 +261,27 @@ private:
// minimal implementation of Serializer!
class CloneSerializer : public Serializer {
public:
CloneSerializer(SerializationFormat* format = 0) : Serializer(format) { }
virtual ~CloneSerializer() { }
explicit CloneSerializer(SerializationFormat* format = 0) : Serializer(format) { }
~CloneSerializer() override
{ }
protected:
virtual void ReportError(const char* msg) { reporter->Error("%s", msg); }
virtual void GotID(ID* id, Val* val) { }
virtual void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args) { }
virtual void GotFunctionCall(const char* name, double time,
Func* func, val_list* args) { }
virtual void GotStateAccess(StateAccess* s) { delete s; }
virtual void GotTimer(Timer* t) { }
virtual void GotConnection(Connection* c) { }
virtual void GotPacket(Packet* packet) { }
void ReportError(const char* msg) override { reporter->Error("%s", msg); }
void GotID(ID* id, Val* val) override { }
void GotEvent(const char* name, double time, EventHandlerPtr event, val_list* args) override { }
void GotFunctionCall(const char* name, double time,
Func* func, val_list* args) override { }
void GotStateAccess(StateAccess* s) override { delete s; }
void GotTimer(Timer* t) override { }
void GotConnection(Connection* c) override { }
void GotPacket(Packet* packet) override { }
};
// Write values/events to file or fd.
class FileSerializer : public Serializer {
public:
FileSerializer(SerializationFormat* format = 0);
virtual ~FileSerializer();
explicit FileSerializer(SerializationFormat* format = 0);
~FileSerializer() override;
// Opens the file for serialization.
bool Open(const char* file, bool pure = false);
@ -291,16 +291,16 @@ public:
bool Read(UnserialInfo* info, const char* file, bool header = true);
protected:
virtual void ReportError(const char* msg);
virtual void GotID(ID* id, Val* val);
virtual void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args);
virtual void GotFunctionCall(const char* name, double time,
Func* func, val_list* args);
virtual void GotStateAccess(StateAccess* s);
virtual void GotTimer(Timer* t);
virtual void GotConnection(Connection* c);
virtual void GotPacket(Packet* packet);
void ReportError(const char* msg) override;
void GotID(ID* id, Val* val) override;
void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args) override;
void GotFunctionCall(const char* name, double time,
Func* func, val_list* args) override;
void GotStateAccess(StateAccess* s) override;
void GotTimer(Timer* t) override;
void GotConnection(Connection* c) override;
void GotPacket(Packet* packet) override;
bool OpenFile(const char* file, bool readonly, bool should_exist = false);
void CloseFile();
@ -331,21 +331,21 @@ public:
// Plays a file of events back.
class EventPlayer : public FileSerializer, public iosource::IOSource {
public:
EventPlayer(const char* file);
virtual ~EventPlayer();
explicit EventPlayer(const char* file);
~EventPlayer() override;
virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except);
virtual double NextTimestamp(double* local_network_time);
virtual void Process();
virtual const char* Tag() { return "EventPlayer"; }
void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except) override;
double NextTimestamp(double* local_network_time) override;
void Process() override;
const char* Tag() override { return "EventPlayer"; }
protected:
virtual void GotID(ID* id, Val* val) {}
virtual void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args);
virtual void GotFunctionCall(const char* name, double time,
Func* func, val_list* args);
void GotID(ID* id, Val* val) override {}
void GotEvent(const char* name, double time,
EventHandlerPtr event, val_list* args) override;
void GotFunctionCall(const char* name, double time,
Func* func, val_list* args) override;
double stream_time; // time of first captured event
double replay_time; // network time of replay start

View file

@ -337,11 +337,25 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
return;
}
// For both of these it is safe to pass ip_hdr because the presence
// is guaranteed for the functions that pass data to us.
uint16 ip_hdr_len = ip_hdr->HdrLen();
if ( ip_hdr_len > len )
{
Weird("invalid_IP_header_size", ip_hdr, encapsulation);
return;
}
if ( ip_hdr_len > caplen )
{
Weird("internally_truncated_header", ip_hdr, encapsulation);
return;
}
// Ignore if packet matches packet filter.
if ( packet_filter && packet_filter->Match(ip_hdr, len, caplen) )
return;
int ip_hdr_len = ip_hdr->HdrLen();
if ( ! ignore_checksums && ip4 &&
ones_complement_checksum((void*) ip4, ip_hdr_len, 0) != 0xffff )
{
@ -381,6 +395,12 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
caplen = len = ip_hdr->TotalLen();
ip_hdr_len = ip_hdr->HdrLen();
if ( ip_hdr_len > len )
{
Weird("invalid_IP_header_size", ip_hdr, encapsulation);
return;
}
}
}
@ -431,7 +451,6 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
return;
}
#endif
int proto = ip_hdr->NextProto();
if ( CheckHeaderTrunc(proto, len, caplen, pkt, encapsulation) )
@ -510,6 +529,11 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
uint16 proto_typ = ntohs(*((uint16*)(data + 2)));
int gre_version = flags_ver & 0x0007;
// If a carried packet has ethernet, this will help skip it.
unsigned int eth_len = 0;
unsigned int gre_len = gre_header_len(flags_ver);
unsigned int ppp_len = gre_version == 1 ? 4 : 0;
if ( gre_version != 0 && gre_version != 1 )
{
Weird(fmt("unknown_gre_version_%d", gre_version), ip_hdr,
@ -519,7 +543,18 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
if ( gre_version == 0 )
{
if ( proto_typ != 0x0800 && proto_typ != 0x86dd )
if ( proto_typ == 0x6558 && len > gre_len + 14 )
{
// transparent ethernet bridging
eth_len = 14;
proto_typ = ntohs(*((uint16*)(data + gre_len + 12)));
}
if ( proto_typ == 0x0800 )
proto = IPPROTO_IPV4;
else if ( proto_typ == 0x86dd )
proto = IPPROTO_IPV6;
else
{
// Not IPv4/IPv6 payload.
Weird(fmt("unknown_gre_protocol_%" PRIu16, proto_typ), ip_hdr,
@ -527,7 +562,6 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
return;
}
proto = (proto_typ == 0x0800) ? IPPROTO_IPV4 : IPPROTO_IPV6;
}
else // gre_version == 1
@ -556,10 +590,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
return;
}
unsigned int gre_len = gre_header_len(flags_ver);
unsigned int ppp_len = gre_version == 1 ? 1 : 0;
if ( len < gre_len + ppp_len || caplen < gre_len + ppp_len )
if ( len < gre_len + ppp_len + eth_len || caplen < gre_len + ppp_len + eth_len )
{
Weird("truncated_GRE", ip_hdr, encapsulation);
return;
@ -567,7 +598,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
if ( gre_version == 1 )
{
int ppp_proto = *((uint8*)(data + gre_len));
uint16 ppp_proto = ntohs(*((uint16*)(data + gre_len + 2)));
if ( ppp_proto != 0x0021 && ppp_proto != 0x0057 )
{
@ -578,9 +609,9 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
proto = (ppp_proto == 0x0021) ? IPPROTO_IPV4 : IPPROTO_IPV6;
}
data += gre_len + ppp_len;
len -= gre_len + ppp_len;
caplen -= gre_len + ppp_len;
data += gre_len + ppp_len + eth_len;
len -= gre_len + ppp_len + eth_len;
caplen -= gre_len + ppp_len + eth_len;
// Treat GRE tunnel like IP tunnels, fallthrough to logic below now
// that GRE header is stripped and only payload packet remains.
@ -607,10 +638,10 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
// Check for a valid inner packet first.
IP_Hdr* inner = 0;
int result = ParseIPPacket(caplen, data, proto, inner);
if ( result < 0 )
if ( result == -2 )
Weird("invalid_inner_IP_version", ip_hdr, encapsulation);
else if ( result < 0 )
Weird("truncated_inner_IP", ip_hdr, encapsulation);
else if ( result > 0 )
Weird("inner_IP_payload_length_mismatch", ip_hdr, encapsulation);
@ -794,6 +825,7 @@ void NetSessions::DoNextInnerPacket(double t, const Packet* pkt,
// Construct fake packet for DoNextPacket
Packet p;
p.Init(DLT_RAW, &ts, caplen, len, data, false, "");
DoNextPacket(t, &p, inner, outer);
delete inner;
@ -808,7 +840,10 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
if ( caplen < (int)sizeof(struct ip6_hdr) )
return -1;
inner = new IP_Hdr((const struct ip6_hdr*) pkt, false, caplen);
const struct ip6_hdr* ip6 = (const struct ip6_hdr*) pkt;
inner = new IP_Hdr(ip6, false, caplen);
if ( ( ip6->ip6_ctlun.ip6_un2_vfc & 0xF0 ) != 0x60 )
return -2;
}
else if ( proto == IPPROTO_IPV4 )
@ -816,7 +851,10 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
if ( caplen < (int)sizeof(struct ip) )
return -1;
inner = new IP_Hdr((const struct ip*) pkt, false);
const struct ip* ip4 = (const struct ip*) pkt;
inner = new IP_Hdr(ip4, false);
if ( ip4->ip_v != 4 )
return -2;
}
else
@ -1212,28 +1250,11 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
if ( ! WantConnection(src_h, dst_h, tproto, flags, flip) )
return 0;
ConnID flip_id = *id;
if ( flip )
{
// Make a guess that we're seeing the tail half of
// an analyzable connection.
const IPAddr ta = flip_id.src_addr;
flip_id.src_addr = flip_id.dst_addr;
flip_id.dst_addr = ta;
uint32 t = flip_id.src_port;
flip_id.src_port = flip_id.dst_port;
flip_id.dst_port = t;
id = &flip_id;
}
Connection* conn = new Connection(this, k, t, id, flow_label, pkt, encapsulation);
conn->SetTransport(tproto);
if ( flip )
conn->AddHistory('^');
conn->FlipRoles();
if ( ! analyzer_mgr->BuildInitialAnalyzerTree(conn) )
{

View file

@ -56,7 +56,7 @@ public:
: Timer(t, TIMER_TIMERMGR_EXPIRE), mgr(arg_mgr)
{ }
virtual void Dispatch(double t, int is_expire);
void Dispatch(double t, int is_expire) override;
protected:
TimerMgr* mgr;
@ -151,8 +151,9 @@ public:
/**
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
* or IPv6 header based on whether it's long enough to contain such a header
* and also that the payload length field of that header matches the actual
* or IPv6 header based on whether it's long enough to contain such a header,
* if version given in the header matches the proto argument, and also checks
* that the payload length field of that header matches the actual
* length of \a pkt given by \a caplen.
*
* @param caplen The length of \a pkt in bytes.
@ -163,7 +164,8 @@ public:
* if \a pkt looks like a valid IP packet or at least long enough
* to hold an IP header.
* @return 0 If the inner IP packet appeared valid, else -1 if \a caplen
* is greater than the supposed IP packet's payload length field or
* is greater than the supposed IP packet's payload length field, -2
* if the version of the inner header does not match proto or
* 1 if \a caplen is less than the supposed packet's payload length.
* In the -1 case, \a inner may still be non-null if \a caplen was
* long enough to be an IP header, and \a inner is always non-null
@ -258,9 +260,9 @@ public:
: Timer(t + BifConst::Tunnel::ip_tunnel_timeout,
TIMER_IP_TUNNEL_INACTIVITY), tunnel_idx(p) {}
~IPTunnelTimer() {}
~IPTunnelTimer() override {}
void Dispatch(double t, int is_expire);
void Dispatch(double t, int is_expire) override;
protected:
NetSessions::IPPair tunnel_idx;

View file

@ -41,10 +41,10 @@ public:
typedef BSSAlignVec::iterator BSSAlignVecIt;
typedef BSSAlignVec::const_iterator BSSAlignVecCIt;
BroSubstring(const string& string)
explicit BroSubstring(const string& string)
: BroString(string), _num(), _new(false) { }
BroSubstring(const BroString& string)
explicit BroSubstring(const BroString& string)
: BroString(string), _num(), _new(false) { }
BroSubstring(const BroSubstring& bst);
@ -97,7 +97,7 @@ private:
//
class BroSubstringCmp {
public:
BroSubstringCmp(unsigned int index) { _index = index; }
explicit BroSubstringCmp(unsigned int index) { _index = index; }
bool operator()(const BroSubstring* bst1, const BroSubstring* bst2) const;
private:
@ -119,7 +119,7 @@ enum SWVariant {
// Parameters for Smith-Waterman are stored in this simple record.
//
struct SWParams {
SWParams(unsigned int min_toklen = 3, SWVariant sw_variant = SW_SINGLE)
explicit SWParams(unsigned int min_toklen = 3, SWVariant sw_variant = SW_SINGLE)
{
_min_toklen = min_toklen;
_sw_variant = sw_variant;

View file

@ -48,7 +48,7 @@ public:
StateAccess(const StateAccess& sa);
virtual ~StateAccess();
~StateAccess() override;
// Replays this access in the our environment.
void Replay();

View file

@ -9,10 +9,7 @@
#include "DNS_Mgr.h"
#include "Trigger.h"
#include "threading/Manager.h"
#ifdef ENABLE_BROKER
#include "broker/Manager.h"
#endif
uint64 killed_by_inactivity = 0;
@ -226,25 +223,19 @@ void ProfileLogger::Log()
));
}
#ifdef ENABLE_BROKER
auto cs = broker_mgr->ConsumeStatistics();
auto cs = broker_mgr->GetStatistics();
file->Write(fmt("%0.6f Comm: peers=%zu stores=%zu "
"store_queries=%zu store_responses=%zu "
"outgoing_conn_status=%zu incoming_conn_status=%zu "
"reports=%zu\n",
network_time, cs.outgoing_peer_count, cs.data_store_count,
cs.pending_query_count, cs.response_count,
cs.outgoing_conn_status_count, cs.incoming_conn_status_count,
cs.report_count));
for ( const auto& s : cs.print_count )
file->Write(fmt(" %-25s prints dequeued=%zu\n", s.first.data(), s.second));
for ( const auto& s : cs.event_count )
file->Write(fmt(" %-25s events dequeued=%zu\n", s.first.data(), s.second));
for ( const auto& s : cs.log_count )
file->Write(fmt(" %-25s logs dequeued=%zu\n", s.first.data(), s.second));
#endif
"pending_queries=%zu "
"events_in=%zu events_out=%zu "
"logs_in=%zu logs_out=%zu "
"ids_in=%zu ids_out=%zu ",
network_time, cs.num_peers, cs.num_stores,
cs.num_pending_queries,
cs.num_events_incoming, cs.num_events_outgoing,
cs.num_logs_incoming, cs.num_logs_outgoing,
cs.num_ids_incoming, cs.num_ids_outgoing
));
// Script-level state.
unsigned int size, mem = 0;

View file

@ -63,14 +63,14 @@ protected:
class ProfileLogger : public SegmentStatsReporter {
public:
ProfileLogger(BroFile* file, double interval);
~ProfileLogger();
~ProfileLogger() override;
void Log();
BroFile* File() { return file; }
protected:
void SegmentProfile(const char* name, const Location* loc,
double dtime, int dmem);
double dtime, int dmem) override;
private:
BroFile* file;
@ -82,7 +82,7 @@ private:
class SampleLogger : public SegmentStatsReporter {
public:
SampleLogger();
~SampleLogger();
~SampleLogger() override;
// These are called to report that a given function or location
// has been seen during the sampling.
@ -91,7 +91,7 @@ public:
protected:
void SegmentProfile(const char* name, const Location* loc,
double dtime, int dmem);
double dtime, int dmem) override;
TableVal* load_samples;
};

View file

@ -546,8 +546,8 @@ static BroStmtTag get_last_stmt_tag(const Stmt* stmt)
return get_last_stmt_tag(stmts->Stmts()[len - 1]);
}
Case::Case(ListExpr* c, Stmt* arg_s)
: cases(c), s(arg_s)
Case::Case(ListExpr* arg_expr_cases, id_list* arg_type_cases, Stmt* arg_s)
: expr_cases(arg_expr_cases), type_cases(arg_type_cases), s(arg_s)
{
BroStmtTag t = get_last_stmt_tag(Body());
@ -557,13 +557,18 @@ Case::Case(ListExpr* c, Stmt* arg_s)
Case::~Case()
{
Unref(cases);
Unref(expr_cases);
Unref(s);
loop_over_list((*type_cases), i)
Unref((*type_cases)[i]);
delete type_cases;
}
void Case::Describe(ODesc* d) const
{
if ( ! Cases() )
if ( ! (expr_cases || type_cases) )
{
if ( ! d->IsBinary() )
d->Add("default:");
@ -578,20 +583,49 @@ void Case::Describe(ODesc* d) const
return;
}
const expr_list& e = Cases()->Exprs();
if ( ! d->IsBinary() )
d->Add("case");
d->AddCount(e.length());
loop_over_list(e, j)
if ( expr_cases )
{
if ( j > 0 && ! d->IsReadable() )
d->Add(",");
const expr_list& e = expr_cases->Exprs();
d->SP();
e[j]->Describe(d);
d->AddCount(e.length());
loop_over_list(e, i)
{
if ( i > 0 && d->IsReadable() )
d->Add(",");
d->SP();
e[i]->Describe(d);
}
}
if ( type_cases )
{
const id_list& t = *type_cases;
d->AddCount(t.length());
loop_over_list(t, i)
{
if ( i > 0 && d->IsReadable() )
d->Add(",");
d->SP();
d->Add("type");
d->SP();
t[i]->Type()->Describe(d);
if ( t[i]->Name() )
{
d->SP();
d->Add("as");
d->SP();
d->Add(t[i]->Name());
}
}
}
if ( d->IsReadable() )
@ -607,12 +641,17 @@ TraversalCode Case::Traverse(TraversalCallback* cb) const
{
TraversalCode tc;
if ( cases )
if ( expr_cases )
{
tc = cases->Traverse(cb);
tc = expr_cases->Traverse(cb);
HANDLE_TC_STMT_PRE(tc);
}
if ( type_cases )
{
// No traverse support for types.
}
tc = s->Traverse(cb);
HANDLE_TC_STMT_PRE(tc);
@ -634,17 +673,48 @@ IMPLEMENT_SERIAL(Case, SER_CASE);
bool Case::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_CASE, BroObj);
return cases->Serialize(info) && this->s->Serialize(info);
if ( ! expr_cases->Serialize(info) )
return false;
id_list empty;
id_list* types = (type_cases ? type_cases : &empty);
if ( ! SERIALIZE(types->length()) )
return false;
loop_over_list((*types), i)
{
if ( ! (*types)[i]->Serialize(info) )
return false;
}
return this->s->Serialize(info);
}
bool Case::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(BroObj);
cases = (ListExpr*) Expr::Unserialize(info, EXPR_LIST);
if ( ! cases )
expr_cases = (ListExpr*) Expr::Unserialize(info, EXPR_LIST);
if ( ! expr_cases )
return false;
int len;
if ( ! UNSERIALIZE(&len) )
return false;
type_cases = new id_list;
while ( len-- )
{
ID* id = ID::Unserialize(info);
if ( ! id )
return false;
type_cases->append(id);
}
this->s = Stmt::Unserialize(info);
return this->s != 0;
}
@ -661,7 +731,7 @@ void SwitchStmt::Init()
comp_hash = new CompositeHash(t);
Unref(t);
case_label_map.SetDeleteFunc(int_del_func);
case_label_value_map.SetDeleteFunc(int_del_func);
}
SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
@ -669,16 +739,22 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
{
Init();
if ( ! is_atomic_type(e->Type()) )
e->Error("switch expression must be of an atomic type");
bool have_exprs = false;
bool have_types = false;
loop_over_list(*cases, i)
{
Case* c = (*cases)[i];
ListExpr* le = c->Cases();
ListExpr* le = c->ExprCases();
id_list* tl = c->TypeCases();
if ( le )
{
have_exprs = true;
if ( ! is_atomic_type(e->Type()) )
e->Error("switch expression must be of an atomic type when cases are expressions");
if ( ! le->Type()->AsTypeList()->AllMatch(e->Type(), false) )
{
le->Error("case expression type differs from switch type", e);
@ -736,12 +812,34 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
exprs[j]->Error("case label expression isn't constant");
else
{
if ( ! AddCaseLabelMapping(exprs[j]->ExprVal(), i) )
if ( ! AddCaseLabelValueMapping(exprs[j]->ExprVal(), i) )
exprs[j]->Error("duplicate case label");
}
}
}
else if ( tl )
{
have_types = true;
loop_over_list((*tl), j)
{
BroType* ct = (*tl)[j]->Type();
if ( ! can_cast_value_to_type(e->Type(), ct) )
{
c->Error("cannot cast switch expression to case type");
continue;
}
if ( ! AddCaseLabelTypeMapping((*tl)[j], i) )
{
c->Error("duplicate case label");
continue;
}
}
}
else
{
if ( default_case_idx != -1 )
@ -750,6 +848,10 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
default_case_idx = i;
}
}
if ( have_exprs && have_types )
Error("cannot mix cases with expressions and types");
}
SwitchStmt::~SwitchStmt()
@ -761,7 +863,7 @@ SwitchStmt::~SwitchStmt()
delete comp_hash;
}
bool SwitchStmt::AddCaseLabelMapping(const Val* v, int idx)
bool SwitchStmt::AddCaseLabelValueMapping(const Val* v, int idx)
{
HashKey* hk = comp_hash->ComputeHash(v, 1);
@ -772,7 +874,7 @@ bool SwitchStmt::AddCaseLabelMapping(const Val* v, int idx)
type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
}
int* label_idx = case_label_map.Lookup(hk);
int* label_idx = case_label_value_map.Lookup(hk);
if ( label_idx )
{
@ -780,38 +882,76 @@ bool SwitchStmt::AddCaseLabelMapping(const Val* v, int idx)
return false;
}
case_label_map.Insert(hk, new int(idx));
case_label_value_map.Insert(hk, new int(idx));
delete hk;
return true;
}
int SwitchStmt::FindCaseLabelMatch(const Val* v) const
bool SwitchStmt::AddCaseLabelTypeMapping(ID* t, int idx)
{
HashKey* hk = comp_hash->ComputeHash(v, 1);
if ( ! hk )
for ( auto i : case_label_type_list )
{
reporter->PushLocation(e->GetLocationInfo());
reporter->Error("switch expression type mismatch (%s/%s)",
type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
return -1;
if ( same_type(i.first->Type(), t->Type()) )
return false;
}
int* label_idx = case_label_map.Lookup(hk);
auto e = std::make_pair(t, idx);
case_label_type_list.push_back(e);
delete hk;
return true;
}
if ( ! label_idx )
return default_case_idx;
std::pair<int, ID*> SwitchStmt::FindCaseLabelMatch(const Val* v) const
{
int label_idx = -1;
ID* label_id = 0;
// Find matching expression cases.
if ( case_label_value_map.Length() )
{
HashKey* hk = comp_hash->ComputeHash(v, 1);
if ( ! hk )
{
reporter->PushLocation(e->GetLocationInfo());
reporter->Error("switch expression type mismatch (%s/%s)",
type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
return std::make_pair(-1, nullptr);
}
if ( auto i = case_label_value_map.Lookup(hk) )
label_idx = *i;
delete hk;
}
// Find matching type cases.
for ( auto i : case_label_type_list )
{
auto id = i.first;
auto type = id->Type();
if ( can_cast_value_to_type(v, type) )
{
label_idx = i.second;
label_id = id;
break;
}
}
if ( label_idx < 0 )
return std::make_pair(default_case_idx, nullptr);
else
return *label_idx;
return std::make_pair(label_idx, label_id);
}
Val* SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
{
Val* rval = 0;
int matching_label_idx = FindCaseLabelMatch(v);
auto m = FindCaseLabelMatch(v);
int matching_label_idx = m.first;
ID* matching_id = m.second;
if ( matching_label_idx == -1 )
return 0;
@ -820,6 +960,12 @@ Val* SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
{
const Case* c = (*cases)[i];
if ( matching_id )
{
auto cv = cast_value_to_type(v, matching_id->Type());
f->SetElement(matching_id->Offset(), cv);
}
flow = FLOW_NEXT;
rval = c->Body()->Exec(f, flow);
@ -841,7 +987,7 @@ int SwitchStmt::IsPure() const
loop_over_list(*cases, i)
{
Case* c = (*cases)[i];
if ( ! c->Cases()->IsPure() || ! c->Body()->IsPure() )
if ( ! c->ExprCases()->IsPure() || ! c->Body()->IsPure() )
return 0;
}
@ -928,7 +1074,7 @@ bool SwitchStmt::DoUnserialize(UnserialInfo* info)
loop_over_list(*cases, i)
{
const ListExpr* le = (*cases)[i]->Cases();
const ListExpr* le = (*cases)[i]->ExprCases();
if ( ! le )
continue;
@ -937,7 +1083,7 @@ bool SwitchStmt::DoUnserialize(UnserialInfo* info)
loop_over_list(exprs, j)
{
if ( ! AddCaseLabelMapping(exprs[j]->ExprVal(), i) )
if ( ! AddCaseLabelValueMapping(exprs[j]->ExprVal(), i) )
return false;
}
}
@ -1293,6 +1439,9 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
TableVal* tv = v->AsTableVal();
const PDict(TableEntryVal)* loop_vals = tv->AsTable();
if ( ! loop_vals->Length() )
return 0;
HashKey* k;
IterCookie* c = loop_vals->InitForIteration();
while ( loop_vals->NextEntry(k, c) )
@ -1387,7 +1536,7 @@ void ForStmt::Describe(ODesc* d) const
if ( i > 0 )
d->Add(",");
}
if ( loop_vars->length() )
d->Add("]");

View file

@ -23,15 +23,15 @@ class Stmt : public BroObj {
public:
BroStmtTag Tag() const { return tag; }
virtual ~Stmt();
~Stmt() override;
virtual Val* Exec(Frame* f, stmt_flow_type& flow) const = 0;
Stmt* Ref() { ::Ref(this); return this; }
bool SetLocationInfo(const Location* loc)
bool SetLocationInfo(const Location* loc) override
{ return Stmt::SetLocationInfo(loc, loc); }
bool SetLocationInfo(const Location* start, const Location* end);
bool SetLocationInfo(const Location* start, const Location* end) override;
// True if the statement has no side effects, false otherwise.
virtual int IsPure() const;
@ -58,7 +58,7 @@ public:
void AccessStats(ODesc* d) const;
uint32 GetAccessCount() const { return access_count; }
virtual void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
virtual void IncrBPCount() { ++breakpoint_count; }
virtual void DecrBPCount()
@ -78,7 +78,7 @@ public:
protected:
Stmt() {}
Stmt(BroStmtTag arg_tag);
explicit Stmt(BroStmtTag arg_tag);
void AddTag(ODesc* d) const;
void DescribeDone(ODesc* d) const;
@ -97,18 +97,18 @@ class ExprListStmt : public Stmt {
public:
const ListExpr* ExprList() const { return l; }
TraversalCode Traverse(TraversalCallback* cb) const;
TraversalCode Traverse(TraversalCallback* cb) const override;
protected:
ExprListStmt() { l = 0; }
ExprListStmt(BroStmtTag t, ListExpr* arg_l);
virtual ~ExprListStmt();
~ExprListStmt() override;
Val* Exec(Frame* f, stmt_flow_type& flow) const;
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
virtual Val* DoExec(val_list* vals, stmt_flow_type& flow) const = 0;
void Describe(ODesc* d) const;
void Describe(ODesc* d) const override;
void PrintVals(ODesc* d, val_list* vals, int offset) const;
DECLARE_ABSTRACT_SERIAL(ExprListStmt);
@ -118,7 +118,7 @@ protected:
class PrintStmt : public ExprListStmt {
public:
PrintStmt(ListExpr* l) : ExprListStmt(STMT_PRINT, l) { }
explicit PrintStmt(ListExpr* l) : ExprListStmt(STMT_PRINT, l) { }
protected:
friend class Stmt;
@ -131,8 +131,8 @@ protected:
class ExprStmt : public Stmt {
public:
ExprStmt(Expr* e);
virtual ~ExprStmt();
explicit ExprStmt(Expr* e);
~ExprStmt() override;
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
@ -159,7 +159,7 @@ protected:
class IfStmt : public ExprStmt {
public:
IfStmt(Expr* test, Stmt* s1, Stmt* s2);
~IfStmt();
~IfStmt() override;
const Stmt* TrueBranch() const { return s1; }
const Stmt* FalseBranch() const { return s2; }
@ -183,11 +183,14 @@ protected:
class Case : public BroObj {
public:
Case(ListExpr* c, Stmt* arg_s);
~Case();
Case(ListExpr* c, id_list* types, Stmt* arg_s);
~Case() override;
const ListExpr* Cases() const { return cases; }
ListExpr* Cases() { return cases; }
const ListExpr* ExprCases() const { return expr_cases; }
ListExpr* ExprCases() { return expr_cases; }
const id_list* TypeCases() const { return type_cases; }
id_list* TypeCases() { return type_cases; }
const Stmt* Body() const { return s; }
Stmt* Body() { return s; }
@ -201,18 +204,19 @@ public:
protected:
friend class Stmt;
Case() { cases = 0; s = 0; }
Case() { expr_cases = 0; type_cases = 0; s = 0; }
DECLARE_SERIAL(Case);
ListExpr* cases;
ListExpr* expr_cases;
id_list* type_cases;
Stmt* s;
};
class SwitchStmt : public ExprStmt {
public:
SwitchStmt(Expr* index, case_list* cases);
~SwitchStmt();
~SwitchStmt() override;
const case_list* Cases() const { return cases; }
@ -232,25 +236,32 @@ protected:
// Initialize composite hash and case label map.
void Init();
// Adds an entry in case_label_map for the given value to associate it
// Adds an entry in case_label_value_map for the given value to associate it
// with the given index in the cases list. If the entry already exists,
// returns false, else returns true.
bool AddCaseLabelMapping(const Val* v, int idx);
bool AddCaseLabelValueMapping(const Val* v, int idx);
// Returns index of a case label that's equal to the value, or
// default_case_idx if no case label matches (which may be -1 if there's
// no default label).
int FindCaseLabelMatch(const Val* v) const;
// Adds an entry in case_label_type_map for the given type (w/ ID) to
// associate it with the given index in the cases list. If an entry
// for the type already exists, returns false; else returns true.
bool AddCaseLabelTypeMapping(ID* t, int idx);
// Returns index of a case label that matches the value, or
// default_case_idx if no case label matches (which may be -1 if
// there's no default label). The second tuple element is the ID of
// the matching type-based case if it defines one.
std::pair<int, ID*> FindCaseLabelMatch(const Val* v) const;
case_list* cases;
int default_case_idx;
CompositeHash* comp_hash;
PDict(int) case_label_map;
PDict(int) case_label_value_map;
std::vector<std::pair<ID*, int>> case_label_type_list;
};
class AddStmt : public ExprStmt {
public:
AddStmt(Expr* e);
explicit AddStmt(Expr* e);
int IsPure() const override;
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
@ -266,7 +277,7 @@ protected:
class DelStmt : public ExprStmt {
public:
DelStmt(Expr* e);
explicit DelStmt(Expr* e);
int IsPure() const override;
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
@ -282,7 +293,7 @@ protected:
class EventStmt : public ExprStmt {
public:
EventStmt(EventExpr* e);
explicit EventStmt(EventExpr* e);
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
@ -301,7 +312,7 @@ class WhileStmt : public Stmt {
public:
WhileStmt(Expr* loop_condition, Stmt* body);
~WhileStmt();
~WhileStmt() override;
int IsPure() const override;
@ -326,7 +337,7 @@ protected:
class ForStmt : public ExprStmt {
public:
ForStmt(id_list* loop_vars, Expr* loop_expr);
~ForStmt();
~ForStmt() override;
void AddBody(Stmt* arg_body) { body = arg_body; }
@ -399,7 +410,7 @@ protected:
class ReturnStmt : public ExprStmt {
public:
ReturnStmt(Expr* e);
explicit ReturnStmt(Expr* e);
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
@ -415,7 +426,7 @@ protected:
class StmtList : public Stmt {
public:
StmtList();
~StmtList();
~StmtList() override;
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
@ -456,14 +467,14 @@ protected:
class InitStmt : public Stmt {
public:
InitStmt(id_list* arg_inits) : Stmt(STMT_INIT)
explicit InitStmt(id_list* arg_inits) : Stmt(STMT_INIT)
{
inits = arg_inits;
if ( arg_inits && arg_inits->length() )
SetLocationInfo((*arg_inits)[0]->GetLocationInfo());
}
~InitStmt();
~InitStmt() override;
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
@ -501,7 +512,7 @@ class WhenStmt : public Stmt {
public:
// s2 is null if no timeout block given.
WhenStmt(Expr* cond, Stmt* s1, Stmt* s2, Expr* timeout, bool is_return);
~WhenStmt();
~WhenStmt() override;
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
int IsPure() const override;

View file

@ -132,7 +132,7 @@ protected:
*
* @param val An enum value of script type \c Analyzer::Tag.
*/
Tag(EnumVal* val);
explicit Tag(EnumVal* val);
private:
type_t type; // Main type.

View file

@ -6,6 +6,7 @@
#include "Timer.h"
#include "Desc.h"
#include "Serializer.h"
#include "broker/Manager.h"
// Names of timers in same order than in TimerType.
const char* TimerNames[] = {
@ -103,6 +104,7 @@ int TimerMgr::Advance(double arg_t, int max_expire)
last_timestamp = 0;
num_expired = 0;
last_advance = timer_mgr->Time();
broker_mgr->AdvanceTime(arg_t);
return DoAdvance(t, max_expire);
}

View file

@ -56,7 +56,7 @@ class Timer : public SerialObj, public PQ_Element {
public:
Timer(double t, TimerType arg_type) : PQ_Element(t)
{ type = (char) arg_type; }
virtual ~Timer() { }
~Timer() override { }
TimerType Type() const { return (TimerType) type; }
@ -118,7 +118,7 @@ public:
static unsigned int* CurrentTimers() { return current_timers; }
protected:
TimerMgr(const Tag& arg_tag)
explicit TimerMgr(const Tag& arg_tag)
{
t = 0.0;
num_expired = 0;
@ -141,20 +141,19 @@ protected:
class PQ_TimerMgr : public TimerMgr {
public:
PQ_TimerMgr(const Tag& arg_tag);
~PQ_TimerMgr();
explicit PQ_TimerMgr(const Tag& arg_tag);
~PQ_TimerMgr() override;
void Add(Timer* timer);
void Expire();
void Add(Timer* timer) override;
void Expire() override;
int Size() const { return q->Size(); }
int PeakSize() const { return q->PeakSize(); }
uint64 CumulativeNum() const { return q->CumulativeNum(); }
unsigned int MemoryUsage() const;
int Size() const override { return q->Size(); }
int PeakSize() const override { return q->PeakSize(); }
uint64 CumulativeNum() const override { return q->CumulativeNum(); }
protected:
int DoAdvance(double t, int max_expire);
void Remove(Timer* timer);
int DoAdvance(double t, int max_expire) override;
void Remove(Timer* timer) override;
Timer* Remove() { return (Timer*) q->Remove(); }
Timer* Top() { return (Timer*) q->Top(); }
@ -164,20 +163,20 @@ protected:
class CQ_TimerMgr : public TimerMgr {
public:
CQ_TimerMgr(const Tag& arg_tag);
~CQ_TimerMgr();
explicit CQ_TimerMgr(const Tag& arg_tag);
~CQ_TimerMgr() override;
void Add(Timer* timer);
void Expire();
void Add(Timer* timer) override;
void Expire() override;
int Size() const { return cq_size(cq); }
int PeakSize() const { return cq_max_size(cq); }
uint64 CumulativeNum() const { return cq_cumulative_num(cq); }
int Size() const override { return cq_size(cq); }
int PeakSize() const override { return cq_max_size(cq); }
uint64 CumulativeNum() const override { return cq_cumulative_num(cq); }
unsigned int MemoryUsage() const;
protected:
int DoAdvance(double t, int max_expire);
void Remove(Timer* timer);
int DoAdvance(double t, int max_expire) override;
void Remove(Timer* timer) override;
struct cq_handle *cq;
};

View file

@ -9,6 +9,10 @@ TraversalCode traverse_all(TraversalCallback* cb)
if ( ! global_scope() )
return TC_CONTINUE;
if ( ! stmts )
// May be null when parsing fails.
return TC_CONTINUE;
cb->current_scope = global_scope();
TraversalCode tc = global_scope()->Traverse(cb);

View file

@ -136,12 +136,12 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
if ( timeout_val )
{
Unref(timeout_val);
timeout_value = timeout_val->AsInterval();
Unref(timeout_val);
}
// Make sure we don't get deleted if somebody calls a method like
// Timeout() while evaluating the trigger.
// Timeout() while evaluating the trigger.
Ref(this);
if ( ! Eval() && timeout_value >= 0 )

View file

@ -21,7 +21,7 @@ public:
// right away.
Trigger(Expr* cond, Stmt* body, Stmt* timeout_stmts, Expr* timeout,
Frame* f, bool is_return, const Location* loc);
~Trigger();
~Trigger() override;
// Evaluates the condition. If true, executes the body and deletes
// the object deleted.
@ -57,16 +57,16 @@ public:
bool Disabled() const { return disabled; }
virtual void Describe(ODesc* d) const { d->Add("<trigger>"); }
void Describe(ODesc* d) const override
{ d->Add("<trigger>"); }
// Overidden from Notifier. We queue the trigger and evaluate it
// later to avoid race conditions.
virtual void Access(ID* id, const StateAccess& sa)
void Access(ID* id, const StateAccess& sa) override
{ QueueTrigger(this); }
virtual void Access(Val* val, const StateAccess& sa)
void Access(Val* val, const StateAccess& sa) override
{ QueueTrigger(this); }
virtual const char* Name() const;
const char* Name() const override;
static void QueueTrigger(Trigger* trigger);

View file

@ -22,9 +22,9 @@ RecordVal* EncapsulatingConn::GetRecordVal() const
RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal(src_addr));
id_val->Assign(1, new PortVal(ntohs(src_port), proto));
id_val->Assign(1, port_mgr->Get(ntohs(src_port), proto));
id_val->Assign(2, new AddrVal(dst_addr));
id_val->Assign(3, new PortVal(ntohs(dst_port), proto));
id_val->Assign(3, port_mgr->Get(ntohs(dst_port), proto));
rv->Assign(0, id_val);
rv->Assign(1, new EnumVal(type, BifType::Enum::Tunnel::Type));

View file

@ -545,7 +545,7 @@ bool IndexType::DoUnserialize(UnserialInfo* info)
DO_UNSERIALIZE(BroType);
UNSERIALIZE_OPTIONAL(yield_type, BroType::Unserialize(info));
indices = (TypeList*) BroType::Unserialize(info, TYPE_LIST);
indices = (TypeList*) BroType::Unserialize(info);
return indices != 0;
}
@ -865,11 +865,11 @@ bool FuncType::DoUnserialize(UnserialInfo* info)
UNSERIALIZE_OPTIONAL(yield, BroType::Unserialize(info));
args = (RecordType*) BroType::Unserialize(info, TYPE_RECORD);
args = (RecordType*) BroType::Unserialize(info);
if ( ! args )
return false;
arg_types = (TypeList*) BroType::Unserialize(info, TYPE_LIST);
arg_types = (TypeList*) BroType::Unserialize(info);
if ( ! arg_types )
return false;
@ -1185,7 +1185,14 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const
if ( d->FindType(td->type) )
d->Add("<recursion>");
else
td->DescribeReST(d);
{
if ( num_fields == 1 && streq(td->id, "va_args") &&
td->type->Tag() == TYPE_ANY )
// This was a BIF using variable argument list
d->Add("...");
else
td->DescribeReST(d);
}
if ( func_args )
continue;

View file

@ -82,8 +82,8 @@ const int MATCHES_INDEX_VECTOR = 2;
class BroType : public BroObj {
public:
BroType(TypeTag tag, bool base_type = false);
~BroType() { }
explicit BroType(TypeTag tag, bool base_type = false);
~BroType() override { }
BroType* Clone() const;
@ -249,7 +249,7 @@ public:
BroType* Ref() { ::Ref(this); return this; }
virtual void Describe(ODesc* d) const override;
void Describe(ODesc* d) const override;
virtual void DescribeReST(ODesc* d, bool roles_only = false) const;
virtual unsigned MemoryAllocation() const;
@ -265,7 +265,7 @@ public:
static std::set<BroType*> GetAliases(const std::string& type_name)
{ return BroType::type_aliases[type_name]; }
static void AddAlias(const std::string type_name, BroType* type)
static void AddAlias(const std::string &type_name, BroType* type)
{ BroType::type_aliases[type_name].insert(type); }
protected:
@ -287,13 +287,13 @@ private:
class TypeList : public BroType {
public:
TypeList(BroType* arg_pure_type = 0) : BroType(TYPE_LIST)
explicit TypeList(BroType* arg_pure_type = 0) : BroType(TYPE_LIST)
{
pure_type = arg_pure_type;
if ( pure_type )
pure_type->Ref();
}
~TypeList();
~TypeList() override;
const type_list* Types() const { return &types; }
type_list* Types() { return &types; }
@ -352,7 +352,7 @@ protected:
indices = arg_indices;
yield_type = arg_yield_type;
}
~IndexType();
~IndexType() override;
DECLARE_SERIAL(IndexType)
@ -379,7 +379,7 @@ protected:
class SetType : public TableType {
public:
SetType(TypeList* ind, ListExpr* arg_elements);
~SetType();
~SetType() override;
ListExpr* SetElements() const { return elements; }
@ -395,7 +395,7 @@ class FuncType : public BroType {
public:
FuncType(RecordType* args, BroType* yield, function_flavor f);
~FuncType();
~FuncType() override;
RecordType* Args() const { return args; }
BroType* YieldType() override;
@ -428,8 +428,8 @@ protected:
class TypeType : public BroType {
public:
TypeType(BroType* t) : BroType(TYPE_TYPE) { type = t->Ref(); }
~TypeType() { Unref(type); }
explicit TypeType(BroType* t) : BroType(TYPE_TYPE) { type = t->Ref(); }
~TypeType() override { Unref(type); }
BroType* Type() { return type; }
@ -460,9 +460,9 @@ public:
class RecordType : public BroType {
public:
RecordType(type_decl_list* types);
explicit RecordType(type_decl_list* types);
~RecordType();
~RecordType() override;
int HasField(const char* field) const override;
BroType* FieldType(const char* field) const override;
@ -512,8 +512,8 @@ protected:
class FileType : public BroType {
public:
FileType(BroType* yield_type);
~FileType();
explicit FileType(BroType* yield_type);
~FileType() override;
BroType* YieldType() override;
@ -529,8 +529,8 @@ protected:
class OpaqueType : public BroType {
public:
OpaqueType(const string& name);
virtual ~OpaqueType() { };
explicit OpaqueType(const string& name);
~OpaqueType() override { };
const string& Name() const { return name; }
@ -549,9 +549,9 @@ class EnumType : public BroType {
public:
typedef std::list<std::pair<string, bro_int_t> > enum_name_list;
EnumType(EnumType* e);
EnumType(const string& arg_name);
~EnumType();
explicit EnumType(EnumType* e);
explicit EnumType(const string& arg_name);
~EnumType() override;
// The value of this name is next internal counter value, starting
// with zero. The internal counter is incremented.
@ -598,8 +598,8 @@ protected:
class VectorType : public BroType {
public:
VectorType(BroType* t);
virtual ~VectorType();
explicit VectorType(BroType* t);
~VectorType() override;
BroType* YieldType() override;
const BroType* YieldType() const;
@ -628,6 +628,7 @@ extern OpaqueType* cardinality_type;
extern OpaqueType* topk_type;
extern OpaqueType* bloomfilter_type;
extern OpaqueType* x509_opaque_type;
extern OpaqueType* ocsp_resp_opaque_type;
// Returns the Bro basic (non-parameterized) type with the given type.
// The reference count of the type is not increased.

View file

@ -28,7 +28,7 @@ public:
* Construct a UID of a given bit-length, optionally from given values.
* @see UID::Set
*/
UID(bro_uint_t bits, const uint64* v = 0, size_t n = 0)
explicit UID(bro_uint_t bits, const uint64* v = 0, size_t n = 0)
{ Set(bits, v, n); }
/**
@ -59,9 +59,8 @@ public:
/**
* @return false if the UID instance was created via the default ctor
* and not yet initialized w/ Set().
* TODO: this would be better as an "explicit" conversion operator (C++11)
*/
operator bool() const
explicit operator bool() const
{ return initialized; }
/**

Some files were not shown because too many files have changed in this diff Show more