mirror of
https://github.com/zeek/zeek.git
synced 2025-10-14 20:48:21 +00:00
Merge remote-tracking branch 'origin/master' into topic/jsiwek/gh-893-intrusive-ptr-migration
This commit is contained in:
commit
2cbf36721c
35 changed files with 594 additions and 387 deletions
|
@ -26,14 +26,6 @@ using namespace std;
|
|||
using threading::Value;
|
||||
using threading::Field;
|
||||
|
||||
static void delete_value_ptr_array(Value** vals, int num_fields)
|
||||
{
|
||||
for ( int i = 0; i < num_fields; ++i )
|
||||
delete vals[i];
|
||||
|
||||
delete [] vals;
|
||||
}
|
||||
|
||||
/**
|
||||
* InputHashes are used as Dictionaries to store the value and index hashes
|
||||
* for all lines currently stored in a table. Index hash is stored as
|
||||
|
@ -1091,7 +1083,7 @@ void Manager::SendEntry(ReaderFrontend* reader, Value* *vals)
|
|||
else
|
||||
assert(false);
|
||||
|
||||
delete_value_ptr_array(vals, readFields);
|
||||
Value::delete_value_ptr_array(vals, readFields);
|
||||
}
|
||||
|
||||
int Manager::SendEntryTable(Stream* i, const Value* const *vals)
|
||||
|
@ -1458,7 +1450,7 @@ void Manager::Put(ReaderFrontend* reader, Value* *vals)
|
|||
else
|
||||
assert(false);
|
||||
|
||||
delete_value_ptr_array(vals, readFields);
|
||||
Value::delete_value_ptr_array(vals, readFields);
|
||||
}
|
||||
|
||||
int Manager::SendEventStreamEvent(Stream* i, EnumVal* type, const Value* const *vals)
|
||||
|
@ -1762,7 +1754,7 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
|
|||
return false;
|
||||
}
|
||||
|
||||
delete_value_ptr_array(vals, readVals);
|
||||
Value::delete_value_ptr_array(vals, readVals);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -1787,68 +1779,6 @@ bool Manager::CallPred(Func* pred_func, const int numvals, ...) const
|
|||
return result;
|
||||
}
|
||||
|
||||
// Raise everything in here as warnings so it is passed to scriptland without
|
||||
// looking "fatal". In addition to these warnings, ReaderBackend will queue
|
||||
// one reporter message.
|
||||
bool Manager::SendEvent(ReaderFrontend* reader, const string& name, const int num_vals, Value* *vals) const
|
||||
{
|
||||
Stream *i = FindStream(reader);
|
||||
if ( i == nullptr )
|
||||
{
|
||||
reporter->InternalWarning("Unknown reader %s in SendEvent for event %s", reader->Name(), name.c_str());
|
||||
delete_value_ptr_array(vals, num_vals);
|
||||
return false;
|
||||
}
|
||||
|
||||
EventHandler* handler = event_registry->Lookup(name);
|
||||
if ( handler == nullptr )
|
||||
{
|
||||
Warning(i, "Event %s not found", name.c_str());
|
||||
delete_value_ptr_array(vals, num_vals);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
DBG_LOG(DBG_INPUT, "SendEvent for event %s with %d vals",
|
||||
name.c_str(), num_vals);
|
||||
#endif
|
||||
|
||||
const auto& type = handler->GetType()->Params();
|
||||
int num_event_vals = type->NumFields();
|
||||
if ( num_vals != num_event_vals )
|
||||
{
|
||||
Warning(i, "Wrong number of values for event %s", name.c_str());
|
||||
delete_value_ptr_array(vals, num_vals);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool convert_error = false;
|
||||
|
||||
zeek::Args vl;
|
||||
vl.reserve(num_vals);
|
||||
|
||||
for ( int j = 0; j < num_vals; j++)
|
||||
{
|
||||
Val* v = ValueToVal(i, vals[j], convert_error);
|
||||
vl.emplace_back(AdoptRef{}, v);
|
||||
|
||||
if ( v && ! convert_error && ! same_type(type->GetFieldType(j).get(), v->GetType().get()) )
|
||||
{
|
||||
convert_error = true;
|
||||
type->GetFieldType(j)->Error("SendEvent types do not match", v->GetType().get());
|
||||
}
|
||||
}
|
||||
|
||||
delete_value_ptr_array(vals, num_vals);
|
||||
|
||||
if ( convert_error )
|
||||
return false;
|
||||
else if ( handler )
|
||||
mgr.Enqueue(handler, std::move(vl), SOURCE_LOCAL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Manager::SendEvent(EventHandlerPtr ev, const int numvals, ...) const
|
||||
{
|
||||
zeek::Args vl;
|
||||
|
@ -2228,9 +2158,9 @@ HashKey* Manager::HashValues(const int num_elements, const Value* const *vals) c
|
|||
}
|
||||
|
||||
// convert threading value to Bro value
|
||||
// have_error is a reference to a boolean which is set to true as soon as an error occured.
|
||||
// have_error is a reference to a boolean which is set to true as soon as an error occurs.
|
||||
// When have_error is set to true at the beginning of the function, it is assumed that
|
||||
// an error already occured in the past and processing is aborted.
|
||||
// an error already occurred in the past and processing is aborted.
|
||||
Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_type, bool& have_error) const
|
||||
{
|
||||
if ( have_error )
|
||||
|
@ -2383,204 +2313,6 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Val* Manager::ValueToVal(const Stream* i, const Value* val, bool& have_error) const
|
||||
{
|
||||
if ( have_error )
|
||||
return nullptr;
|
||||
|
||||
if ( ! val->present )
|
||||
return nullptr; // unset field
|
||||
|
||||
switch ( val->type ) {
|
||||
case TYPE_BOOL:
|
||||
return val_mgr->Bool(val->val.int_val)->Ref();
|
||||
|
||||
case TYPE_INT:
|
||||
return val_mgr->Int(val->val.int_val).release();
|
||||
|
||||
case TYPE_COUNT:
|
||||
case TYPE_COUNTER:
|
||||
return val_mgr->Count(val->val.int_val).release();
|
||||
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_TIME:
|
||||
case TYPE_INTERVAL:
|
||||
return new Val(val->val.double_val, val->type);
|
||||
|
||||
case TYPE_STRING:
|
||||
{
|
||||
BroString *s = new BroString((const u_char*)val->val.string_val.data, val->val.string_val.length, true);
|
||||
return new StringVal(s);
|
||||
}
|
||||
|
||||
case TYPE_PORT:
|
||||
return val_mgr->Port(val->val.port_val.port, val->val.port_val.proto)->Ref();
|
||||
|
||||
case TYPE_ADDR:
|
||||
{
|
||||
IPAddr* addr = nullptr;
|
||||
switch ( val->val.addr_val.family ) {
|
||||
case IPv4:
|
||||
addr = new IPAddr(val->val.addr_val.in.in4);
|
||||
break;
|
||||
|
||||
case IPv6:
|
||||
addr = new IPAddr(val->val.addr_val.in.in6);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
AddrVal* addrval = new AddrVal(*addr);
|
||||
delete addr;
|
||||
return addrval;
|
||||
}
|
||||
|
||||
case TYPE_SUBNET:
|
||||
{
|
||||
IPAddr* addr = nullptr;
|
||||
switch ( val->val.subnet_val.prefix.family ) {
|
||||
case IPv4:
|
||||
addr = new IPAddr(val->val.subnet_val.prefix.in.in4);
|
||||
break;
|
||||
|
||||
case IPv6:
|
||||
addr = new IPAddr(val->val.subnet_val.prefix.in.in6);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
SubNetVal* subnetval = new SubNetVal(*addr, val->val.subnet_val.length);
|
||||
delete addr;
|
||||
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:
|
||||
{
|
||||
IntrusivePtr<TypeList> set_index;
|
||||
if ( val->val.set_val.size == 0 && val->subtype == TYPE_VOID )
|
||||
// don't know type - unspecified table.
|
||||
set_index = make_intrusive<TypeList>();
|
||||
else
|
||||
{
|
||||
// all entries have to have the same type...
|
||||
TypeTag stag = val->subtype;
|
||||
if ( stag == TYPE_VOID )
|
||||
TypeTag stag = val->val.set_val.vals[0]->type;
|
||||
|
||||
IntrusivePtr<BroType> index_type;
|
||||
|
||||
if ( stag == TYPE_ENUM )
|
||||
{
|
||||
// Enums are not a base-type, so need to look it up.
|
||||
const auto& sv = val->val.set_val.vals[0]->val.string_val;
|
||||
std::string enum_name(sv.data, sv.length);
|
||||
const auto& enum_id = global_scope()->Find(enum_name);
|
||||
|
||||
if ( ! enum_id )
|
||||
{
|
||||
Warning(i, "Value '%s' for stream '%s' is not a valid enum.",
|
||||
enum_name.data(), i->name.c_str());
|
||||
|
||||
have_error = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
index_type = enum_id->GetType();
|
||||
}
|
||||
else
|
||||
index_type = base_type(stag);
|
||||
|
||||
set_index = make_intrusive<TypeList>(index_type);
|
||||
set_index->Append(std::move(index_type));
|
||||
}
|
||||
|
||||
auto s = make_intrusive<SetType>(std::move(set_index), nullptr);
|
||||
TableVal* t = new TableVal(std::move(s));
|
||||
for ( int j = 0; j < val->val.set_val.size; j++ )
|
||||
{
|
||||
Val* assignval = ValueToVal(i, val->val.set_val.vals[j], have_error);
|
||||
|
||||
t->Assign({AdoptRef{}, assignval}, nullptr);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
case TYPE_VECTOR:
|
||||
{
|
||||
IntrusivePtr<BroType> type;
|
||||
|
||||
if ( val->val.vector_val.size == 0 && val->subtype == TYPE_VOID )
|
||||
// don't know type - unspecified table.
|
||||
type = base_type(TYPE_ANY);
|
||||
else
|
||||
{
|
||||
// all entries have to have the same type...
|
||||
if ( val->subtype == TYPE_VOID )
|
||||
type = base_type(val->val.vector_val.vals[0]->type);
|
||||
else
|
||||
type = base_type(val->subtype);
|
||||
}
|
||||
|
||||
auto vt = make_intrusive<VectorType>(std::move(type));
|
||||
auto v = make_intrusive<VectorVal>(std::move(vt));
|
||||
|
||||
for ( int j = 0; j < val->val.vector_val.size; j++ )
|
||||
v->Assign(j, ValueToVal(i, val->val.vector_val.vals[j], have_error));
|
||||
|
||||
return v.release();
|
||||
}
|
||||
|
||||
case TYPE_ENUM: {
|
||||
// Convert to string first to not have to deal with missing
|
||||
// \0's...
|
||||
string enum_string(val->val.string_val.data, val->val.string_val.length);
|
||||
|
||||
// let's try looking it up by global ID.
|
||||
auto id = lookup_ID(enum_string.c_str(), GLOBAL_MODULE_NAME);
|
||||
if ( ! id || ! id->IsEnumConst() )
|
||||
{
|
||||
Warning(i, "Value '%s' for stream '%s' is not a valid enum.",
|
||||
enum_string.c_str(), i->name.c_str());
|
||||
|
||||
have_error = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EnumType* t = id->GetType()->AsEnumType();
|
||||
int intval = t->Lookup(id->ModuleName(), id->Name());
|
||||
if ( intval < 0 )
|
||||
{
|
||||
Warning(i, "Enum value '%s' for stream '%s' not found.",
|
||||
enum_string.c_str(), i->name.c_str());
|
||||
|
||||
have_error = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto rval = t->GetVal(intval);
|
||||
return rval.release();
|
||||
}
|
||||
|
||||
default:
|
||||
reporter->InternalError("Unsupported type for input_read in stream %s", i->name.c_str());
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Manager::Stream* Manager::FindStream(const string &name) const
|
||||
{
|
||||
for ( auto s = readers.begin(); s != readers.end(); ++s )
|
||||
|
|
|
@ -118,7 +118,6 @@ protected:
|
|||
friend class PutMessage;
|
||||
friend class DeleteMessage;
|
||||
friend class ClearMessage;
|
||||
friend class SendEventMessage;
|
||||
friend class SendEntryMessage;
|
||||
friend class EndCurrentSendMessage;
|
||||
friend class ReaderClosedMessage;
|
||||
|
@ -142,11 +141,6 @@ protected:
|
|||
void SendEntry(ReaderFrontend* reader, threading::Value* *vals);
|
||||
void EndCurrentSend(ReaderFrontend* reader);
|
||||
|
||||
// Allows readers to directly send Bro events. The num_vals and vals
|
||||
// must be the same the named event expects. Takes ownership of
|
||||
// threading::Value fields.
|
||||
bool SendEvent(ReaderFrontend* reader, const std::string& name, const int num_vals, threading::Value* *vals) const;
|
||||
|
||||
// Instantiates a new ReaderBackend of the given type (note that
|
||||
// doing so creates a new thread!).
|
||||
ReaderBackend* CreateBackend(ReaderFrontend* frontend, EnumVal* tag);
|
||||
|
@ -227,14 +221,9 @@ private:
|
|||
// startpos.
|
||||
int CopyValue(char *data, const int startpos, const threading::Value* val) const;
|
||||
|
||||
// Convert Threading::Value to an internal Bro Type (works also with
|
||||
// Records).
|
||||
// Convert Threading::Value to an internal Bro Type (works with Records).
|
||||
Val* ValueToVal(const Stream* i, const threading::Value* val, BroType* request_type, bool& have_error) const;
|
||||
|
||||
// Convert Threading::Value to an internal Bro type just using the information given in the threading::Value.
|
||||
// This allows more flexibility, especially given structures in script-land that contain any types.
|
||||
Val* ValueToVal(const Stream* i, const threading::Value* val, bool& have_error) const;
|
||||
|
||||
// Convert Threading::Value to an internal Bro list type.
|
||||
Val* ValueToIndexVal(const Stream* i, int num_fields, const RecordType* type, const threading::Value* const *vals, bool& have_error) const;
|
||||
|
||||
|
|
|
@ -54,30 +54,6 @@ public:
|
|||
private:
|
||||
};
|
||||
|
||||
class SendEventMessage final : public threading::OutputMessage<ReaderFrontend> {
|
||||
public:
|
||||
SendEventMessage(ReaderFrontend* reader, const char* name, const int num_vals, Value* *val)
|
||||
: threading::OutputMessage<ReaderFrontend>("SendEvent", reader),
|
||||
name(copy_string(name)), num_vals(num_vals), val(val) {}
|
||||
|
||||
~SendEventMessage() override { delete [] name; }
|
||||
|
||||
bool Process() override
|
||||
{
|
||||
bool success = input_mgr->SendEvent(Object(), name, num_vals, val);
|
||||
|
||||
if ( ! success )
|
||||
reporter->Error("SendEvent for event %s failed", name);
|
||||
|
||||
return true; // We do not want to die if sendEvent fails because the event did not return.
|
||||
}
|
||||
|
||||
private:
|
||||
const char* name;
|
||||
const int num_vals;
|
||||
Value* *val;
|
||||
};
|
||||
|
||||
class ReaderErrorMessage final : public threading::OutputMessage<ReaderFrontend>
|
||||
{
|
||||
public:
|
||||
|
@ -229,11 +205,6 @@ void ReaderBackend::Clear()
|
|||
SendOut(new ClearMessage(frontend));
|
||||
}
|
||||
|
||||
void ReaderBackend::SendEvent(const char* name, const int num_vals, Value* *vals)
|
||||
{
|
||||
SendOut(new SendEventMessage(frontend, name, num_vals, vals));
|
||||
}
|
||||
|
||||
void ReaderBackend::EndCurrentSend()
|
||||
{
|
||||
SendOut(new EndCurrentSendMessage(frontend));
|
||||
|
|
|
@ -280,18 +280,6 @@ protected:
|
|||
*/
|
||||
virtual bool DoHeartbeat(double network_time, double current_time) = 0;
|
||||
|
||||
/**
|
||||
* Method allowing a reader to send a specified Bro event. Vals must
|
||||
* match the values expected by the bro event.
|
||||
*
|
||||
* @param name name of the bro event to send
|
||||
*
|
||||
* @param num_vals number of entries in \a vals
|
||||
*
|
||||
* @param vals the values to be given to the event
|
||||
*/
|
||||
void SendEvent(const char* name, const int num_vals, threading::Value* *vals);
|
||||
|
||||
// Content-sending-functions (simple mode). Include table-specific
|
||||
// functionality that simply is not used if we have no table.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue