diff --git a/NEWS b/NEWS index 6fec41925f..ae171789fd 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,9 @@ Deprecated Functionality be used instead. There's also now a variadic template that forwards all arguments. +- The ``EventMgr::QueueEvent()`` and EventMgr::QueueEventFast()`` methods + are now deprecated, use ``EventMgr::Enqueue()`` instead. + Zeek 3.1.0 ========== diff --git a/src/Conn.cc b/src/Conn.cc index 99d1b22933..d512f32166 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -497,15 +497,15 @@ void Connection::ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* a, val_l } // "this" is passed as a cookie for the event - mgr.QueueEvent(f, std::move(vl), SOURCE_LOCAL, - a ? a->GetID() : 0, timer_mgr, this); + mgr.Enqueue(f, zeek::val_list_to_args(&vl), SOURCE_LOCAL, + a ? a->GetID() : 0, timer_mgr, this); } void Connection::ConnectionEventFast(EventHandlerPtr f, analyzer::Analyzer* a, val_list vl) { // "this" is passed as a cookie for the event - mgr.QueueEventFast(f, std::move(vl), SOURCE_LOCAL, - a ? a->GetID() : 0, timer_mgr, this); + mgr.Enqueue(f, zeek::val_list_to_args(&vl), SOURCE_LOCAL, + a ? a->GetID() : 0, timer_mgr, this); } void Connection::ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* a, val_list* vl) @@ -514,6 +514,14 @@ void Connection::ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* a, val_l delete vl; } +void Connection::EnqueueEvent(EventHandlerPtr f, zeek::Args args, + analyzer::Analyzer* a) + { + // "this" is passed as a cookie for the event + mgr.Enqueue(f, std::move(args), SOURCE_LOCAL, a ? a->GetID() : 0, + timer_mgr, this); + } + void Connection::Weird(const char* name, const char* addl) { weird = 1; diff --git a/src/Conn.h b/src/Conn.h index 1468d7041e..53f8ff74a7 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -12,6 +12,7 @@ #include "IPAddr.h" #include "UID.h" #include "WeirdState.h" +#include "ZeekArgs.h" #include "iosource/Packet.h" #include "analyzer/Tag.h" @@ -187,6 +188,7 @@ public: // If a handler exists for 'f', an event will be generated. In any case, // reference count for each element in the 'vl' list are decremented. The // arguments used for the event are whatevever is provided in 'vl'. + // TODO: deprecate void ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* analyzer, val_list vl); @@ -194,6 +196,7 @@ public: // pointer instead of by value. This function takes ownership of the // memory pointed to by 'vl' and also for decrementing the reference count // of each of its elements. + // TODO: deprecate void ConnectionEvent(EventHandlerPtr f, analyzer::Analyzer* analyzer, val_list* vl); @@ -205,9 +208,16 @@ public: // the case where there's no handlers (one usually also does that because // it would be a waste of effort to construct all the event arguments when // there's no handlers to consume them). + // TODO: deprecate void ConnectionEventFast(EventHandlerPtr f, analyzer::Analyzer* analyzer, val_list vl); + /** + * Enqueues an event associated with this connection and given analyzer. + */ + void EnqueueEvent(EventHandlerPtr f, zeek::Args args, + analyzer::Analyzer* analyzer = nullptr); + void Weird(const char* name, const char* addl = ""); bool DidWeird() const { return weird != 0; } diff --git a/src/Event.cc b/src/Event.cc index f3665cf54d..621b03c45b 100644 --- a/src/Event.cc +++ b/src/Event.cc @@ -109,38 +109,30 @@ void EventMgr::QueueEvent(const EventHandlerPtr &h, val_list vl, SourceID src, analyzer::ID aid, TimerMgr* mgr, BroObj* obj) { + auto args = zeek::val_list_to_args(&vl); + if ( h ) - QueueEvent(new Event(h, zeek::val_list_to_args(&vl), src, aid, mgr, obj)); - else - { - for ( const auto& v : vl ) - Unref(v); - } + Enqueue(h, std::move(args), src, aid, mgr, obj); } void EventMgr::QueueEvent(const EventHandlerPtr &h, val_list* vl, SourceID src, analyzer::ID aid, TimerMgr* mgr, BroObj* obj) { - QueueEvent(h, std::move(*vl), src, aid, mgr, obj); + auto args = zeek::val_list_to_args(vl); delete vl; + + if ( h ) + Enqueue(h, std::move(args), src, aid, mgr, obj); } -void EventMgr::QueueCheckedEvent(const EventHandlerPtr& h, zeek::Args vl, - SourceID src, analyzer::ID aid, - TimerMgr* mgr, BroObj* obj) +void EventMgr::Enqueue(const EventHandlerPtr& h, zeek::Args vl, + SourceID src, analyzer::ID aid, + TimerMgr* mgr, BroObj* obj) { QueueEvent(new Event(h, std::move(vl), src, aid, mgr, obj)); } -void EventMgr::QueueUncheckedEvent(const EventHandlerPtr& h, zeek::Args vl, - SourceID src, analyzer::ID aid, - TimerMgr* mgr, BroObj* obj) - { - if ( h ) - QueueEvent(new Event(h, std::move(vl), src, aid, mgr, obj)); - } - void EventMgr::QueueEvent(Event* event) { bool done = PLUGIN_HOOK_WITH_RESULT(HOOK_QUEUE_EVENT, HookQueueEvent(event), false); diff --git a/src/Event.h b/src/Event.h index 46d166c1a3..327b186f1d 100644 --- a/src/Event.h +++ b/src/Event.h @@ -8,6 +8,9 @@ #include "Flare.h" #include "ZeekArgs.h" +#include +#include + class EventMgr; class Event : public BroObj { @@ -60,7 +63,7 @@ public: // because it would be a waste of effort to construct all the event // arguments when there's no handlers to consume them). // TODO: deprecate - /* [[deprecated("Remove in v4.1. Use IntrusivePtr overload instead.")]] */ + /* [[deprecated("Remove in v4.1. Use Enqueue() instead.")]] */ void QueueEventFast(const EventHandlerPtr &h, val_list vl, SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0, TimerMgr* mgr = 0, BroObj* obj = 0); @@ -71,8 +74,7 @@ public: // checked for event handler existence, you may wish to call // QueueEventFast() instead of this function to prevent the redundant // existence check. - // TODO: deprecate - /* [[deprecated("Remove in v4.1. Use IntrusivePtr overload instead.")]] */ + [[deprecated("Remove in v4.1. Use Enqueue() instead.")]] void QueueEvent(const EventHandlerPtr &h, val_list vl, SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0, TimerMgr* mgr = 0, BroObj* obj = 0); @@ -81,32 +83,36 @@ public: // pointer instead of by value. This function takes ownership of the // memory pointed to by 'vl' as well as decrementing the reference count of // each of its elements. - // TODO: deprecate - /* [[deprecated("Remove in v4.1. Use IntrusivePtr overload instead.")]] */ + [[deprecated("Remove in v4.1. Use Enqueue() instead.")]] void QueueEvent(const EventHandlerPtr &h, val_list* vl, SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0, TimerMgr* mgr = 0, BroObj* obj = 0); /** - * Queues an event without first checking if there's an event handler - * remote consumer. If there are actually no handlers/consumers upon - * dispatching the event, nothing happens besides having wasted a bit of - * time and resources. This method is mostly useful from a performance - * standpoint: usually callers have already checked that the event will - * consumed so they don't waste time creating an argument list that will - * only be discarded, so there's no need to do the same check again when - * going to queue the event. + * Adds an event to the queue. If no handler is found for the event + * when later going to call it, nothing happens except for having + * wasted a bit of time/resources, so callers may want to first check + * if any handler/consumer exists before enqueuing an event. + * @param h reference to the event handler to later call. + * @param vl the argument list to the event handler call. + * @param src indicates the origin of the event (local versus remote). + * @param aid identifies the protocol analyzer generating the event. + * @param obj an arbitrary object to use as a "cookie" or just hold a + * reference to until dispatching the event. */ - void QueueUncheckedEvent(const EventHandlerPtr& h, zeek::Args vl, - SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0, - TimerMgr* mgr = nullptr, BroObj* obj = nullptr); + void Enqueue(const EventHandlerPtr& h, zeek::Args vl, + SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0, + TimerMgr* mgr = nullptr, BroObj* obj = nullptr); /** - * Queues an event if it has an event handler or remote consumer. + * A version of Enqueue() taking a variable number of arguments. */ - void QueueCheckedEvent(const EventHandlerPtr& h, zeek::Args vl, - SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0, - TimerMgr* mgr = nullptr, BroObj* obj = nullptr); + template + std::enable_if_t< + std::is_convertible_v< + std::tuple_element_t<0, std::tuple>, IntrusivePtr>> + Enqueue(const EventHandlerPtr& h, Args&&... args) + { return Enqueue(h, zeek::Args{std::forward(args)...}); } void Dispatch(Event* event, bool no_remote = false); diff --git a/src/Expr.cc b/src/Expr.cc index 09a0c63fc0..693ff316c2 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3897,7 +3897,8 @@ ScheduleTimer::~ScheduleTimer() void ScheduleTimer::Dispatch(double /* t */, int /* is_expire */) { - mgr.QueueUncheckedEvent(event, std::move(args), SOURCE_LOCAL, 0, tmgr); + if ( event ) + mgr.Enqueue(event, std::move(args), SOURCE_LOCAL, 0, tmgr); } ScheduleExpr::ScheduleExpr(IntrusivePtr arg_when, @@ -4443,7 +4444,10 @@ IntrusivePtr EventExpr::Eval(Frame* f) const return nullptr; auto v = eval_list(f, args.get()); - mgr.QueueUncheckedEvent(handler, std::move(*v)); + + if ( handler ) + mgr.Enqueue(handler, std::move(*v)); + return nullptr; } diff --git a/src/Sessions.cc b/src/Sessions.cc index 5eb83ffcd8..d39fa9f8e6 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -330,7 +330,8 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr } if ( mobile_ipv6_message ) - mgr.QueueEvent(mobile_ipv6_message, {ip_hdr->BuildPktHdrVal()}); + mgr.Enqueue(mobile_ipv6_message, + IntrusivePtr{AdoptRef{}, ip_hdr->BuildPktHdrVal()}); if ( ip_hdr->NextProto() != IPPROTO_NONE ) Weird("mobility_piggyback", pkt, encapsulation); diff --git a/src/Stmt.cc b/src/Stmt.cc index 2e90592dd6..1cfc0c93df 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -960,9 +960,10 @@ IntrusivePtr EventStmt::Exec(Frame* f, stmt_flow_type& flow) const { RegisterAccess(); auto args = eval_list(f, event_expr->Args()); + auto h = event_expr->Handler(); - if ( args ) - mgr.QueueUncheckedEvent(event_expr->Handler(), std::move(*args)); + if ( args && h ) + mgr.Enqueue(h, std::move(*args)); flow = FLOW_NEXT; return nullptr; diff --git a/src/file_analysis/analyzer/x509/OCSP.cc b/src/file_analysis/analyzer/x509/OCSP.cc index 30b7e4283c..801dd50f12 100644 --- a/src/file_analysis/analyzer/x509/OCSP.cc +++ b/src/file_analysis/analyzer/x509/OCSP.cc @@ -75,7 +75,7 @@ static bool OCSP_RESPID_bio(OCSP_BASICRESP* basic_resp, BIO* bio) return true; } -bool ocsp_add_cert_id(const OCSP_CERTID* cert_id, val_list* vl, BIO* bio) +static bool ocsp_add_cert_id(const OCSP_CERTID* cert_id, zeek::Args* vl, BIO* bio) { ASN1_OBJECT* hash_alg = nullptr; ASN1_OCTET_STRING* issuer_name_hash = nullptr; @@ -89,10 +89,10 @@ bool ocsp_add_cert_id(const OCSP_CERTID* cert_id, val_list* vl, BIO* bio) if ( ! res ) { reporter->Weird("OpenSSL failed to get OCSP_CERTID info"); - vl->push_back(val_mgr->GetEmptyString()); - vl->push_back(val_mgr->GetEmptyString()); - vl->push_back(val_mgr->GetEmptyString()); - vl->push_back(val_mgr->GetEmptyString()); + vl->emplace_back(AdoptRef{}, val_mgr->GetEmptyString()); + vl->emplace_back(AdoptRef{}, val_mgr->GetEmptyString()); + vl->emplace_back(AdoptRef{}, val_mgr->GetEmptyString()); + vl->emplace_back(AdoptRef{}, val_mgr->GetEmptyString()); return false; } @@ -101,22 +101,22 @@ bool ocsp_add_cert_id(const OCSP_CERTID* cert_id, val_list* vl, BIO* bio) i2a_ASN1_OBJECT(bio, hash_alg); int len = BIO_read(bio, buf, sizeof(buf)); - vl->push_back(new StringVal(len, buf)); + vl->emplace_back(make_intrusive(len, buf)); BIO_reset(bio); i2a_ASN1_STRING(bio, issuer_name_hash, V_ASN1_OCTET_STRING); len = BIO_read(bio, buf, sizeof(buf)); - vl->push_back(new StringVal(len, buf)); + vl->emplace_back(make_intrusive(len, buf)); BIO_reset(bio); i2a_ASN1_STRING(bio, issuer_key_hash, V_ASN1_OCTET_STRING); len = BIO_read(bio, buf, sizeof(buf)); - vl->push_back(new StringVal(len, buf)); + vl->emplace_back(make_intrusive(len, buf)); BIO_reset(bio); i2a_ASN1_INTEGER(bio, serial_number); len = BIO_read(bio, buf, sizeof(buf)); - vl->push_back(new StringVal(len, buf)); + vl->emplace_back(make_intrusive(len, buf)); BIO_reset(bio); return true; @@ -430,14 +430,17 @@ void file_analysis::OCSP::ParseRequest(OCSP_REQUEST* req) int req_count = OCSP_request_onereq_count(req); for ( int i=0; iGetVal()->Ref()); + zeek::Args rvl; + rvl.reserve(5); + rvl.emplace_back(NewRef{}, GetFile()->GetVal()); OCSP_ONEREQ *one_req = OCSP_request_onereq_get0(req, i); OCSP_CERTID *cert_id = OCSP_onereq_get0_id(one_req); ocsp_add_cert_id(cert_id, &rvl, bio); - mgr.QueueEvent(ocsp_request_certificate, std::move(rvl)); + + if ( ocsp_request_certificate ) + mgr.Enqueue(ocsp_request_certificate, std::move(rvl)); } BIO_free(bio); @@ -479,7 +482,8 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) //int len = BIO_read(bio, buf, sizeof(buf)); //BIO_reset(bio); - val_list vl(8); + zeek::Args vl; + vl.reserve(8); // get the basic response basic_resp = OCSP_response_get1_basic(resp); @@ -498,26 +502,26 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) } #endif - vl.push_back(GetFile()->GetVal()->Ref()); - vl.push_back(status_val); + vl.emplace_back(NewRef{}, GetFile()->GetVal()); + vl.emplace_back(AdoptRef{}, status_val); #if ( OPENSSL_VERSION_NUMBER < 0x10100000L ) || defined(LIBRESSL_VERSION_NUMBER) - vl.push_back(val_mgr->GetCount((uint64_t)ASN1_INTEGER_get(resp_data->version))); + vl.emplace_back(AdoptRef{}, val_mgr->GetCount((uint64_t)ASN1_INTEGER_get(resp_data->version))); #else - vl.push_back(parse_basic_resp_data_version(basic_resp)); + vl.emplace_back(AdoptRef{}, parse_basic_resp_data_version(basic_resp)); #endif // responderID if ( OCSP_RESPID_bio(basic_resp, bio) ) { len = BIO_read(bio, buf, sizeof(buf)); - vl.push_back(new StringVal(len, buf)); + vl.emplace_back(make_intrusive(len, buf)); BIO_reset(bio); } else { reporter->Weird("OpenSSL failed to get OCSP responder id"); - vl.push_back(val_mgr->GetEmptyString()); + vl.emplace_back(AdoptRef{}, val_mgr->GetEmptyString()); } // producedAt @@ -527,7 +531,7 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) produced_at = OCSP_resp_get0_produced_at(basic_resp); #endif - vl.push_back(new Val(GetTimeFromAsn1(produced_at, GetFile(), reporter), TYPE_TIME)); + vl.emplace_back(make_intrusive(GetTimeFromAsn1(produced_at, GetFile(), reporter), TYPE_TIME)); // responses @@ -540,8 +544,9 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) if ( !single_resp ) continue; - val_list rvl(10); - rvl.push_back(GetFile()->GetVal()->Ref()); + zeek::Args rvl; + rvl.reserve(10); + rvl.emplace_back(NewRef{}, GetFile()->GetVal()); // cert id const OCSP_CERTID* cert_id = nullptr; @@ -569,38 +574,39 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) reporter->Weird("OpenSSL failed to find status of OCSP response"); const char* cert_status_str = OCSP_cert_status_str(status); - rvl.push_back(new StringVal(strlen(cert_status_str), cert_status_str)); + rvl.emplace_back(make_intrusive(strlen(cert_status_str), cert_status_str)); // revocation time and reason if revoked if ( status == V_OCSP_CERTSTATUS_REVOKED ) { - rvl.push_back(new Val(GetTimeFromAsn1(revoke_time, GetFile(), reporter), TYPE_TIME)); + rvl.emplace_back(make_intrusive(GetTimeFromAsn1(revoke_time, GetFile(), reporter), TYPE_TIME)); if ( reason != OCSP_REVOKED_STATUS_NOSTATUS ) { const char* revoke_reason = OCSP_crl_reason_str(reason); - rvl.push_back(new StringVal(strlen(revoke_reason), revoke_reason)); + rvl.emplace_back(make_intrusive(strlen(revoke_reason), revoke_reason)); } else - rvl.push_back(new StringVal(0, "")); + rvl.emplace_back(make_intrusive(0, "")); } else { - rvl.push_back(new Val(0.0, TYPE_TIME)); - rvl.push_back(new StringVal(0, "")); + rvl.emplace_back(make_intrusive(0.0, TYPE_TIME)); + rvl.emplace_back(make_intrusive(0, "")); } if ( this_update ) - rvl.push_back(new Val(GetTimeFromAsn1(this_update, GetFile(), reporter), TYPE_TIME)); + rvl.emplace_back(make_intrusive(GetTimeFromAsn1(this_update, GetFile(), reporter), TYPE_TIME)); else - rvl.push_back(new Val(0.0, TYPE_TIME)); + rvl.emplace_back(make_intrusive(0.0, TYPE_TIME)); if ( next_update ) - rvl.push_back(new Val(GetTimeFromAsn1(next_update, GetFile(), reporter), TYPE_TIME)); + rvl.emplace_back(make_intrusive(GetTimeFromAsn1(next_update, GetFile(), reporter), TYPE_TIME)); else - rvl.push_back(new Val(0.0, TYPE_TIME)); + rvl.emplace_back(make_intrusive(0.0, TYPE_TIME)); - mgr.QueueEvent(ocsp_response_certificate, std::move(rvl)); + if ( ocsp_response_certificate ) + mgr.Enqueue(ocsp_response_certificate, std::move(rvl)); num_ext = OCSP_SINGLERESP_get_ext_count(single_resp); for ( int k = 0; k < num_ext; ++k ) @@ -616,10 +622,10 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) #if ( OPENSSL_VERSION_NUMBER < 0x10100000L ) || defined(LIBRESSL_VERSION_NUMBER) i2a_ASN1_OBJECT(bio, basic_resp->signatureAlgorithm->algorithm); len = BIO_read(bio, buf, sizeof(buf)); - vl.push_back(new StringVal(len, buf)); + vl.emplace_back(make_intrusive(len, buf)); BIO_reset(bio); #else - vl.push_back(parse_basic_resp_sig_alg(basic_resp, bio, buf, sizeof(buf))); + vl.emplace_back(AdoptRef{}, parse_basic_resp_sig_alg(basic_resp, bio, buf, sizeof(buf))); #endif //i2a_ASN1_OBJECT(bio, basic_resp->signature); @@ -628,7 +634,7 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) //BIO_reset(bio); certs_vector = new VectorVal(internal_type("x509_opaque_vector")->AsVectorType()); - vl.push_back(certs_vector); + vl.emplace_back(AdoptRef{}, certs_vector); #if ( OPENSSL_VERSION_NUMBER < 0x10100000L ) || defined(LIBRESSL_VERSION_NUMBER) certs = basic_resp->certs; @@ -650,7 +656,8 @@ void file_analysis::OCSP::ParseResponse(OCSP_RESPONSE *resp) } } - mgr.QueueEvent(ocsp_response_bytes, std::move(vl)); + if ( ocsp_response_bytes ) + mgr.Enqueue(ocsp_response_bytes, std::move(vl)); // ok, now that we are done with the actual certificate - let's parse extensions :) num_ext = OCSP_BASICRESP_get_ext_count(basic_resp); diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index 30ddee9042..cc1173d7f2 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -82,11 +82,11 @@ bool file_analysis::X509::EndOfFile() RecordVal* cert_record = ParseCertificate(cert_val, GetFile()); // and send the record on to scriptland - mgr.QueueEvent(x509_certificate, { - GetFile()->GetVal()->Ref(), - cert_val->Ref(), - cert_record->Ref(), // we Ref it here, because we want to keep a copy around for now... - }); + if ( x509_certificate ) + mgr.Enqueue(x509_certificate, + IntrusivePtr{NewRef{}, GetFile()->GetVal()}, + IntrusivePtr{NewRef{}, cert_val}, + IntrusivePtr{NewRef{}, cert_record}); // after parsing the certificate - parse the extensions... @@ -420,7 +420,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) } } - RecordVal* sanExt = new RecordVal(BifType::Record::X509::SubjectAlternativeName); + auto sanExt = make_intrusive(BifType::Record::X509::SubjectAlternativeName); if ( names != 0 ) sanExt->Assign(0, names); @@ -436,10 +436,9 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) sanExt->Assign(4, val_mgr->GetBool(otherfields)); - mgr.QueueEvent(x509_ext_subject_alternative_name, { - GetFile()->GetVal()->Ref(), - sanExt, - }); + mgr.Enqueue(x509_ext_subject_alternative_name, + IntrusivePtr{NewRef{}, GetFile()->GetVal()}, + std::move(sanExt)); GENERAL_NAMES_free(altname); } diff --git a/src/file_analysis/analyzer/x509/X509Common.cc b/src/file_analysis/analyzer/x509/X509Common.cc index a2eb1d7d9a..86ab607707 100644 --- a/src/file_analysis/analyzer/x509/X509Common.cc +++ b/src/file_analysis/analyzer/x509/X509Common.cc @@ -257,12 +257,19 @@ void file_analysis::X509Common::ParseExtension(X509_EXTENSION* ex, const EventHa } } - StringVal* ext_val = GetExtensionFromBIO(bio, GetFile()); + auto ext_val = GetExtensionFromBIO(bio, GetFile()); + + if ( ! h ) + { + // let individual analyzers parse more. + ParseExtensionsSpecific(ex, global, ext_asn, oid); + return; + } if ( ! ext_val ) - ext_val = new StringVal(0, ""); + ext_val = make_intrusive(0, ""); - RecordVal* pX509Ext = new RecordVal(BifType::Record::X509::Extension); + auto pX509Ext = make_intrusive(BifType::Record::X509::Extension); pX509Ext->Assign(0, make_intrusive(name)); if ( short_name and strlen(short_name) > 0 ) @@ -280,22 +287,18 @@ void file_analysis::X509Common::ParseExtension(X509_EXTENSION* ex, const EventHa // but I am not sure if there is a better way to do it... if ( h == ocsp_extension ) - mgr.QueueEvent(h, { - GetFile()->GetVal()->Ref(), - pX509Ext, - val_mgr->GetBool(global ? 1 : 0), - }); + mgr.Enqueue(h, IntrusivePtr{NewRef{}, GetFile()->GetVal()}, + std::move(pX509Ext), + IntrusivePtr{AdoptRef{}, val_mgr->GetBool(global)}); else - mgr.QueueEvent(h, { - GetFile()->GetVal()->Ref(), - pX509Ext, - }); + mgr.Enqueue(h, IntrusivePtr{NewRef{}, GetFile()->GetVal()}, + std::move(pX509Ext)); // let individual analyzers parse more. ParseExtensionsSpecific(ex, global, ext_asn, oid); } -StringVal* file_analysis::X509Common::GetExtensionFromBIO(BIO* bio, File* f) +IntrusivePtr file_analysis::X509Common::GetExtensionFromBIO(BIO* bio, File* f) { BIO_flush(bio); ERR_clear_error(); @@ -313,7 +316,7 @@ StringVal* file_analysis::X509Common::GetExtensionFromBIO(BIO* bio, File* f) if ( length == 0 ) { BIO_free_all(bio); - return val_mgr->GetEmptyString(); + return {AdoptRef{}, val_mgr->GetEmptyString()}; } char* buffer = (char*) malloc(length); @@ -328,7 +331,7 @@ StringVal* file_analysis::X509Common::GetExtensionFromBIO(BIO* bio, File* f) } BIO_read(bio, (void*) buffer, length); - StringVal* ext_val = new StringVal(length, buffer); + auto ext_val = make_intrusive(length, buffer); free(buffer); BIO_free_all(bio); diff --git a/src/file_analysis/analyzer/x509/X509Common.h b/src/file_analysis/analyzer/x509/X509Common.h index 2fd69c17ee..f8f934093e 100644 --- a/src/file_analysis/analyzer/x509/X509Common.h +++ b/src/file_analysis/analyzer/x509/X509Common.h @@ -13,6 +13,7 @@ class EventHandlerPtr; class Reporter; class StringVal; +template class IntrusivePtr; namespace file_analysis { @@ -34,7 +35,7 @@ public: * * @return The X509 extension value. */ - static StringVal* GetExtensionFromBIO(BIO* bio, File* f = 0); + static IntrusivePtr GetExtensionFromBIO(BIO* bio, File* f = 0); static double GetTimeFromAsn1(const ASN1_TIME* atime, File* f, Reporter* reporter); diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index 85a1af2fa8..7b4819e213 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -189,12 +189,12 @@ function x509_get_certificate_string%(cert: opaque of x509, pem: bool &default=F else i2d_X509_bio(bio, h->GetCertificate()); - StringVal* ext_val = file_analysis::X509::GetExtensionFromBIO(bio); + auto ext_val = file_analysis::X509::GetExtensionFromBIO(bio); if ( ! ext_val ) - ext_val = val_mgr->GetEmptyString(); + ext_val = {AdoptRef{}, val_mgr->GetEmptyString()}; - return ext_val; + return ext_val.release(); %} ## Verifies an OCSP reply. diff --git a/src/input/Manager.cc b/src/input/Manager.cc index f20c9a3bae..010d4f88fa 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -1837,12 +1837,14 @@ bool Manager::SendEvent(ReaderFrontend* reader, const string& name, const int nu bool convert_error = false; - val_list vl(num_vals); + zeek::Args vl; + vl.reserve(num_vals); for ( int j = 0; j < num_vals; j++) { Val* v = ValueToVal(i, vals[j], convert_error); - vl.push_back(v); + vl.emplace_back(AdoptRef{}, v); + if ( v && ! convert_error && ! same_type(type->FieldType(j), v->Type()) ) { convert_error = true; @@ -1853,21 +1855,17 @@ bool Manager::SendEvent(ReaderFrontend* reader, const string& name, const int nu delete_value_ptr_array(vals, num_vals); if ( convert_error ) - { - for ( const auto& v : vl ) - Unref(v); - return false; - } - else - mgr.QueueEvent(handler, std::move(vl), SOURCE_LOCAL); + else if ( handler ) + mgr.Enqueue(handler, std::move(vl), SOURCE_LOCAL); return true; } void Manager::SendEvent(EventHandlerPtr ev, const int numvals, ...) const { - val_list vl(numvals); + zeek::Args vl; + vl.reserve(numvals); #ifdef DEBUG DBG_LOG(DBG_INPUT, "SendEvent with %d vals", @@ -1877,16 +1875,18 @@ void Manager::SendEvent(EventHandlerPtr ev, const int numvals, ...) const va_list lP; va_start(lP, numvals); for ( int i = 0; i < numvals; i++ ) - vl.push_back( va_arg(lP, Val*) ); + vl.emplace_back(AdoptRef{}, va_arg(lP, Val*)); va_end(lP); - mgr.QueueEvent(ev, std::move(vl), SOURCE_LOCAL); + if ( ev ) + mgr.Enqueue(ev, std::move(vl), SOURCE_LOCAL); } void Manager::SendEvent(EventHandlerPtr ev, list events) const { - val_list vl(events.size()); + zeek::Args vl; + vl.reserve(events.size()); #ifdef DEBUG DBG_LOG(DBG_INPUT, "SendEvent with %" PRIuPTR " vals (list)", @@ -1894,9 +1894,10 @@ void Manager::SendEvent(EventHandlerPtr ev, list events) const #endif for ( list::iterator i = events.begin(); i != events.end(); i++ ) - vl.push_back( *i ); + vl.emplace_back(AdoptRef{}, *i); - mgr.QueueEvent(ev, std::move(vl), SOURCE_LOCAL); + if ( ev ) + mgr.Enqueue(ev, std::move(vl), SOURCE_LOCAL); } // Convert a bro list value to a bro record value.