diff --git a/src/Event.cc b/src/Event.cc index 8f9cc76315..7f61e062dd 100644 --- a/src/Event.cc +++ b/src/Event.cc @@ -2,9 +2,12 @@ #include "zeek/Event.h" +#include + #include "zeek/Desc.h" #include "zeek/EventRegistry.h" #include "zeek/Trigger.h" +#include "zeek/Type.h" #include "zeek/Val.h" #include "zeek/iosource/Manager.h" #include "zeek/plugin/Manager.h" @@ -15,19 +18,58 @@ zeek::EventMgr zeek::event_mgr; namespace zeek { +detail::EventMetadataVectorPtr detail::MakeEventMetadataVector(double t) { + auto tv = make_intrusive(t); + auto entry = detail::MetadataEntry{static_cast(detail::MetadataType::NetworkTimestamp), std::move(tv)}; + return std::make_unique(std::vector{std::move(entry)}); +} + +RecordValPtr detail::MetadataEntry::BuildVal() const { + static const auto rt = id::find_type("EventMetadata::Entry"); + auto rv = make_intrusive(rt); + const auto* desc = event_registry->LookupMetadata(id); + if ( ! desc ) { + zeek::reporter->InternalWarning("unable to find metadata descriptor for id %" PRIu64, id); + return rv; + } + + rv->Assign(0, desc->IdVal()); + rv->Assign(1, val); + + return rv; +} + Event::Event(const EventHandlerPtr& arg_handler, zeek::Args arg_args, util::detail::SourceID arg_src, analyzer::ID arg_aid, Obj* arg_obj, double arg_ts) : handler(arg_handler), args(std::move(arg_args)), src(arg_src), aid(arg_aid), - ts(arg_ts), obj(arg_obj), - next_event(nullptr) { + next_event(nullptr), + meta(detail::MakeEventMetadataVector(arg_ts)) { if ( obj ) Ref(obj); } +double Event::Time() const { + if ( ! meta ) + return 0.0; + + for ( const auto& m : *meta ) + if ( m.Id() == static_cast(detail::MetadataType::NetworkTimestamp) ) { + if ( m.Val()->GetType()->Tag() != TYPE_TIME ) { + // This should've been caught during parsing. + zeek::reporter->InternalError("event metadata timestamp has wrong type: %s", + obj_desc_short(m.Val()->GetType().get()).c_str()); + } + + return m.Val()->AsTime(); + } + + return 0.0; +} + void Event::Describe(ODesc* d) const { if ( d->IsReadable() ) d->AddSP("event"); @@ -53,7 +95,7 @@ void Event::Dispatch(bool no_remote) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" // Replace in v8.1 with handler->Call(&args). - handler->Call(&args, no_remote, ts); + handler->Call(&args, no_remote, Time()); #pragma GCC diagnostic pop } diff --git a/src/Event.h b/src/Event.h index a5229b3e10..68c235d6ee 100644 --- a/src/Event.h +++ b/src/Event.h @@ -4,6 +4,7 @@ #include #include +#include #include "zeek/ZeekArgs.h" #include "zeek/analyzer/Analyzer.h" @@ -18,6 +19,38 @@ extern double network_time; class EventMgr; +namespace detail { + +/** + * An event metadata entry as stored in Event or @ref zeek::cluster::detail::Event. + */ +class MetadataEntry { +public: + MetadataEntry(zeek_uint_t id, zeek::ValPtr val) : id(id), val(std::move(val)) {} + + zeek_uint_t Id() const { return id; } + const zeek::ValPtr& Val() const { return val; } + + /** + * @return Pointer to a script-layer ``EventMetadata::Entry`` zeek::RecordVal representing this metadata entry. + */ + RecordValPtr BuildVal() const; + +private: + zeek_uint_t id; + zeek::ValPtr val; +}; + +using EventMetadataVector = std::vector; +using EventMetadataVectorPtr = std::unique_ptr; + +/** + * @return A new event metadata vector containing network timestamp value set to \a t; + */ +EventMetadataVectorPtr MakeEventMetadataVector(double t); + +} // namespace detail + class Event final : public Obj { public: Event(const EventHandlerPtr& handler, zeek::Args args, util::detail::SourceID src = util::detail::SOURCE_LOCAL, @@ -30,7 +63,7 @@ public: analyzer::ID Analyzer() const { return aid; } EventHandlerPtr Handler() const { return handler; } const zeek::Args& Args() const { return args; } - double Time() const { return ts; } + double Time() const; void Describe(ODesc* d) const override; @@ -45,9 +78,9 @@ private: zeek::Args args; util::detail::SourceID src; analyzer::ID aid; - double ts; Obj* obj; Event* next_event; + detail::EventMetadataVectorPtr meta; }; class EventMgr final : public Obj, public iosource::IOSource {