Make paraglob serializable and copyable.

This commit is contained in:
ZekeMedley 2019-05-29 14:18:20 -07:00
parent e1520a0d67
commit 42b1f4fd2e
26 changed files with 295 additions and 225 deletions

@ -1 +1 @@
Subproject commit 757e00b6510d2b0e92510c9c26f9e3279aa442a4
Subproject commit bdff7b76349fa740f049e794d3f7881a0d65c766

View file

@ -281,4 +281,3 @@ string IPPrefix::AsString() const
return prefix.AsString() +"/" + l;
}

View file

@ -871,18 +871,18 @@ void CardinalityVal::Add(const Val* val)
}
ParaglobVal::ParaglobVal(paraglob::Paraglob* p)
ParaglobVal::ParaglobVal(std::unique_ptr<paraglob::Paraglob> p)
: OpaqueVal(paraglob_type)
{
this->internal_paraglob = p;
this->internal_paraglob = std::move(p);
}
VectorVal* ParaglobVal::get(StringVal* &pattern)
{
VectorVal* rval = new VectorVal(internal_type("string_vec")->AsVectorType());
std::string string_pattern (pattern->CheckString(), pattern->Len());
std::vector<std::string> matches = this->internal_paraglob->get(string_pattern);
std::vector<std::string> matches = this->internal_paraglob->get(string_pattern);
for (unsigned int i = 0; i < matches.size(); i++) {
rval->Assign(i, new StringVal(matches.at(i).c_str()));
}
@ -890,7 +890,45 @@ VectorVal* ParaglobVal::get(StringVal* &pattern)
return rval;
}
bool ParaglobVal::operator==(const ParaglobVal *other)
bool ParaglobVal::operator==(const ParaglobVal& other) const
{
return (*(this->internal_paraglob) == *(other->internal_paraglob));
return *(this->internal_paraglob) == *(other.internal_paraglob);
}
IMPLEMENT_SERIAL(ParaglobVal, SER_PARAGLOB_VAL)
bool ParaglobVal::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_PARAGLOB_VAL, OpaqueVal)
std::unique_ptr<std::vector<uint8_t>> iv = this->internal_paraglob->serialize();
return SERIALIZE(iv.get());
}
bool ParaglobVal::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(OpaqueVal)
std::unique_ptr<std::vector<uint8_t>> iv (new std::vector<uint8_t>);
bool success = UNSERIALIZE(iv.get());
try {
this->internal_paraglob = build_unique<paraglob::Paraglob>(std::move(iv));
} catch (const paraglob::underflow_error& e) {
reporter->Error(e.what());
return false;
} catch (const paraglob::overflow_error& e) {
reporter->Error(e.what());
return false;
}
return success;
}
Val* ParaglobVal::DoClone(CloneState* state)
{
return new ParaglobVal
(build_unique<paraglob::Paraglob>(this->internal_paraglob->serialize()));
}

View file

@ -4,6 +4,7 @@
#define OPAQUEVAL_H
#include <typeinfo>
#include <memory> // std::unique_ptr
#include "RandTest.h"
#include "Val.h"
@ -191,12 +192,24 @@ private:
class ParaglobVal : public OpaqueVal {
public:
explicit ParaglobVal(paraglob::Paraglob* p);
explicit ParaglobVal(std::unique_ptr<paraglob::Paraglob> p);
VectorVal* get(StringVal* &pattern);
bool operator==(const ParaglobVal *other);
Val* DoClone(CloneState* state) override;
bool operator==(const ParaglobVal& other) const;
protected:
ParaglobVal() : OpaqueVal(paraglob_type) {}
private:
paraglob::Paraglob* internal_paraglob;
std::unique_ptr<paraglob::Paraglob> internal_paraglob;
// Small convenience function. Does what std::make_unique does in C++14. Wont
// work on arrays.
template <typename T, typename ... Args>
std::unique_ptr<T> build_unique (Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
DECLARE_SERIAL(ParaglobVal)
};
#endif

View file

@ -53,6 +53,7 @@ SERIAL_IS(BITVECTOR, 0x1500)
SERIAL_IS(COUNTERVECTOR, 0x1600)
SERIAL_IS(BLOOMFILTER, 0x1700)
SERIAL_IS(HASHER, 0x1800)
SERIAL_IS(PARAGLOB, 0x1900)
// These are the externally visible types.
const SerialType SER_NONE = 0;
@ -116,6 +117,7 @@ SERIAL_VAL(X509_VAL, 23)
SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24)
SERIAL_VAL(COMM_DATA_VAL, 25)
SERIAL_VAL(OCSP_RESP_VAL, 26)
SERIAL_VAL(PARAGLOB_VAL, 27)
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
SERIAL_EXPR(EXPR, 1)
@ -224,6 +226,8 @@ SERIAL_HASHER(HASHER, 1)
SERIAL_HASHER(DEFAULTHASHER, 2)
SERIAL_HASHER(DOUBLEHASHER, 3)
SERIAL_CONST(PARAGLOB, 1, PARAGLOB)
SERIAL_CONST2(ID)
SERIAL_CONST2(STATE_ACCESS)
SERIAL_CONST2(CASE)

View file

@ -233,6 +233,20 @@ bool BinarySerializationFormat::Read(string* v, const char* tag)
return true;
}
bool BinarySerializationFormat::Read (vector<uint8_t>* v, const char* tag)
{
uint64_t size = 0;
if ( ! Read(&size, "vec-size"))
return false;
v->resize(size);
uint8_t* data = v->data();
if ( ! ReadData(data, size*sizeof(uint8_t)) )
return false;
return true;
}
bool BinarySerializationFormat::Read(IPAddr* addr, const char* tag)
{
int n = 0;
@ -367,6 +381,13 @@ bool BinarySerializationFormat::Write(const string& s, const char* tag)
return Write(s.data(), s.size(), tag);
}
bool BinarySerializationFormat::Write (const vector<uint8_t>* v, const char* tag)
{
uint64_t size = v->size();
bool valid = Write(size, "vec-size");
return valid && WriteData(v->data(), size);
}
bool BinarySerializationFormat::Write(const IPAddr& addr, const char* tag)
{
const uint32_t* raw;
@ -435,4 +456,3 @@ bool BinarySerializationFormat::Write(const char* buf, int len, const char* tag)
uint32 l = htonl(len);
return WriteData(&l, sizeof(l)) && WriteData(buf, len);
}

View file

@ -31,6 +31,7 @@ public:
virtual bool Read(bool* v, const char* tag) = 0;
virtual bool Read(double* d, const char* tag) = 0;
virtual bool Read(string* s, const char* tag) = 0;
virtual bool Read(vector<uint8>* v, const char* tag) = 0;
virtual bool Read(IPAddr* addr, const char* tag) = 0;
virtual bool Read(IPPrefix* prefix, const char* tag) = 0;
virtual bool Read(struct in_addr* addr, const char* tag) = 0;
@ -65,6 +66,7 @@ public:
virtual bool Write(const char* s, const char* tag) = 0;
virtual bool Write(const char* buf, int len, const char* tag) = 0;
virtual bool Write(const string& s, const char* tag) = 0;
virtual bool Write(const vector<uint8>* v, const char* tag) = 0;
virtual bool Write(const IPAddr& addr, const char* tag) = 0;
virtual bool Write(const IPPrefix& prefix, const char* tag) = 0;
virtual bool Write(const struct in_addr& addr, const char* tag) = 0;
@ -110,10 +112,12 @@ public:
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(vector<uint8>* v, 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;
@ -125,6 +129,7 @@ public:
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 vector<uint8>* v, 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;

View file

@ -69,6 +69,7 @@ public:
{ return format->Read(const_cast<char**>(str), len, tag); }
bool Read(string* s, const char* tag);
bool Read(vector<uint8>* v, const char* tag) { return format->Read(v, tag); }
bool Read(IPAddr* a, const char* tag) { return format->Read(a, tag); }
bool Read(IPPrefix* p, const char* tag) { return format->Read(p, tag); }
@ -78,6 +79,8 @@ public:
{ return format->Write(buf, len, tag); }
bool Write(const string& s, const char* tag)
{ return format->Write(s.data(), s.size(), tag); }
bool Write(const vector<uint8>* v, const char* tag)
{ return format->Write(v, tag); }
bool Write(const IPAddr& a, const char* tag) { return format->Write(a, tag); }
bool Write(const IPPrefix& p, const char* tag) { return format->Write(p, tag); }

View file

@ -802,7 +802,7 @@ function paraglob_init%(v: any%) : opaque of paraglob
if ( v->Type()->Tag() != TYPE_VECTOR ||
v->Type()->YieldType()->Tag() != TYPE_STRING )
{
builtin_error("paraglob requires a vector for initialization.");
builtin_error("paraglob requires a vector of strings for initialization.");
return nullptr;
}
@ -814,7 +814,17 @@ function paraglob_init%(v: any%) : opaque of paraglob
patterns.push_back(std::string(s->CheckString(), s->Len()));
}
return new ParaglobVal(new paraglob::Paraglob(patterns));
try
{
std::unique_ptr<paraglob::Paraglob> p (new paraglob::Paraglob(patterns));
return new ParaglobVal(std::move(p));
}
// Thrown if paraglob fails to add a pattern.
catch (const paraglob::add_error& e)
{
builtin_error(e.what());
return nullptr;
}
%}
## Gets all the strings inside the handle associated with an input pattern.
@ -835,15 +845,14 @@ function paraglob_get%(handle: opaque of paraglob, pat: string%): string_vec
## p_one: A compiled paraglob.
## p_two: A compiled paraglob.
##
## Returns: True of both paraglobs contain the same patterns, false otherwise.
## Returns: True if both paraglobs contain the same patterns, false otherwise.
##
## ## .. zeek:see::paraglob_add paraglob_get paraglob_init
function paraglob_equals%(p_one: opaque of paraglob, p_two: opaque of paraglob%)
: bool
%{
bool eq =
(static_cast<ParaglobVal*>(p_one) == static_cast<ParaglobVal*>(p_two));
return val_mgr->GetBool(eq);
return val_mgr->GetBool(
*(static_cast<ParaglobVal*>(p_one)) == *(static_cast<ParaglobVal*>(p_two)));
%}
## Returns 32-bit digest of arbitrary input values using FNV-1a hash algorithm.

View file

@ -83,17 +83,17 @@ struct scoped_reporter_location {
};
#ifdef DEBUG
static std::string RenderMessage(std::string topic, broker::data x)
static std::string RenderMessage(std::string topic, const broker::data& x)
{
return fmt("%s -> %s", broker::to_string(x).c_str(), topic.c_str());
}
static std::string RenderEvent(std::string topic, std::string name, broker::data args)
static std::string RenderEvent(std::string topic, std::string name, const broker::data& args)
{
return fmt("%s(%s) -> %s", name.c_str(), broker::to_string(args).c_str(), topic.c_str());
}
static std::string RenderMessage(broker::store::response x)
static std::string RenderMessage(const broker::store::response& x)
{
return fmt("%s [id %" PRIu64 "]", (x.answer ? broker::to_string(*x.answer).c_str() : "<no answer>"), x.id);
}
@ -358,7 +358,7 @@ bool Manager::PublishEvent(string topic, std::string name, broker::vector args)
DBG_LOG(DBG_BROKER, "Publishing event: %s",
RenderEvent(topic, name, args).c_str());
broker::zeek::Event ev(std::move(name), std::move(args));
bstate->endpoint.publish(move(topic), std::move(ev));
bstate->endpoint.publish(move(topic), ev.move_data());
++statistics.num_events_outgoing;
return true;
}
@ -420,8 +420,8 @@ bool Manager::PublishIdentifier(std::string topic, std::string id)
broker::zeek::IdentifierUpdate msg(move(id), move(*data));
DBG_LOG(DBG_BROKER, "Publishing id-update: %s",
RenderMessage(topic, msg).c_str());
bstate->endpoint.publish(move(topic), move(msg));
RenderMessage(topic, msg.as_data()).c_str());
bstate->endpoint.publish(move(topic), msg.move_data());
++statistics.num_ids_outgoing;
return true;
}
@ -471,14 +471,14 @@ bool Manager::PublishLogCreate(EnumVal* stream, EnumVal* writer,
auto bwriter_id = broker::enum_value(move(writer_id));
broker::zeek::LogCreate msg(move(bstream_id), move(bwriter_id), move(writer_info), move(fields_data));
DBG_LOG(DBG_BROKER, "Publishing log creation: %s", RenderMessage(topic, msg).c_str());
DBG_LOG(DBG_BROKER, "Publishing log creation: %s", RenderMessage(topic, msg.as_data()).c_str());
if ( peer.node != NoPeer.node )
// Direct message.
bstate->endpoint.publish(peer, move(topic), move(msg));
bstate->endpoint.publish(peer, move(topic), msg.move_data());
else
// Broadcast.
bstate->endpoint.publish(move(topic), move(msg));
bstate->endpoint.publish(move(topic), msg.move_data());
return true;
}
@ -560,7 +560,7 @@ bool Manager::PublishLogWrite(EnumVal* stream, EnumVal* writer, string path, int
broker::zeek::LogWrite msg(move(bstream_id), move(bwriter_id), move(path),
move(serial_data));
DBG_LOG(DBG_BROKER, "Buffering log record: %s", RenderMessage(topic, msg).c_str());
DBG_LOG(DBG_BROKER, "Buffering log record: %s", RenderMessage(topic, msg.as_data()).c_str());
if ( log_buffers.size() <= (unsigned int)stream_id_num )
log_buffers.resize(stream_id_num + 1);
@ -568,7 +568,7 @@ bool Manager::PublishLogWrite(EnumVal* stream, EnumVal* writer, string path, int
auto& lb = log_buffers[stream_id_num];
++lb.message_count;
auto& pending_batch = lb.msgs[topic];
pending_batch.emplace_back(std::move(msg));
pending_batch.emplace_back(msg.move_data());
if ( lb.message_count >= log_batch_size ||
(network_time - lb.last_flush >= log_batch_interval ) )
@ -594,7 +594,7 @@ size_t Manager::LogBuffer::Flush(broker::endpoint& endpoint, size_t log_batch_si
batch.reserve(log_batch_size + 1);
pending_batch.swap(batch);
broker::zeek::Batch msg(std::move(batch));
endpoint.publish(topic, move(msg));
endpoint.publish(topic, msg.move_data());
}
auto rval = message_count;
@ -805,15 +805,8 @@ bool Manager::Unsubscribe(const string& topic_prefix)
void Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except)
{
if ( bstate->status_subscriber.available() || bstate->subscriber.available() )
SetIdle(false);
read->Insert(bstate->subscriber.fd());
read->Insert(bstate->status_subscriber.fd());
write->Insert(bstate->subscriber.fd());
write->Insert(bstate->status_subscriber.fd());
except->Insert(bstate->subscriber.fd());
except->Insert(bstate->status_subscriber.fd());
for ( auto& x : data_stores )
read->Insert(x.second->proxy.mailbox().descriptor());
@ -821,19 +814,10 @@ void Manager::GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
double Manager::NextTimestamp(double* local_network_time)
{
if ( ! IsIdle() )
// We're only asked for a timestamp if either (1) a FD was ready
// or (2) we're not idle (and we go idle if when Process is no-op),
// so there's no case where returning -1 to signify a skip will help.
return timer_mgr->Time();
if ( bstate->status_subscriber.available() || bstate->subscriber.available() )
return timer_mgr->Time();
for ( auto& s : data_stores )
{
if ( ! s.second->proxy.mailbox().empty() )
return timer_mgr->Time();
}
return -1;
}
void Manager::DispatchMessage(const broker::topic& topic, broker::data msg)
@ -933,11 +917,15 @@ void Manager::Process()
for ( auto& s : data_stores )
{
while ( ! s.second->proxy.mailbox().empty() )
auto num_available = s.second->proxy.mailbox().size();
if ( num_available > 0 )
{
had_input = true;
auto response = s.second->proxy.receive();
ProcessStoreResponse(s.second, move(response));
auto responses = s.second->proxy.receive(num_available);
for ( auto& r : responses )
ProcessStoreResponse(s.second, move(r));
}
}
@ -975,7 +963,7 @@ void Manager::ProcessEvent(const broker::topic& topic, broker::zeek::Event ev)
if ( ! ev.valid() )
{
reporter->Warning("received invalid broker Event: %s",
broker::to_string(ev).data());
broker::to_string(ev.as_data()).data());
return;
}
@ -1048,7 +1036,7 @@ void Manager::ProcessEvent(const broker::topic& topic, broker::zeek::Event ev)
bool bro_broker::Manager::ProcessLogCreate(broker::zeek::LogCreate lc)
{
DBG_LOG(DBG_BROKER, "Received log-create: %s", RenderMessage(lc).c_str());
DBG_LOG(DBG_BROKER, "Received log-create: %s", RenderMessage(lc.as_data()).c_str());
if ( ! lc.valid() )
{
reporter->Warning("received invalid broker LogCreate: %s",
@ -1118,7 +1106,7 @@ bool bro_broker::Manager::ProcessLogCreate(broker::zeek::LogCreate lc)
bool bro_broker::Manager::ProcessLogWrite(broker::zeek::LogWrite lw)
{
DBG_LOG(DBG_BROKER, "Received log-write: %s", RenderMessage(lw).c_str());
DBG_LOG(DBG_BROKER, "Received log-write: %s", RenderMessage(lw.as_data()).c_str());
if ( ! lw.valid() )
{
@ -1205,7 +1193,7 @@ bool bro_broker::Manager::ProcessLogWrite(broker::zeek::LogWrite lw)
bool Manager::ProcessIdentifierUpdate(broker::zeek::IdentifierUpdate iu)
{
DBG_LOG(DBG_BROKER, "Received id-update: %s", RenderMessage(iu).c_str());
DBG_LOG(DBG_BROKER, "Received id-update: %s", RenderMessage(iu.as_data()).c_str());
if ( ! iu.valid() )
{

View file

@ -824,7 +824,6 @@ bool Manager::IsCompatibleType(BroType* t, bool atomic_only)
case TYPE_INTERVAL:
case TYPE_ENUM:
case TYPE_STRING:
case TYPE_PATTERN:
return true;
case TYPE_RECORD:
@ -2075,12 +2074,6 @@ int Manager::GetValueLength(const Value* val) const
}
break;
case TYPE_PATTERN:
{
length += strlen(val->val.pattern_text_val) + 1;
break;
}
case TYPE_TABLE:
{
for ( int i = 0; i < val->val.set_val.size; i++ )
@ -2200,14 +2193,6 @@ int Manager::CopyValue(char *data, const int startpos, const Value* val) const
return length;
}
case TYPE_PATTERN:
{
// include null-terminator
int length = strlen(val->val.pattern_text_val) + 1;
memcpy(data + startpos, val->val.pattern_text_val, length);
return length;
}
case TYPE_TABLE:
{
int length = 0;
@ -2365,13 +2350,6 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ
return subnetval;
}
case TYPE_PATTERN:
{
RE_Matcher* re = new RE_Matcher(val->val.pattern_text_val);
re->Compile();
return new PatternVal(re);
}
case TYPE_TABLE:
{
// all entries have to have the same type...
@ -2514,13 +2492,6 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) co
return subnetval;
}
case TYPE_PATTERN:
{
RE_Matcher* re = new RE_Matcher(val->val.pattern_text_val);
re->Compile();
return new PatternVal(re);
}
case TYPE_TABLE:
{
TypeList* set_index;

View file

@ -305,11 +305,15 @@ bool Ascii::DoUpdate()
// no change
return true;
// Warn again in case of trouble if the file changes. The comparison to 0
// is to suppress an extra warning that we'd otherwise get on the initial
// inode assignment.
if ( ino != 0 )
suppress_warnings = false;
mtime = sb.st_mtime;
ino = sb.st_ino;
// file changed. reread.
// fallthrough
// File changed. Fall through to re-read.
}
case MODE_MANUAL:
@ -470,8 +474,8 @@ bool Ascii::DoHeartbeat(double network_time, double current_time)
case MODE_REREAD:
case MODE_STREAM:
Update(); // call update and not DoUpdate, because update
// checks disabled.
Update(); // Call Update, not DoUpdate, because Update
// checks the "disabled" flag.
break;
default:

View file

@ -151,11 +151,15 @@ bool Config::DoUpdate()
// no change
return true;
// Warn again in case of trouble if the file changes. The comparison to 0
// is to suppress an extra warning that we'd otherwise get on the initial
// inode assignment.
if ( ino != 0 )
suppress_warnings = false;
mtime = sb.st_mtime;
ino = sb.st_ino;
// file changed. reread.
// fallthrough
// File changed. Fall through to re-read.
}
case MODE_MANUAL:
@ -309,8 +313,8 @@ bool Config::DoHeartbeat(double network_time, double current_time)
case MODE_REREAD:
case MODE_STREAM:
Update(); // call update and not DoUpdate, because update
// checks disabled.
Update(); // Call Update, not DoUpdate, because Update
// checks the "disabled" flag.
break;
default:

View file

@ -126,7 +126,6 @@ struct Value {
vec_t vector_val;
addr_t addr_val;
subnet_t subnet_val;
const char* pattern_text_val;
struct {
char* data;

View file

@ -325,28 +325,6 @@ threading::Value* Ascii::ParseValue(const string& s, const string& name, TypeTag
break;
}
case TYPE_PATTERN:
{
string cannidate = get_unescaped_string(s);
// A string is a cannidate pattern iff it begins and ends with
// a '/'. Rather or not the rest of the string is legal will
// be determined later when it is given to the RE engine.
if ( cannidate.size() >= 2 )
{
if ( cannidate.front() == cannidate.back() &&
cannidate.back() == '/' )
{
// Remove the '/'s
cannidate.erase(0, 1);
cannidate.erase(cannidate.size() - 1);
val->val.pattern_text_val = copy_string(cannidate.c_str());
break;
}
}
GetThread()->Error(GetThread()->Fmt("String '%s' contained no parseable pattern.", cannidate.c_str()));
goto parse_error;
}
case TYPE_TABLE:
case TYPE_VECTOR:
// First - common initialization

View file

@ -22,3 +22,6 @@
============ Entropy
[entropy=4.715374, chi_square=591.981818, mean=75.472727, monte_carlo_pi=4.0, serial_correlation=-0.11027]
[entropy=4.715374, chi_square=591.981818, mean=75.472727, monte_carlo_pi=4.0, serial_correlation=-0.11027]
============ Paraglob
T
T

View file

@ -0,0 +1,12 @@
receiver added peer: endpoint=127.0.0.1 msg=handshake successful
is_remote should be T, and is, T
receiver got ping number: 1
[*, *ello, hello]
is_remote should be T, and is, T
receiver got ping number: 2
[*, *ello, hello]
is_remote should be T, and is, T
receiver got ping number: 3
[*, *ello, hello]
is_remote should be T, and is, T
[num_peers=1, num_stores=0, num_pending_queries=0, num_events_incoming=4, num_events_outgoing=3, num_logs_incoming=0, num_logs_outgoing=1, num_ids_incoming=0, num_ids_outgoing=0]

View file

@ -0,0 +1,11 @@
Starting send.
[*, *ello, hello]
is_remote should be F, and is, F
sender added peer: endpoint=127.0.0.1 msg=received handshake from remote core
is_remote should be T, and is, T
sender got pong number: 1
is_remote should be T, and is, T
sender got pong number: 2
is_remote should be T, and is, T
sender got pong number: 3
sender lost peer: endpoint=127.0.0.1 msg=lost remote peer

View file

@ -1,9 +0,0 @@
error: input.log/Input::READER_ASCII: String '/cat/sss' contained no parseable pattern.
warning: input.log/Input::READER_ASCII: Could not convert line '2 /cat/sss' of input.log to Val. Ignoring line.
error: input.log/Input::READER_ASCII: String '/foo|bar' contained no parseable pattern.
warning: input.log/Input::READER_ASCII: Could not convert line '3 /foo|bar' of input.log to Val. Ignoring line.
error: input.log/Input::READER_ASCII: String 'this is not a pattern' contained no parseable pattern.
warning: input.log/Input::READER_ASCII: Could not convert line '4 this is not a pattern' of input.log to Val. Ignoring line.
error: input.log/Input::READER_ASCII: String '/5' contained no parseable pattern.
warning: input.log/Input::READER_ASCII: Could not convert line '5 /5' of input.log to Val. Ignoring line.
received termination signal

View file

@ -1,9 +0,0 @@
T
F
T
{
[2] = [p=/^?(cat)$?/],
[4] = [p=/^?(^oob)$?/],
[1] = [p=/^?(dog)$?/],
[3] = [p=/^?(foo|bar)$?/]
}

View file

@ -78,4 +78,12 @@ event zeek_init()
local handle2 = copy(handle);
print entropy_test_finish(handle);
print entropy_test_finish(handle2);
print "============ Paraglob";
local p = paraglob_init(vector("https://*.google.com/*", "*malware*", "*.gov*"));
local p2 = copy(p);
print paraglob_equals(p, p2);
# A get operation shouldn't change the paraglob
paraglob_get(p, "whitehouse.gov");
print paraglob_equals(p, p2);
}

View file

@ -0,0 +1,102 @@
# @TEST-PORT: BROKER_PORT
#
# @TEST-EXEC: btest-bg-run recv "zeek -B broker -b ../recv.zeek >recv.out"
# @TEST-EXEC: btest-bg-run send "zeek -B broker -b ../send.zeek >send.out"
#
# @TEST-EXEC: btest-bg-wait 30
# @TEST-EXEC: btest-diff recv/recv.out
# @TEST-EXEC: btest-diff send/send.out
@TEST-START-FILE send.zeek
redef exit_only_after_terminate = T;
global event_count = 0;
global p: opaque of paraglob = paraglob_init(vector("hello", "*ello", "*"));
global ping: event(msg: opaque of paraglob, c: count);
event zeek_init()
{
print "Starting send.";
print paraglob_get(p, "hello");
Broker::subscribe("bro/event/my_topic");
Broker::peer("127.0.0.1", 9999/tcp);
print "is_remote should be F, and is", is_remote_event();
}
function send_event()
{
++event_count;
local e = Broker::make_event(ping, p, event_count);
Broker::publish("bro/event/my_topic", e);
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
print fmt("sender added peer: endpoint=%s msg=%s",
endpoint$network$address, msg);
send_event();
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
print fmt("sender lost peer: endpoint=%s msg=%s",
endpoint$network$address, msg);
terminate();
}
event pong(msg: opaque of paraglob, n: count)
{
print "is_remote should be T, and is", is_remote_event();
print fmt("sender got pong number: %s", n);
send_event();
}
@TEST-END-FILE
@TEST-START-FILE recv.zeek
redef exit_only_after_terminate = T;
const events_to_recv = 3;
global handler: event(msg: string, c: count);
global auto_handler: event(msg: string, c: count);
global pong: event(msg: opaque of paraglob, c: count);
event zeek_init()
{
Broker::subscribe("bro/event/my_topic");
Broker::listen("127.0.0.1", 9999/tcp);
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
print fmt("receiver added peer: endpoint=%s msg=%s", endpoint$network$address, msg);
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
print fmt("receiver lost peer: endpoint=%s msg=%s", endpoint$network$address, msg);
}
event ping(msg: opaque of paraglob, n: count)
{
print "is_remote should be T, and is", is_remote_event();
if ( n > events_to_recv )
{
print get_broker_stats();
terminate();
return;
}
print fmt("receiver got ping number: %s", n);
print paraglob_get(msg, "hello");
local e = Broker::make_event(pong, msg, n);
Broker::publish("bro/event/my_topic", e);
}
@TEST-END-FILE

View file

@ -15,9 +15,11 @@ event zeek_init ()
# paraglob_init should not modify v1
print (v1 == vector("*", "d?g", "*og", "d?", "d[!wl]g"));
# p_eq and p1 should be the same paraglobs
print paraglob_equals(p1, p_eq);
print paraglob_equals(p_eq, p1);
print paraglob_get(p1, "dog");
print paraglob_get(p2, "once");
print paraglob_get(p3, "www.strange-malware-domain.gov");

View file

@ -1,38 +0,0 @@
# @TEST-EXEC: zeek -b %INPUT
# @TEST-EXEC: btest-diff .stderr
@TEST-START-FILE input.log
#separator \x09
#fields i p
#types count pattern
1 /d/og/
2 /cat/sss
3 /foo|bar
4 this is not a pattern
5 /5
@TEST-END-FILE
redef exit_only_after_terminate = T;
module A;
type Idx: record {
i: int;
};
type Val: record {
p: pattern;
};
event kill_me()
{
terminate();
}
global pats: table[int] of Val = table();
event zeek_init()
{
Input::add_table([$source="input.log", $name="pats", $idx=Idx, $val=Val, $destination=pats]);
schedule 10msec { kill_me() };
}

View file

@ -1,47 +0,0 @@
# @TEST-EXEC: btest-bg-run zeek zeek -b %INPUT
# @TEST-EXEC: btest-bg-wait 10
redef exit_only_after_terminate = T;
@TEST-START-FILE input.log
#separator \x09
#fields i p
#types count pattern
1 /dog/
2 /cat/
3 /foo|bar/
4 /^oob/
@TEST-END-FILE
global outfile: file;
module A;
type Idx: record {
i: int;
};
type Val: record {
p: pattern;
};
global pats: table[int] of Val = table();
event zeek_init()
{
outfile = open("../out");
# first read in the old stuff into the table...
Input::add_table([$source="../input.log", $name="pats", $idx=Idx, $val=Val, $destination=pats]);
}
event Input::end_of_data(name: string, source:string)
{
print outfile, (pats[3]$p in "foobar"); # T
print outfile, (pats[4]$p in "foobar"); # F
print outfile, (pats[3]$p == "foo"); # T
print outfile, pats;
Input::remove("pats");
close(outfile);
terminate();
}