mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Compare commits
9 commits
55c6e748ac
...
a27cc89335
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a27cc89335 | ||
![]() |
686f100f0d | ||
![]() |
6af1459f5e | ||
![]() |
3c16ee9667 | ||
![]() |
31d7df915e | ||
![]() |
3abc1116a1 | ||
![]() |
0700427bac | ||
![]() |
01666df3d7 | ||
![]() |
550c7eb0a7 |
18 changed files with 160 additions and 217 deletions
34
CHANGES
34
CHANGES
|
@ -1,3 +1,37 @@
|
|||
8.1.0-dev.612 | 2025-09-29 18:04:24 +0200
|
||||
|
||||
* Supervisor: Make last_signal atomic to squelch data race (Arne Welzel, Corelight)
|
||||
|
||||
When the stem process terminates and SIGCHLD is sent to the supervisor,
|
||||
the signal might be handled by the main thread or any other threads that
|
||||
aren't blocking SIGCHLD explicitly. Convert last_signal to a std::atomic<int>
|
||||
such that non-main threads can safely set last_signal without triggering
|
||||
data race as reported by TSAN. This doesn't make it less racy to work
|
||||
last_signal, but it appears we only use it for debug printing anyhow and
|
||||
another option might have been to just remove last_signal altogether.
|
||||
|
||||
Follow-up for #4849
|
||||
|
||||
8.1.0-dev.610 | 2025-09-29 08:21:01 -0700
|
||||
|
||||
* Update docs submodule [nomail] (Tim Wojtulewicz, Corelight)
|
||||
|
||||
8.1.0-dev.609 | 2025-09-29 13:08:15 +0200
|
||||
|
||||
* cluster/zeromq: Fix Cluster::subscribe() block if not initialized (Arne Welzel, Corelight)
|
||||
|
||||
If Cluster::init() hasn't been invoked yet, Cluster::subscribe() with the
|
||||
ZeroMQ backend would block because the main_inproc socket didn't
|
||||
yet have a connection from the child thread. Prevent this by connecting
|
||||
the main and child socket pair at construction time.
|
||||
|
||||
This will queue the subscriptions and start processing them once the
|
||||
child thread has started.
|
||||
|
||||
8.1.0-dev.607 | 2025-09-26 14:19:40 -0700
|
||||
|
||||
* Fixes for -O gen-standalone-C++ for tracking BiFs, lambdas, attribute types, and independent globals (Vern Paxson, Corelight)
|
||||
|
||||
8.1.0-dev.605 | 2025-09-26 11:19:17 -0700
|
||||
|
||||
* OpaqueVal, OCSP, X509: drop outdated LibreSSL guards to fix OpenBSD (Klemens Nanni)
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
8.1.0-dev.605
|
||||
8.1.0-dev.612
|
||||
|
|
2
doc
2
doc
|
@ -1 +1 @@
|
|||
Subproject commit 2731def9159247e6da8a3191783c89683363689c
|
||||
Subproject commit 8f38ae2fd563314393eb1ca58c827d26e9966520
|
|
@ -27,10 +27,6 @@
|
|||
#include "zeek/probabilistic/BloomFilter.h"
|
||||
#include "zeek/probabilistic/CardinalityCounter.h"
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
inline void* EVP_MD_CTX_md_data(const EVP_MD_CTX* ctx) { return ctx->md_data; }
|
||||
#endif
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x30000000L )
|
||||
#include <openssl/md5.h>
|
||||
#endif
|
||||
|
|
|
@ -85,6 +85,7 @@ ZeroMQBackend::ZeroMQBackend(std::unique_ptr<EventSerializer> es, std::unique_pt
|
|||
: ThreadedBackend("ZeroMQ", std::move(es), std::move(ls), std::move(ehs),
|
||||
new zeek::detail::OnLoopProcess<ThreadedBackend, QueueMessage>(this, "ZeroMQ", onloop_queue_hwm)),
|
||||
main_inproc(zmq::socket_t(ctx, zmq::socket_type::pair)),
|
||||
child_inproc(zmq::socket_t(ctx, zmq::socket_type::pair)),
|
||||
// Counters for block and drop metrics.
|
||||
total_xpub_drops(
|
||||
zeek::telemetry_mgr->CounterInstance("zeek", "cluster_zeromq_xpub_drops", {},
|
||||
|
@ -94,7 +95,13 @@ ZeroMQBackend::ZeroMQBackend(std::unique_ptr<EventSerializer> es, std::unique_pt
|
|||
"Number of received events dropped due to OnLoop queue full.")),
|
||||
total_msg_errors(
|
||||
zeek::telemetry_mgr->CounterInstance("zeek", "cluster_zeromq_msg_errors", {},
|
||||
"Number of events with the wrong number of message parts.")) {}
|
||||
"Number of events with the wrong number of message parts.")) {
|
||||
// Establish the socket connection between main thread and child thread
|
||||
// already in the constructor. This allows Subscribe() and Unsubscribe()
|
||||
// calls to be delayed until DoInit() was called.
|
||||
main_inproc.bind("inproc://inproc-bridge");
|
||||
child_inproc.connect("inproc://inproc-bridge");
|
||||
}
|
||||
|
||||
ZeroMQBackend::~ZeroMQBackend() {
|
||||
try {
|
||||
|
@ -169,10 +176,11 @@ void ZeroMQBackend::DoTerminate() {
|
|||
ctx.shutdown();
|
||||
|
||||
// Close the sockets that are used from the main thread,
|
||||
// the remaining sockets were closed by self_thread during
|
||||
// shutdown already.
|
||||
// the remaining sockets except for the child_inproc one
|
||||
// were closed by self_thread during shutdown already.
|
||||
log_push.close();
|
||||
main_inproc.close();
|
||||
child_inproc.close();
|
||||
|
||||
ZEROMQ_DEBUG("Closing ctx");
|
||||
ctx.close();
|
||||
|
@ -197,7 +205,6 @@ bool ZeroMQBackend::DoInit() {
|
|||
xpub = zmq::socket_t(ctx, zmq::socket_type::xpub);
|
||||
log_push = zmq::socket_t(ctx, zmq::socket_type::push);
|
||||
log_pull = zmq::socket_t(ctx, zmq::socket_type::pull);
|
||||
child_inproc = zmq::socket_t(ctx, zmq::socket_type::pair);
|
||||
|
||||
xpub.set(zmq::sockopt::linger, linger_ms);
|
||||
|
||||
|
@ -286,10 +293,6 @@ bool ZeroMQBackend::DoInit() {
|
|||
//
|
||||
// https://funcptr.net/2012/09/10/zeromq---edge-triggered-notification/
|
||||
|
||||
// Setup connectivity between main and child thread.
|
||||
main_inproc.bind("inproc://inproc-bridge");
|
||||
child_inproc.connect("inproc://inproc-bridge");
|
||||
|
||||
// Thread is joined in backend->DoTerminate(), backend outlives it.
|
||||
self_thread = std::thread([](auto* backend) { backend->Run(); }, this);
|
||||
|
||||
|
@ -634,7 +637,6 @@ void ZeroMQBackend::Run() {
|
|||
|
||||
// Called when Run() terminates.
|
||||
auto deferred_close = util::Deferred([this]() {
|
||||
child_inproc.close();
|
||||
xpub.close();
|
||||
xsub.close();
|
||||
log_pull.close();
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
|
||||
#include "zeek/Reporter.h"
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L ) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define EVP_MD_CTX_new EVP_MD_CTX_create
|
||||
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||
#endif
|
||||
|
||||
static_assert(ZEEK_MD5_DIGEST_LENGTH == MD5_DIGEST_LENGTH);
|
||||
|
||||
static_assert(ZEEK_SHA_DIGEST_LENGTH == SHA_DIGEST_LENGTH);
|
||||
|
|
|
@ -26,28 +26,11 @@ namespace zeek::file_analysis::detail {
|
|||
static constexpr size_t OCSP_STRING_BUF_SIZE = 2048;
|
||||
|
||||
static bool OCSP_RESPID_bio(OCSP_BASICRESP* basic_resp, BIO* bio) {
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
ASN1_OCTET_STRING* key = nullptr;
|
||||
X509_NAME* name = nullptr;
|
||||
|
||||
if ( ! basic_resp->tbsResponseData )
|
||||
return false;
|
||||
|
||||
auto resp_id = basic_resp->tbsResponseData->responderId;
|
||||
|
||||
if ( resp_id->type == V_OCSP_RESPID_NAME )
|
||||
name = resp_id->value.byName;
|
||||
else if ( resp_id->type == V_OCSP_RESPID_KEY )
|
||||
key = resp_id->value.byKey;
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
const ASN1_OCTET_STRING* key = nullptr;
|
||||
const X509_NAME* name = nullptr;
|
||||
|
||||
if ( ! OCSP_resp_get0_id(basic_resp, &key, &name) )
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if ( name )
|
||||
X509_NAME_print_ex(bio, name, 0, XN_FLAG_ONELINE);
|
||||
|
@ -150,8 +133,6 @@ bool OCSP::EndOfFile() {
|
|||
return true;
|
||||
}
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER >= 0x10100000L )
|
||||
|
||||
struct ASN1Seq {
|
||||
ASN1Seq(const unsigned char** der_in, long length) { decoded = d2i_ASN1_SEQUENCE_ANY(nullptr, der_in, length); }
|
||||
|
||||
|
@ -345,7 +326,6 @@ static uint64_t parse_request_version(OCSP_REQUEST* req) {
|
|||
OPENSSL_free(der_req_dat);
|
||||
return asn1_int;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OCSP::ParseRequest(OCSP_REQUEST* req) {
|
||||
char buf[OCSP_STRING_BUF_SIZE]; // we need a buffer for some of the openssl functions
|
||||
|
@ -353,13 +333,8 @@ void OCSP::ParseRequest(OCSP_REQUEST* req) {
|
|||
|
||||
uint64_t version = 0;
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
if ( req->tbsRequest->version )
|
||||
version = (uint64_t)ASN1_INTEGER_get(req->tbsRequest->version);
|
||||
#else
|
||||
version = parse_request_version(req);
|
||||
// TODO: try to parse out general name ?
|
||||
#endif
|
||||
|
||||
if ( ocsp_request )
|
||||
event_mgr.Enqueue(ocsp_request, GetFile()->ToVal(), val_mgr->Count(version));
|
||||
|
@ -425,20 +400,10 @@ void OCSP::ParseResponse(OCSP_RESPONSE* resp) {
|
|||
if ( ! basic_resp )
|
||||
goto clean_up;
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
resp_data = basic_resp->tbsResponseData;
|
||||
if ( ! resp_data )
|
||||
goto clean_up;
|
||||
#endif
|
||||
|
||||
vl.emplace_back(GetFile()->ToVal());
|
||||
vl.emplace_back(std::move(status_val));
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
vl.emplace_back(val_mgr->Count((uint64_t)ASN1_INTEGER_get(resp_data->version)));
|
||||
#else
|
||||
vl.emplace_back(parse_basic_resp_data_version(basic_resp));
|
||||
#endif
|
||||
|
||||
// responderID
|
||||
if ( OCSP_RESPID_bio(basic_resp, bio) ) {
|
||||
|
@ -452,11 +417,7 @@ void OCSP::ParseResponse(OCSP_RESPONSE* resp) {
|
|||
}
|
||||
|
||||
// producedAt
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
produced_at = resp_data->producedAt;
|
||||
#else
|
||||
produced_at = OCSP_resp_get0_produced_at(basic_resp);
|
||||
#endif
|
||||
|
||||
vl.emplace_back(make_intrusive<TimeVal>(GetTimeFromAsn1(produced_at, GetFile(), reporter)));
|
||||
|
||||
|
@ -477,11 +438,7 @@ void OCSP::ParseResponse(OCSP_RESPONSE* resp) {
|
|||
// cert id
|
||||
const OCSP_CERTID* cert_id = nullptr;
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
cert_id = single_resp->certId;
|
||||
#else
|
||||
cert_id = OCSP_SINGLERESP_get0_id(single_resp);
|
||||
#endif
|
||||
|
||||
ocsp_add_cert_id(cert_id, &rvl, bio);
|
||||
BIO_reset(bio);
|
||||
|
@ -550,14 +507,7 @@ void OCSP::ParseResponse(OCSP_RESPONSE* resp) {
|
|||
}
|
||||
}
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
i2a_ASN1_OBJECT(bio, basic_resp->signatureAlgorithm->algorithm);
|
||||
len = BIO_read(bio, buf, sizeof(buf));
|
||||
vl.emplace_back(make_intrusive<StringVal>(len, buf));
|
||||
BIO_reset(bio);
|
||||
#else
|
||||
vl.emplace_back(parse_basic_resp_sig_alg(basic_resp, bio, buf, sizeof(buf)));
|
||||
#endif
|
||||
|
||||
// i2a_ASN1_OBJECT(bio, basic_resp->signature);
|
||||
// len = BIO_read(bio, buf, sizeof(buf));
|
||||
|
@ -567,11 +517,7 @@ void OCSP::ParseResponse(OCSP_RESPONSE* resp) {
|
|||
certs_vector = new VectorVal(id::find_type<VectorType>("x509_opaque_vector"));
|
||||
vl.emplace_back(AdoptRef{}, certs_vector);
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
certs = basic_resp->certs;
|
||||
#else
|
||||
certs = OCSP_resp_get0_certs(basic_resp);
|
||||
#endif
|
||||
|
||||
if ( certs ) {
|
||||
int num_certs = sk_X509_num(certs);
|
||||
|
|
|
@ -161,13 +161,9 @@ RecordValPtr X509::ParseCertificate(X509Val* cert_val, file_analysis::File* f) {
|
|||
|
||||
pX509Cert->Assign(7, buf);
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
i2a_ASN1_OBJECT(bio, ssl_cert->sig_alg->algorithm);
|
||||
#else
|
||||
const ASN1_OBJECT* alg;
|
||||
X509_ALGOR_get0(&alg, nullptr, nullptr, X509_get0_tbs_sigalg(ssl_cert));
|
||||
i2a_ASN1_OBJECT(bio, alg);
|
||||
#endif
|
||||
len = BIO_gets(bio, buf, sizeof(buf));
|
||||
pX509Cert->Assign(13, make_intrusive<StringVal>(len, buf));
|
||||
BIO_free(bio);
|
||||
|
@ -349,11 +345,7 @@ void X509::ParseSAN(X509_EXTENSION* ext) {
|
|||
}
|
||||
|
||||
auto len = ASN1_STRING_length(gen->d.ia5);
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L ) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
const char* name = (const char*)ASN1_STRING_data(gen->d.ia5);
|
||||
#else
|
||||
const char* name = (const char*)ASN1_STRING_get0_data(gen->d.ia5);
|
||||
#endif
|
||||
auto bs = make_intrusive<StringVal>(len, name);
|
||||
|
||||
switch ( gen->type ) {
|
||||
|
|
|
@ -9,55 +9,6 @@
|
|||
#include "zeek/OpaqueVal.h"
|
||||
#include "zeek/file_analysis/analyzer/x509/X509Common.h"
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10002000L )
|
||||
|
||||
#define X509_get_signature_nid(x) OBJ_obj2nid((x)->sig_alg->algorithm)
|
||||
|
||||
#endif
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x1010000fL )
|
||||
|
||||
#define X509_OBJECT_new() (X509_OBJECT*)malloc(sizeof(X509_OBJECT))
|
||||
#define X509_OBJECT_free(a) free(a)
|
||||
|
||||
#define OCSP_resp_get0_certs(x) (x)->certs
|
||||
|
||||
#define EVP_PKEY_get0_DSA(p) ((p)->pkey.dsa)
|
||||
#define EVP_PKEY_get0_EC_KEY(p) ((p)->pkey.ec)
|
||||
#define EVP_PKEY_get0_RSA(p) ((p)->pkey.rsa)
|
||||
|
||||
#if ! defined(LIBRESSL_VERSION_NUMBER) || (LIBRESSL_VERSION_NUMBER < 0x2070000fL)
|
||||
|
||||
#define OCSP_SINGLERESP_get0_id(s) (s)->certId
|
||||
|
||||
static X509* X509_OBJECT_get0_X509(const X509_OBJECT* a) {
|
||||
if ( a == nullptr || a->type != X509_LU_X509 )
|
||||
return nullptr;
|
||||
return a->data.x509;
|
||||
}
|
||||
|
||||
static void DSA_get0_pqg(const DSA* d, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g) {
|
||||
if ( p != nullptr )
|
||||
*p = d->p;
|
||||
if ( q != nullptr )
|
||||
*q = d->q;
|
||||
if ( g != nullptr )
|
||||
*g = d->g;
|
||||
}
|
||||
|
||||
static void RSA_get0_key(const RSA* r, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d) {
|
||||
if ( n != nullptr )
|
||||
*n = r->n;
|
||||
if ( e != nullptr )
|
||||
*e = r->e;
|
||||
if ( d != nullptr )
|
||||
*d = r->d;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace zeek::file_analysis::detail {
|
||||
|
||||
class X509Val;
|
||||
|
|
|
@ -65,19 +65,8 @@ X509* x509_get_ocsp_signer(const STACK_OF(X509)* certs,
|
|||
const ASN1_OCTET_STRING* key = nullptr;
|
||||
const X509_NAME* name = nullptr;
|
||||
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
OCSP_RESPID* resp_id = basic_resp->tbsResponseData->responderId;
|
||||
|
||||
if ( resp_id->type == V_OCSP_RESPID_NAME )
|
||||
name = resp_id->value.byName;
|
||||
else if ( resp_id->type == V_OCSP_RESPID_KEY )
|
||||
key = resp_id->value.byKey;
|
||||
else
|
||||
return nullptr;
|
||||
#else
|
||||
if ( ! OCSP_resp_get0_id(basic_resp, &key, &name) )
|
||||
return nullptr;
|
||||
#endif
|
||||
|
||||
if ( name )
|
||||
return X509_find_by_subject(const_cast<STACK_OF(X509)*>(certs),
|
||||
|
@ -359,11 +348,7 @@ function x509_ocsp_verify%(certs: x509_opaque_vector, ocsp_reply: string, root_c
|
|||
|
||||
// Because we actually want to be able to give nice error messages that show why we were
|
||||
// not able to verify the OCSP response - do our own verification logic first.
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L )
|
||||
signer = x509_get_ocsp_signer(basic->certs, basic);
|
||||
#else
|
||||
signer = x509_get_ocsp_signer(OCSP_resp_get0_certs(basic), basic);
|
||||
#endif
|
||||
|
||||
/*
|
||||
Do this perhaps - OpenSSL also cannot do it, so I do not really feel bad about it.
|
||||
|
@ -730,12 +715,7 @@ function sct_verify%(cert: opaque of x509, logid: string, log_key: string, signa
|
|||
uint32_t cert_length;
|
||||
if ( precert )
|
||||
{
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10002000L )
|
||||
x->cert_info->enc.modified = 1;
|
||||
cert_length = i2d_X509_CINF(x->cert_info, &cert_out);
|
||||
#else
|
||||
cert_length = i2d_re_X509_tbs(x, &cert_out);
|
||||
#endif
|
||||
data.append(reinterpret_cast<const char*>(issuer_key_hash->Bytes()), issuer_key_hash->Len());
|
||||
}
|
||||
else
|
||||
|
@ -1058,11 +1038,7 @@ function x509_check_cert_hostname%(cert_opaque: opaque of x509, hostname: string
|
|||
continue;
|
||||
|
||||
std::size_t len = ASN1_STRING_length(gen->d.ia5);
|
||||
#if ( OPENSSL_VERSION_NUMBER < 0x10100000L ) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
auto* name = reinterpret_cast<const char*>(ASN1_STRING_data(gen->d.ia5));
|
||||
#else
|
||||
auto* name = reinterpret_cast<const char*>(ASN1_STRING_get0_data(gen->d.ia5));
|
||||
#endif
|
||||
std::string_view nameview {name, len};
|
||||
if ( check_hostname(hostview, nameview) )
|
||||
{
|
||||
|
|
|
@ -83,9 +83,22 @@ void CPPCompile::Compile(bool report_uncompilable) {
|
|||
accessed_globals.insert(g);
|
||||
for ( auto& ag : pf->AllGlobals() )
|
||||
all_accessed_globals.insert(ag);
|
||||
for ( auto& l : pf->Lambdas() )
|
||||
// We might not have profiled this previously if none
|
||||
// of the functions refer to the global. This can
|
||||
// happen for example for a global "const" table that's
|
||||
// made available for external lookup use.
|
||||
pfs->ProfileLambda(l);
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto& g : pfs->BiFGlobals() )
|
||||
all_accessed_globals.insert(g);
|
||||
|
||||
for ( auto& t : pfs->MainTypes() )
|
||||
if ( obj_matches_opt_files(t) == AnalyzeDecision::SHOULD )
|
||||
rep_types.insert(TypeRep(t));
|
||||
|
||||
for ( auto& l : pfs->Lambdas() )
|
||||
if ( obj_matches_opt_files(l) == AnalyzeDecision::SHOULD )
|
||||
accessed_lambdas.insert(l);
|
||||
|
|
|
@ -622,6 +622,20 @@ ProfileFuncs::ProfileFuncs(std::vector<FuncInfo>& funcs, is_compilable_pred pred
|
|||
ComputeSideEffects();
|
||||
}
|
||||
|
||||
void ProfileFuncs::ProfileLambda(const LambdaExpr* l) {
|
||||
if ( lambdas.contains(l) )
|
||||
return;
|
||||
|
||||
lambdas.insert(l);
|
||||
pending_exprs.push_back(l);
|
||||
|
||||
do
|
||||
DrainPendingExprs();
|
||||
while ( ! pending_exprs.empty() );
|
||||
|
||||
AnalyzeLambdaProfile(l);
|
||||
}
|
||||
|
||||
bool ProfileFuncs::IsTableWithDefaultAggr(const Type* t) {
|
||||
auto analy = tbl_has_aggr_default.find(t);
|
||||
if ( analy != tbl_has_aggr_default.end() )
|
||||
|
@ -848,14 +862,22 @@ void ProfileFuncs::ComputeBodyHashes(std::vector<FuncInfo>& funcs) {
|
|||
ComputeProfileHash(f.ProfilePtr());
|
||||
}
|
||||
|
||||
for ( auto& l : lambdas ) {
|
||||
for ( auto& l : lambdas )
|
||||
AnalyzeLambdaProfile(l);
|
||||
}
|
||||
|
||||
void ProfileFuncs::AnalyzeLambdaProfile(const LambdaExpr* l) {
|
||||
if ( processed_lambdas.contains(l) )
|
||||
return;
|
||||
|
||||
processed_lambdas.insert(l);
|
||||
|
||||
auto pf = ExprProf(l);
|
||||
func_profs[l->PrimaryFunc().get()] = pf;
|
||||
lambda_primaries[l->Name()] = l->PrimaryFunc().get();
|
||||
|
||||
if ( compute_func_hashes || ! pf->HasHashVal() )
|
||||
ComputeProfileHash(pf);
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileFuncs::ComputeProfileHash(std::shared_ptr<ProfileFunc> pf) {
|
||||
|
|
|
@ -366,6 +366,10 @@ public:
|
|||
ProfileFuncs(std::vector<FuncInfo>& funcs, is_compilable_pred pred, bool compute_func_hashes,
|
||||
bool full_record_hashes);
|
||||
|
||||
// Used to profile additional lambdas that (potentially) weren't part
|
||||
// of the overall function profiling.
|
||||
void ProfileLambda(const LambdaExpr* l);
|
||||
|
||||
// The following accessors provide a global profile across all of
|
||||
// the (non-skipped) functions in "funcs". See the comments for
|
||||
// the associated member variables for documentation.
|
||||
|
@ -449,6 +453,9 @@ protected:
|
|||
// Compute hashes to associate with each function
|
||||
void ComputeBodyHashes(std::vector<FuncInfo>& funcs);
|
||||
|
||||
// For a given lambda, completes analysis of its profile.
|
||||
void AnalyzeLambdaProfile(const LambdaExpr* l);
|
||||
|
||||
// Compute the hash associated with a single function profile.
|
||||
void ComputeProfileHash(std::shared_ptr<ProfileFunc> pf);
|
||||
|
||||
|
@ -540,6 +547,10 @@ protected:
|
|||
// And for lambda's.
|
||||
std::unordered_set<const LambdaExpr*> lambdas;
|
||||
|
||||
// Lambdas that we have already processed. An optimization to avoid
|
||||
// unnecessary work.
|
||||
std::unordered_set<const LambdaExpr*> processed_lambdas;
|
||||
|
||||
// Names of generated events.
|
||||
std::unordered_set<std::string> events;
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ static ForkResult fork_with_stdio_redirect(const char* where) {
|
|||
|
||||
void Supervisor::HandleChildSignal() {
|
||||
if ( last_signal >= 0 ) {
|
||||
DBG_LOG(DBG_SUPERVISOR, "Supervisor received signal %d", last_signal);
|
||||
DBG_LOG(DBG_SUPERVISOR, "Supervisor received signal %d", last_signal.load());
|
||||
last_signal = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
@ -323,7 +324,7 @@ private:
|
|||
|
||||
Config config;
|
||||
pid_t stem_pid;
|
||||
int last_signal = -1;
|
||||
std::atomic<int> last_signal = -1;
|
||||
std::unique_ptr<detail::PipePair> stem_pipe;
|
||||
detail::LineBufferedPipe stem_stdout;
|
||||
detail::LineBufferedPipe stem_stderr;
|
||||
|
|
|
@ -97,58 +97,6 @@ int perftools_leaks = 0;
|
|||
int perftools_profile = 0;
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
struct CRYPTO_dynlock_value {
|
||||
std::mutex mtx;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
std::unique_ptr<std::mutex[]> ssl_mtx_tbl;
|
||||
|
||||
void ssl_lock_fn(int mode, int n, const char*, int) {
|
||||
if ( mode & CRYPTO_LOCK )
|
||||
ssl_mtx_tbl[static_cast<size_t>(n)].lock();
|
||||
else
|
||||
ssl_mtx_tbl[static_cast<size_t>(n)].unlock();
|
||||
}
|
||||
|
||||
CRYPTO_dynlock_value* ssl_dynlock_create(const char*, int) { return new CRYPTO_dynlock_value; }
|
||||
|
||||
void ssl_dynlock_lock(int mode, CRYPTO_dynlock_value* ptr, const char*, int) {
|
||||
if ( mode & CRYPTO_LOCK )
|
||||
ptr->mtx.lock();
|
||||
else
|
||||
ptr->mtx.unlock();
|
||||
}
|
||||
|
||||
void ssl_dynlock_destroy(CRYPTO_dynlock_value* ptr, const char*, int) { delete ptr; }
|
||||
|
||||
void do_ssl_init() {
|
||||
ERR_load_crypto_strings();
|
||||
OPENSSL_add_all_algorithms_conf();
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
ssl_mtx_tbl.reset(new std::mutex[CRYPTO_num_locks()]);
|
||||
CRYPTO_set_locking_callback(ssl_lock_fn);
|
||||
CRYPTO_set_dynlock_create_callback(ssl_dynlock_create);
|
||||
CRYPTO_set_dynlock_lock_callback(ssl_dynlock_lock);
|
||||
CRYPTO_set_dynlock_destroy_callback(ssl_dynlock_destroy);
|
||||
}
|
||||
|
||||
void do_ssl_deinit() {
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
CRYPTO_set_locking_callback(nullptr);
|
||||
CRYPTO_set_dynlock_create_callback(nullptr);
|
||||
CRYPTO_set_dynlock_lock_callback(nullptr);
|
||||
CRYPTO_set_dynlock_destroy_callback(nullptr);
|
||||
ssl_mtx_tbl.reset();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#else
|
||||
namespace {
|
||||
|
||||
void do_ssl_init() { OPENSSL_init_ssl(0, nullptr); }
|
||||
|
@ -160,7 +108,6 @@ void do_ssl_deinit() {
|
|||
}
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
zeek::ValManager* zeek::val_mgr = nullptr;
|
||||
zeek::packet_analysis::Manager* zeek::packet_mgr = nullptr;
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
test(), 42
|
55
testing/btest/cluster/zeromq/subscribe-before-init.zeek
Normal file
55
testing/btest/cluster/zeromq/subscribe-before-init.zeek
Normal file
|
@ -0,0 +1,55 @@
|
|||
# @TEST-DOC: Regression test Cluster::subscribe() blocking if called in a high-priority zeek_init() handler
|
||||
#
|
||||
# @TEST-REQUIRES: have-zeromq
|
||||
#
|
||||
# @TEST-GROUP: cluster-zeromq
|
||||
#
|
||||
# @TEST-PORT: XPUB_PORT
|
||||
# @TEST-PORT: XSUB_PORT
|
||||
# @TEST-PORT: LOG_PULL_PORT
|
||||
#
|
||||
# @TEST-EXEC: cp $FILES/zeromq/cluster-layout-simple.zeek cluster-layout.zeek
|
||||
# @TEST-EXEC: cp $FILES/zeromq/test-bootstrap.zeek zeromq-test-bootstrap.zeek
|
||||
#
|
||||
# @TEST-EXEC: zeek --parse-only ./manager.zeek ./worker.zeek
|
||||
#
|
||||
# @TEST-EXEC: btest-bg-run manager "ZEEKPATH=$ZEEKPATH:.. && CLUSTER_NODE=manager zeek -b ../manager.zeek >out"
|
||||
# @TEST-EXEC: btest-bg-run worker "ZEEKPATH=$ZEEKPATH:.. && CLUSTER_NODE=worker-1 zeek -b ../worker.zeek >out"
|
||||
#
|
||||
# @TEST-EXEC: btest-bg-wait 30
|
||||
# @TEST-EXEC: btest-diff ./manager/out
|
||||
|
||||
# @TEST-START-FILE common.zeek
|
||||
@load ./zeromq-test-bootstrap
|
||||
|
||||
global test: event(c: count) &is_used;
|
||||
|
||||
# @TEST-END-FILE
|
||||
|
||||
# @TEST-START-FILE manager.zeek
|
||||
@load ./common.zeek
|
||||
|
||||
event zeek_init() &priority=1000000
|
||||
{
|
||||
Cluster::subscribe("test.early");
|
||||
}
|
||||
|
||||
event test(c: count)
|
||||
{
|
||||
print "test()", c;
|
||||
}
|
||||
|
||||
event Cluster::node_down(name: string, id: string)
|
||||
{
|
||||
terminate();
|
||||
}
|
||||
# @TEST-END-FILE
|
||||
|
||||
# @TEST-START-FILE worker.zeek
|
||||
@load ./common.zeek
|
||||
event Cluster::node_up(name: string, id: string)
|
||||
{
|
||||
Cluster::publish("test.early", test, 42);
|
||||
terminate();
|
||||
}
|
||||
# @TEST-END-FILE
|
Loading…
Add table
Add a link
Reference in a new issue