From 2d950ffde9ca4b3d97e72cc347ec37ff8a265cf6 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Mon, 19 Apr 2021 11:18:59 +0200 Subject: [PATCH 001/204] ssl: rudimentary decryption for TLS 1.2 Several limitations still apply: - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 is the only supported cipher suite - Some tests are broken due to a failing assertion regarding bytestring - No newly written tests for decryption (the patch was tested extensively for our paper) - Several small open technical questions marked with FIXME - Architecture in the ssl module might not be optimal --- scripts/policy/protocols/ssl/decryption.zeek | 106 ++++++++ scripts/policy/protocols/ssl/heartbleed.zeek | 2 +- scripts/test-all-policy.zeek | 1 + scripts/zeekygen/__load__.zeek | 1 + src/analyzer/protocol/ssl/CMakeLists.txt | 4 +- src/analyzer/protocol/ssl/DTLS.cc | 5 + src/analyzer/protocol/ssl/DTLS.h | 2 + src/analyzer/protocol/ssl/SSL.cc | 238 ++++++++++++++++++ src/analyzer/protocol/ssl/SSL.h | 14 ++ src/analyzer/protocol/ssl/events.bif | 4 +- src/analyzer/protocol/ssl/functions.bif | 22 ++ .../protocol/ssl/proc-client-hello-tls.pac | 56 +++++ .../protocol/ssl/proc-server-hello-tls.pac | 41 +++ .../protocol/ssl/ssl-dtls-analyzer.pac | 13 +- .../protocol/ssl/ssl-dtls-protocol.pac | 2 +- .../protocol/ssl/tls-handshake-analyzer.pac | 4 +- .../protocol/ssl/tls-handshake-protocol.pac | 31 +++ .../really-all-events.log | 2 + .../base/protocols/ssl/handshake-events.test | 2 +- .../scripts/base/protocols/ssl/tls13.test | 2 +- .../ssl/tls13_encrypted_handshake_events.test | 2 +- 21 files changed, 541 insertions(+), 13 deletions(-) create mode 100644 scripts/policy/protocols/ssl/decryption.zeek create mode 100644 src/analyzer/protocol/ssl/proc-client-hello-tls.pac create mode 100644 src/analyzer/protocol/ssl/proc-server-hello-tls.pac diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek new file mode 100644 index 0000000000..a3608d81e7 --- /dev/null +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -0,0 +1,106 @@ +#! Decrypt SSL/TLS payloads + +@load base/frameworks/input +@load base/frameworks/notice +@load base/protocols/conn +@load base/protocols/ssl + +module SSL; + +# Local +const input_stream_name = "input-tls-keylog-file"; + +type Idx: record { + client_random: string; +}; + +type Val: record { + secret: string; +}; + +global randoms: table[string] of string = {}; + +export { + redef record Info += { + # decryption uses client_random as identifier + client_random: string &log &optional; + }; + + const keylog_file = getenv("ZEEK_TLS_KEYLOG_FILE") &redef; + + global secrets: table[string] of string = {} &redef; + global keys: table[string] of string = {} &redef; + + event SSL::add_keys(client_random: string, val: string) + { + SSL::keys[client_random] = val; + } + + event SSL::add_secret(client_random: string, val: string) + { + SSL::secrets[client_random] = val; + } +} + +event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) + { + c$ssl$client_random = client_random; + + if ( client_random in keys ) + { + set_keys(c, keys[client_random]); + } + else if ( client_random in secrets ) + { + set_secret(c, secrets[client_random]); + } + } + +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) + { + if ( c$ssl?$client_random ) + { + if ( c$ssl$client_random in keys ) + { + set_keys(c, keys[c$ssl$client_random]); + } + else if ( c$ssl$client_random in secrets ) + { + set_secret(c, secrets[c$ssl$client_random]); + } + else + { + # FIXME: should this be moved to reporter.log or removed completely? + #print "No suitable key or secret found for random:", randoms[c$uid]; + } + } + } + +event SSL::tls_input_done() + { + continue_processing(); + } + +event Input::end_of_data(name: string, source: string) + { + if ( name == input_stream_name ) + { + event SSL::tls_input_done(); + } +} + +event zeek_init() + { + # listen for secrets + Broker::subscribe("/zeek/tls/decryption"); + + # FIXME: is such a functionality helpful? + # ingest keylog file if the environment is set + if ( keylog_file != "" ) + { + suspend_processing(); + + Input::add_table([$name=input_stream_name, $source=keylog_file, $destination=secrets, $idx=Idx, $val=Val, $want_record=F]); + Input::remove(input_stream_name); + } +} diff --git a/scripts/policy/protocols/ssl/heartbleed.zeek b/scripts/policy/protocols/ssl/heartbleed.zeek index aabafbff14..40bc800b8c 100644 --- a/scripts/policy/protocols/ssl/heartbleed.zeek +++ b/scripts/policy/protocols/ssl/heartbleed.zeek @@ -223,7 +223,7 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) } } -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) { if ( !c?$ssl ) return; diff --git a/scripts/test-all-policy.zeek b/scripts/test-all-policy.zeek index 879d1fbd9b..0b421e7c21 100644 --- a/scripts/test-all-policy.zeek +++ b/scripts/test-all-policy.zeek @@ -101,6 +101,7 @@ @load protocols/ssh/geo-data.zeek @load protocols/ssh/interesting-hostnames.zeek @load protocols/ssh/software.zeek +#@load protocols/ssl/decryption.zeek @load protocols/ssl/expiring-certs.zeek @load protocols/ssl/extract-certs-pem.zeek @load protocols/ssl/heartbleed.zeek diff --git a/scripts/zeekygen/__load__.zeek b/scripts/zeekygen/__load__.zeek index 64494037b8..524c12a609 100644 --- a/scripts/zeekygen/__load__.zeek +++ b/scripts/zeekygen/__load__.zeek @@ -1,6 +1,7 @@ @load test-all-policy.zeek # Scripts which are commented out in test-all-policy.zeek. +@load protocols/ssl/decryption.zeek @load protocols/ssl/notary.zeek @load frameworks/control/controllee.zeek @load frameworks/control/controller.zeek diff --git a/src/analyzer/protocol/ssl/CMakeLists.txt b/src/analyzer/protocol/ssl/CMakeLists.txt index 47093a978e..2a9179ce64 100644 --- a/src/analyzer/protocol/ssl/CMakeLists.txt +++ b/src/analyzer/protocol/ssl/CMakeLists.txt @@ -10,8 +10,8 @@ zeek_plugin_bif(events.bif) zeek_plugin_bif(functions.bif) zeek_plugin_bif(consts.bif) zeek_plugin_pac(tls-handshake.pac tls-handshake-protocol.pac tls-handshake-analyzer.pac ssl-defs.pac - proc-client-hello.pac - proc-server-hello.pac + proc-client-hello-tls.pac + proc-server-hello-tls.pac proc-certificate.pac tls-handshake-signed_certificate_timestamp.pac ) diff --git a/src/analyzer/protocol/ssl/DTLS.cc b/src/analyzer/protocol/ssl/DTLS.cc index 09f9e7c305..ee823148bd 100644 --- a/src/analyzer/protocol/ssl/DTLS.cc +++ b/src/analyzer/protocol/ssl/DTLS.cc @@ -72,4 +72,9 @@ void DTLS_Analyzer::SendHandshake(uint16_t raw_tls_version, uint8_t msg_type, ui } } +bool DTLS_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version) + { + // noop for now as DTLS decryption is currently not supported + } + } // namespace zeek::analyzer::dtls diff --git a/src/analyzer/protocol/ssl/DTLS.h b/src/analyzer/protocol/ssl/DTLS.h index 1554c1bb6e..7c956f0860 100644 --- a/src/analyzer/protocol/ssl/DTLS.h +++ b/src/analyzer/protocol/ssl/DTLS.h @@ -27,6 +27,8 @@ public: static analyzer::Analyzer* Instantiate(Connection* conn) { return new DTLS_Analyzer(conn); } + bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version); + protected: binpac::DTLS::SSL_Conn* interp; binpac::TLSHandshake::Handshake_Conn* handshake_interp; diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index d5088a6746..6fd2349fa1 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -1,5 +1,6 @@ #include "zeek/analyzer/protocol/ssl/SSL.h" +#include "zeek/analyzer/Manager.h" #include "zeek/analyzer/protocol/tcp/TCP_Reassembler.h" #include "zeek/Reporter.h" #include "zeek/util.h" @@ -8,6 +9,73 @@ #include "zeek/analyzer/protocol/ssl/ssl_pac.h" #include "zeek/analyzer/protocol/ssl/tls-handshake_pac.h" +#include +#include +#include + +#define MSB(a) ((a>>8)&0xff) +#define LSB(a) (a&0xff) + +static void fmt_seq(uint32_t num, u_char* buf) + { + memset(buf, 0, 8); + uint32_t netnum = htonl(num); + memcpy(buf+4, &netnum, 4); + } + +static void print_hex(std::string name, u_char* data, int len) + { + int i = 0; + printf("%s (%d): ", name.c_str(), len); + if (len > 0) + printf("0x%02x", data[0]); + + for (i = 1; i < len; i++) + { + printf(" 0x%02x", data[i]); + } + printf("\n"); + } + +static bool tls1_prf(const u_char *secret, int secret_len, const char* label, + const u_char* rnd1, int rnd1_len, const u_char* rnd2, int rnd2_len, u_char* out, size_t out_len) + { + // alloc buffers + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); + size_t seed_len = strlen(label) + rnd1_len + rnd2_len; + u_char *seed = (u_char*) malloc(seed_len); + u_char *ptr = seed; + + // seed = label + rnd1 + rnd2 + memcpy(ptr, label, strlen(label)); + ptr += strlen(label); + memcpy(ptr, rnd1, rnd1_len); + ptr += rnd1_len; + memcpy(ptr, rnd2, rnd2_len); + ptr += rnd2_len; + + if (EVP_PKEY_derive_init(pctx) <= 0) + goto abort; /* Error */ + // FIXME: sha384 should not be hardcoded + if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret, secret_len) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seed_len) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_derive(pctx, out, &out_len) <= 0) + goto abort; /* Error */ + + EVP_PKEY_CTX_free(pctx); + free(seed); + return true; + +abort: + EVP_PKEY_CTX_free(pctx); + free(seed); + return false; + } + namespace zeek::analyzer::ssl { SSL_Analyzer::SSL_Analyzer(Connection* c) @@ -16,12 +84,20 @@ SSL_Analyzer::SSL_Analyzer(Connection* c) interp = new binpac::SSL::SSL_Conn(this); handshake_interp = new binpac::TLSHandshake::Handshake_Conn(this); had_gap = false; + c_seq = 0; + s_seq = 0; + // FIXME: should this be initialized to nullptr? + secret = new zeek::StringVal(0, ""); + keys = new zeek::StringVal(0, ""); + pia = nullptr; } SSL_Analyzer::~SSL_Analyzer() { delete interp; delete handshake_interp; + delete secret; + delete keys; } void SSL_Analyzer::Done() @@ -98,4 +174,166 @@ void SSL_Analyzer::Undelivered(uint64_t seq, int len, bool orig) interp->NewGap(orig, len); } +void SSL_Analyzer::SetSecret(const u_char* data, int len) + { + // FIXME: Is this the proper way to initialize a zeek::StringVal? + // the alternative requires a cast: new zeek::StringVal(len, data) + secret = new zeek::StringVal(new zeek::String(data, len, true)); + } + +void SSL_Analyzer::SetKeys(const u_char* data, int len) + { + keys = new zeek::StringVal(new zeek::String(data, len, true)); + } + +bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version) + { + // Unsupported cipher suite. Currently supported: + // - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 == 0xC030 + auto cipher = handshake_interp->chosen_cipher(); + if ( cipher != 0xC030 ) + { + //printf("Unsupported cipher suite: %d\n", cipher); + return false; + } + + // Neither secret or key present: abort + if ( secret->Len() == 0 && keys->Len() == 0 ) + { + // FIXME: this is just for debugging + printf("Could not decrypt packet (missing key):\n"); + print_hex("->client_random:", handshake_interp->client_random().data(), handshake_interp->client_random().length()); + return false; + } + + // Secret present, but no keys derived yet: derive keys + if ( secret->Len() != 0 && keys->Len() == 0 ) + { + uint32_t ts = htonl((uint32_t) handshake_interp->gmt_unix_time()); + + u_char crand[32] = {0x00}; + u_char keybuf[72]; + + auto c_rnd = handshake_interp->client_random(); + auto s_rnd = handshake_interp->server_random(); + memcpy(crand, &(ts), 4); + memcpy(crand + 4, c_rnd.data(), c_rnd.length()); + + tls1_prf(secret->Bytes(), secret->Len(), "key expansion", s_rnd.data(), s_rnd.length(), + crand, sizeof(crand), keybuf, sizeof(keybuf)); + + // save derived keys + SetKeys(keybuf, sizeof(keybuf)); + } + + // Keys present: decrypt TLS application data + if ( keys->Len() != 0 ) + { + // session keys & AEAD data + u_char c_wk[32]; + u_char s_wk[32]; + u_char c_iv[4]; + u_char s_iv[4]; + u_char s_aead_nonce[12]; + u_char s_aead_tag[13]; + + memcpy(c_wk, keys->Bytes(), 32); + memcpy(s_wk, &(keys->Bytes()[32]), 32); + memcpy(c_iv, &(keys->Bytes()[64]), 4); + memcpy(s_iv, &(keys->Bytes()[68]), 4); + + // FIXME: should we change types here? + u_char* encrypted = (u_char*)data; + size_t encrypted_len = len; + + // FIXME: should this be moved to SSL_Conn? + if ( is_orig ) + c_seq++; + else + s_seq++; + + if ( is_orig ) + memcpy(s_aead_nonce, c_iv, 4); + else + memcpy(s_aead_nonce, s_iv, 4); + memcpy(&(s_aead_nonce[4]), encrypted, 8); + + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX_init(ctx); + EVP_CipherInit(ctx, EVP_aes_256_gcm(), NULL, NULL, 0); + + encrypted += 8; + // FIXME: is this because of nonce and aead tag? + encrypted_len -= 8; + encrypted_len -= 16; + + if (is_orig) + EVP_DecryptInit(ctx, EVP_aes_256_gcm(), c_wk, s_aead_nonce); + else + EVP_DecryptInit(ctx, EVP_aes_256_gcm(), s_wk, s_aead_nonce); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, encrypted + encrypted_len); + + if (is_orig) + fmt_seq(c_seq, s_aead_tag); + else + fmt_seq(s_seq, s_aead_tag); + + s_aead_tag[8] = content_type; + s_aead_tag[9] = MSB(raw_tls_version); + s_aead_tag[10] = LSB(raw_tls_version); + s_aead_tag[11] = MSB(encrypted_len); + s_aead_tag[12] = LSB(encrypted_len); + + u_char *decrypted = (u_char*)malloc(encrypted_len); + int decrypted_len = 0; + + EVP_DecryptUpdate(ctx, NULL, &decrypted_len, s_aead_tag, 13); + EVP_DecryptUpdate(ctx, decrypted, &decrypted_len, (const u_char*) encrypted, encrypted_len); + + int res = 0; + if ( ! (res = EVP_DecryptFinal(ctx, NULL, &res)) ) + { + printf("Decryption failed with return code %d. Invalid key?\n", res); + EVP_CIPHER_CTX_free(ctx); + free(decrypted); + return false; + } + + EVP_CIPHER_CTX_free(ctx); + ForwardDecryptedData(decrypted_len, reinterpret_cast(decrypted), is_orig); + + free(decrypted); + return true; + } + + // This is only reached if key derivation somehow failed + return false; + } + +void SSL_Analyzer::ForwardDecryptedData(int len, const u_char* data, bool is_orig) + { + if ( ! pia ) + { + pia = new analyzer::pia::PIA_TCP(Conn()); + if ( AddChildAnalyzer(pia) ) + { + pia->FirstPacket(true, nullptr); + pia->FirstPacket(false, nullptr); + } + else + reporter->FatalError("Could not initialize PIA"); + + // FIXME: Also statically add HTTP/H2 at the moment. + // We should move this bit to scriptland + auto http = analyzer_mgr->InstantiateAnalyzer("HTTP", Conn()); + if ( http ) + AddChildAnalyzer(http); + auto http2 = analyzer_mgr->InstantiateAnalyzer("HTTP2", Conn()); + if ( http2 ) + AddChildAnalyzer(http2); + } + + ForwardStream(len, data, is_orig); + } + } // namespace zeek::analyzer::ssl diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index 12dd2ce57c..4eac7e77a6 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -1,5 +1,6 @@ #pragma once +#include "zeek/analyzer/protocol/pia/PIA.h" #include "zeek/analyzer/protocol/tcp/TCP.h" #include "zeek/analyzer/protocol/ssl/events.bif.h" @@ -33,11 +34,24 @@ public: static analyzer::Analyzer* Instantiate(Connection* conn) { return new SSL_Analyzer(conn); } + // Key material for decryption + void SetSecret(const u_char* data, int len); + void SetKeys(const u_char* data, int len); + + bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version); + void ForwardDecryptedData(int len, const u_char* data, bool is_orig); + protected: binpac::SSL::SSL_Conn* interp; binpac::TLSHandshake::Handshake_Conn* handshake_interp; bool had_gap; + // FIXME: should this be moved into the connection? + int c_seq; + int s_seq; + zeek::StringVal *secret; + zeek::StringVal *keys; + zeek::analyzer::pia::PIA_TCP *pia; }; } // namespace zeek::analyzer::ssl diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 25bc34398b..9192babfdf 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -558,9 +558,11 @@ event ssl_plaintext_data%(c: connection, is_orig: bool, record_version: count, c ## ## length: length of the entire message. ## +## payload: encrypted payload of the SSL/TLS message +## ## .. zeek:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello ## ssl_alert ssl_heartbeat ssl_probable_encrypted_handshake_message -event ssl_encrypted_data%(c: connection, is_orig: bool, record_version: count, content_type: count, length: count%); +event ssl_encrypted_data%(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string%); ## This event is generated for application data records of TLS 1.3 connections of which ## we suspect that they contain handshake messages. diff --git a/src/analyzer/protocol/ssl/functions.bif b/src/analyzer/protocol/ssl/functions.bif index 2d72a4a741..b04bf19b3f 100644 --- a/src/analyzer/protocol/ssl/functions.bif +++ b/src/analyzer/protocol/ssl/functions.bif @@ -16,3 +16,25 @@ function set_ssl_established%(c: connection%): any static_cast(sa)->StartEncryption(); return nullptr; %} + +function set_secret%(c: connection, secret: string%): bool + %{ + analyzer::Analyzer* sa = c->FindAnalyzer("SSL"); + if ( sa ) + { + static_cast(sa)->SetSecret(secret->Bytes(), secret->Len()); + return zeek::val_mgr->True(); + } + return zeek::val_mgr->False(); + %} + +function set_keys%(c: connection, keys: string%): bool + %{ + analyzer::Analyzer* sa = c->FindAnalyzer("SSL"); + if ( sa ) + { + static_cast(sa)->SetKeys(keys->Bytes(), keys->Len()); + return zeek::val_mgr->True(); + } + return zeek::val_mgr->False(); + %} diff --git a/src/analyzer/protocol/ssl/proc-client-hello-tls.pac b/src/analyzer/protocol/ssl/proc-client-hello-tls.pac new file mode 100644 index 0000000000..a06be74e36 --- /dev/null +++ b/src/analyzer/protocol/ssl/proc-client-hello-tls.pac @@ -0,0 +1,56 @@ + function proc_client_hello( + version : uint16, ts : double, + client_random : bytestring, + session_id : uint8[], + cipher_suites16 : uint16[], + cipher_suites24 : uint24[], + compression_methods: uint8[]) : bool + %{ + if ( ! version_ok(version) ) + { + zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); + zeek_analyzer()->SetSkip(true); + } + else + zeek_analyzer()->ProtocolConfirmation(); + + if ( ssl_client_hello ) + { + vector cipher_suites; + + if ( cipher_suites16 ) + std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(cipher_suites)); + else + std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(cipher_suites), to_int()); + + auto cipher_vec = zeek::make_intrusive(zeek::id::index_vec); + + for ( unsigned int i = 0; i < cipher_suites.size(); ++i ) + { + auto ciph = zeek::val_mgr->Count(cipher_suites[i]); + cipher_vec->Assign(i, ciph); + } + + auto comp_vec = zeek::make_intrusive(zeek::id::index_vec); + + if ( compression_methods ) + { + for ( unsigned int i = 0; i < compression_methods->size(); ++i ) + { + auto comp = zeek::val_mgr->Count((*compression_methods)[i]); + comp_vec->Assign(i, comp); + } + } + + set_client_random(client_random); + set_gmt_unix_time(ts); + zeek::BifEvent::enqueue_ssl_client_hello(zeek_analyzer(), zeek_analyzer()->Conn(), + version, record_version(), ts, + zeek::make_intrusive(client_random.length(), + (const char*) client_random.data()), + {zeek::AdoptRef{}, to_string_val(session_id)}, + std::move(cipher_vec), std::move(comp_vec)); + } + + return true; + %} diff --git a/src/analyzer/protocol/ssl/proc-server-hello-tls.pac b/src/analyzer/protocol/ssl/proc-server-hello-tls.pac new file mode 100644 index 0000000000..456cc9bcd0 --- /dev/null +++ b/src/analyzer/protocol/ssl/proc-server-hello-tls.pac @@ -0,0 +1,41 @@ + function proc_server_hello( + version : uint16, v2 : bool, + server_random : bytestring, + session_id : uint8[], + cipher_suites16 : uint16[], + cipher_suites24 : uint24[], + comp_method : uint8) : bool + %{ + if ( ! version_ok(version) ) + { + zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); + zeek_analyzer()->SetSkip(true); + } + + if ( ssl_server_hello ) + { + vector* ciphers = new vector(); + + if ( cipher_suites16 ) + std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*ciphers)); + else + std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*ciphers), to_int()); + + uint32 ts = 0; + if ( v2 == 0 && server_random.length() >= 4 ) + ts = ntohl(*((uint32*)server_random.data())); + + set_server_random(server_random); + zeek::BifEvent::enqueue_ssl_server_hello(zeek_analyzer(), + zeek_analyzer()->Conn(), + version, record_version(), ts, + zeek::make_intrusive(server_random.length(), + (const char*) server_random.data()), + {zeek::AdoptRef{}, to_string_val(session_id)}, + ciphers->size()==0 ? 0 : ciphers->at(0), comp_method); + + delete ciphers; + } + + return true; + %} diff --git a/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac b/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac index f086fae609..8cb076ad6b 100644 --- a/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac @@ -43,7 +43,7 @@ refine connection SSL_Conn += { return true; %} - function proc_ciphertext_record(rec : SSLRecord) : bool + function proc_ciphertext_record(rec : SSLRecord, cont: bytestring) : bool %{ if ( established_ == false && determine_tls13() == 1 ) { @@ -62,8 +62,15 @@ refine connection SSL_Conn += { } if ( ssl_encrypted_data ) + { zeek::BifEvent::enqueue_ssl_encrypted_data(zeek_analyzer(), - zeek_analyzer()->Conn(), ${rec.is_orig}, ${rec.raw_tls_version}, ${rec.content_type}, ${rec.length}); + zeek_analyzer()->Conn(), ${rec.is_orig}, ${rec.raw_tls_version}, ${rec.content_type}, ${rec.length}, + zeek::make_intrusive(cont.length(), (const char*) cont.data())); + if (rec->content_type() == APPLICATION_DATA) + { + zeek_analyzer()->TryDecryptApplicationData(cont.length(), cont.data(), rec->is_orig(), rec->content_type(), rec->raw_tls_version()); + } + } return true; %} @@ -123,7 +130,7 @@ refine typeattr UnknownRecord += &let { }; refine typeattr CiphertextRecord += &let { - proc : bool = $context.connection.proc_ciphertext_record(rec); + proc : bool = $context.connection.proc_ciphertext_record(rec, cont); } refine typeattr PlaintextRecord += &let { diff --git a/src/analyzer/protocol/ssl/ssl-dtls-protocol.pac b/src/analyzer/protocol/ssl/ssl-dtls-protocol.pac index ad2b869ae8..156c1bf6f4 100644 --- a/src/analyzer/protocol/ssl/ssl-dtls-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-dtls-protocol.pac @@ -96,7 +96,7 @@ type UnknownRecord(rec: SSLRecord) = record { }; type CiphertextRecord(rec: SSLRecord) = record { - cont : bytestring &restofdata &transient; + cont : bytestring &restofdata; }; ###################################################################### diff --git a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac index 961eb8eaf3..9559ba0151 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac @@ -25,8 +25,8 @@ refine connection Handshake_Conn += { - %include proc-client-hello.pac - %include proc-server-hello.pac + %include proc-client-hello-tls.pac + %include proc-server-hello-tls.pac %include proc-certificate.pac function proc_session_ticket_handshake(rec: SessionTicketHandshake, is_orig: bool): bool diff --git a/src/analyzer/protocol/ssl/tls-handshake-protocol.pac b/src/analyzer/protocol/ssl/tls-handshake-protocol.pac index e37a0c512a..628dd3da48 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-protocol.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-protocol.pac @@ -943,6 +943,9 @@ refine connection Handshake_Conn += { uint32 chosen_cipher_; uint16 chosen_version_; uint16 record_version_; + bytestring client_random_; + bytestring server_random_; + uint32 gmt_unix_time_; %} %init{ @@ -950,6 +953,10 @@ refine connection Handshake_Conn += { chosen_version_ = UNKNOWN_VERSION; record_version_ = 0; + // FIXME: How should bytestrings be initialized? + // client_random_ = ?? + // server_random_ = ?? + gmt_unix_time_ = 0; %} function chosen_cipher() : int %{ return chosen_cipher_; %} @@ -983,5 +990,29 @@ refine connection Handshake_Conn += { record_version_ = version; return true; %} + + function client_random() : bytestring %{ return client_random_; %} + + function set_client_random(client_random: bytestring) : bool + %{ + client_random_.init(client_random.data(), client_random.length()); + return true; + %} + + function server_random() : bytestring %{ return server_random_; %} + + function set_server_random(server_random: bytestring) : bool + %{ + server_random_.init(server_random.data(), server_random.length()); + return true; + %} + + function gmt_unix_time() : uint32 %{ return gmt_unix_time_; %} + + function set_gmt_unix_time(ts: uint32) : bool + %{ + gmt_unix_time_ = ts; + return true; + %} }; diff --git a/testing/btest/Baseline/scripts.policy.misc.dump-events/really-all-events.log b/testing/btest/Baseline/scripts.policy.misc.dump-events/really-all-events.log index 0d937690c2..e20dbfb687 100644 --- a/testing/btest/Baseline/scripts.policy.misc.dump-events/really-all-events.log +++ b/testing/btest/Baseline/scripts.policy.misc.dump-events/really-all-events.log @@ -9079,6 +9079,7 @@ XXXXXXXXXX.XXXXXX ssl_encrypted_data [2] record_version: count = 771 [3] content_type: count = 22 [4] length: count = 32 + [5] payload: string = \x1c\x1c\x84S/9\x14e\xb6'\xe5,\x03\x0fY\xdf\x1b\xcfu\xc84\xae\x1a"\xea]9j'\xbeZ\xa7 XXXXXXXXXX.XXXXXX raw_packet [0] p: raw_pkt_hdr = [l2=[encap=LINK_ETHERNET, len=91, cap_len=91, src=58:b0:35:86:54:8d, dst=cc:b2:55:f4:62:92, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=77, id=51331, ttl=64, p=6, src=192.168.133.100, dst=17.167.150.73], ip6=, tcp=[sport=49655/tcp, dport=443/tcp, seq=3289393854, ack=2319612745, hl=20, dl=37, reserved=0, flags=24, win=8192], udp=, icmp=] @@ -9176,6 +9177,7 @@ XXXXXXXXXX.XXXXXX ssl_encrypted_data [2] record_version: count = 771 [3] content_type: count = 22 [4] length: count = 32 + [5] payload: string = Z\x99\x17~d\x06\xbd;\xb4\xdf\xe2\xb3~9,|\xac\xdb\xb4\xeb\xcc\x95.\x17\xd2Q\x8a\x96\xdb\x13\x09! XXXXXXXXXX.XXXXXX raw_packet [0] p: raw_pkt_hdr = [l2=[encap=LINK_ETHERNET, len=97, cap_len=97, src=cc:b2:55:f4:62:92, dst=58:b0:35:86:54:8d, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=83, id=50807, ttl=243, p=6, src=17.167.150.73, dst=192.168.133.100], ip6=, tcp=[sport=443/tcp, dport=49655/tcp, seq=2319612745, ack=3289393891, hl=20, dl=43, reserved=0, flags=24, win=3626], udp=, icmp=] diff --git a/testing/btest/scripts/base/protocols/ssl/handshake-events.test b/testing/btest/scripts/base/protocols/ssl/handshake-events.test index 0b45bebc02..0c694bfaa1 100644 --- a/testing/btest/scripts/base/protocols/ssl/handshake-events.test +++ b/testing/btest/scripts/base/protocols/ssl/handshake-events.test @@ -27,7 +27,7 @@ event ssl_plaintext_data(c: connection, is_orig: bool, record_version: count, co print "Plaintext data", c$id$orig_h, c$id$resp_h, is_orig, SSL::version_strings[record_version], content_type, length; } -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) { print "Encrypted data", c$id$orig_h, c$id$resp_h, is_orig, SSL::version_strings[record_version], content_type, length; } diff --git a/testing/btest/scripts/base/protocols/ssl/tls13.test b/testing/btest/scripts/base/protocols/ssl/tls13.test index 875149ce80..f1f03cd5df 100644 --- a/testing/btest/scripts/base/protocols/ssl/tls13.test +++ b/testing/btest/scripts/base/protocols/ssl/tls13.test @@ -37,7 +37,7 @@ event ssl_established(c: connection) print "established", c$id; } -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) { print "encrypted", c$id, is_orig, SSL::version_strings[record_version], content_type; } diff --git a/testing/btest/scripts/base/protocols/ssl/tls13_encrypted_handshake_events.test b/testing/btest/scripts/base/protocols/ssl/tls13_encrypted_handshake_events.test index 3293315723..08936cee56 100644 --- a/testing/btest/scripts/base/protocols/ssl/tls13_encrypted_handshake_events.test +++ b/testing/btest/scripts/base/protocols/ssl/tls13_encrypted_handshake_events.test @@ -6,7 +6,7 @@ redef SSL::disable_analyzer_after_detection=F; -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) { print "encrypted", c$id, is_orig, SSL::version_strings[record_version], content_type; } From f73935aa45a87c92ce1901285584668595657420 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Wed, 5 May 2021 15:41:36 +0200 Subject: [PATCH 002/204] ssl/decryption.zeek: cleanup --- scripts/policy/protocols/ssl/decryption.zeek | 87 +++++++++++--------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek index a3608d81e7..982dc12154 100644 --- a/scripts/policy/protocols/ssl/decryption.zeek +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -7,8 +7,25 @@ module SSL; -# Local -const input_stream_name = "input-tls-keylog-file"; +export { + const keylog_file = getenv("ZEEK_TLS_KEYLOG_FILE") &redef; + + global secrets: table[string] of string = {} &redef; + global keys: table[string] of string = {} &redef; + + global add_keys: event(client_random: string, keys: string); + + global add_secret: event(client_random: string, secret: string); +} + +# Do not disable analyzers after detection - otherwise we will not receive +# encrypted packets. +redef SSL::disable_analyzer_after_detection=F; + +redef record SSL::Info += { + # Decryption uses client_random as identifier + client_random: string &log &optional; +}; type Idx: record { client_random: string; @@ -18,30 +35,34 @@ type Val: record { secret: string; }; -global randoms: table[string] of string = {}; +const input_stream_name = "input-tls-keylog-file"; -export { - redef record Info += { - # decryption uses client_random as identifier - client_random: string &log &optional; - }; - - const keylog_file = getenv("ZEEK_TLS_KEYLOG_FILE") &redef; - - global secrets: table[string] of string = {} &redef; - global keys: table[string] of string = {} &redef; - - event SSL::add_keys(client_random: string, val: string) +event zeek_init() { - SSL::keys[client_random] = val; - } + # listen for secrets + Broker::subscribe("/zeek/tls/decryption"); - event SSL::add_secret(client_random: string, val: string) - { - SSL::secrets[client_random] = val; - } + # FIXME: is such a functionality helpful? + # ingest keylog file if the environment is set + if ( keylog_file != "" ) + { + suspend_processing(); + + Input::add_table([$name=input_stream_name, $source=keylog_file, $destination=secrets, $idx=Idx, $val=Val, $want_record=F]); + Input::remove(input_stream_name); + } } +event SSL::add_keys(client_random: string, keys: string) + { + SSL::keys[client_random] = keys; + } + +event SSL::add_secret(client_random: string, secret: string) + { + SSL::secrets[client_random] = secret; + } + event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) { c$ssl$client_random = client_random; @@ -70,8 +91,8 @@ event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, co } else { - # FIXME: should this be moved to reporter.log or removed completely? - #print "No suitable key or secret found for random:", randoms[c$uid]; + # FIXME: replace with @if gated reporter + #print "No suitable key or secret found for random:", c$ssl$client_random; } } } @@ -84,23 +105,7 @@ event SSL::tls_input_done() event Input::end_of_data(name: string, source: string) { if ( name == input_stream_name ) - { - event SSL::tls_input_done(); - } -} - -event zeek_init() - { - # listen for secrets - Broker::subscribe("/zeek/tls/decryption"); - - # FIXME: is such a functionality helpful? - # ingest keylog file if the environment is set - if ( keylog_file != "" ) { - suspend_processing(); - - Input::add_table([$name=input_stream_name, $source=keylog_file, $destination=secrets, $idx=Idx, $val=Val, $want_record=F]); - Input::remove(input_stream_name); + event SSL::tls_input_done(); } -} + } From c1c0cb6f3c4c4963f9a47c44008b60f6a3907cb8 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Wed, 5 May 2021 15:46:20 +0200 Subject: [PATCH 003/204] analyzer/ssl: Formatting, printf -> DBG_LOG, namespacing --- scripts/policy/protocols/ssl/decryption.zeek | 8 +++--- src/analyzer/protocol/ssl/DTLS.cc | 8 +++--- src/analyzer/protocol/ssl/SSL.cc | 27 ++++++++++---------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek index 982dc12154..1bd5eed622 100644 --- a/scripts/policy/protocols/ssl/decryption.zeek +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -53,14 +53,14 @@ event zeek_init() } } -event SSL::add_keys(client_random: string, keys: string) +event SSL::add_keys(client_random: string, val: string) { - SSL::keys[client_random] = keys; + SSL::keys[client_random] = val; } -event SSL::add_secret(client_random: string, secret: string) +event SSL::add_secret(client_random: string, val: string) { - SSL::secrets[client_random] = secret; + SSL::secrets[client_random] = val; } event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) diff --git a/src/analyzer/protocol/ssl/DTLS.cc b/src/analyzer/protocol/ssl/DTLS.cc index ee823148bd..faded0d56d 100644 --- a/src/analyzer/protocol/ssl/DTLS.cc +++ b/src/analyzer/protocol/ssl/DTLS.cc @@ -49,9 +49,9 @@ void DTLS_Analyzer::EndOfData(bool is_orig) } uint16_t DTLS_Analyzer::GetNegotiatedVersion() const - { - return handshake_interp->chosen_version(); - } + { + return handshake_interp->chosen_version(); + } void DTLS_Analyzer::SendHandshake(uint16_t raw_tls_version, uint8_t msg_type, uint32_t length, const u_char* begin, const u_char* end, bool orig) { @@ -74,7 +74,7 @@ void DTLS_Analyzer::SendHandshake(uint16_t raw_tls_version, uint8_t msg_type, ui bool DTLS_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version) { - // noop for now as DTLS decryption is currently not supported + // noop for now as DTLS decryption is currently not supported } } // namespace zeek::analyzer::dtls diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 6fd2349fa1..6f92bdbfcf 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -13,16 +13,6 @@ #include #include -#define MSB(a) ((a>>8)&0xff) -#define LSB(a) (a&0xff) - -static void fmt_seq(uint32_t num, u_char* buf) - { - memset(buf, 0, 8); - uint32_t netnum = htonl(num); - memcpy(buf+4, &netnum, 4); - } - static void print_hex(std::string name, u_char* data, int len) { int i = 0; @@ -78,6 +68,16 @@ abort: namespace zeek::analyzer::ssl { +#define MSB(a) ((a>>8)&0xff) +#define LSB(a) (a&0xff) + +static void fmt_seq(uint32_t num, u_char* buf) + { + memset(buf, 0, 8); + uint32_t netnum = htonl(num); + memcpy(buf+4, &netnum, 4); + } + SSL_Analyzer::SSL_Analyzer(Connection* c) : analyzer::tcp::TCP_ApplicationAnalyzer("SSL", c) { @@ -193,15 +193,14 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i auto cipher = handshake_interp->chosen_cipher(); if ( cipher != 0xC030 ) { - //printf("Unsupported cipher suite: %d\n", cipher); + DBG_LOG(DBG_ANALYZER, "Unsupported cipher suite: %d\n", cipher); return false; } // Neither secret or key present: abort if ( secret->Len() == 0 && keys->Len() == 0 ) { - // FIXME: this is just for debugging - printf("Could not decrypt packet (missing key):\n"); + DBG_LOG(DBG_ANALYZER, "Could not decrypt packet due to missing key\n"); print_hex("->client_random:", handshake_interp->client_random().data(), handshake_interp->client_random().length()); return false; } @@ -293,7 +292,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i int res = 0; if ( ! (res = EVP_DecryptFinal(ctx, NULL, &res)) ) { - printf("Decryption failed with return code %d. Invalid key?\n", res); + DBG_LOG(DBG_ANALYZER, "Decryption failed with return code: %d. Invalid key?\n", res); EVP_CIPHER_CTX_free(ctx); free(decrypted); return false; From febc69d320e1ca967d46a1f40fcf2e755f0309a7 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Wed, 5 May 2021 18:22:56 +0200 Subject: [PATCH 004/204] analyzer/ssl: cleanup SSL_Analyzer - make TLS12 PRF a member function of the analyzer - use std::string in PRF - use StringValPtr instead of zeek::StringVal - replace malloc/free with C++ style allocations --- scripts/policy/protocols/ssl/decryption.zeek | 2 +- src/analyzer/protocol/ssl/SSL.cc | 115 +++++++++---------- src/analyzer/protocol/ssl/SSL.h | 5 +- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek index 1bd5eed622..766bb4d940 100644 --- a/scripts/policy/protocols/ssl/decryption.zeek +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -51,7 +51,7 @@ event zeek_init() Input::add_table([$name=input_stream_name, $source=keylog_file, $destination=secrets, $idx=Idx, $val=Val, $want_record=F]); Input::remove(input_stream_name); } -} + } event SSL::add_keys(client_random: string, val: string) { diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 6f92bdbfcf..ec1ebffea2 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -27,45 +27,6 @@ static void print_hex(std::string name, u_char* data, int len) printf("\n"); } -static bool tls1_prf(const u_char *secret, int secret_len, const char* label, - const u_char* rnd1, int rnd1_len, const u_char* rnd2, int rnd2_len, u_char* out, size_t out_len) - { - // alloc buffers - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); - size_t seed_len = strlen(label) + rnd1_len + rnd2_len; - u_char *seed = (u_char*) malloc(seed_len); - u_char *ptr = seed; - - // seed = label + rnd1 + rnd2 - memcpy(ptr, label, strlen(label)); - ptr += strlen(label); - memcpy(ptr, rnd1, rnd1_len); - ptr += rnd1_len; - memcpy(ptr, rnd2, rnd2_len); - ptr += rnd2_len; - - if (EVP_PKEY_derive_init(pctx) <= 0) - goto abort; /* Error */ - // FIXME: sha384 should not be hardcoded - if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0) - goto abort; /* Error */ - if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret, secret_len) <= 0) - goto abort; /* Error */ - if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seed_len) <= 0) - goto abort; /* Error */ - if (EVP_PKEY_derive(pctx, out, &out_len) <= 0) - goto abort; /* Error */ - - EVP_PKEY_CTX_free(pctx); - free(seed); - return true; - -abort: - EVP_PKEY_CTX_free(pctx); - free(seed); - return false; - } - namespace zeek::analyzer::ssl { #define MSB(a) ((a>>8)&0xff) @@ -87,8 +48,8 @@ SSL_Analyzer::SSL_Analyzer(Connection* c) c_seq = 0; s_seq = 0; // FIXME: should this be initialized to nullptr? - secret = new zeek::StringVal(0, ""); - keys = new zeek::StringVal(0, ""); + secret = nullptr; + keys = nullptr; pia = nullptr; } @@ -96,8 +57,6 @@ SSL_Analyzer::~SSL_Analyzer() { delete interp; delete handshake_interp; - delete secret; - delete keys; } void SSL_Analyzer::Done() @@ -176,16 +135,49 @@ void SSL_Analyzer::Undelivered(uint64_t seq, int len, bool orig) void SSL_Analyzer::SetSecret(const u_char* data, int len) { - // FIXME: Is this the proper way to initialize a zeek::StringVal? - // the alternative requires a cast: new zeek::StringVal(len, data) - secret = new zeek::StringVal(new zeek::String(data, len, true)); + secret = make_intrusive(len, (const char*)data); } void SSL_Analyzer::SetKeys(const u_char* data, int len) { - keys = new zeek::StringVal(new zeek::String(data, len, true)); + keys = make_intrusive(len, (const char*)data); } +bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label, + const char* rnd1, size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len) + { + // alloc buffers + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); + size_t seed_len = label.length() + rnd1_len + rnd2_len; + std::string seed{}; + seed.reserve(seed_len); + + // seed = label + rnd1 + rnd2 + seed.append(label); + seed.append(rnd1, rnd1_len); + seed.append(rnd2, rnd2_len); + + if (EVP_PKEY_derive_init(pctx) <= 0) + goto abort; /* Error */ + // FIXME: sha384 should not be hardcoded + if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret.data(), secret.length()) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.length()) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_derive(pctx, out, &out_len) <= 0) + goto abort; /* Error */ + + EVP_PKEY_CTX_free(pctx); + return true; + +abort: + EVP_PKEY_CTX_free(pctx); + return false; + } + + bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version) { // Unsupported cipher suite. Currently supported: @@ -198,19 +190,20 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i } // Neither secret or key present: abort - if ( secret->Len() == 0 && keys->Len() == 0 ) + if ( ( secret == nullptr || secret->Len() == 0 ) && ( keys == nullptr || keys->Len() == 0 ) ) { - DBG_LOG(DBG_ANALYZER, "Could not decrypt packet due to missing key\n"); - print_hex("->client_random:", handshake_interp->client_random().data(), handshake_interp->client_random().length()); + DBG_LOG(DBG_ANALYZER, "Could not decrypt packet due to missing keys/secret.\n"); + // FIXME: change util function to return a printably std::string for DBG_LOG + //print_hex("->client_random:", handshake_interp->client_random().data(), handshake_interp->client_random().length()); return false; } // Secret present, but no keys derived yet: derive keys - if ( secret->Len() != 0 && keys->Len() == 0 ) + if ( secret != nullptr && secret->Len() != 0 && ( keys == nullptr || keys->Len() == 0 ) ) { uint32_t ts = htonl((uint32_t) handshake_interp->gmt_unix_time()); - u_char crand[32] = {0x00}; + char crand[32] = {0x00}; u_char keybuf[72]; auto c_rnd = handshake_interp->client_random(); @@ -218,15 +211,20 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i memcpy(crand, &(ts), 4); memcpy(crand + 4, c_rnd.data(), c_rnd.length()); - tls1_prf(secret->Bytes(), secret->Len(), "key expansion", s_rnd.data(), s_rnd.length(), - crand, sizeof(crand), keybuf, sizeof(keybuf)); + auto res = TLS12_PRF(secret->ToStdString(), "key expansion", + (char*)s_rnd.data(), s_rnd.length(), crand, sizeof(crand), keybuf, sizeof(keybuf)); + if ( !res ) + { + DBG_LOG(DBG_ANALYZER, "TLS PRF failed. Aborting.\n"); + return false; + } // save derived keys SetKeys(keybuf, sizeof(keybuf)); } // Keys present: decrypt TLS application data - if ( keys->Len() != 0 ) + if ( keys != nullptr && keys->Len() != 0 ) { // session keys & AEAD data u_char c_wk[32]; @@ -266,6 +264,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i encrypted_len -= 8; encrypted_len -= 16; + // FIXME: aes_256_gcm should not be hardcoded here ;) if (is_orig) EVP_DecryptInit(ctx, EVP_aes_256_gcm(), c_wk, s_aead_nonce); else @@ -283,7 +282,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i s_aead_tag[11] = MSB(encrypted_len); s_aead_tag[12] = LSB(encrypted_len); - u_char *decrypted = (u_char*)malloc(encrypted_len); + u_char *decrypted = new u_char[ encrypted_len ]; int decrypted_len = 0; EVP_DecryptUpdate(ctx, NULL, &decrypted_len, s_aead_tag, 13); @@ -294,14 +293,14 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i { DBG_LOG(DBG_ANALYZER, "Decryption failed with return code: %d. Invalid key?\n", res); EVP_CIPHER_CTX_free(ctx); - free(decrypted); + delete [] decrypted; return false; } EVP_CIPHER_CTX_free(ctx); ForwardDecryptedData(decrypted_len, reinterpret_cast(decrypted), is_orig); - free(decrypted); + delete [] decrypted; return true; } diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index 4eac7e77a6..e4df7a5b55 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -39,6 +39,7 @@ public: void SetKeys(const u_char* data, int len); bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version); + bool TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1, size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len); void ForwardDecryptedData(int len, const u_char* data, bool is_orig); protected: @@ -49,8 +50,8 @@ protected: // FIXME: should this be moved into the connection? int c_seq; int s_seq; - zeek::StringVal *secret; - zeek::StringVal *keys; + StringValPtr secret; + StringValPtr keys; zeek::analyzer::pia::PIA_TCP *pia; }; From 68f5ae9538b919050e42723c3351cae3937ed759 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Wed, 5 May 2021 19:12:25 +0200 Subject: [PATCH 005/204] analyzer/ssl: move proc-{client,server}-hello into the respective analyzers --- src/analyzer/protocol/ssl/CMakeLists.txt | 4 - .../protocol/ssl/proc-client-hello-tls.pac | 56 ---------- .../protocol/ssl/proc-client-hello.pac | 54 ---------- .../protocol/ssl/proc-server-hello-tls.pac | 41 ------- .../protocol/ssl/proc-server-hello.pac | 40 ------- src/analyzer/protocol/ssl/ssl-analyzer.pac | 98 ++++++++++++++++- .../protocol/ssl/tls-handshake-analyzer.pac | 101 +++++++++++++++++- 7 files changed, 195 insertions(+), 199 deletions(-) delete mode 100644 src/analyzer/protocol/ssl/proc-client-hello-tls.pac delete mode 100644 src/analyzer/protocol/ssl/proc-client-hello.pac delete mode 100644 src/analyzer/protocol/ssl/proc-server-hello-tls.pac delete mode 100644 src/analyzer/protocol/ssl/proc-server-hello.pac diff --git a/src/analyzer/protocol/ssl/CMakeLists.txt b/src/analyzer/protocol/ssl/CMakeLists.txt index 2a9179ce64..9a82ecff8a 100644 --- a/src/analyzer/protocol/ssl/CMakeLists.txt +++ b/src/analyzer/protocol/ssl/CMakeLists.txt @@ -10,14 +10,10 @@ zeek_plugin_bif(events.bif) zeek_plugin_bif(functions.bif) zeek_plugin_bif(consts.bif) zeek_plugin_pac(tls-handshake.pac tls-handshake-protocol.pac tls-handshake-analyzer.pac ssl-defs.pac - proc-client-hello-tls.pac - proc-server-hello-tls.pac proc-certificate.pac tls-handshake-signed_certificate_timestamp.pac ) zeek_plugin_pac(ssl.pac ssl-dtls-analyzer.pac ssl-analyzer.pac ssl-dtls-protocol.pac ssl-protocol.pac ssl-defs.pac - proc-client-hello.pac - proc-server-hello.pac proc-certificate.pac ) zeek_plugin_pac(dtls.pac ssl-dtls-analyzer.pac dtls-analyzer.pac ssl-dtls-protocol.pac dtls-protocol.pac ssl-defs.pac) diff --git a/src/analyzer/protocol/ssl/proc-client-hello-tls.pac b/src/analyzer/protocol/ssl/proc-client-hello-tls.pac deleted file mode 100644 index a06be74e36..0000000000 --- a/src/analyzer/protocol/ssl/proc-client-hello-tls.pac +++ /dev/null @@ -1,56 +0,0 @@ - function proc_client_hello( - version : uint16, ts : double, - client_random : bytestring, - session_id : uint8[], - cipher_suites16 : uint16[], - cipher_suites24 : uint24[], - compression_methods: uint8[]) : bool - %{ - if ( ! version_ok(version) ) - { - zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); - zeek_analyzer()->SetSkip(true); - } - else - zeek_analyzer()->ProtocolConfirmation(); - - if ( ssl_client_hello ) - { - vector cipher_suites; - - if ( cipher_suites16 ) - std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(cipher_suites)); - else - std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(cipher_suites), to_int()); - - auto cipher_vec = zeek::make_intrusive(zeek::id::index_vec); - - for ( unsigned int i = 0; i < cipher_suites.size(); ++i ) - { - auto ciph = zeek::val_mgr->Count(cipher_suites[i]); - cipher_vec->Assign(i, ciph); - } - - auto comp_vec = zeek::make_intrusive(zeek::id::index_vec); - - if ( compression_methods ) - { - for ( unsigned int i = 0; i < compression_methods->size(); ++i ) - { - auto comp = zeek::val_mgr->Count((*compression_methods)[i]); - comp_vec->Assign(i, comp); - } - } - - set_client_random(client_random); - set_gmt_unix_time(ts); - zeek::BifEvent::enqueue_ssl_client_hello(zeek_analyzer(), zeek_analyzer()->Conn(), - version, record_version(), ts, - zeek::make_intrusive(client_random.length(), - (const char*) client_random.data()), - {zeek::AdoptRef{}, to_string_val(session_id)}, - std::move(cipher_vec), std::move(comp_vec)); - } - - return true; - %} diff --git a/src/analyzer/protocol/ssl/proc-client-hello.pac b/src/analyzer/protocol/ssl/proc-client-hello.pac deleted file mode 100644 index ae3774ed9a..0000000000 --- a/src/analyzer/protocol/ssl/proc-client-hello.pac +++ /dev/null @@ -1,54 +0,0 @@ - function proc_client_hello( - version : uint16, ts : double, - client_random : bytestring, - session_id : uint8[], - cipher_suites16 : uint16[], - cipher_suites24 : uint24[], - compression_methods: uint8[]) : bool - %{ - if ( ! version_ok(version) ) - { - zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); - zeek_analyzer()->SetSkip(true); - } - else - zeek_analyzer()->ProtocolConfirmation(); - - if ( ssl_client_hello ) - { - vector cipher_suites; - - if ( cipher_suites16 ) - std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(cipher_suites)); - else - std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(cipher_suites), to_int()); - - auto cipher_vec = zeek::make_intrusive(zeek::id::index_vec); - - for ( unsigned int i = 0; i < cipher_suites.size(); ++i ) - { - auto ciph = zeek::val_mgr->Count(cipher_suites[i]); - cipher_vec->Assign(i, ciph); - } - - auto comp_vec = zeek::make_intrusive(zeek::id::index_vec); - - if ( compression_methods ) - { - for ( unsigned int i = 0; i < compression_methods->size(); ++i ) - { - auto comp = zeek::val_mgr->Count((*compression_methods)[i]); - comp_vec->Assign(i, comp); - } - } - - zeek::BifEvent::enqueue_ssl_client_hello(zeek_analyzer(), zeek_analyzer()->Conn(), - version, record_version(), ts, - zeek::make_intrusive(client_random.length(), - (const char*) client_random.data()), - {zeek::AdoptRef{}, to_string_val(session_id)}, - std::move(cipher_vec), std::move(comp_vec)); - } - - return true; - %} diff --git a/src/analyzer/protocol/ssl/proc-server-hello-tls.pac b/src/analyzer/protocol/ssl/proc-server-hello-tls.pac deleted file mode 100644 index 456cc9bcd0..0000000000 --- a/src/analyzer/protocol/ssl/proc-server-hello-tls.pac +++ /dev/null @@ -1,41 +0,0 @@ - function proc_server_hello( - version : uint16, v2 : bool, - server_random : bytestring, - session_id : uint8[], - cipher_suites16 : uint16[], - cipher_suites24 : uint24[], - comp_method : uint8) : bool - %{ - if ( ! version_ok(version) ) - { - zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); - zeek_analyzer()->SetSkip(true); - } - - if ( ssl_server_hello ) - { - vector* ciphers = new vector(); - - if ( cipher_suites16 ) - std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*ciphers)); - else - std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*ciphers), to_int()); - - uint32 ts = 0; - if ( v2 == 0 && server_random.length() >= 4 ) - ts = ntohl(*((uint32*)server_random.data())); - - set_server_random(server_random); - zeek::BifEvent::enqueue_ssl_server_hello(zeek_analyzer(), - zeek_analyzer()->Conn(), - version, record_version(), ts, - zeek::make_intrusive(server_random.length(), - (const char*) server_random.data()), - {zeek::AdoptRef{}, to_string_val(session_id)}, - ciphers->size()==0 ? 0 : ciphers->at(0), comp_method); - - delete ciphers; - } - - return true; - %} diff --git a/src/analyzer/protocol/ssl/proc-server-hello.pac b/src/analyzer/protocol/ssl/proc-server-hello.pac deleted file mode 100644 index 30356508c6..0000000000 --- a/src/analyzer/protocol/ssl/proc-server-hello.pac +++ /dev/null @@ -1,40 +0,0 @@ - function proc_server_hello( - version : uint16, v2 : bool, - server_random : bytestring, - session_id : uint8[], - cipher_suites16 : uint16[], - cipher_suites24 : uint24[], - comp_method : uint8) : bool - %{ - if ( ! version_ok(version) ) - { - zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); - zeek_analyzer()->SetSkip(true); - } - - if ( ssl_server_hello ) - { - vector* ciphers = new vector(); - - if ( cipher_suites16 ) - std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*ciphers)); - else - std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*ciphers), to_int()); - - uint32 ts = 0; - if ( v2 == 0 && server_random.length() >= 4 ) - ts = ntohl(*((uint32*)server_random.data())); - - zeek::BifEvent::enqueue_ssl_server_hello(zeek_analyzer(), - zeek_analyzer()->Conn(), - version, record_version(), ts, - zeek::make_intrusive(server_random.length(), - (const char*) server_random.data()), - {zeek::AdoptRef{}, to_string_val(session_id)}, - ciphers->size()==0 ? 0 : ciphers->at(0), comp_method); - - delete ciphers; - } - - return true; - %} diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index c1a8876058..d676630ae8 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -2,10 +2,104 @@ refine connection SSL_Conn += { - %include proc-client-hello.pac - %include proc-server-hello.pac %include proc-certificate.pac + function proc_client_hello( + version : uint16, ts : double, + client_random : bytestring, + session_id : uint8[], + cipher_suites16 : uint16[], + cipher_suites24 : uint24[], + compression_methods: uint8[]) : bool + %{ + if ( ! version_ok(version) ) + { + zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); + zeek_analyzer()->SetSkip(true); + } + else + zeek_analyzer()->ProtocolConfirmation(); + + if ( ssl_client_hello ) + { + vector cipher_suites; + + if ( cipher_suites16 ) + std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(cipher_suites)); + else + std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(cipher_suites), to_int()); + + auto cipher_vec = zeek::make_intrusive(zeek::id::index_vec); + + for ( unsigned int i = 0; i < cipher_suites.size(); ++i ) + { + auto ciph = zeek::val_mgr->Count(cipher_suites[i]); + cipher_vec->Assign(i, ciph); + } + + auto comp_vec = zeek::make_intrusive(zeek::id::index_vec); + + if ( compression_methods ) + { + for ( unsigned int i = 0; i < compression_methods->size(); ++i ) + { + auto comp = zeek::val_mgr->Count((*compression_methods)[i]); + comp_vec->Assign(i, comp); + } + } + + zeek::BifEvent::enqueue_ssl_client_hello(zeek_analyzer(), zeek_analyzer()->Conn(), + version, record_version(), ts, + zeek::make_intrusive(client_random.length(), + (const char*) client_random.data()), + {zeek::AdoptRef{}, to_string_val(session_id)}, + std::move(cipher_vec), std::move(comp_vec)); + } + + return true; + %} + + function proc_server_hello( + version : uint16, v2 : bool, + server_random : bytestring, + session_id : uint8[], + cipher_suites16 : uint16[], + cipher_suites24 : uint24[], + comp_method : uint8) : bool + %{ + if ( ! version_ok(version) ) + { + zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); + zeek_analyzer()->SetSkip(true); + } + + if ( ssl_server_hello ) + { + vector* ciphers = new vector(); + + if ( cipher_suites16 ) + std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*ciphers)); + else + std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*ciphers), to_int()); + + uint32 ts = 0; + if ( v2 == 0 && server_random.length() >= 4 ) + ts = ntohl(*((uint32*)server_random.data())); + + zeek::BifEvent::enqueue_ssl_server_hello(zeek_analyzer(), + zeek_analyzer()->Conn(), + version, record_version(), ts, + zeek::make_intrusive(server_random.length(), + (const char*) server_random.data()), + {zeek::AdoptRef{}, to_string_val(session_id)}, + ciphers->size()==0 ? 0 : ciphers->at(0), comp_method); + + delete ciphers; + } + + return true; + %} + function proc_v2_certificate(is_orig: bool, cert : bytestring) : bool %{ vector* cert_list = new vector(1,cert); diff --git a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac index 9559ba0151..ccc90bc7e7 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac @@ -25,10 +25,107 @@ refine connection Handshake_Conn += { - %include proc-client-hello-tls.pac - %include proc-server-hello-tls.pac %include proc-certificate.pac + function proc_client_hello( + version : uint16, ts : double, + client_random : bytestring, + session_id : uint8[], + cipher_suites16 : uint16[], + cipher_suites24 : uint24[], + compression_methods: uint8[]) : bool + %{ + if ( ! version_ok(version) ) + { + zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); + zeek_analyzer()->SetSkip(true); + } + else + zeek_analyzer()->ProtocolConfirmation(); + + if ( ssl_client_hello ) + { + vector cipher_suites; + + if ( cipher_suites16 ) + std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(cipher_suites)); + else + std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(cipher_suites), to_int()); + + auto cipher_vec = zeek::make_intrusive(zeek::id::index_vec); + + for ( unsigned int i = 0; i < cipher_suites.size(); ++i ) + { + auto ciph = zeek::val_mgr->Count(cipher_suites[i]); + cipher_vec->Assign(i, ciph); + } + + auto comp_vec = zeek::make_intrusive(zeek::id::index_vec); + + if ( compression_methods ) + { + for ( unsigned int i = 0; i < compression_methods->size(); ++i ) + { + auto comp = zeek::val_mgr->Count((*compression_methods)[i]); + comp_vec->Assign(i, comp); + } + } + + set_client_random(client_random); + set_gmt_unix_time(ts); + zeek::BifEvent::enqueue_ssl_client_hello(zeek_analyzer(), zeek_analyzer()->Conn(), + version, record_version(), ts, + zeek::make_intrusive(client_random.length(), + (const char*) client_random.data()), + {zeek::AdoptRef{}, to_string_val(session_id)}, + std::move(cipher_vec), std::move(comp_vec)); + } + + return true; + %} + + function proc_server_hello( + version : uint16, v2 : bool, + server_random : bytestring, + session_id : uint8[], + cipher_suites16 : uint16[], + cipher_suites24 : uint24[], + comp_method : uint8) : bool + %{ + if ( ! version_ok(version) ) + { + zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); + zeek_analyzer()->SetSkip(true); + } + + if ( ssl_server_hello ) + { + vector* ciphers = new vector(); + + if ( cipher_suites16 ) + std::copy(cipher_suites16->begin(), cipher_suites16->end(), std::back_inserter(*ciphers)); + else + std::transform(cipher_suites24->begin(), cipher_suites24->end(), std::back_inserter(*ciphers), to_int()); + + uint32 ts = 0; + if ( v2 == 0 && server_random.length() >= 4 ) + ts = ntohl(*((uint32*)server_random.data())); + + set_server_random(server_random); + zeek::BifEvent::enqueue_ssl_server_hello(zeek_analyzer(), + zeek_analyzer()->Conn(), + version, record_version(), ts, + zeek::make_intrusive(server_random.length(), + (const char*) server_random.data()), + {zeek::AdoptRef{}, to_string_val(session_id)}, + ciphers->size()==0 ? 0 : ciphers->at(0), comp_method); + + delete ciphers; + } + + return true; + %} + function proc_session_ticket_handshake(rec: SessionTicketHandshake, is_orig: bool): bool %{ if ( ssl_session_ticket_handshake ) From 95a6ee27b13fac95676072ea8d5765a822e4a90c Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Fri, 7 May 2021 17:03:24 +0200 Subject: [PATCH 006/204] analyzer/ssl: silence warning in DTLS analyzer --- src/analyzer/protocol/ssl/DTLS.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/analyzer/protocol/ssl/DTLS.cc b/src/analyzer/protocol/ssl/DTLS.cc index faded0d56d..95f6d5471b 100644 --- a/src/analyzer/protocol/ssl/DTLS.cc +++ b/src/analyzer/protocol/ssl/DTLS.cc @@ -75,6 +75,7 @@ void DTLS_Analyzer::SendHandshake(uint16_t raw_tls_version, uint8_t msg_type, ui bool DTLS_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version) { // noop for now as DTLS decryption is currently not supported + return false; } } // namespace zeek::analyzer::dtls From 979bf2076985b83612ea01c8e50e5f4bf8979513 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Fri, 7 May 2021 17:04:16 +0200 Subject: [PATCH 007/204] analyzer/ssl: handle missing --- cmake | 2 +- src/analyzer/protocol/ssl/SSL.cc | 16 ++++++++++++---- zeek-config.h.in | 3 +++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cmake b/cmake index 74259745de..cce53d1500 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 74259745dea5ee4889d1ac1f4ebde4e2c59c329a +Subproject commit cce53d15008a26dcb1b7eb534a78f52f9355c676 diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index ec1ebffea2..072518b8ea 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -11,7 +11,10 @@ #include #include -#include + +#ifdef OPENSSL_HAVE_KDF_H + #include +#endif static void print_hex(std::string name, u_char* data, int len) { @@ -146,6 +149,7 @@ void SSL_Analyzer::SetKeys(const u_char* data, int len) bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1, size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len) { +#ifdef OPENSSL_HAVE_KDF_H // alloc buffers EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); size_t seed_len = label.length() + rnd1_len + rnd2_len; @@ -174,6 +178,7 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label abort: EVP_PKEY_CTX_free(pctx); +#endif return false; } @@ -201,6 +206,8 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i // Secret present, but no keys derived yet: derive keys if ( secret != nullptr && secret->Len() != 0 && ( keys == nullptr || keys->Len() == 0 ) ) { +#ifdef OPENSSL_HAVE_KDF_H + DBG_LOG(DBG_ANALYZER, "Deriving TLS keys for connection foo"); uint32_t ts = htonl((uint32_t) handshake_interp->gmt_unix_time()); char crand[32] = {0x00}; @@ -221,7 +228,8 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i // save derived keys SetKeys(keybuf, sizeof(keybuf)); - } +#endif + } // Keys present: decrypt TLS application data if ( keys != nullptr && keys->Len() != 0 ) @@ -302,9 +310,9 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i delete [] decrypted; return true; - } + } - // This is only reached if key derivation somehow failed + // This is only reached if key derivation fails or is unsupported return false; } diff --git a/zeek-config.h.in b/zeek-config.h.in index 8cc0c013d5..cf5d690913 100644 --- a/zeek-config.h.in +++ b/zeek-config.h.in @@ -77,6 +77,9 @@ /* Compatibility for Darwin */ #cmakedefine NEED_NAMESER_COMPAT_H +/* openssl/kdf.h for TLS PRF (key derivation) */ +#cmakedefine OPENSSL_HAVE_KDF_H + /* d2i_x509 uses const char** */ #cmakedefine OPENSSL_D2I_X509_USES_CONST_CHAR From 8c67b9c8fccddcd6f834c95f0bdf94502e11ad22 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Wed, 12 May 2021 11:46:17 +0200 Subject: [PATCH 008/204] testing: add ssl/decryption test --- .../http.log | 11 +++++++++++ testing/btest/Traces/tls/tls12-decryption.pcap | Bin 0 -> 6106 bytes .../scripts/policy/protocols/ssl/decryption.zeek | 10 ++++++++++ 3 files changed, 21 insertions(+) create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.decryption/http.log create mode 100644 testing/btest/Traces/tls/tls12-decryption.pcap create mode 100644 testing/btest/scripts/policy/protocols/ssl/decryption.zeek diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.decryption/http.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.decryption/http.log new file mode 100644 index 0000000000..a01d49a497 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.decryption/http.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer version user_agent origin request_body_len response_body_len status_code status_msg info_code info_msg tags username password proxied orig_fuids orig_filenames orig_mime_types resp_fuids resp_filenames resp_mime_types +#types time string addr port addr port count string string string string string string string count count count string count string set[enum] string string set[string] vector[string] vector[string] vector[string] vector[string] vector[string] vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.100.70 48216 193.99.144.80 443 1 GET heise.de / - 1.1 Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 - 0 229 301 Moved Permanently - - (empty) - - - - - - FaOfPL638bbaQ1KMh - text/html +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/tls/tls12-decryption.pcap b/testing/btest/Traces/tls/tls12-decryption.pcap new file mode 100644 index 0000000000000000000000000000000000000000..73ffaa14bd5279e5735181330c88b0edb5f855b0 GIT binary patch literal 6106 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 literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/policy/protocols/ssl/decryption.zeek b/testing/btest/scripts/policy/protocols/ssl/decryption.zeek new file mode 100644 index 0000000000..9e73ef418f --- /dev/null +++ b/testing/btest/scripts/policy/protocols/ssl/decryption.zeek @@ -0,0 +1,10 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/tls/tls12-decryption.pcap %INPUT + +# @TEST-EXEC: btest-diff http.log + +@load protocols/ssl/decryption +@load base/protocols/http + +redef SSL::secrets += { +["\xb4\x0a\x24\x4b\x48\xe4\x2e\xac\x28\x71\x44\xb1\xb7\x39\x30\x57\xca\xa1\x31\xf9\x61\xa7\x8e\x38\xb0\xe7\x7c\x1e"] = "\xbd\x01\xe5\x89\xd1\x05\x19\x9e\x9a\xb5\xfc\x9b\xd7\x58\xb5\xf2\x88\xdb\x28\xfd\x80\xaa\x02\x26\x1e\x47\x65\xac\x13\x57\xd0\x07\xfd\x08\xc7\xbd\xab\x45\x45\x0e\x01\x5a\x01\xd0\x8e\x5e\x7c\xa6", +}; From a7fe2bd9c58717d674325a007686f247a87a89cf Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Fri, 28 May 2021 12:56:01 +0200 Subject: [PATCH 009/204] testing: feature gate ssl/decryption test --- testing/btest/scripts/policy/protocols/ssl/decryption.zeek | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/btest/scripts/policy/protocols/ssl/decryption.zeek b/testing/btest/scripts/policy/protocols/ssl/decryption.zeek index 9e73ef418f..741284a540 100644 --- a/testing/btest/scripts/policy/protocols/ssl/decryption.zeek +++ b/testing/btest/scripts/policy/protocols/ssl/decryption.zeek @@ -1,5 +1,6 @@ -# @TEST-EXEC: zeek -b -C -r $TRACES/tls/tls12-decryption.pcap %INPUT +# @TEST-REQUIRES: grep -q "#define OPENSSL_HAVE_KDF_H" $BUILD/zeek-config.h +# @TEST-EXEC: zeek -b -C -r $TRACES/tls/tls12-decryption.pcap %INPUT # @TEST-EXEC: btest-diff http.log @load protocols/ssl/decryption From aaaff39e127d23ee0c76fcd4af50869407595be6 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Wed, 23 Jun 2021 17:34:41 +0200 Subject: [PATCH 010/204] analyzer/ssl: defensive key length check + more debug logging --- src/analyzer/protocol/ssl/SSL.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 072518b8ea..24897c0693 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -228,12 +228,16 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i // save derived keys SetKeys(keybuf, sizeof(keybuf)); +#else + DBG_LOG(DBG_ANALYZER, "Cannot derive TLS keys as Zeek was compiled without "); #endif } // Keys present: decrypt TLS application data - if ( keys != nullptr && keys->Len() != 0 ) + if ( keys != nullptr && keys->Len() == 72 ) { + // FIXME: could also print keys or conn id here + DBG_LOG(DBG_ANALYZER, "Decrypting application data"); // session keys & AEAD data u_char c_wk[32]; u_char s_wk[32]; @@ -305,6 +309,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i return false; } + DBG_LOG(DBG_ANALYZER, "Successfully decrypted %d bytes.", decrypted_len); EVP_CIPHER_CTX_free(ctx); ForwardDecryptedData(decrypted_len, reinterpret_cast(decrypted), is_orig); From ebea26a0654d764ea9daeb38a81def96efd7bfa0 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Thu, 24 Jun 2021 17:05:34 +0200 Subject: [PATCH 011/204] analyzer/ssl: several improvements - use better data structures for secret and key material storage - add documentation to the new methods in the analyzer --- src/analyzer/protocol/ssl/SSL.cc | 61 +++++++++++------ src/analyzer/protocol/ssl/SSL.h | 90 +++++++++++++++++++++++-- src/analyzer/protocol/ssl/functions.bif | 4 +- 3 files changed, 126 insertions(+), 29 deletions(-) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 24897c0693..55c0f74324 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -50,9 +50,6 @@ SSL_Analyzer::SSL_Analyzer(Connection* c) had_gap = false; c_seq = 0; s_seq = 0; - // FIXME: should this be initialized to nullptr? - secret = nullptr; - keys = nullptr; pia = nullptr; } @@ -136,14 +133,27 @@ void SSL_Analyzer::Undelivered(uint64_t seq, int len, bool orig) interp->NewGap(orig, len); } -void SSL_Analyzer::SetSecret(const u_char* data, int len) +void SSL_Analyzer::SetSecret(zeek::StringVal* secret) { - secret = make_intrusive(len, (const char*)data); + SetSecret(secret->Len(), secret->Bytes()); } -void SSL_Analyzer::SetKeys(const u_char* data, int len) +void SSL_Analyzer::SetSecret(size_t len, const u_char* data) { - keys = make_intrusive(len, (const char*)data); + secret.clear(); + secret.append((const char*)data, len); + } + +void SSL_Analyzer::SetKeys(zeek::StringVal* keys) + { + SetKeys(keys->Len(), keys->Bytes()); + } + +void SSL_Analyzer::SetKeys(size_t len, const u_char* data) + { + keys.clear(); + keys.reserve(len); + std::copy(data, data + len, std::back_inserter(keys)); } bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label, @@ -152,7 +162,7 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label #ifdef OPENSSL_HAVE_KDF_H // alloc buffers EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); - size_t seed_len = label.length() + rnd1_len + rnd2_len; + size_t seed_len = label.size() + rnd1_len + rnd2_len; std::string seed{}; seed.reserve(seed_len); @@ -166,9 +176,9 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label // FIXME: sha384 should not be hardcoded if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0) goto abort; /* Error */ - if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret.data(), secret.length()) <= 0) + if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret.data(), secret.size()) <= 0) goto abort; /* Error */ - if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.length()) <= 0) + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.size()) <= 0) goto abort; /* Error */ if (EVP_PKEY_derive(pctx, out, &out_len) <= 0) goto abort; /* Error */ @@ -195,16 +205,16 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i } // Neither secret or key present: abort - if ( ( secret == nullptr || secret->Len() == 0 ) && ( keys == nullptr || keys->Len() == 0 ) ) + if ( secret.size() == 0 && keys.size() == 0 ) { DBG_LOG(DBG_ANALYZER, "Could not decrypt packet due to missing keys/secret.\n"); // FIXME: change util function to return a printably std::string for DBG_LOG - //print_hex("->client_random:", handshake_interp->client_random().data(), handshake_interp->client_random().length()); + //print_hex("->client_random:", handshake_interp->client_random().data(), handshake_interp->client_random().size()); return false; } // Secret present, but no keys derived yet: derive keys - if ( secret != nullptr && secret->Len() != 0 && ( keys == nullptr || keys->Len() == 0 ) ) + if ( secret.size() != 0 && keys.size() == 0 ) { #ifdef OPENSSL_HAVE_KDF_H DBG_LOG(DBG_ANALYZER, "Deriving TLS keys for connection foo"); @@ -218,7 +228,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i memcpy(crand, &(ts), 4); memcpy(crand + 4, c_rnd.data(), c_rnd.length()); - auto res = TLS12_PRF(secret->ToStdString(), "key expansion", + auto res = TLS12_PRF(secret, "key expansion", (char*)s_rnd.data(), s_rnd.length(), crand, sizeof(crand), keybuf, sizeof(keybuf)); if ( !res ) { @@ -227,29 +237,36 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i } // save derived keys - SetKeys(keybuf, sizeof(keybuf)); + SetKeys(sizeof(keybuf), keybuf); #else DBG_LOG(DBG_ANALYZER, "Cannot derive TLS keys as Zeek was compiled without "); #endif } // Keys present: decrypt TLS application data - if ( keys != nullptr && keys->Len() == 72 ) + if ( keys.size() == 72 ) { // FIXME: could also print keys or conn id here DBG_LOG(DBG_ANALYZER, "Decrypting application data"); - // session keys & AEAD data + + // client write_key u_char c_wk[32]; + // server write_key u_char s_wk[32]; + // client IV u_char c_iv[4]; + // server IV u_char s_iv[4]; + + // AEAD nonce & tag u_char s_aead_nonce[12]; u_char s_aead_tag[13]; - memcpy(c_wk, keys->Bytes(), 32); - memcpy(s_wk, &(keys->Bytes()[32]), 32); - memcpy(c_iv, &(keys->Bytes()[64]), 4); - memcpy(s_iv, &(keys->Bytes()[68]), 4); + // FIXME: there should be a better way to do these copies + memcpy(c_wk, keys.data(), 32); + memcpy(s_wk, keys.data() + 32, 32); + memcpy(c_iv, keys.data() + 64, 4); + memcpy(s_iv, keys.data() + 68, 4); // FIXME: should we change types here? u_char* encrypted = (u_char*)data; @@ -301,7 +318,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i EVP_DecryptUpdate(ctx, decrypted, &decrypted_len, (const u_char*) encrypted, encrypted_len); int res = 0; - if ( ! (res = EVP_DecryptFinal(ctx, NULL, &res)) ) + if ( ! ( res = EVP_DecryptFinal(ctx, NULL, &res) ) ) { DBG_LOG(DBG_ANALYZER, "Decryption failed with return code: %d. Invalid key?\n", res); EVP_CIPHER_CTX_free(ctx); diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index e4df7a5b55..6a5abe2ce7 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -34,12 +34,92 @@ public: static analyzer::Analyzer* Instantiate(Connection* conn) { return new SSL_Analyzer(conn); } - // Key material for decryption - void SetSecret(const u_char* data, int len); - void SetKeys(const u_char* data, int len); + /** + * Set the secret that should be used to derive keys for the + * connection. (For TLS 1.2 this is the pre-master secret) + * + * @param secret The secret to set + */ + void SetSecret(StringVal* secret); + /** + * Set the secret that should be used to derive keys for the + * connection. (For TLS 1.2 this is the pre-master secret) + * + * @param len Length of the secret bytes + * + * @param data Pointer to the secret bytes + */ + void SetSecret(size_t len, const u_char* data); + + /** + * Set the decryption keys that should be used to decrypt + * TLS application data in the connection. + * + * @param keys The key buffer as derived via TLS PRF (for + * AES_GCM this should be 72 bytes in length) + */ + void SetKeys(StringVal* keys); + + /** + * Set the decryption keys that should be used to decrypt + * TLS application data in the connection. + * + * @param len Length of the key buffer (for AES_GCM this should + * be 72) + * + * @param data Pointer to the key buffer as derived via TLS PRF + */ + void SetKeys(size_t len, const u_char* data); + + /** + * Try to decrypt TLS application data from a packet. Requires secret or keys to be set prior + * + * @param len Length of the encrypted bytes to decrypt + * + * @param data Pointer to the encrypted bytes to decrypt + * + * @param is_orig Direction of the connection + * + * @param content_type Content type as given in the TLS packet + * + * @param raw_tls_version Raw TLS version as given in the TLS packets + */ bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version); + + /** + * TLS 1.2 pseudo random function (PRF) used to expand the pre-master secret and derive keys. + * The seed is obtained by concatinating rnd1 and rnd2 + * + * @param secret Secret as defined in the TLS RFC + * + * @param label Label as defined in the TLS RFC + * + * @param rnd1 Pointer to the first part of the seed + * + * @param rnd1_len Length of the first part of the seed + * + * @param rnd2 Pointer to the second part of the seed + * + * @param rnd2_len Length of the second part of the seed + * + * @param out Pointer to the derived bytes + * + * @param out_len Length indicating how many bytes should be derived + * + * @return True, if the operation completed successfully, false otherwise + */ bool TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1, size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len); + + /** + * Forward decrypted TLS application data to child analyzers + * + * @param len Length of the data to forward + * + * @param data Pointer to the data to forward + * + * @param is_orig Direction of the connection + */ void ForwardDecryptedData(int len, const u_char* data, bool is_orig); protected: @@ -50,8 +130,8 @@ protected: // FIXME: should this be moved into the connection? int c_seq; int s_seq; - StringValPtr secret; - StringValPtr keys; + std::string secret; + std::vector keys; zeek::analyzer::pia::PIA_TCP *pia; }; diff --git a/src/analyzer/protocol/ssl/functions.bif b/src/analyzer/protocol/ssl/functions.bif index b04bf19b3f..19661ad4f3 100644 --- a/src/analyzer/protocol/ssl/functions.bif +++ b/src/analyzer/protocol/ssl/functions.bif @@ -22,7 +22,7 @@ function set_secret%(c: connection, secret: string%): bool analyzer::Analyzer* sa = c->FindAnalyzer("SSL"); if ( sa ) { - static_cast(sa)->SetSecret(secret->Bytes(), secret->Len()); + static_cast(sa)->SetSecret(secret); return zeek::val_mgr->True(); } return zeek::val_mgr->False(); @@ -33,7 +33,7 @@ function set_keys%(c: connection, keys: string%): bool analyzer::Analyzer* sa = c->FindAnalyzer("SSL"); if ( sa ) { - static_cast(sa)->SetKeys(keys->Bytes(), keys->Len()); + static_cast(sa)->SetKeys(keys); return zeek::val_mgr->True(); } return zeek::val_mgr->False(); From 946d74674a3b7862ea53279159c47b69f17ef671 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Fri, 25 Jun 2021 16:04:41 +0200 Subject: [PATCH 012/204] ssl/analyzer: potentially fix memory leaks caused by bytestrings --- src/analyzer/protocol/ssl/tls-handshake-protocol.pac | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/analyzer/protocol/ssl/tls-handshake-protocol.pac b/src/analyzer/protocol/ssl/tls-handshake-protocol.pac index 628dd3da48..b42f292720 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-protocol.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-protocol.pac @@ -959,6 +959,11 @@ refine connection Handshake_Conn += { gmt_unix_time_ = 0; %} + %cleanup{ + client_random_.free(); + server_random_.free(); + %} + function chosen_cipher() : int %{ return chosen_cipher_; %} function set_cipher(cipher: uint32) : bool @@ -995,6 +1000,7 @@ refine connection Handshake_Conn += { function set_client_random(client_random: bytestring) : bool %{ + client_random_.free(); client_random_.init(client_random.data(), client_random.length()); return true; %} @@ -1003,6 +1009,7 @@ refine connection Handshake_Conn += { function set_server_random(server_random: bytestring) : bool %{ + server_random_.free(); server_random_.init(server_random.data(), server_random.length()); return true; %} From 83938682073057dcca0b70fb291eb54edde6c24a Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Thu, 14 Oct 2021 17:45:41 +0200 Subject: [PATCH 013/204] ssl: adapt TLS-PRF to openSSL 3.0 --- src/analyzer/protocol/ssl/SSL.cc | 37 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 5c72751cb8..fd7fc25eec 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -12,7 +12,8 @@ #include #ifdef OPENSSL_HAVE_KDF_H - #include + #include + #include #endif static void print_hex(std::string name, u_char* data, int len) @@ -160,34 +161,32 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label const char* rnd1, size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len) { #ifdef OPENSSL_HAVE_KDF_H - // alloc buffers - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); + // alloc context + params + EVP_KDF *kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); + EVP_KDF_CTX *pctx = EVP_KDF_CTX_new(kdf); + OSSL_PARAM params[4], *p = params; + EVP_KDF_free(kdf); + + // prepare seed: seed = label + rnd1 + rnd2 size_t seed_len = label.size() + rnd1_len + rnd2_len; std::string seed{}; seed.reserve(seed_len); - // seed = label + rnd1 + rnd2 seed.append(label); seed.append(rnd1, rnd1_len); seed.append(rnd2, rnd2_len); - if (EVP_PKEY_derive_init(pctx) <= 0) - goto abort; /* Error */ + // setup OSSL_PARAM array: digest, secret, seed // FIXME: sha384 should not be hardcoded - if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0) - goto abort; /* Error */ - if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret.data(), secret.size()) <= 0) - goto abort; /* Error */ - if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.size()) <= 0) - goto abort; /* Error */ - if (EVP_PKEY_derive(pctx, out, &out_len) <= 0) - goto abort; /* Error */ + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha384, strlen(SN_sha384)); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, (void*)secret.data(), secret.size()); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void*)seed.data(), seed.size()); + *p = OSSL_PARAM_construct_end(); - EVP_PKEY_CTX_free(pctx); - return true; - -abort: - EVP_PKEY_CTX_free(pctx); + // derive key material + bool result = EVP_KDF_derive(pctx, out, out_len, params) <= 0; + EVP_KDF_CTX_free(pctx); + return result; #endif return false; } From eabb6eb743745b44105d6757b046add2ce766383 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 15 Oct 2021 09:13:31 +0100 Subject: [PATCH 014/204] TLS 1.2 decryption: adapt OpenSSL 3.0 changes for 1.1 Now this should compile and work with both OpenSSL 3 and OpenSSL 1.1. --- src/analyzer/protocol/ssl/SSL.cc | 35 ++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index fd7fc25eec..3ab7d63416 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -10,10 +10,14 @@ #include #include +#include #ifdef OPENSSL_HAVE_KDF_H #include - #include +#endif + +#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) +#include #endif static void print_hex(std::string name, u_char* data, int len) @@ -161,11 +165,16 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label const char* rnd1, size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len) { #ifdef OPENSSL_HAVE_KDF_H +#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) // alloc context + params EVP_KDF *kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); EVP_KDF_CTX *pctx = EVP_KDF_CTX_new(kdf); OSSL_PARAM params[4], *p = params; EVP_KDF_free(kdf); +#else /* OSSL 3 */ + // alloc buffers + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); +#endif /* OSSL 3 */ // prepare seed: seed = label + rnd1 + rnd2 size_t seed_len = label.size() + rnd1_len + rnd2_len; @@ -176,6 +185,7 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label seed.append(rnd1, rnd1_len); seed.append(rnd2, rnd2_len); +#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) // setup OSSL_PARAM array: digest, secret, seed // FIXME: sha384 should not be hardcoded *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha384, strlen(SN_sha384)); @@ -187,7 +197,28 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label bool result = EVP_KDF_derive(pctx, out, out_len, params) <= 0; EVP_KDF_CTX_free(pctx); return result; -#endif +#else /* OSSL 3 */ + if (EVP_PKEY_derive_init(pctx) <= 0) + goto abort; /* Error */ + // setup OSSL_PARAM array: digest, secret, seed + // FIXME: sha384 should not be hardcoded + if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret.data(), secret.size()) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.size()) <= 0) + goto abort; /* Error */ + if (EVP_PKEY_derive(pctx, out, &out_len) <= 0) + goto abort; /* Error */ + + EVP_PKEY_CTX_free(pctx); + return true; + +abort: + EVP_PKEY_CTX_free(pctx); +#endif /* OSSL 3 */ + +#endif /* HAVE_KDF */ return false; } From fe4e06e8ca80e3bf98cc7f2dce9fb57495b0db49 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 19 Oct 2021 17:28:59 +0200 Subject: [PATCH 015/204] TLS decryption: remove payload from ssl_encrypted_data again. There is no reason to make the payload available in the event - it is still encrypted. --- scripts/policy/protocols/ssl/decryption.zeek | 2 +- scripts/policy/protocols/ssl/heartbleed.zeek | 2 +- src/analyzer/protocol/ssl/events.bif | 4 +--- src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac | 3 +-- .../scripts.policy.misc.dump-events/really-all-events.log | 2 -- .../btest/scripts/base/protocols/ssl/handshake-events.test | 2 +- testing/btest/scripts/base/protocols/ssl/tls13.test | 2 +- .../base/protocols/ssl/tls13_encrypted_handshake_events.test | 2 +- 8 files changed, 7 insertions(+), 12 deletions(-) diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek index 766bb4d940..a8bb7e52e9 100644 --- a/scripts/policy/protocols/ssl/decryption.zeek +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -77,7 +77,7 @@ event ssl_client_hello(c: connection, version: count, record_version: count, pos } } -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) { if ( c$ssl?$client_random ) { diff --git a/scripts/policy/protocols/ssl/heartbleed.zeek b/scripts/policy/protocols/ssl/heartbleed.zeek index 40bc800b8c..aabafbff14 100644 --- a/scripts/policy/protocols/ssl/heartbleed.zeek +++ b/scripts/policy/protocols/ssl/heartbleed.zeek @@ -223,7 +223,7 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) } } -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) { if ( !c?$ssl ) return; diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 9192babfdf..25bc34398b 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -558,11 +558,9 @@ event ssl_plaintext_data%(c: connection, is_orig: bool, record_version: count, c ## ## length: length of the entire message. ## -## payload: encrypted payload of the SSL/TLS message -## ## .. zeek:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello ## ssl_alert ssl_heartbeat ssl_probable_encrypted_handshake_message -event ssl_encrypted_data%(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string%); +event ssl_encrypted_data%(c: connection, is_orig: bool, record_version: count, content_type: count, length: count%); ## This event is generated for application data records of TLS 1.3 connections of which ## we suspect that they contain handshake messages. diff --git a/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac b/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac index 8cb076ad6b..c3cc45e6ad 100644 --- a/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac @@ -64,8 +64,7 @@ refine connection SSL_Conn += { if ( ssl_encrypted_data ) { zeek::BifEvent::enqueue_ssl_encrypted_data(zeek_analyzer(), - zeek_analyzer()->Conn(), ${rec.is_orig}, ${rec.raw_tls_version}, ${rec.content_type}, ${rec.length}, - zeek::make_intrusive(cont.length(), (const char*) cont.data())); + zeek_analyzer()->Conn(), ${rec.is_orig}, ${rec.raw_tls_version}, ${rec.content_type}, ${rec.length}); if (rec->content_type() == APPLICATION_DATA) { zeek_analyzer()->TryDecryptApplicationData(cont.length(), cont.data(), rec->is_orig(), rec->content_type(), rec->raw_tls_version()); diff --git a/testing/btest/Baseline/scripts.policy.misc.dump-events/really-all-events.log b/testing/btest/Baseline/scripts.policy.misc.dump-events/really-all-events.log index a2360dbd29..3836b0306c 100644 --- a/testing/btest/Baseline/scripts.policy.misc.dump-events/really-all-events.log +++ b/testing/btest/Baseline/scripts.policy.misc.dump-events/really-all-events.log @@ -9079,7 +9079,6 @@ XXXXXXXXXX.XXXXXX ssl_encrypted_data [2] record_version: count = 771 [3] content_type: count = 22 [4] length: count = 32 - [5] payload: string = \x1c\x1c\x84S/9\x14e\xb6'\xe5,\x03\x0fY\xdf\x1b\xcfu\xc84\xae\x1a"\xea]9j'\xbeZ\xa7 XXXXXXXXXX.XXXXXX raw_packet [0] p: raw_pkt_hdr = [l2=[encap=LINK_ETHERNET, len=91, cap_len=91, src=58:b0:35:86:54:8d, dst=cc:b2:55:f4:62:92, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=77, id=51331, ttl=64, p=6, src=192.168.133.100, dst=17.167.150.73], ip6=, tcp=[sport=49655/tcp, dport=443/tcp, seq=3289393854, ack=2319612745, hl=20, dl=37, reserved=0, flags=24, win=8192], udp=, icmp=] @@ -9177,7 +9176,6 @@ XXXXXXXXXX.XXXXXX ssl_encrypted_data [2] record_version: count = 771 [3] content_type: count = 22 [4] length: count = 32 - [5] payload: string = Z\x99\x17~d\x06\xbd;\xb4\xdf\xe2\xb3~9,|\xac\xdb\xb4\xeb\xcc\x95.\x17\xd2Q\x8a\x96\xdb\x13\x09! XXXXXXXXXX.XXXXXX raw_packet [0] p: raw_pkt_hdr = [l2=[encap=LINK_ETHERNET, len=97, cap_len=97, src=cc:b2:55:f4:62:92, dst=58:b0:35:86:54:8d, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=83, id=50807, ttl=243, p=6, src=17.167.150.73, dst=192.168.133.100], ip6=, tcp=[sport=443/tcp, dport=49655/tcp, seq=2319612745, ack=3289393891, hl=20, dl=43, reserved=0, flags=24, win=3626], udp=, icmp=] diff --git a/testing/btest/scripts/base/protocols/ssl/handshake-events.test b/testing/btest/scripts/base/protocols/ssl/handshake-events.test index 0c694bfaa1..0b45bebc02 100644 --- a/testing/btest/scripts/base/protocols/ssl/handshake-events.test +++ b/testing/btest/scripts/base/protocols/ssl/handshake-events.test @@ -27,7 +27,7 @@ event ssl_plaintext_data(c: connection, is_orig: bool, record_version: count, co print "Plaintext data", c$id$orig_h, c$id$resp_h, is_orig, SSL::version_strings[record_version], content_type, length; } -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) { print "Encrypted data", c$id$orig_h, c$id$resp_h, is_orig, SSL::version_strings[record_version], content_type, length; } diff --git a/testing/btest/scripts/base/protocols/ssl/tls13.test b/testing/btest/scripts/base/protocols/ssl/tls13.test index f1f03cd5df..875149ce80 100644 --- a/testing/btest/scripts/base/protocols/ssl/tls13.test +++ b/testing/btest/scripts/base/protocols/ssl/tls13.test @@ -37,7 +37,7 @@ event ssl_established(c: connection) print "established", c$id; } -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) { print "encrypted", c$id, is_orig, SSL::version_strings[record_version], content_type; } diff --git a/testing/btest/scripts/base/protocols/ssl/tls13_encrypted_handshake_events.test b/testing/btest/scripts/base/protocols/ssl/tls13_encrypted_handshake_events.test index 08936cee56..3293315723 100644 --- a/testing/btest/scripts/base/protocols/ssl/tls13_encrypted_handshake_events.test +++ b/testing/btest/scripts/base/protocols/ssl/tls13_encrypted_handshake_events.test @@ -6,7 +6,7 @@ redef SSL::disable_analyzer_after_detection=F; -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count, payload: string) +event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) { print "encrypted", c$id, is_orig, SSL::version_strings[record_version], content_type; } From cc9e38f58b5909617b3fc41856ff8feda59622d2 Mon Sep 17 00:00:00 2001 From: Florian Wilkens Date: Fri, 5 Nov 2021 15:57:43 +0100 Subject: [PATCH 016/204] add missing call to EVP_KDF_CTX_set_params --- src/analyzer/protocol/ssl/SSL.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 3ab7d63416..cee214fe8f 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -168,7 +168,7 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) // alloc context + params EVP_KDF *kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); - EVP_KDF_CTX *pctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); OSSL_PARAM params[4], *p = params; EVP_KDF_free(kdf); #else /* OSSL 3 */ @@ -193,14 +193,23 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void*)seed.data(), seed.size()); *p = OSSL_PARAM_construct_end(); + // set OSSL params + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) + goto abort; // derive key material - bool result = EVP_KDF_derive(pctx, out, out_len, params) <= 0; - EVP_KDF_CTX_free(pctx); - return result; + if (EVP_KDF_derive(kctx, out, out_len, NULL) <= 0) + goto abort; + + EVP_KDF_CTX_free(kctx); + return true; + +abort: + EVP_KDF_CTX_free(kctx); + return false; #else /* OSSL 3 */ if (EVP_PKEY_derive_init(pctx) <= 0) goto abort; /* Error */ - // setup OSSL_PARAM array: digest, secret, seed + // setup PKEY params: digest, secret, seed // FIXME: sha384 should not be hardcoded if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0) goto abort; /* Error */ From 56f30b500aa23cde7edb041cf6f21776ded74cd8 Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Mon, 20 Dec 2021 08:16:21 +0100 Subject: [PATCH 017/204] Update to latest Broker without public CAF dep --- CMakeLists.txt | 46 +---- auxil/broker | 2 +- src/Func.h | 7 +- src/OpaqueVal.cc | 44 ++-- src/Val.cc | 10 +- src/broker/Data.cc | 66 +++--- src/broker/Data.h | 6 +- src/broker/Manager.cc | 107 +++------- src/broker/Manager.h | 5 - src/broker/Store.h | 4 +- src/broker/data.bif | 4 +- src/file_analysis/analyzer/x509/X509.cc | 2 +- src/logging/WriterBackend.cc | 20 +- src/probabilistic/BitVector.cc | 8 +- src/probabilistic/BloomFilter.cc | 4 +- src/probabilistic/CardinalityCounter.cc | 10 +- src/probabilistic/CounterVector.cc | 4 +- src/probabilistic/Hasher.cc | 10 +- src/probabilistic/Topk.cc | 16 +- src/telemetry/CMakeLists.txt | 4 - src/telemetry/Counter.cc | 77 ------- src/telemetry/Counter.h | 58 +++--- src/telemetry/Detail.h | 259 ------------------------ src/telemetry/Gauge.cc | 102 ---------- src/telemetry/Gauge.h | 73 ++++--- src/telemetry/Histogram.cc | 102 ---------- src/telemetry/Histogram.h | 67 +++--- src/telemetry/Manager.cc | 125 +++--------- src/telemetry/Manager.h | 69 ++++--- src/telemetry/MetricFamily.cc | 54 ----- src/telemetry/MetricFamily.h | 25 ++- src/zeek-setup.cc | 2 +- 32 files changed, 328 insertions(+), 1064 deletions(-) delete mode 100644 src/telemetry/Counter.cc delete mode 100644 src/telemetry/Detail.h delete mode 100644 src/telemetry/Gauge.cc delete mode 100644 src/telemetry/Histogram.cc delete mode 100644 src/telemetry/MetricFamily.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 494cb2efa2..e934481023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -321,36 +321,15 @@ if ( PYTHON_VERSION_STRING VERSION_LESS ${ZEEK_PYTHON_MIN} ) message(FATAL_ERROR "Python ${ZEEK_PYTHON_MIN} or greater is required.") endif () -if ( CAF_ROOT OR BROKER_ROOT_DIR ) - # TODO: drop < 3.12 compatibility check when raising the minimum CMake version - if ( CAF_ROOT AND CMAKE_VERSION VERSION_LESS 3.12 ) - find_package(CAF ${CAF_VERSION_MIN_REQUIRED} REQUIRED - COMPONENTS openssl test io core - PATHS "${CAF_ROOT}") - else () - find_package(CAF ${CAF_VERSION_MIN_REQUIRED} REQUIRED - COMPONENTS openssl test io core) - endif () - message(STATUS "Using system CAF version ${CAF_VERSION}") - # TODO: drop these legacy variables and simply use the targets consistently - set(CAF_LIBRARIES CAF::core CAF::io CAF::openssl CACHE INTERNAL "") - set(caf_dirs "") - foreach (caf_lib IN LISTS CAF_LIBRARIES ITEMS CAF::test) - get_target_property(dirs ${caf_lib} INTERFACE_INCLUDE_DIRECTORIES) - if ( dirs ) - list(APPEND caf_dirs ${dirs}) - endif () - endforeach () - list(REMOVE_DUPLICATES caf_dirs) - list(GET caf_dirs 0 caf_dir) - set(CAF_INCLUDE_DIRS "${caf_dirs}" CACHE INTERNAL "") -endif () - add_subdirectory(auxil/paraglob) set(zeekdeps ${zeekdeps} paraglob) -if ( BROKER_ROOT_DIR ) - find_package(Broker REQUIRED) +if ( Broker_ROOT ) + find_package(Broker REQUIRED PATHS "${Broker_ROOT}") + set(zeekdeps ${zeekdeps} ${BROKER_LIBRARY}) + set(broker_includes ${BROKER_INCLUDE_DIR}) +elseif ( BROKER_ROOT_DIR ) + find_package(Broker REQUIRED PATHS "${BROKER_ROOT_DIR}") set(zeekdeps ${zeekdeps} ${BROKER_LIBRARY}) set(broker_includes ${BROKER_INCLUDE_DIR}) else () @@ -375,11 +354,6 @@ else () set(broker_includes ${CMAKE_CURRENT_SOURCE_DIR}/auxil/broker/include ${CMAKE_CURRENT_BINARY_DIR}/auxil/broker/include) endif () -# CAF_LIBRARIES and CAF_INCLUDE_DIRS are defined either by calling -# find_package(CAF) or by calling add_subdirectory(auxil/broker). In either case, -# we have to care about CAF here because Broker headers can pull in CAF -# headers. -set(zeekdeps ${zeekdeps} ${CAF_LIBRARIES}) include_directories(BEFORE ${PCAP_INCLUDE_DIR} ${BIND_INCLUDE_DIR} @@ -452,7 +426,7 @@ endif () # Any headers that are possibly bundled in the Zeek source-tree and that are supposed # to have priority over any pre-existing/system-wide headers need to appear early in # compiler search path. -include_directories(BEFORE ${broker_includes} ${CAF_INCLUDE_DIRS}) +include_directories(BEFORE ${broker_includes}) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/auxil/highwayhash) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/auxil/paraglob/include) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/auxil/rapidjson/include) @@ -512,12 +486,6 @@ execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "." "${CMAKE_CURRENT_BINARY_DIR}/zeek") -if ( CAF_ROOT ) - set(ZEEK_CONFIG_CAF_ROOT_DIR ${CAF_ROOT}) -else () - set(ZEEK_CONFIG_CAF_ROOT_DIR ${ZEEK_ROOT_DIR}) -endif () - if ( BinPAC_ROOT_DIR ) set(ZEEK_CONFIG_BINPAC_ROOT_DIR ${BinPAC_ROOT_DIR}) else () diff --git a/auxil/broker b/auxil/broker index 36339ad8c9..ce321c0a90 160000 --- a/auxil/broker +++ b/auxil/broker @@ -1 +1 @@ -Subproject commit 36339ad8c9844f1758f8e9d0da4645047f480c34 +Subproject commit ce321c0a90f1d4176796c996fd27fe69ea520316 diff --git a/src/Func.h b/src/Func.h index 713a34fb67..d3bae45d01 100644 --- a/src/Func.h +++ b/src/Func.h @@ -18,16 +18,11 @@ #include "zeek/ZeekArgs.h" #include "zeek/ZeekList.h" -namespace caf - { -template class expected; - } - namespace broker { class data; using vector = std::vector; -using caf::expected; +template class expected; } namespace zeek diff --git a/src/OpaqueVal.cc b/src/OpaqueVal.cc index e18d6e7e28..f39c1933a4 100644 --- a/src/OpaqueVal.cc +++ b/src/OpaqueVal.cc @@ -33,7 +33,7 @@ inline bool get_vector_idx(const V& v, unsigned int i, D* dst) if ( i >= v.size() ) return false; - auto x = caf::get_if(&v[i]); + auto x = broker::get_if(&v[i]); if ( ! x ) return false; @@ -81,12 +81,12 @@ broker::expected OpaqueVal::Serialize() const OpaqueValPtr OpaqueVal::Unserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() == 2) ) return nullptr; - auto type = caf::get_if(&(*v)[0]); + auto type = broker::get_if(&(*v)[0]); if ( ! type ) return nullptr; @@ -118,17 +118,17 @@ broker::expected OpaqueVal::SerializeType(const TypePtr& t) TypePtr OpaqueVal::UnserializeType(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() == 2) ) return nullptr; - auto by_name = caf::get_if(&(*v)[0]); + auto by_name = broker::get_if(&(*v)[0]); if ( ! by_name ) return nullptr; if ( *by_name ) { - auto name = caf::get_if(&(*v)[1]); + auto name = broker::get_if(&(*v)[1]); if ( ! name ) return nullptr; @@ -142,7 +142,7 @@ TypePtr OpaqueVal::UnserializeType(const broker::data& data) return id->GetType(); } - auto tag = caf::get_if(&(*v)[1]); + auto tag = broker::get_if(&(*v)[1]); if ( ! tag ) return nullptr; @@ -295,11 +295,11 @@ broker::expected MD5Val::DoSerialize() const bool MD5Val::DoUnserialize(const broker::data& data) { - auto d = caf::get_if(&data); + auto d = broker::get_if(&data); if ( ! d ) return false; - auto valid = caf::get_if(&(*d)[0]); + auto valid = broker::get_if(&(*d)[0]); if ( ! valid ) return false; @@ -312,7 +312,7 @@ bool MD5Val::DoUnserialize(const broker::data& data) if ( (*d).size() != 2 ) return false; - auto s = caf::get_if(&(*d)[1]); + auto s = broker::get_if(&(*d)[1]); if ( ! s ) return false; @@ -385,11 +385,11 @@ broker::expected SHA1Val::DoSerialize() const bool SHA1Val::DoUnserialize(const broker::data& data) { - auto d = caf::get_if(&data); + auto d = broker::get_if(&data); if ( ! d ) return false; - auto valid = caf::get_if(&(*d)[0]); + auto valid = broker::get_if(&(*d)[0]); if ( ! valid ) return false; @@ -402,7 +402,7 @@ bool SHA1Val::DoUnserialize(const broker::data& data) if ( (*d).size() != 2 ) return false; - auto s = caf::get_if(&(*d)[1]); + auto s = broker::get_if(&(*d)[1]); if ( ! s ) return false; @@ -475,11 +475,11 @@ broker::expected SHA256Val::DoSerialize() const bool SHA256Val::DoUnserialize(const broker::data& data) { - auto d = caf::get_if(&data); + auto d = broker::get_if(&data); if ( ! d ) return false; - auto valid = caf::get_if(&(*d)[0]); + auto valid = broker::get_if(&(*d)[0]); if ( ! valid ) return false; @@ -492,7 +492,7 @@ bool SHA256Val::DoUnserialize(const broker::data& data) if ( (*d).size() != 2 ) return false; - auto s = caf::get_if(&(*d)[1]); + auto s = broker::get_if(&(*d)[1]); if ( ! s ) return false; @@ -546,7 +546,7 @@ broker::expected EntropyVal::DoSerialize() const bool EntropyVal::DoUnserialize(const broker::data& data) { - auto d = caf::get_if(&data); + auto d = broker::get_if(&data); if ( ! d ) return false; @@ -728,12 +728,12 @@ broker::expected BloomFilterVal::DoSerialize() const bool BloomFilterVal::DoUnserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() == 2) ) return false; - auto no_type = caf::get_if(&(*v)[0]); + auto no_type = broker::get_if(&(*v)[0]); if ( ! no_type ) { auto t = UnserializeType((*v)[0]); @@ -822,12 +822,12 @@ broker::expected CardinalityVal::DoSerialize() const bool CardinalityVal::DoUnserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() == 2) ) return false; - auto no_type = caf::get_if(&(*v)[0]); + auto no_type = broker::get_if(&(*v)[0]); if ( ! no_type ) { auto t = UnserializeType((*v)[0]); @@ -879,7 +879,7 @@ broker::expected ParaglobVal::DoSerialize() const bool ParaglobVal::DoUnserialize(const broker::data& data) { - auto d = caf::get_if(&data); + auto d = broker::get_if(&data); if ( ! d ) return false; diff --git a/src/Val.cc b/src/Val.cc index 3ad6169149..7c89f28c41 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -2145,15 +2145,7 @@ void TableVal::SendToStore(const Val* index, const TableEntryVal* new_entry_val, case ELEMENT_NEW: case ELEMENT_CHANGED: { -#ifndef __clang__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - broker::optional expiry; -#ifndef __clang__ -#pragma GCC diagnostic pop -#endif - + std::optional expiry; auto expire_time = GetExpireTime(); if ( expire_time == 0 ) // Entry is set to immediately expire. Let's not forward it. diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 80651fc822..84c59d3700 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -226,7 +226,7 @@ struct val_converter { const auto& expected_index_types = tt->GetIndices()->GetTypes(); broker::vector composite_key; - auto indices = caf::get_if(&item); + auto indices = get_if(&item); if ( indices ) { @@ -281,7 +281,7 @@ struct val_converter { const auto& expected_index_types = tt->GetIndices()->GetTypes(); broker::vector composite_key; - auto indices = caf::get_if(&item.first); + auto indices = get_if(&item.first); if ( indices ) { @@ -446,7 +446,7 @@ struct val_converter if ( idx >= a.size() ) return nullptr; - if ( caf::get_if(&a[idx]) != nullptr ) + if ( get_if(&a[idx]) != nullptr ) { rval->Remove(i); ++idx; @@ -469,8 +469,8 @@ struct val_converter if ( a.size() != 2 ) return nullptr; - auto exact_text = caf::get_if(&a[0]); - auto anywhere_text = caf::get_if(&a[1]); + auto exact_text = get_if(&a[0]); + auto anywhere_text = get_if(&a[1]); if ( ! exact_text || ! anywhere_text ) return nullptr; @@ -606,7 +606,7 @@ struct type_checker for ( const auto& item : a ) { const auto& expected_index_types = tt->GetIndices()->GetTypes(); - auto indices = caf::get_if(&item); + auto indices = get_if(&item); vector indices_to_check; if ( indices ) @@ -663,7 +663,7 @@ struct type_checker for ( auto& item : a ) { const auto& expected_index_types = tt->GetIndices()->GetTypes(); - auto indices = caf::get_if(&item.first); + auto indices = get_if(&item.first); vector indices_to_check; if ( indices ) @@ -765,7 +765,7 @@ struct type_checker if ( idx >= a.size() ) return false; - if ( caf::get_if(&a[idx]) != nullptr ) + if ( get_if(&a[idx]) != nullptr ) { ++idx; continue; @@ -784,8 +784,8 @@ struct type_checker if ( a.size() != 2 ) return false; - auto exact_text = caf::get_if(&a[0]); - auto anywhere_text = caf::get_if(&a[1]); + auto exact_text = get_if(&a[0]); + auto anywhere_text = get_if(&a[1]); if ( ! exact_text || ! anywhere_text ) return false; @@ -820,7 +820,7 @@ static bool data_type_check(const broker::data& d, Type* t) if ( t->Tag() == TYPE_ANY ) return true; - return caf::visit(type_checker{t}, d); + return visit(type_checker{t}, d); } ValPtr data_to_val(broker::data d, Type* type) @@ -828,7 +828,7 @@ ValPtr data_to_val(broker::data d, Type* type) if ( type->Tag() == TYPE_ANY ) return make_data_val(move(d)); - return caf::visit(val_converter{type}, std::move(d)); + return visit(val_converter{type}, d); } broker::expected val_to_data(const Val* v) @@ -961,7 +961,7 @@ broker::expected val_to_data(const Val* v) key = move(composite_key); if ( is_set ) - caf::get(rval).emplace(move(key)); + get(rval).emplace(move(key)); else { auto val = val_to_data(entry->GetVal().get()); @@ -969,7 +969,7 @@ broker::expected val_to_data(const Val* v) if ( ! val ) return broker::ec::invalid_data; - caf::get(rval).emplace(move(key), move(*val)); + get(rval).emplace(move(key), move(*val)); } } @@ -1180,7 +1180,7 @@ struct data_type_getter EnumValPtr get_data_type(RecordVal* v, zeek::detail::Frame* frame) { - return caf::visit(data_type_getter{}, opaque_field_to_data(v, frame)); + return visit(data_type_getter{}, opaque_field_to_data(v, frame)); } broker::data& opaque_field_to_data(RecordVal* v, zeek::detail::Frame* f) @@ -1240,11 +1240,11 @@ broker::expected SetIterator::DoSerialize() const bool SetIterator::DoUnserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = get_if(&data); if ( ! (v && v->size() == 2) ) return false; - auto x = caf::get_if(&(*v)[0]); + auto x = get_if(&(*v)[0]); // We set the iterator by finding the element it used to point to. // This is not perfect, as there's no guarantee that the restored @@ -1267,11 +1267,11 @@ broker::expected TableIterator::DoSerialize() const bool TableIterator::DoUnserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = get_if(&data); if ( ! (v && v->size() == 2) ) return false; - auto x = caf::get_if(&(*v)[0]); + auto x = get_if(&(*v)[0]); // We set the iterator by finding the element it used to point to. // This is not perfect, as there's no guarantee that the restored @@ -1295,12 +1295,12 @@ broker::expected VectorIterator::DoSerialize() const bool VectorIterator::DoUnserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = get_if(&data); if ( ! (v && v->size() == 2) ) return false; - auto x = caf::get_if(&(*v)[0]); - auto y = caf::get_if(&(*v)[1]); + auto x = get_if(&(*v)[0]); + auto y = get_if(&(*v)[1]); if ( ! (x && y) ) return false; @@ -1320,12 +1320,12 @@ broker::expected RecordIterator::DoSerialize() const bool RecordIterator::DoUnserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = get_if(&data); if ( ! (v && v->size() == 2) ) return false; - auto x = caf::get_if(&(*v)[0]); - auto y = caf::get_if(&(*v)[1]); + auto x = get_if(&(*v)[0]); + auto y = get_if(&(*v)[1]); if ( ! (x && y) ) return false; @@ -1352,25 +1352,25 @@ broker::data threading_field_to_data(const threading::Field* f) threading::Field* data_to_threading_field(broker::data d) { - if ( ! caf::holds_alternative(d) ) + if ( ! holds_alternative(d) ) return nullptr; - auto& v = caf::get(d); - auto name = caf::get_if(&v[0]); + auto& v = get(d); + auto name = get_if(&v[0]); auto secondary = v[1]; - auto type = caf::get_if(&v[2]); - auto subtype = caf::get_if(&v[3]); - auto optional = caf::get_if(&v[4]); + auto type = get_if(&v[2]); + auto subtype = get_if(&v[3]); + auto optional = get_if(&v[4]); if ( ! (name && type && subtype && optional) ) return nullptr; - if ( secondary != broker::nil && ! caf::holds_alternative(secondary) ) + if ( secondary != broker::nil && ! holds_alternative(secondary) ) return nullptr; return new threading::Field( name->c_str(), - secondary != broker::nil ? caf::get(secondary).c_str() : nullptr, + secondary != broker::nil ? get(secondary).c_str() : nullptr, static_cast(*type), static_cast(*subtype), *optional); } diff --git a/src/broker/Data.h b/src/broker/Data.h index b948f3744c..3335adf4b2 100644 --- a/src/broker/Data.h +++ b/src/broker/Data.h @@ -5,6 +5,8 @@ #include "zeek/OpaqueVal.h" #include "zeek/Reporter.h" +#include "broker/data.hh" + namespace zeek { @@ -181,10 +183,10 @@ broker::data& opaque_field_to_data(zeek::RecordVal* v, zeek::detail::Frame* f); template T& require_data_type(broker::data& d, zeek::TypeTag tag, zeek::detail::Frame* f) { - auto ptr = caf::get_if(&d); + auto ptr = broker::get_if(&d); if ( ! ptr ) zeek::reporter->RuntimeError(f->GetCallLocation(), "data is of type '%s' not of type '%s'", - caf::visit(type_name_getter{tag}, d), zeek::type_name(tag)); + visit(type_name_getter{tag}, d), zeek::type_name(tag)); return *ptr; } diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index d4a8445c37..babf719d3e 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -1,6 +1,7 @@ #include "zeek/broker/Manager.h" #include +#include #include #include #include @@ -90,10 +91,10 @@ namespace struct opt_mapping { broker::configuration* cfg; - std::string_view broker_name; + std::string broker_name; const char* zeek_name; - template auto broker_read() { return caf::get_as(*cfg, broker_name); } + template auto broker_read() { return broker::get_as(*cfg, broker_name); } template auto broker_write(T&& val) { cfg->set(broker_name, std::forward(val)); } @@ -107,23 +108,10 @@ struct opt_mapping } // namespace -class BrokerConfig : public broker::configuration - { -public: - BrokerConfig(broker::broker_options options) : broker::configuration(options) - { - openssl_cafile = get_option("Broker::ssl_cafile")->AsString()->CheckString(); - openssl_capath = get_option("Broker::ssl_capath")->AsString()->CheckString(); - openssl_certificate = get_option("Broker::ssl_certificate")->AsString()->CheckString(); - openssl_key = get_option("Broker::ssl_keyfile")->AsString()->CheckString(); - openssl_passphrase = get_option("Broker::ssl_passphrase")->AsString()->CheckString(); - } - }; - class BrokerState { public: - BrokerState(BrokerConfig config, size_t congestion_queue_size) + BrokerState(broker::configuration config, size_t congestion_queue_size) : endpoint(std::move(config)), subscriber(endpoint.make_subscriber({broker::topic::statuses(), broker::topic::errors()}, congestion_queue_size)) @@ -238,7 +226,13 @@ void Manager::InitPostScript() options.forward = get_option("Broker::forward_messages")->AsBool(); options.use_real_time = use_real_time; - BrokerConfig config{std::move(options)}; + broker::configuration config{std::move(options)}; + + config.openssl_cafile(get_option("Broker::ssl_cafile")->AsString()->CheckString()); + config.openssl_capath(get_option("Broker::ssl_capath")->AsString()->CheckString()); + config.openssl_certificate(get_option("Broker::ssl_certificate")->AsString()->CheckString()); + config.openssl_key(get_option("Broker::ssl_keyfile")->AsString()->CheckString()); + config.openssl_passphrase(get_option("Broker::ssl_passphrase")->AsString()->CheckString()); auto scheduler_policy = get_option("Broker::scheduler_policy")->AsString()->CheckString(); @@ -257,11 +251,11 @@ void Manager::InitPostScript() config.set("caf.scheduler.max-threads", get_option("Broker::max_threads")->AsCount()); config.set("caf.work-stealing.moderate-sleep-duration", - caf::timespan(static_cast( + broker::timespan(static_cast( get_option("Broker::moderate_sleep")->AsInterval() * 1e9))); config.set("caf.work-stealing.relaxed-sleep-duration", - caf::timespan( + broker::timespan( static_cast(get_option("Broker::relaxed_sleep")->AsInterval() * 1e9))); config.set("caf.work-stealing.aggressive-poll-attempts", @@ -363,6 +357,8 @@ void Manager::InitPostScript() bstate->subscriber.add_topic(broker::topic::store_events(), true); + telemetry_mgr->InitPostBrokerSetup(bstate->endpoint); + InitializeBrokerStoreForwarding(); } @@ -1030,7 +1026,7 @@ void Manager::DispatchMessage(const broker::topic& topic, broker::data msg) if ( ! batch.valid() ) { reporter->Warning("received invalid broker Batch: %s", - broker::to_string(batch).data()); + broker::to_string(batch.as_data()).data()); return; } @@ -1376,7 +1372,8 @@ bool Manager::ProcessLogCreate(broker::zeek::LogCreate lc) DBG_LOG(DBG_BROKER, "Received log-create: %s", RenderMessage(lc.as_data()).c_str()); if ( ! lc.valid() ) { - reporter->Warning("received invalid broker LogCreate: %s", broker::to_string(lc).data()); + reporter->Warning("received invalid broker LogCreate: %s", + broker::to_string(lc.as_data()).data()); return false; } @@ -1402,7 +1399,7 @@ bool Manager::ProcessLogCreate(broker::zeek::LogCreate lc) } // Get log fields. - auto fields_data = caf::get_if(&lc.fields_data()); + auto fields_data = get_if(&lc.fields_data()); if ( ! fields_data ) { @@ -1442,7 +1439,8 @@ bool Manager::ProcessLogWrite(broker::zeek::LogWrite lw) if ( ! lw.valid() ) { - reporter->Warning("received invalid broker LogWrite: %s", broker::to_string(lw).data()); + reporter->Warning("received invalid broker LogWrite: %s", + broker::to_string(lw.as_data()).data()); return false; } @@ -1467,7 +1465,7 @@ bool Manager::ProcessLogWrite(broker::zeek::LogWrite lw) return false; } - auto path = caf::get_if(&lw.path()); + auto path = get_if(&lw.path()); if ( ! path ) { @@ -1476,7 +1474,7 @@ bool Manager::ProcessLogWrite(broker::zeek::LogWrite lw) return false; } - auto serial_data = caf::get_if(&lw.serial_data()); + auto serial_data = get_if(&lw.serial_data()); if ( ! serial_data ) { @@ -1531,7 +1529,7 @@ bool Manager::ProcessIdentifierUpdate(broker::zeek::IdentifierUpdate iu) if ( ! iu.valid() ) { reporter->Warning("received invalid broker IdentifierUpdate: %s", - broker::to_string(iu).data()); + broker::to_string(iu.as_data()).data()); return false; } @@ -1655,12 +1653,12 @@ void Manager::ProcessError(broker::error_view err) if ( auto ctx = err.context() ) { msg += '('; - msg += to_string(ctx->node); + msg += broker::to_string(ctx->node); msg += ", "; - msg += caf::deep_to_string(ctx->network); + msg += broker::to_string(ctx->network); msg += ", "; if ( auto what = err.message() ) - msg += caf::deep_to_string(*what); + msg += *what; else msg += R"_("")_"; msg += ')'; @@ -1783,7 +1781,7 @@ void Manager::BrokerStoreToZeekTable(const std::string& name, const detail::Stor if ( ! keys ) return; - auto set = caf::get_if(&(keys->get_data())); + auto set = get_if(&(keys->get_data())); auto table = handle->forward_to; const auto& its = table->GetType()->AsTableType()->GetIndexTypes(); bool is_set = table->GetType()->IsSet(); @@ -1982,53 +1980,4 @@ void Manager::SetMetricsExportPrefixes(std::vector filter) bstate->endpoint.metrics_exporter().set_prefixes(std::move(filter)); } -std::unique_ptr Manager::NewTelemetryManager() - { - // The telemetry Manager actually only has a dependency on the actor system, - // not to the Broker Manager. By having the telemetry Manager hold on to a - // shared_ptr to our Broker state, we make sure the Broker endpoint, which - // owns the CAF actor system, lives for as long as necessary. This also - // makes sure that the Broker Manager may even get destroyed before the - // telemetry Manager. - struct TM final : public telemetry::Manager - { - using MetricRegistryPtr = std::unique_ptr; - - static auto getPimpl(BrokerState& st) - { - auto registry = std::addressof(st.endpoint.system().metrics()); - return reinterpret_cast(registry); - } - - static auto getPimpl(MetricRegistryPtr& ptr) - { - return reinterpret_cast(ptr.get()); - } - - explicit TM(Broker::Manager* parent, MetricRegistryPtr ptr) - : telemetry::Manager(getPimpl(ptr)), parent(parent), tmp(std::move(ptr)) - { - assert(tmp != nullptr); - assert(parent != nullptr); - } - - void InitPostScript() override - { - assert(parent->bstate != nullptr); - ptr = parent->bstate; - auto registry = std::addressof(ptr->endpoint.system().metrics()); - registry->merge(*tmp); - tmp.reset(); - pimpl = reinterpret_cast(registry); - } - - Broker::Manager* parent; - MetricRegistryPtr tmp; - std::shared_ptr ptr; - }; - - auto tmp = std::make_unique(); - return std::make_unique(this, std::move(tmp)); - } - } // namespace zeek::Broker diff --git a/src/broker/Manager.h b/src/broker/Manager.h index 867180e7e9..0c1bcd0232 100644 --- a/src/broker/Manager.h +++ b/src/broker/Manager.h @@ -396,11 +396,6 @@ public: */ void SetMetricsExportPrefixes(std::vector filter); - /** - * Allocates a new manager for telemetry data. - */ - std::unique_ptr NewTelemetryManager(); - private: void DispatchMessage(const broker::topic& topic, broker::data msg); // Process events used for Broker store backed zeek tables diff --git a/src/broker/Store.h b/src/broker/Store.h index b81eec89cc..70cba682b6 100644 --- a/src/broker/Store.h +++ b/src/broker/Store.h @@ -52,9 +52,9 @@ inline RecordValPtr query_result(RecordValPtr data) * @param e: expire interval as double; 0 if no expiry * @return expire interval in Broker format */ -static broker::optional convert_expiry(double e) +static std::optional convert_expiry(double e) { - broker::optional ts; + std::optional ts; if ( e ) { diff --git a/src/broker/data.bif b/src/broker/data.bif index f671702bf2..85b34aa991 100644 --- a/src/broker/data.bif +++ b/src/broker/data.bif @@ -471,7 +471,7 @@ function Broker::__record_lookup%(r: Broker::Data, idx: count%): Broker::Data auto& v = zeek::Broker::detail::require_data_type(r->AsRecordVal(), zeek::TYPE_RECORD, frame); - if ( idx >= v.size() || caf::get_if(&v[idx]) ) + if ( idx >= v.size() || broker::get_if(&v[idx]) ) return zeek::make_intrusive(zeek::BifType::Record::Broker::Data); return zeek::Broker::detail::make_data_val(v[idx]); @@ -510,7 +510,7 @@ function Broker::__record_iterator_value%(it: opaque of Broker::RecordIterator%) return rval; } - if ( caf::get_if(&(*ri->it)) ) + if ( broker::get_if(&(*ri->it)) ) return rval; // field isn't set rval->Assign(0, zeek::make_intrusive(*ri->it)); diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index e5841cca33..29e5d951a8 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -623,7 +623,7 @@ broker::expected X509Val::DoSerialize() const bool X509Val::DoUnserialize(const broker::data& data) { - auto s = caf::get_if(&data); + auto s = broker::get_if(&data); if ( ! s ) return false; diff --git a/src/logging/WriterBackend.cc b/src/logging/WriterBackend.cc index 33c8d5e23c..e0aae0db8f 100644 --- a/src/logging/WriterBackend.cc +++ b/src/logging/WriterBackend.cc @@ -100,16 +100,16 @@ broker::data WriterBackend::WriterInfo::ToBroker() const bool WriterBackend::WriterInfo::FromBroker(broker::data d) { - if ( ! caf::holds_alternative(d) ) + if ( ! broker::is(d) ) return false; - auto v = caf::get(d); - auto bpath = caf::get_if(&v[0]); - auto brotation_base = caf::get_if(&v[1]); - auto brotation_interval = caf::get_if(&v[2]); - auto bnetwork_time = caf::get_if(&v[3]); - auto bconfig = caf::get_if(&v[4]); - auto bppf = caf::get_if(&v[5]); + auto v = broker::get(d); + auto bpath = broker::get_if(&v[0]); + auto brotation_base = broker::get_if(&v[1]); + auto brotation_interval = broker::get_if(&v[2]); + auto bnetwork_time = broker::get_if(&v[3]); + auto bconfig = broker::get_if(&v[4]); + auto bppf = broker::get_if(&v[5]); if ( ! (bpath && brotation_base && brotation_interval && bnetwork_time && bconfig && bppf) ) return false; @@ -122,8 +122,8 @@ bool WriterBackend::WriterInfo::FromBroker(broker::data d) for ( auto i : *bconfig ) { - auto k = caf::get_if(&i.first); - auto v = caf::get_if(&i.second); + auto k = broker::get_if(&i.first); + auto v = broker::get_if(&i.second); if ( ! (k && v) ) return false; diff --git a/src/probabilistic/BitVector.cc b/src/probabilistic/BitVector.cc index 2f2175a594..f18915a77f 100644 --- a/src/probabilistic/BitVector.cc +++ b/src/probabilistic/BitVector.cc @@ -512,12 +512,12 @@ broker::expected BitVector::Serialize() const std::unique_ptr BitVector::Unserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() >= 2) ) return nullptr; - auto num_bits = caf::get_if(&(*v)[0]); - auto size = caf::get_if(&(*v)[1]); + auto num_bits = broker::get_if(&(*v)[0]); + auto size = broker::get_if(&(*v)[1]); if ( ! (num_bits && size) ) return nullptr; @@ -530,7 +530,7 @@ std::unique_ptr BitVector::Unserialize(const broker::data& data) for ( size_t i = 0; i < *size; ++i ) { - auto x = caf::get_if(&(*v)[2 + i]); + auto x = broker::get_if(&(*v)[2 + i]); if ( ! x ) return nullptr; diff --git a/src/probabilistic/BloomFilter.cc b/src/probabilistic/BloomFilter.cc index 4c046c3511..d3f27695d9 100644 --- a/src/probabilistic/BloomFilter.cc +++ b/src/probabilistic/BloomFilter.cc @@ -46,12 +46,12 @@ broker::expected BloomFilter::Serialize() const std::unique_ptr BloomFilter::Unserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() == 3) ) return nullptr; - auto type = caf::get_if(&(*v)[0]); + auto type = broker::get_if(&(*v)[0]); if ( ! type ) return nullptr; diff --git a/src/probabilistic/CardinalityCounter.cc b/src/probabilistic/CardinalityCounter.cc index 0e9365b4d3..b203fa6642 100644 --- a/src/probabilistic/CardinalityCounter.cc +++ b/src/probabilistic/CardinalityCounter.cc @@ -212,13 +212,13 @@ broker::expected CardinalityCounter::Serialize() const std::unique_ptr CardinalityCounter::Unserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() >= 3) ) return nullptr; - auto m = caf::get_if(&(*v)[0]); - auto V = caf::get_if(&(*v)[1]); - auto alpha_m = caf::get_if(&(*v)[2]); + auto m = broker::get_if(&(*v)[0]); + auto V = broker::get_if(&(*v)[1]); + auto alpha_m = broker::get_if(&(*v)[2]); if ( ! (m && V && alpha_m) ) return nullptr; @@ -233,7 +233,7 @@ std::unique_ptr CardinalityCounter::Unserialize(const broker for ( size_t i = 0; i < *m; ++i ) { - auto x = caf::get_if(&(*v)[3 + i]); + auto x = broker::get_if(&(*v)[3 + i]); if ( ! x ) return nullptr; diff --git a/src/probabilistic/CounterVector.cc b/src/probabilistic/CounterVector.cc index 1272487ee9..7224411f62 100644 --- a/src/probabilistic/CounterVector.cc +++ b/src/probabilistic/CounterVector.cc @@ -169,11 +169,11 @@ broker::expected CounterVector::Serialize() const std::unique_ptr CounterVector::Unserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() >= 2) ) return nullptr; - auto width = caf::get_if(&(*v)[0]); + auto width = broker::get_if(&(*v)[0]); auto bits = BitVector::Unserialize((*v)[1]); if ( ! (width && bits) ) diff --git a/src/probabilistic/Hasher.cc b/src/probabilistic/Hasher.cc index 9935f31896..5b20222d10 100644 --- a/src/probabilistic/Hasher.cc +++ b/src/probabilistic/Hasher.cc @@ -60,15 +60,15 @@ broker::expected Hasher::Serialize() const std::unique_ptr Hasher::Unserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() == 4) ) return nullptr; - auto type = caf::get_if(&(*v)[0]); - auto k = caf::get_if(&(*v)[1]); - auto h1 = caf::get_if(&(*v)[2]); - auto h2 = caf::get_if(&(*v)[3]); + auto type = broker::get_if(&(*v)[0]); + auto k = broker::get_if(&(*v)[1]); + auto h1 = broker::get_if(&(*v)[2]); + auto h2 = broker::get_if(&(*v)[3]); if ( ! (type && k && h1 && h2) ) return nullptr; diff --git a/src/probabilistic/Topk.cc b/src/probabilistic/Topk.cc index 481499630e..bc2232335d 100644 --- a/src/probabilistic/Topk.cc +++ b/src/probabilistic/Topk.cc @@ -447,14 +447,14 @@ broker::expected TopkVal::DoSerialize() const bool TopkVal::DoUnserialize(const broker::data& data) { - auto v = caf::get_if(&data); + auto v = broker::get_if(&data); if ( ! (v && v->size() >= 4) ) return false; - auto size_ = caf::get_if(&(*v)[0]); - auto numElements_ = caf::get_if(&(*v)[1]); - auto pruned_ = caf::get_if(&(*v)[2]); + auto size_ = broker::get_if(&(*v)[0]); + auto numElements_ = broker::get_if(&(*v)[1]); + auto pruned_ = broker::get_if(&(*v)[2]); if ( ! (size_ && numElements_ && pruned_) ) return false; @@ -463,7 +463,7 @@ bool TopkVal::DoUnserialize(const broker::data& data) numElements = *numElements_; pruned = *pruned_; - auto no_type = caf::get_if(&(*v)[3]); + auto no_type = broker::get_if(&(*v)[3]); if ( ! no_type ) { auto t = UnserializeType((*v)[3]); @@ -479,8 +479,8 @@ bool TopkVal::DoUnserialize(const broker::data& data) while ( i < numElements ) { - auto elements_count = caf::get_if(&(*v)[idx++]); - auto count = caf::get_if(&(*v)[idx++]); + auto elements_count = broker::get_if(&(*v)[idx++]); + auto count = broker::get_if(&(*v)[idx++]); if ( ! (elements_count && count) ) return false; @@ -491,7 +491,7 @@ bool TopkVal::DoUnserialize(const broker::data& data) for ( uint64_t j = 0; j < *elements_count; j++ ) { - auto epsilon = caf::get_if(&(*v)[idx++]); + auto epsilon = broker::get_if(&(*v)[idx++]); auto val = Broker::detail::data_to_val((*v)[idx++], type.get()); if ( ! (epsilon && val) ) diff --git a/src/telemetry/CMakeLists.txt b/src/telemetry/CMakeLists.txt index c0c2153387..542b7a8528 100644 --- a/src/telemetry/CMakeLists.txt +++ b/src/telemetry/CMakeLists.txt @@ -6,11 +6,7 @@ include_directories(BEFORE ) set(telemetry_SRCS - Counter.cc - Gauge.cc - Histogram.cc Manager.cc - MetricFamily.cc ) bif_target(telemetry.bif) diff --git a/src/telemetry/Counter.cc b/src/telemetry/Counter.cc deleted file mode 100644 index 6ddc7ece5a..0000000000 --- a/src/telemetry/Counter.cc +++ /dev/null @@ -1,77 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#include "zeek/telemetry/Counter.h" - -#include "zeek/telemetry/Detail.h" - -#include "caf/telemetry/counter.hpp" -#include "caf/telemetry/metric_family.hpp" -#include "caf/telemetry/metric_family_impl.hpp" - -namespace zeek::telemetry - { - -// -- IntCounter --------------------------------------------------------------- - -void IntCounter::Inc() noexcept - { - deref(pimpl).inc(); - } - -void IntCounter::Inc(int64_t amount) noexcept - { - deref(pimpl).inc(amount); - } - -int64_t IntCounter::operator++() noexcept - { - return ++deref(pimpl); - } - -int64_t IntCounter::Value() const noexcept - { - return deref(pimpl).value(); - } - -IntCounterFamily::IntCounterFamily(Impl* ptr) : MetricFamily(upcast(ptr)) { } - -IntCounter IntCounterFamily::GetOrAdd(Span labels) - { - return with_native_labels(labels, - [this](auto nativeLabels) - { - auto hdl = opaque(deref(this, pimpl).get_or_add(nativeLabels)); - return IntCounter{hdl}; - }); - } - -// -- DblCounter --------------------------------------------------------------- - -void DblCounter::Inc() noexcept - { - deref(pimpl).inc(); - } - -void DblCounter::Inc(double amount) noexcept - { - deref(pimpl).inc(amount); - } - -double DblCounter::Value() const noexcept - { - return deref(pimpl).value(); - } - -DblCounterFamily::DblCounterFamily(Impl* ptr) : MetricFamily(upcast(ptr)) { } - -DblCounter DblCounterFamily::GetOrAdd(Span labels) - { - return with_native_labels(labels, - [this](auto nativeLabels) - { - auto hdl = opaque(deref(this, pimpl).get_or_add(nativeLabels)); - return DblCounter{hdl}; - }); - } - - } // namespace zeek::telemetry diff --git a/src/telemetry/Counter.h b/src/telemetry/Counter.h index 126816b523..6f5e360a89 100644 --- a/src/telemetry/Counter.h +++ b/src/telemetry/Counter.h @@ -9,6 +9,8 @@ #include "zeek/Span.h" #include "zeek/telemetry/MetricFamily.h" +#include "broker/telemetry/fwd.hh" + namespace zeek::telemetry { @@ -24,8 +26,6 @@ class IntCounter public: friend class IntCounterFamily; - struct Impl; - static inline const char* OpaqueName = "IntCounterMetricVal"; IntCounter() = delete; @@ -35,34 +35,36 @@ public: /** * Increments the value by 1. */ - void Inc() noexcept; + void Inc() noexcept { broker::telemetry::inc(hdl); } /** * Increments the value by @p amount. * @pre `amount >= 0` */ - void Inc(int64_t amount) noexcept; + void Inc(int64_t amount) noexcept { broker::telemetry::inc(hdl, amount); } /** * Increments the value by 1. * @return The new value. */ - int64_t operator++() noexcept; + int64_t operator++() noexcept { return broker::telemetry::inc(hdl); } /** * @return The current value. */ - int64_t Value() const noexcept; + int64_t Value() const noexcept { return broker::telemetry::value(hdl); } /** * @return Whether @c this and @p other refer to the same counter. */ - constexpr bool IsSameAs(IntCounter other) const noexcept { return pimpl == other.pimpl; } + constexpr bool IsSameAs(IntCounter other) const noexcept { return hdl == other.hdl; } private: - explicit IntCounter(Impl* ptr) noexcept : pimpl(ptr) { } + using Handle = broker::telemetry::int_counter_hdl*; - Impl* pimpl; + explicit IntCounter(Handle hdl) noexcept : hdl(hdl) { } + + Handle hdl; }; /** @@ -89,8 +91,6 @@ class IntCounterFamily : public MetricFamily public: friend class Manager; - class Impl; - static inline const char* OpaqueName = "IntCounterMetricFamilyVal"; using InstanceType = IntCounter; @@ -102,7 +102,10 @@ public: * Returns the metrics handle for given labels, creating a new instance * lazily if necessary. */ - IntCounter GetOrAdd(Span labels); + IntCounter GetOrAdd(Span labels) + { + return IntCounter{int_counter_get_or_add(hdl, labels)}; + } /** * @copydoc GetOrAdd @@ -113,7 +116,9 @@ public: } private: - explicit IntCounterFamily(Impl* ptr); + using Handle = broker::telemetry::int_counter_family_hdl*; + + explicit IntCounterFamily(Handle hdl) : MetricFamily(upcast(hdl)) { } }; /** @@ -125,8 +130,6 @@ class DblCounter public: friend class DblCounterFamily; - struct Impl; - static inline const char* OpaqueName = "DblCounterMetricVal"; DblCounter() = delete; @@ -136,28 +139,30 @@ public: /** * Increments the value by 1. */ - void Inc() noexcept; + void Inc() noexcept { broker::telemetry::inc(hdl); } /** * Increments the value by @p amount. * @pre `amount >= 0` */ - void Inc(double amount) noexcept; + void Inc(double amount) noexcept { broker::telemetry::inc(hdl, amount); } /** * @return The current value. */ - double Value() const noexcept; + double Value() const noexcept { return broker::telemetry::value(hdl); } /** * @return Whether @c this and @p other refer to the same counter. */ - constexpr bool IsSameAs(DblCounter other) const noexcept { return pimpl == other.pimpl; } + constexpr bool IsSameAs(DblCounter other) const noexcept { return hdl == other.hdl; } private: - explicit DblCounter(Impl* ptr) noexcept : pimpl(ptr) { } + using Handle = broker::telemetry::dbl_counter_hdl*; - Impl* pimpl; + explicit DblCounter(Handle hdl) noexcept : hdl(hdl) { } + + Handle hdl; }; /** @@ -184,8 +189,6 @@ class DblCounterFamily : public MetricFamily public: friend class Manager; - class Impl; - static inline const char* OpaqueName = "DblCounterMetricFamilyVal"; using InstanceType = DblCounter; @@ -197,7 +200,10 @@ public: * Returns the metrics handle for given labels, creating a new instance * lazily if necessary. */ - DblCounter GetOrAdd(Span labels); + DblCounter GetOrAdd(Span labels) + { + return DblCounter{dbl_counter_get_or_add(hdl, labels)}; + } /** * @copydoc GetOrAdd @@ -208,7 +214,9 @@ public: } private: - explicit DblCounterFamily(Impl* ptr); + using Handle = broker::telemetry::dbl_counter_family_hdl*; + + explicit DblCounterFamily(Handle hdl) : MetricFamily(upcast(hdl)) { } }; namespace detail diff --git a/src/telemetry/Detail.h b/src/telemetry/Detail.h deleted file mode 100644 index 829041d7ad..0000000000 --- a/src/telemetry/Detail.h +++ /dev/null @@ -1,259 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -// This header contains private implementation details for telemetry classes -// and should not get included outside of .cc files. - -#pragma once - -#include -#include -#include - -#include "zeek/Span.h" -#include "zeek/telemetry/Counter.h" -#include "zeek/telemetry/Gauge.h" -#include "zeek/telemetry/Histogram.h" -#include "zeek/telemetry/Manager.h" -#include "zeek/telemetry/MetricFamily.h" - -#include "caf/telemetry/label_view.hpp" -#include "caf/telemetry/metric_family.hpp" - -namespace zeek::telemetry - { - -// -- traits for converting between opaque handles and native pointers --------- - -/** - * This trait must provide the member types @c Native for referring to the CAF - * type, @c Opaque for referring to the @c Impl type. For instance types such as - * @c IntCounter, the trait must also provide the member type @c NativeFamily. - */ -template struct PimplTrait; - -template <> struct PimplTrait - { - using Native = caf::telemetry::int_counter; - using Oqaque = IntCounter::Impl; - using NativeFamily = caf::telemetry::metric_family_impl; - }; - -template <> struct PimplTrait : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = typename PimplTrait::NativeFamily; - using Oqaque = IntCounterFamily::Impl; - }; - -template <> -struct PimplTrait::NativeFamily> - : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = caf::telemetry::dbl_counter; - using Oqaque = DblCounter::Impl; - using NativeFamily = caf::telemetry::metric_family_impl; - }; - -template <> struct PimplTrait : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = typename PimplTrait::NativeFamily; - using Oqaque = DblCounterFamily::Impl; - }; - -template <> -struct PimplTrait::NativeFamily> - : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = caf::telemetry::int_gauge; - using Oqaque = IntGauge::Impl; - using NativeFamily = caf::telemetry::metric_family_impl; - }; - -template <> struct PimplTrait : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = typename PimplTrait::NativeFamily; - using Oqaque = IntGaugeFamily::Impl; - }; - -template <> -struct PimplTrait::NativeFamily> - : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = caf::telemetry::dbl_gauge; - using Oqaque = DblGauge::Impl; - using NativeFamily = caf::telemetry::metric_family_impl; - }; - -template <> struct PimplTrait : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = typename PimplTrait::NativeFamily; - using Oqaque = DblGaugeFamily::Impl; - }; - -template <> -struct PimplTrait::NativeFamily> - : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = caf::telemetry::int_histogram; - using Oqaque = IntHistogram::Impl; - using NativeFamily = caf::telemetry::metric_family_impl; - }; - -template <> struct PimplTrait : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = typename PimplTrait::NativeFamily; - using Oqaque = IntHistogramFamily::Impl; - }; - -template <> -struct PimplTrait::NativeFamily> - : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = caf::telemetry::dbl_histogram; - using Oqaque = DblHistogram::Impl; - using NativeFamily = caf::telemetry::metric_family_impl; - }; - -template <> struct PimplTrait : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = typename PimplTrait::NativeFamily; - using Oqaque = DblHistogramFamily::Impl; - }; - -template <> -struct PimplTrait::NativeFamily> - : PimplTrait - { - }; - -template <> struct PimplTrait - { - using Native = caf::telemetry::metric_registry; - using Oqaque = Manager::Impl; - }; - -template <> -struct PimplTrait::Native> : PimplTrait - { - }; - -// -- free functions ----------------------------------------------------------- - -template ::Native> auto& deref(T* ptr) - { - return *reinterpret_cast(ptr); - } - -template auto& deref(Family*, MetricFamily::Impl* ptr) - { - using InstanceType = typename Family::InstanceType; - using ImplType = typename InstanceType::Impl; - using NativeType = typename PimplTrait::NativeFamily; - return *reinterpret_cast(ptr); - } - -template ::Oqaque> auto opaque(T* ptr) - { - return reinterpret_cast(ptr); - } - -template auto opaque(const Family*, MetricFamily::Impl* ptr) - { - using InstanceType = typename Family::InstanceType; - using ImplType = typename InstanceType::Impl; - using OpaqueType = typename PimplTrait::NativeFamily; - return reinterpret_cast(ptr); - } - -template ::Native> auto upcast(T* ptr) - { - auto native = reinterpret_cast(ptr); - auto base_ptr = static_cast(native); - return reinterpret_cast(base_ptr); - } - -template auto with_native_labels(Span xs, F continuation) - { - namespace ct = caf::telemetry; - - if ( xs.size() <= 10 ) - { - ct::label_view buf[10] = { - {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, - {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, {{}, {}}, - }; - for ( size_t index = 0; index < xs.size(); ++index ) - buf[index] = ct::label_view{xs[index].first, xs[index].second}; - return continuation(Span{buf, xs.size()}); - } - else - { - std::vector buf; - for ( auto x : xs ) - buf.emplace_back(x.first, x.second); - return continuation(Span{buf}); - } - } - -template auto with_native_labels(Span xs, F continuation) - { - if ( xs.size() <= 10 ) - { - caf::string_view buf[10]; - for ( size_t index = 0; index < xs.size(); ++index ) - buf[index] = xs[index]; - return continuation(Span{buf, xs.size()}); - } - else - { - std::vector buf; - for ( auto x : xs ) - buf.emplace_back(x); - return continuation(Span{buf}); - } - } - - } // namespace zeek::telemetry diff --git a/src/telemetry/Gauge.cc b/src/telemetry/Gauge.cc deleted file mode 100644 index ad6ed5d6ea..0000000000 --- a/src/telemetry/Gauge.cc +++ /dev/null @@ -1,102 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#include "zeek/telemetry/Gauge.h" - -#include "zeek/telemetry/Detail.h" - -#include "caf/telemetry/gauge.hpp" -#include "caf/telemetry/metric_family.hpp" -#include "caf/telemetry/metric_family_impl.hpp" - -namespace zeek::telemetry - { - -// -- IntGauge --------------------------------------------------------------- - -void IntGauge::Inc() noexcept - { - deref(pimpl).inc(); - } - -void IntGauge::Inc(int64_t amount) noexcept - { - deref(pimpl).inc(amount); - } - -void IntGauge::Dec() noexcept - { - deref(pimpl).dec(); - } - -void IntGauge::Dec(int64_t amount) noexcept - { - deref(pimpl).dec(amount); - } - -int64_t IntGauge::operator++() noexcept - { - return ++deref(pimpl); - } - -int64_t IntGauge::operator--() noexcept - { - return --deref(pimpl); - } - -int64_t IntGauge::Value() const noexcept - { - return deref(pimpl).value(); - } - -IntGaugeFamily::IntGaugeFamily(Impl* ptr) : MetricFamily(upcast(ptr)) { } - -IntGauge IntGaugeFamily::GetOrAdd(Span labels) - { - return with_native_labels(labels, - [this](auto nativeLabels) - { - auto hdl = opaque(deref(this, pimpl).get_or_add(nativeLabels)); - return IntGauge{hdl}; - }); - } - -// -- DblGauge --------------------------------------------------------------- - -void DblGauge::Inc() noexcept - { - deref(pimpl).inc(); - } - -void DblGauge::Inc(double amount) noexcept - { - deref(pimpl).inc(amount); - } - -void DblGauge::Dec() noexcept - { - deref(pimpl).dec(); - } - -void DblGauge::Dec(double amount) noexcept - { - deref(pimpl).dec(amount); - } - -double DblGauge::Value() const noexcept - { - return deref(pimpl).value(); - } - -DblGaugeFamily::DblGaugeFamily(Impl* ptr) : MetricFamily(upcast(ptr)) { } - -DblGauge DblGaugeFamily::GetOrAdd(Span labels) - { - return with_native_labels(labels, - [this](auto nativeLabels) - { - auto hdl = opaque(deref(this, pimpl).get_or_add(nativeLabels)); - return DblGauge{hdl}; - }); - } - - } // namespace zeek::telemetry diff --git a/src/telemetry/Gauge.h b/src/telemetry/Gauge.h index f072178d98..e0af13f2c5 100644 --- a/src/telemetry/Gauge.h +++ b/src/telemetry/Gauge.h @@ -9,6 +9,8 @@ #include "zeek/Span.h" #include "zeek/telemetry/MetricFamily.h" +#include "broker/telemetry/fwd.hh" + namespace zeek::telemetry { @@ -17,7 +19,7 @@ class IntGaugeFamily; class Manager; /** - * A handle to a metric that represents an integer value. Gauges are less + * A handle to a metric that represents an integer value. Gauges are more * permissive than counters and also allow decrementing the value. */ class IntGauge @@ -25,8 +27,6 @@ class IntGauge public: friend class IntGaugeFamily; - struct Impl; - static inline const char* OpaqueName = "IntGaugeMetricVal"; IntGauge() = delete; @@ -36,49 +36,51 @@ public: /** * Increments the value by 1. */ - void Inc() noexcept; + void Inc() noexcept { broker::telemetry::inc(hdl); } /** * Increments the value by @p amount. */ - void Inc(int64_t amount) noexcept; + void Inc(int64_t amount) noexcept { broker::telemetry::inc(hdl, amount); } /** * Increments the value by 1. * @return The new value. */ - int64_t operator++() noexcept; + int64_t operator++() noexcept { return broker::telemetry::inc(hdl); } /** * Decrements the value by 1. */ - void Dec() noexcept; + void Dec() noexcept { broker::telemetry::dec(hdl); } /** * Decrements the value by @p amount. */ - void Dec(int64_t amount) noexcept; + void Dec(int64_t amount) noexcept { broker::telemetry::dec(hdl, amount); } /** * Decrements the value by 1. * @return The new value. */ - int64_t operator--() noexcept; + int64_t operator--() noexcept { return broker::telemetry::dec(hdl); } /** * @return The current value. */ - int64_t Value() const noexcept; + int64_t Value() const noexcept { return broker::telemetry::value(hdl); } /** * @return Whether @c this and @p other refer to the same counter. */ - constexpr bool IsSameAs(IntGauge other) const noexcept { return pimpl == other.pimpl; } + constexpr bool IsSameAs(IntGauge other) const noexcept { return hdl == other.hdl; } private: - explicit IntGauge(Impl* ptr) noexcept : pimpl(ptr) { } + using Handle = broker::telemetry::int_gauge_hdl*; - Impl* pimpl; + explicit IntGauge(Handle hdl) noexcept : hdl(hdl) { } + + Handle hdl; }; /** @@ -105,8 +107,6 @@ class IntGaugeFamily : public MetricFamily public: friend class Manager; - class Impl; - static inline const char* OpaqueName = "IntGaugeMetricFamilyVal"; using InstanceType = IntGauge; @@ -118,7 +118,10 @@ public: * Returns the metrics handle for given labels, creating a new instance * lazily if necessary. */ - IntGauge GetOrAdd(Span labels); + IntGauge GetOrAdd(Span labels) + { + return IntGauge{int_gauge_get_or_add(hdl, labels)}; + } /** * @copydoc GetOrAdd @@ -129,21 +132,20 @@ public: } private: - explicit IntGaugeFamily(Impl* ptr); + using Handle = broker::telemetry::int_gauge_family_hdl*; + + explicit IntGaugeFamily(Handle hdl) : MetricFamily(upcast(hdl)) { } }; /** - * A handle to a metric that represents a floating point value. Gauges are less + * A handle to a metric that represents a floating point value. Gauges are more * permissive than counters and also allow decrementing the value. - * up. */ class DblGauge { public: friend class DblGaugeFamily; - struct Impl; - static inline const char* OpaqueName = "DblGaugeMetricVal"; DblGauge() = delete; @@ -153,37 +155,39 @@ public: /** * Increments the value by 1. */ - void Inc() noexcept; + void Inc() noexcept { broker::telemetry::inc(hdl); } /** * Increments the value by @p amount. */ - void Inc(double amount) noexcept; + void Inc(double amount) noexcept { broker::telemetry::inc(hdl, amount); } /** * Increments the value by 1. */ - void Dec() noexcept; + void Dec() noexcept { broker::telemetry::dec(hdl); } /** * Increments the value by @p amount. */ - void Dec(double amount) noexcept; + void Dec(double amount) noexcept { broker::telemetry::dec(hdl, amount); } /** * @return The current value. */ - double Value() const noexcept; + double Value() const noexcept { return broker::telemetry::value(hdl); } /** * @return Whether @c this and @p other refer to the same counter. */ - constexpr bool IsSameAs(DblGauge other) const noexcept { return pimpl == other.pimpl; } + constexpr bool IsSameAs(DblGauge other) const noexcept { return hdl == other.hdl; } private: - explicit DblGauge(Impl* ptr) noexcept : pimpl(ptr) { } + using Handle = broker::telemetry::dbl_gauge_hdl*; - Impl* pimpl; + explicit DblGauge(Handle hdl) noexcept : hdl(hdl) { } + + Handle hdl; }; /** @@ -210,8 +214,6 @@ class DblGaugeFamily : public MetricFamily public: friend class Manager; - class Impl; - static inline const char* OpaqueName = "DblGaugeMetricFamilyVal"; using InstanceType = DblGauge; @@ -223,7 +225,10 @@ public: * Returns the metrics handle for given labels, creating a new instance * lazily if necessary. */ - DblGauge GetOrAdd(Span labels); + DblGauge GetOrAdd(Span labels) + { + return DblGauge{dbl_gauge_get_or_add(hdl, labels)}; + } /** * @copydoc GetOrAdd @@ -234,7 +239,9 @@ public: } private: - explicit DblGaugeFamily(Impl* ptr); + using Handle = broker::telemetry::dbl_gauge_family_hdl*; + + explicit DblGaugeFamily(Handle hdl) : MetricFamily(upcast(hdl)) { } }; namespace detail diff --git a/src/telemetry/Histogram.cc b/src/telemetry/Histogram.cc deleted file mode 100644 index e6f95a55f3..0000000000 --- a/src/telemetry/Histogram.cc +++ /dev/null @@ -1,102 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#include "zeek/telemetry/Histogram.h" - -#include - -#include "zeek/telemetry/Detail.h" - -#include "caf/telemetry/histogram.hpp" -#include "caf/telemetry/metric_family.hpp" -#include "caf/telemetry/metric_family_impl.hpp" - -namespace zeek::telemetry - { - -// -- IntHistogram --------------------------------------------------------------- - -void IntHistogram::Observe(int64_t value) noexcept - { - deref(pimpl).observe(value); - } - -int64_t IntHistogram::Sum() const noexcept - { - return deref(pimpl).sum(); - } - -size_t IntHistogram::NumBuckets() const noexcept - { - return deref(pimpl).buckets().size(); - } - -int64_t IntHistogram::CountAt(size_t index) const noexcept - { - auto xs = deref(pimpl).buckets(); - assert(index < xs.size()); - return xs[index].count.value(); - } - -int64_t IntHistogram::UpperBoundAt(size_t index) const noexcept - { - auto xs = deref(pimpl).buckets(); - assert(index < xs.size()); - return xs[index].upper_bound; - } - -IntHistogramFamily::IntHistogramFamily(Impl* ptr) : MetricFamily(upcast(ptr)) { } - -IntHistogram IntHistogramFamily::GetOrAdd(Span labels) - { - return with_native_labels(labels, - [this](auto nativeLabels) - { - auto hdl = opaque(deref(this, pimpl).get_or_add(nativeLabels)); - return IntHistogram{hdl}; - }); - } - -// -- DblHistogram --------------------------------------------------------------- - -void DblHistogram::Observe(double amount) noexcept - { - deref(pimpl).observe(amount); - } - -double DblHistogram::Sum() const noexcept - { - return deref(pimpl).sum(); - } - -size_t DblHistogram::NumBuckets() const noexcept - { - return deref(pimpl).buckets().size(); - } - -int64_t DblHistogram::CountAt(size_t index) const noexcept - { - auto xs = deref(pimpl).buckets(); - assert(index < xs.size()); - return xs[index].count.value(); - } - -double DblHistogram::UpperBoundAt(size_t index) const noexcept - { - auto xs = deref(pimpl).buckets(); - assert(index < xs.size()); - return xs[index].upper_bound; - } - -DblHistogramFamily::DblHistogramFamily(Impl* ptr) : MetricFamily(upcast(ptr)) { } - -DblHistogram DblHistogramFamily::GetOrAdd(Span labels) - { - return with_native_labels(labels, - [this](auto nativeLabels) - { - auto hdl = opaque(deref(this, pimpl).get_or_add(nativeLabels)); - return DblHistogram{hdl}; - }); - } - - } // namespace zeek::telemetry diff --git a/src/telemetry/Histogram.h b/src/telemetry/Histogram.h index 0097142bc2..3b69ef3af3 100644 --- a/src/telemetry/Histogram.h +++ b/src/telemetry/Histogram.h @@ -9,6 +9,8 @@ #include "zeek/Span.h" #include "zeek/telemetry/MetricFamily.h" +#include "broker/telemetry/fwd.hh" + namespace zeek::telemetry { @@ -26,8 +28,6 @@ class IntHistogram public: friend class IntHistogramFamily; - struct Impl; - static inline const char* OpaqueName = "IntHistogramMetricVal"; IntHistogram() = delete; @@ -38,31 +38,33 @@ public: * Increments all buckets with an upper bound less than or equal to @p value * by one and adds @p value to the total sum of all observed values. */ - void Observe(int64_t value) noexcept; + void Observe(int64_t value) noexcept { return broker::telemetry::observe(hdl, value); } /// @return The sum of all observed values. - int64_t Sum() const noexcept; + int64_t Sum() const noexcept { return broker::telemetry::sum(hdl); } /// @return The number of buckets, including the implicit "infinite" bucket. - size_t NumBuckets() const noexcept; + size_t NumBuckets() const noexcept { return broker::telemetry::num_buckets(hdl); } /// @return The number of observations in the bucket at @p index. /// @pre index < NumBuckets() - int64_t CountAt(size_t index) const noexcept; + int64_t CountAt(size_t index) const noexcept { return broker::telemetry::count_at(hdl, index); } /// @return The upper bound of the bucket at @p index. /// @pre index < NumBuckets() - int64_t UpperBoundAt(size_t index) const noexcept; + int64_t UpperBoundAt(size_t index) const noexcept { return broker::telemetry::upper_bound_at(hdl, index); } /** * @return Whether @c this and @p other refer to the same histogram. */ - constexpr bool IsSameAs(IntHistogram other) const noexcept { return pimpl == other.pimpl; } + constexpr bool IsSameAs(IntHistogram other) const noexcept { return hdl == other.hdl; } private: - explicit IntHistogram(Impl* ptr) noexcept : pimpl(ptr) { } + using Handle = broker::telemetry::int_histogram_hdl*; - Impl* pimpl; + explicit IntHistogram(Handle hdl) noexcept : hdl(hdl) { } + + Handle hdl; }; /** @@ -88,8 +90,6 @@ class IntHistogramFamily : public MetricFamily public: friend class Manager; - class Impl; - static inline const char* OpaqueName = "IntHistogramMetricFamilyVal"; using InstanceType = IntHistogram; @@ -101,7 +101,10 @@ public: * Returns the metrics handle for given labels, creating a new instance * lazily if necessary. */ - IntHistogram GetOrAdd(Span labels); + IntHistogram GetOrAdd(Span labels) + { + return IntHistogram{int_histogram_get_or_add(hdl, labels)}; + } /** * @copydoc GetOrAdd @@ -112,7 +115,9 @@ public: } private: - explicit IntHistogramFamily(Impl* ptr); + using Handle = broker::telemetry::int_histogram_family_hdl*; + + explicit IntHistogramFamily(Handle hdl) : MetricFamily(upcast(hdl)) { } }; /** @@ -125,8 +130,6 @@ class DblHistogram public: friend class DblHistogramFamily; - struct Impl; - static inline const char* OpaqueName = "DblHistogramMetricVal"; DblHistogram() = delete; @@ -137,31 +140,36 @@ public: * Increments all buckets with an upper bound less than or equal to @p value * by one and adds @p value to the total sum of all observed values. */ - void Observe(double value) noexcept; + void Observe(double value) noexcept { broker::telemetry::observe(hdl, value); } /// @return The sum of all observed values. - double Sum() const noexcept; + double Sum() const noexcept { return broker::telemetry::sum(hdl); } /// @return The number of buckets, including the implicit "infinite" bucket. - size_t NumBuckets() const noexcept; + size_t NumBuckets() const noexcept { return broker::telemetry::num_buckets(hdl); } /// @return The number of observations in the bucket at @p index. /// @pre index < NumBuckets() - int64_t CountAt(size_t index) const noexcept; + int64_t CountAt(size_t index) const noexcept { return broker::telemetry::count_at(hdl, index); } /// @return The upper bound of the bucket at @p index. /// @pre index < NumBuckets() - double UpperBoundAt(size_t index) const noexcept; + double UpperBoundAt(size_t index) const noexcept + { + return broker::telemetry::upper_bound_at(hdl, index); + } /** * @return Whether @c this and @p other refer to the same histogram. */ - constexpr bool IsSameAs(DblHistogram other) const noexcept { return pimpl == other.pimpl; } + constexpr bool IsSameAs(DblHistogram other) const noexcept { return hdl == other.hdl; } private: - explicit DblHistogram(Impl* ptr) noexcept : pimpl(ptr) { } + using Handle = broker::telemetry::dbl_histogram_hdl*; - Impl* pimpl; + explicit DblHistogram(Handle hdl) noexcept : hdl(hdl) { } + + Handle hdl; }; /** @@ -187,8 +195,6 @@ class DblHistogramFamily : public MetricFamily public: friend class Manager; - class Impl; - static inline const char* OpaqueName = "DblHistogramMetricFamilyVal"; using InstanceType = DblHistogram; @@ -200,7 +206,10 @@ public: * Returns the metrics handle for given labels, creating a new instance * lazily if necessary. */ - DblHistogram GetOrAdd(Span labels); + DblHistogram GetOrAdd(Span labels) + { + return DblHistogram{dbl_histogram_get_or_add(hdl, labels)}; + } /** * @copydoc GetOrAdd @@ -211,7 +220,9 @@ public: } private: - explicit DblHistogramFamily(Impl* ptr); + using Handle = broker::telemetry::dbl_histogram_family_hdl*; + + explicit DblHistogramFamily(Handle hdl) : MetricFamily(upcast(hdl)) { } }; namespace detail diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index d7eac6904e..66fb3d5b94 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -5,102 +5,37 @@ #include #include "zeek/3rdparty/doctest.h" -#include "zeek/telemetry/Detail.h" +#include "zeek/broker/Manager.h" #include "zeek/telemetry/Timer.h" -#include "caf/telemetry/metric_registry.hpp" +#include "broker/telemetry/metric_registry.hh" + +namespace + { +using NativeManager = broker::telemetry::metric_registry; +using NativeManagerImpl = broker::telemetry::metric_registry_impl; +using NativeManagerImplPtr = zeek::IntrusivePtr; + } namespace zeek::telemetry { +Manager::Manager() + { + auto reg = NativeManager::pre_init_instance(); + NativeManagerImplPtr ptr{NewRef{}, reg.pimpl()}; + pimpl.swap(ptr); + } + Manager::~Manager() { } void Manager::InitPostScript() { } -IntCounterFamily Manager::IntCounterFam(std::string_view prefix, std::string_view name, - Span labels, - std::string_view helptext, std::string_view unit, - bool is_sum) +void Manager::InitPostBrokerSetup(broker::endpoint& ep) { - return with_native_labels(labels, - [&, this](auto xs) - { - auto ptr = deref(pimpl).counter_family(prefix, name, xs, helptext, - unit, is_sum); - return IntCounterFamily{opaque(ptr)}; - }); - } - -DblCounterFamily Manager::DblCounterFam(std::string_view prefix, std::string_view name, - Span labels, - std::string_view helptext, std::string_view unit, - bool is_sum) - { - return with_native_labels(labels, - [&, this](auto xs) - { - auto ptr = deref(pimpl).counter_family( - prefix, name, xs, helptext, unit, is_sum); - return DblCounterFamily{opaque(ptr)}; - }); - } - -IntGaugeFamily Manager::IntGaugeFam(std::string_view prefix, std::string_view name, - Span labels, std::string_view helptext, - std::string_view unit, bool is_sum) - { - return with_native_labels(labels, - [&, this](auto xs) - { - auto ptr = deref(pimpl).gauge_family(prefix, name, xs, helptext, - unit, is_sum); - return IntGaugeFamily{opaque(ptr)}; - }); - } - -DblGaugeFamily Manager::DblGaugeFam(std::string_view prefix, std::string_view name, - Span labels, std::string_view helptext, - std::string_view unit, bool is_sum) - { - return with_native_labels(labels, - [&, this](auto xs) - { - auto ptr = deref(pimpl).gauge_family( - prefix, name, xs, helptext, unit, is_sum); - return DblGaugeFamily{opaque(ptr)}; - }); - } - -IntHistogramFamily Manager::IntHistoFam(std::string_view prefix, std::string_view name, - Span labels, - Span ubounds, std::string_view helptext, - std::string_view unit, bool is_sum) - { - return with_native_labels( - labels, - [&, this](auto xs) - { - auto bounds = caf::span{ubounds.data(), ubounds.size()}; - auto ptr = deref(pimpl).histogram_family(prefix, name, xs, bounds, helptext, unit, - is_sum); - return IntHistogramFamily{opaque(ptr)}; - }); - } - -DblHistogramFamily Manager::DblHistoFam(std::string_view prefix, std::string_view name, - Span labels, - Span ubounds, std::string_view helptext, - std::string_view unit, bool is_sum) - { - return with_native_labels( - labels, - [&, this](auto xs) - { - auto bounds = caf::span{ubounds.data(), ubounds.size()}; - auto ptr = deref(pimpl).histogram_family(prefix, name, xs, bounds, helptext, - unit, is_sum); - return DblHistogramFamily{opaque(ptr)}; - }); + auto reg = NativeManager::merge(NativeManager{pimpl.get()}, ep); + NativeManagerImplPtr ptr{NewRef{}, reg.pimpl()}; + pimpl.swap(ptr); } } // namespace zeek::telemetry @@ -110,8 +45,6 @@ DblHistogramFamily Manager::DblHistoFam(std::string_view prefix, std::string_vie using namespace std::literals; using namespace zeek::telemetry; -using NativeManager = caf::telemetry::metric_registry; - namespace { @@ -129,8 +62,7 @@ SCENARIO("telemetry managers provide access to counter singletons") { GIVEN("a telemetry manager") { - NativeManager native_mgr; - Manager mgr{opaque(&native_mgr)}; + Manager mgr; WHEN("retrieving an IntCounter singleton") { auto first = mgr.CounterSingleton("zeek", "int-count", "test"); @@ -184,8 +116,7 @@ SCENARIO("telemetry managers provide access to counter families") { GIVEN("a telemetry manager") { - NativeManager native_mgr; - Manager mgr{opaque(&native_mgr)}; + Manager mgr; WHEN("retrieving an IntCounter family") { auto family = mgr.CounterFamily("zeek", "requests", {"method"}, "test", "1", true); @@ -244,8 +175,7 @@ SCENARIO("telemetry managers provide access to gauge singletons") { GIVEN("a telemetry manager") { - NativeManager native_mgr; - Manager mgr{opaque(&native_mgr)}; + Manager mgr; WHEN("retrieving an IntGauge singleton") { auto first = mgr.GaugeSingleton("zeek", "int-gauge", "test"); @@ -309,8 +239,7 @@ SCENARIO("telemetry managers provide access to gauge families") { GIVEN("a telemetry manager") { - NativeManager native_mgr; - Manager mgr{opaque(&native_mgr)}; + Manager mgr; WHEN("retrieving an IntGauge family") { auto family = mgr.GaugeFamily("zeek", "open-connections", {"protocol"}, "test"); @@ -369,8 +298,7 @@ SCENARIO("telemetry managers provide access to histogram singletons") { GIVEN("a telemetry manager") { - NativeManager native_mgr; - Manager mgr{opaque(&native_mgr)}; + Manager mgr; WHEN("retrieving an IntHistogram singleton") { const auto max_int = std::numeric_limits::max(); @@ -456,8 +384,7 @@ SCENARIO("telemetry managers provide access to histogram families") { GIVEN("a telemetry manager") { - NativeManager native_mgr; - Manager mgr{opaque(&native_mgr)}; + Manager mgr; WHEN("retrieving an IntHistogram family") { int64_t buckets[] = {10, 20}; diff --git a/src/telemetry/Manager.h b/src/telemetry/Manager.h index 1643fe0fa7..9158ab667c 100644 --- a/src/telemetry/Manager.h +++ b/src/telemetry/Manager.h @@ -7,11 +7,24 @@ #include #include +#include "zeek/IntrusivePtr.h" #include "zeek/Span.h" #include "zeek/telemetry/Counter.h" #include "zeek/telemetry/Gauge.h" #include "zeek/telemetry/Histogram.h" +#include "broker/telemetry/fwd.hh" + +namespace broker + { +class endpoint; + } + +namespace zeek::Broker + { +class Manager; + } + namespace zeek::telemetry { @@ -21,9 +34,9 @@ namespace zeek::telemetry class Manager { public: - class Impl; + friend class Broker::Manager; - explicit Manager(Impl* ptr) : pimpl(ptr) { } + Manager(); Manager(const Manager&) = delete; @@ -54,13 +67,15 @@ public: { if constexpr ( std::is_same::value ) { - return IntCounterFam(prefix, name, labels, helptext, unit, is_sum); + auto fam = int_counter_fam(ptr(), prefix, name, labels, helptext, unit, is_sum); + return IntCounterFamily{fam}; } else { static_assert(std::is_same::value, "metrics only support int64_t and double values"); - return DblCounterFam(prefix, name, labels, helptext, unit, is_sum); + auto fam = dbl_counter_fam(ptr(), prefix, name, labels, helptext, unit, is_sum); + return DblCounterFamily{fam}; } } @@ -148,13 +163,15 @@ public: { if constexpr ( std::is_same::value ) { - return IntGaugeFam(prefix, name, labels, helptext, unit, is_sum); + auto fam = int_gauge_fam(ptr(), prefix, name, labels, helptext, unit, is_sum); + return IntGaugeFamily{fam}; } else { static_assert(std::is_same::value, "metrics only support int64_t and double values"); - return DblGaugeFam(prefix, name, labels, helptext, unit, is_sum); + auto fam = dbl_gauge_fam(ptr(), prefix, name, labels, helptext, unit, is_sum); + return DblGaugeFamily{fam}; } } @@ -264,13 +281,17 @@ public: { if constexpr ( std::is_same::value ) { - return IntHistoFam(prefix, name, labels, default_upper_bounds, helptext, unit, is_sum); + auto fam = int_histogram_fam(ptr(), prefix, name, labels, default_upper_bounds, + helptext, unit, is_sum); + return IntHistogramFamily{fam}; } else { static_assert(std::is_same::value, "metrics only support int64_t and double values"); - return DblHistoFam(prefix, name, labels, default_upper_bounds, helptext, unit, is_sum); + auto fam = dbl_histogram_fam(ptr(), prefix, name, labels, default_upper_bounds, + helptext, unit, is_sum); + return DblHistogramFamily{fam}; } } @@ -368,30 +389,6 @@ public: } protected: - IntCounterFamily IntCounterFam(std::string_view prefix, std::string_view name, - Span labels, std::string_view helptext, - std::string_view unit, bool is_sum); - - DblCounterFamily DblCounterFam(std::string_view prefix, std::string_view name, - Span labels, std::string_view helptext, - std::string_view unit, bool is_sum); - - IntGaugeFamily IntGaugeFam(std::string_view prefix, std::string_view name, - Span labels, std::string_view helptext, - std::string_view unit, bool is_sum); - - DblGaugeFamily DblGaugeFam(std::string_view prefix, std::string_view name, - Span labels, std::string_view helptext, - std::string_view unit, bool is_sum); - - IntHistogramFamily IntHistoFam(std::string_view prefix, std::string_view name, - Span labels, Span ubounds, - std::string_view helptext, std::string_view unit, bool is_sum); - - DblHistogramFamily DblHistoFam(std::string_view prefix, std::string_view name, - Span labels, Span ubounds, - std::string_view helptext, std::string_view unit, bool is_sum); - template static void WithLabelNames(Span xs, F continuation) { if ( xs.size() <= 10 ) @@ -410,7 +407,13 @@ protected: } } - Impl* pimpl; + broker::telemetry::metric_registry_impl* ptr() { return pimpl.get(); } + + // Connects all the dots after the Broker Manager constructed the endpoint + // for this Zeek instance. Called from Broker::Manager::InitPostScript(). + void InitPostBrokerSetup(broker::endpoint&); + + IntrusivePtr pimpl; }; } // namespace zeek::telemetry diff --git a/src/telemetry/MetricFamily.cc b/src/telemetry/MetricFamily.cc deleted file mode 100644 index cdd7f52e4e..0000000000 --- a/src/telemetry/MetricFamily.cc +++ /dev/null @@ -1,54 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#include "zeek/telemetry/MetricFamily.h" - -#include "caf/telemetry/metric_family.hpp" - -namespace zeek::telemetry - { - -namespace - { - -namespace ct = caf::telemetry; - -using NativeMetricFamily = ct::metric_family; - -auto& deref(MetricFamily::Impl* ptr) - { - return *reinterpret_cast(ptr); - } - - } // namespace - -std::string_view MetricFamily::Prefix() const noexcept - { - return deref(pimpl).prefix(); - } - -std::string_view MetricFamily::Name() const noexcept - { - return deref(pimpl).name(); - } - -Span MetricFamily::LabelNames() const noexcept - { - return deref(pimpl).label_names(); - } - -std::string_view MetricFamily::Helptext() const noexcept - { - return deref(pimpl).helptext(); - } - -std::string_view MetricFamily::Unit() const noexcept - { - return deref(pimpl).unit(); - } - -bool MetricFamily::IsSum() const noexcept - { - return deref(pimpl).is_sum(); - } - - } // namespace zeek::telemetry diff --git a/src/telemetry/MetricFamily.h b/src/telemetry/MetricFamily.h index 6ea546d5d3..7fdf65fd43 100644 --- a/src/telemetry/MetricFamily.h +++ b/src/telemetry/MetricFamily.h @@ -8,6 +8,8 @@ #include "zeek/Span.h" +#include "broker/telemetry/metric_family.hh" + namespace zeek::telemetry { @@ -23,8 +25,6 @@ using LabelView = std::pair; class MetricFamily { public: - struct Impl; - MetricFamily() = delete; MetricFamily(const MetricFamily&) noexcept = default; MetricFamily& operator=(const MetricFamily&) noexcept = default; @@ -35,42 +35,47 @@ public: * script, may use a prefix that represents the application/script * or protocol (e.g. @c http) name. */ - std::string_view Prefix() const noexcept; + std::string_view Prefix() const noexcept { return broker::telemetry::prefix(hdl); } /** * @return The human-readable name of the metric, e.g., * @p open-connections. */ - std::string_view Name() const noexcept; + std::string_view Name() const noexcept { return broker::telemetry::name(hdl); } /** * @return The names for all label dimensions. */ - Span LabelNames() const noexcept; + Span LabelNames() const noexcept + { + return broker::telemetry::label_names(hdl); + } /** * @return A short explanation of the metric. */ - std::string_view Helptext() const noexcept; + std::string_view Helptext() const noexcept { return broker::telemetry::helptext(hdl); } /** * @return The unit of measurement, preferably a base unit such as * @c bytes or @c seconds. Dimensionless counts return the * pseudo-unit @c 1. */ - std::string_view Unit() const noexcept; + std::string_view Unit() const noexcept { return broker::telemetry::unit(hdl); } /** * @return Whether metrics of this family accumulate values, where only the * total value is of interest. For example, the total number of * HTTP requests. */ - bool IsSum() const noexcept; + bool IsSum() const noexcept { return broker::telemetry::is_sum(hdl); } protected: - explicit MetricFamily(Impl* ptr) : pimpl(ptr) { } + using Handle = broker::telemetry::metric_family_hdl*; - Impl* pimpl; + explicit MetricFamily(Handle hdl) : hdl(hdl) { } + + Handle hdl; }; } // namespace zeek::telemetry diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 871ced8e53..7a5fd82d2d 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -579,7 +579,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) file_mgr = new file_analysis::Manager(); auto broker_real_time = ! options.pcap_file && ! options.deterministic_mode; broker_mgr = new Broker::Manager(broker_real_time); - telemetry_mgr = broker_mgr->NewTelemetryManager().release(); + telemetry_mgr = new telemetry::Manager; trigger_mgr = new trigger::Manager(); plugin_mgr->InitPreScript(); From da2a5ef4558b870a394ea5470fdc932011deb1d3 Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Tue, 21 Dec 2021 11:02:26 +0100 Subject: [PATCH 018/204] Fix GCC builds and string output for Broker errors --- auxil/broker | 2 +- src/broker/Manager.cc | 53 +++++++++++++++++++++++++++++++++- src/probabilistic/BitVector.cc | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/auxil/broker b/auxil/broker index ce321c0a90..0b2691392f 160000 --- a/auxil/broker +++ b/auxil/broker @@ -1 +1 @@ -Subproject commit ce321c0a90f1d4176796c996fd27fe69ea520316 +Subproject commit 0b2691392f335d409781257f210c7b1681530c59 diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index babf719d3e..6fc8327d51 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -28,6 +28,57 @@ using namespace std; +namespace { + +void print_escaped(std::string& buf, std::string_view str) + { + buf.push_back('"'); + for ( auto c : str ) + { + switch ( c ) + { + default: + buf.push_back(c); + break; + case '\\': + buf.push_back('\\'); + buf.push_back('\\'); + break; + case '\b': + buf.push_back('\\'); + buf.push_back('b'); + break; + case '\f': + buf.push_back('\\'); + buf.push_back('f'); + break; + case '\n': + buf.push_back('\\'); + buf.push_back('n'); + break; + case '\r': + buf.push_back('\\'); + buf.push_back('r'); + break; + case '\t': + buf.push_back('\\'); + buf.push_back('t'); + break; + case '\v': + buf.push_back('\\'); + buf.push_back('v'); + break; + case '"': + buf.push_back('\\'); + buf.push_back('"'); + break; + } + } + buf.push_back('"'); + } + + } // namespace + namespace zeek::Broker { @@ -1658,7 +1709,7 @@ void Manager::ProcessError(broker::error_view err) msg += broker::to_string(ctx->network); msg += ", "; if ( auto what = err.message() ) - msg += *what; + print_escaped(msg, *what); else msg += R"_("")_"; msg += ')'; diff --git a/src/probabilistic/BitVector.cc b/src/probabilistic/BitVector.cc index f18915a77f..d724a54e7f 100644 --- a/src/probabilistic/BitVector.cc +++ b/src/probabilistic/BitVector.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "zeek/digest.h" From 9e5c4ae700ea1da32e1ff836810668931a23e314 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 5 Jan 2022 10:28:26 +0000 Subject: [PATCH 019/204] Clang-format updates --- src/analyzer/protocol/ssl/DTLS.cc | 3 +- src/analyzer/protocol/ssl/DTLS.h | 3 +- src/analyzer/protocol/ssl/SSL.cc | 82 ++++++++++++++++--------------- src/analyzer/protocol/ssl/SSL.h | 8 +-- 4 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/analyzer/protocol/ssl/DTLS.cc b/src/analyzer/protocol/ssl/DTLS.cc index 67def99641..7ddd714989 100644 --- a/src/analyzer/protocol/ssl/DTLS.cc +++ b/src/analyzer/protocol/ssl/DTLS.cc @@ -76,7 +76,8 @@ void DTLS_Analyzer::SendHandshake(uint16_t raw_tls_version, uint8_t msg_type, ui } } -bool DTLS_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version) +bool DTLS_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, + uint8_t content_type, uint16_t raw_tls_version) { // noop for now as DTLS decryption is currently not supported return false; diff --git a/src/analyzer/protocol/ssl/DTLS.h b/src/analyzer/protocol/ssl/DTLS.h index d0d798f9df..34f69fba65 100644 --- a/src/analyzer/protocol/ssl/DTLS.h +++ b/src/analyzer/protocol/ssl/DTLS.h @@ -39,7 +39,8 @@ public: static analyzer::Analyzer* Instantiate(Connection* conn) { return new DTLS_Analyzer(conn); } - bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version); + bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, + uint16_t raw_tls_version); protected: binpac::DTLS::SSL_Conn* interp; diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index cd606285bc..2d49906d76 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -1,5 +1,9 @@ #include "zeek/analyzer/protocol/ssl/SSL.h" +#include +#include +#include + #include "zeek/Reporter.h" #include "zeek/analyzer/Manager.h" #include "zeek/analyzer/protocol/ssl/events.bif.h" @@ -8,12 +12,8 @@ #include "zeek/analyzer/protocol/tcp/TCP_Reassembler.h" #include "zeek/util.h" -#include -#include -#include - #ifdef OPENSSL_HAVE_KDF_H - #include +#include #endif #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) @@ -24,10 +24,10 @@ static void print_hex(std::string name, u_char* data, int len) { int i = 0; printf("%s (%d): ", name.c_str(), len); - if (len > 0) + if ( len > 0 ) printf("0x%02x", data[0]); - for (i = 1; i < len; i++) + for ( i = 1; i < len; i++ ) { printf(" 0x%02x", data[i]); } @@ -37,14 +37,14 @@ static void print_hex(std::string name, u_char* data, int len) namespace zeek::analyzer::ssl { -#define MSB(a) ((a>>8)&0xff) -#define LSB(a) (a&0xff) +#define MSB(a) ((a >> 8) & 0xff) +#define LSB(a) (a & 0xff) static void fmt_seq(uint32_t num, u_char* buf) { memset(buf, 0, 8); uint32_t netnum = htonl(num); - memcpy(buf+4, &netnum, 4); + memcpy(buf + 4, &netnum, 4); } SSL_Analyzer::SSL_Analyzer(Connection* c) : analyzer::tcp::TCP_ApplicationAnalyzer("SSL", c) @@ -161,19 +161,20 @@ void SSL_Analyzer::SetKeys(size_t len, const u_char* data) std::copy(data, data + len, std::back_inserter(keys)); } -bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label, - const char* rnd1, size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len) +bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1, + size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, + size_t out_len) { #ifdef OPENSSL_HAVE_KDF_H #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) // alloc context + params - EVP_KDF *kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF* kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); + EVP_KDF_CTX* kctx = EVP_KDF_CTX_new(kdf); OSSL_PARAM params[4], *p = params; EVP_KDF_free(kdf); #else /* OSSL 3 */ // alloc buffers - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); + EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); #endif /* OSSL 3 */ // prepare seed: seed = label + rnd1 + rnd2 @@ -189,15 +190,16 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label // setup OSSL_PARAM array: digest, secret, seed // FIXME: sha384 should not be hardcoded *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha384, strlen(SN_sha384)); - *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, (void*)secret.data(), secret.size()); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, (void*)secret.data(), + secret.size()); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void*)seed.data(), seed.size()); *p = OSSL_PARAM_construct_end(); // set OSSL params - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) + if ( EVP_KDF_CTX_set_params(kctx, params) <= 0 ) goto abort; // derive key material - if (EVP_KDF_derive(kctx, out, out_len, NULL) <= 0) + if ( EVP_KDF_derive(kctx, out, out_len, NULL) <= 0 ) goto abort; EVP_KDF_CTX_free(kctx); @@ -207,17 +209,17 @@ abort: EVP_KDF_CTX_free(kctx); return false; #else /* OSSL 3 */ - if (EVP_PKEY_derive_init(pctx) <= 0) + if ( EVP_PKEY_derive_init(pctx) <= 0 ) goto abort; /* Error */ // setup PKEY params: digest, secret, seed // FIXME: sha384 should not be hardcoded - if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0) + if ( EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha384()) <= 0 ) goto abort; /* Error */ - if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret.data(), secret.size()) <= 0) + if ( EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, secret.data(), secret.size()) <= 0 ) goto abort; /* Error */ - if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.size()) <= 0) + if ( EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.size()) <= 0 ) goto abort; /* Error */ - if (EVP_PKEY_derive(pctx, out, &out_len) <= 0) + if ( EVP_PKEY_derive(pctx, out, &out_len) <= 0 ) goto abort; /* Error */ EVP_PKEY_CTX_free(pctx); @@ -231,8 +233,8 @@ abort: return false; } - -bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version) +bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, + uint8_t content_type, uint16_t raw_tls_version) { // Unsupported cipher suite. Currently supported: // - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 == 0xC030 @@ -248,7 +250,8 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i { DBG_LOG(DBG_ANALYZER, "Could not decrypt packet due to missing keys/secret.\n"); // FIXME: change util function to return a printably std::string for DBG_LOG - //print_hex("->client_random:", handshake_interp->client_random().data(), handshake_interp->client_random().size()); + // print_hex("->client_random:", handshake_interp->client_random().data(), + // handshake_interp->client_random().size()); return false; } @@ -257,7 +260,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i { #ifdef OPENSSL_HAVE_KDF_H DBG_LOG(DBG_ANALYZER, "Deriving TLS keys for connection foo"); - uint32_t ts = htonl((uint32_t) handshake_interp->gmt_unix_time()); + uint32_t ts = htonl((uint32_t)handshake_interp->gmt_unix_time()); char crand[32] = {0x00}; u_char keybuf[72]; @@ -267,9 +270,9 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i memcpy(crand, &(ts), 4); memcpy(crand + 4, c_rnd.data(), c_rnd.length()); - auto res = TLS12_PRF(secret, "key expansion", - (char*)s_rnd.data(), s_rnd.length(), crand, sizeof(crand), keybuf, sizeof(keybuf)); - if ( !res ) + auto res = TLS12_PRF(secret, "key expansion", (char*)s_rnd.data(), s_rnd.length(), crand, + sizeof(crand), keybuf, sizeof(keybuf)); + if ( ! res ) { DBG_LOG(DBG_ANALYZER, "TLS PRF failed. Aborting.\n"); return false; @@ -278,7 +281,8 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i // save derived keys SetKeys(sizeof(keybuf), keybuf); #else - DBG_LOG(DBG_ANALYZER, "Cannot derive TLS keys as Zeek was compiled without "); + DBG_LOG(DBG_ANALYZER, + "Cannot derive TLS keys as Zeek was compiled without "); #endif } @@ -323,7 +327,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i memcpy(s_aead_nonce, s_iv, 4); memcpy(&(s_aead_nonce[4]), encrypted, 8); - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_CipherInit(ctx, EVP_aes_256_gcm(), NULL, NULL, 0); @@ -333,13 +337,13 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i encrypted_len -= 16; // FIXME: aes_256_gcm should not be hardcoded here ;) - if (is_orig) + if ( is_orig ) EVP_DecryptInit(ctx, EVP_aes_256_gcm(), c_wk, s_aead_nonce); else EVP_DecryptInit(ctx, EVP_aes_256_gcm(), s_wk, s_aead_nonce); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, encrypted + encrypted_len); - if (is_orig) + if ( is_orig ) fmt_seq(c_seq, s_aead_tag); else fmt_seq(s_seq, s_aead_tag); @@ -350,18 +354,18 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i s_aead_tag[11] = MSB(encrypted_len); s_aead_tag[12] = LSB(encrypted_len); - u_char *decrypted = new u_char[ encrypted_len ]; + u_char* decrypted = new u_char[encrypted_len]; int decrypted_len = 0; EVP_DecryptUpdate(ctx, NULL, &decrypted_len, s_aead_tag, 13); - EVP_DecryptUpdate(ctx, decrypted, &decrypted_len, (const u_char*) encrypted, encrypted_len); + EVP_DecryptUpdate(ctx, decrypted, &decrypted_len, (const u_char*)encrypted, encrypted_len); int res = 0; - if ( ! ( res = EVP_DecryptFinal(ctx, NULL, &res) ) ) + if ( ! (res = EVP_DecryptFinal(ctx, NULL, &res)) ) { DBG_LOG(DBG_ANALYZER, "Decryption failed with return code: %d. Invalid key?\n", res); EVP_CIPHER_CTX_free(ctx); - delete [] decrypted; + delete[] decrypted; return false; } @@ -369,7 +373,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i EVP_CIPHER_CTX_free(ctx); ForwardDecryptedData(decrypted_len, reinterpret_cast(decrypted), is_orig); - delete [] decrypted; + delete[] decrypted; return true; } diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index 3d8c13e93c..630531aabb 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -97,7 +97,8 @@ public: * * @param raw_tls_version Raw TLS version as given in the TLS packets */ - bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version); + bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, + uint16_t raw_tls_version); /** * TLS 1.2 pseudo random function (PRF) used to expand the pre-master secret and derive keys. @@ -121,7 +122,8 @@ public: * * @return True, if the operation completed successfully, false otherwise */ - bool TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1, size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len); + bool TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1, + size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len); /** * Forward decrypted TLS application data to child analyzers @@ -144,7 +146,7 @@ protected: int s_seq; std::string secret; std::vector keys; - zeek::analyzer::pia::PIA_TCP *pia; + zeek::analyzer::pia::PIA_TCP* pia; }; } // namespace zeek::analyzer::ssl From f77213ba66b0fa15ba4f0d13145a1fe3cb15cda9 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 5 Jan 2022 10:41:55 +0000 Subject: [PATCH 020/204] Deprecation and warning fixes --- src/analyzer/protocol/ssl/SSL.cc | 3 ++- src/analyzer/protocol/ssl/ssl-analyzer.pac | 6 +++--- src/analyzer/protocol/ssl/tls-handshake-analyzer.pac | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 2d49906d76..d46c92b120 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -189,7 +189,8 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) // setup OSSL_PARAM array: digest, secret, seed // FIXME: sha384 should not be hardcoded - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha384, strlen(SN_sha384)); + // The const-cast is a bit ugly - but otherwise we have to copy the static string. + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, const_cast(SN_sha384), 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, (void*)secret.data(), secret.size()); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void*)seed.data(), seed.size()); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index d676630ae8..3f7543c39f 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -14,11 +14,11 @@ refine connection SSL_Conn += { %{ if ( ! version_ok(version) ) { - zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); + zeek_analyzer()->AnalyzerViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); zeek_analyzer()->SetSkip(true); } else - zeek_analyzer()->ProtocolConfirmation(); + zeek_analyzer()->AnalyzerConfirmation(); if ( ssl_client_hello ) { @@ -69,7 +69,7 @@ refine connection SSL_Conn += { %{ if ( ! version_ok(version) ) { - zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); + zeek_analyzer()->AnalyzerViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); zeek_analyzer()->SetSkip(true); } diff --git a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac index 589921e6b3..0f222ae682 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-analyzer.pac @@ -37,11 +37,11 @@ refine connection Handshake_Conn += { %{ if ( ! version_ok(version) ) { - zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); + zeek_analyzer()->AnalyzerViolation(zeek::util::fmt("unsupported client SSL version 0x%04x", version)); zeek_analyzer()->SetSkip(true); } else - zeek_analyzer()->ProtocolConfirmation(); + zeek_analyzer()->AnalyzerConfirmation(); if ( ssl_client_hello ) { @@ -94,7 +94,7 @@ refine connection Handshake_Conn += { %{ if ( ! version_ok(version) ) { - zeek_analyzer()->ProtocolViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); + zeek_analyzer()->AnalyzerViolation(zeek::util::fmt("unsupported server SSL version 0x%04x", version)); zeek_analyzer()->SetSkip(true); } From 4204615997bab79c65af1d497865cdc78ba4ed1b Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 5 Jan 2022 10:50:28 +0000 Subject: [PATCH 021/204] SSL decryption: small style changes, a bit of documentation --- scripts/policy/protocols/ssl/decryption.zeek | 23 +++++--------------- src/analyzer/protocol/ssl/DTLS.h | 7 ++++++ src/analyzer/protocol/ssl/SSL.h | 5 ++++- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek index a8bb7e52e9..75c1d345b6 100644 --- a/scripts/policy/protocols/ssl/decryption.zeek +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -20,11 +20,11 @@ export { # Do not disable analyzers after detection - otherwise we will not receive # encrypted packets. -redef SSL::disable_analyzer_after_detection=F; +redef SSL::disable_analyzer_after_detection = F; redef record SSL::Info += { - # Decryption uses client_random as identifier - client_random: string &log &optional; + # Decryption uses client_random as identifier + client_random: string &log &optional; }; type Idx: record { @@ -55,12 +55,12 @@ event zeek_init() event SSL::add_keys(client_random: string, val: string) { - SSL::keys[client_random] = val; + SSL::keys[client_random] = val; } event SSL::add_secret(client_random: string, val: string) { - SSL::secrets[client_random] = val; + SSL::secrets[client_random] = val; } event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) @@ -68,13 +68,9 @@ event ssl_client_hello(c: connection, version: count, record_version: count, pos c$ssl$client_random = client_random; if ( client_random in keys ) - { set_keys(c, keys[client_random]); - } else if ( client_random in secrets ) - { set_secret(c, secrets[client_random]); - } } event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) @@ -82,17 +78,12 @@ event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, co if ( c$ssl?$client_random ) { if ( c$ssl$client_random in keys ) - { set_keys(c, keys[c$ssl$client_random]); - } else if ( c$ssl$client_random in secrets ) - { set_secret(c, secrets[c$ssl$client_random]); - } else { - # FIXME: replace with @if gated reporter - #print "No suitable key or secret found for random:", c$ssl$client_random; + # FIXME: perhaps report that we could not decrypt the session } } } @@ -105,7 +96,5 @@ event SSL::tls_input_done() event Input::end_of_data(name: string, source: string) { if ( name == input_stream_name ) - { event SSL::tls_input_done(); - } } diff --git a/src/analyzer/protocol/ssl/DTLS.h b/src/analyzer/protocol/ssl/DTLS.h index 34f69fba65..1642cb4a6c 100644 --- a/src/analyzer/protocol/ssl/DTLS.h +++ b/src/analyzer/protocol/ssl/DTLS.h @@ -39,6 +39,13 @@ public: static analyzer::Analyzer* Instantiate(Connection* conn) { return new DTLS_Analyzer(conn); } + /** + * Try to decrypt TLS application data from a packet. + * + * For DTLS, this operation is not currently implemented and this function will + * always return false. + * + **/ bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version); diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index 630531aabb..b96172fc1b 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -141,11 +141,14 @@ protected: binpac::TLSHandshake::Handshake_Conn* handshake_interp; bool had_gap; - // FIXME: should this be moved into the connection? + // client and server sequence number, used for TLS 1.2 decryption int c_seq; int s_seq; + // secret, for decyption std::string secret; + // derived keys, for decryption std::vector keys; + // PIA, for decrypted data zeek::analyzer::pia::PIA_TCP* pia; }; From c04246bd7c6840ce5ae97e8d4f85f5f7bb8b9542 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 5 Jan 2022 15:42:48 +0000 Subject: [PATCH 022/204] SSL decryption: refactor TLS12_PRF Less use of raw pointers. --- src/analyzer/protocol/ssl/SSL.cc | 77 ++++++++++++++------------------ src/analyzer/protocol/ssl/SSL.h | 7 +-- 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index d46c92b120..2cc072f0cd 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -20,20 +20,6 @@ #include #endif -static void print_hex(std::string name, u_char* data, int len) - { - int i = 0; - printf("%s (%d): ", name.c_str(), len); - if ( len > 0 ) - printf("0x%02x", data[0]); - - for ( i = 1; i < len; i++ ) - { - printf(" 0x%02x", data[i]); - } - printf("\n"); - } - namespace zeek::analyzer::ssl { @@ -149,21 +135,21 @@ void SSL_Analyzer::SetSecret(size_t len, const u_char* data) secret.append((const char*)data, len); } -void SSL_Analyzer::SetKeys(zeek::StringVal* keys) - { - SetKeys(keys->Len(), keys->Bytes()); - } - -void SSL_Analyzer::SetKeys(size_t len, const u_char* data) +void SSL_Analyzer::SetKeys(zeek::StringVal* nkeys) { keys.clear(); - keys.reserve(len); - std::copy(data, data + len, std::back_inserter(keys)); + keys.reserve(nkeys->Len()); + std::copy(nkeys->Bytes(), nkeys->Bytes() + nkeys->Len(), std::back_inserter(keys)); } -bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1, - size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, - size_t out_len) +void SSL_Analyzer::SetKeys(const std::vector newkeys) + { + keys = newkeys; + } + +std::optional> +SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label, + const std::string& rnd1, const std::string& rnd2, size_t requested_len) { #ifdef OPENSSL_HAVE_KDF_H #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) @@ -178,13 +164,12 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label #endif /* OSSL 3 */ // prepare seed: seed = label + rnd1 + rnd2 - size_t seed_len = label.size() + rnd1_len + rnd2_len; std::string seed{}; - seed.reserve(seed_len); + seed.reserve(label.size() + rnd1.size() + rnd2.size()); seed.append(label); - seed.append(rnd1, rnd1_len); - seed.append(rnd2, rnd2_len); + seed.append(rnd1); + seed.append(rnd2); #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) // setup OSSL_PARAM array: digest, secret, seed @@ -196,20 +181,23 @@ bool SSL_Analyzer::TLS12_PRF(const std::string& secret, const std::string& label *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void*)seed.data(), seed.size()); *p = OSSL_PARAM_construct_end(); + auto keybuf = std::vector(requested_len); + // set OSSL params if ( EVP_KDF_CTX_set_params(kctx, params) <= 0 ) goto abort; // derive key material - if ( EVP_KDF_derive(kctx, out, out_len, NULL) <= 0 ) + if ( EVP_KDF_derive(kctx, keybuf.data(), requested_len, nullptr) <= 0 ) goto abort; EVP_KDF_CTX_free(kctx); - return true; + return keybuf; abort: EVP_KDF_CTX_free(kctx); - return false; + return {}; #else /* OSSL 3 */ + auto keybuf = std::vector(requested_len); if ( EVP_PKEY_derive_init(pctx) <= 0 ) goto abort; /* Error */ // setup PKEY params: digest, secret, seed @@ -220,18 +208,18 @@ abort: goto abort; /* Error */ if ( EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed.data(), seed.size()) <= 0 ) goto abort; /* Error */ - if ( EVP_PKEY_derive(pctx, out, &out_len) <= 0 ) + if ( EVP_PKEY_derive(pctx, keybuf.data(), &requested_len) <= 0 ) goto abort; /* Error */ EVP_PKEY_CTX_free(pctx); - return true; + return keubuf; abort: EVP_PKEY_CTX_free(pctx); #endif /* OSSL 3 */ #endif /* HAVE_KDF */ - return false; + return {}; } bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool is_orig, @@ -260,19 +248,19 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i if ( secret.size() != 0 && keys.size() == 0 ) { #ifdef OPENSSL_HAVE_KDF_H - DBG_LOG(DBG_ANALYZER, "Deriving TLS keys for connection foo"); + DBG_LOG(DBG_ANALYZER, "Deriving TLS keys for connection"); uint32_t ts = htonl((uint32_t)handshake_interp->gmt_unix_time()); - char crand[32] = {0x00}; - u_char keybuf[72]; - auto c_rnd = handshake_interp->client_random(); auto s_rnd = handshake_interp->server_random(); - memcpy(crand, &(ts), 4); - memcpy(crand + 4, c_rnd.data(), c_rnd.length()); - auto res = TLS12_PRF(secret, "key expansion", (char*)s_rnd.data(), s_rnd.length(), crand, - sizeof(crand), keybuf, sizeof(keybuf)); + std::string crand; + crand.append(reinterpret_cast(&(ts)), 4); + crand.append(reinterpret_cast(c_rnd.data()), c_rnd.length()); + std::string srand(reinterpret_cast(s_rnd.data()), s_rnd.length()); + + // fixme - 72 should not be hardcoded + auto res = TLS12_PRF(secret, "key expansion", srand, crand, 72); if ( ! res ) { DBG_LOG(DBG_ANALYZER, "TLS PRF failed. Aborting.\n"); @@ -280,10 +268,11 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i } // save derived keys - SetKeys(sizeof(keybuf), keybuf); + SetKeys(res.value()); #else DBG_LOG(DBG_ANALYZER, "Cannot derive TLS keys as Zeek was compiled without "); + return false; #endif } diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index b96172fc1b..b19bd0b6c0 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -82,7 +82,7 @@ public: * * @param data Pointer to the key buffer as derived via TLS PRF */ - void SetKeys(size_t len, const u_char* data); + void SetKeys(const std::vector newkeys); /** * Try to decrypt TLS application data from a packet. Requires secret or keys to be set prior @@ -122,8 +122,9 @@ public: * * @return True, if the operation completed successfully, false otherwise */ - bool TLS12_PRF(const std::string& secret, const std::string& label, const char* rnd1, - size_t rnd1_len, const char* rnd2, size_t rnd2_len, u_char* out, size_t out_len); + std::optional> TLS12_PRF(const std::string& secret, + const std::string& label, const std::string& rnd1, + const std::string& rnd2, size_t requested_len); /** * Forward decrypted TLS application data to child analyzers From 543c992e6629893c93c97e39be3b555e6f4d9b77 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 11 Jan 2022 11:20:05 +0000 Subject: [PATCH 023/204] Small code fix and test baseline update. After this, tests hopefully should pass consistently. --- src/analyzer/protocol/ssl/SSL.cc | 2 +- testing/btest/Baseline/coverage.bare-mode-errors/errors | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 2cc072f0cd..8d580c03fc 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -212,7 +212,7 @@ abort: goto abort; /* Error */ EVP_PKEY_CTX_free(pctx); - return keubuf; + return keybuf; abort: EVP_PKEY_CTX_free(pctx); diff --git a/testing/btest/Baseline/coverage.bare-mode-errors/errors b/testing/btest/Baseline/coverage.bare-mode-errors/errors index 31f9346536..880d44d1ad 100644 --- a/testing/btest/Baseline/coverage.bare-mode-errors/errors +++ b/testing/btest/Baseline/coverage.bare-mode-errors/errors @@ -1,9 +1,9 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### NOTE: This file has been sorted with diff-sort. -warning in <...>/extract-certs-pem.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:12 "Remove in v5.1. Use log-certs-base64.zeek instead." +warning in <...>/extract-certs-pem.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:13 "Remove in v5.1. Use log-certs-base64.zeek instead." warning in <...>/extract-certs-pem.zeek, line 1: deprecated script loaded from command line arguments "Remove in v5.1. Use log-certs-base64.zeek instead." warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:59 ("Remove in v5.1. OCSP logging is now enabled by default") warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:59 ("Remove in v5.1. OCSP logging is now enabled by default") warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from command line arguments ("Remove in v5.1. OCSP logging is now enabled by default") -warning in <...>/notary.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:4 ("Remove in v5.1. Please switch to other more modern approaches like SCT validation (validate-sct.zeek).") +warning in <...>/notary.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:5 ("Remove in v5.1. Please switch to other more modern approaches like SCT validation (validate-sct.zeek).") warning in <...>/notary.zeek, line 1: deprecated script loaded from command line arguments ("Remove in v5.1. Please switch to other more modern approaches like SCT validation (validate-sct.zeek).") From b78f30339fc25bf65d4ae20a6ed4dd4240693066 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 17 Jan 2022 12:15:40 +0000 Subject: [PATCH 024/204] TLS decryption: refactoring, more comments, less bare pointers This commit refactors TLS decryption, adds more comments in scripts and in C++ source-code, and removes use of bare pointers, instead relying more on stl data types. --- scripts/policy/protocols/ssl/decryption.zeek | 88 ++++++++++------- scripts/test-all-policy.zeek | 2 +- src/analyzer/protocol/ssl/SSL.cc | 99 ++++++++++--------- src/analyzer/protocol/ssl/SSL.h | 57 +++++++---- src/analyzer/protocol/ssl/functions.bif | 43 ++++++-- .../protocol/ssl/ssl-dtls-analyzer.pac | 13 ++- .../policy/protocols/ssl/decryption.zeek | 4 +- 7 files changed, 186 insertions(+), 120 deletions(-) diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek index 75c1d345b6..81ed2ee33e 100644 --- a/scripts/policy/protocols/ssl/decryption.zeek +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -1,4 +1,10 @@ -#! Decrypt SSL/TLS payloads +##! This script allows for the decryption of certain TLS 1.2 connection, if the user is in possession +##! of the private key material for the session. Key material can either be provided via a file (useful +##! for processing trace files) or via sending events via broker (for live decoding). +##! +##! Please note that this feature is experimental and can change without guarantees to our typical +##! deprecation tieline. Please also note that currently only TLS 1.2 connections that use the +##! TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 cipher suite are supported. @load base/frameworks/input @load base/frameworks/notice @@ -7,49 +13,69 @@ module SSL; -export { - const keylog_file = getenv("ZEEK_TLS_KEYLOG_FILE") &redef; - - global secrets: table[string] of string = {} &redef; - global keys: table[string] of string = {} &redef; - - global add_keys: event(client_random: string, keys: string); - - global add_secret: event(client_random: string, secret: string); -} - # Do not disable analyzers after detection - otherwise we will not receive # encrypted packets. redef SSL::disable_analyzer_after_detection = F; +export { + ## This can be set to a file that contains the session secrets for decryption, when parsing a pcap file. + ## Please note that, when using this feature, you probably want to pause processing of data till this + ## file has been read. + const keylog_file = getenv("ZEEK_TLS_KEYLOG_FILE") &redef; + + ## Secrets expire after this time of not being used. + const secret_expiration = 5 mins &redef; + + ## This event can be triggered, e.g., via broker to add known keys to the TLS key database. + ## + ## client_random: client random for which the key is set + ## + ## keys: key material + global add_keys: event(client_random: string, keys: string); + + ## This event can be triggered, e.g., via broker to add known secrets to the TLS secret datbase. + ## + ## client_random: client random for which the secret is set + ## + ## secrets: derived TLS secrets material + global add_secret: event(client_random: string, secret: string); +} + +@if ( keylog_file == "" ) +# If a keylog file was given via an environment variable, let's disable secret expiration - that does not +# make sense for pcaps. +global secrets: table[string] of string = {} &redef; +global keys: table[string] of string = {} &redef; +@else +#global secrets: table[string] of string = {} &read_expire=secret_expiration &redef; +#global keys: table[string] of string = {} &read_expire=secret_expiration &redef; +@endif + + redef record SSL::Info += { # Decryption uses client_random as identifier - client_random: string &log &optional; + client_random: string &optional; }; -type Idx: record { +type SecretsIdx: record { client_random: string; }; -type Val: record { +type SecretsVal: record { secret: string; }; -const input_stream_name = "input-tls-keylog-file"; +const tls_decrypt_stream_name = "tls-keylog-file"; event zeek_init() { # listen for secrets Broker::subscribe("/zeek/tls/decryption"); - # FIXME: is such a functionality helpful? - # ingest keylog file if the environment is set if ( keylog_file != "" ) { - suspend_processing(); - - Input::add_table([$name=input_stream_name, $source=keylog_file, $destination=secrets, $idx=Idx, $val=Val, $want_record=F]); - Input::remove(input_stream_name); + Input::add_table([$name=tls_decrypt_stream_name, $source=keylog_file, $destination=secrets, $idx=SecretsIdx, $val=SecretsVal, $want_record=F]); + Input::remove(tls_decrypt_stream_name); } } @@ -66,6 +92,7 @@ event SSL::add_secret(client_random: string, val: string) event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) { c$ssl$client_random = client_random; + print "Client random!"; if ( client_random in keys ) set_keys(c, keys[client_random]); @@ -73,7 +100,7 @@ event ssl_client_hello(c: connection, version: count, record_version: count, pos set_secret(c, secrets[client_random]); } -event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, content_type: count, length: count) +event ssl_change_cipher_spec(c: connection, is_orig: bool) { if ( c$ssl?$client_random ) { @@ -81,20 +108,5 @@ event ssl_encrypted_data(c: connection, is_orig: bool, record_version: count, co set_keys(c, keys[c$ssl$client_random]); else if ( c$ssl$client_random in secrets ) set_secret(c, secrets[c$ssl$client_random]); - else - { - # FIXME: perhaps report that we could not decrypt the session - } } } - -event SSL::tls_input_done() - { - continue_processing(); - } - -event Input::end_of_data(name: string, source: string) - { - if ( name == input_stream_name ) - event SSL::tls_input_done(); - } diff --git a/scripts/test-all-policy.zeek b/scripts/test-all-policy.zeek index 10a7637422..6b1febf51b 100644 --- a/scripts/test-all-policy.zeek +++ b/scripts/test-all-policy.zeek @@ -116,7 +116,7 @@ @load protocols/ssh/geo-data.zeek @load protocols/ssh/interesting-hostnames.zeek @load protocols/ssh/software.zeek -#@load protocols/ssl/decryption.zeek +@load protocols/ssl/decryption.zeek @load protocols/ssl/expiring-certs.zeek # @load protocols/ssl/extract-certs-pem.zeek @load protocols/ssl/heartbleed.zeek diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 8d580c03fc..e968ccfef9 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -26,11 +26,14 @@ namespace zeek::analyzer::ssl #define MSB(a) ((a >> 8) & 0xff) #define LSB(a) (a & 0xff) -static void fmt_seq(uint32_t num, u_char* buf) +static std::basic_string fmt_seq(uint32_t num) { - memset(buf, 0, 8); + std::basic_string out(4, '\0'); + out.reserve(13); uint32_t netnum = htonl(num); - memcpy(buf + 4, &netnum, 4); + out.append(reinterpret_cast(&netnum), 4); + out.append(5, '\0'); + return out; } SSL_Analyzer::SSL_Analyzer(Connection* c) : analyzer::tcp::TCP_ApplicationAnalyzer("SSL", c) @@ -124,9 +127,9 @@ void SSL_Analyzer::Undelivered(uint64_t seq, int len, bool orig) interp->NewGap(orig, len); } -void SSL_Analyzer::SetSecret(zeek::StringVal* secret) +void SSL_Analyzer::SetSecret(const zeek::StringVal& secret) { - SetSecret(secret->Len(), secret->Bytes()); + SetSecret(secret.Len(), secret.Bytes()); } void SSL_Analyzer::SetSecret(size_t len, const u_char* data) @@ -135,11 +138,11 @@ void SSL_Analyzer::SetSecret(size_t len, const u_char* data) secret.append((const char*)data, len); } -void SSL_Analyzer::SetKeys(zeek::StringVal* nkeys) +void SSL_Analyzer::SetKeys(const zeek::StringVal& nkeys) { keys.clear(); - keys.reserve(nkeys->Len()); - std::copy(nkeys->Bytes(), nkeys->Bytes() + nkeys->Len(), std::back_inserter(keys)); + keys.reserve(nkeys.Len()); + std::copy(nkeys.Bytes(), nkeys.Bytes() + nkeys.Len(), std::back_inserter(keys)); } void SSL_Analyzer::SetKeys(const std::vector newkeys) @@ -282,40 +285,38 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i // FIXME: could also print keys or conn id here DBG_LOG(DBG_ANALYZER, "Decrypting application data"); + // NOTE: you must not call functions that invalidate keys.data() on keys during the + // remainder of this function. (Given that we do not manipulate the key material in this + // function that should not be hard) + // client write_key - u_char c_wk[32]; + const u_char* c_wk = keys.data(); // server write_key - u_char s_wk[32]; + const u_char* s_wk = keys.data() + 32; // client IV - u_char c_iv[4]; + const u_char* c_iv = keys.data() + 64; // server IV - u_char s_iv[4]; - - // AEAD nonce & tag - u_char s_aead_nonce[12]; - u_char s_aead_tag[13]; - - // FIXME: there should be a better way to do these copies - memcpy(c_wk, keys.data(), 32); - memcpy(s_wk, keys.data() + 32, 32); - memcpy(c_iv, keys.data() + 64, 4); - memcpy(s_iv, keys.data() + 68, 4); + const u_char* s_iv = keys.data() + 68; // FIXME: should we change types here? u_char* encrypted = (u_char*)data; size_t encrypted_len = len; - // FIXME: should this be moved to SSL_Conn? if ( is_orig ) c_seq++; else s_seq++; + // AEAD nonce, length 12 + std::basic_string s_aead_nonce; if ( is_orig ) - memcpy(s_aead_nonce, c_iv, 4); + s_aead_nonce.assign(c_iv, 4); else - memcpy(s_aead_nonce, s_iv, 4); - memcpy(&(s_aead_nonce[4]), encrypted, 8); + s_aead_nonce.assign(s_iv, 4); + + // this should be the explicit counter + s_aead_nonce.append(encrypted, 8); + assert(s_aead_nonce.size() == 12); EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); @@ -323,47 +324,60 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i encrypted += 8; // FIXME: is this because of nonce and aead tag? + if ( encrypted_len <= (16 + 8) ) + { + DBG_LOG(DBG_ANALYZER, "Invalid encrypted length encountered during TLS decryption"); + EVP_CIPHER_CTX_free(ctx); + return false; + } encrypted_len -= 8; encrypted_len -= 16; // FIXME: aes_256_gcm should not be hardcoded here ;) if ( is_orig ) - EVP_DecryptInit(ctx, EVP_aes_256_gcm(), c_wk, s_aead_nonce); + EVP_DecryptInit(ctx, EVP_aes_256_gcm(), c_wk, s_aead_nonce.data()); else - EVP_DecryptInit(ctx, EVP_aes_256_gcm(), s_wk, s_aead_nonce); + EVP_DecryptInit(ctx, EVP_aes_256_gcm(), s_wk, s_aead_nonce.data()); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, encrypted + encrypted_len); + // AEAD tag + std::basic_string s_aead_tag; if ( is_orig ) - fmt_seq(c_seq, s_aead_tag); + s_aead_tag = fmt_seq(c_seq); else - fmt_seq(s_seq, s_aead_tag); + s_aead_tag = fmt_seq(s_seq); s_aead_tag[8] = content_type; s_aead_tag[9] = MSB(raw_tls_version); s_aead_tag[10] = LSB(raw_tls_version); s_aead_tag[11] = MSB(encrypted_len); s_aead_tag[12] = LSB(encrypted_len); + assert(s_aead_tag.size() == 13); - u_char* decrypted = new u_char[encrypted_len]; + auto decrypted = std::vector( + encrypted_len + + 16); // see OpenSSL manpage - 16 is the block size for the supported cipher int decrypted_len = 0; - EVP_DecryptUpdate(ctx, NULL, &decrypted_len, s_aead_tag, 13); - EVP_DecryptUpdate(ctx, decrypted, &decrypted_len, (const u_char*)encrypted, encrypted_len); + EVP_DecryptUpdate(ctx, NULL, &decrypted_len, s_aead_tag.data(), s_aead_tag.size()); + EVP_DecryptUpdate(ctx, decrypted.data(), &decrypted_len, (const u_char*)encrypted, + encrypted_len); + assert(decrypted_len <= decrypted.size()); + decrypted.resize(decrypted_len); int res = 0; if ( ! (res = EVP_DecryptFinal(ctx, NULL, &res)) ) { DBG_LOG(DBG_ANALYZER, "Decryption failed with return code: %d. Invalid key?\n", res); EVP_CIPHER_CTX_free(ctx); - delete[] decrypted; return false; } DBG_LOG(DBG_ANALYZER, "Successfully decrypted %d bytes.", decrypted_len); EVP_CIPHER_CTX_free(ctx); - ForwardDecryptedData(decrypted_len, reinterpret_cast(decrypted), is_orig); + ForwardDecryptedData(decrypted, is_orig); - delete[] decrypted; return true; } @@ -371,7 +385,7 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i return false; } -void SSL_Analyzer::ForwardDecryptedData(int len, const u_char* data, bool is_orig) +void SSL_Analyzer::ForwardDecryptedData(const std::vector& data, bool is_orig) { if ( ! pia ) { @@ -383,18 +397,9 @@ void SSL_Analyzer::ForwardDecryptedData(int len, const u_char* data, bool is_ori } else reporter->FatalError("Could not initialize PIA"); - - // FIXME: Also statically add HTTP/H2 at the moment. - // We should move this bit to scriptland - auto http = analyzer_mgr->InstantiateAnalyzer("HTTP", Conn()); - if ( http ) - AddChildAnalyzer(http); - auto http2 = analyzer_mgr->InstantiateAnalyzer("HTTP2", Conn()); - if ( http2 ) - AddChildAnalyzer(http2); } - ForwardStream(len, data, is_orig); + ForwardStream(data.size(), data.data(), is_orig); } } // namespace zeek::analyzer::ssl diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index b19bd0b6c0..415dcd9129 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -25,6 +25,9 @@ namespace zeek::analyzer::ssl class SSL_Analyzer final : public analyzer::tcp::TCP_ApplicationAnalyzer { + // let binpac forward encryppted TLS application data to us. + friend class binpac::SSL::SSL_Conn; + public: explicit SSL_Analyzer(Connection* conn); ~SSL_Analyzer() override; @@ -50,14 +53,20 @@ public: * Set the secret that should be used to derive keys for the * connection. (For TLS 1.2 this is the pre-master secret) * + * Please note that these functions currently are hardcoded to only work with a single TLS 1.2 + * cuphersuite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). + * * @param secret The secret to set */ - void SetSecret(StringVal* secret); + void SetSecret(const StringVal& secret); /** * Set the secret that should be used to derive keys for the * connection. (For TLS 1.2 this is the pre-master secret) * + * Please note that these functions currently are hardcoded to only work with a single TLS 1.2 + * cuphersuite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). + * * @param len Length of the secret bytes * * @param data Pointer to the secret bytes @@ -68,24 +77,32 @@ public: * Set the decryption keys that should be used to decrypt * TLS application data in the connection. * + * Please note that these functions currently are hardcoded to only work with a single TLS 1.2 + * cuphersuite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). + * * @param keys The key buffer as derived via TLS PRF (for * AES_GCM this should be 72 bytes in length) */ - void SetKeys(StringVal* keys); + void SetKeys(const StringVal& keys); /** * Set the decryption keys that should be used to decrypt * TLS application data in the connection. * - * @param len Length of the key buffer (for AES_GCM this should - * be 72) + * Please note that these functions currently are hardcoded to only work with a single TLS 1.2 + * cuphersuite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). * - * @param data Pointer to the key buffer as derived via TLS PRF + * @param keys The key buffer as derived via TLS PRF (for + * AES_GCM this should be 72 bytes in length) */ void SetKeys(const std::vector newkeys); +protected: /** - * Try to decrypt TLS application data from a packet. Requires secret or keys to be set prior + * Try to decrypt TLS application data from a packet. Requires secret or keys to be set prior. + * + * Please note that these functions currently are hardcoded to only work with a single TLS 1.2 + * cuphersuite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). * * @param len Length of the encrypted bytes to decrypt * @@ -96,48 +113,46 @@ public: * @param content_type Content type as given in the TLS packet * * @param raw_tls_version Raw TLS version as given in the TLS packets + * + * @return True if decryption succeeded and data was forwarded. */ bool TryDecryptApplicationData(int len, const u_char* data, bool is_orig, uint8_t content_type, uint16_t raw_tls_version); /** * TLS 1.2 pseudo random function (PRF) used to expand the pre-master secret and derive keys. - * The seed is obtained by concatinating rnd1 and rnd2 + * The seed is obtained by concatinating rnd1 and rnd2. + * + * Please note that these functions currently are hardcoded to only work with a single TLS 1.2 + * cuphersuite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). * * @param secret Secret as defined in the TLS RFC * * @param label Label as defined in the TLS RFC * - * @param rnd1 Pointer to the first part of the seed + * @param First part of the seed * - * @param rnd1_len Length of the first part of the seed - * - * @param rnd2 Pointer to the second part of the seed + * @param rnd2 Second part of the seed * * @param rnd2_len Length of the second part of the seed * - * @param out Pointer to the derived bytes + * @param requested_len Length indicating how many bytes should be derived * - * @param out_len Length indicating how many bytes should be derived - * - * @return True, if the operation completed successfully, false otherwise + * @return The derived bytes, if the operation succeeds. */ std::optional> TLS12_PRF(const std::string& secret, const std::string& label, const std::string& rnd1, const std::string& rnd2, size_t requested_len); /** - * Forward decrypted TLS application data to child analyzers + * Forward decrypted TLS application data to child analyzers. * - * @param len Length of the data to forward - * - * @param data Pointer to the data to forward + * @param data Data to forward * * @param is_orig Direction of the connection */ - void ForwardDecryptedData(int len, const u_char* data, bool is_orig); + void ForwardDecryptedData(const std::vector& data, bool is_orig); -protected: binpac::SSL::SSL_Conn* interp; binpac::TLSHandshake::Handshake_Conn* handshake_interp; bool had_gap; diff --git a/src/analyzer/protocol/ssl/functions.bif b/src/analyzer/protocol/ssl/functions.bif index 19661ad4f3..75e4d3c26a 100644 --- a/src/analyzer/protocol/ssl/functions.bif +++ b/src/analyzer/protocol/ssl/functions.bif @@ -9,32 +9,59 @@ ## finished succesfully). ## ## c: The SSL connection. -function set_ssl_established%(c: connection%): any +## +## Returns: T on success, F on failure. +function set_ssl_established%(c: connection%): bool %{ zeek::analyzer::Analyzer* sa = c->FindAnalyzer("SSL"); + if ( sa ) + { static_cast(sa)->StartEncryption(); - return nullptr; + return zeek::val_mgr->True(); + } + + return zeek::val_mgr->False(); %} +## Set the secret that should be used to derive keys for the connection. +## (For TLS 1.2 this is the pre-master secret). +## +## c: The affected connection +## +## secret: secret to set +## +## Returns: T on success, F on failure. function set_secret%(c: connection, secret: string%): bool %{ analyzer::Analyzer* sa = c->FindAnalyzer("SSL"); + if ( sa ) - { - static_cast(sa)->SetSecret(secret); + { + static_cast(sa)->SetSecret(*secret); return zeek::val_mgr->True(); - } + } + return zeek::val_mgr->False(); %} +## Set the decryption keys that should be used to decrypt +## TLS application data in the connection. +## +## c: The affected connection +## +## keys: The key buffer as derived via TLS PRF. +## +## Returns: T on success, F on failure. function set_keys%(c: connection, keys: string%): bool %{ analyzer::Analyzer* sa = c->FindAnalyzer("SSL"); + if ( sa ) - { - static_cast(sa)->SetKeys(keys); + { + static_cast(sa)->SetKeys(*keys); return zeek::val_mgr->True(); - } + } + return zeek::val_mgr->False(); %} diff --git a/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac b/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac index 1d97ad7e1a..32849bd910 100644 --- a/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac @@ -13,10 +13,12 @@ refine connection SSL_Conn += { %member{ int established_; + int decryption_failed_; %} %init{ established_ = false; + decryption_failed_ = false; %} %cleanup{ @@ -65,10 +67,13 @@ refine connection SSL_Conn += { { zeek::BifEvent::enqueue_ssl_encrypted_data(zeek_analyzer(), zeek_analyzer()->Conn(), ${rec.is_orig}, ${rec.raw_tls_version}, ${rec.content_type}, ${rec.length}); - if (rec->content_type() == APPLICATION_DATA) - { - zeek_analyzer()->TryDecryptApplicationData(cont.length(), cont.data(), rec->is_orig(), rec->content_type(), rec->raw_tls_version()); - } + } + + if ( rec->content_type() == APPLICATION_DATA && decryption_failed_ == false ) + { + // If decryption of one packet fails, do not try to decrypt future packets. + if ( ! zeek_analyzer()->TryDecryptApplicationData(cont.length(), cont.data(), rec->is_orig(), rec->content_type(), rec->raw_tls_version()) ) + decryption_failed_ = true; } return true; diff --git a/testing/btest/scripts/policy/protocols/ssl/decryption.zeek b/testing/btest/scripts/policy/protocols/ssl/decryption.zeek index 741284a540..71dea5e41d 100644 --- a/testing/btest/scripts/policy/protocols/ssl/decryption.zeek +++ b/testing/btest/scripts/policy/protocols/ssl/decryption.zeek @@ -1,11 +1,13 @@ # @TEST-REQUIRES: grep -q "#define OPENSSL_HAVE_KDF_H" $BUILD/zeek-config.h -# @TEST-EXEC: zeek -b -C -r $TRACES/tls/tls12-decryption.pcap %INPUT +# @TEST-EXEC: zeek -B dpd -C -r $TRACES/tls/tls12-decryption.pcap %INPUT # @TEST-EXEC: btest-diff http.log @load protocols/ssl/decryption @load base/protocols/http +module SSL; + redef SSL::secrets += { ["\xb4\x0a\x24\x4b\x48\xe4\x2e\xac\x28\x71\x44\xb1\xb7\x39\x30\x57\xca\xa1\x31\xf9\x61\xa7\x8e\x38\xb0\xe7\x7c\x1e"] = "\xbd\x01\xe5\x89\xd1\x05\x19\x9e\x9a\xb5\xfc\x9b\xd7\x58\xb5\xf2\x88\xdb\x28\xfd\x80\xaa\x02\x26\x1e\x47\x65\xac\x13\x57\xd0\x07\xfd\x08\xc7\xbd\xab\x45\x45\x0e\x01\x5a\x01\xd0\x8e\x5e\x7c\xa6", }; From 7ec2fa2ac9e282e9661b1f9e72e5e690fa2dc059 Mon Sep 17 00:00:00 2001 From: Zeke Date: Wed, 19 Jan 2022 10:03:41 -0800 Subject: [PATCH 025/204] Consistently warn about mixing vector and scalar operand depreciaton Resolves #1890 --- src/Expr.cc | 38 +++++++++++++++++-- src/Expr.h | 18 +++++++++ testing/btest/Baseline/core.scalar-vector/out | 16 ++++++++ testing/btest/core/scalar-vector.zeek | 20 ++++++++++ 4 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 testing/btest/Baseline/core.scalar-vector/out create mode 100644 testing/btest/core/scalar-vector.zeek diff --git a/src/Expr.cc b/src/Expr.cc index 396a860cab..daf0f2000d 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -13,11 +13,13 @@ #include "zeek/Hash.h" #include "zeek/IPAddr.h" #include "zeek/RE.h" +#include "zeek/Reporter.h" #include "zeek/RunState.h" #include "zeek/Scope.h" #include "zeek/Stmt.h" #include "zeek/Traverse.h" #include "zeek/Trigger.h" +#include "zeek/Type.h" #include "zeek/broker/Data.h" #include "zeek/digest.h" #include "zeek/module_util.h" @@ -1219,9 +1221,6 @@ void BinaryExpr::PromoteOps(TypeTag t) if ( is_vec2 ) bt2 = op2->GetType()->AsVectorType()->Yield()->Tag(); - if ( (is_vec1 || is_vec2) && ! (is_vec1 && is_vec2) ) - reporter->Warning("mixing vector and scalar operands is deprecated"); - if ( bt1 != t ) op1 = make_intrusive(op1, t); if ( bt2 != t ) @@ -1249,6 +1248,25 @@ void BinaryExpr::PromoteForInterval(ExprPtr& op) op = make_intrusive(op, TYPE_DOUBLE); } +bool BinaryExpr::IsScalarAggregateOp() const + { + const bool is_vec1 = IsAggr(op1->GetType()->Tag()) || is_list(op1); + const bool is_vec2 = IsAggr(op2->GetType()->Tag()) || is_list(op2); + const bool either_vec = is_vec1 || is_vec2; + const bool both_vec = is_vec1 && is_vec2; + + return either_vec && ! both_vec; + } + +void BinaryExpr::CheckScalarAggOp() const + { + if ( ! IsError() && IsScalarAggregateOp() ) + { + reporter->Warning("mixing vector and scalar operands is deprecated (%s) (%s)", + type_name(op1->GetType()->Tag()), type_name(op2->GetType()->Tag())); + } + } + CloneExpr::CloneExpr(ExprPtr arg_op) : UnaryExpr(EXPR_CLONE, std::move(arg_op)) { if ( IsError() ) @@ -1520,6 +1538,8 @@ AddExpr::AddExpr(ExprPtr arg_op1, ExprPtr arg_op2) else ExprError("requires arithmetic operands"); + CheckScalarAggOp(); + if ( base_result_type ) { if ( is_vector(op1) || is_vector(op2) ) @@ -1652,6 +1672,8 @@ SubExpr::SubExpr(ExprPtr arg_op1, ExprPtr arg_op2) else ExprError("requires arithmetic operands"); + CheckScalarAggOp(); + if ( base_result_type ) { if ( is_vector(op1) || is_vector(op2) ) @@ -1728,6 +1750,8 @@ TimesExpr::TimesExpr(ExprPtr arg_op1, ExprPtr arg_op2) PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); else ExprError("requires arithmetic operands"); + + CheckScalarAggOp(); } void TimesExpr::Canonicize() @@ -1776,6 +1800,8 @@ DivideExpr::DivideExpr(ExprPtr arg_op1, ExprPtr arg_op2) else ExprError("requires arithmetic operands"); + + CheckScalarAggOp(); } ValPtr DivideExpr::AddrFold(Val* v1, Val* v2) const @@ -1823,6 +1849,8 @@ ModExpr::ModExpr(ExprPtr arg_op1, ExprPtr arg_op2) PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); else ExprError("requires integral operands"); + + CheckScalarAggOp(); } BoolExpr::BoolExpr(BroExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) @@ -2086,6 +2114,8 @@ EqExpr::EqExpr(BroExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) else ExprError("type clash in comparison"); + + CheckScalarAggOp(); } void EqExpr::Canonicize() @@ -2166,6 +2196,8 @@ RelExpr::RelExpr(BroExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2) else if ( bt1 != TYPE_TIME && bt1 != TYPE_INTERVAL && bt1 != TYPE_PORT && bt1 != TYPE_ADDR && bt1 != TYPE_STRING ) ExprError("illegal comparison"); + + CheckScalarAggOp(); } void RelExpr::Canonicize() diff --git a/src/Expr.h b/src/Expr.h index fabf0915b3..026e65ed84 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -622,6 +622,14 @@ protected: void ExprDescribe(ODesc* d) const override; + // Reports on if this BinaryExpr involves a scalar and + // aggregate type (vec, list, table, record). + bool IsScalarAggregateOp() const; + + // Warns about depreciated scalar vector operations like + // `[1, 2, 3] == 1` or `["a", "b", "c"] + "a"`. + void CheckScalarAggOp() const; + ExprPtr op1; ExprPtr op2; }; @@ -1801,5 +1809,15 @@ inline bool is_vector(const ExprPtr& e) return is_vector(e.get()); } +// True if the given Expr* has a list type +inline bool is_list(Expr* e) + { + return e->GetType()->Tag() == TYPE_LIST; + } +inline bool is_list(const ExprPtr& e) + { + return is_list(e.get()); + } + } // namespace detail } // namespace zeek diff --git a/testing/btest/Baseline/core.scalar-vector/out b/testing/btest/Baseline/core.scalar-vector/out new file mode 100644 index 0000000000..49b3872f4c --- /dev/null +++ b/testing/btest/Baseline/core.scalar-vector/out @@ -0,0 +1,16 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +warning in <...>/scalar-vector.zeek, line 7: mixing vector and scalar operands is deprecated (string) (vector) +warning in <...>/scalar-vector.zeek, line 8: mixing vector and scalar operands is deprecated (vector) (string) +warning in <...>/scalar-vector.zeek, line 9: mixing vector and scalar operands is deprecated (string) (vector) +warning in <...>/scalar-vector.zeek, line 13: mixing vector and scalar operands is deprecated (count) (vector) +warning in <...>/scalar-vector.zeek, line 14: mixing vector and scalar operands is deprecated (count) (vector) +warning in <...>/scalar-vector.zeek, line 15: mixing vector and scalar operands is deprecated (vector) (count) +warning in <...>/scalar-vector.zeek, line 16: mixing vector and scalar operands is deprecated (vector) (count) +[F, T, F] +[aa, ba, ca] +[aa, ab, ac] +[F, T, F] +[2, 4, 6] +[1, 0, 1] +[0, 1, 1] +[1, 2, 3, 1] diff --git a/testing/btest/core/scalar-vector.zeek b/testing/btest/core/scalar-vector.zeek new file mode 100644 index 0000000000..3382066816 --- /dev/null +++ b/testing/btest/core/scalar-vector.zeek @@ -0,0 +1,20 @@ +# @TEST-EXEC: zeek -b %INPUT > out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath" btest-diff out + +event zeek_init() + { + const sv = vector("a", "b", "c"); + print sv == "b"; + print sv + "a"; + print "a" + sv; + + + const nv = vector(1, 2, 3); + print nv == 2; + print nv * 2; + print nv % 2; + print nv / 2; + + const also_nv = nv += 1; + print nv; + } From 404c43e36c24b57e31048b7c04ad6494d332114a Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 14 Jan 2022 19:09:00 -0800 Subject: [PATCH 026/204] CI update: add CentOS Stream 9 --- .cirrus.yml | 9 ++++++++- ci/centos-stream-9/Dockerfile | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 ci/centos-stream-9/Dockerfile diff --git a/.cirrus.yml b/.cirrus.yml index e91b0091b7..458f734d5a 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -108,9 +108,16 @@ fedora34_task: << : *RESOURCES_TEMPLATE << : *CI_TEMPLATE +centosstream9_task: + container: + # Stream 9 EOL: Around Dec 2027 + dockerfile: ci/centos-stream-9/Dockerfile + << : *RESOURCES_TEMPLATE + << : *CI_TEMPLATE + centosstream8_task: container: - # Stream 8 support should be 5 years, so until 2024. but I cannot find a concrete timeline --cpk + # Stream 8 EOL: May 31, 2024 dockerfile: ci/centos-stream-8/Dockerfile << : *RESOURCES_TEMPLATE << : *CI_TEMPLATE diff --git a/ci/centos-stream-9/Dockerfile b/ci/centos-stream-9/Dockerfile new file mode 100644 index 0000000000..0ad201521d --- /dev/null +++ b/ci/centos-stream-9/Dockerfile @@ -0,0 +1,36 @@ +FROM quay.io/centos/centos:stream9 + +# dnf config-manager isn't available at first, and +# we need it to install the CRB repo below. +RUN dnf -y install 'dnf-command(config-manager)' + +# What used to be powertools is now called "CRB". +# We need it for some of the packages installed below. +# https://docs.fedoraproject.org/en-US/epel/ +RUN dnf config-manager --set-enabled crb +RUN dnf -y install \ + https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \ + https://dl.fedoraproject.org/pub/epel/epel-next-release-latest-9.noarch.rpm + +# The --nobest flag is hopefully temporary. Without it we currently hit +# package versioning conflicts around OpenSSL. +RUN dnf -y --nobest install \ + bison \ + cmake \ + diffutils \ + flex \ + git \ + gcc \ + gcc-c++ \ + libpcap-devel \ + make \ + openssl-devel \ + python3-devel \ + python3-pip\ + sqlite \ + swig \ + which \ + zlib-devel \ + && dnf clean all && rm -rf /var/cache/dnf + +RUN pip3 install junit2html From 1de58030f2054c3f2d14958140059d9339c70dfc Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 14 Jan 2022 19:16:47 -0800 Subject: [PATCH 027/204] CI update: remove OpenSUSE Leap 15.2 (EOL) --- .cirrus.yml | 7 ------- ci/opensuse-leap-15.2/Dockerfile | 25 ------------------------- 2 files changed, 32 deletions(-) delete mode 100644 ci/opensuse-leap-15.2/Dockerfile diff --git a/.cirrus.yml b/.cirrus.yml index 458f734d5a..490102b7fd 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -167,13 +167,6 @@ debian9_32bit_task: << : *RESOURCES_TEMPLATE << : *CI_TEMPLATE -opensuse_leap_15_2_task: - container: - # Opensuse Leap 15.2 EOL: Dec 2021 - dockerfile: ci/opensuse-leap-15.2/Dockerfile - << : *RESOURCES_TEMPLATE - << : *CI_TEMPLATE - opensuse_leap_15_3_task: container: # Opensuse Leap 15.3 EOL: TBD diff --git a/ci/opensuse-leap-15.2/Dockerfile b/ci/opensuse-leap-15.2/Dockerfile deleted file mode 100644 index 7b23204cde..0000000000 --- a/ci/opensuse-leap-15.2/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM opensuse/leap:15.2 - -RUN zypper in -y \ - cmake \ - make \ - gcc \ - gcc-c++ \ - python3 \ - python3-devel \ - flex \ - bison \ - libpcap-devel \ - libopenssl-devel \ - zlib-devel \ - swig \ - git \ - curl \ - python3-pip \ - which \ - gzip \ - tar \ - && rm -rf /var/cache/zypp - - -RUN pip3 install junit2html From 8e24f848575877948095adaa788fa8d654107cd5 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 14 Jan 2022 19:55:18 -0800 Subject: [PATCH 028/204] CI update: add Ubuntu 21.10 --- .cirrus.yml | 7 +++++++ ci/ubuntu-21.10/Dockerfile | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 ci/ubuntu-21.10/Dockerfile diff --git a/.cirrus.yml b/.cirrus.yml index 490102b7fd..65d1ef8b06 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -174,6 +174,13 @@ opensuse_leap_15_3_task: << : *RESOURCES_TEMPLATE << : *CI_TEMPLATE +ubuntu21_task: + container: + # Ubuntu 21.10 EOL: July 2022 + dockerfile: ci/ubuntu-21.10/Dockerfile + << : *RESOURCES_TEMPLATE + << : *CI_TEMPLATE + ubuntu20_task: container: # Ubuntu 20.04 EOL: April 2025 diff --git a/ci/ubuntu-21.10/Dockerfile b/ci/ubuntu-21.10/Dockerfile new file mode 100644 index 0000000000..4a51a122e9 --- /dev/null +++ b/ci/ubuntu-21.10/Dockerfile @@ -0,0 +1,33 @@ +FROM ubuntu:21.10 + +ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles" + +RUN apt-get update && apt-get -y install \ + git \ + cmake \ + make \ + gcc \ + g++ \ + flex \ + bison \ + libpcap-dev \ + libssl-dev \ + python3 \ + python3-dev \ + python3-pip\ + swig \ + zlib1g-dev \ + libmaxminddb-dev \ + libkrb5-dev \ + bsdmainutils \ + sqlite3 \ + curl \ + wget \ + unzip \ + ruby \ + bc \ + lcov \ + && rm -rf /var/lib/apt/lists/* + +RUN pip3 install junit2html +RUN gem install coveralls-lcov From d758585e429af31e9cb14367e5d74e479f65cab2 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 24 Jan 2022 14:26:20 -0800 Subject: [PATCH 029/204] updated Bro->Zeek in comments in the source tree --- src/DbgBreakpoint.h | 2 +- src/DbgDisplay.h | 2 +- src/DbgHelp.cc | 2 +- src/DbgWatch.h | 2 +- src/Debug.cc | 2 +- src/Debug.h | 2 +- src/DebugCmds.cc | 2 +- src/DebugCmds.h | 2 +- src/Event.cc | 2 +- src/EventRegistry.h | 2 +- src/PolicyFile.h | 2 +- src/RandTest.cc | 2 +- src/RuleCondition.h | 2 +- src/RuleMatcher.h | 2 +- src/RunState.cc | 4 +- src/RunState.h | 6 +- src/ScriptCoverageManager.h | 4 +- src/Val.h | 4 +- src/ZeekString.h | 4 +- src/analyzer/Analyzer.h | 10 +-- src/analyzer/Component.h | 2 +- src/analyzer/Manager.h | 4 +- src/analyzer/protocol/mime/MIME.cc | 2 +- src/analyzer/protocol/mime/MIME.h | 2 +- src/analyzer/protocol/pop3/POP3.cc | 2 +- src/analyzer/protocol/pop3/POP3.h | 2 +- src/analyzer/protocol/rpc/NFS.h | 2 +- src/analyzer/protocol/tcp/ContentLine.cc | 2 +- src/broker/Data.cc | 2 +- src/broker/Data.h | 22 +++--- src/broker/Manager.h | 6 +- src/file_analysis/Manager.h | 6 +- src/file_analysis/analyzer/x509/X509.h | 4 +- src/input/Manager.cc | 10 +-- src/input/Manager.h | 10 +-- src/input/ReaderBackend.h | 4 +- src/input/readers/config/Config.cc | 2 +- src/iosource/BPF_Program.cc | 2 +- src/iosource/Component.h | 4 +- src/iosource/IOSource.h | 2 +- src/iosource/Manager.h | 4 +- src/iosource/PktSrc.cc | 2 +- src/logging/Manager.h | 2 +- src/logging/WriterBackend.h | 4 +- src/logging/writers/ascii/Ascii.cc | 2 +- src/module_util.h | 2 +- src/packet_analysis/Analyzer.h | 2 +- .../protocol/tcp/TCPSessionAdapter.cc | 2 +- src/plugin/Component.h | 2 +- src/plugin/Manager.h | 22 +++--- src/plugin/Plugin.h | 70 +++++++++---------- src/probabilistic/Hasher.h | 4 +- src/probabilistic/Topk.h | 6 +- src/re-scan.l | 2 +- src/rule-scan.l | 2 +- src/telemetry/Manager.h | 2 +- src/threading/BasicThread.h | 16 ++--- src/threading/Formatter.h | 2 +- src/threading/Manager.h | 2 +- src/threading/MsgThread.h | 20 +++--- src/threading/Queue.h | 2 +- src/threading/SerialTypes.cc | 2 +- src/util.h | 2 +- src/version.c.in | 2 +- src/zeek-setup.cc | 2 +- src/zeekygen/Manager.cc | 8 +-- src/zeekygen/Manager.h | 24 +++---- src/zeekygen/ScriptInfo.cc | 2 +- src/zeekygen/ScriptInfo.h | 2 +- src/zeekygen/Target.cc | 2 +- src/zeekygen/Target.h | 2 +- 71 files changed, 186 insertions(+), 186 deletions(-) diff --git a/src/DbgBreakpoint.h b/src/DbgBreakpoint.h index 788d19ac18..f5af59d7a8 100644 --- a/src/DbgBreakpoint.h +++ b/src/DbgBreakpoint.h @@ -1,4 +1,4 @@ -// Structures and methods for implementing breakpoints in the Bro debugger. +// Structures and methods for implementing breakpoints in the Zeek debugger. #pragma once diff --git a/src/DbgDisplay.h b/src/DbgDisplay.h index 7b4ed086c4..09af4b230e 100644 --- a/src/DbgDisplay.h +++ b/src/DbgDisplay.h @@ -1,4 +1,4 @@ -// Structures and methods for implementing watches in the Bro debugger. +// Structures and methods for implementing watches in the Zeek debugger. #pragma once diff --git a/src/DbgHelp.cc b/src/DbgHelp.cc index 373f0c0613..7f346b9a14 100644 --- a/src/DbgHelp.cc +++ b/src/DbgHelp.cc @@ -1,4 +1,4 @@ -// Bro Debugger Help +// Zeek Debugger Help #include "zeek/zeek-config.h" diff --git a/src/DbgWatch.h b/src/DbgWatch.h index 8bfda57c16..22715c2195 100644 --- a/src/DbgWatch.h +++ b/src/DbgWatch.h @@ -1,4 +1,4 @@ -// Structures and methods for implementing watches in the Bro debugger. +// Structures and methods for implementing watches in the Zeek debugger. #pragma once diff --git a/src/Debug.cc b/src/Debug.cc index 469d016f2d..d63cef512c 100644 --- a/src/Debug.cc +++ b/src/Debug.cc @@ -1,4 +1,4 @@ -// Debugging support for Bro policy files. +// Debugging support for Zeek policy files. #include "zeek/Debug.h" diff --git a/src/Debug.h b/src/Debug.h index a006f35971..06bc483b98 100644 --- a/src/Debug.h +++ b/src/Debug.h @@ -1,4 +1,4 @@ -// Debugging support for Bro policy files. +// Debugging support for Zeek policy files. #pragma once diff --git a/src/DebugCmds.cc b/src/DebugCmds.cc index 3f69bccbd7..dbb150d716 100644 --- a/src/DebugCmds.cc +++ b/src/DebugCmds.cc @@ -1,4 +1,4 @@ -// Support routines to help deal with Bro debugging commands and +// Support routines to help deal with Zeek debugging commands and // implementation of most commands. #include "zeek/DebugCmds.h" diff --git a/src/DebugCmds.h b/src/DebugCmds.h index 4a0d511cae..35a0a773cd 100644 --- a/src/DebugCmds.h +++ b/src/DebugCmds.h @@ -1,4 +1,4 @@ -// Support routines to help deal with Bro debugging commands and +// Support routines to help deal with Zeek debugging commands and // implementation of most commands. #pragma once diff --git a/src/Event.cc b/src/Event.cc index c6dfc5365a..0ae98f8fab 100644 --- a/src/Event.cc +++ b/src/Event.cc @@ -136,7 +136,7 @@ void EventMgr::Drain() draining = true; - // Past Bro versions drained as long as there events, including when + // Past Zeek versions drained as long as there events, including when // a handler queued new events during its execution. This could lead // to endless loops in case a handler kept triggering its own event. // We now limit this to just a couple of rounds. We do more than diff --git a/src/EventRegistry.h b/src/EventRegistry.h index 5b48334bbc..a0dd10d69e 100644 --- a/src/EventRegistry.h +++ b/src/EventRegistry.h @@ -1,4 +1,4 @@ -// Each event raised/handled by Bro is registered in the EventRegistry. +// Each event raised/handled by Zeek is registered in the EventRegistry. #pragma once diff --git a/src/PolicyFile.h b/src/PolicyFile.h index d85883cb0b..8631bc3c55 100644 --- a/src/PolicyFile.h +++ b/src/PolicyFile.h @@ -8,7 +8,7 @@ // (probably in the lexer). Then later any function that so desires // can call a relevant function. Note that since it caches the contents, // changes to the policy files will not be reflected until restart, -// which is probably good since it'll always display the code that Bro +// which is probably good since it'll always display the code that Zeek // is actually using. // policy_filename arguments should be absolute or relative paths; diff --git a/src/RandTest.cc b/src/RandTest.cc index 1422993695..5062c6968d 100644 --- a/src/RandTest.cc +++ b/src/RandTest.cc @@ -9,7 +9,7 @@ without fee is hereby granted, without any conditions or restrictions. This software is provided “as is” without express or implied warranty. - Modified for Bro by Seth Hall - July 2010 + Modified for Zeek/Bro by Seth Hall - July 2010 */ #include "zeek/RandTest.h" diff --git a/src/RuleCondition.h b/src/RuleCondition.h index c83e712b3e..e32a4553cc 100644 --- a/src/RuleCondition.h +++ b/src/RuleCondition.h @@ -122,7 +122,7 @@ private: Comp comp; }; -// Implements "eval" which evaluates the given Bro identifier. +// Implements "eval" which evaluates the given Zeek identifier. class RuleConditionEval : public RuleCondition { public: diff --git a/src/RuleMatcher.h b/src/RuleMatcher.h index 76599c117a..6713a623c0 100644 --- a/src/RuleMatcher.h +++ b/src/RuleMatcher.h @@ -74,7 +74,7 @@ using maskedvalue_list = PList; using string_list = PList; using bstr_list = PList; -// Get values from Bro's script-level variables. +// Get values from Zeek's script-level variables. extern void id_to_maskedvallist(const char* id, maskedvalue_list* append_to, std::vector* prefix_vector = nullptr); extern char* id_to_str(const char* id); diff --git a/src/RunState.cc b/src/RunState.cc index 3a8e367714..30abb987e0 100644 --- a/src/RunState.cc +++ b/src/RunState.cc @@ -190,7 +190,7 @@ void init_run(const std::optional& interface, if ( const auto& id = zeek::detail::global_scope()->Find("trace_output_file") ) id->SetVal(make_intrusive(writefile)); else - reporter->Error("trace_output_file not defined in bro.init"); + reporter->Error("trace_output_file not defined"); } zeek::detail::init_ip_addr_anonymizers(); @@ -472,7 +472,7 @@ double pseudo_realtime = 0.0; double network_time = 0.0; // time according to last packet timestamp // (or current time) double processing_start_time = 0.0; // time started working on current pkt -double zeek_start_time = 0.0; // time Bro started. +double zeek_start_time = 0.0; // time Zeek started. double zeek_start_network_time; // timestamp of first packet bool terminating = false; // whether we're done reading and finishing up bool is_parsing = false; diff --git a/src/RunState.h b/src/RunState.h index 6bba345b74..3b9171c483 100644 --- a/src/RunState.h +++ b/src/RunState.h @@ -93,10 +93,10 @@ extern double pseudo_realtime; // queue. extern double processing_start_time; -// When the Bro process was started. +// When the Zeek process was started. extern double zeek_start_time; -// Time at which the Bro process was started with respect to network time, +// Time at which the Zeek process was started with respect to network time, // i.e. the timestamp of the first packet. extern double zeek_start_network_time; @@ -106,7 +106,7 @@ extern double network_time; // True if we're a in the process of cleaning-up just before termination. extern bool terminating; -// True if Bro is currently parsing scripts. +// True if Zeek is currently parsing scripts. extern bool is_parsing; extern const zeek::Packet* current_pkt; diff --git a/src/ScriptCoverageManager.h b/src/ScriptCoverageManager.h index 702137d9ed..1cc74bb43d 100644 --- a/src/ScriptCoverageManager.h +++ b/src/ScriptCoverageManager.h @@ -13,7 +13,7 @@ namespace zeek::detail class Stmt; /** - * A simple class for managing stats of Bro script coverage across Bro runs. + * A simple class for managing stats of Zeek script coverage across Zeek runs. */ class ScriptCoverageManager { @@ -22,7 +22,7 @@ public: virtual ~ScriptCoverageManager(); /** - * Imports Bro script Stmt usage information from file pointed to by + * Imports Zeek script Stmt usage information from file pointed to by * environment variable ZEEK_PROFILER_FILE. * * @return: true if usage info was read, otherwise false. diff --git a/src/Val.h b/src/Val.h index e5ff5fcb77..abb2d8cbda 100644 --- a/src/Val.h +++ b/src/Val.h @@ -822,7 +822,7 @@ public: // Returns true if this set contains the same members as the // given set. Note that comparisons are done using hash keys, // so errors can arise for compound sets such as sets-of-sets. - // See https://bro-tracker.atlassian.net/browse/BIT-1949. + // See https://github.com/zeek/zeek/issues/151. bool EqualTo(const TableVal& v) const; // Returns true if this set is a subset (not necessarily proper) @@ -1355,7 +1355,7 @@ public: TableValPtr GetRecordFieldsVal() const; // This is an experiment to associate a Obj within the - // event engine to a record value in bro script. + // event engine to a record value in Zeek script. void SetOrigin(Obj* o) { origin = o; } Obj* GetOrigin() const { return origin; } diff --git a/src/ZeekString.h b/src/ZeekString.h index 9c0845dd0e..1f8ec84985 100644 --- a/src/ZeekString.h +++ b/src/ZeekString.h @@ -102,7 +102,7 @@ public: static constexpr int EXPANDED_STRING = // the original style ESC_HEX; - static constexpr int BRO_STRING_LITERAL = // as in a Bro string literal + static constexpr int BRO_STRING_LITERAL = // as in a Bro/Zeek string literal ESC_ESC | ESC_QUOT | ESC_HEX; // Renders a string into a newly allocated character array that @@ -193,7 +193,7 @@ extern int Bstr_cmp(const String* s1, const String* s2); // which would be necessary if String were used. Unlike String, // the string should not be deallocated on destruction. // -// "BroConstString" might be a better name here. +// "ZeekConstString" might be a better name here. struct data_chunk_t { diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 3d84632374..6d56fa129a 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -523,7 +523,7 @@ public: void RemoveSupportAnalyzer(SupportAnalyzer* analyzer); /** - * Signals Bro's protocol detection that the analyzer has recognized + * Signals Zeek's protocol detection that the analyzer has recognized * the input to indeed conform to the expected protocol. This should * be called as early as possible during a connection's life-time. It * may turn into \c protocol_confirmed event at the script-layer (but @@ -537,7 +537,7 @@ public: ProtocolConfirmation(zeek::Tag tag = zeek::Tag()); /** - * Signals Bro's protocol detection that the analyzer has found a + * Signals Zeek's protocol detection that the analyzer has found a * severe protocol violation that could indicate that it's not * parsing the expected protocol. This turns into \c * protocol_violation events at the script-layer (one such event is @@ -577,7 +577,7 @@ public: virtual void AnalyzerConfirmation(zeek::Tag tag = zeek::Tag()); /** - * Signals Bro's protocol detection that the analyzer has found a + * Signals Zeek's protocol detection that the analyzer has found a * severe protocol violation that could indicate that it's not * parsing the expected protocol. This turns into \c * analyzer_violation events at the script-layer (one such event is @@ -683,7 +683,7 @@ protected: * * @param t The absolute time when the timer will fire. * - * @param do_expire If true, the timer will also fire when Bro + * @param do_expire If true, the timer will also fire when Zeek * terminates even if \a t has not been reache yet. * * @param type The timer's type. @@ -899,7 +899,7 @@ private: SupportAnalyzer* sibling; }; -// The following need to be consistent with bro.init. +// The following need to be consistent with zeek.init. #define CONTENTS_NONE 0 #define CONTENTS_ORIG 1 #define CONTENTS_RESP 2 diff --git a/src/analyzer/Component.h b/src/analyzer/Component.h index 6588c512c9..323d31a823 100644 --- a/src/analyzer/Component.h +++ b/src/analyzer/Component.h @@ -83,7 +83,7 @@ public: /** * Returns whether the analyzer supports partial connections. Partial - * connections are those where Bro starts processing payload + * connections are those where Zeek starts processing payload * mid-stream, after missing the beginning. */ bool Partial() const { return partial; } diff --git a/src/analyzer/Manager.h b/src/analyzer/Manager.h index 74938c8941..c510e2d921 100644 --- a/src/analyzer/Manager.h +++ b/src/analyzer/Manager.h @@ -3,7 +3,7 @@ /** * The central management unit for registering and instantiating analyzers. * - * For each protocol that Bro supports, there's one class derived from + * For each protocol that Zeek supports, there's one class derived from * analyzer::Analyzer. Once we have decided that a connection's payload is to * be parsed as a given protocol, we instantiate the corresponding * analyzer-derived class and add the new instance as a child node into the @@ -71,7 +71,7 @@ public: /** * Second-stage initialization of the manager. This is called late - * during Bro's initialization after any scripts are processed. + * during Zeek's initialization after any scripts are processed. */ void InitPostScript(); diff --git a/src/analyzer/protocol/mime/MIME.cc b/src/analyzer/protocol/mime/MIME.cc index 00517beac7..51870e1c00 100644 --- a/src/analyzer/protocol/mime/MIME.cc +++ b/src/analyzer/protocol/mime/MIME.cc @@ -11,7 +11,7 @@ // Here are a few things to do: // -// 1. Add a Bro internal function 'stop_deliver_data_of_entity' so +// 1. Add a Zeek internal function 'stop_deliver_data_of_entity' so // that the engine does not decode and deliver further data for the // entity (which may speed up the engine by avoiding copying). // diff --git a/src/analyzer/protocol/mime/MIME.h b/src/analyzer/protocol/mime/MIME.h index 0fde98a44c..cdde47c5c7 100644 --- a/src/analyzer/protocol/mime/MIME.h +++ b/src/analyzer/protocol/mime/MIME.h @@ -191,7 +191,7 @@ protected: // The reason I separate MIME_Message as an abstract class is to // present the *interface* separated from its implementation to -// generate Bro events. +// generate Zeek events. class MIME_Message { diff --git a/src/analyzer/protocol/pop3/POP3.cc b/src/analyzer/protocol/pop3/POP3.cc index 6bf3f64fb3..bc88a279cd 100644 --- a/src/analyzer/protocol/pop3/POP3.cc +++ b/src/analyzer/protocol/pop3/POP3.cc @@ -1,4 +1,4 @@ -// This code contributed to Bro by Florian Schimandl, Hugh Dollman and +// This code contributed to Zeek/Bro by Florian Schimandl, Hugh Dollman and // Robin Sommer. #include "zeek/analyzer/protocol/pop3/POP3.h" diff --git a/src/analyzer/protocol/pop3/POP3.h b/src/analyzer/protocol/pop3/POP3.h index d5cecee222..8628b29a70 100644 --- a/src/analyzer/protocol/pop3/POP3.h +++ b/src/analyzer/protocol/pop3/POP3.h @@ -1,4 +1,4 @@ -// This code contributed to Bro by Florian Schimandl and Hugh Dollman. +// This code contributed to Zeek/Bro by Florian Schimandl and Hugh Dollman. // // An analyser for the POP3 protocol. diff --git a/src/analyzer/protocol/rpc/NFS.h b/src/analyzer/protocol/rpc/NFS.h index 2e54481c0c..3518a6c74e 100644 --- a/src/analyzer/protocol/rpc/NFS.h +++ b/src/analyzer/protocol/rpc/NFS.h @@ -68,7 +68,7 @@ protected: BifEnum::NFS3::status_t status); // Consumes the file data in the RPC message. Depending on NFS::return_data* consts - // in bro.init returns NULL or the data as string val: + // in zeek.init returns NULL or the data as string val: // * offset is the offset of the read/write call // * size is the amount of bytes read (or requested to be written), StringValPtr nfs3_file_data(const u_char*& buf, int& n, uint64_t offset, int size); diff --git a/src/analyzer/protocol/tcp/ContentLine.cc b/src/analyzer/protocol/tcp/ContentLine.cc index 50e1ad2b43..70963cbea4 100644 --- a/src/analyzer/protocol/tcp/ContentLine.cc +++ b/src/analyzer/protocol/tcp/ContentLine.cc @@ -349,7 +349,7 @@ void ContentLine_Analyzer::CheckNUL() void ContentLine_Analyzer::SkipBytesAfterThisLine(int64_t length) { - // This is a little complicated because Bro has to handle + // This is a little complicated because Zeek has to handle // both CR and CRLF as a line break. When a line is delivered, // it's possible that only a CR is seen, and we may not know // if an LF is following until we see the next packet. If an diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 80651fc822..43b14fe978 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -1173,7 +1173,7 @@ struct data_type_getter { // Note that Broker uses vectors to store record data, so there's // no actual way to tell if this data was originally associated - // with a Bro record. + // with a Zeek record. return BifType::Enum::Broker::DataType->GetEnumVal(BifEnum::Broker::VECTOR); } }; diff --git a/src/broker/Data.h b/src/broker/Data.h index b948f3744c..955bee07aa 100644 --- a/src/broker/Data.h +++ b/src/broker/Data.h @@ -33,8 +33,8 @@ extern OpaqueTypePtr opaque_of_record_iterator; TransportProto to_zeek_port_proto(broker::port::protocol tp); /** - * Create a Broker::Data value from a Bro value. - * @param v the Bro value to convert to a Broker data value. + * Create a Broker::Data value from a Zeek value. + * @param v the Zeek value to convert to a Broker data value. * @return a Broker::Data value, where the optional field is set if the conversion * was possible, else it is unset. */ @@ -56,17 +56,17 @@ RecordValPtr make_data_val(broker::data d); EnumValPtr get_data_type(RecordVal* v, zeek::detail::Frame* frame); /** - * Convert a Bro value to a Broker data value. - * @param v a Bro value. - * @return a Broker data value if the Bro value could be converted to one. + * Convert a Zeek value to a Broker data value. + * @param v a Zeek value. + * @return a Broker data value if the Zeek value could be converted to one. */ broker::expected val_to_data(const Val* v); /** - * Convert a Broker data value to a Bro value. + * Convert a Broker data value to a Zeek value. * @param d a Broker data value. * @param type the expected type of the value to return. - * @return a pointer to a new Bro value or a nullptr if the conversion was not + * @return a pointer to a new Zeek value or a nullptr if the conversion was not * possible. */ ValPtr data_to_val(broker::data d, Type* type); @@ -87,7 +87,7 @@ broker::data threading_field_to_data(const threading::Field* f); threading::Field* data_to_threading_field(broker::data d); /** - * A Bro value which wraps a Broker data value. + * A Zeek value which wraps a Broker data value. */ class DataVal : public OpaqueVal { @@ -99,7 +99,7 @@ public: ValPtr castTo(zeek::Type* t); bool canCastTo(zeek::Type* t) const; - // Returns the Bro type that scripts use to represent a Broker data + // Returns the Zeek type that scripts use to represent a Broker data // instance. This may be wrapping the opaque value inside another // type. static const TypePtr& ScriptDataType(); @@ -160,7 +160,7 @@ struct type_name_getter }; /** - * Retrieve Broker data value associated with a Broker::Data Bro value. + * Retrieve Broker data value associated with a Broker::Data Zeek value. * @param v a Broker::Data value. * @param f used to get location information on error. * @return a reference to the wrapped Broker data value. A runtime interpreter @@ -172,7 +172,7 @@ broker::data& opaque_field_to_data(zeek::RecordVal* v, zeek::detail::Frame* f); * Retrieve variant data from a Broker data value. * @tparam T a type that the variant may contain. * @param d a Broker data value to get variant data out of. - * @param tag a Bro tag which corresponds to T (just used for error reporting). + * @param tag a Zeek tag which corresponds to T (just used for error reporting). * @param f used to get location information on error. * @return a refrence to the requested type in the variant Broker data. * A runtime interpret exception is thrown if trying to access a type which diff --git a/src/broker/Manager.h b/src/broker/Manager.h index 867180e7e9..1a1b76cff2 100644 --- a/src/broker/Manager.h +++ b/src/broker/Manager.h @@ -77,7 +77,7 @@ struct Stats }; /** - * Manages various forms of communication between peer Bro processes + * Manages various forms of communication between peer Zeek processes * or other external applications via use of the Broker messaging library. */ class Manager : public iosource::IOSource @@ -96,7 +96,7 @@ public: ~Manager() override; /** - * Initialization of the manager. This is called late during Bro's + * Initialization of the manager. This is called late during Zeek's * initialization after any scripts are processed. */ void InitPostScript(); @@ -223,7 +223,7 @@ public: * @param topic a topic string associated with the event message. * Peers advertise interest by registering a subscription to some prefix * of this topic name. - * @param event a Bro event value. + * @param event a Zeek event value. * @return true if automatic event sending is now enabled. */ bool AutoPublishEvent(std::string topic, Val* event); diff --git a/src/file_analysis/Manager.h b/src/file_analysis/Manager.h index 5f48fddec7..30a78fef7c 100644 --- a/src/file_analysis/Manager.h +++ b/src/file_analysis/Manager.h @@ -49,13 +49,13 @@ public: /** * First-stage initializion of the manager. This is called early on - * during Bro's initialization, before any scripts are processed. + * during Zeek's initialization, before any scripts are processed. */ void InitPreScript(); /** * Second-stage initialization of the manager. This is called late - * during Bro's initialization after any scripts are processed. + * during Zeek's initialization after any scripts are processed. */ void InitPostScript(); @@ -384,7 +384,7 @@ protected: * Evaluate timeout policy for a file and remove the File object mapped to * \a file_id if needed. * @param file_id the file identifier/hash. - * @param is_termination whether the Manager (and probably Bro) is in a + * @param is_termination whether the Manager (and probably Zeek) is in a * terminating state. If true, then the timeout cannot be postponed. */ void Timeout(const std::string& file_id, bool is_terminating = run_state::terminating); diff --git a/src/file_analysis/analyzer/x509/X509.h b/src/file_analysis/analyzer/x509/X509.h index 033f86ab83..d4ad9b02d4 100644 --- a/src/file_analysis/analyzer/x509/X509.h +++ b/src/file_analysis/analyzer/x509/X509.h @@ -150,8 +150,8 @@ private: /** * This class wraps an OpenSSL X509 data structure. * - * We need these to be able to pass OpenSSL pointers around in Bro - * script-land. Otherwise, we cannot verify certificates from Bro + * We need these to be able to pass OpenSSL pointers around in Zeek + * script-land. Otherwise, we cannot verify certificates from Zeek * scriptland */ class X509Val : public OpaqueVal diff --git a/src/input/Manager.cc b/src/input/Manager.cc index 7dbef26ebb..a105739d21 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -30,7 +30,7 @@ namespace zeek::input /** * 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 - * HashKey*, because it is thrown into other Bro functions that need the + * HashKey*, because it is thrown into other Zeek functions that need the * complex structure of it. For everything we do (with values), we just take * the hash_t value and compare it directly with "==" */ @@ -1889,7 +1889,7 @@ void Manager::SendEvent(EventHandlerPtr ev, list events) const event_mgr.Enqueue(ev, std::move(vl), util::detail::SOURCE_LOCAL); } -// Convert a bro list value to a bro record value. +// Convert a Zeek list value to a Zeek record value. // I / we could think about moving this functionality to val.cc RecordVal* Manager::ListValToRecordVal(ListVal* list, RecordType* request_type, int* position) const { @@ -2067,7 +2067,7 @@ int Manager::GetValueLength(const Value* val) const } // Given a threading::value, copy the raw data bytes into *data and return how many bytes were -// copied. Used for hashing the values for lookup in the bro table +// copied. Used for hashing the values for lookup in the Zeek table int Manager::CopyValue(char* data, const int startpos, const Value* val) const { assert(val->present); // presence has to be checked elsewhere @@ -2243,7 +2243,7 @@ zeek::detail::HashKey* Manager::HashValues(const int num_elements, const Value* return key; } -// convert threading value to Bro value +// convert threading value to Zeek value // 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 occurred in the past and processing is aborted. @@ -2440,7 +2440,7 @@ Manager::Stream* Manager::FindStream(ReaderFrontend* reader) const return nullptr; } -// Function is called on Bro shutdown. +// Function is called on Zeek shutdown. // Signal all frontends that they will cease operation. void Manager::Terminate() { diff --git a/src/input/Manager.h b/src/input/Manager.h index 2928b4f23d..4d875ebe12 100644 --- a/src/input/Manager.h +++ b/src/input/Manager.h @@ -99,12 +99,12 @@ public: bool RemoveStream(const std::string& id); /** - * Signals the manager to shutdown at Bro's termination. + * Signals the manager to shutdown at Zeek's termination. */ void Terminate(); /** - * Checks if a Bro type can be used for data reading. Note that + * Checks if a Zeek type can be used for data reading. Note that * this function only applies to input streams; the logging framework * has an equivalent function; however we support logging of a wider * variety of types (e.g. functions). @@ -229,11 +229,11 @@ private: // startpos. int CopyValue(char* data, const int startpos, const threading::Value* val) const; - // Convert Threading::Value to an internal Bro Type (works with Records). + // Convert Threading::Value to an internal Zeek Type (works with Records). Val* ValueToVal(const Stream* i, const threading::Value* val, Type* request_type, bool& have_error) const; - // Convert Threading::Value to an internal Bro list type. + // Convert Threading::Value to an internal Zeek list type. Val* ValueToIndexVal(const Stream* i, int num_fields, const RecordType* type, const threading::Value* const* vals, bool& have_error) const; @@ -244,7 +244,7 @@ private: Val* RecordValToIndexVal(RecordVal* r) const; - // Converts a Bro ListVal to a RecordVal given the record type. + // Converts a Zeek ListVal to a RecordVal given the record type. RecordVal* ListValToRecordVal(ListVal* list, RecordType* request_type, int* position) const; // Internally signal errors, warnings, etc. diff --git a/src/input/ReaderBackend.h b/src/input/ReaderBackend.h index 60bc8690da..319a114dcd 100644 --- a/src/input/ReaderBackend.h +++ b/src/input/ReaderBackend.h @@ -300,7 +300,7 @@ protected: void Put(threading::Value** val); /** - * Method allowing a reader to delete a specific value from a Bro + * Method allowing a reader to delete a specific value from a Zeek * table. * * If the receiving stream is an event stream, only a removed event @@ -312,7 +312,7 @@ protected: void Delete(threading::Value** val); /** - * Method allowing a reader to clear a Bro table. + * Method allowing a reader to clear a Zeek table. * * If the receiving stream is an event stream, this is ignored. * diff --git a/src/input/readers/config/Config.cc b/src/input/readers/config/Config.cc index fb5201fcf0..f2a2a83590 100644 --- a/src/input/readers/config/Config.cc +++ b/src/input/readers/config/Config.cc @@ -239,7 +239,7 @@ bool Config::DoUpdate() // we only send the event if the underlying value has changed. Let's check that. // (Yes, this means we keep all configuration options in memory twice - once here in - // the reader and once in memory in Bro; that is difficult to change. + // the reader and once in memory in Zeek; that is difficult to change. auto search = option_values.find(key); if ( search != option_values.end() && search->second == value ) { diff --git a/src/iosource/BPF_Program.cc b/src/iosource/BPF_Program.cc index 13f15e14d8..a712a8745b 100644 --- a/src/iosource/BPF_Program.cc +++ b/src/iosource/BPF_Program.cc @@ -63,7 +63,7 @@ namespace zeek::iosource::detail { // Simple heuristic to identify filters that always match, so that we can -// skip the filtering in that case. "ip or not ip" is Bro's default filter. +// skip the filtering in that case. "ip or not ip" is Zeek's default filter. static bool filter_matches_anything(const char* filter) { return (! filter) || strlen(filter) == 0 || strcmp(filter, "ip or not ip") == 0; diff --git a/src/iosource/Component.h b/src/iosource/Component.h index e5f4bb18ca..3f6edc3023 100644 --- a/src/iosource/Component.h +++ b/src/iosource/Component.h @@ -115,7 +115,7 @@ public: /** * Generates a human-readable description of the component. This goes - * into the output of \c "bro -NN". + * into the output of \c "zeek -NN". */ void DoDescribe(ODesc* d) const override; @@ -164,7 +164,7 @@ public: /** * Generates a human-readable description of the component. This goes - * into the output of \c "bro -NN". + * into the output of \c "zeek -NN". */ void DoDescribe(ODesc* d) const override; diff --git a/src/iosource/IOSource.h b/src/iosource/IOSource.h index a6931120f7..8e863f78e1 100644 --- a/src/iosource/IOSource.h +++ b/src/iosource/IOSource.h @@ -6,7 +6,7 @@ namespace zeek::iosource { /** - * Interface class for components providing/consuming data inside Bro's main + * Interface class for components providing/consuming data inside Zeek's main * loop. */ class IOSource diff --git a/src/iosource/Manager.h b/src/iosource/Manager.h index cb8af3fe4c..5053bbd132 100644 --- a/src/iosource/Manager.h +++ b/src/iosource/Manager.h @@ -85,7 +85,7 @@ public: /** * Opens a new packet source. * - * @param path The interface or file name, as one would give to Bro \c -i. + * @param path The interface or file name, as one would give to zeek \c -i. * * @param is_live True if \a path represents a live interface, false * for a file. @@ -101,7 +101,7 @@ public: * * @param append True to append if \a path already exists. * - * @return The new packet dumper, or null if an error occured. + * @return The new packet dumper, or null if an error occurred. */ PktDumper* OpenPktDumper(const std::string& path, bool append); diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index 663fec53ad..8ac60485b7 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -110,7 +110,7 @@ void PktSrc::Closed() void PktSrc::Error(const std::string& msg) { - // We don't report this immediately, Bro will ask us for the error + // We don't report this immediately, Zeek will ask us for the error // once it notices we aren't open. errbuf = msg; DBG_LOG(DBG_PKTIO, "Error with source %s: %s", IsOpen() ? props.path.c_str() : "", diff --git a/src/logging/Manager.h b/src/logging/Manager.h index cd194fc797..fbdfc97e35 100644 --- a/src/logging/Manager.h +++ b/src/logging/Manager.h @@ -226,7 +226,7 @@ public: bool Flush(EnumVal* id); /** - * Signals the manager to shutdown at Bro's termination. + * Signals the manager to shutdown at Zeek's termination. */ void Terminate(); diff --git a/src/logging/WriterBackend.h b/src/logging/WriterBackend.h index 30203d26da..c9278a6257 100644 --- a/src/logging/WriterBackend.h +++ b/src/logging/WriterBackend.h @@ -243,7 +243,7 @@ public: * @param close: The timestamp when the origina file was closed. * * @param terminating: True if the original rotation request occured - * due to the main Bro process shutting down. + * due to the main Zeek process shutting down. */ bool FinishedRotation(const char* new_name, const char* old_name, double open, double close, bool terminating); @@ -363,7 +363,7 @@ protected: * @param close The network time when the *current* file was closed. * * @param terminating Indicates whether the rotation request occurs - * due the main Bro prcoess terminating (and not because we've + * due the main Zeek prcoess terminating (and not because we've * reached a regularly scheduled time for rotation). */ virtual bool DoRotate(const char* rotated_path, double open, double close, diff --git a/src/logging/writers/ascii/Ascii.cc b/src/logging/writers/ascii/Ascii.cc index 0b189c75b5..269eef5277 100644 --- a/src/logging/writers/ascii/Ascii.cc +++ b/src/logging/writers/ascii/Ascii.cc @@ -391,7 +391,7 @@ bool Ascii::InitFormatter() if ( enable_utf_8 ) desc.EnableUTF8(); - // Use the default "Bro logs" format. + // Use the default "Zeek logs" format. desc.EnableEscaping(); desc.AddEscapeSequence(separator); threading::formatter::Ascii::SeparatorInfo sep_info(separator, set_separator, unset_field, diff --git a/src/module_util.h b/src/module_util.h index 31e6901b97..111790649b 100644 --- a/src/module_util.h +++ b/src/module_util.h @@ -1,5 +1,5 @@ // -// These functions are used by both Bro and bifcl. +// These functions are used by both Zeek and bifcl. // #pragma once diff --git a/src/packet_analysis/Analyzer.h b/src/packet_analysis/Analyzer.h index d778128b7c..baa10156a9 100644 --- a/src/packet_analysis/Analyzer.h +++ b/src/packet_analysis/Analyzer.h @@ -141,7 +141,7 @@ public: virtual void AnalyzerConfirmation(session::Session* session, zeek::Tag tag = zeek::Tag()); /** - * Signals Bro's protocol detection that the analyzer has found a + * Signals Zeek's protocol detection that the analyzer has found a * severe protocol violation that could indicate that it's not * parsing the expected protocol. This turns into \c * analyzer_violation events at the script-layer (one such event is diff --git a/src/packet_analysis/protocol/tcp/TCPSessionAdapter.cc b/src/packet_analysis/protocol/tcp/TCPSessionAdapter.cc index 3e04adb844..d0f4e6cb21 100644 --- a/src/packet_analysis/protocol/tcp/TCPSessionAdapter.cc +++ b/src/packet_analysis/protocol/tcp/TCPSessionAdapter.cc @@ -566,7 +566,7 @@ void TCPSessionAdapter::Process(bool is_orig, const struct tcphdr* tp, int len, if ( seq_underflow && ! flags.RST() ) // Can't tell if if this is a retransmit/out-of-order or something - // before the sequence Bro initialized the endpoint at or the TCP is + // before the sequence Zeek initialized the endpoint at or the TCP is // just broken and sending garbage sequences. In either case, some // standard analysis doesn't apply (e.g. reassembly). Weird("TCP_seq_underflow_or_misorder"); diff --git a/src/plugin/Component.h b/src/plugin/Component.h index c62ad88cb5..4472bd91c2 100644 --- a/src/plugin/Component.h +++ b/src/plugin/Component.h @@ -101,7 +101,7 @@ public: /** * Returns a textual representation of the component. This goes into - * the output of "bro -NN". + * the output of "zeek -NN". * * By default, this just outputs the type and the name. Derived * versions can override DoDescribe() to add type specific details. diff --git a/src/plugin/Manager.h b/src/plugin/Manager.h index f2324c2b44..61a103dd98 100644 --- a/src/plugin/Manager.h +++ b/src/plugin/Manager.h @@ -108,7 +108,7 @@ public: /** * First-stage initializion of the manager. This is called early on - * during Bro's initialization, before any scripts are processed, and + * during Zeek's initialization, before any scripts are processed, and * forwards to the corresponding Plugin methods. */ void InitPreScript(); @@ -121,7 +121,7 @@ public: /** * Third-stage initialization of the manager. This is called late during - * Bro's initialization after any scripts are processed, and forwards to + * Zeek's initialization after any scripts are processed, and forwards to * the corresponding Plugin methods. */ void InitPostScript(); @@ -206,8 +206,8 @@ public: /** * Registers interest in an event by a plugin, even if there's no handler * for it. Normally a plugin receives events through HookQueueEvent() - * only if Bro actually has code to execute for it. By calling this - * method, the plugin tells Bro to raise the event even if there's no + * only if Zeek actually has code to execute for it. By calling this + * method, the plugin tells Zeek to raise the event even if there's no * correspondong handler; it will then go into HookQueueEvent() just as * any other. * @@ -218,7 +218,7 @@ public: void RequestEvent(EventHandlerPtr handler, Plugin* plugin); /** - * Register interest in the destruction of a Obj instance. When Bro's + * Register interest in the destruction of a Obj instance. When Zeek's * reference counting triggers the objects destructor to run, the \a * HookBroObjDtor will be called. * @@ -233,9 +233,9 @@ public: /** * Hook that gives plugins a chance to take over loading an input * file. This method must be called between InitPreScript() and - * InitPostScript() for each input file Bro is about to load, either + * InitPostScript() for each input file Zeek is about to load, either * given on the command line or via @load script directives. The hook can - * take over the file, in which case Bro must not further process it + * take over the file, in which case Zeek must not further process it * otherwise. * * @return 1 if a plugin took over the file and loaded it successfully; 0 @@ -248,10 +248,10 @@ public: /** * Hook that gives plugins a chance to take over loading an input file, * including replacing the file's content. This method must be called - * between InitPreScript() and InitPostScript() for each input file Bro is + * between InitPreScript() and InitPostScript() for each input file Zeek is * about to load, either given on the command line or via @load script - * directives. The hook can take over the file, in which case Bro must not - * further process it otherwise; or provide its content, in which case Bro + * directives. The hook can take over the file, in which case Zeek must not + * further process it otherwise; or provide its content, in which case Zeek * must use that and ignore the original file. * * @return tuple where the first element is 1 if a plugin took over the @@ -397,7 +397,7 @@ public: * * @param conn The associated connection * - * @param addl Additional Bro values; typically will be passed to the event + * @param addl Additional Zeek values; typically will be passed to the event * by the reporter framework. * * @param location True if event expects location information diff --git a/src/plugin/Plugin.h b/src/plugin/Plugin.h index 8f2e75e64b..b4d483e178 100644 --- a/src/plugin/Plugin.h +++ b/src/plugin/Plugin.h @@ -283,7 +283,7 @@ public: } /** - * Constructor with a Bro value argument. + * Constructor with a Zeek value argument. */ explicit HookArgument(const Val* a) { @@ -292,7 +292,7 @@ public: } /** - * Constructor with a list of Bro values argument. + * Constructor with a list of Zeek values argument. */ explicit HookArgument(const ValPList* a) { @@ -453,7 +453,7 @@ public: } /** - * Returns the value for a Bro value argument. The argument's type must + * Returns the value for a Zeek value argument. The argument's type must * match accordingly. */ const Val* AsVal() const @@ -463,7 +463,7 @@ public: } /** - * Returns the value for a Bro wrapped value argument. The argument's type must + * Returns the value for a Zeek wrapped value argument. The argument's type must * match accordingly. */ const std::pair AsFuncResult() const @@ -473,7 +473,7 @@ public: } /** - * Returns the value for a Bro frame argument. The argument's type must + * Returns the value for a Zeek frame argument. The argument's type must * match accordingly. */ const zeek::detail::Frame* AsFrame() const @@ -503,7 +503,7 @@ public: } /** - * Returns the value for a list of Bro values argument. The argument's type must + * Returns the value for a list of Zeek values argument. The argument's type must * match accordingly. */ const ValPList* AsValList() const @@ -584,7 +584,7 @@ using HookArgumentList = std::list; /** * Base class for all plugins. * - * Plugins encapsulate functionality that extends one or more of Bro's major + * Plugins encapsulate functionality that extends one or more of Zeek's major * subsystems, such as analysis of a specific protocol, or logging output in * a particular format. A plugin acts a logical container that can provide a * set of functionality. Specifically, it may: @@ -599,7 +599,7 @@ using HookArgumentList = std::list; * they'll be defined in *.bif files, but a plugin can also create them * internally. * - * - Provide hooks (aka callbacks) into Bro's core processing to inject + * - Provide hooks (aka callbacks) into Zeek's core processing to inject * and/or alter functionality. * * A plugin needs to explicitly register all the functionality it provides. @@ -699,7 +699,7 @@ public: * * Note that this method is rarely the right one to use. As it's for * informational purposes only, the plugin still needs to register - * the BiF items themselves with the corresponding Bro parts. Doing + * the BiF items themselves with the corresponding Zeek parts. Doing * so can be tricky, and it's recommned to instead define BiF items * in separate *.bif files that the plugin then pulls in. If defined * there, one does *not* need to call this method. @@ -711,8 +711,8 @@ public: void AddBifItem(const std::string& name, BifItem::Type type); /** - * Adds a file to the list of files that Bro loads at startup. This - * will normally be a Bro script, but it passes through the plugin + * Adds a file to the list of files that Zeek loads at startup. This + * will normally be a Zeek script, but it passes through the plugin * system as well to load files with other extensions as supported by * any of the current plugins. In other words, calling this method is * similar to giving a file on the command line. Note that the file @@ -732,7 +732,7 @@ protected: friend class Manager; /** - * First-stage initialization of the plugin called early during Bro's + * First-stage initialization of the plugin called early during Zeek's * startup, before scripts are parsed. This can be overridden by * derived classes; they must however call the parent's * implementation. @@ -740,7 +740,7 @@ protected: virtual void InitPreScript(); /** - * Second-stage initialization of the plugin called late during Bro's + * Second-stage initialization of the plugin called late during Zeek's * startup, after scripts are parsed. This can be overridden by * derived classes; they must however call the parent's * implementation. @@ -768,12 +768,12 @@ protected: /** * Enables a hook. The corresponding virtual method will now be - * called as Bro's processing proceeds. Note that enabling hooks can - * have performance impact as many trigger frequently inside Bro's + * called as Zeek's processing proceeds. Note that enabling hooks can + * have performance impact as many trigger frequently inside Zeek's * main processing path. * * Note that while hooks may be enabled/disabled dynamically at any - * time, the output of Bro's \c -NN option will only reflect their + * time, the output of Zeek's \c -NN option will only reflect their * state at startup time. Usually one should call this method for a * plugin's hooks in either the plugin's constructor or in * InitPreScript(). @@ -788,7 +788,7 @@ protected: void EnableHook(HookType hook, int priority = 0); /** - * Disables a hook. Bro will no longer call the corresponding virtual + * Disables a hook. Zeek will no longer call the corresponding virtual * method. * * @param hook The hook to disable. @@ -803,9 +803,9 @@ protected: /** * Registers interest in an event, even if there's no handler for it. - * Normally a plugin receives events through HookQueueEvent() only if Bro + * Normally a plugin receives events through HookQueueEvent() only if Zeek * actually has code to execute for it. By calling this method, the - * plugin tells Bro to raise the event even if there's no correspondong + * plugin tells Zeek to raise the event even if there's no correspondong * handler; it will then go into HookQueueEvent() just as any other. * * @param handler The event handler being interested in. @@ -814,7 +814,7 @@ protected: /** * Registers interest in the destruction of a Obj instance. When - * Bro's reference counting triggers the objects destructor to run, + * Zeek's reference counting triggers the objects destructor to run, * \a HookBroObjDtor will be called. * * Note that his can get expensive if triggered for many objects. @@ -828,10 +828,10 @@ protected: /** * Hook into loading input files. This method will be called between * InitPreScript() and InitPostScript(), but with no further order or - * timing guaranteed. It will be called once for each input file Bro + * timing guaranteed. It will be called once for each input file Zeek * is about to load, either given on the command line or via @load * script directives. The hook can take over the file, in which case - * Bro will not further process it otherwise. + * Zeek will not further process it otherwise. * * @param type The type of load encountered: script load, signatures load, * or plugin load. @@ -839,13 +839,13 @@ protected: * @param file The filename that was passed to @load. Only includes * an extension if it was given in @load. * - * @param resolved The file or directory name Bro resolved from + * @param resolved The file or directory name Zeek resolved from * the given path and is going to load. Empty string - * if Bro was not able to resolve a path. + * if Zeek was not able to resolve a path. * * @return 1 if the plugin took over the file and loaded it * successfully; 0 if the plugin took over the file but had trouble - * loading it (Bro will abort in this case, and the plugin should + * loading it (Zeek will abort in this case, and the plugin should * have printed an error message); and -1 if the plugin wasn't * interested in the file at all. */ @@ -856,10 +856,10 @@ protected: * Hook into loading input files, with extended capabilities. This method * will be called between InitPreScript() and InitPostScript(), but with no * further order or timing guaranteed. It will be called once for each - * input file Bro is about to load, either given on the command line or via + * input file Zeek is about to load, either given on the command line or via * @load script directives. The hook can take over the file, in which case - * Bro will not further process it otherwise. It can, alternatively, also - * provide the file content as a string, which Bro will then process just + * Zeek will not further process it otherwise. It can, alternatively, also + * provide the file content as a string, which Zeek will then process just * as if it had read it from a file. * * @param type The type of load encountered: script load, signatures load, @@ -868,21 +868,21 @@ protected: * @param file The filename that was passed to @load. Only includes * an extension if it was given in @load. * - * @param resolved The file or directory name Bro resolved from + * @param resolved The file or directory name Zeek resolved from * the given path and is going to load. Empty string - * if Bro was not able to resolve a path. + * if Zeek was not able to resolve a path. * * @return tuple of an integer and an optional string, where: the integer * must be 1 if the plugin takes over loading the file (see below); 0 if * the plugin wanted to take over the file but had trouble loading it * (processing will abort in this case, and the plugin should have printed - * an error message); and -1 if the plugin wants Bro to proceeed processing + * an error message); and -1 if the plugin wants Zeek to proceeed processing * the file normally. If the plugins takes over by returning 1, there are * two cases: if the second tuple element remains unset, the plugin handled - * the loading completely internally; Bro will not do anything further with + * the loading completely internally; Zeek will not do anything further with * it. Alternatively, the plugin may optionally return the acutal content * to use for the file as a string through the tuple's second element. If - * so, Bro will ignore the file on disk and use that provided content + * so, Zeek will ignore the file on disk and use that provided content * instead (including when there's actually no physical file in place on * disk at all, and loading would have hence failed otherwise). */ @@ -959,7 +959,7 @@ protected: /** * Hook for destruction of objects registered with - * RequestBroObjDtor(). When Bro's reference counting triggers the + * RequestBroObjDtor(). When Zeek's reference counting triggers the * objects destructor to run, this method will be run. It may also * run for other objects that this plugin has not registered for. * @@ -1041,7 +1041,7 @@ protected: * * @param conn The associated connection * - * @param addl Additional Bro values; typically will be passed to the event + * @param addl Additional Zeek values; typically will be passed to the event * by the reporter framework. * * @param location True if event expects location information diff --git a/src/probabilistic/Hasher.h b/src/probabilistic/Hasher.h index 70a3ca6630..c98b630d95 100644 --- a/src/probabilistic/Hasher.h +++ b/src/probabilistic/Hasher.h @@ -49,7 +49,7 @@ public: * @param data A pointer to contiguous data that should be crunched into a * seed. If 0, the function tries to find a global_hash_seed script variable * to derive a seed from. If this variable does not exist, the function uses - * the initial seed generated at Bro startup. + * the initial seed generated at Zeek startup. * * @param size The number of bytes of *data*. * @@ -148,7 +148,7 @@ public: /** * Constructs an hash function seeded with a given seed and an - * optional extra seed to replace the initial Bro seed. + * optional extra seed to replace the initial Zeek seed. * * @param arg_seed The seed to use for this instance. */ diff --git a/src/probabilistic/Topk.h b/src/probabilistic/Topk.h index d449879f70..8f269fb13e 100644 --- a/src/probabilistic/Topk.h +++ b/src/probabilistic/Topk.h @@ -58,7 +58,7 @@ public: /** * Call this when a new value is encountered. Note that on the first - * call, the Bro type of the value types that are counted is set. All + * call, the Zeek type of the value types that are counted is set. All * following calls to encountered have to specify the same type. * * @param value The encountered element @@ -81,7 +81,7 @@ public: * certain val. Returns 0 if the val is unknown (and logs the error * to reporter). * - * @param value Bro value to get counts for + * @param value Zeek value to get counts for * * @returns internal count for val, 0 if unknown */ @@ -91,7 +91,7 @@ public: * Get the current epsilon tracked in the top-k data structure for a * certain val. * - * @param value Bro value to get epsilons for + * @param value Zeek value to get epsilons for * * @returns the epsilon. Returns 0 if the val is unknown (and logs * the error to reporter) diff --git a/src/re-scan.l b/src/re-scan.l index 9e0397e231..d7d3c1eb05 100644 --- a/src/re-scan.l +++ b/src/re-scan.l @@ -1,4 +1,4 @@ -/* scan.l - scanner for Bro regular expressions */ +/* scan.l - scanner for Zeek regular expressions */ /* * See the file "COPYING" in the main distribution directory for copyright. diff --git a/src/rule-scan.l b/src/rule-scan.l index 3d9bc6da84..128292043d 100644 --- a/src/rule-scan.l +++ b/src/rule-scan.l @@ -218,7 +218,7 @@ finger { rules_lval.val = zeek::detail::Rule::FINGER; return TOK_PATTERN_TYPE; } %% -// We're about to parse a Bro policy-layer symbol. +// We're about to parse a Zeek policy-layer symbol. void begin_PS() { BEGIN(PS); diff --git a/src/telemetry/Manager.h b/src/telemetry/Manager.h index 1643fe0fa7..7712198e76 100644 --- a/src/telemetry/Manager.h +++ b/src/telemetry/Manager.h @@ -32,7 +32,7 @@ public: virtual ~Manager(); /** - * Initialization of the manager. This is called late during Bro's + * Initialization of the manager. This is called late during Zeek's * initialization after any scripts are processed. */ virtual void InitPostScript(); diff --git a/src/threading/BasicThread.h b/src/threading/BasicThread.h index f009a457df..3c5d3de1e8 100644 --- a/src/threading/BasicThread.h +++ b/src/threading/BasicThread.h @@ -27,7 +27,7 @@ public: * Creates a new thread object. Instantiating the object does however * not yet start the actual OS thread, that requires calling Start(). * - * Only Bro's main thread may create new thread instances. + * Only Zeek's main thread may create new thread instances. * * @param name A descriptive name for thread the thread. This may * show up in messages to the user. @@ -68,7 +68,7 @@ public: * executing Run(). Note that one can't restart a thread after a * Stop(), doing so will be ignored. * - * Only Bro's main thread must call this method. + * Only Zeek's main thread must call this method. */ void Start(); @@ -83,7 +83,7 @@ public: * Calling this method has no effect if Start() hasn't been executed * yet. * - * Only Bro's main thread must call this method. + * Only Zeek's main thread must call this method. */ void SignalStop(); @@ -94,7 +94,7 @@ public: * yet. If this is executed without calling SignalStop() first, * results are undefined. * - * Only Bro's main thread must call this method. + * Only Zeek's main thread must call this method. */ void WaitForStop(); @@ -143,14 +143,14 @@ protected: /** * Executed with Start(). This is a hook into starting the thread. It - * will be called from Bro's main thread after the OS thread has been + * will be called from Zeek's main thread after the OS thread has been * started. */ virtual void OnStart() { } /** * Executed with SignalStop(). This is a hook into preparing the - * thread for stopping. It will be called from Bro's main thread + * thread for stopping. It will be called from Zeek's main thread * before the thread has been signaled to stop. */ virtual void OnSignalStop() { } @@ -159,7 +159,7 @@ protected: * Executed with WaitForStop(). This is a hook into waiting for the * thread to stop. It must be overridden by derived classes and only * return once the thread has indeed finished processing. The method - * will be called from Bro's main thread. + * will be called from Zeek's main thread. */ virtual void OnWaitForStop() = 0; @@ -171,7 +171,7 @@ protected: /** * Destructor. This will be called by the manager. * - * Only Bro's main thread may delete thread instances. + * Only Zeek's main thread may delete thread instances. * */ virtual ~BasicThread(); diff --git a/src/threading/Formatter.h b/src/threading/Formatter.h index 1d463a9c0c..aa5f697616 100644 --- a/src/threading/Formatter.h +++ b/src/threading/Formatter.h @@ -107,7 +107,7 @@ public: static std::string Render(const Value::subnet_t& subnet); /** - * Convert a double into a string. This renders the double with Bro's + * Convert a double into a string. This renders the double with Zeek's * standard precision. * * This is a helper function that formatter implementations may use. diff --git a/src/threading/Manager.h b/src/threading/Manager.h index 62716e88fa..6e21a2e600 100644 --- a/src/threading/Manager.h +++ b/src/threading/Manager.h @@ -35,7 +35,7 @@ protected: * In addition to basic threads, the manager also provides additional * functionality specific to MsgThread instances. In particular, it polls * their outgoing message queue on a regular basis and feeds data sent into - * the rest of Bro. It also triggers the regular heartbeats. + * the rest of Zeek. It also triggers the regular heartbeats. */ class Manager { diff --git a/src/threading/MsgThread.h b/src/threading/MsgThread.h index 43b0c1ca3b..121b19a2db 100644 --- a/src/threading/MsgThread.h +++ b/src/threading/MsgThread.h @@ -29,7 +29,7 @@ class KillMeMessage; /** * A specialized thread that provides bi-directional message passing between - * Bro's main thread and the child thread. Messages are instances of + * Zeek's main thread and the child thread. Messages are instances of * BasicInputMessage and BasicOutputMessage for message sent \a to the child * thread and received \a from the child thread, respectively. * @@ -45,7 +45,7 @@ public: * Constructor. It automatically registers the thread with the * threading::Manager. * - * Only Bro's main thread may instantiate a new thread. + * Only Zeek's main thread may instantiate a new thread. */ MsgThread(); @@ -77,7 +77,7 @@ public: * Allows the child thread to send a specified Zeek event. The given Vals * must match the values expected by the event. * - * @param name name of the bro event to send + * @param name name of the Zeek event to send * * @param num_vals number of entries in \a vals * @@ -129,7 +129,7 @@ public: /** * Reports a fatal error from the child thread. The main thread will - * pass this to the Reporter once received. Bro will terminate after + * pass this to the Reporter once received. Zeek will terminate after * the message has been reported. * * Only the child thread may call this method. @@ -140,7 +140,7 @@ public: /** * Reports a fatal error from the child thread. The main thread will - * pass this to the Reporter once received. Bro will terminate with a + * pass this to the Reporter once received. Zeek will terminate with a * core dump after the message has been reported. * * Only the child thread may call this method. @@ -151,7 +151,7 @@ public: /** * Reports a potential internal problem from the child thread. The - * main thread will pass this to the Reporter once received. Bro will + * main thread will pass this to the Reporter once received. Zeek will * continue normally. * * Only the child thread may call this method. @@ -162,7 +162,7 @@ public: /** * Reports an internal program error from the child thread. The main - * thread will pass this to the Reporter once received. Bro will + * thread will pass this to the Reporter once received. Zeek will * terminate with a core dump after the message has been reported. * * Only the child thread may call this method. @@ -353,7 +353,7 @@ private: }; /** - * Base class for all message between Bro's main process and a MsgThread. + * Base class for all message between Zeek's main process and a MsgThread. */ class Message { @@ -389,7 +389,7 @@ private: }; /** - * Base class for messages sent from Bro's main thread to a child MsgThread. + * Base class for messages sent from Zeek's main thread to a child MsgThread. */ class BasicInputMessage : public Message { @@ -404,7 +404,7 @@ protected: }; /** - * Base class for messages sent from a child MsgThread to Bro's main thread. + * Base class for messages sent from a child MsgThread to Zeek's main thread. */ class BasicOutputMessage : public Message { diff --git a/src/threading/Queue.h b/src/threading/Queue.h index 619177c405..b005476f57 100644 --- a/src/threading/Queue.h +++ b/src/threading/Queue.h @@ -21,7 +21,7 @@ namespace zeek::threading * The implementation uses multiple queues and reads/writes in rotary fashion * in an attempt to limit contention. * - * All Queue instances must be instantiated by Bro's main thread. + * All Queue instances must be instantiated by Zeek's main thread. * * TODO: Unclear how critical performance is for this qeueue. We could likely * optimize it further if helpful. diff --git a/src/threading/SerialTypes.cc b/src/threading/SerialTypes.cc index a68640bc2f..2418f718ed 100644 --- a/src/threading/SerialTypes.cc +++ b/src/threading/SerialTypes.cc @@ -73,7 +73,7 @@ std::string Field::TypeName() const { std::string n; - // We do not support tables, if the internal Bro type is table it + // We do not support tables, if the internal Zeek type is table it // always is a set. if ( type == TYPE_TABLE ) n = "set"; diff --git a/src/util.h b/src/util.h index 019162a7bb..e715a665ec 100644 --- a/src/util.h +++ b/src/util.h @@ -169,7 +169,7 @@ void seed_random(unsigned int seed); void set_thread_name(const char* name, pthread_t tid = pthread_self()); // Each event source that may generate events gets an internally unique ID. -// This is always LOCAL for a local Bro. For remote event sources, it gets +// This is always LOCAL for a local Zeek. For remote event sources, it gets // assigned by the RemoteSerializer. // // FIXME: Find a nicer place for this type definition. diff --git a/src/version.c.in b/src/version.c.in index ef967f16aa..311a0ee58a 100644 --- a/src/version.c.in +++ b/src/version.c.in @@ -5,7 +5,7 @@ char version[] = "@VERSION@"; // A C function that has the current version built into its name. // One can link a shared library against this to ensure that it won't -// load if the version of the main Bro binary differs compared to +// load if the version of the main Zeek binary differs compared to // what the library was compiled against. const char* BRO_VERSION_FUNCTION() { diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 871ced8e53..c0786f29fd 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -304,7 +304,7 @@ static void terminate_bro() if ( profiling_logger ) { // FIXME: There are some occasional crashes in the memory - // allocation code when killing Bro. Disabling this for now. + // allocation code when killing Zeek. Disabling this for now. if ( ! (signal_val == SIGTERM || signal_val == SIGINT) ) profiling_logger->Log(); diff --git a/src/zeekygen/Manager.cc b/src/zeekygen/Manager.cc index 903d543e6b..5eb2d7b668 100644 --- a/src/zeekygen/Manager.cc +++ b/src/zeekygen/Manager.cc @@ -61,11 +61,11 @@ Manager::Manager(const string& arg_config, const string& bro_command) if ( getenv("ZEEK_DISABLE_ZEEKYGEN") ) disabled = true; - // If running bro without the "-X" option, then we don't need bro_mtime. + // If running Zeek without the "-X" option, then we don't need bro_mtime. if ( disabled || arg_config.empty() ) return; - // Find the absolute or relative path to bro by checking each PATH + // Find the absolute or relative path to Zeek by checking each PATH // component and also the current directory (so that this works if // bro_command is a relative path). const char* env_path = getenv("PATH"); @@ -73,9 +73,9 @@ Manager::Manager(const string& arg_config, const string& bro_command) string path_to_bro = util::find_file(bro_command, path); struct stat s; - // One way that find_file() could fail is when bro is located in + // One way that find_file() could fail is when Zeek is located in // a PATH component that starts with a tilde (such as "~/bin"). A simple - // workaround is to just run bro with a relative or absolute path. + // workaround is to just run Zeek with a relative or absolute path. if ( path_to_bro.empty() || stat(path_to_bro.c_str(), &s) < 0 ) reporter->InternalError("Zeekygen can't get mtime of zeek binary %s (try again by " "specifying the absolute or relative path to Zeek): %s", diff --git a/src/zeekygen/Manager.h b/src/zeekygen/Manager.h index 54202d6b08..772079df3d 100644 --- a/src/zeekygen/Manager.h +++ b/src/zeekygen/Manager.h @@ -58,8 +58,8 @@ public: * Ctor. * @param config Path to a Zeekygen config file if documentation is to be * written to disk. - * @param bro_command The command used to invoke the bro process. - * It's used when checking for out-of-date targets. If the bro binary is + * @param bro_command The command used to invoke the Zeek process. + * It's used when checking for out-of-date targets. If the Zeek binary is * newer then a target, it needs to be rebuilt. */ Manager(const std::string& config, const std::string& bro_command); @@ -88,15 +88,15 @@ public: void GenerateDocs() const; /** - * Register Bro script for which information/documentation will be gathered. - * @param path Absolute path to Bro script. + * Register Zeek script for which information/documentation will be gathered. + * @param path Absolute path to Zeek script. */ void Script(const std::string& path); /** - * Register Bro script dependency ("@load"). - * @param path Absolute path to a Bro script. - * @param dep Absolute path to a Bro script being "@load"d from script given + * Register Zeek script dependency ("@load"). + * @param path Absolute path to a Zeek script. + * @param dep Absolute path to a Zeek script being "@load"d from script given * by \a path. */ void ScriptDependency(const std::string& path, const std::string& dep); @@ -104,7 +104,7 @@ public: /** * Register a module usage (script may export identifiers in to the * module namespace). - * @param path Absolute path to a Bro script. + * @param path Absolute path to a Zeek script. * @param module The module which script given by \a path is using. */ void ModuleUsage(const std::string& path, const std::string& module); @@ -128,7 +128,7 @@ public: * gathered. * @param id The identifier of the record type which has the field. * @param field The field name/type information. - * @param path Absolute path to a Bro script in which this field is + * @param path Absolute path to a Zeek script in which this field is * declared. This can be different from the place where the record type * is declared due to redefs. * @param from_redef The field is from a record redefinition. @@ -139,7 +139,7 @@ public: /** * Register a redefinition of a particular identifier. * @param id The identifier being redef'd. - * @param path Absolute path to a Bro script doing the redef. + * @param path Absolute path to a Zeek script doing the redef. * @param ic The initialization class that was used (e.g. =, +=, -=). * @param init_expr The intiialization expression that was used. */ @@ -150,7 +150,7 @@ public: /** * Register Zeekygen script summary content. - * @param path Absolute path to a Bro script. + * @param path Absolute path to a Zeek script. * @param comment Zeekygen-style summary comment ("##!") to associate with * script given by \a path. */ @@ -209,7 +209,7 @@ public: * @param target_file output file of a Zeekygen target. * @param dependencies all dependencies of the target. * @return true if modification time of \a target_file is newer than - * modification time of Bro binary, Zeekygen config file, and all + * modification time of Zeek binary, Zeekygen config file, and all * dependencies, else false. */ template diff --git a/src/zeekygen/ScriptInfo.cc b/src/zeekygen/ScriptInfo.cc index 61e2316cf3..f44232014f 100644 --- a/src/zeekygen/ScriptInfo.cc +++ b/src/zeekygen/ScriptInfo.cc @@ -340,7 +340,7 @@ void ScriptInfo::DoInitPostScript() state_vars.push_back(info); } - // The following enum types are automatically created internally in Bro, + // The following enum types are automatically created internally in Zeek, // so just manually associating them with scripts for now. if ( name == "base/frameworks/input/main.zeek" ) { diff --git a/src/zeekygen/ScriptInfo.h b/src/zeekygen/ScriptInfo.h index 6ad92fcb95..48ee3fde24 100644 --- a/src/zeekygen/ScriptInfo.h +++ b/src/zeekygen/ScriptInfo.h @@ -27,7 +27,7 @@ using id_info_set = std::set; using id_info_list = std::list; /** - * Information about a Bro script. + * Information about a Zeek script. */ class ScriptInfo : public Info { diff --git a/src/zeekygen/Target.cc b/src/zeekygen/Target.cc index a4e62b742d..ef5b32d092 100644 --- a/src/zeekygen/Target.cc +++ b/src/zeekygen/Target.cc @@ -260,7 +260,7 @@ void AnalyzerTarget::DoFindDependencies(const std::vector& infos) { // TODO: really should add to dependency list the tag type's ID and // all bif items for matching analyzer plugins, but that's all dependent - // on the bro binary itself, so I'm cheating. + // on the Zeek binary itself, so I'm cheating. } void AnalyzerTarget::DoGenerate() const diff --git a/src/zeekygen/Target.h b/src/zeekygen/Target.h index cbd71b518a..7ed0e08815 100644 --- a/src/zeekygen/Target.h +++ b/src/zeekygen/Target.h @@ -43,7 +43,7 @@ struct TargetFile /** * A Zeekygen target abstract base class. A target is generally any portion of - * documentation that Bro can build. It's identified by a type (e.g. script, + * documentation that Zeek can build. It's identified by a type (e.g. script, * identifier, package), a pattern (e.g. "example.zeek", "HTTP::Info"), and * a path to an output file. */ From 63bfae180aabcb8c5e1a8e3a722628a0e5b7c51c Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 25 Jan 2022 10:47:15 -0800 Subject: [PATCH 030/204] bug fix for vector slice assignment --- src/Val.cc | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Val.cc b/src/Val.cc index 88becd2096..97451b01ed 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -3323,19 +3323,10 @@ bool VectorVal::Insert(unsigned int index, ValPtr element) auto n = vector_val->size(); if ( index < n ) - { // May need to delete previous element + { // Find location within existing vector elements. it = std::next(vector_val->begin(), index); if ( yield_types ) - { - if ( *it ) - ZVal::DeleteIfManaged(**it, element->GetType()); types_it = std::next(yield_types->begin(), index); - } - else if ( managed_yield ) - { - if ( *it ) - ZVal::DeleteManagedType(**it); - } } else { From c378017269bfb01ab48d94a8142890a2ed9b3f19 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 25 Jan 2022 10:47:33 -0800 Subject: [PATCH 031/204] btest to catch vector slice assignment issues --- .../Baseline/language.vector-slice-assign/out | 2 ++ .../btest/language/vector-slice-assign.zeek | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 testing/btest/Baseline/language.vector-slice-assign/out create mode 100644 testing/btest/language/vector-slice-assign.zeek diff --git a/testing/btest/Baseline/language.vector-slice-assign/out b/testing/btest/Baseline/language.vector-slice-assign/out new file mode 100644 index 0000000000..d494ea9828 --- /dev/null +++ b/testing/btest/Baseline/language.vector-slice-assign/out @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +[[seq=4], [seq=5], [seq=3], [seq=1], [seq=2], [seq=6], [seq=7]] diff --git a/testing/btest/language/vector-slice-assign.zeek b/testing/btest/language/vector-slice-assign.zeek new file mode 100644 index 0000000000..dcf4b5537f --- /dev/null +++ b/testing/btest/language/vector-slice-assign.zeek @@ -0,0 +1,24 @@ +# @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff out + +type testrec: record { + seq: count; +}; + +function make_recs(seqs: vector of count): vector of testrec +{ + local r: vector of testrec; + for (i in seqs) + r += testrec($seq=seqs[i]); + return r; +} + +event zeek_init() +{ + local seqs: vector of count = {1, 2, 3, 4, 5, 6, 7}; + local v = make_recs(seqs); + local tmp = v[0:2]; + v[0:2] = v[3:5]; + v[3:5] = tmp; + print v; +} From 9b0d525728dcddd2119aa9fad5595be32ce0ee02 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 28 Jan 2022 12:02:56 +0100 Subject: [PATCH 032/204] Let our TCP-based application analyzers operate without any TCP parent analyzer. Conceptually, a TCP-based application analyzer should not need any knowledge about the underlying TCP analysis; it's supposed to just process its reassembled input stream as it's handed over. But our analyzers break that assumption at a few places because sometimes knowledge about the TCP state of the connection can be helpful for heuristics. This is fine as long as there actually *is* a TCP parent analyzer available. Sometimes, however, there isn't: if the payload stream is encapsulated inside another application-layer protocol, the semantic link to TCP is broken. And if the outer connection is even UDP, then we don't have a TCP analyzer at all. We didn't handle this situation well so far. Most analyzers needing TCP state would just crash if there's no TCP analyzer (in debug mode with an `assert`, in release mode with a null pointer deref ...). Only HTTP did the right thing already: check if TCP is available and adapt accordingly. We know extend that check to all other analyzers as well: all accesses to `TCP()` are guarded, with reasonable defaults if not available. It's actually a pretty small change overall, which is evidence for how little this layering violation actually matters. The existing behavior is what's causing https://github.com/corelight/zeek-spicy-openvpn/issues/3. --- src/analyzer/protocol/bittorrent/BitTorrent.cc | 5 +---- .../protocol/bittorrent/BitTorrentTracker.cc | 5 +---- src/analyzer/protocol/dce-rpc/DCE_RPC.cc | 2 -- src/analyzer/protocol/ftp/FTP.cc | 13 ++++++++----- src/analyzer/protocol/gssapi/GSSAPI.cc | 2 -- src/analyzer/protocol/imap/IMAP.cc | 3 +-- src/analyzer/protocol/krb/KRB_TCP.cc | 3 +-- src/analyzer/protocol/login/Login.cc | 4 ++-- src/analyzer/protocol/login/RSH.cc | 9 ++++++--- src/analyzer/protocol/login/Rlogin.cc | 9 ++++++--- src/analyzer/protocol/mqtt/MQTT.cc | 2 -- src/analyzer/protocol/mysql/MySQL.cc | 3 +-- src/analyzer/protocol/ncp/NCP.cc | 8 ++++++-- src/analyzer/protocol/ntlm/NTLM.cc | 2 -- src/analyzer/protocol/rdp/RDP.cc | 3 +-- src/analyzer/protocol/rfb/RFB.cc | 4 ++-- src/analyzer/protocol/rpc/RPC.cc | 14 +++++++------- src/analyzer/protocol/sip/SIP_TCP.cc | 3 +-- src/analyzer/protocol/smb/SMB.cc | 2 -- src/analyzer/protocol/socks/SOCKS.cc | 5 +---- src/analyzer/protocol/ssh/SSH.cc | 3 +-- src/analyzer/protocol/syslog/Syslog.cc | 5 +---- src/analyzer/protocol/tcp/ContentLine.cc | 4 +--- src/analyzer/protocol/tcp/TCP.cc | 13 +++++++------ src/analyzer/protocol/xmpp/XMPP.cc | 3 +-- .../src/FOO.cc | 3 +-- testing/btest/plugins/protocol-plugin/src/Foo.cc | 5 +---- 27 files changed, 58 insertions(+), 79 deletions(-) diff --git a/src/analyzer/protocol/bittorrent/BitTorrent.cc b/src/analyzer/protocol/bittorrent/BitTorrent.cc index 74c6ff269f..143658743e 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrent.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrent.cc @@ -36,10 +36,7 @@ void BitTorrent_Analyzer::DeliverStream(int len, const u_char* data, bool orig) analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - - if ( TCP()->IsPartial() ) - // punt on partial. + if ( TCP() && TCP()->IsPartial() ) return; if ( this_stop ) diff --git a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc index 92de0788c8..09f86a54fa 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc @@ -80,10 +80,7 @@ void BitTorrentTracker_Analyzer::DeliverStream(int len, const u_char* data, bool { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - - if ( TCP()->IsPartial() ) - // punt on partial. + if ( TCP() && TCP()->IsPartial() ) return; if ( orig ) diff --git a/src/analyzer/protocol/dce-rpc/DCE_RPC.cc b/src/analyzer/protocol/dce-rpc/DCE_RPC.cc index 36678f67ad..109542371e 100644 --- a/src/analyzer/protocol/dce-rpc/DCE_RPC.cc +++ b/src/analyzer/protocol/dce-rpc/DCE_RPC.cc @@ -50,8 +50,6 @@ void DCE_RPC_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - if ( had_gap ) // If only one side had a content gap, we could still try to // deliver data to the other side if the script layer can handle this. diff --git a/src/analyzer/protocol/ftp/FTP.cc b/src/analyzer/protocol/ftp/FTP.cc index c8b3e6f2d7..594da3606a 100644 --- a/src/analyzer/protocol/ftp/FTP.cc +++ b/src/analyzer/protocol/ftp/FTP.cc @@ -45,11 +45,14 @@ void FTP_Analyzer::Done() { analyzer::tcp::TCP_ApplicationAnalyzer::Done(); - if ( nvt_orig->HasPartialLine() && - (TCP()->OrigState() == analyzer::tcp::TCP_ENDPOINT_CLOSED || - TCP()->OrigPrevState() == analyzer::tcp::TCP_ENDPOINT_CLOSED) ) - // ### should include the partial text - Weird("partial_ftp_request"); + if ( TCP() ) + { + if ( nvt_orig->HasPartialLine() && + (TCP()->OrigState() == analyzer::tcp::TCP_ENDPOINT_CLOSED || + TCP()->OrigPrevState() == analyzer::tcp::TCP_ENDPOINT_CLOSED) ) + // ### should include the partial text + Weird("partial_ftp_request"); + } } static uint32_t get_reply_code(int len, const char* line) diff --git a/src/analyzer/protocol/gssapi/GSSAPI.cc b/src/analyzer/protocol/gssapi/GSSAPI.cc index 6730e6bafd..6201d99f5d 100644 --- a/src/analyzer/protocol/gssapi/GSSAPI.cc +++ b/src/analyzer/protocol/gssapi/GSSAPI.cc @@ -38,8 +38,6 @@ void GSSAPI_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - try { interp->NewData(orig, data, data + len); diff --git a/src/analyzer/protocol/imap/IMAP.cc b/src/analyzer/protocol/imap/IMAP.cc index 3d074de875..43ab073b50 100644 --- a/src/analyzer/protocol/imap/IMAP.cc +++ b/src/analyzer/protocol/imap/IMAP.cc @@ -47,8 +47,7 @@ void IMAP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) return; } - assert(TCP()); - if ( TCP()->IsPartial() ) + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/src/analyzer/protocol/krb/KRB_TCP.cc b/src/analyzer/protocol/krb/KRB_TCP.cc index 8dd5124eef..dc03e79f4b 100644 --- a/src/analyzer/protocol/krb/KRB_TCP.cc +++ b/src/analyzer/protocol/krb/KRB_TCP.cc @@ -39,8 +39,7 @@ void KRB_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - if ( TCP()->IsPartial() ) + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/src/analyzer/protocol/login/Login.cc b/src/analyzer/protocol/login/Login.cc index 8be877acc4..db90dc359c 100644 --- a/src/analyzer/protocol/login/Login.cc +++ b/src/analyzer/protocol/login/Login.cc @@ -123,8 +123,8 @@ void Login_Analyzer::NewLine(bool orig, char* line) if ( state == LOGIN_STATE_AUTHENTICATE ) { - if ( TCP()->OrigState() == analyzer::tcp::TCP_ENDPOINT_PARTIAL || - TCP()->RespState() == analyzer::tcp::TCP_ENDPOINT_PARTIAL ) + if ( TCP() && (TCP()->OrigState() == analyzer::tcp::TCP_ENDPOINT_PARTIAL || + TCP()->RespState() == analyzer::tcp::TCP_ENDPOINT_PARTIAL) ) state = LOGIN_STATE_CONFUSED; // unknown login state else { diff --git a/src/analyzer/protocol/login/RSH.cc b/src/analyzer/protocol/login/RSH.cc index 35cb65b27d..34cdd92ba6 100644 --- a/src/analyzer/protocol/login/RSH.cc +++ b/src/analyzer/protocol/login/RSH.cc @@ -34,10 +34,13 @@ Contents_Rsh_Analyzer::~Contents_Rsh_Analyzer() { } void Contents_Rsh_Analyzer::DoDeliver(int len, const u_char* data) { - auto* tcp = static_cast(Parent())->TCP(); - assert(tcp); + int endp_state; - int endp_state = IsOrig() ? tcp->OrigState() : tcp->RespState(); + if ( auto* tcp = static_cast(Parent())->TCP() ) + endp_state = IsOrig() ? tcp->OrigState() : tcp->RespState(); + else + endp_state = tcp::TCP_ENDPOINT_ESTABLISHED; // no TCP parent, assume somebody's feeding us a + // legitimate stream for ( ; len > 0; --len, ++data ) { diff --git a/src/analyzer/protocol/login/Rlogin.cc b/src/analyzer/protocol/login/Rlogin.cc index 7543a437f6..771c121874 100644 --- a/src/analyzer/protocol/login/Rlogin.cc +++ b/src/analyzer/protocol/login/Rlogin.cc @@ -30,10 +30,13 @@ Contents_Rlogin_Analyzer::~Contents_Rlogin_Analyzer() { } void Contents_Rlogin_Analyzer::DoDeliver(int len, const u_char* data) { - auto* tcp = static_cast(Parent())->TCP(); - assert(tcp); + int endp_state; - int endp_state = IsOrig() ? tcp->OrigState() : tcp->RespState(); + if ( auto* tcp = static_cast(Parent())->TCP() ) + endp_state = IsOrig() ? tcp->OrigState() : tcp->RespState(); + else + endp_state = tcp::TCP_ENDPOINT_ESTABLISHED; // no TCP parent, assume somebody's feeding us a + // legitimate stream for ( ; len > 0; --len, ++data ) { diff --git a/src/analyzer/protocol/mqtt/MQTT.cc b/src/analyzer/protocol/mqtt/MQTT.cc index cf55b04e34..2917b233e3 100644 --- a/src/analyzer/protocol/mqtt/MQTT.cc +++ b/src/analyzer/protocol/mqtt/MQTT.cc @@ -37,8 +37,6 @@ void MQTT_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - try { interp->NewData(orig, data, data + len); diff --git a/src/analyzer/protocol/mysql/MySQL.cc b/src/analyzer/protocol/mysql/MySQL.cc index 1d4c54a2a2..6e9d319903 100644 --- a/src/analyzer/protocol/mysql/MySQL.cc +++ b/src/analyzer/protocol/mysql/MySQL.cc @@ -38,8 +38,7 @@ void MySQL_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - if ( TCP()->IsPartial() ) + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/src/analyzer/protocol/ncp/NCP.cc b/src/analyzer/protocol/ncp/NCP.cc index 8d275168bc..d6ecf6d05b 100644 --- a/src/analyzer/protocol/ncp/NCP.cc +++ b/src/analyzer/protocol/ncp/NCP.cc @@ -180,8 +180,12 @@ void Contents_NCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig if ( ! resync_set ) { resync_set = true; - resync = (IsOrig() ? tcp->OrigState() : tcp->RespState()) != - analyzer::tcp::TCP_ENDPOINT_ESTABLISHED; + + if ( tcp ) + resync = (IsOrig() ? tcp->OrigState() : tcp->RespState()) != + analyzer::tcp::TCP_ENDPOINT_ESTABLISHED; + else + resync = false; } if ( tcp && tcp->HadGap(orig) ) diff --git a/src/analyzer/protocol/ntlm/NTLM.cc b/src/analyzer/protocol/ntlm/NTLM.cc index 8f623c1230..fe81ddf454 100644 --- a/src/analyzer/protocol/ntlm/NTLM.cc +++ b/src/analyzer/protocol/ntlm/NTLM.cc @@ -37,8 +37,6 @@ void NTLM_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - try { interp->NewData(orig, data, data + len); diff --git a/src/analyzer/protocol/rdp/RDP.cc b/src/analyzer/protocol/rdp/RDP.cc index e1531e04ba..b50006e6ca 100644 --- a/src/analyzer/protocol/rdp/RDP.cc +++ b/src/analyzer/protocol/rdp/RDP.cc @@ -39,8 +39,7 @@ void RDP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - if ( TCP()->IsPartial() ) + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/src/analyzer/protocol/rfb/RFB.cc b/src/analyzer/protocol/rfb/RFB.cc index af52b7f4d8..486b9879e5 100644 --- a/src/analyzer/protocol/rfb/RFB.cc +++ b/src/analyzer/protocol/rfb/RFB.cc @@ -36,8 +36,8 @@ void RFB_Analyzer::EndpointEOF(bool is_orig) void RFB_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - if ( TCP()->IsPartial() ) + + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/src/analyzer/protocol/rpc/RPC.cc b/src/analyzer/protocol/rpc/RPC.cc index f169ea7854..4628749309 100644 --- a/src/analyzer/protocol/rpc/RPC.cc +++ b/src/analyzer/protocol/rpc/RPC.cc @@ -446,16 +446,16 @@ bool Contents_RPC::CheckResync(int& len, const u_char*& data, bool orig) // is fully established we are in sync (since it's the first chunk // of data after the SYN if its not established we need to // resync. - auto* tcp = static_cast(Parent())->TCP(); - assert(tcp); + resync_state = INSYNC; - if ( (IsOrig() ? tcp->OrigState() : tcp->RespState()) != - analyzer::tcp::TCP_ENDPOINT_ESTABLISHED ) + if ( auto* tcp = static_cast(Parent())->TCP() ) { - NeedResync(); + if ( (IsOrig() ? tcp->OrigState() : tcp->RespState()) != + analyzer::tcp::TCP_ENDPOINT_ESTABLISHED ) + { + NeedResync(); + } } - else - resync_state = INSYNC; } if ( resync_state == INSYNC ) diff --git a/src/analyzer/protocol/sip/SIP_TCP.cc b/src/analyzer/protocol/sip/SIP_TCP.cc index d02e0f2252..7011d5df8c 100644 --- a/src/analyzer/protocol/sip/SIP_TCP.cc +++ b/src/analyzer/protocol/sip/SIP_TCP.cc @@ -41,8 +41,7 @@ void SIP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - if ( TCP()->IsPartial() ) + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/src/analyzer/protocol/smb/SMB.cc b/src/analyzer/protocol/smb/SMB.cc index be27fa60ce..677e9bcdf9 100644 --- a/src/analyzer/protocol/smb/SMB.cc +++ b/src/analyzer/protocol/smb/SMB.cc @@ -61,8 +61,6 @@ void SMB_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - // It we need to resync and we don't have an SMB header, bail! if ( need_sync && ! HasSMBHeader(len, data) ) return; diff --git a/src/analyzer/protocol/socks/SOCKS.cc b/src/analyzer/protocol/socks/SOCKS.cc index cace5115dd..49d66490d1 100644 --- a/src/analyzer/protocol/socks/SOCKS.cc +++ b/src/analyzer/protocol/socks/SOCKS.cc @@ -46,10 +46,7 @@ void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - - if ( TCP()->IsPartial() ) - // punt on partial. + if ( TCP() && TCP()->IsPartial() ) return; if ( orig_done && resp_done ) diff --git a/src/analyzer/protocol/ssh/SSH.cc b/src/analyzer/protocol/ssh/SSH.cc index e62601a858..f2974cce84 100644 --- a/src/analyzer/protocol/ssh/SSH.cc +++ b/src/analyzer/protocol/ssh/SSH.cc @@ -44,8 +44,7 @@ void SSH_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - if ( TCP()->IsPartial() ) + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/src/analyzer/protocol/syslog/Syslog.cc b/src/analyzer/protocol/syslog/Syslog.cc index 8b059ed58d..8dfd5ab52c 100644 --- a/src/analyzer/protocol/syslog/Syslog.cc +++ b/src/analyzer/protocol/syslog/Syslog.cc @@ -79,10 +79,7 @@ void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint // { // analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); // -// assert(TCP()); -// -// if ( TCP()->IsPartial() || TCP()->HadGap(orig) ) -// // punt-on-partial or stop-on-gap. +// if ( TCP() && TCP()->IsPartial() ) // return; // // interp->NewData(orig, data, data + len); diff --git a/src/analyzer/protocol/tcp/ContentLine.cc b/src/analyzer/protocol/tcp/ContentLine.cc index 70963cbea4..5d4b06c7d6 100644 --- a/src/analyzer/protocol/tcp/ContentLine.cc +++ b/src/analyzer/protocol/tcp/ContentLine.cc @@ -331,9 +331,7 @@ void ContentLine_Analyzer::CheckNUL() // had been an initial SYN, so we check for whether // the connection has at most two bytes so far. - auto* tcp = static_cast(Parent())->TCP(); - - if ( tcp ) + if ( auto* tcp = static_cast(Parent())->TCP() ) { TCP_Endpoint* endp = IsOrig() ? tcp->Orig() : tcp->Resp(); if ( endp->state == TCP_ENDPOINT_PARTIAL && endp->LastSeq() - endp->StartSeq() <= 2 ) diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index 2ac794dff3..358ddbf003 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -36,12 +36,13 @@ void TCP_ApplicationAnalyzer::Init() void TCP_ApplicationAnalyzer::AnalyzerViolation(const char* reason, const char* data, int len) { - auto* tcp = TCP(); - - if ( tcp && (tcp->IsPartial() || tcp->HadGap(false) || tcp->HadGap(true)) ) - // Filter out incomplete connections. Parsing them is - // too unreliable. - return; + if ( auto* tcp = TCP() ) + { + if ( tcp->IsPartial() || tcp->HadGap(false) || tcp->HadGap(true) ) + // Filter out incomplete connections. Parsing them is + // too unreliable. + return; + } Analyzer::AnalyzerViolation(reason, data, len); } diff --git a/src/analyzer/protocol/xmpp/XMPP.cc b/src/analyzer/protocol/xmpp/XMPP.cc index f2a007dfed..5c74ea3b25 100644 --- a/src/analyzer/protocol/xmpp/XMPP.cc +++ b/src/analyzer/protocol/xmpp/XMPP.cc @@ -44,8 +44,7 @@ void XMPP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) return; } - assert(TCP()); - if ( TCP()->IsPartial() ) + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/testing/btest/plugins/binpac-flowbuffer-frame-length-plugin/src/FOO.cc b/testing/btest/plugins/binpac-flowbuffer-frame-length-plugin/src/FOO.cc index 3eea2c8121..743f530665 100644 --- a/testing/btest/plugins/binpac-flowbuffer-frame-length-plugin/src/FOO.cc +++ b/testing/btest/plugins/binpac-flowbuffer-frame-length-plugin/src/FOO.cc @@ -38,8 +38,7 @@ void FOO_Analyzer::DeliverStream(int len, const u_char* data, bool orig) { tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - if ( TCP()->IsPartial() ) + if ( TCP() && TCP()->IsPartial() ) return; if ( had_gap ) diff --git a/testing/btest/plugins/protocol-plugin/src/Foo.cc b/testing/btest/plugins/protocol-plugin/src/Foo.cc index d1cf72196e..aef658e7ec 100644 --- a/testing/btest/plugins/protocol-plugin/src/Foo.cc +++ b/testing/btest/plugins/protocol-plugin/src/Foo.cc @@ -36,10 +36,7 @@ void Foo::DeliverStream(int len, const u_char* data, bool orig) { zeek::analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig); - assert(TCP()); - - if ( TCP()->IsPartial() ) - // punt on partial. + if ( TCP() && TCP()->IsPartial() ) return; try From f9ac03d6e3a6bcd33e6169dae1e695af5789e6c9 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 31 Jan 2022 17:40:23 -0800 Subject: [PATCH 033/204] Simplify ClusterController::API::set_configuration_request/response It's easier to track outstanding controller/agent requests via a simple set of pending agent names, and we can remove all of the result aggregation logic since we can simply re-use the results reported by the agents. This can serve as a template for request-response patterns where a client's request triggers a request to all agents, followed by a response to the client once all agents have responded. Once we have a few more of those, it'll become clearer how to abstract this further. --- .../frameworks/cluster/controller/main.zeek | 70 +++++-------------- .../cluster/controller/request.zeek | 2 +- 2 files changed, 20 insertions(+), 52 deletions(-) diff --git a/scripts/policy/frameworks/cluster/controller/main.zeek b/scripts/policy/frameworks/cluster/controller/main.zeek index 33e0456049..d96b49d58f 100644 --- a/scripts/policy/frameworks/cluster/controller/main.zeek +++ b/scripts/policy/frameworks/cluster/controller/main.zeek @@ -70,9 +70,9 @@ function send_config_to_agents(req: ClusterController::Request::Request, areq$parent_id = req$id; # We track the requests sent off to each agent. As the - # responses come in, we can check them off as completed, - # and once all are, we respond back to the client. - req$set_configuration_state$requests += areq; + # responses come in, we delete them. Once the requests + # set is empty, we respond back to the client. + add req$set_configuration_state$requests[areq$id]; # We could also broadcast just once on the agent prefix, but # explicit request/response pairs for each agent seems cleaner. @@ -283,62 +283,30 @@ event ClusterAgent::API::set_configuration_response(reqid: string, result: Clust if ( ClusterController::Request::is_null(areq) ) return; - # Record the result and mark the request as done. This also - # marks the request as done in the parent-level request, since - # these records are stored by reference. - areq$results[0] = result; # We only have a single result here atm - areq$finished = T; + # Release the request, which is now done. + ClusterController::Request::finish(areq$id); - # Update the original request from the client: + # Find the original request from the client local req = ClusterController::Request::lookup(areq$parent_id); if ( ClusterController::Request::is_null(req) ) return; - # If there are any requests to the agents still unfinished, - # we're not done yet. - for ( i in req$set_configuration_state$requests ) - if ( ! req$set_configuration_state$requests[i]$finished ) - return; + # Add this result to the overall response + req$results[|req$results|] = result; - # All set_configuration requests to instances are done, so respond - # back to client. We need to compose the result, aggregating - # the results we got from the requests to the agents. In the - # end we have one Result per instance requested in the - # original set_configuration_request. - # - # XXX we can likely generalize result aggregation in the request module. - for ( i in req$set_configuration_state$requests ) - { - local r = req$set_configuration_state$requests[i]; + # Mark this request as done by removing it from the table of pending + # ones. The following if-check should always be true. + if ( areq$id in req$set_configuration_state$requests ) + delete req$set_configuration_state$requests[areq$id]; - local success = T; - local errors: string_vec; - local instance = ""; + # If there are any pending requests to the agents, we're + # done: we respond once every agent has responed (or we time out). + if ( |req$set_configuration_state$requests| > 0 ) + return; - for ( j in r$results ) - { - local res = r$results[j]; - instance = res$instance; - - if ( res$success ) - next; - - success = F; - errors += fmt("node %s failed: %s", res$node, res$error); - } - - req$results += ClusterController::Types::Result( - $reqid = req$id, - $instance = instance, - $success = success, - $error = join_string_vec(errors, ", ") - ); - - ClusterController::Request::finish(r$id); - } - - # We're now done with the original set_configuration request. - # Adopt the configuration as the current one. + # All set_configuration requests to instances are done, so adopt the + # client's requested configuration as the new one and respond back to + # client. g_config_current = req$set_configuration_state$config; g_config_reqid_pending = ""; diff --git a/scripts/policy/frameworks/cluster/controller/request.zeek b/scripts/policy/frameworks/cluster/controller/request.zeek index 202a615e6b..987dc9338c 100644 --- a/scripts/policy/frameworks/cluster/controller/request.zeek +++ b/scripts/policy/frameworks/cluster/controller/request.zeek @@ -28,7 +28,7 @@ export { # State specific to the set_configuration request/response events type SetConfigurationState: record { config: ClusterController::Types::Configuration; - requests: vector of Request &default=vector(); + requests: set[string] &default=set(); }; # State specific to supervisor interactions From 4b5584a85d28d3e449254d80db43a5781d4dcbc6 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 31 Jan 2022 18:13:15 -0800 Subject: [PATCH 034/204] Move redefs of ClusterController::Request::Request to their places of use The Request module does not need to know about additional state tucked onto it by its users. --- .../policy/frameworks/cluster/agent/main.zeek | 13 ++++++-- .../frameworks/cluster/controller/main.zeek | 18 +++++++++-- .../cluster/controller/request.zeek | 32 +++---------------- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/scripts/policy/frameworks/cluster/agent/main.zeek b/scripts/policy/frameworks/cluster/agent/main.zeek index f545186304..6c782734c1 100644 --- a/scripts/policy/frameworks/cluster/agent/main.zeek +++ b/scripts/policy/frameworks/cluster/agent/main.zeek @@ -13,6 +13,15 @@ module ClusterAgent::Runtime; +# Request state specific to supervisor interactions +type SupervisorState: record { + node: string; +}; + +redef record ClusterController::Request::Request += { + supervisor_state: SupervisorState &optional; +}; + redef ClusterController::role = ClusterController::Types::AGENT; # The global configuration as passed to us by the controller @@ -69,7 +78,7 @@ event SupervisorControl::destroy_response(reqid: string, result: bool) function supervisor_create(nc: Supervisor::NodeConfig) { local req = ClusterController::Request::create(); - req$supervisor_state = ClusterController::Request::SupervisorState($node = nc$name); + req$supervisor_state = SupervisorState($node = nc$name); event SupervisorControl::create_request(req$id, nc); ClusterController::Log::info(fmt("issued supervisor create for %s, %s", nc$name, req$id)); } @@ -77,7 +86,7 @@ function supervisor_create(nc: Supervisor::NodeConfig) function supervisor_destroy(node: string) { local req = ClusterController::Request::create(); - req$supervisor_state = ClusterController::Request::SupervisorState($node = node); + req$supervisor_state = SupervisorState($node = node); event SupervisorControl::destroy_request(req$id, node); ClusterController::Log::info(fmt("issued supervisor destroy for %s, %s", node, req$id)); } diff --git a/scripts/policy/frameworks/cluster/controller/main.zeek b/scripts/policy/frameworks/cluster/controller/main.zeek index d96b49d58f..b0fe565553 100644 --- a/scripts/policy/frameworks/cluster/controller/main.zeek +++ b/scripts/policy/frameworks/cluster/controller/main.zeek @@ -15,6 +15,20 @@ module ClusterController::Runtime; +# Request state specific to the set_configuration request/response events +type SetConfigurationState: record { + config: ClusterController::Types::Configuration; + requests: set[string] &default=set(); +}; + +# Dummy state for testing events. +type TestState: record { }; + +redef record ClusterController::Request::Request += { + set_configuration_state: SetConfigurationState &optional; + test_state: TestState &optional; +}; + redef ClusterController::role = ClusterController::Types::CONTROLLER; global check_instances_ready: function(); @@ -323,7 +337,7 @@ event ClusterController::API::set_configuration_request(reqid: string, config: C local res: ClusterController::Types::Result; local req = ClusterController::Request::create(reqid); - req$set_configuration_state = ClusterController::Request::SetConfigurationState($config = config); + req$set_configuration_state = SetConfigurationState($config = config); # At the moment there can only be one pending request. if ( g_config_reqid_pending != "" ) @@ -486,7 +500,7 @@ event ClusterController::API::test_timeout_request(reqid: string, with_state: bo # This state times out and triggers a timeout response in the # above request_expired event handler. local req = ClusterController::Request::create(reqid); - req$test_state = ClusterController::Request::TestState(); + req$test_state = TestState(); } } diff --git a/scripts/policy/frameworks/cluster/controller/request.zeek b/scripts/policy/frameworks/cluster/controller/request.zeek index 987dc9338c..4fc648b511 100644 --- a/scripts/policy/frameworks/cluster/controller/request.zeek +++ b/scripts/policy/frameworks/cluster/controller/request.zeek @@ -18,37 +18,13 @@ export { ## received by the client), this specifies that original, "parent" ## request. parent_id: string &optional; - }; - # API-specific state. XXX we may be able to generalize after this has - # settled a bit more. It would also be nice to move request-specific - # state out of this module -- we could for example redef Request in - # main.zeek as needed. - - # State specific to the set_configuration request/response events - type SetConfigurationState: record { - config: ClusterController::Types::Configuration; - requests: set[string] &default=set(); - }; - - # State specific to supervisor interactions - type SupervisorState: record { - node: string; - }; - - # State for testing events - type TestState: record { - }; - - # The redef is a workaround so we can use the Request type - # while it is still being defined. - redef record Request += { + ## The results vector builds up the list of results we eventually + ## send to the requestor when we have processed the request. results: ClusterController::Types::ResultVec &default=vector(); - finished: bool &default=F; - set_configuration_state: SetConfigurationState &optional; - supervisor_state: SupervisorState &optional; - test_state: TestState &optional; + ## An internal flag to track whether a request is complete. + finished: bool &default=F; }; ## A token request that serves as a null/nonexistant request. From 3da95de5b80a4a98ceddd148d42b017b44819ffa Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 31 Jan 2022 18:35:22 -0800 Subject: [PATCH 035/204] Be more conservative with triggering request timeout events --- scripts/policy/frameworks/cluster/controller/request.zeek | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/policy/frameworks/cluster/controller/request.zeek b/scripts/policy/frameworks/cluster/controller/request.zeek index 4fc648b511..d7bca5d1a3 100644 --- a/scripts/policy/frameworks/cluster/controller/request.zeek +++ b/scripts/policy/frameworks/cluster/controller/request.zeek @@ -77,7 +77,11 @@ export { function requests_expire_func(reqs: table[string] of Request, reqid: string): interval { - event ClusterController::Request::request_expired(reqs[reqid]); + # No need to flag request expiration when we've already internally marked + # the request as done. + if ( ! reqs[reqid]$finished ) + event ClusterController::Request::request_expired(reqs[reqid]); + return 0secs; } From ad4744eba6eda7b9fe1449a75e732fdbd2d397b5 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 31 Jan 2022 18:42:03 -0800 Subject: [PATCH 036/204] Make members of the ClusterController::Types::State enum all-caps A consistency tweak since we mostly use all-caps elsewhere as well. --- .../policy/frameworks/cluster/controller/types.zeek | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/policy/frameworks/cluster/controller/types.zeek b/scripts/policy/frameworks/cluster/controller/types.zeek index 9d7bc82e3c..20e598c482 100644 --- a/scripts/policy/frameworks/cluster/controller/types.zeek +++ b/scripts/policy/frameworks/cluster/controller/types.zeek @@ -37,11 +37,11 @@ export { ## State that a Cluster Node can be in. State changes trigger an ## API notification (see notify_change()). type State: enum { - Running, ##< Running and operating normally - Stopped, ##< Explicitly stopped - Failed, ##< Failed to start; and permanently halted - Crashed, ##< Crashed, will be restarted, - Unknown, ##< State not known currently (e.g., because of lost connectivity) + RUNNING, ##< Running and operating normally + STOPPED, ##< Explicitly stopped + FAILED, ##< Failed to start; and permanently halted + CRASHED, ##< Crashed, will be restarted, + UNKNOWN, ##< State not known currently (e.g., because of lost connectivity) }; ## Configuration describing a Cluster Node process. From c79c2a2b00c8619b1859b11b6736e9b96b7dbfbb Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 31 Jan 2022 17:53:03 -0800 Subject: [PATCH 037/204] Don't auto-publish Supervisor response events in the cluster agent This was an oversight: we auto-publish the agent's requests _to_ the supervisor, not the latter's responses. --- scripts/policy/frameworks/cluster/agent/main.zeek | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/policy/frameworks/cluster/agent/main.zeek b/scripts/policy/frameworks/cluster/agent/main.zeek index 6c782734c1..553bd771c4 100644 --- a/scripts/policy/frameworks/cluster/agent/main.zeek +++ b/scripts/policy/frameworks/cluster/agent/main.zeek @@ -255,11 +255,8 @@ event zeek_init() Broker::auto_publish(agent_topic, ClusterAgent::API::notify_log); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::create_request); - Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::create_response); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::destroy_request); - Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::destroy_response); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::restart_request); - Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::restart_response); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::stop_request); # Establish connectivity with the controller. From 95f15654986918d43eb77c4eb36d61c2bf048ea3 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 1 Feb 2022 16:48:57 +0000 Subject: [PATCH 038/204] Match DPD TLS signature on one-sided connections. This commit changes DPD matching for TLS connections. A one-sided match is enough to enable DPD now. This commit also removes DPD for SSLv2 connections. SSLv2 connections do basically no longer happen in the wild. SSLv2 is also really finnicky to identify correctly - there is very little data required to match it, and basically all matches today will be false positives. If DPD for SSLv2 is still desired, the optional signature in policy/protocols/ssl/dpd-v2.sig can be loaded. Fixes GH-1952 --- scripts/base/protocols/ssl/dpd.sig | 16 ++++++++-------- scripts/policy/protocols/ssl/dpd-v2.sig | 17 +++++++++++++++++ .../btest/scripts/base/protocols/ssl/dpd.test | 1 + .../external/commit-hash.zeek-testing-private | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 scripts/policy/protocols/ssl/dpd-v2.sig diff --git a/scripts/base/protocols/ssl/dpd.sig b/scripts/base/protocols/ssl/dpd.sig index 1b8cad2f76..2603441d9a 100644 --- a/scripts/base/protocols/ssl/dpd.sig +++ b/scripts/base/protocols/ssl/dpd.sig @@ -1,17 +1,17 @@ -signature dpd_ssl_server { +signature dpd_tls_server { ip-proto == tcp - # Server hello. - payload /^((\x15\x03[\x00\x01\x02\x03]....)?\x16\x03[\x00\x01\x02\x03]..\x02...((\x03[\x00\x01\x02\x03\x04])|(\x7F[\x00-\x50]))|...?\x04..\x00\x02).*/ - requires-reverse-signature dpd_ssl_client - enable "ssl" + # SSL3 / TLS Server hello. + payload /^(\x15\x03[\x00\x01\x02\x03]....)?\x16\x03[\x00\x01\x02\x03]..\x02...((\x03[\x00\x01\x02\x03\x04])|(\x7F[\x00-\x50])).*/ tcp-state responder + enable "ssl" } -signature dpd_ssl_client { +signature dpd_tls_client { ip-proto == tcp - # Client hello. - payload /^(\x16\x03[\x00\x01\x02\x03]..\x01...\x03[\x00\x01\x02\x03]|...?\x01[\x00\x03][\x00\x01\x02\x03\x04]).*/ + # SSL3 / TLS Client hello. + payload /^\x16\x03[\x00\x01\x02\x03]..\x01...\x03[\x00\x01\x02\x03].*/ tcp-state originator + enable "ssl" } signature dpd_dtls_client { diff --git a/scripts/policy/protocols/ssl/dpd-v2.sig b/scripts/policy/protocols/ssl/dpd-v2.sig new file mode 100644 index 0000000000..66f44441c6 --- /dev/null +++ b/scripts/policy/protocols/ssl/dpd-v2.sig @@ -0,0 +1,17 @@ +# This signature can be used to enable DPD for SSL version 2. +# Note that SSLv2 is basically unused by now. Due to the structure of the protocol, it also is sometimes +# hard to disambiguate it from random noise - so you will probably always get a few false positives. + +signature dpd_ssl_server { + ip-proto == tcp + payload /^...?\x04..\x00\x02.*/ + requires-reverse-signature dpd_ssl_client + tcp-state responder + enable "ssl" +} + +signature dpd_ssl_client { + ip-proto == tcp + payload /^...?\x01[\x00\x03][\x00\x01\x02\x03\x04].*/ + tcp-state originator +} diff --git a/testing/btest/scripts/base/protocols/ssl/dpd.test b/testing/btest/scripts/base/protocols/ssl/dpd.test index f7f76a6e1a..4a23aeb0d2 100644 --- a/testing/btest/scripts/base/protocols/ssl/dpd.test +++ b/testing/btest/scripts/base/protocols/ssl/dpd.test @@ -8,6 +8,7 @@ @load base/frameworks/dpd @load base/frameworks/signatures @load-sigs base/protocols/ssl/dpd.sig +@load-sigs policy/protocols/ssl/dpd-v2.sig event zeek_init() { diff --git a/testing/external/commit-hash.zeek-testing-private b/testing/external/commit-hash.zeek-testing-private index 78c1099b34..5b4873bfd1 100644 --- a/testing/external/commit-hash.zeek-testing-private +++ b/testing/external/commit-hash.zeek-testing-private @@ -1 +1 @@ -7c40cc2c3709fc54e5c75c119d1d01ed8a3ceb93 +76b3112a06ff6c1b25c2aedcfe1828bf0b82d7bf From 88c73f468081461fedc040e908f7ff416370e95c Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 2 Feb 2022 12:48:41 +0100 Subject: [PATCH 039/204] Updating CHANGES and VERSION. --- CHANGES | 5 +++++ VERSION | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 4913b7ebc7..3f7d9e3446 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +5.0.0-dev.74 | 2022-02-02 09:46:00 +0100 + + * GH-1890: Consistently warn about mixing vector and scalar operand + depreciaton (Zeke Medley, Corelight) + 5.0.0-dev.72 | 2022-02-02 09:36:30 +0100 * Let TCP-based application analyzers operate without any TCP parent diff --git a/VERSION b/VERSION index 8c3fd1b1e2..69c7f49ec8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.0.0-dev.72 +5.0.0-dev.74 From 791e5545b13739d2e0263339f54dd78929c67532 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 2 Feb 2022 16:09:20 -0800 Subject: [PATCH 040/204] Support optional listening ports for cluster nodes This makes cluster node listening ports &optional, and maps absent values to 0/unknown, the value the cluster framework currently uses to indicate that listening isn't desired. --- scripts/policy/frameworks/cluster/agent/main.zeek | 10 +++++++++- .../policy/frameworks/cluster/controller/types.zeek | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/policy/frameworks/cluster/agent/main.zeek b/scripts/policy/frameworks/cluster/agent/main.zeek index 553bd771c4..e28d516520 100644 --- a/scripts/policy/frameworks/cluster/agent/main.zeek +++ b/scripts/policy/frameworks/cluster/agent/main.zeek @@ -124,10 +124,18 @@ event ClusterAgent::API::set_configuration_request(reqid: string, config: Cluste if ( node$instance == ClusterAgent::name ) g_nodes[node$name] = node; + # The cluster and supervisor frameworks require a port for every + # node, using 0/unknown to signify "don't listen". We use + # optional values and map an absent value to 0/unknown. + local p = 0/unknown; + + if ( node?$p ) + p = node$p; + local cep = Supervisor::ClusterEndpoint( $role = node$role, $host = g_instances[node$instance]$host, - $p = node$p); + $p = p); if ( node?$interface ) cep$interface = node$interface; diff --git a/scripts/policy/frameworks/cluster/controller/types.zeek b/scripts/policy/frameworks/cluster/controller/types.zeek index 20e598c482..e1021aa951 100644 --- a/scripts/policy/frameworks/cluster/controller/types.zeek +++ b/scripts/policy/frameworks/cluster/controller/types.zeek @@ -48,9 +48,9 @@ export { type Node: record { name: string; ##< Cluster-unique, human-readable node name instance: string; ##< Name of instance where node is to run - p: port; ##< Port on which this node will listen role: Supervisor::ClusterRole; ##< Role of the node. state: State; ##< Desired, or current, run state. + p: port &optional; ##< Port on which this node will listen scripts: vector of string &optional; ##< Additional Zeek scripts for node options: set[Option] &optional; ##< Zeek options for node interface: string &optional; ##< Interface to sniff From 7db8634c8ba8bc8b6ca77d67d1f70ac40192880a Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 31 Jan 2022 17:51:33 -0800 Subject: [PATCH 041/204] Add ClusterController::API::get_nodes_request/response event pair This allows querying the status of Zeek nodes currently running in a cluster. The controller relays the request to all instances and accumulates their responses. The response back to the client contains one Result record per instance response, each of which carrying a ClusterController::Types::NodeState vector in its $data member to convey the state of each node at that instance. The NodeState record tracks the name of the node, its role in the controller (if any), its role in the data cluster (if any), as well as PID and listening port, if any. --- .../policy/frameworks/cluster/agent/api.zeek | 23 +++- .../policy/frameworks/cluster/agent/main.zeek | 94 +++++++++++++++ .../frameworks/cluster/controller/api.zeek | 23 ++++ .../frameworks/cluster/controller/main.zeek | 110 +++++++++++++++++- .../frameworks/cluster/controller/types.zeek | 34 +++++- 5 files changed, 272 insertions(+), 12 deletions(-) diff --git a/scripts/policy/frameworks/cluster/agent/api.zeek b/scripts/policy/frameworks/cluster/agent/api.zeek index 7957677457..02b3b28ea9 100644 --- a/scripts/policy/frameworks/cluster/agent/api.zeek +++ b/scripts/policy/frameworks/cluster/agent/api.zeek @@ -13,7 +13,6 @@ export { ## controller and agent. const version = 1; - # Agent API events ## The controller sends this event to convey a new cluster configuration @@ -42,6 +41,28 @@ export { result: ClusterController::Types::Result); + ## The controller sends this event to request a list of + ## :zeek:see:`ClusterController::Types::NodeStatus` records that capture + ## the status of Supervisor-managed nodes running on this instance. + ## instances. + ## + ## reqid: a request identifier string, echoed in the response event. + ## + global get_nodes_request: event(reqid: string); + + ## Response to a get_nodes_request event. The agent sends this back to the + ## controller. + ## + ## reqid: the request identifier used in the request event. + ## + ## result: a :zeek:see:`ClusterController::Types::Result` record. Its data + ## member is a vector of :zeek:see:`ClusterController::Types::NodeState` + ## records, covering the nodes at this instance. The result may also + ## indicate failure, with error messages indicating what went wrong. + ## + global get_nodes_response: event(reqid: string, + result: ClusterController::Types::Result); + ## The controller sends this event to confirm to the agent that it is ## part of the current cluster topology. The agent acknowledges with the ## corresponding response event. diff --git a/scripts/policy/frameworks/cluster/agent/main.zeek b/scripts/policy/frameworks/cluster/agent/main.zeek index e28d516520..9376ae967c 100644 --- a/scripts/policy/frameworks/cluster/agent/main.zeek +++ b/scripts/policy/frameworks/cluster/agent/main.zeek @@ -186,6 +186,94 @@ event ClusterAgent::API::set_configuration_request(reqid: string, config: Cluste } } +event SupervisorControl::status_response(reqid: string, result: Supervisor::Status) + { + local req = ClusterController::Request::lookup(reqid); + if ( ClusterController::Request::is_null(req) ) + return; + + ClusterController::Request::finish(reqid); + + local res = ClusterController::Types::Result( + $reqid = req$parent_id, $instance = ClusterAgent::name); + + local node_statuses: ClusterController::Types::NodeStatusVec; + + for ( node in result$nodes ) + { + local sns = result$nodes[node]; # Supervisor node status + local cns = ClusterController::Types::NodeStatus( + $node=node, $state=ClusterController::Types::PENDING); + + # Identify the role of the node. For data cluster roles (worker, + # manager, etc) we derive this from the cluster node table. For + # agent and controller, we identify via environment variables + # that the controller framework establishes upon creation (see + # the respective boot.zeek scripts). + if ( node in sns$node$cluster ) + { + cns$cluster_role = sns$node$cluster[node]$role; + + # The supervisor's responses use 0/tcp (not 0/unknown) + # when indicating an unused port because its internal + # serialization always assumes TCP. + if ( sns$node$cluster[node]$p != 0/tcp ) + cns$p = sns$node$cluster[node]$p; + } + else + { + if ( "ZEEK_CLUSTER_MGMT_NODE" in sns$node$env ) + { + local role = sns$node$env["ZEEK_CLUSTER_MGMT_NODE"]; + if ( role == "CONTROLLER" ) + { + cns$mgmt_role = ClusterController::Types::CONTROLLER; + # The controller always listens, so the Zeek client can connect. + cns$p = ClusterController::endpoint_info()$network$bound_port; + } + else if ( role == "AGENT" ) + { + cns$mgmt_role = ClusterController::Types::AGENT; + # If we have a controller address, the agent connects to it + # and does not listen. See zeek_init() below for similar logic. + if ( ClusterAgent::controller$address == "0.0.0.0" ) + cns$p = ClusterAgent::endpoint_info()$network$bound_port; + } + else + ClusterController::Log::warning(fmt( + "unexpected cluster management node type '%'", role)); + } + } + + # A PID is available if a supervised node has fully launched + # and is therefore running. + if ( sns?$pid ) + { + cns$pid = sns$pid; + cns$state = ClusterController::Types::RUNNING; + } + + node_statuses += cns; + } + + res$data = node_statuses; + + ClusterController::Log::info(fmt("tx ClusterAgent::API::get_nodes_response %s", + ClusterController::Types::result_to_string(res))); + event ClusterAgent::API::get_nodes_response(req$parent_id, res); + } + +event ClusterAgent::API::get_nodes_request(reqid: string) + { + ClusterController::Log::info(fmt("rx ClusterAgent::API::get_nodes_request %s", reqid)); + + local req = ClusterController::Request::create(); + req$parent_id = reqid; + + event SupervisorControl::status_request(req$id, ""); + ClusterController::Log::info(fmt("issued supervisor status, %s", req$id)); + } + event ClusterAgent::API::agent_welcome_request(reqid: string) { ClusterController::Log::info(fmt("rx ClusterAgent::API::agent_welcome_request %s", reqid)); @@ -231,6 +319,10 @@ event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) to_addr(epi$network$address), ClusterAgent::API::version); } +# XXX We may want a request timeout event handler here. It's arguably cleaner to +# send supervisor failure events back to the controller than to rely on its +# controller-agent request timeout to kick in. + event zeek_init() { local epi = ClusterAgent::endpoint_info(); @@ -253,6 +345,7 @@ event zeek_init() # Auto-publish a bunch of events. Glob patterns or module-level # auto-publish would be helpful here. + Broker::auto_publish(agent_topic, ClusterAgent::API::get_nodes_response); Broker::auto_publish(agent_topic, ClusterAgent::API::set_configuration_response); Broker::auto_publish(agent_topic, ClusterAgent::API::agent_welcome_response); Broker::auto_publish(agent_topic, ClusterAgent::API::agent_standby_response); @@ -263,6 +356,7 @@ event zeek_init() Broker::auto_publish(agent_topic, ClusterAgent::API::notify_log); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::create_request); + Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::status_request); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::destroy_request); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::restart_request); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::stop_request); diff --git a/scripts/policy/frameworks/cluster/controller/api.zeek b/scripts/policy/frameworks/cluster/controller/api.zeek index 27c41d33ff..4ed77ffdb2 100644 --- a/scripts/policy/frameworks/cluster/controller/api.zeek +++ b/scripts/policy/frameworks/cluster/controller/api.zeek @@ -57,6 +57,29 @@ export { result: ClusterController::Types::ResultVec); + ## zeek-client sends this event to request a list of + ## :zeek:see:`ClusterController::Types::NodeStatus` records that capture + ## the status of Supervisor-managed nodes running on the cluster's + ## instances. + ## + ## reqid: a request identifier string, echoed in the response event. + ## + global get_nodes_request: event(reqid: string); + + ## Response to a get_nodes_request event. The controller sends this + ## back to the client. + ## + ## reqid: the request identifier used in the request event. + ## + ## result: a :zeek:type`vector` of :zeek:see:`ClusterController::Types::Result` + ## records. Each record covers one cluster instance. Each record's data + ## member is a vector of :zeek:see:`ClusterController::Types::NodeState` + ## records, covering the nodes at that instance. Results may also indicate + ## failure, with error messages indicating what went wrong. + global get_nodes_response: event(reqid: string, + result: ClusterController::Types::ResultVec); + + # Testing events. These don't provide operational value but expose # internal functionality, triggered by test cases. diff --git a/scripts/policy/frameworks/cluster/controller/main.zeek b/scripts/policy/frameworks/cluster/controller/main.zeek index b0fe565553..3e93d715fd 100644 --- a/scripts/policy/frameworks/cluster/controller/main.zeek +++ b/scripts/policy/frameworks/cluster/controller/main.zeek @@ -21,11 +21,17 @@ type SetConfigurationState: record { requests: set[string] &default=set(); }; +# Request state specific to the get_nodes request/response events +type GetNodesState: record { + requests: set[string] &default=set(); +}; + # Dummy state for testing events. type TestState: record { }; redef record ClusterController::Request::Request += { set_configuration_state: SetConfigurationState &optional; + get_nodes_state: GetNodesState &optional; test_state: TestState &optional; }; @@ -457,6 +463,84 @@ event ClusterController::API::get_instances_request(reqid: string) event ClusterController::API::get_instances_response(reqid, res); } +event ClusterAgent::API::get_nodes_response(reqid: string, result: ClusterController::Types::Result) + { + ClusterController::Log::info(fmt("rx ClusterAgent::API::get_nodes_response %s", reqid)); + + # Retrieve state for the request we just got a response to + local areq = ClusterController::Request::lookup(reqid); + if ( ClusterController::Request::is_null(areq) ) + return; + + # Release the request, which is now done. + ClusterController::Request::finish(areq$id); + + # Find the original request from the client + local req = ClusterController::Request::lookup(areq$parent_id); + if ( ClusterController::Request::is_null(req) ) + return; + + # Zeek's ingestion of an any-typed val via Broker yields an opaque + # Broker DataVal. When Zeek forwards this val via another event it stays + # in this opaque form. To avoid forcing recipients to distinguish + # whether the val is of the actual, intended (any-)type or a Broker + # DataVal wrapper, we explicitly cast it back to our intended Zeek + # type. This test case demonstrates: broker.remote_event_vector_any + result$data = result$data as ClusterController::Types::NodeStatusVec; + + # Add this result to the overall response + req$results[|req$results|] = result; + + # Mark this request as done by removing it from the table of pending + # ones. The following if-check should always be true. + if ( areq$id in req$get_nodes_state$requests ) + delete req$get_nodes_state$requests[areq$id]; + + # If we still have pending queries out to the agents, do nothing: we'll + # handle this soon, or our request will time out and we respond with + # error. + if ( |req$get_nodes_state$requests| > 0 ) + return; + + ClusterController::Log::info(fmt("tx ClusterController::API::get_nodes_response %s", + ClusterController::Request::to_string(req))); + event ClusterController::API::get_nodes_response(req$id, req$results); + ClusterController::Request::finish(req$id); + } + +event ClusterController::API::get_nodes_request(reqid: string) + { + ClusterController::Log::info(fmt("rx ClusterController::API::get_nodes_request %s", reqid)); + + # Special case: if we have no instances, respond right away. + if ( |g_instances| == 0 ) + { + ClusterController::Log::info(fmt("tx ClusterController::API::get_nodes_response %s", reqid)); + event ClusterController::API::get_nodes_response(reqid, vector( + ClusterController::Types::Result($reqid=reqid, $success=F, + $error="no instances connected"))); + return; + } + + local req = ClusterController::Request::create(reqid); + req$get_nodes_state = GetNodesState(); + + for ( name in g_instances ) + { + if ( name !in g_instances_ready ) + next; + + local agent_topic = ClusterAgent::topic_prefix + "/" + name; + local areq = ClusterController::Request::create(); + + areq$parent_id = req$id; + add req$get_nodes_state$requests[areq$id]; + + ClusterController::Log::info(fmt("tx ClusterAgent::API::get_nodes_request %s to %s", areq$id, name)); + Broker::publish(agent_topic, ClusterAgent::API::get_nodes_request, areq$id); + } + } + event ClusterController::Request::request_expired(req: ClusterController::Request::Request) { # Various handlers for timed-out request state. We use the state members @@ -480,6 +564,18 @@ event ClusterController::Request::request_expired(req: ClusterController::Reques event ClusterController::API::set_configuration_response(req$id, req$results); } + if ( req?$get_nodes_state ) + { + res = ClusterController::Types::Result($reqid=req$id); + res$success = F; + res$error = "request timed out"; + req$results += res; + + ClusterController::Log::info(fmt("tx ClusterController::API::get_nodes_response %s", + ClusterController::Request::to_string(req))); + event ClusterController::API::get_nodes_response(req$id, req$results); + } + if ( req?$test_state ) { res = ClusterController::Types::Result($reqid=req$id); @@ -525,13 +621,15 @@ event zeek_init() Broker::subscribe(ClusterController::topic); # Events sent to the client: + local events: vector of any = [ + ClusterController::API::get_instances_response, + ClusterController::API::set_configuration_response, + ClusterController::API::get_nodes_response, + ClusterController::API::test_timeout_response + ]; - Broker::auto_publish(ClusterController::topic, - ClusterController::API::get_instances_response); - Broker::auto_publish(ClusterController::topic, - ClusterController::API::set_configuration_response); - Broker::auto_publish(ClusterController::topic, - ClusterController::API::test_timeout_response); + for ( i in events ) + Broker::auto_publish(ClusterController::topic, events[i]); ClusterController::Log::info("controller is live"); } diff --git a/scripts/policy/frameworks/cluster/controller/types.zeek b/scripts/policy/frameworks/cluster/controller/types.zeek index e1021aa951..ad7fce9c1e 100644 --- a/scripts/policy/frameworks/cluster/controller/types.zeek +++ b/scripts/policy/frameworks/cluster/controller/types.zeek @@ -9,9 +9,9 @@ export { ## include the data cluster node types (worker, logger, etc) -- those ## continue to be managed by the cluster framework. type Role: enum { - NONE, - AGENT, - CONTROLLER, + NONE, ##< No active role in cluster management + AGENT, ##< A cluster management agent. + CONTROLLER, ##< The cluster's controller. }; ## A Zeek-side option with value. @@ -35,8 +35,11 @@ export { type InstanceVec: vector of Instance; ## State that a Cluster Node can be in. State changes trigger an - ## API notification (see notify_change()). + ## API notification (see notify_change()). The Pending state corresponds + ## to the Supervisor not yet reporting a PID for a node when it has not + ## yet fully launched. type State: enum { + PENDING, ##< Not yet running RUNNING, ##< Running and operating normally STOPPED, ##< Explicitly stopped FAILED, ##< Failed to start; and permanently halted @@ -61,7 +64,6 @@ export { ## Data structure capturing a cluster's complete configuration. type Configuration: record { id: string &default=unique_id(""); ##< Unique identifier for a particular configuration - ## The instances in the cluster. instances: set[Instance] &default=set(); @@ -69,6 +71,26 @@ export { nodes: set[Node] &default=set(); }; + ## The status of a Supervisor-managed node, as reported to the client in + ## a get_nodes_request/get_nodes_response transaction. + type NodeStatus: record { + ## Cluster-unique, human-readable node name + node: string; + ## Current run state of the node. + state: State; + ## Role the node plays in cluster management. + mgmt_role: Role &default=NONE; + ## Role the node plays in the data cluster. + cluster_role: Supervisor::ClusterRole &default=Supervisor::NONE; + ## Process ID of the node. This is optional because the Supervisor may not have + ## a PID when a node is still bootstrapping. + pid: int &optional; + ## The node's Broker peering listening port, if any. + p: port &optional; + }; + + type NodeStatusVec: vector of NodeStatus; + ## Return value for request-response API event pairs type Result: record { reqid: string; ##< Request ID of operation this result refers to @@ -81,6 +103,8 @@ export { type ResultVec: vector of Result; + ## Given a :zeek:see:`ClusterController::Types::Result` record, + ## this function returns a string summarizing it. global result_to_string: function(res: Result): string; } From 4c5de66a2269e1551dc65fae55ac71e0177afa5c Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 31 Jan 2022 18:51:24 -0800 Subject: [PATCH 042/204] Bump zeek-client for the get-nodes command --- auxil/zeek-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeek-client b/auxil/zeek-client index 553d897734..749e3542b9 160000 --- a/auxil/zeek-client +++ b/auxil/zeek-client @@ -1 +1 @@ -Subproject commit 553d897734b6d9abbc2e4467fae89f68a2c7315d +Subproject commit 749e3542b9a77bbcb67db945818d11211205a35e From 3b79c36146af84dc25ed2067602c9e8c7750af63 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 31 Jan 2022 22:58:10 -0800 Subject: [PATCH 043/204] Bump external cluster testsuite --- testing/external/commit-hash.zeek-testing-cluster | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/external/commit-hash.zeek-testing-cluster b/testing/external/commit-hash.zeek-testing-cluster index 93a321a305..460a403c4e 100644 --- a/testing/external/commit-hash.zeek-testing-cluster +++ b/testing/external/commit-hash.zeek-testing-cluster @@ -1 +1 @@ -a2b3414ff6cf7cc3141c11849519c58fe15727ec +8e0401661fca089e941ab844694f9d2314f1401f From 94e71b738a66f3bf9358b39c9018e2e3ab981268 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 3 Feb 2022 08:53:10 -0800 Subject: [PATCH 044/204] minor enhancements for ZAM inlining --- src/Expr.h | 5 +++-- src/script_opt/Expr.cc | 6 ++++++ src/script_opt/Inline.cc | 17 +---------------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/Expr.h b/src/Expr.h index ddfcdaf124..c7eb4cea21 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -626,8 +626,8 @@ protected: // type (vec, list, table, record). bool IsScalarAggregateOp() const; - // Warns about depreciated scalar vector operations like `[1, 2, - // 3] == 1` or `["a", "b", "c"] + "a"`. + // Warns about deprecated scalar vector operations like + // `[1, 2, 3] == 1` or `["a", "b", "c"] + "a"`. void CheckScalarAggOp() const; ExprPtr op1; @@ -1161,6 +1161,7 @@ public: // Optimization-related: ExprPtr Duplicate() override; + ExprPtr Inline(Inliner* inl) override; bool HasReducedOps(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index b4db48a6ec..95f2274150 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -1858,6 +1858,12 @@ ExprPtr RecordConstructorExpr::Duplicate() return SetSucc(new RecordConstructorExpr(op_l)); } +ExprPtr RecordConstructorExpr::Inline(Inliner* inl) + { + op = op->Inline(inl)->AsListExprPtr(); + return ThisPtr(); + } + bool RecordConstructorExpr::HasReducedOps(Reducer* c) const { auto& exprs = op->AsListExpr()->Exprs(); diff --git a/src/script_opt/Inline.cc b/src/script_opt/Inline.cc index 15e1c81391..f9b3e12fd5 100644 --- a/src/script_opt/Inline.cc +++ b/src/script_opt/Inline.cc @@ -125,23 +125,8 @@ void Inliner::Analyze() } for ( auto& f : funcs ) - { - const auto& func_ptr = f.FuncPtr(); - const auto& func = func_ptr.get(); - const auto& body = f.Body(); - - // Processing optimization: only spend time trying to inline f - // if we haven't marked it as inlineable. This trades off a - // bunch of compilation load (inlining every single function, - // even though almost none will be called directly) for a - // modest gain of having compiled code for those rare - // circumstances in which a Zeek function can be called - // not ultimately stemming from an event (such as global - // scripting, or expiration functions). - - if ( should_analyze(func_ptr, body) && inline_ables.count(func) == 0 ) + if ( should_analyze(f.FuncPtr(), f.Body()) ) InlineFunction(&f); - } } void Inliner::InlineFunction(FuncInfo* f) From 16e9af137fa50abc92d4e42ca011616f61ea08f9 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 3 Feb 2022 08:59:39 -0800 Subject: [PATCH 045/204] fixes for ZAM profiling, which didn't get fully integrated originally --- src/Options.cc | 5 +++-- src/script_opt/ScriptOpt.cc | 19 +++++++++++++++++++ src/script_opt/ScriptOpt.h | 3 +++ src/zeek-setup.cc | 2 ++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Options.cc b/src/Options.cc index 9ddeed5b0c..ccc9ddae5e 100644 --- a/src/Options.cc +++ b/src/Options.cc @@ -193,7 +193,8 @@ static void print_analysis_help() fprintf(stderr, " no-ZAM-opt omit low-level ZAM optimization\n"); fprintf(stderr, " optimize-all optimize all scripts, even inlined ones\n"); fprintf(stderr, " optimize-AST optimize the (transformed) AST; implies xform\n"); - fprintf(stderr, " profile-ZAM generate to stdout a ZAM execution profile\n"); + fprintf(stderr, + " profile-ZAM generate to stdout a ZAM execution profile; implies -O ZAM\n"); fprintf(stderr, " report-recursive report on recursive functions and exit\n"); fprintf(stderr, " xform transform scripts to \"reduced\" form\n"); @@ -248,7 +249,7 @@ static void set_analysis_option(const char* opt, Options& opts) else if ( util::streq(opt, "optimize-AST") ) a_o.activate = a_o.optimize_AST = true; else if ( util::streq(opt, "profile-ZAM") ) - a_o.activate = a_o.profile_ZAM = true; + a_o.activate = a_o.gen_ZAM_code = a_o.profile_ZAM = true; else if ( util::streq(opt, "report-C++") ) a_o.report_CPP = true; else if ( util::streq(opt, "report-recursive") ) diff --git a/src/script_opt/ScriptOpt.cc b/src/script_opt/ScriptOpt.cc index 05ef655016..94f711da6c 100644 --- a/src/script_opt/ScriptOpt.cc +++ b/src/script_opt/ScriptOpt.cc @@ -578,4 +578,23 @@ void analyze_scripts() analyze_scripts_for_ZAM(pfs); } +void profile_script_execution() + { + if ( analysis_options.profile_ZAM ) + { + report_ZOP_profile(); + + for ( auto& f : funcs ) + { + if ( f.Body()->Tag() == STMT_ZAM ) + cast_intrusive(f.Body())->ProfileExecution(); + } + } + } + +void finish_script_execution() + { + profile_script_execution(); + } + } // namespace zeek::detail diff --git a/src/script_opt/ScriptOpt.h b/src/script_opt/ScriptOpt.h index dba9a41187..95d7889d7e 100644 --- a/src/script_opt/ScriptOpt.h +++ b/src/script_opt/ScriptOpt.h @@ -185,6 +185,9 @@ extern bool should_analyze(const ScriptFuncPtr& f, const StmtPtr& body); // Analyze all of the parsed scripts collectively for optimization. extern void analyze_scripts(); +// Called when Zeek is terminating. +extern void finish_script_execution(); + // Used for C++-compiled scripts to signal their presence, by setting this // to a non-empty value. extern void (*CPP_init_hook)(); diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index c0786f29fd..968bac26f3 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -324,6 +324,8 @@ static void terminate_bro() plugin_mgr->FinishPlugins(); + finish_script_execution(); + delete zeekygen_mgr; delete packet_mgr; delete analyzer_mgr; From a6e493062c4dc36830bae1625e6e7f06f3617ca1 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 3 Feb 2022 20:35:25 -0800 Subject: [PATCH 046/204] fix existing checks for looking to use C++ when it's not available --- src/script_opt/ScriptOpt.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/script_opt/ScriptOpt.cc b/src/script_opt/ScriptOpt.cc index 05ef655016..57abebda1a 100644 --- a/src/script_opt/ScriptOpt.cc +++ b/src/script_opt/ScriptOpt.cc @@ -286,9 +286,6 @@ static void init_options() if ( analysis_options.use_CPP && generating_CPP ) reporter->FatalError("generating C++ incompatible with using C++"); - if ( analysis_options.use_CPP && ! CPP_init_hook ) - reporter->FatalError("no C++ functions available to use"); - auto usage = getenv("ZEEK_USAGE_ISSUES"); if ( usage ) @@ -336,10 +333,7 @@ static void init_options() static void report_CPP() { if ( ! CPP_init_hook ) - { - printf("no C++ script bodies available\n"); - exit(0); - } + reporter->FatalError("no C++ script bodies available"); printf("C++ script bodies available that match loaded scripts:\n"); @@ -373,6 +367,9 @@ static void report_CPP() static void use_CPP() { + if ( ! CPP_init_hook ) + reporter->FatalError("no C++ functions available to use"); + for ( auto& f : funcs ) { auto hash = f.Profile()->HashVal(); @@ -553,7 +550,14 @@ void analyze_scripts() auto pfs = std::make_unique(funcs, is_CPP_compilable, false); if ( CPP_init_hook ) + { (*CPP_init_hook)(); + if ( compiled_scripts.empty() ) + // The initialization failed to produce any + // script bodies. Make this easily available + // to subsequent checks. + CPP_init_hook = nullptr; + } if ( analysis_options.report_CPP ) { From 4f470c24ede6fa3e0dde461075ab7894428f222c Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 4 Feb 2022 13:52:04 -0700 Subject: [PATCH 047/204] String/StringVal: Replace char*/string constructors with string_view --- src/Val.cc | 4 +--- src/Val.h | 3 +-- src/ZeekString.cc | 27 ++++++--------------------- src/ZeekString.h | 6 ++---- 4 files changed, 10 insertions(+), 30 deletions(-) diff --git a/src/Val.cc b/src/Val.cc index fa6b5934dd..7b32cdb326 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -939,9 +939,7 @@ StringVal::StringVal(int length, const char* s) { } -StringVal::StringVal(const char* s) : StringVal(new String(s)) { } - -StringVal::StringVal(const string& s) : StringVal(s.length(), s.data()) { } +StringVal::StringVal(std::string_view s) : StringVal(s.length(), s.data()) { } StringVal::~StringVal() { diff --git a/src/Val.h b/src/Val.h index abb2d8cbda..acbca8edec 100644 --- a/src/Val.h +++ b/src/Val.h @@ -527,8 +527,7 @@ class StringVal final : public Val { public: explicit StringVal(String* s); - explicit StringVal(const char* s); - explicit StringVal(const std::string& s); + StringVal(std::string_view s); StringVal(int length, const char* s); ~StringVal() override; diff --git a/src/ZeekString.cc b/src/ZeekString.cc index b62c661b1b..d59c58ff24 100644 --- a/src/ZeekString.cc +++ b/src/ZeekString.cc @@ -47,12 +47,7 @@ String::String(const u_char* str, int arg_n, bool add_NUL) : String() Set(str, arg_n, add_NUL); } -String::String(const char* str) : String() - { - Set(str); - } - -String::String(const std::string& str) : String() +String::String(std::string_view str) : String() { Set(str); } @@ -147,31 +142,21 @@ void String::Set(const u_char* str, int len, bool add_NUL) use_free_to_delete = false; } -void String::Set(const char* str) +void String::Set(std::string_view str) { Reset(); - if ( str ) + if ( str.data() ) { - n = strlen(str); + n = str.size(); b = new u_char[n + 1]; - memcpy(b, str, n + 1); + memcpy(b, str.data(), n); + b[n] = 0; final_NUL = true; use_free_to_delete = false; } } -void String::Set(const std::string& str) - { - Reset(); - - n = str.size(); - b = new u_char[n + 1]; - memcpy(b, str.c_str(), n + 1); - final_NUL = true; - use_free_to_delete = false; - } - void String::Set(const String& str) { *this = str; diff --git a/src/ZeekString.h b/src/ZeekString.h index 1f8ec84985..e92574c2ec 100644 --- a/src/ZeekString.h +++ b/src/ZeekString.h @@ -43,8 +43,7 @@ public: // Constructors creating internal copies of the data passed in. String(const u_char* str, int arg_n, bool add_NUL); - explicit String(const char* str); - explicit String(const std::string& str); + String(std::string_view str); String(const String& bs); // Constructor that takes owernship of the vector passed in. @@ -72,8 +71,7 @@ public: // contents to a copy of the string given by the arguments. // void Set(const u_char* str, int len, bool add_NUL = true); - void Set(const char* str); - void Set(const std::string& str); + void Set(std::string_view str); void Set(const String& str); void SetUseFreeToDelete(int use_it) { use_free_to_delete = use_it; } From 6a46d1584cda2007cda1de8dc2c8a45e0d41966d Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 4 Feb 2022 12:29:26 -0800 Subject: [PATCH 048/204] Add capture to a Sumstats when-statement This resolves a deprecation warning that currently triggers when running Sumstats in clusterized Zeek. --- scripts/base/frameworks/sumstats/cluster.zeek | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base/frameworks/sumstats/cluster.zeek b/scripts/base/frameworks/sumstats/cluster.zeek index f055355170..40f6eb43c9 100644 --- a/scripts/base/frameworks/sumstats/cluster.zeek +++ b/scripts/base/frameworks/sumstats/cluster.zeek @@ -481,7 +481,7 @@ function request_key(ss_name: string, key: Key): Result add dynamic_requests[uid]; event SumStats::cluster_get_result(uid, ss_name, key, F); - return when ( uid in done_with && Cluster::worker_count == done_with[uid] ) + return when [uid, ss_name, key] ( uid in done_with && Cluster::worker_count == done_with[uid] ) { #print "done with request_key"; local result = key_requests[uid]; From 5bcccbd90ecee62dbc5ff6db506c19bb9dc67f70 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 7 Feb 2022 10:05:29 -0700 Subject: [PATCH 049/204] Update submodule(s) [nomail] [skip ci] --- auxil/bifcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/bifcl b/auxil/bifcl index eed5effea5..3b5efa59f1 160000 --- a/auxil/bifcl +++ b/auxil/bifcl @@ -1 +1 @@ -Subproject commit eed5effea5661e03b50d0436fecb620a05fb1250 +Subproject commit 3b5efa59f137fc5a15ace602d44e176f97bae083 From 0a70595d44d6ebe842ecb3e5fcc7a230dc606bfa Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 7 Feb 2022 15:35:02 -0700 Subject: [PATCH 050/204] Update submodule(s) [nomail] [skip ci] --- auxil/zeek-aux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeek-aux b/auxil/zeek-aux index 0f120aa00c..6e9235cf39 160000 --- a/auxil/zeek-aux +++ b/auxil/zeek-aux @@ -1 +1 @@ -Subproject commit 0f120aa00c2b666ed5c430a6bcf1043b82f17e64 +Subproject commit 6e9235cf39a038fa96d4ae1acf8f446a7e75cc24 From 41abf8f4227db4bcac6f964c1efe3d5232e7061b Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Tue, 8 Feb 2022 10:02:12 -0800 Subject: [PATCH 051/204] Bump zeek-client for Broker enum fix/workaround --- auxil/zeek-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeek-client b/auxil/zeek-client index 0f5648f8d6..3a3aa08e0d 160000 --- a/auxil/zeek-client +++ b/auxil/zeek-client @@ -1 +1 @@ -Subproject commit 0f5648f8d694eb91f6944a41851e2def7bcc82f3 +Subproject commit 3a3aa08e0d68d7f734fb92329798c375978ccb3a From 3e0a86e3b3c52f78350d6cfd6463c9206d78beaa Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 9 Feb 2022 12:26:42 -0800 Subject: [PATCH 052/204] Updates to the cluster controller scripts to fix the docs build Mostly trivial changes, except for one aspect: if a module exports a record type and that record bears Zeekygen comments, then redefs that add to the record in another module cannot be private to that module. Zeekygen will complain with "unknown target" errors, even when such redefs have Zeekygen comments. So this commits also adds two export-blocks that aren't technically required at this point. --- .../policy/frameworks/cluster/agent/api.zeek | 2 +- .../policy/frameworks/cluster/agent/main.zeek | 13 ++++--- .../frameworks/cluster/controller/api.zeek | 2 +- .../frameworks/cluster/controller/main.zeek | 34 +++++++++++++------ .../cluster/controller/request.zeek | 7 +++- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/scripts/policy/frameworks/cluster/agent/api.zeek b/scripts/policy/frameworks/cluster/agent/api.zeek index 02b3b28ea9..460c106b9b 100644 --- a/scripts/policy/frameworks/cluster/agent/api.zeek +++ b/scripts/policy/frameworks/cluster/agent/api.zeek @@ -56,7 +56,7 @@ export { ## reqid: the request identifier used in the request event. ## ## result: a :zeek:see:`ClusterController::Types::Result` record. Its data - ## member is a vector of :zeek:see:`ClusterController::Types::NodeState` + ## member is a vector of :zeek:see:`ClusterController::Types::NodeStatus` ## records, covering the nodes at this instance. The result may also ## indicate failure, with error messages indicating what went wrong. ## diff --git a/scripts/policy/frameworks/cluster/agent/main.zeek b/scripts/policy/frameworks/cluster/agent/main.zeek index 9376ae967c..7abd263d56 100644 --- a/scripts/policy/frameworks/cluster/agent/main.zeek +++ b/scripts/policy/frameworks/cluster/agent/main.zeek @@ -13,10 +13,15 @@ module ClusterAgent::Runtime; -# Request state specific to supervisor interactions -type SupervisorState: record { - node: string; -}; +# This export is mainly to appease Zeekygen's need to understand redefs of the +# Request record below. Without it, it fails to establish link targets for the +# tucked-on types. +export { + ## Request state specific to the agent's Supervisor interactions. + type SupervisorState: record { + node: string; ##< Name of the node the Supervisor is acting on. + }; +} redef record ClusterController::Request::Request += { supervisor_state: SupervisorState &optional; diff --git a/scripts/policy/frameworks/cluster/controller/api.zeek b/scripts/policy/frameworks/cluster/controller/api.zeek index 4ed77ffdb2..ce0ebe31c5 100644 --- a/scripts/policy/frameworks/cluster/controller/api.zeek +++ b/scripts/policy/frameworks/cluster/controller/api.zeek @@ -73,7 +73,7 @@ export { ## ## result: a :zeek:type`vector` of :zeek:see:`ClusterController::Types::Result` ## records. Each record covers one cluster instance. Each record's data - ## member is a vector of :zeek:see:`ClusterController::Types::NodeState` + ## member is a vector of :zeek:see:`ClusterController::Types::NodeStatus` ## records, covering the nodes at that instance. Results may also indicate ## failure, with error messages indicating what went wrong. global get_nodes_response: event(reqid: string, diff --git a/scripts/policy/frameworks/cluster/controller/main.zeek b/scripts/policy/frameworks/cluster/controller/main.zeek index 3e93d715fd..4e7d261b2c 100644 --- a/scripts/policy/frameworks/cluster/controller/main.zeek +++ b/scripts/policy/frameworks/cluster/controller/main.zeek @@ -15,19 +15,31 @@ module ClusterController::Runtime; -# Request state specific to the set_configuration request/response events -type SetConfigurationState: record { - config: ClusterController::Types::Configuration; - requests: set[string] &default=set(); -}; +# This export is mainly to appease Zeekygen's need to understand redefs of the +# Request record below. Without it, it fails to establish link targets for the +# tucked-on types. +export { + ## Request state specific to + ## :zeek:see:`ClusterController::API::set_configuration_request` and + ## :zeek:see:`ClusterController::API::set_configuration_response`. + type SetConfigurationState: record { + ## The cluster configuration established with this request + config: ClusterController::Types::Configuration; + ## Request state for every controller/agent transaction. + requests: set[string] &default=set(); + }; -# Request state specific to the get_nodes request/response events -type GetNodesState: record { - requests: set[string] &default=set(); -}; + ## Request state specific to + ## :zeek:see:`ClusterController::API::get_nodes_request` and + ## :zeek:see:`ClusterController::API::get_nodes_response`. + type GetNodesState: record { + ## Request state for every controller/agent transaction. + requests: set[string] &default=set(); + }; -# Dummy state for testing events. -type TestState: record { }; + ## Dummy state for internal state-keeping test cases. + type TestState: record { }; +} redef record ClusterController::Request::Request += { set_configuration_state: SetConfigurationState &optional; diff --git a/scripts/policy/frameworks/cluster/controller/request.zeek b/scripts/policy/frameworks/cluster/controller/request.zeek index d7bca5d1a3..06f23b67da 100644 --- a/scripts/policy/frameworks/cluster/controller/request.zeek +++ b/scripts/policy/frameworks/cluster/controller/request.zeek @@ -8,7 +8,12 @@ module ClusterController::Request; export { - ## Request records track each request's state. + ## Request records track state associated with a request/response event + ## pair. Calls to + ## :zeek:see:`ClusterController::Request::create` establish such state + ## when an entity sends off a request event, while + ## :zeek:see:`ClusterController::Request::finish` clears the state when + ## a corresponding response event comes in, or the state times out. type Request: record { ## Each request has a hopfully unique ID provided by the requester. id: string; From a117c81d853def332a99972fa3ce5df2abce8a19 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 9 Feb 2022 10:44:10 -0700 Subject: [PATCH 053/204] Fixing a big pile of Coverity issues 1469562/1469558: Uninitialized fields in Func constructor 1469571/1469566: Null pointer dereference in Trigger::Init() 1469568: Uninitialized fields in CounterVector constructor 1469570: Uncaught exception in plugin manager 1469569: Resource leak in script_opt::Stmt 1469561/1469561: Uninitialized fields in ZBody constructor 1469559: Uninitialized fields in logging::Manager 1469563: Resource leak in ZAMCompiler::CompileDel 1469549/1469553/1469556: Context not fully initialized in HashVals 1469548: Remove dead code from IPAddr 1469551/1469554: Handle iosource_mgr registration failure in broker::Manager 1469552/1469572: Resource leaks in input::Manager --- src/Func.h | 10 +++--- src/IPAddr.h | 4 --- src/OpaqueVal.cc | 15 ++++++-- src/Trigger.cc | 2 +- src/broker/Manager.cc | 9 +++-- src/input/Manager.cc | 9 ++--- src/logging/Manager.cc | 58 +++++++++++++++---------------- src/plugin/Manager.cc | 26 +++++++++----- src/probabilistic/CounterVector.h | 6 ++-- src/probabilistic/Topk.h | 10 +++--- src/script_opt/Stmt.cc | 5 ++- src/script_opt/ZAM/Stmt.cc | 5 ++- src/script_opt/ZAM/ZBody.h | 4 +-- 13 files changed, 93 insertions(+), 70 deletions(-) diff --git a/src/Func.h b/src/Func.h index d3bae45d01..9c9b1c0e97 100644 --- a/src/Func.h +++ b/src/Func.h @@ -139,8 +139,8 @@ protected: std::vector bodies; detail::ScopePtr scope; - Kind kind; - uint32_t unique_id; + Kind kind = SCRIPT_FUNC; + uint32_t unique_id = 0; FuncTypePtr type; std::string name; static inline std::vector unique_ids; @@ -298,7 +298,7 @@ protected: virtual void SetCaptures(Frame* f); private: - size_t frame_size; + size_t frame_size = 0; // List of the outer IDs used in the function. IDPList outer_ids; @@ -369,8 +369,8 @@ struct function_ingredients IDPtr id; StmtPtr body; std::vector inits; - int frame_size; - int priority; + int frame_size = 0; + int priority = 0; ScopePtr scope; }; diff --git a/src/IPAddr.h b/src/IPAddr.h index ea4ed9ac08..91170d73a0 100644 --- a/src/IPAddr.h +++ b/src/IPAddr.h @@ -504,7 +504,6 @@ inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const switch ( v->family ) { - case IPv4: CopyIPv4(&v->in.in4); return; @@ -512,9 +511,6 @@ inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const case IPv6: CopyIPv6(&v->in.in6); return; - - // Can't be reached. - abort(); } } diff --git a/src/OpaqueVal.cc b/src/OpaqueVal.cc index f39c1933a4..94fb70e0e3 100644 --- a/src/OpaqueVal.cc +++ b/src/OpaqueVal.cc @@ -215,7 +215,10 @@ HashVal::HashVal(OpaqueTypePtr t) : OpaqueVal(std::move(t)) valid = false; } -MD5Val::MD5Val() : HashVal(md5_type) { } +MD5Val::MD5Val() : HashVal(md5_type) + { + memset(&ctx, 0, sizeof(ctx)); + } MD5Val::~MD5Val() { } @@ -324,7 +327,10 @@ bool MD5Val::DoUnserialize(const broker::data& data) return true; } -SHA1Val::SHA1Val() : HashVal(sha1_type) { } +SHA1Val::SHA1Val() : HashVal(sha1_type) + { + memset(&ctx, 0, sizeof(ctx)); + } SHA1Val::~SHA1Val() { } @@ -414,7 +420,10 @@ bool SHA1Val::DoUnserialize(const broker::data& data) return true; } -SHA256Val::SHA256Val() : HashVal(sha256_type) { } +SHA256Val::SHA256Val() : HashVal(sha256_type) + { + memset(&ctx, 0, sizeof(ctx)); + } SHA256Val::~SHA256Val() { } diff --git a/src/Trigger.cc b/src/Trigger.cc index 0ce780ef38..9be2bed8d0 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -166,7 +166,7 @@ void Trigger::Init(ExprPtr arg_cond, StmtPtr arg_body, StmtPtr arg_timeout_stmts DBG_LOG(DBG_NOTIFIERS, "%s: instantiating", Name()); - if ( is_return ) + if ( is_return && frame && arg_frame ) { Trigger* parent = frame->GetTrigger(); if ( ! parent ) diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index 4db8c22959..9b8fa1ba1e 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -1811,7 +1811,10 @@ detail::StoreHandleVal* Manager::MakeMaster(const string& name, broker::backend Ref(handle); data_stores.emplace(name, handle); - iosource_mgr->RegisterFd(handle->proxy.mailbox().descriptor(), this); + if ( ! iosource_mgr->RegisterFd(handle->proxy.mailbox().descriptor(), this) ) + reporter->FatalError( + "Failed to register broker master mailbox descriptor with iosource_mgr"); + PrepareForwarding(name); if ( ! bstate->endpoint.use_real_time() ) @@ -1916,7 +1919,9 @@ detail::StoreHandleVal* Manager::MakeClone(const string& name, double resync_int Ref(handle); data_stores.emplace(name, handle); - iosource_mgr->RegisterFd(handle->proxy.mailbox().descriptor(), this); + if ( ! iosource_mgr->RegisterFd(handle->proxy.mailbox().descriptor(), this) ) + reporter->FatalError( + "Failed to register broker clone mailbox descriptor with iosource_mgr"); PrepareForwarding(name); return handle; } diff --git a/src/input/Manager.cc b/src/input/Manager.cc index a105739d21..119834b7d6 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -1473,8 +1473,9 @@ void Manager::SendEndOfData(const Stream* i) #ifdef DEBUG DBG_LOG(DBG_INPUT, "SendEndOfData for stream %s", i->name.c_str()); #endif - SendEvent(end_of_data, 2, new StringVal(i->name.c_str()), - new StringVal(i->reader->Info().source)); + auto name = make_intrusive(i->name.c_str()); + auto source = make_intrusive(i->reader->Info().source); + SendEvent(end_of_data, 2, name->Ref(), source->Ref()); if ( i->stream_type == ANALYSIS_STREAM ) file_mgr->EndOfFile(static_cast(i)->file_id); @@ -2560,8 +2561,8 @@ void Manager::ErrorHandler(const Stream* i, ErrorType et, bool reporter_send, co __builtin_unreachable(); } - auto* message = new StringVal(buf); - SendEvent(i->error_event, 3, i->description->Ref(), message, ev.release()); + auto message = make_intrusive(buf); + SendEvent(i->error_event, 3, i->description->Ref(), message->Ref(), ev.release()); } if ( reporter_send ) diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index d35a92f2cf..67e674838c 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -31,27 +31,27 @@ namespace zeek::logging struct Manager::Filter { - Val* fval; + Val* fval = nullptr; string name; - EnumVal* id; - Func* policy; - Func* path_func; + EnumVal* id = nullptr; + Func* policy = nullptr; + Func* path_func = nullptr; string path; - Val* path_val; - EnumVal* writer; - TableVal* config; - TableVal* field_name_map; + Val* path_val = nullptr; + EnumVal* writer = nullptr; + TableVal* config = nullptr; + TableVal* field_name_map = nullptr; string scope_sep; string ext_prefix; - Func* ext_func; - int num_ext_fields; - bool local; - bool remote; - double interval; - Func* postprocessor; + Func* ext_func = nullptr; + int num_ext_fields = 0; + bool local = false; + bool remote = false; + double interval = 0.0; + Func* postprocessor = nullptr; - int num_fields; - threading::Field** fields; + int num_fields = 0; + threading::Field** fields = nullptr; // Vector indexed by field number. Each element is a list of record // indices defining a path leading to the value across potential @@ -63,26 +63,26 @@ struct Manager::Filter struct Manager::WriterInfo { - EnumVal* type; - double open_time; - detail::Timer* rotation_timer; - double interval; - Func* postprocessor; - WriterFrontend* writer; - WriterBackend::WriterInfo* info; - bool from_remote; - bool hook_initialized; + EnumVal* type = nullptr; + double open_time = 0.0; + detail::Timer* rotation_timer = nullptr; + double interval = 0.0; + Func* postprocessor = nullptr; + WriterFrontend* writer = nullptr; + WriterBackend::WriterInfo* info = nullptr; + bool from_remote = false; + bool hook_initialized = false; string instantiating_filter; }; struct Manager::Stream { - EnumVal* id; - bool enabled; + EnumVal* id = nullptr; + bool enabled = false; string name; - RecordType* columns; + RecordType* columns = nullptr; EventHandlerPtr event; - Func* policy; + Func* policy = nullptr; list filters; using WriterPathPair = pair; diff --git a/src/plugin/Manager.cc b/src/plugin/Manager.cc index 7270191dbf..64cfcbf151 100644 --- a/src/plugin/Manager.cc +++ b/src/plugin/Manager.cc @@ -423,16 +423,26 @@ void Manager::ExtendZeekPathForPlugins() if ( p->DynamicPlugin() || p->Name().empty() ) continue; - string canon = std::regex_replace(p->Name(), std::regex("::"), "_"); - string dir = "builtin-plugins/" + canon; + try + { + string canon = std::regex_replace(p->Name(), std::regex("::"), "_"); + string dir = "builtin-plugins/" + canon; - // Use find_file to find the directory in the path. - string script_dir = util::find_file(dir, util::zeek_path()); - if ( script_dir.empty() || ! util::is_dir(script_dir) ) - continue; + // Use find_file to find the directory in the path. + string script_dir = util::find_file(dir, util::zeek_path()); + if ( script_dir.empty() || ! util::is_dir(script_dir) ) + continue; - DBG_LOG(DBG_PLUGINS, " Adding %s to ZEEKPATH", script_dir.c_str()); - path_additions.push_back(script_dir); + DBG_LOG(DBG_PLUGINS, " Adding %s to ZEEKPATH", script_dir.c_str()); + path_additions.push_back(script_dir); + } + catch ( const std::regex_error& e ) + { + // This really shouldn't ever happen, but we do need to catch the exception. + // Report a fatal error because something is wrong if this occurs. + reporter->FatalError("Failed to replace colons in plugin name %s: %s", + p->Name().c_str(), e.what()); + } } for ( const auto& plugin_path : path_additions ) diff --git a/src/probabilistic/CounterVector.h b/src/probabilistic/CounterVector.h index c4a40becea..866b1bf962 100644 --- a/src/probabilistic/CounterVector.h +++ b/src/probabilistic/CounterVector.h @@ -150,13 +150,13 @@ public: protected: friend CounterVector operator|(const CounterVector& x, const CounterVector& y); - CounterVector() { } + CounterVector() = default; private: CounterVector& operator=(const CounterVector&); // Disable. - BitVector* bits; - size_t width; + BitVector* bits = nullptr; + size_t width = 0; }; } // namespace zeek::probabilistic::detail diff --git a/src/probabilistic/Topk.h b/src/probabilistic/Topk.h index 8f269fb13e..10238bef98 100644 --- a/src/probabilistic/Topk.h +++ b/src/probabilistic/Topk.h @@ -171,12 +171,12 @@ private: void Typify(TypePtr t); TypePtr type; - zeek::detail::CompositeHash* hash; + zeek::detail::CompositeHash* hash = nullptr; std::list buckets; - PDict* elementDict; - uint64_t size; // how many elements are we tracking? - uint64_t numElements; // how many elements do we have at the moment - bool pruned; // was this data structure pruned? + PDict* elementDict = nullptr; + uint64_t size = 0; // how many elements are we tracking? + uint64_t numElements = 0; // how many elements do we have at the moment + bool pruned = false; // was this data structure pruned? }; } // namespace zeek::probabilistic::detail diff --git a/src/script_opt/Stmt.cc b/src/script_opt/Stmt.cc index 27a55c5658..feea66a927 100644 --- a/src/script_opt/Stmt.cc +++ b/src/script_opt/Stmt.cc @@ -728,7 +728,7 @@ bool StmtList::IsReduced(Reducer* c) const StmtPtr StmtList::DoReduce(Reducer* c) { - StmtPList* f_stmts = new StmtPList; + StmtPList* f_stmts = new StmtPList{}; bool did_change = false; int n = Stmts().length(); @@ -749,7 +749,10 @@ StmtPtr StmtList::DoReduce(Reducer* c) } if ( f_stmts->length() == 0 ) + { + delete f_stmts; return TransformMe(make_intrusive(), c); + } if ( f_stmts->length() == 1 ) return (*f_stmts)[0]->Reduce(c); diff --git a/src/script_opt/ZAM/Stmt.cc b/src/script_opt/ZAM/Stmt.cc index ad25ca4d0e..fc729e34eb 100644 --- a/src/script_opt/ZAM/Stmt.cc +++ b/src/script_opt/ZAM/Stmt.cc @@ -711,9 +711,8 @@ const ZAMStmt ZAMCompiler::CompileDel(const DelStmt* ds) if ( index_list->Tag() != EXPR_LIST ) reporter->InternalError("non-list in \"delete\""); - auto internal_ind = BuildVals(index_list->AsListExprPtr()); - - return DelTableVO(aggr, internal_ind); + auto internal_ind = std::unique_ptr(BuildVals(index_list->AsListExprPtr())); + return DelTableVO(aggr, internal_ind.get()); } const ZAMStmt ZAMCompiler::CompileWhile(const WhileStmt* ws) diff --git a/src/script_opt/ZAM/ZBody.h b/src/script_opt/ZAM/ZBody.h index 32a9e43b3f..3e39bc8b03 100644 --- a/src/script_opt/ZAM/ZBody.h +++ b/src/script_opt/ZAM/ZBody.h @@ -70,7 +70,7 @@ protected: TraversalCode Traverse(TraversalCallback* cb) const override; private: - const char* func_name; + const char* func_name = nullptr; const ZInst* insts = nullptr; unsigned int ninst; @@ -109,7 +109,7 @@ private: // const method. std::vector* inst_count = nullptr; // for profiling double* CPU_time = nullptr; // cumulative CPU time for the program - std::vector* inst_CPU; // per-instruction CPU time. + std::vector* inst_CPU = nullptr; // per-instruction CPU time. CaseMaps int_cases; CaseMaps uint_cases; From 2e79bc861d37a298ce2d07131b1e71df1a1cfcde Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 9 Feb 2022 14:24:58 -0800 Subject: [PATCH 054/204] Expand generate-docs Github workflow to test docs build on PRs This adds pull requests as a trigger event and runs the doc submodule commit/push as well as the submodule bump only on the original scheduled runs. --- .github/workflows/generate-docs.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index a940523edf..47446522d3 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -1,9 +1,14 @@ name: Generate Documentation on: + pull_request: schedule: - cron: '0 0 * * *' +defaults: + run: + shell: bash + jobs: generate: if: github.repository == 'zeek/zeek' @@ -15,7 +20,6 @@ jobs: token: ${{ secrets.ZEEK_BOT_TOKEN }} - name: Sync Submodules - shell: bash run: | auth_header="$(git config --local --get http.https://github.com/.extraheader)" git submodule sync --recursive @@ -58,7 +62,6 @@ jobs: ( cd build && make -j 3 ) - name: Generate Docs - shell: bash run: | git config --global user.name zeek-bot git config --global user.email info@zeek.org @@ -76,16 +79,19 @@ jobs: echo "*** Check for Sphinx Warnings ***" grep -q WARNING make.out && exit 1 rm make.out - echo "*** Pushing zeek-docs Changes ***" + + - name: Push zeek-docs Changes + if: github.event_name == 'schedule' + run: | + cd doc git remote set-url origin "https://zeek-bot:${{ secrets.ZEEK_BOT_TOKEN }}@github.com/zeek/zeek-docs" git add scripts/ script-reference/ git status git commit -m "Generate docs" && git push || /bin/true - cd .. - name: Update zeek-docs Submodule + if: github.event_name == 'schedule' run: | - echo "*** Update zeek/doc Submodule ***" git config --global user.name zeek-bot git config --global user.email info@zeek.org git remote add auth "https://zeek-bot:${{ secrets.ZEEK_BOT_TOKEN }}@github.com/zeek/zeek" From f34906c9d1d5041ca29f57713d781c5bb4387e67 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 9 Feb 2022 15:57:55 -0800 Subject: [PATCH 055/204] Minor modernizations to Github workflows - Rely on checkout action for recursive clone at depth 1 - Remove some unneeded subshells - Use nproc to determine number of cores for parallelization --- .github/workflows/coverity-scan.yml | 14 ++++---------- .github/workflows/generate-docs.yml | 14 ++++---------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index 2347ed1e07..2b4655b5c7 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -11,14 +11,8 @@ jobs: steps: - uses: actions/checkout@v2 - - - name: Update Submodules - shell: bash - run: | - auth_header="$(git config --local --get http.https://github.com/.extraheader)" - git submodule sync --recursive - git -c "http.extraheader=$auth_header" -c protocol.version=2 \ - submodule update --init --force --recursive --depth=1 + with: + submodules: "recursive" - name: Fetch Dependencies run: | @@ -45,7 +39,7 @@ jobs: wget - name: Install CAF - run: ( cd auxil/broker/caf && ./configure --prefix=`pwd`/build/install-root && cd build && make -j 3 install ) + run: cd auxil/broker/caf && ./configure --prefix=`pwd`/build/install-root && cd build && make -j $(nproc) install - name: Configure run: ./configure --build-type=debug --with-caf=`pwd`/auxil/broker/caf/build/install-root --disable-broker-tests @@ -65,7 +59,7 @@ jobs: - name: Build run: | export PATH=`pwd`/coverity-tools/bin:$PATH - ( cd build && cov-build --dir cov-int make -j 3 ) + ( cd build && cov-build --dir cov-int make -j $(nproc) ) cat build/cov-int/build-log.txt - name: Submit diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index 47446522d3..20baa71484 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -17,15 +17,10 @@ jobs: steps: - uses: actions/checkout@v2 with: - token: ${{ secrets.ZEEK_BOT_TOKEN }} + submodules: "recursive" - - name: Sync Submodules - run: | - auth_header="$(git config --local --get http.https://github.com/.extraheader)" - git submodule sync --recursive - git -c "http.extraheader=$auth_header" -c protocol.version=2 \ - submodule update --init --force --recursive --depth=1 - ( cd doc && git checkout master ) + - name: Switch doc submodule to master + run: cd doc && git checkout master - name: Fetch Dependencies run: | @@ -58,8 +53,7 @@ jobs: run: ./configure - name: Build - run: | - ( cd build && make -j 3 ) + run: cd build && make -j $(nproc) - name: Generate Docs run: | From 54aaf3a62300e9cbe80b2920a8283eea5c7544ea Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 4 Feb 2022 18:04:42 -0800 Subject: [PATCH 056/204] Reorg of the cluster controller to new "Management framework" layout - This gives the cluster controller and agent the common name "Management framework" and changes the start directory of the sources from "policy/frameworks/cluster" to "policy/frameworks/management". This avoids ambiguity with the existing cluster framework. - It renames the "ClusterController" and "ClusterAgent" script modules to "Management::Controller" and "Management::Agent", respectively. This allows us to anchor tooling common to both controller and agent at the "Management" module. - It moves common configuration settings, logging, requests, types, and utilities to the common "Management" module. - It removes the explicit "::Types" submodule (so a request/response result is now a Management::Result, not a Management::Types::Result), which makes typenames more readable. - It updates tests that depend on module naming and full set of scripts. --- .../frameworks/cluster/agent/__load__.zeek | 4 - .../cluster/controller/__load__.zeek | 4 - .../frameworks/cluster/controller/boot.zeek | 36 --- .../frameworks/cluster/controller/config.zeek | 110 ------- .../frameworks/management/__load__.zeek | 11 + .../frameworks/management/agent/__load__.zeek | 4 + .../{cluster => management}/agent/api.zeek | 30 +- .../{cluster => management}/agent/boot.zeek | 18 +- .../{cluster => management}/agent/config.zeek | 67 ++-- .../{cluster => management}/agent/main.zeek | 179 ++++++----- .../policy/frameworks/management/config.zeek | 20 ++ .../management/controller/__load__.zeek | 4 + .../controller/api.zeek | 26 +- .../management/controller/boot.zeek | 36 +++ .../management/controller/config.zeek | 90 ++++++ .../controller/main.zeek | 299 +++++++++--------- .../controller => management}/log.zeek | 36 ++- .../controller => management}/request.zeek | 42 +-- .../controller => management}/types.zeek | 10 +- .../controller => management}/util.zeek | 4 +- scripts/test-all-policy.zeek | 30 +- scripts/zeekygen/__load__.zeek | 4 +- .../Baseline/coverage.bare-mode-errors/errors | 4 +- .../zeek.controller.stdout | 0 .../controller/agent-checkin.zeek | 22 +- 25 files changed, 554 insertions(+), 536 deletions(-) delete mode 100644 scripts/policy/frameworks/cluster/agent/__load__.zeek delete mode 100644 scripts/policy/frameworks/cluster/controller/__load__.zeek delete mode 100644 scripts/policy/frameworks/cluster/controller/boot.zeek delete mode 100644 scripts/policy/frameworks/cluster/controller/config.zeek create mode 100644 scripts/policy/frameworks/management/__load__.zeek create mode 100644 scripts/policy/frameworks/management/agent/__load__.zeek rename scripts/policy/frameworks/{cluster => management}/agent/api.zeek (84%) rename scripts/policy/frameworks/{cluster => management}/agent/boot.zeek (63%) rename scripts/policy/frameworks/{cluster => management}/agent/config.zeek (56%) rename scripts/policy/frameworks/{cluster => management}/agent/main.zeek (58%) create mode 100644 scripts/policy/frameworks/management/config.zeek create mode 100644 scripts/policy/frameworks/management/controller/__load__.zeek rename scripts/policy/frameworks/{cluster => management}/controller/api.zeek (83%) create mode 100644 scripts/policy/frameworks/management/controller/boot.zeek create mode 100644 scripts/policy/frameworks/management/controller/config.zeek rename scripts/policy/frameworks/{cluster => management}/controller/main.zeek (56%) rename scripts/policy/frameworks/{cluster/controller => management}/log.zeek (76%) rename scripts/policy/frameworks/{cluster/controller => management}/request.zeek (72%) rename scripts/policy/frameworks/{cluster/controller => management}/types.zeek (93%) rename scripts/policy/frameworks/{cluster/controller => management}/util.zeek (79%) rename testing/btest/Baseline/{scripts.policy.frameworks.cluster.controller.agent-checkin => scripts.policy.frameworks.management.controller.agent-checkin}/zeek.controller.stdout (100%) rename testing/btest/scripts/policy/frameworks/{cluster => management}/controller/agent-checkin.zeek (64%) diff --git a/scripts/policy/frameworks/cluster/agent/__load__.zeek b/scripts/policy/frameworks/cluster/agent/__load__.zeek deleted file mode 100644 index f7f36173f3..0000000000 --- a/scripts/policy/frameworks/cluster/agent/__load__.zeek +++ /dev/null @@ -1,4 +0,0 @@ -##! The entry point for the cluster agent. It runs bootstrap logic for launching -##! the agent process via Zeek's Supervisor. - -@load ./boot diff --git a/scripts/policy/frameworks/cluster/controller/__load__.zeek b/scripts/policy/frameworks/cluster/controller/__load__.zeek deleted file mode 100644 index 6cd1dc789d..0000000000 --- a/scripts/policy/frameworks/cluster/controller/__load__.zeek +++ /dev/null @@ -1,4 +0,0 @@ -##! The entry point for the cluster controller. It runs bootstrap logic for -##! launching the controller process via Zeek's Supervisor. - -@load ./boot diff --git a/scripts/policy/frameworks/cluster/controller/boot.zeek b/scripts/policy/frameworks/cluster/controller/boot.zeek deleted file mode 100644 index f06a560760..0000000000 --- a/scripts/policy/frameworks/cluster/controller/boot.zeek +++ /dev/null @@ -1,36 +0,0 @@ -##! The cluster controller's boot logic runs in Zeek's supervisor and instructs -##! it to launch the controller process. The controller's main logic resides in -##! main.zeek, similarly to other frameworks. The new process will execute that -##! script. -##! -##! If the current process is not the Zeek supervisor, this does nothing. - -@load ./config - -event zeek_init() - { - if ( ! Supervisor::is_supervisor() ) - return; - - local epi = ClusterController::endpoint_info(); - local sn = Supervisor::NodeConfig($name=epi$id, $bare_mode=T, - $scripts=vector("policy/frameworks/cluster/controller/main.zeek")); - - if ( ClusterController::directory != "" ) - sn$directory = ClusterController::directory; - if ( ClusterController::stdout_file != "" ) - sn$stdout_file = ClusterController::stdout_file; - if ( ClusterController::stderr_file != "" ) - sn$stderr_file = ClusterController::stderr_file; - - # This helps Zeek run controller and agent with a minimal set of scripts. - sn$env["ZEEK_CLUSTER_MGMT_NODE"] = "CONTROLLER"; - - local res = Supervisor::create(sn); - - if ( res != "" ) - { - print(fmt("error: supervisor could not create controller node: %s", res)); - exit(1); - } - } diff --git a/scripts/policy/frameworks/cluster/controller/config.zeek b/scripts/policy/frameworks/cluster/controller/config.zeek deleted file mode 100644 index de4e570115..0000000000 --- a/scripts/policy/frameworks/cluster/controller/config.zeek +++ /dev/null @@ -1,110 +0,0 @@ -##! Configuration settings for the cluster controller. - -@load policy/frameworks/cluster/agent/config - -module ClusterController; - -export { - ## The name of this controller. Defaults to the value of the - ## ZEEK_CONTROLLER_NAME environment variable. When that is unset and the - ## user doesn't redef the value, the implementation defaults to - ## "controller-". - const name = getenv("ZEEK_CONTROLLER_NAME") &redef; - - ## The controller's stdout log name. If the string is non-empty, Zeek will - ## produce a free-form log (i.e., not one governed by Zeek's logging - ## framework) in Zeek's working directory. If left empty, no such log - ## results. - ## - ## Note that the controller also establishes a "proper" Zeek log via the - ## :zeek:see:`ClusterController::Log` module. - const stdout_file = "controller.stdout" &redef; - - ## The controller's stderr log name. Like :zeek:see:`ClusterController::stdout_file`, - ## but for the stderr stream. - const stderr_file = "controller.stderr" &redef; - - ## The network address the controller listens on. By default this uses - ## the value of the ZEEK_CONTROLLER_ADDR environment variable, but you - ## may also redef to a specific value. When empty, the implementation - ## falls back to :zeek:see:`ClusterController::default_address`. - const listen_address = getenv("ZEEK_CONTROLLER_ADDR") &redef; - - ## The fallback listen address if :zeek:see:`ClusterController::listen_address` - ## remains empty. Unless redefined, this uses Broker's own default - ## listen address. - const default_address = Broker::default_listen_address &redef; - - ## The network port the controller listens on. Counterpart to - ## :zeek:see:`ClusterController::listen_address`, defaulting to the - ## ZEEK_CONTROLLER_PORT environment variable. - const listen_port = getenv("ZEEK_CONTROLLER_PORT") &redef; - - ## The fallback listen port if :zeek:see:`ClusterController::listen_port` - ## remains empty. - const default_port = 2150/tcp &redef; - - ## The controller's connect retry interval. Defaults to a more - ## aggressive value compared to Broker's 30s. - const connect_retry = 1sec &redef; - - ## The controller's Broker topic. Clients send requests to this topic. - const topic = "zeek/cluster-control/controller" &redef; - - ## The role of this process in cluster management. Agent and controller - ## both redefine this. Used during logging. - const role = ClusterController::Types::NONE &redef; - - ## The timeout for request state. Such state (see the :zeek:see:`ClusterController::Request` - ## module) ties together request and response event pairs. The timeout causes - ## its cleanup in the absence of a timely response. It applies both to - ## state kept for client requests, as well as state in the agents for - ## requests to the supervisor. - const request_timeout = 10sec &redef; - - ## An optional custom output directory for the controller's stdout and - ## stderr logs. Agent and controller currently only log locally, not via - ## the data cluster's logger node. (This might change in the future.) - ## This means that if both write to the same log file, the output gets - ## garbled. - const directory = "" &redef; - - ## Returns a :zeek:see:`Broker::NetworkInfo` record describing the controller. - global network_info: function(): Broker::NetworkInfo; - - ## Returns a :zeek:see:`Broker::EndpointInfo` record describing the controller. - global endpoint_info: function(): Broker::EndpointInfo; -} - -function network_info(): Broker::NetworkInfo - { - local ni: Broker::NetworkInfo; - - if ( ClusterController::listen_address != "" ) - ni$address = ClusterController::listen_address; - else if ( ClusterController::default_address != "" ) - ni$address = ClusterController::default_address; - else - ni$address = "127.0.0.1"; - - if ( ClusterController::listen_port != "" ) - ni$bound_port = to_port(ClusterController::listen_port); - else - ni$bound_port = ClusterController::default_port; - - return ni; - } - -function endpoint_info(): Broker::EndpointInfo - { - local epi: Broker::EndpointInfo; - - if ( ClusterController::name != "" ) - epi$id = ClusterController::name; - else - epi$id = fmt("controller-%s", gethostname()); - - epi$network = network_info(); - - return epi; - } diff --git a/scripts/policy/frameworks/management/__load__.zeek b/scripts/policy/frameworks/management/__load__.zeek new file mode 100644 index 0000000000..96192ea366 --- /dev/null +++ b/scripts/policy/frameworks/management/__load__.zeek @@ -0,0 +1,11 @@ +##! This loads Management framework functionality needed by both the controller +##! and agents. Note that there's no notion of loading "the Management +##! framework" -- one always loads "management/controller" or +##! "management/agent". This __load__ script exists only to simplify loading all +##! common functionality. + +@load ./config +@load ./log +@load ./request +@load ./types +@load ./util diff --git a/scripts/policy/frameworks/management/agent/__load__.zeek b/scripts/policy/frameworks/management/agent/__load__.zeek new file mode 100644 index 0000000000..57cefe0757 --- /dev/null +++ b/scripts/policy/frameworks/management/agent/__load__.zeek @@ -0,0 +1,4 @@ +##! The entry point for the Management framework's cluster agent. It runs +##! bootstrap logic for launching the agent process via Zeek's Supervisor. + +@load ./boot diff --git a/scripts/policy/frameworks/cluster/agent/api.zeek b/scripts/policy/frameworks/management/agent/api.zeek similarity index 84% rename from scripts/policy/frameworks/cluster/agent/api.zeek rename to scripts/policy/frameworks/management/agent/api.zeek index 460c106b9b..876f121500 100644 --- a/scripts/policy/frameworks/cluster/agent/api.zeek +++ b/scripts/policy/frameworks/management/agent/api.zeek @@ -4,9 +4,9 @@ ##! "_response", respectively. @load base/frameworks/supervisor/control -@load policy/frameworks/cluster/controller/types +@load policy/frameworks/management/types -module ClusterAgent::API; +module Management::Agent::API; export { ## A simple versioning scheme, used to track basic compatibility of @@ -21,14 +21,14 @@ export { ## ## reqid: a request identifier string, echoed in the response event. ## - ## config: a :zeek:see:`ClusterController::Types::Configuration` record + ## config: a :zeek:see:`Management::Configuration` record ## describing the cluster topology. Note that this contains the full ## topology, not just the part pertaining to this agent. That's because ## the cluster framework requires full cluster visibility to establish ## the needed peerings. ## global set_configuration_request: event(reqid: string, - config: ClusterController::Types::Configuration); + config: Management::Configuration); ## Response to a set_configuration_request event. The agent sends ## this back to the controller. @@ -38,11 +38,11 @@ export { ## result: the result record. ## global set_configuration_response: event(reqid: string, - result: ClusterController::Types::Result); + result: Management::Result); ## The controller sends this event to request a list of - ## :zeek:see:`ClusterController::Types::NodeStatus` records that capture + ## :zeek:see:`Management::NodeStatus` records that capture ## the status of Supervisor-managed nodes running on this instance. ## instances. ## @@ -55,13 +55,13 @@ export { ## ## reqid: the request identifier used in the request event. ## - ## result: a :zeek:see:`ClusterController::Types::Result` record. Its data - ## member is a vector of :zeek:see:`ClusterController::Types::NodeStatus` + ## result: a :zeek:see:`Management::Result` record. Its data + ## member is a vector of :zeek:see:`Management::NodeStatus` ## records, covering the nodes at this instance. The result may also ## indicate failure, with error messages indicating what went wrong. ## global get_nodes_response: event(reqid: string, - result: ClusterController::Types::Result); + result: Management::Result); ## The controller sends this event to confirm to the agent that it is ## part of the current cluster topology. The agent acknowledges with the @@ -79,7 +79,7 @@ export { ## result: the result record. ## global agent_welcome_response: event(reqid: string, - result: ClusterController::Types::Result); + result: Management::Result); ## The controller sends this event to convey that the agent is not @@ -102,7 +102,7 @@ export { ## result: the result record. ## global agent_standby_response: event(reqid: string, - result: ClusterController::Types::Result); + result: Management::Result); # Notification events, agent -> controller @@ -112,7 +112,7 @@ export { ## communicate with. It is a controller-level equivalent of ## `:zeek:see:`Broker::peer_added`. ## - ## instance: an instance name, really the agent's name as per :zeek:see:`ClusterAgent::name`. + ## instance: an instance name, really the agent's name as per :zeek:see:`Management::Agent::name`. ## ## host: the IP address of the agent. (This may change in the future.) ## @@ -126,9 +126,9 @@ export { # Report node state changes. global notify_change: event(instance: string, - n: ClusterController::Types::Node, - old: ClusterController::Types::State, - new: ClusterController::Types::State); + n: Management::Node, + old: Management::State, + new: Management::State); # Report operational error. global notify_error: event(instance: string, msg: string, node: string &default=""); diff --git a/scripts/policy/frameworks/cluster/agent/boot.zeek b/scripts/policy/frameworks/management/agent/boot.zeek similarity index 63% rename from scripts/policy/frameworks/cluster/agent/boot.zeek rename to scripts/policy/frameworks/management/agent/boot.zeek index daff5b2d24..7b8bedd088 100644 --- a/scripts/policy/frameworks/cluster/agent/boot.zeek +++ b/scripts/policy/frameworks/management/agent/boot.zeek @@ -1,5 +1,5 @@ ##! The cluster agent boot logic runs in Zeek's supervisor and instructs it to -##! launch an agent process. The agent's main logic resides in main.zeek, +##! launch a Management agent process. The agent's main logic resides in main.zeek, ##! similarly to other frameworks. The new process will execute that script. ##! ##! If the current process is not the Zeek supervisor, this does nothing. @@ -17,16 +17,16 @@ event zeek_init() if ( ! Supervisor::is_supervisor() ) return; - local epi = ClusterAgent::endpoint_info(); + local epi = Management::Agent::endpoint_info(); local sn = Supervisor::NodeConfig($name=epi$id, $bare_mode=T, - $scripts=vector("policy/frameworks/cluster/agent/main.zeek")); + $scripts=vector("policy/frameworks/management/agent/main.zeek")); - if ( ClusterAgent::directory != "" ) - sn$directory = ClusterAgent::directory; - if ( ClusterAgent::stdout_file_suffix != "" ) - sn$stdout_file = epi$id + "." + ClusterAgent::stdout_file_suffix; - if ( ClusterAgent::stderr_file_suffix != "" ) - sn$stderr_file = epi$id + "." + ClusterAgent::stderr_file_suffix; + if ( Management::Agent::directory != "" ) + sn$directory = Management::Agent::directory; + if ( Management::Agent::stdout_file_suffix != "" ) + sn$stdout_file = epi$id + "." + Management::Agent::stdout_file_suffix; + if ( Management::Agent::stderr_file_suffix != "" ) + sn$stderr_file = epi$id + "." + Management::Agent::stderr_file_suffix; # This helps Zeek run controller and agent with a minimal set of scripts. sn$env["ZEEK_CLUSTER_MGMT_NODE"] = "AGENT"; diff --git a/scripts/policy/frameworks/cluster/agent/config.zeek b/scripts/policy/frameworks/management/agent/config.zeek similarity index 56% rename from scripts/policy/frameworks/cluster/agent/config.zeek rename to scripts/policy/frameworks/management/agent/config.zeek index 732dc39450..29567b8f5e 100644 --- a/scripts/policy/frameworks/cluster/agent/config.zeek +++ b/scripts/policy/frameworks/management/agent/config.zeek @@ -1,8 +1,9 @@ ##! Configuration settings for a cluster agent. -@load policy/frameworks/cluster/controller/types +@load policy/frameworks/management/config +@load policy/frameworks/management/types -module ClusterAgent; +module Management::Agent; export { ## The name this agent uses to represent the cluster instance it @@ -14,55 +15,49 @@ export { ## Agent stdout log configuration. If the string is non-empty, Zeek will ## produce a free-form log (i.e., not one governed by Zeek's logging ## framework) in Zeek's working directory. The final log's name is - ## ".", where the name is taken from :zeek:see:`ClusterAgent::name`, + ## ".", where the name is taken from :zeek:see:`Management::Agent::name`, ## and the suffix is defined by the following variable. If left empty, ## no such log results. ## ## Note that the agent also establishes a "proper" Zeek log via the - ## :zeek:see:`ClusterController::Log` module. + ## :zeek:see:`Management::Log` module. const stdout_file_suffix = "agent.stdout" &redef; - ## Agent stderr log configuration. Like :zeek:see:`ClusterAgent::stdout_file_suffix`, + ## Agent stderr log configuration. Like :zeek:see:`Management::Agent::stdout_file_suffix`, ## but for the stderr stream. const stderr_file_suffix = "agent.stderr" &redef; ## The network address the agent listens on. This only takes effect if ## the agent isn't configured to connect to the controller (see - ## :zeek:see:`ClusterAgent::controller`). By default this uses the value of the + ## :zeek:see:`Management::Agent::controller`). By default this uses the value of the ## ZEEK_AGENT_ADDR environment variable, but you may also redef to ## a specific value. When empty, the implementation falls back to - ## :zeek:see:`ClusterAgent::default_address`. + ## :zeek:see:`Management::default_address`. const listen_address = getenv("ZEEK_AGENT_ADDR") &redef; - ## The fallback listen address if :zeek:see:`ClusterAgent::listen_address` - ## remains empty. Unless redefined, this uses Broker's own default listen - ## address. - const default_address = Broker::default_listen_address &redef; - ## The network port the agent listens on. Counterpart to - ## :zeek:see:`ClusterAgent::listen_address`, defaulting to the ZEEK_AGENT_PORT + ## :zeek:see:`Management::Agent::listen_address`, defaulting to the ZEEK_AGENT_PORT ## environment variable. const listen_port = getenv("ZEEK_AGENT_PORT") &redef; - ## The fallback listen port if :zeek:see:`ClusterAgent::listen_port` remains empty. + ## The fallback listen port if :zeek:see:`Management::Agent::listen_port` remains empty. const default_port = 2151/tcp &redef; ## The agent's Broker topic prefix. For its own communication, the agent - ## suffixes this with "/", based on :zeek:see:`ClusterAgent::name`. - const topic_prefix = "zeek/cluster-control/agent" &redef; + ## suffixes this with "/", based on :zeek:see:`Management::Agent::name`. + const topic_prefix = "zeek/management/agent" &redef; ## The network coordinates of the controller. When defined, the agent ## peers with (and connects to) the controller; otherwise the controller ## will peer (and connect to) the agent, listening as defined by - ## :zeek:see:`ClusterAgent::listen_address` and :zeek:see:`ClusterAgent::listen_port`. + ## :zeek:see:`Management::Agent::listen_address` and :zeek:see:`Management::Agent::listen_port`. const controller: Broker::NetworkInfo = [ $address="0.0.0.0", $bound_port=0/unknown] &redef; - ## An optional custom output directory for the agent's stdout and stderr - ## logs. Agent and controller currently only log locally, not via the - ## data cluster's logger node. (This might change in the future.) This - ## means that if both write to the same log file, the output gets - ## garbled. + ## An optional custom output directory for stdout/stderr. Agent and + ## controller currently only log locally, not via the data cluster's + ## logger node. This means that if both write to the same log file, + ## output gets garbled. const directory = "" &redef; ## The working directory for data cluster nodes created by this @@ -71,20 +66,20 @@ export { ## cluster nodes. const cluster_directory = "" &redef; - ## Returns a :zeek:see:`ClusterController::Types::Instance` describing this + ## Returns a :zeek:see:`Management::Instance` describing this ## instance (its agent name plus listening address/port, as applicable). - global instance: function(): ClusterController::Types::Instance; + global instance: function(): Management::Instance; ## Returns a :zeek:see:`Broker::EndpointInfo` record for this instance. - ## Similar to :zeek:see:`ClusterAgent::instance`, but with slightly different + ## Similar to :zeek:see:`Management::Agent::instance`, but with slightly different ## data format. global endpoint_info: function(): Broker::EndpointInfo; } -function instance(): ClusterController::Types::Instance +function instance(): Management::Instance { local epi = endpoint_info(); - return ClusterController::Types::Instance($name=epi$id, + return Management::Instance($name=epi$id, $host=to_addr(epi$network$address), $listen_port=epi$network$bound_port); } @@ -94,22 +89,22 @@ function endpoint_info(): Broker::EndpointInfo local epi: Broker::EndpointInfo; local network: Broker::NetworkInfo; - if ( ClusterAgent::name != "" ) - epi$id = ClusterAgent::name; + if ( Management::Agent::name != "" ) + epi$id = Management::Agent::name; else epi$id = fmt("agent-%s", gethostname()); - if ( ClusterAgent::listen_address != "" ) - network$address = ClusterAgent::listen_address; - else if ( ClusterAgent::default_address != "" ) - network$address = ClusterAgent::default_address; + if ( Management::Agent::listen_address != "" ) + network$address = Management::Agent::listen_address; + else if ( Management::default_address != "" ) + network$address = Management::default_address; else network$address = "127.0.0.1"; - if ( ClusterAgent::listen_port != "" ) - network$bound_port = to_port(ClusterAgent::listen_port); + if ( Management::Agent::listen_port != "" ) + network$bound_port = to_port(Management::Agent::listen_port); else - network$bound_port = ClusterAgent::default_port; + network$bound_port = Management::Agent::default_port; epi$network = network; diff --git a/scripts/policy/frameworks/cluster/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek similarity index 58% rename from scripts/policy/frameworks/cluster/agent/main.zeek rename to scripts/policy/frameworks/management/agent/main.zeek index 7abd263d56..75d0247a36 100644 --- a/scripts/policy/frameworks/cluster/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -4,14 +4,12 @@ ##! supervisor. @load base/frameworks/broker - -@load policy/frameworks/cluster/controller/config -@load policy/frameworks/cluster/controller/log -@load policy/frameworks/cluster/controller/request +@load policy/frameworks/management @load ./api +@load ./config -module ClusterAgent::Runtime; +module Mangement::Agent::Runtime; # This export is mainly to appease Zeekygen's need to understand redefs of the # Request record below. Without it, it fails to establish link targets for the @@ -23,20 +21,21 @@ export { }; } -redef record ClusterController::Request::Request += { +redef record Management::Request::Request += { supervisor_state: SupervisorState &optional; }; -redef ClusterController::role = ClusterController::Types::AGENT; +# Tag our logs correctly +redef Management::Log::role = Management::AGENT; # The global configuration as passed to us by the controller -global g_config: ClusterController::Types::Configuration; +global g_config: Management::Configuration; # A map to make other instance info accessible -global g_instances: table[string] of ClusterController::Types::Instance; +global g_instances: table[string] of Management::Instance; # A map for the nodes we run on this instance, via this agent. -global g_nodes: table[string] of ClusterController::Types::Node; +global g_nodes: table[string] of Management::Node; # The node map employed by the supervisor to describe the cluster # topology to newly forked nodes. We refresh it when we receive @@ -46,8 +45,8 @@ global g_data_cluster: table[string] of Supervisor::ClusterEndpoint; event SupervisorControl::create_response(reqid: string, result: string) { - local req = ClusterController::Request::lookup(reqid); - if ( ClusterController::Request::is_null(req) ) + local req = Management::Request::lookup(reqid); + if ( Management::Request::is_null(req) ) return; local name = req$supervisor_state$node; @@ -55,17 +54,17 @@ event SupervisorControl::create_response(reqid: string, result: string) if ( |result| > 0 ) { local msg = fmt("failed to create node %s: %s", name, result); - ClusterController::Log::error(msg); - event ClusterAgent::API::notify_error(ClusterAgent::name, msg, name); + Management::Log::error(msg); + event Management::Agent::API::notify_error(Management::Agent::name, msg, name); } - ClusterController::Request::finish(reqid); + Management::Request::finish(reqid); } event SupervisorControl::destroy_response(reqid: string, result: bool) { - local req = ClusterController::Request::lookup(reqid); - if ( ClusterController::Request::is_null(req) ) + local req = Management::Request::lookup(reqid); + if ( Management::Request::is_null(req) ) return; local name = req$supervisor_state$node; @@ -73,35 +72,35 @@ event SupervisorControl::destroy_response(reqid: string, result: bool) if ( ! result ) { local msg = fmt("failed to destroy node %s, %s", name, reqid); - ClusterController::Log::error(msg); - event ClusterAgent::API::notify_error(ClusterAgent::name, msg, name); + Management::Log::error(msg); + event Management::Agent::API::notify_error(Management::Agent::name, msg, name); } - ClusterController::Request::finish(reqid); + Management::Request::finish(reqid); } function supervisor_create(nc: Supervisor::NodeConfig) { - local req = ClusterController::Request::create(); + local req = Management::Request::create(); req$supervisor_state = SupervisorState($node = nc$name); event SupervisorControl::create_request(req$id, nc); - ClusterController::Log::info(fmt("issued supervisor create for %s, %s", nc$name, req$id)); + Management::Log::info(fmt("issued supervisor create for %s, %s", nc$name, req$id)); } function supervisor_destroy(node: string) { - local req = ClusterController::Request::create(); + local req = Management::Request::create(); req$supervisor_state = SupervisorState($node = node); event SupervisorControl::destroy_request(req$id, node); - ClusterController::Log::info(fmt("issued supervisor destroy for %s, %s", node, req$id)); + Management::Log::info(fmt("issued supervisor destroy for %s, %s", node, req$id)); } -event ClusterAgent::API::set_configuration_request(reqid: string, config: ClusterController::Types::Configuration) +event Management::Agent::API::set_configuration_request(reqid: string, config: Management::Configuration) { - ClusterController::Log::info(fmt("rx ClusterAgent::API::set_configuration_request %s", reqid)); + Management::Log::info(fmt("rx Management::Agent::API::set_configuration_request %s", reqid)); local nodename: string; - local node: ClusterController::Types::Node; + local node: Management::Node; local nc: Supervisor::NodeConfig; local msg: string; @@ -126,7 +125,7 @@ event ClusterAgent::API::set_configuration_request(reqid: string, config: Cluste g_data_cluster = table(); for ( node in config$nodes ) { - if ( node$instance == ClusterAgent::name ) + if ( node$instance == Management::Agent::name ) g_nodes[node$name] = node; # The cluster and supervisor frameworks require a port for every @@ -155,8 +154,8 @@ event ClusterAgent::API::set_configuration_request(reqid: string, config: Cluste node = g_nodes[nodename]; nc = Supervisor::NodeConfig($name=nodename); - if ( ClusterAgent::cluster_directory != "" ) - nc$directory = ClusterAgent::cluster_directory; + if ( Management::Agent::cluster_directory != "" ) + nc$directory = Management::Agent::cluster_directory; if ( node?$interface ) nc$interface = node$interface; @@ -181,34 +180,34 @@ event ClusterAgent::API::set_configuration_request(reqid: string, config: Cluste if ( reqid != "" ) { - local res = ClusterController::Types::Result( + local res = Management::Result( $reqid = reqid, - $instance = ClusterAgent::name); + $instance = Management::Agent::name); - ClusterController::Log::info(fmt("tx ClusterAgent::API::set_configuration_response %s", - ClusterController::Types::result_to_string(res))); - event ClusterAgent::API::set_configuration_response(reqid, res); + Management::Log::info(fmt("tx Management::Agent::API::set_configuration_response %s", + Management::result_to_string(res))); + event Management::Agent::API::set_configuration_response(reqid, res); } } event SupervisorControl::status_response(reqid: string, result: Supervisor::Status) { - local req = ClusterController::Request::lookup(reqid); - if ( ClusterController::Request::is_null(req) ) + local req = Management::Request::lookup(reqid); + if ( Management::Request::is_null(req) ) return; - ClusterController::Request::finish(reqid); + Management::Request::finish(reqid); - local res = ClusterController::Types::Result( - $reqid = req$parent_id, $instance = ClusterAgent::name); + local res = Management::Result( + $reqid = req$parent_id, $instance = Management::Agent::name); - local node_statuses: ClusterController::Types::NodeStatusVec; + local node_statuses: Management::NodeStatusVec; for ( node in result$nodes ) { local sns = result$nodes[node]; # Supervisor node status - local cns = ClusterController::Types::NodeStatus( - $node=node, $state=ClusterController::Types::PENDING); + local cns = Management::NodeStatus( + $node=node, $state=Management::PENDING); # Identify the role of the node. For data cluster roles (worker, # manager, etc) we derive this from the cluster node table. For @@ -232,20 +231,20 @@ event SupervisorControl::status_response(reqid: string, result: Supervisor::Stat local role = sns$node$env["ZEEK_CLUSTER_MGMT_NODE"]; if ( role == "CONTROLLER" ) { - cns$mgmt_role = ClusterController::Types::CONTROLLER; + cns$mgmt_role = Management::CONTROLLER; # The controller always listens, so the Zeek client can connect. - cns$p = ClusterController::endpoint_info()$network$bound_port; + cns$p = Management::Agent::endpoint_info()$network$bound_port; } else if ( role == "AGENT" ) { - cns$mgmt_role = ClusterController::Types::AGENT; + cns$mgmt_role = Management::AGENT; # If we have a controller address, the agent connects to it # and does not listen. See zeek_init() below for similar logic. - if ( ClusterAgent::controller$address == "0.0.0.0" ) - cns$p = ClusterAgent::endpoint_info()$network$bound_port; + if ( Management::Agent::controller$address == "0.0.0.0" ) + cns$p = Management::Agent::endpoint_info()$network$bound_port; } else - ClusterController::Log::warning(fmt( + Management::Log::warning(fmt( "unexpected cluster management node type '%'", role)); } } @@ -255,7 +254,7 @@ event SupervisorControl::status_response(reqid: string, result: Supervisor::Stat if ( sns?$pid ) { cns$pid = sns$pid; - cns$state = ClusterController::Types::RUNNING; + cns$state = Management::RUNNING; } node_statuses += cns; @@ -263,53 +262,53 @@ event SupervisorControl::status_response(reqid: string, result: Supervisor::Stat res$data = node_statuses; - ClusterController::Log::info(fmt("tx ClusterAgent::API::get_nodes_response %s", - ClusterController::Types::result_to_string(res))); - event ClusterAgent::API::get_nodes_response(req$parent_id, res); + Management::Log::info(fmt("tx Management::Agent::API::get_nodes_response %s", + Management::result_to_string(res))); + event Management::Agent::API::get_nodes_response(req$parent_id, res); } -event ClusterAgent::API::get_nodes_request(reqid: string) +event Management::Agent::API::get_nodes_request(reqid: string) { - ClusterController::Log::info(fmt("rx ClusterAgent::API::get_nodes_request %s", reqid)); + Management::Log::info(fmt("rx Management::Agent::API::get_nodes_request %s", reqid)); - local req = ClusterController::Request::create(); + local req = Management::Request::create(); req$parent_id = reqid; event SupervisorControl::status_request(req$id, ""); - ClusterController::Log::info(fmt("issued supervisor status, %s", req$id)); + Management::Log::info(fmt("issued supervisor status, %s", req$id)); } -event ClusterAgent::API::agent_welcome_request(reqid: string) +event Management::Agent::API::agent_welcome_request(reqid: string) { - ClusterController::Log::info(fmt("rx ClusterAgent::API::agent_welcome_request %s", reqid)); + Management::Log::info(fmt("rx Management::Agent::API::agent_welcome_request %s", reqid)); - local res = ClusterController::Types::Result( + local res = Management::Result( $reqid = reqid, - $instance = ClusterAgent::name); + $instance = Management::Agent::name); - ClusterController::Log::info(fmt("tx ClusterAgent::API::agent_welcome_response %s", - ClusterController::Types::result_to_string(res))); - event ClusterAgent::API::agent_welcome_response(reqid, res); + Management::Log::info(fmt("tx Management::Agent::API::agent_welcome_response %s", + Management::result_to_string(res))); + event Management::Agent::API::agent_welcome_response(reqid, res); } -event ClusterAgent::API::agent_standby_request(reqid: string) +event Management::Agent::API::agent_standby_request(reqid: string) { - ClusterController::Log::info(fmt("rx ClusterAgent::API::agent_standby_request %s", reqid)); + Management::Log::info(fmt("rx Management::Agent::API::agent_standby_request %s", reqid)); # We shut down any existing cluster nodes via an empty configuration, # and fall silent. We do not unpeer/disconnect (assuming we earlier # peered/connected -- otherwise there's nothing we can do here via # Broker anyway), mainly to keep open the possibility of running # cluster nodes again later. - event ClusterAgent::API::set_configuration_request("", ClusterController::Types::Configuration()); + event Management::Agent::API::set_configuration_request("", Management::Configuration()); - local res = ClusterController::Types::Result( + local res = Management::Result( $reqid = reqid, - $instance = ClusterAgent::name); + $instance = Management::Agent::name); - ClusterController::Log::info(fmt("tx ClusterAgent::API::agent_standby_response %s", - ClusterController::Types::result_to_string(res))); - event ClusterAgent::API::agent_standby_response(reqid, res); + Management::Log::info(fmt("tx Management::Agent::API::agent_standby_response %s", + Management::result_to_string(res))); + event Management::Agent::API::agent_standby_response(reqid, res); } event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) @@ -318,10 +317,10 @@ event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) # is in fact a controller, so we might send this in vain. # Controllers register the agent upon receipt of the event. - local epi = ClusterAgent::endpoint_info(); + local epi = Management::Agent::endpoint_info(); - event ClusterAgent::API::notify_agent_hello(epi$id, - to_addr(epi$network$address), ClusterAgent::API::version); + event Management::Agent::API::notify_agent_hello(epi$id, + to_addr(epi$network$address), Management::Agent::API::version); } # XXX We may want a request timeout event handler here. It's arguably cleaner to @@ -330,8 +329,8 @@ event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) event zeek_init() { - local epi = ClusterAgent::endpoint_info(); - local agent_topic = ClusterAgent::topic_prefix + "/" + epi$id; + local epi = Management::Agent::endpoint_info(); + local agent_topic = Management::Agent::topic_prefix + "/" + epi$id; # The agent needs to peer with the supervisor -- this doesn't currently # happen automatically. The address defaults to Broker's default, which @@ -350,15 +349,15 @@ event zeek_init() # Auto-publish a bunch of events. Glob patterns or module-level # auto-publish would be helpful here. - Broker::auto_publish(agent_topic, ClusterAgent::API::get_nodes_response); - Broker::auto_publish(agent_topic, ClusterAgent::API::set_configuration_response); - Broker::auto_publish(agent_topic, ClusterAgent::API::agent_welcome_response); - Broker::auto_publish(agent_topic, ClusterAgent::API::agent_standby_response); + Broker::auto_publish(agent_topic, Management::Agent::API::get_nodes_response); + Broker::auto_publish(agent_topic, Management::Agent::API::set_configuration_response); + Broker::auto_publish(agent_topic, Management::Agent::API::agent_welcome_response); + Broker::auto_publish(agent_topic, Management::Agent::API::agent_standby_response); - Broker::auto_publish(agent_topic, ClusterAgent::API::notify_agent_hello); - Broker::auto_publish(agent_topic, ClusterAgent::API::notify_change); - Broker::auto_publish(agent_topic, ClusterAgent::API::notify_error); - Broker::auto_publish(agent_topic, ClusterAgent::API::notify_log); + Broker::auto_publish(agent_topic, Management::Agent::API::notify_agent_hello); + Broker::auto_publish(agent_topic, Management::Agent::API::notify_change); + Broker::auto_publish(agent_topic, Management::Agent::API::notify_error); + Broker::auto_publish(agent_topic, Management::Agent::API::notify_log); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::create_request); Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::status_request); @@ -367,12 +366,12 @@ event zeek_init() Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::stop_request); # Establish connectivity with the controller. - if ( ClusterAgent::controller$address != "0.0.0.0" ) + if ( Management::Agent::controller$address != "0.0.0.0" ) { # We connect to the controller. - Broker::peer(ClusterAgent::controller$address, - ClusterAgent::controller$bound_port, - ClusterController::connect_retry); + Broker::peer(Management::Agent::controller$address, + Management::Agent::controller$bound_port, + Management::connect_retry); } else { @@ -380,5 +379,5 @@ event zeek_init() Broker::listen(cat(epi$network$address), epi$network$bound_port); } - ClusterController::Log::info("agent is live"); + Management::Log::info("agent is live"); } diff --git a/scripts/policy/frameworks/management/config.zeek b/scripts/policy/frameworks/management/config.zeek new file mode 100644 index 0000000000..7b87655ae5 --- /dev/null +++ b/scripts/policy/frameworks/management/config.zeek @@ -0,0 +1,20 @@ +##! Management framework configuration settings common to agent and controller. +##! This does not include config settings that exist in both agent and +##! controller but that they set differently, since setting defaults here would +##! be awkward or pointless (since both node types would overwrite them +##! anyway). For role-specific settings, see management/controller/config.zeek +##! and management/agent/config.zeek. + +module Management; + +export { + ## The fallback listen address if more specific adddresses, such as + ## the controller's :zeek:see:`Management::Controller::listen_address` + ## remains empty. Unless redefined, this uses Broker's own default + ## listen address. + const default_address = Broker::default_listen_address &redef; + + ## The retry interval for Broker connnects. Defaults to a more + ## aggressive value compared to Broker's 30s. + const connect_retry = 1sec &redef; +} diff --git a/scripts/policy/frameworks/management/controller/__load__.zeek b/scripts/policy/frameworks/management/controller/__load__.zeek new file mode 100644 index 0000000000..47af9762c5 --- /dev/null +++ b/scripts/policy/frameworks/management/controller/__load__.zeek @@ -0,0 +1,4 @@ +##! The entry point for the Management framework's cluster controller. It runs +##! bootstrap logic for launching the controller process via Zeek's Supervisor. + +@load ./boot diff --git a/scripts/policy/frameworks/cluster/controller/api.zeek b/scripts/policy/frameworks/management/controller/api.zeek similarity index 83% rename from scripts/policy/frameworks/cluster/controller/api.zeek rename to scripts/policy/frameworks/management/controller/api.zeek index ce0ebe31c5..575f90009a 100644 --- a/scripts/policy/frameworks/cluster/controller/api.zeek +++ b/scripts/policy/frameworks/management/controller/api.zeek @@ -3,9 +3,9 @@ ##! corresponding response event. Such event pairs share the same name prefix ##! and end in "_request" and "_response", respectively. -@load ./types +@load policy/frameworks/management/types -module ClusterController::API; +module Management::Controller::API; export { ## A simple versioning scheme, used to track basic compatibility of @@ -26,10 +26,10 @@ export { ## reqid: the request identifier used in the request event. ## ## result: the result record. Its data member is a - ## :zeek:see:`ClusterController::Types::Instance` record. + ## :zeek:see:`Management::Instance` record. ## global get_instances_response: event(reqid: string, - result: ClusterController::Types::Result); + result: Management::Result); ## zeek-client sends this event to establish a new cluster configuration, @@ -39,26 +39,26 @@ export { ## ## reqid: a request identifier string, echoed in the response event. ## - ## config: a :zeek:see:`ClusterController::Types::Configuration` record + ## config: a :zeek:see:`Management::Configuration` record ## specifying the cluster configuration. ## global set_configuration_request: event(reqid: string, - config: ClusterController::Types::Configuration); + config: Management::Configuration); ## Response to a set_configuration_request event. The controller sends ## this back to the client. ## ## reqid: the request identifier used in the request event. ## - ## result: a vector of :zeek:see:`ClusterController::Types::Result` records. + ## result: a vector of :zeek:see:`Management::Result` records. ## Each member captures one agent's response. ## global set_configuration_response: event(reqid: string, - result: ClusterController::Types::ResultVec); + result: Management::ResultVec); ## zeek-client sends this event to request a list of - ## :zeek:see:`ClusterController::Types::NodeStatus` records that capture + ## :zeek:see:`Management::NodeStatus` records that capture ## the status of Supervisor-managed nodes running on the cluster's ## instances. ## @@ -71,13 +71,13 @@ export { ## ## reqid: the request identifier used in the request event. ## - ## result: a :zeek:type`vector` of :zeek:see:`ClusterController::Types::Result` + ## result: a :zeek:type`vector` of :zeek:see:`Management::Result` ## records. Each record covers one cluster instance. Each record's data - ## member is a vector of :zeek:see:`ClusterController::Types::NodeStatus` + ## member is a vector of :zeek:see:`Management::NodeStatus` ## records, covering the nodes at that instance. Results may also indicate ## failure, with error messages indicating what went wrong. global get_nodes_response: event(reqid: string, - result: ClusterController::Types::ResultVec); + result: Management::ResultVec); # Testing events. These don't provide operational value but expose @@ -102,7 +102,7 @@ export { ## reqid: the request identifier used in the request event. ## global test_timeout_response: event(reqid: string, - result: ClusterController::Types::Result); + result: Management::Result); # Notification events, agent -> controller diff --git a/scripts/policy/frameworks/management/controller/boot.zeek b/scripts/policy/frameworks/management/controller/boot.zeek new file mode 100644 index 0000000000..a3c679c257 --- /dev/null +++ b/scripts/policy/frameworks/management/controller/boot.zeek @@ -0,0 +1,36 @@ +##! The cluster controller's boot logic runs in Zeek's supervisor and instructs +##! it to launch the Management controller process. The controller's main logic +##! resides in main.zeek, similarly to other frameworks. The new process will +##! execute that script. +##! +##! If the current process is not the Zeek supervisor, this does nothing. + +@load ./config + +event zeek_init() + { + if ( ! Supervisor::is_supervisor() ) + return; + + local epi = Management::Controller::endpoint_info(); + local sn = Supervisor::NodeConfig($name=epi$id, $bare_mode=T, + $scripts=vector("policy/frameworks/management/controller/main.zeek")); + + if ( Management::Controller::directory != "" ) + sn$directory = Management::Controller::directory; + if ( Management::Controller::stdout_file != "" ) + sn$stdout_file = Management::Controller::stdout_file; + if ( Management::Controller::stderr_file != "" ) + sn$stderr_file = Management::Controller::stderr_file; + + # This helps Zeek run controller and agent with a minimal set of scripts. + sn$env["ZEEK_CLUSTER_MGMT_NODE"] = "CONTROLLER"; + + local res = Supervisor::create(sn); + + if ( res != "" ) + { + print(fmt("error: supervisor could not create controller node: %s", res)); + exit(1); + } + } diff --git a/scripts/policy/frameworks/management/controller/config.zeek b/scripts/policy/frameworks/management/controller/config.zeek new file mode 100644 index 0000000000..c97c11bb6a --- /dev/null +++ b/scripts/policy/frameworks/management/controller/config.zeek @@ -0,0 +1,90 @@ +##! Configuration settings for the cluster controller. + +@load policy/frameworks/management/config +@load policy/frameworks/management/types + +module Management::Controller; + +export { + ## The name of this controller. Defaults to the value of the + ## ZEEK_CONTROLLER_NAME environment variable. When that is unset and the + ## user doesn't redef the value, the implementation defaults to + ## "controller-". + const name = getenv("ZEEK_CONTROLLER_NAME") &redef; + + ## The controller's stdout log name. If the string is non-empty, Zeek will + ## produce a free-form log (i.e., not one governed by Zeek's logging + ## framework) in Zeek's working directory. If left empty, no such log + ## results. + ## + ## Note that the controller also establishes a "proper" Zeek log via the + ## :zeek:see:`Management::Log` module. + const stdout_file = "controller.stdout" &redef; + + ## The controller's stderr log name. Like :zeek:see:`Management::Controller::stdout_file`, + ## but for the stderr stream. + const stderr_file = "controller.stderr" &redef; + + ## The network address the controller listens on. By default this uses + ## the value of the ZEEK_CONTROLLER_ADDR environment variable, but you + ## may also redef to a specific value. When empty, the implementation + ## falls back to :zeek:see:`Management::default_address`. + const listen_address = getenv("ZEEK_CONTROLLER_ADDR") &redef; + + ## The network port the controller listens on. Counterpart to + ## :zeek:see:`Management::Controller::listen_address`, defaulting to the + ## ZEEK_CONTROLLER_PORT environment variable. + const listen_port = getenv("ZEEK_CONTROLLER_PORT") &redef; + + ## The fallback listen port if :zeek:see:`Management::Controller::listen_port` + ## remains empty. + const default_port = 2150/tcp &redef; + + ## The controller's Broker topic. Clients send requests to this topic. + const topic = "zeek/management/controller" &redef; + + ## An optional custom output directory for stdout/stderr. Agent and + ## controller currently only log locally, not via the data cluster's + ## logger node. This means that if both write to the same log file, + ## output gets garbled. + const directory = "" &redef; + + ## Returns a :zeek:see:`Broker::NetworkInfo` record describing the controller. + global network_info: function(): Broker::NetworkInfo; + + ## Returns a :zeek:see:`Broker::EndpointInfo` record describing the controller. + global endpoint_info: function(): Broker::EndpointInfo; +} + +function network_info(): Broker::NetworkInfo + { + local ni: Broker::NetworkInfo; + + if ( Management::Controller::listen_address != "" ) + ni$address = Management::Controller::listen_address; + else if ( Management::default_address != "" ) + ni$address = Management::default_address; + else + ni$address = "127.0.0.1"; + + if ( Management::Controller::listen_port != "" ) + ni$bound_port = to_port(Management::Controller::listen_port); + else + ni$bound_port = Management::Controller::default_port; + + return ni; + } + +function endpoint_info(): Broker::EndpointInfo + { + local epi: Broker::EndpointInfo; + + if ( Management::Controller::name != "" ) + epi$id = Management::Controller::name; + else + epi$id = fmt("controller-%s", gethostname()); + + epi$network = network_info(); + + return epi; + } diff --git a/scripts/policy/frameworks/cluster/controller/main.zeek b/scripts/policy/frameworks/management/controller/main.zeek similarity index 56% rename from scripts/policy/frameworks/cluster/controller/main.zeek rename to scripts/policy/frameworks/management/controller/main.zeek index 4e7d261b2c..5aa5292b04 100644 --- a/scripts/policy/frameworks/cluster/controller/main.zeek +++ b/scripts/policy/frameworks/management/controller/main.zeek @@ -1,37 +1,36 @@ -##! This is the main "runtime" of the cluster controller. Zeek does not load -##! this directly; rather, the controller's bootstrapping module (in ./boot.zeek) -##! specifies it as the script to run in the node newly created via Zeek's -##! supervisor. +##! This is the main "runtime" of the Management framework's controller. Zeek +##! does not load this directly; rather, the controller's bootstrapping module +##! (in ./boot.zeek) specifies it as the script to run in the node newly created +##! by the supervisor. @load base/frameworks/broker -@load policy/frameworks/cluster/agent/config -@load policy/frameworks/cluster/agent/api +@load policy/frameworks/management +@load policy/frameworks/management/agent/config # For the agent topic prefix +@load policy/frameworks/management/agent/api @load ./api -@load ./log -@load ./request -@load ./util +@load ./config -module ClusterController::Runtime; +module Management::Controller::Runtime; # This export is mainly to appease Zeekygen's need to understand redefs of the # Request record below. Without it, it fails to establish link targets for the # tucked-on types. export { ## Request state specific to - ## :zeek:see:`ClusterController::API::set_configuration_request` and - ## :zeek:see:`ClusterController::API::set_configuration_response`. + ## :zeek:see:`Management::Controller::API::set_configuration_request` and + ## :zeek:see:`Management::Controller::API::set_configuration_response`. type SetConfigurationState: record { ## The cluster configuration established with this request - config: ClusterController::Types::Configuration; + config: Management::Configuration; ## Request state for every controller/agent transaction. requests: set[string] &default=set(); }; ## Request state specific to - ## :zeek:see:`ClusterController::API::get_nodes_request` and - ## :zeek:see:`ClusterController::API::get_nodes_response`. + ## :zeek:see:`Management::Controller::API::get_nodes_request` and + ## :zeek:see:`Management::Controller::API::get_nodes_response`. type GetNodesState: record { ## Request state for every controller/agent transaction. requests: set[string] &default=set(); @@ -41,33 +40,34 @@ export { type TestState: record { }; } -redef record ClusterController::Request::Request += { +redef record Management::Request::Request += { set_configuration_state: SetConfigurationState &optional; get_nodes_state: GetNodesState &optional; test_state: TestState &optional; }; -redef ClusterController::role = ClusterController::Types::CONTROLLER; +# Tag our logs correctly +redef Management::Log::role = Management::CONTROLLER; global check_instances_ready: function(); -global add_instance: function(inst: ClusterController::Types::Instance); -global drop_instance: function(inst: ClusterController::Types::Instance); +global add_instance: function(inst: Management::Instance); +global drop_instance: function(inst: Management::Instance); -global null_config: function(): ClusterController::Types::Configuration; -global is_null_config: function(config: ClusterController::Types::Configuration): bool; +global null_config: function(): Management::Configuration; +global is_null_config: function(config: Management::Configuration): bool; # Checks whether the given instance is one that we know with different # communication settings: a a different peering direction, a different listening # port, etc. Used as a predicate to indicate when we need to drop the existing # one from our internal state. global is_instance_connectivity_change: function - (inst: ClusterController::Types::Instance): bool; + (inst: Management::Instance): bool; # The set of agents the controller interacts with to manage to currently # configured cluster. This may be a subset of all the agents known to the # controller, as tracked by the g_instances_known set. They key is the instance # name and should match the $name member of the corresponding instance record. -global g_instances: table[string] of ClusterController::Types::Instance = table(); +global g_instances: table[string] of Management::Instance = table(); # The set of instances that have checked in with the controller. This is a # superset of g_instances, since it covers any agent that has sent us a @@ -87,18 +87,18 @@ global g_config_reqid_pending: string = ""; # The most recent configuration we have successfully deployed. This is also # the one we send whenever the client requests it. -global g_config_current: ClusterController::Types::Configuration; +global g_config_current: Management::Configuration; -function send_config_to_agents(req: ClusterController::Request::Request, - config: ClusterController::Types::Configuration) +function send_config_to_agents(req: Management::Request::Request, + config: Management::Configuration) { for ( name in g_instances ) { if ( name !in g_instances_ready ) next; - local agent_topic = ClusterAgent::topic_prefix + "/" + name; - local areq = ClusterController::Request::create(); + local agent_topic = Management::Agent::topic_prefix + "/" + name; + local areq = Management::Request::create(); areq$parent_id = req$id; # We track the requests sent off to each agent. As the @@ -108,8 +108,8 @@ function send_config_to_agents(req: ClusterController::Request::Request, # We could also broadcast just once on the agent prefix, but # explicit request/response pairs for each agent seems cleaner. - ClusterController::Log::info(fmt("tx ClusterAgent::API::set_configuration_request %s to %s", areq$id, name)); - Broker::publish(agent_topic, ClusterAgent::API::set_configuration_request, areq$id, config); + Management::Log::info(fmt("tx Management::Agent::API::set_configuration_request %s to %s", areq$id, name)); + Broker::publish(agent_topic, Management::Agent::API::set_configuration_request, areq$id, config); } } @@ -123,16 +123,16 @@ function check_instances_ready() add cur_instances[inst]; if ( cur_instances == g_instances_ready ) - event ClusterController::API::notify_agents_ready(cur_instances); + event Management::Controller::API::notify_agents_ready(cur_instances); } -function add_instance(inst: ClusterController::Types::Instance) +function add_instance(inst: Management::Instance) { g_instances[inst$name] = inst; if ( inst?$listen_port ) Broker::peer(cat(inst$host), inst$listen_port, - ClusterController::connect_retry); + Management::connect_retry); if ( inst$name in g_instances_known ) { @@ -141,23 +141,23 @@ function add_instance(inst: ClusterController::Types::Instance) # the set of ready instances and proceed as feasible with config # deployments. - local req = ClusterController::Request::create(); + local req = Management::Request::create(); - ClusterController::Log::info(fmt("tx ClusterAgent::API::agent_welcome_request to %s", inst$name)); - Broker::publish(ClusterAgent::topic_prefix + "/" + inst$name, - ClusterAgent::API::agent_welcome_request, req$id); + Management::Log::info(fmt("tx Management::Agent::API::agent_welcome_request to %s", inst$name)); + Broker::publish(Management::Agent::topic_prefix + "/" + inst$name, + Management::Agent::API::agent_welcome_request, req$id); } } -function drop_instance(inst: ClusterController::Types::Instance) +function drop_instance(inst: Management::Instance) { if ( inst$name !in g_instances ) return; # Send the agent a standby so it shuts down its cluster nodes & state - ClusterController::Log::info(fmt("tx ClusterAgent::API::agent_standby_request to %s", inst$name)); - Broker::publish(ClusterAgent::topic_prefix + "/" + inst$name, - ClusterAgent::API::agent_standby_request, ""); + Management::Log::info(fmt("tx Management::Agent::API::agent_standby_request to %s", inst$name)); + Broker::publish(Management::Agent::topic_prefix + "/" + inst$name, + Management::Agent::API::agent_standby_request, ""); delete g_instances[inst$name]; @@ -167,20 +167,20 @@ function drop_instance(inst: ClusterController::Types::Instance) # The agent remains in g_instances_known, to track that we're able # to communicate with it in case it's required again. - ClusterController::Log::info(fmt("dropped instance %s", inst$name)); + Management::Log::info(fmt("dropped instance %s", inst$name)); } -function null_config(): ClusterController::Types::Configuration +function null_config(): Management::Configuration { - return ClusterController::Types::Configuration($id=""); + return Management::Configuration($id=""); } -function is_null_config(config: ClusterController::Types::Configuration): bool +function is_null_config(config: Management::Configuration): bool { return config$id == ""; } -function is_instance_connectivity_change(inst: ClusterController::Types::Instance): bool +function is_instance_connectivity_change(inst: Management::Instance): bool { # If we're not tracking this instance as part of a cluster config, it's # not a change. (More precisely: we cannot say whether it's changed.) @@ -206,17 +206,18 @@ function is_instance_connectivity_change(inst: ClusterController::Types::Instanc return F; } -event ClusterController::API::notify_agents_ready(instances: set[string]) +event Management::Controller::API::notify_agents_ready(instances: set[string]) { - local insts = ClusterController::Util::set_to_vector(instances); + local insts = Management::Util::set_to_vector(instances); - ClusterController::Log::info(fmt("rx ClusterController::API:notify_agents_ready %s", join_string_vec(insts, ","))); + Management::Log::info(fmt("rx Management::Controller::API:notify_agents_ready %s", + join_string_vec(insts, ","))); - local req = ClusterController::Request::lookup(g_config_reqid_pending); + local req = Management::Request::lookup(g_config_reqid_pending); # If there's no pending request, when it's no longer available, or it # doesn't have config state, don't do anything else. - if ( ClusterController::Request::is_null(req) || ! req?$set_configuration_state ) + if ( Management::Request::is_null(req) || ! req?$set_configuration_state ) return; # All instances requested in the pending configuration update are now @@ -226,15 +227,15 @@ event ClusterController::API::notify_agents_ready(instances: set[string]) send_config_to_agents(req, req$set_configuration_state$config); } -event ClusterAgent::API::notify_agent_hello(instance: string, host: addr, api_version: count) +event Management::Agent::API::notify_agent_hello(instance: string, host: addr, api_version: count) { - ClusterController::Log::info(fmt("rx ClusterAgent::API::notify_agent_hello %s %s", instance, host)); + Management::Log::info(fmt("rx Management::Agent::API::notify_agent_hello %s %s", instance, host)); # When an agent checks in with a mismatching API version, we log the # fact and drop its state, if any. - if ( api_version != ClusterController::API::version ) + if ( api_version != Management::Controller::API::version ) { - ClusterController::Log::warning( + Management::Log::warning( fmt("instance %s/%s has checked in with incompatible API version %s", instance, host, api_version)); @@ -252,75 +253,75 @@ event ClusterAgent::API::notify_agent_hello(instance: string, host: addr, api_ve { # We need this instance for our cluster and have full context for # it from the configuration. Tell agent. - local req = ClusterController::Request::create(); + local req = Management::Request::create(); - ClusterController::Log::info(fmt("tx ClusterAgent::API::agent_welcome_request to %s", instance)); - Broker::publish(ClusterAgent::topic_prefix + "/" + instance, - ClusterAgent::API::agent_welcome_request, req$id); + Management::Log::info(fmt("tx Management::Agent::API::agent_welcome_request to %s", instance)); + Broker::publish(Management::Agent::topic_prefix + "/" + instance, + Management::Agent::API::agent_welcome_request, req$id); } } -event ClusterAgent::API::agent_welcome_response(reqid: string, result: ClusterController::Types::Result) +event Management::Agent::API::agent_welcome_response(reqid: string, result: Management::Result) { - ClusterController::Log::info(fmt("rx ClusterAgent::API::agent_welcome_response %s", reqid)); + Management::Log::info(fmt("rx Management::Agent::API::agent_welcome_response %s", reqid)); - local req = ClusterController::Request::lookup(reqid); + local req = Management::Request::lookup(reqid); - if ( ClusterController::Request::is_null(req) ) + if ( Management::Request::is_null(req) ) return; - ClusterController::Request::finish(req$id); + Management::Request::finish(req$id); # An agent we've been waiting to hear back from is ready for cluster # work. Double-check we still want it, otherwise drop it. if ( ! result$success || result$instance !in g_instances ) { - ClusterController::Log::info(fmt( - "tx ClusterAgent::API::agent_standby_request to %s", result$instance)); - Broker::publish(ClusterAgent::topic_prefix + "/" + result$instance, - ClusterAgent::API::agent_standby_request, ""); + Management::Log::info(fmt( + "tx Management::Agent::API::agent_standby_request to %s", result$instance)); + Broker::publish(Management::Agent::topic_prefix + "/" + result$instance, + Management::Agent::API::agent_standby_request, ""); return; } add g_instances_ready[result$instance]; - ClusterController::Log::info(fmt("instance %s ready", result$instance)); + Management::Log::info(fmt("instance %s ready", result$instance)); check_instances_ready(); } -event ClusterAgent::API::notify_change(instance: string, n: ClusterController::Types::Node, - old: ClusterController::Types::State, - new: ClusterController::Types::State) +event Management::Agent::API::notify_change(instance: string, n: Management::Node, + old: Management::State, + new: Management::State) { # XXX TODO } -event ClusterAgent::API::notify_error(instance: string, msg: string, node: string) +event Management::Agent::API::notify_error(instance: string, msg: string, node: string) { # XXX TODO } -event ClusterAgent::API::notify_log(instance: string, msg: string, node: string) +event Management::Agent::API::notify_log(instance: string, msg: string, node: string) { # XXX TODO } -event ClusterAgent::API::set_configuration_response(reqid: string, result: ClusterController::Types::Result) +event Management::Agent::API::set_configuration_response(reqid: string, result: Management::Result) { - ClusterController::Log::info(fmt("rx ClusterAgent::API::set_configuration_response %s", reqid)); + Management::Log::info(fmt("rx Management::Agent::API::set_configuration_response %s", reqid)); # Retrieve state for the request we just got a response to - local areq = ClusterController::Request::lookup(reqid); - if ( ClusterController::Request::is_null(areq) ) + local areq = Management::Request::lookup(reqid); + if ( Management::Request::is_null(areq) ) return; # Release the request, which is now done. - ClusterController::Request::finish(areq$id); + Management::Request::finish(areq$id); # Find the original request from the client - local req = ClusterController::Request::lookup(areq$parent_id); - if ( ClusterController::Request::is_null(req) ) + local req = Management::Request::lookup(areq$parent_id); + if ( Management::Request::is_null(req) ) return; # Add this result to the overall response @@ -342,33 +343,33 @@ event ClusterAgent::API::set_configuration_response(reqid: string, result: Clust g_config_current = req$set_configuration_state$config; g_config_reqid_pending = ""; - ClusterController::Log::info(fmt("tx ClusterController::API::set_configuration_response %s", - ClusterController::Request::to_string(req))); - event ClusterController::API::set_configuration_response(req$id, req$results); - ClusterController::Request::finish(req$id); + Management::Log::info(fmt("tx Management::Controller::API::set_configuration_response %s", + Management::Request::to_string(req))); + event Management::Controller::API::set_configuration_response(req$id, req$results); + Management::Request::finish(req$id); } -event ClusterController::API::set_configuration_request(reqid: string, config: ClusterController::Types::Configuration) +event Management::Controller::API::set_configuration_request(reqid: string, config: Management::Configuration) { - ClusterController::Log::info(fmt("rx ClusterController::API::set_configuration_request %s", reqid)); + Management::Log::info(fmt("rx Management::Controller::API::set_configuration_request %s", reqid)); - local res: ClusterController::Types::Result; - local req = ClusterController::Request::create(reqid); + local res: Management::Result; + local req = Management::Request::create(reqid); req$set_configuration_state = SetConfigurationState($config = config); # At the moment there can only be one pending request. if ( g_config_reqid_pending != "" ) { - res = ClusterController::Types::Result($reqid=reqid); + res = Management::Result($reqid=reqid); res$success = F; res$error = fmt("request %s still pending", g_config_reqid_pending); req$results += res; - ClusterController::Log::info(fmt("tx ClusterController::API::set_configuration_response %s", - ClusterController::Request::to_string(req))); - event ClusterController::API::set_configuration_response(req$id, req$results); - ClusterController::Request::finish(req$id); + Management::Log::info(fmt("tx Management::Controller::API::set_configuration_response %s", + Management::Request::to_string(req))); + event Management::Controller::API::set_configuration_response(req$id, req$results); + Management::Request::finish(req$id); return; } @@ -408,11 +409,11 @@ event ClusterController::API::set_configuration_request(reqid: string, config: C local insts_to_keep: set[string]; # Alternative representation of insts_to_add, directly providing the instances. - local insts_to_peer: table[string] of ClusterController::Types::Instance; + local insts_to_peer: table[string] of Management::Instance; # Helpful locals. local inst_name: string; - local inst: ClusterController::Types::Instance; + local inst: Management::Instance; for ( inst_name in g_instances ) add insts_current[inst_name]; @@ -459,37 +460,37 @@ event ClusterController::API::set_configuration_request(reqid: string, config: C check_instances_ready(); } -event ClusterController::API::get_instances_request(reqid: string) +event Management::Controller::API::get_instances_request(reqid: string) { - ClusterController::Log::info(fmt("rx ClusterController::API::set_instances_request %s", reqid)); + Management::Log::info(fmt("rx Management::Controller::API::set_instances_request %s", reqid)); - local res = ClusterController::Types::Result($reqid = reqid); - local insts: vector of ClusterController::Types::Instance; + local res = Management::Result($reqid = reqid); + local insts: vector of Management::Instance; for ( i in g_instances ) insts += g_instances[i]; res$data = insts; - ClusterController::Log::info(fmt("tx ClusterController::API::get_instances_response %s", reqid)); - event ClusterController::API::get_instances_response(reqid, res); + Management::Log::info(fmt("tx Management::Controller::API::get_instances_response %s", reqid)); + event Management::Controller::API::get_instances_response(reqid, res); } -event ClusterAgent::API::get_nodes_response(reqid: string, result: ClusterController::Types::Result) +event Management::Agent::API::get_nodes_response(reqid: string, result: Management::Result) { - ClusterController::Log::info(fmt("rx ClusterAgent::API::get_nodes_response %s", reqid)); + Management::Log::info(fmt("rx Management::Agent::API::get_nodes_response %s", reqid)); # Retrieve state for the request we just got a response to - local areq = ClusterController::Request::lookup(reqid); - if ( ClusterController::Request::is_null(areq) ) + local areq = Management::Request::lookup(reqid); + if ( Management::Request::is_null(areq) ) return; # Release the request, which is now done. - ClusterController::Request::finish(areq$id); + Management::Request::finish(areq$id); # Find the original request from the client - local req = ClusterController::Request::lookup(areq$parent_id); - if ( ClusterController::Request::is_null(req) ) + local req = Management::Request::lookup(areq$parent_id); + if ( Management::Request::is_null(req) ) return; # Zeek's ingestion of an any-typed val via Broker yields an opaque @@ -498,7 +499,7 @@ event ClusterAgent::API::get_nodes_response(reqid: string, result: ClusterContro # whether the val is of the actual, intended (any-)type or a Broker # DataVal wrapper, we explicitly cast it back to our intended Zeek # type. This test case demonstrates: broker.remote_event_vector_any - result$data = result$data as ClusterController::Types::NodeStatusVec; + result$data = result$data as Management::NodeStatusVec; # Add this result to the overall response req$results[|req$results|] = result; @@ -514,27 +515,27 @@ event ClusterAgent::API::get_nodes_response(reqid: string, result: ClusterContro if ( |req$get_nodes_state$requests| > 0 ) return; - ClusterController::Log::info(fmt("tx ClusterController::API::get_nodes_response %s", - ClusterController::Request::to_string(req))); - event ClusterController::API::get_nodes_response(req$id, req$results); - ClusterController::Request::finish(req$id); + Management::Log::info(fmt("tx Management::Controller::API::get_nodes_response %s", + Management::Request::to_string(req))); + event Management::Controller::API::get_nodes_response(req$id, req$results); + Management::Request::finish(req$id); } -event ClusterController::API::get_nodes_request(reqid: string) +event Management::Controller::API::get_nodes_request(reqid: string) { - ClusterController::Log::info(fmt("rx ClusterController::API::get_nodes_request %s", reqid)); + Management::Log::info(fmt("rx Management::Controller::API::get_nodes_request %s", reqid)); # Special case: if we have no instances, respond right away. if ( |g_instances| == 0 ) { - ClusterController::Log::info(fmt("tx ClusterController::API::get_nodes_response %s", reqid)); - event ClusterController::API::get_nodes_response(reqid, vector( - ClusterController::Types::Result($reqid=reqid, $success=F, + Management::Log::info(fmt("tx Management::Controller::API::get_nodes_response %s", reqid)); + event Management::Controller::API::get_nodes_response(reqid, vector( + Management::Result($reqid=reqid, $success=F, $error="no instances connected"))); return; } - local req = ClusterController::Request::create(reqid); + local req = Management::Request::create(reqid); req$get_nodes_state = GetNodesState(); for ( name in g_instances ) @@ -542,72 +543,72 @@ event ClusterController::API::get_nodes_request(reqid: string) if ( name !in g_instances_ready ) next; - local agent_topic = ClusterAgent::topic_prefix + "/" + name; - local areq = ClusterController::Request::create(); + local agent_topic = Management::Agent::topic_prefix + "/" + name; + local areq = Management::Request::create(); areq$parent_id = req$id; add req$get_nodes_state$requests[areq$id]; - ClusterController::Log::info(fmt("tx ClusterAgent::API::get_nodes_request %s to %s", areq$id, name)); - Broker::publish(agent_topic, ClusterAgent::API::get_nodes_request, areq$id); + Management::Log::info(fmt("tx Management::Agent::API::get_nodes_request %s to %s", areq$id, name)); + Broker::publish(agent_topic, Management::Agent::API::get_nodes_request, areq$id); } } -event ClusterController::Request::request_expired(req: ClusterController::Request::Request) +event Management::Request::request_expired(req: Management::Request::Request) { # Various handlers for timed-out request state. We use the state members # to identify how to respond. No need to clean up the request itself, # since we're getting here via the request module's expiration # mechanism that handles the cleanup. - local res: ClusterController::Types::Result; + local res: Management::Result; if ( req?$set_configuration_state ) { # This timeout means we no longer have a pending request. g_config_reqid_pending = ""; - res = ClusterController::Types::Result($reqid=req$id); + res = Management::Result($reqid=req$id); res$success = F; res$error = "request timed out"; req$results += res; - ClusterController::Log::info(fmt("tx ClusterController::API::set_configuration_response %s", - ClusterController::Request::to_string(req))); - event ClusterController::API::set_configuration_response(req$id, req$results); + Management::Log::info(fmt("tx Management::Controller::API::set_configuration_response %s", + Management::Request::to_string(req))); + event Management::Controller::API::set_configuration_response(req$id, req$results); } if ( req?$get_nodes_state ) { - res = ClusterController::Types::Result($reqid=req$id); + res = Management::Result($reqid=req$id); res$success = F; res$error = "request timed out"; req$results += res; - ClusterController::Log::info(fmt("tx ClusterController::API::get_nodes_response %s", - ClusterController::Request::to_string(req))); - event ClusterController::API::get_nodes_response(req$id, req$results); + Management::Log::info(fmt("tx Management::Controller::API::get_nodes_response %s", + Management::Request::to_string(req))); + event Management::Controller::API::get_nodes_response(req$id, req$results); } if ( req?$test_state ) { - res = ClusterController::Types::Result($reqid=req$id); + res = Management::Result($reqid=req$id); res$success = F; res$error = "request timed out"; - ClusterController::Log::info(fmt("tx ClusterController::API::test_timeout_response %s", req$id)); - event ClusterController::API::test_timeout_response(req$id, res); + Management::Log::info(fmt("tx Management::Controller::API::test_timeout_response %s", req$id)); + event Management::Controller::API::test_timeout_response(req$id, res); } } -event ClusterController::API::test_timeout_request(reqid: string, with_state: bool) +event Management::Controller::API::test_timeout_request(reqid: string, with_state: bool) { - ClusterController::Log::info(fmt("rx ClusterController::API::test_timeout_request %s %s", reqid, with_state)); + Management::Log::info(fmt("rx Management::Controller::API::test_timeout_request %s %s", reqid, with_state)); if ( with_state ) { # This state times out and triggers a timeout response in the # above request_expired event handler. - local req = ClusterController::Request::create(reqid); + local req = Management::Request::create(reqid); req$test_state = TestState(); } } @@ -625,23 +626,23 @@ event zeek_init() # connectivity to agents: agents are defined and communicated with as # defined via configurations defined by the client. - local cni = ClusterController::network_info(); + local cni = Management::Controller::network_info(); Broker::listen(cat(cni$address), cni$bound_port); - Broker::subscribe(ClusterAgent::topic_prefix); - Broker::subscribe(ClusterController::topic); + Broker::subscribe(Management::Agent::topic_prefix); + Broker::subscribe(Management::Controller::topic); # Events sent to the client: local events: vector of any = [ - ClusterController::API::get_instances_response, - ClusterController::API::set_configuration_response, - ClusterController::API::get_nodes_response, - ClusterController::API::test_timeout_response + Management::Controller::API::get_instances_response, + Management::Controller::API::set_configuration_response, + Management::Controller::API::get_nodes_response, + Management::Controller::API::test_timeout_response ]; for ( i in events ) - Broker::auto_publish(ClusterController::topic, events[i]); + Broker::auto_publish(Management::Controller::topic, events[i]); - ClusterController::Log::info("controller is live"); + Management::Log::info("controller is live"); } diff --git a/scripts/policy/frameworks/cluster/controller/log.zeek b/scripts/policy/frameworks/management/log.zeek similarity index 76% rename from scripts/policy/frameworks/cluster/controller/log.zeek rename to scripts/policy/frameworks/management/log.zeek index a7525dec0c..e69c55b122 100644 --- a/scripts/policy/frameworks/cluster/controller/log.zeek +++ b/scripts/policy/frameworks/management/log.zeek @@ -1,11 +1,11 @@ -##! This module implements straightforward logging abilities for cluster -##! controller and agent. It uses Zeek's logging framework, and works only for -##! nodes managed by the supervisor. In this setting Zeek's logging framework -##! operates locally, i.e., this logging does not involve any logger nodes. +##! This module implements logging abilities for controller and agent. It uses +##! Zeek's logging framework and works only for nodes managed by the +##! supervisor. In this setting Zeek's logging framework operates locally, i.e., +##! this does not involve logger nodes. -@load ./config +@load ./types -module ClusterController::Log; +module Management::Log; export { ## The cluster logging stream identifier. @@ -25,12 +25,12 @@ export { ## The record type containing the column fields of the agent/controller log. type Info: record { ## The time at which a cluster message was generated. - ts: time; + ts: time; ## The name of the node that is creating the log record. node: string; ## Log level of this message, converted from the above Level enum level: string; - ## The role of the node, translated from ClusterController::Types::Role. + ## The role of the node, translated from Management::Role. role: string; ## A message indicating information about cluster controller operation. message: string; @@ -63,6 +63,10 @@ export { ## message: the message to log. ## global error: function(message: string); + + ## The role of this process in cluster management. Agent and controller + ## both redefine this, and we use it during logging. + const role = Management::NONE &redef; } # Enum translations to strings. This avoids those enums being reported @@ -75,9 +79,9 @@ global l2s: table[Level] of string = { [ERROR] = "ERROR", }; -global r2s: table[ClusterController::Types::Role] of string = { - [ClusterController::Types::AGENT] = "AGENT", - [ClusterController::Types::CONTROLLER] = "CONTROLLER", +global r2s: table[Management::Role] of string = { + [Management::AGENT] = "AGENT", + [Management::CONTROLLER] = "CONTROLLER", }; function debug(message: string) @@ -87,7 +91,7 @@ function debug(message: string) local node = Supervisor::node(); Log::write(LOG, [$ts=network_time(), $node=node$name, $level=l2s[DEBUG], - $role=r2s[ClusterController::role], $message=message]); + $role=r2s[role], $message=message]); } function info(message: string) @@ -97,7 +101,7 @@ function info(message: string) local node = Supervisor::node(); Log::write(LOG, [$ts=network_time(), $node=node$name, $level=l2s[INFO], - $role=r2s[ClusterController::role], $message=message]); + $role=r2s[role], $message=message]); } function warning(message: string) @@ -107,7 +111,7 @@ function warning(message: string) local node = Supervisor::node(); Log::write(LOG, [$ts=network_time(), $node=node$name, $level=l2s[WARNING], - $role=r2s[ClusterController::role], $message=message]); + $role=r2s[role], $message=message]); } function error(message: string) @@ -117,7 +121,7 @@ function error(message: string) local node = Supervisor::node(); Log::write(LOG, [$ts=network_time(), $node=node$name, $level=l2s[ERROR], - $role=r2s[ClusterController::role], $message=message]); + $role=r2s[role], $message=message]); } event zeek_init() @@ -133,5 +137,5 @@ event zeek_init() local stream = Log::Stream($columns=Info, $path=fmt("cluster-%s", node$name), $policy=log_policy); - Log::create_stream(ClusterController::Log::LOG, stream); + Log::create_stream(Management::Log::LOG, stream); } diff --git a/scripts/policy/frameworks/cluster/controller/request.zeek b/scripts/policy/frameworks/management/request.zeek similarity index 72% rename from scripts/policy/frameworks/cluster/controller/request.zeek rename to scripts/policy/frameworks/management/request.zeek index 06f23b67da..82a4de3648 100644 --- a/scripts/policy/frameworks/cluster/controller/request.zeek +++ b/scripts/policy/frameworks/management/request.zeek @@ -1,18 +1,18 @@ -##! This module implements a request state abstraction that both cluster -##! controller and agent use to tie responses to received request events and be -##! able to time-out such requests. +##! This module implements a request state abstraction in the Management +##! framework that both controller and agent use to connect request events to +##! subsequent response ones, and to be able to time out such requests. -@load ./types @load ./config +@load ./types -module ClusterController::Request; +module Management::Request; export { ## Request records track state associated with a request/response event ## pair. Calls to - ## :zeek:see:`ClusterController::Request::create` establish such state + ## :zeek:see:`Management::Request::create` establish such state ## when an entity sends off a request event, while - ## :zeek:see:`ClusterController::Request::finish` clears the state when + ## :zeek:see:`Management::Request::finish` clears the state when ## a corresponding response event comes in, or the state times out. type Request: record { ## Each request has a hopfully unique ID provided by the requester. @@ -26,12 +26,19 @@ export { ## The results vector builds up the list of results we eventually ## send to the requestor when we have processed the request. - results: ClusterController::Types::ResultVec &default=vector(); + results: Management::ResultVec &default=vector(); ## An internal flag to track whether a request is complete. finished: bool &default=F; }; + ## The timeout for request state. Such state (see the :zeek:see:`Management::Request` + ## module) ties together request and response event pairs. The timeout causes + ## its cleanup in the absence of a timely response. It applies both to + ## state kept for client requests, as well as state in the agents for + ## requests to the supervisor. + const timeout_interval = 10sec &redef; + ## A token request that serves as a null/nonexistant request. global null_req = Request($id="", $finished=T); @@ -42,7 +49,7 @@ export { global create: function(reqid: string &default=unique_id("")): Request; ## This function looks up the request for a given request ID and returns - ## it. When no such request exists, returns ClusterController::Request::null_req. + ## it. When no such request exists, returns Management::Request::null_req. ## ## reqid: the ID of the request state to retrieve. ## @@ -57,8 +64,8 @@ export { global finish: function(reqid: string): bool; ## This event fires when a request times out (as per the - ## ClusterController::request_timeout) before it has been finished via - ## ClusterController::Request::finish(). + ## Management::Request::timeout_interval) before it has been finished via + ## Management::Request::finish(). ## ## req: the request state that is expiring. ## @@ -85,18 +92,17 @@ function requests_expire_func(reqs: table[string] of Request, reqid: string): in # No need to flag request expiration when we've already internally marked # the request as done. if ( ! reqs[reqid]$finished ) - event ClusterController::Request::request_expired(reqs[reqid]); + event Management::Request::request_expired(reqs[reqid]); return 0secs; } # This is the global request-tracking table. The table maps from request ID # strings to corresponding Request records. Entries time out after the -# ClusterController::request_timeout interval. Upon expiration, a -# request_expired event triggers that conveys the request state. +# Management::Request::timeout_interval. Upon expiration, a request_expired +# event triggers that conveys the request state. global g_requests: table[string] of Request - &create_expire=ClusterController::request_timeout - &expire_func=requests_expire_func; + &create_expire=timeout_interval &expire_func=requests_expire_func; function create(reqid: string): Request { @@ -137,7 +143,7 @@ function is_null(request: Request): bool function to_string(request: Request): string { local results: string_vec; - local res: ClusterController::Types::Result; + local res: Management::Result; local parent_id = ""; if ( request?$parent_id ) @@ -146,7 +152,7 @@ function to_string(request: Request): string for ( idx in request$results ) { res = request$results[idx]; - results[|results|] = ClusterController::Types::result_to_string(res); + results[|results|] = Management::result_to_string(res); } return fmt("[request %s%s %s, results: %s]", request$id, parent_id, diff --git a/scripts/policy/frameworks/cluster/controller/types.zeek b/scripts/policy/frameworks/management/types.zeek similarity index 93% rename from scripts/policy/frameworks/cluster/controller/types.zeek rename to scripts/policy/frameworks/management/types.zeek index ad7fce9c1e..824ea7dfb4 100644 --- a/scripts/policy/frameworks/cluster/controller/types.zeek +++ b/scripts/policy/frameworks/management/types.zeek @@ -1,8 +1,8 @@ -##! This module holds the basic types needed for the Cluster Controller -##! framework. These are used by both agent and controller, and several -##! have corresponding equals in the zeek-client implementation. +##! This module holds the basic types needed for the Management framework. These +##! are used by both cluster agent and controller, and several have corresponding +##! implementations in zeek-client. -module ClusterController::Types; +module Management; export { ## Management infrastructure node type. This intentionally does not @@ -103,7 +103,7 @@ export { type ResultVec: vector of Result; - ## Given a :zeek:see:`ClusterController::Types::Result` record, + ## Given a :zeek:see:`Management::Result` record, ## this function returns a string summarizing it. global result_to_string: function(res: Result): string; } diff --git a/scripts/policy/frameworks/cluster/controller/util.zeek b/scripts/policy/frameworks/management/util.zeek similarity index 79% rename from scripts/policy/frameworks/cluster/controller/util.zeek rename to scripts/policy/frameworks/management/util.zeek index 0329438f2f..98d79c8f9e 100644 --- a/scripts/policy/frameworks/cluster/controller/util.zeek +++ b/scripts/policy/frameworks/management/util.zeek @@ -1,7 +1,7 @@ -##! Utility functions for the cluster controller framework, available to agent +##! Utility functions for the Management framework, available to agent ##! and controller. -module ClusterController::Util; +module Management::Util; export { ## Renders a set of strings to an alphabetically sorted vector. diff --git a/scripts/test-all-policy.zeek b/scripts/test-all-policy.zeek index bdc052d301..8dd1d8797f 100644 --- a/scripts/test-all-policy.zeek +++ b/scripts/test-all-policy.zeek @@ -11,20 +11,22 @@ # @load frameworks/control/controllee.zeek # @load frameworks/control/controller.zeek -@load frameworks/cluster/agent/__load__.zeek -@load frameworks/cluster/agent/api.zeek -@load frameworks/cluster/agent/boot.zeek -@load frameworks/cluster/agent/config.zeek -# @load frameworks/cluster/agent/main.zeek -@load frameworks/cluster/controller/__load__.zeek -@load frameworks/cluster/controller/api.zeek -@load frameworks/cluster/controller/boot.zeek -@load frameworks/cluster/controller/config.zeek -@load frameworks/cluster/controller/log.zeek -# @load frameworks/cluster/controller/main.zeek -@load frameworks/cluster/controller/request.zeek -@load frameworks/cluster/controller/types.zeek -@load frameworks/cluster/controller/util.zeek +@load frameworks/management/agent/__load__.zeek +@load frameworks/management/agent/api.zeek +@load frameworks/management/agent/boot.zeek +@load frameworks/management/agent/config.zeek +# @load frameworks/management/agent/main.zeek +@load frameworks/management/controller/__load__.zeek +@load frameworks/management/controller/api.zeek +@load frameworks/management/controller/boot.zeek +@load frameworks/management/controller/config.zeek +# @load frameworks/management/controller/main.zeek +@load frameworks/management/__load__.zeek +@load frameworks/management/config.zeek +@load frameworks/management/log.zeek +@load frameworks/management/request.zeek +@load frameworks/management/types.zeek +@load frameworks/management/util.zeek @load frameworks/dpd/detect-protocols.zeek @load frameworks/dpd/packet-segment-logging.zeek @load frameworks/intel/do_notice.zeek diff --git a/scripts/zeekygen/__load__.zeek b/scripts/zeekygen/__load__.zeek index 75a5f7a666..4c7851955a 100644 --- a/scripts/zeekygen/__load__.zeek +++ b/scripts/zeekygen/__load__.zeek @@ -4,8 +4,8 @@ @load protocols/ssl/notary.zeek @load frameworks/control/controllee.zeek @load frameworks/control/controller.zeek -@load frameworks/cluster/agent/main.zeek -@load frameworks/cluster/controller/main.zeek +@load frameworks/management/agent/main.zeek +@load frameworks/management/controller/main.zeek @load frameworks/files/extract-all-files.zeek @load policy/misc/dump-events.zeek @load policy/protocols/conn/speculative-service.zeek diff --git a/testing/btest/Baseline/coverage.bare-mode-errors/errors b/testing/btest/Baseline/coverage.bare-mode-errors/errors index 31f9346536..719aa01af5 100644 --- a/testing/btest/Baseline/coverage.bare-mode-errors/errors +++ b/testing/btest/Baseline/coverage.bare-mode-errors/errors @@ -2,8 +2,8 @@ ### NOTE: This file has been sorted with diff-sort. warning in <...>/extract-certs-pem.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:12 "Remove in v5.1. Use log-certs-base64.zeek instead." warning in <...>/extract-certs-pem.zeek, line 1: deprecated script loaded from command line arguments "Remove in v5.1. Use log-certs-base64.zeek instead." -warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:59 ("Remove in v5.1. OCSP logging is now enabled by default") -warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:59 ("Remove in v5.1. OCSP logging is now enabled by default") +warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:61 ("Remove in v5.1. OCSP logging is now enabled by default") +warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:61 ("Remove in v5.1. OCSP logging is now enabled by default") warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from command line arguments ("Remove in v5.1. OCSP logging is now enabled by default") warning in <...>/notary.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:4 ("Remove in v5.1. Please switch to other more modern approaches like SCT validation (validate-sct.zeek).") warning in <...>/notary.zeek, line 1: deprecated script loaded from command line arguments ("Remove in v5.1. Please switch to other more modern approaches like SCT validation (validate-sct.zeek).") diff --git a/testing/btest/Baseline/scripts.policy.frameworks.cluster.controller.agent-checkin/zeek.controller.stdout b/testing/btest/Baseline/scripts.policy.frameworks.management.controller.agent-checkin/zeek.controller.stdout similarity index 100% rename from testing/btest/Baseline/scripts.policy.frameworks.cluster.controller.agent-checkin/zeek.controller.stdout rename to testing/btest/Baseline/scripts.policy.frameworks.management.controller.agent-checkin/zeek.controller.stdout diff --git a/testing/btest/scripts/policy/frameworks/cluster/controller/agent-checkin.zeek b/testing/btest/scripts/policy/frameworks/management/controller/agent-checkin.zeek similarity index 64% rename from testing/btest/scripts/policy/frameworks/cluster/controller/agent-checkin.zeek rename to testing/btest/scripts/policy/frameworks/management/controller/agent-checkin.zeek index cf1304e3f3..ecdc3b17ed 100644 --- a/testing/btest/scripts/policy/frameworks/cluster/controller/agent-checkin.zeek +++ b/testing/btest/scripts/policy/frameworks/management/controller/agent-checkin.zeek @@ -1,7 +1,7 @@ -# This test verifies basic agent-controller communication. We launch agent and -# controller via the supervisor, add an extra handler for the notify_agent_hello -# event that travels agent -> controller, and verify its print output in the -# controller's stdout log. +# This test verifies basic agent-controller communication in the Management +# framework. We launch agent and controller via the supervisor, add an extra +# handler for the notify_agent_hello event that travels agent -> controller, and +# verify its print output in the controller's stdout log. # The following env vars is known to the controller framework # @TEST-PORT: ZEEK_CONTROLLER_PORT @@ -12,20 +12,20 @@ # @TEST-EXEC: btest-bg-wait 10 # @TEST-EXEC: btest-diff zeek/controller.stdout -@load policy/frameworks/cluster/agent -@load policy/frameworks/cluster/controller +@load policy/frameworks/management/agent +@load policy/frameworks/management/controller redef Broker::default_port = to_port(getenv("BROKER_PORT")); -redef ClusterController::name = "controller"; -redef ClusterAgent::name = "agent"; +redef Management::Controller::name = "controller"; +redef Management::Agent::name = "agent"; # Tell the agent where to locate the controller. -redef ClusterAgent::controller = [$address="127.0.0.1", $bound_port=to_port(getenv("ZEEK_CONTROLLER_PORT"))]; +redef Management::Agent::controller = [$address="127.0.0.1", $bound_port=to_port(getenv("ZEEK_CONTROLLER_PORT"))]; @if ( Supervisor::is_supervised() ) -@load policy/frameworks/cluster/agent/api +@load policy/frameworks/management/agent/api global logged = F; @@ -41,7 +41,7 @@ event zeek_init() } } -event ClusterAgent::API::notify_agent_hello(instance: string, host: addr, api_version: count) +event Management::Agent::API::notify_agent_hello(instance: string, host: addr, api_version: count) { if ( Supervisor::node()$name == "controller" ) { From c77cbc5c58edd9a0e3305c62f8508dc416005e95 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 7 Feb 2022 00:09:27 -0800 Subject: [PATCH 057/204] Bump zeek-client to reflect Management framework reorg --- auxil/zeek-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeek-client b/auxil/zeek-client index 3a3aa08e0d..797700966a 160000 --- a/auxil/zeek-client +++ b/auxil/zeek-client @@ -1 +1 @@ -Subproject commit 3a3aa08e0d68d7f734fb92329798c375978ccb3a +Subproject commit 797700966a0b41d23a15c91181f6c5389fd9841e From 59fa19424df8f68bd5b6c0e30aa4ed8f83c83d9b Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 7 Feb 2022 00:10:34 -0800 Subject: [PATCH 058/204] Bump external cluster testsuite to reflect Management framework reorg --- testing/external/commit-hash.zeek-testing-cluster | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/external/commit-hash.zeek-testing-cluster b/testing/external/commit-hash.zeek-testing-cluster index 460a403c4e..e3b62310ef 100644 --- a/testing/external/commit-hash.zeek-testing-cluster +++ b/testing/external/commit-hash.zeek-testing-cluster @@ -1 +1 @@ -8e0401661fca089e941ab844694f9d2314f1401f +af7ad3971e622e1e5cb2d95c87152481c38d8c44 From 11f8729997ed0273783f4c7722099f11fb025b8c Mon Sep 17 00:00:00 2001 From: Matthew Luckie Date: Sat, 19 Feb 2022 19:17:51 +1300 Subject: [PATCH 059/204] remove deprecated union and timer types, addressing #1898 --- src/Expr.cc | 2 -- src/Type.cc | 42 +++++++++--------------------- src/Type.h | 32 ++++++++++------------- src/ZVal.cc | 6 ----- src/parse.y | 14 +--------- src/scan.l | 2 -- src/script_opt/CPP/RuntimeInits.cc | 1 - src/script_opt/CPP/Types.cc | 3 --- src/script_opt/ProfileFunc.cc | 4 --- 9 files changed, 28 insertions(+), 78 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index daf0f2000d..4885067887 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -4275,8 +4275,6 @@ ScheduleExpr::ScheduleExpr(ExprPtr arg_when, EventExprPtr arg_event) if ( bt != TYPE_TIME && bt != TYPE_INTERVAL ) ExprError("schedule expression requires a time or time interval"); - else - SetType(base_type(TYPE_TIMER)); } bool ScheduleExpr::IsPure() const diff --git a/src/Type.cc b/src/Type.cc index cb459533a6..19f585f0ae 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -42,21 +42,19 @@ const char* type_name(TypeTag t) "string", // 7 "pattern", // 8 "enum", // 9 - "timer", // 10 - "port", // 11 - "addr", // 12 - "subnet", // 13 - "any", // 14 - "table", // 15 - "union", // 16 - "record", // 17 - "types", // 18 - "func", // 19 - "file", // 20 - "vector", // 21 - "opaque", // 22 - "type", // 23 - "error", // 24 + "port", // 10 + "addr", // 11 + "subnet", // 12 + "any", // 13 + "table", // 14 + "record", // 15 + "types", // 16 + "func", // 17 + "file", // 18 + "vector", // 19 + "opaque", // 20 + "type", // 21 + "error", // 22 }; if ( int(t) >= NUM_TYPES ) @@ -208,7 +206,6 @@ TypePtr Type::ShallowClone() case TYPE_INTERVAL: case TYPE_STRING: case TYPE_PATTERN: - case TYPE_TIMER: case TYPE_PORT: case TYPE_ADDR: case TYPE_SUBNET: @@ -1870,7 +1867,6 @@ bool same_type(const Type& arg_t1, const Type& arg_t2, bool is_init, bool match_ case TYPE_INTERVAL: case TYPE_STRING: case TYPE_PATTERN: - case TYPE_TIMER: case TYPE_PORT: case TYPE_ADDR: case TYPE_SUBNET: @@ -1971,9 +1967,6 @@ bool same_type(const Type& arg_t1, const Type& arg_t2, bool is_init, bool match_ case TYPE_FILE: case TYPE_TYPE: break; - - case TYPE_UNION: - reporter->Error("union type in same_type()"); } // If we get to here, then we're dealing with a type with @@ -2190,7 +2183,6 @@ bool is_assignable(TypeTag t) case TYPE_STRING: case TYPE_PATTERN: case TYPE_ENUM: - case TYPE_TIMER: case TYPE_PORT: case TYPE_ADDR: case TYPE_SUBNET: @@ -2210,9 +2202,6 @@ bool is_assignable(TypeTag t) case TYPE_VOID: return false; - - case TYPE_UNION: - reporter->Error("union type in is_assignable()"); } return false; @@ -2269,7 +2258,6 @@ TypePtr merge_types(const TypePtr& arg_t1, const TypePtr& arg_t2) case TYPE_INTERVAL: case TYPE_STRING: case TYPE_PATTERN: - case TYPE_TIMER: case TYPE_PORT: case TYPE_ADDR: case TYPE_SUBNET: @@ -2471,10 +2459,6 @@ TypePtr merge_types(const TypePtr& arg_t1, const TypePtr& arg_t2) return make_intrusive(merge_types(t1->Yield(), t2->Yield())); - case TYPE_UNION: - reporter->InternalError("union type in merge_types()"); - return nullptr; - default: reporter->InternalError("bad type in merge_types()"); return nullptr; diff --git a/src/Type.h b/src/Type.h index f29180fb0b..e13ec6d7fb 100644 --- a/src/Type.h +++ b/src/Type.h @@ -49,21 +49,19 @@ enum TypeTag TYPE_STRING, // 7 TYPE_PATTERN, // 8 TYPE_ENUM, // 9 - TYPE_TIMER, // 10 - TYPE_PORT, // 11 - TYPE_ADDR, // 12 - TYPE_SUBNET, // 13 - TYPE_ANY, // 14 - TYPE_TABLE, // 15 - TYPE_UNION, // 16 - TYPE_RECORD, // 17 - TYPE_LIST, // 18 - TYPE_FUNC, // 19 - TYPE_FILE, // 20 - TYPE_VECTOR, // 21 - TYPE_OPAQUE, // 22 - TYPE_TYPE, // 23 - TYPE_ERROR // 24 + TYPE_PORT, // 10 + TYPE_ADDR, // 11 + TYPE_SUBNET, // 12 + TYPE_ANY, // 13 + TYPE_TABLE, // 14 + TYPE_RECORD, // 15 + TYPE_LIST, // 16 + TYPE_FUNC, // 17 + TYPE_FILE, // 18 + TYPE_VECTOR, // 19 + TYPE_OPAQUE, // 20 + TYPE_TYPE, // 21 + TYPE_ERROR // 22 #define NUM_TYPES (int(TYPE_ERROR) + 1) }; @@ -126,10 +124,8 @@ constexpr InternalTypeTag to_internal_type_tag(TypeTag tag) noexcept return TYPE_INTERNAL_SUBNET; case TYPE_PATTERN: - case TYPE_TIMER: case TYPE_ANY: case TYPE_TABLE: - case TYPE_UNION: case TYPE_RECORD: case TYPE_LIST: case TYPE_FUNC: @@ -951,7 +947,7 @@ inline bool IsInterval(TypeTag t) // True if the given type tag corresponds to a record type. inline bool IsRecord(TypeTag t) { - return (t == TYPE_RECORD || t == TYPE_UNION); + return (t == TYPE_RECORD); } // True if the given type tag corresponds to a function type. diff --git a/src/ZVal.cc b/src/ZVal.cc index d2a1ca684c..4b27d24045 100644 --- a/src/ZVal.cc +++ b/src/ZVal.cc @@ -104,8 +104,6 @@ ZVal::ZVal(ValPtr v, const TypePtr& t) break; case TYPE_ERROR: - case TYPE_TIMER: - case TYPE_UNION: case TYPE_VOID: reporter->InternalError("bad type in ZVal constructor"); } @@ -185,8 +183,6 @@ ZVal::ZVal(const TypePtr& t) break; case TYPE_ERROR: - case TYPE_TIMER: - case TYPE_UNION: case TYPE_VOID: reporter->InternalError("bad type in ZVal constructor"); } @@ -275,8 +271,6 @@ ValPtr ZVal::ToVal(const TypePtr& t) const break; case TYPE_ERROR: - case TYPE_TIMER: - case TYPE_UNION: case TYPE_VOID: default: v = nullptr; diff --git a/src/parse.y b/src/parse.y index b52cf95a93..a7e93446fe 100644 --- a/src/parse.y +++ b/src/parse.y @@ -18,7 +18,7 @@ %token TOK_PORT TOK_PRINT TOK_RECORD TOK_REDEF %token TOK_REMOVE_FROM TOK_RETURN TOK_SCHEDULE TOK_SET %token TOK_STRING TOK_SUBNET TOK_SWITCH TOK_TABLE -%token TOK_TIME TOK_TIMEOUT TOK_TIMER TOK_TYPE TOK_UNION TOK_VECTOR TOK_WHEN +%token TOK_TIME TOK_TIMEOUT TOK_TYPE TOK_VECTOR TOK_WHEN %token TOK_WHILE TOK_AS TOK_IS %token TOK_ATTR_ADD_FUNC TOK_ATTR_DEFAULT TOK_ATTR_OPTIONAL TOK_ATTR_REDEF @@ -1023,11 +1023,6 @@ type: $$ = base_type(TYPE_PATTERN)->Ref(); } - | TOK_TIMER { - set_location(@1); - $$ = base_type(TYPE_TIMER)->Ref(); - } - | TOK_PORT { set_location(@1); $$ = base_type(TYPE_PORT)->Ref(); @@ -1070,13 +1065,6 @@ type: $$ = new RecordType($4); } - | TOK_UNION '{' type_list '}' - { - set_location(@1, @4); - reporter->Error("union type not implemented"); - $$ = 0; - } - | TOK_ENUM '{' { set_location(@1); parse_new_enum(); } enum_body '}' { set_location(@1, @5); diff --git a/src/scan.l b/src/scan.l index 4012d60645..a53c247798 100644 --- a/src/scan.l +++ b/src/scan.l @@ -297,9 +297,7 @@ switch return TOK_SWITCH; table return TOK_TABLE; time return TOK_TIME; timeout return TOK_TIMEOUT; -timer return TOK_TIMER; type return TOK_TYPE; -union return TOK_UNION; vector return TOK_VECTOR; when return TOK_WHEN; diff --git a/src/script_opt/CPP/RuntimeInits.cc b/src/script_opt/CPP/RuntimeInits.cc index 5286540997..ef30da2242 100644 --- a/src/script_opt/CPP/RuntimeInits.cc +++ b/src/script_opt/CPP/RuntimeInits.cc @@ -279,7 +279,6 @@ void CPP_TypeInits::Generate(InitsManager* im, vector& ivec, int offset case TYPE_PORT: case TYPE_STRING: case TYPE_TIME: - case TYPE_TIMER: case TYPE_VOID: case TYPE_SUBNET: case TYPE_FILE: diff --git a/src/script_opt/CPP/Types.cc b/src/script_opt/CPP/Types.cc index 9a482d072e..79d667e988 100644 --- a/src/script_opt/CPP/Types.cc +++ b/src/script_opt/CPP/Types.cc @@ -141,8 +141,6 @@ const char* CPPCompile::TypeTagName(TypeTag tag) return "TYPE_TABLE"; case TYPE_TIME: return "TYPE_TIME"; - case TYPE_TIMER: - return "TYPE_TIMER"; case TYPE_TYPE: return "TYPE_TYPE"; case TYPE_VECTOR: @@ -302,7 +300,6 @@ shared_ptr CPPCompile::RegisterType(const TypePtr& tp) case TYPE_PORT: case TYPE_STRING: case TYPE_TIME: - case TYPE_TIMER: case TYPE_VOID: case TYPE_SUBNET: case TYPE_FILE: diff --git a/src/script_opt/ProfileFunc.cc b/src/script_opt/ProfileFunc.cc index 3315fa1fc4..1b8c31b019 100644 --- a/src/script_opt/ProfileFunc.cc +++ b/src/script_opt/ProfileFunc.cc @@ -576,8 +576,6 @@ void ProfileFuncs::TraverseValue(const ValPtr& v) case TYPE_STRING: case TYPE_SUBNET: case TYPE_TIME: - case TYPE_TIMER: - case TYPE_UNION: case TYPE_VOID: break; @@ -777,8 +775,6 @@ p_hash_type ProfileFuncs::HashType(const Type* t) case TYPE_STRING: case TYPE_SUBNET: case TYPE_TIME: - case TYPE_TIMER: - case TYPE_UNION: case TYPE_VOID: h = merge_p_hashes(h, p_hash(t)); break; From 08bf6f13e293482e585268d130f893888ded9cae Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 22 Feb 2022 15:16:36 -0700 Subject: [PATCH 060/204] GH-1949: Remove unused timer_mgr_inactivity_timeout global --- scripts/base/init-bare.zeek | 3 --- src/NetVar.cc | 4 ---- src/NetVar.h | 2 -- 3 files changed, 9 deletions(-) diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 9e102ed6fc..d8c3ec2114 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -4963,9 +4963,6 @@ const dpd_ignore_ports = F &redef; ## connection if it misses the initial handshake. const likely_server_ports: set[port] &redef; -## Per-incident timer managers are drained after this amount of inactivity. -const timer_mgr_inactivity_timeout = 1 min &redef; - ## If true, output profiling for Time-Machine queries. const time_machine_profiling = F &redef; diff --git a/src/NetVar.cc b/src/NetVar.cc index e9084f3085..3d66da0990 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -189,8 +189,6 @@ int dpd_ignore_ports; int check_for_unused_event_handlers; -double timer_mgr_inactivity_timeout; - int record_all_packets; bro_uint_t bits_per_uid; @@ -345,8 +343,6 @@ void init_net_var() dpd_match_only_beginning = id::find_val("dpd_match_only_beginning")->AsBool(); dpd_late_match_stop = id::find_val("dpd_late_match_stop")->AsBool(); dpd_ignore_ports = id::find_val("dpd_ignore_ports")->AsBool(); - - timer_mgr_inactivity_timeout = id::find_val("timer_mgr_inactivity_timeout")->AsInterval(); } } // namespace zeek::detail diff --git a/src/NetVar.h b/src/NetVar.h index b79e80d2b1..3f8e11bac0 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -90,8 +90,6 @@ extern int dpd_ignore_ports; extern int check_for_unused_event_handlers; -extern double timer_mgr_inactivity_timeout; - extern int record_all_packets; extern bro_uint_t bits_per_uid; From 1c9ea09d9f83be1d709c40ecdd7f3dae25dfb33b Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 23 Feb 2022 11:31:21 +0000 Subject: [PATCH 061/204] Address PR feedback This addresses feedback to GH-1814. The most significant change is the fact that the ChipertextRecord now can remain &transient - which might lead to improved speed. --- scripts/policy/protocols/ssl/decryption.zeek | 16 ++++++++-------- src/analyzer/protocol/ssl/SSL.cc | 15 +++++++++++---- src/analyzer/protocol/ssl/SSL.h | 4 ++-- src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac | 4 ++-- src/analyzer/protocol/ssl/ssl-dtls-protocol.pac | 2 +- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek index 81ed2ee33e..3440b11f36 100644 --- a/scripts/policy/protocols/ssl/decryption.zeek +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -1,9 +1,9 @@ -##! This script allows for the decryption of certain TLS 1.2 connection, if the user is in possession +##! This script allows for the decryption of certain TLS 1.2 connections, if the user is in possession ##! of the private key material for the session. Key material can either be provided via a file (useful -##! for processing trace files) or via sending events via broker (for live decoding). +##! for processing trace files) or via sending events via Broker (for live decoding). ##! ##! Please note that this feature is experimental and can change without guarantees to our typical -##! deprecation tieline. Please also note that currently only TLS 1.2 connections that use the +##! deprecation timeline. Please also note that currently only TLS 1.2 connections that use the ##! TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 cipher suite are supported. @load base/frameworks/input @@ -26,19 +26,19 @@ export { ## Secrets expire after this time of not being used. const secret_expiration = 5 mins &redef; - ## This event can be triggered, e.g., via broker to add known keys to the TLS key database. + ## This event can be triggered, e.g., via Broker to add known keys to the TLS key database. ## ## client_random: client random for which the key is set ## ## keys: key material global add_keys: event(client_random: string, keys: string); - ## This event can be triggered, e.g., via broker to add known secrets to the TLS secret datbase. + ## This event can be triggered, e.g., via Broker to add known secrets to the TLS secret datbase. ## ## client_random: client random for which the secret is set ## ## secrets: derived TLS secrets material - global add_secret: event(client_random: string, secret: string); + global add_secret: event(client_random: string, secrets: string); } @if ( keylog_file == "" ) @@ -47,8 +47,8 @@ export { global secrets: table[string] of string = {} &redef; global keys: table[string] of string = {} &redef; @else -#global secrets: table[string] of string = {} &read_expire=secret_expiration &redef; -#global keys: table[string] of string = {} &read_expire=secret_expiration &redef; +global secrets: table[string] of string = {} &read_expire=secret_expiration &redef; +global keys: table[string] of string = {} &read_expire=secret_expiration &redef; @endif diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index e968ccfef9..37ef7286cc 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -23,8 +23,15 @@ namespace zeek::analyzer::ssl { -#define MSB(a) ((a >> 8) & 0xff) -#define LSB(a) (a & 0xff) +template static inline T MSB(const T a) + { + return ((a >> 8) & 0xff); + } + +template static inline T LSB(const T a) + { + return (a & 0xff); + } static std::basic_string fmt_seq(uint32_t num) { @@ -147,7 +154,7 @@ void SSL_Analyzer::SetKeys(const zeek::StringVal& nkeys) void SSL_Analyzer::SetKeys(const std::vector newkeys) { - keys = newkeys; + keys = std::move(newkeys); } std::optional> @@ -396,7 +403,7 @@ void SSL_Analyzer::ForwardDecryptedData(const std::vector& data, bool is pia->FirstPacket(false, nullptr); } else - reporter->FatalError("Could not initialize PIA"); + reporter->Error("Could not initialize PIA"); } ForwardStream(data.size(), data.data(), is_orig); diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index 415dcd9129..5fdbc27dca 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -25,7 +25,7 @@ namespace zeek::analyzer::ssl class SSL_Analyzer final : public analyzer::tcp::TCP_ApplicationAnalyzer { - // let binpac forward encryppted TLS application data to us. + // let binpac forward encrypted TLS application data to us. friend class binpac::SSL::SSL_Conn; public: @@ -54,7 +54,7 @@ public: * connection. (For TLS 1.2 this is the pre-master secret) * * Please note that these functions currently are hardcoded to only work with a single TLS 1.2 - * cuphersuite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). + * ciphersuite (TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384). * * @param secret The secret to set */ diff --git a/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac b/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac index 32849bd910..8ddecbe318 100644 --- a/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-dtls-analyzer.pac @@ -45,7 +45,7 @@ refine connection SSL_Conn += { return true; %} - function proc_ciphertext_record(rec : SSLRecord, cont: bytestring) : bool + function proc_ciphertext_record(rec : SSLRecord, cont: const_bytestring) : bool %{ if ( established_ == false && determine_tls13() == 1 ) { @@ -72,7 +72,7 @@ refine connection SSL_Conn += { if ( rec->content_type() == APPLICATION_DATA && decryption_failed_ == false ) { // If decryption of one packet fails, do not try to decrypt future packets. - if ( ! zeek_analyzer()->TryDecryptApplicationData(cont.length(), cont.data(), rec->is_orig(), rec->content_type(), rec->raw_tls_version()) ) + if ( ! zeek_analyzer()->TryDecryptApplicationData(cont.length(), cont.begin(), rec->is_orig(), rec->content_type(), rec->raw_tls_version()) ) decryption_failed_ = true; } diff --git a/src/analyzer/protocol/ssl/ssl-dtls-protocol.pac b/src/analyzer/protocol/ssl/ssl-dtls-protocol.pac index 156c1bf6f4..ad2b869ae8 100644 --- a/src/analyzer/protocol/ssl/ssl-dtls-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-dtls-protocol.pac @@ -96,7 +96,7 @@ type UnknownRecord(rec: SSLRecord) = record { }; type CiphertextRecord(rec: SSLRecord) = record { - cont : bytestring &restofdata; + cont : bytestring &restofdata &transient; }; ###################################################################### From adb66ba9933ab0af1d5c234f26aa9857119bc819 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 23 Feb 2022 16:49:18 -0700 Subject: [PATCH 062/204] Update cmake submodule [skip ci] [nomail] --- cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake b/cmake index 105f6c9df6..d13b955a1b 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 105f6c9df616a4c2286d5ef38c2b31a718192301 +Subproject commit d13b955a1b8447fbf5b8c47a85983b32b05ef4e9 From 1232adca386150fb1cb0117b15524ba3a8cff6df Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 23 Feb 2022 10:56:57 -0700 Subject: [PATCH 063/204] GH-1980: Deprecate and return warning for zeek-config's caf-root option --- zeek-config.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zeek-config.in b/zeek-config.in index 20c3e22475..a25449ff04 100755 --- a/zeek-config.in +++ b/zeek-config.in @@ -65,7 +65,7 @@ Toplevel installation directories for third-party components: --binpac_root BinPAC compiler --broker_root Broker communication framework - --caf_root C++ Actor Framework + --caf_root C++ Actor Framework (deprecated, will be removed in 5.1) " } @@ -100,7 +100,7 @@ while [ $# -ne 0 ]; do echo $build_type ;; --caf_root) - echo $caf_root + echo "The caf_root option is deprecated and will be removed in 5.1. The Broker API has been updated to no longer require access to CAF to build against Broker." ;; --cmake_dir) echo $cmake_dir From 41f4f526229fcbf819ed506f47749ce4a3bc34c7 Mon Sep 17 00:00:00 2001 From: Yacin Nadji Date: Thu, 24 Feb 2022 12:10:51 -0500 Subject: [PATCH 064/204] Add raw_bytes_to_v6_addr function --- src/zeek.bif | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/zeek.bif b/src/zeek.bif index 6bc0382882..db0af51ea1 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -2720,6 +2720,34 @@ function raw_bytes_to_v4_addr%(b: string%): addr return zeek::make_intrusive(htonl(a)); %} +## Converts a :zeek:type:`string` of bytes into an IPv6 address. In particular, +## this function interprets the first 16 bytes of the string as an IPv6 address +## in network order. +## +## b: The raw bytes (:zeek:type:`string`) to convert. +## +## Returns: The byte :zeek:type:`string` *b* as :zeek:type:`addr`. +## +## .. zeek:see:: raw_bytes_to_v6_addr to_addr to_subnet +function raw_bytes_to_v6_addr%(x: string%): addr + %{ + uint32_t bytes[4]; + + if ( x->Len() < 16 ) + zeek::emit_builtin_error("too short a string as input to raw_bytes_to_v6_addr()"); + + else + { + const u_char* xp = x->Bytes(); + bytes[0] = htonl((xp[0] << 24) | (xp[1] << 16) | (xp[2] << 8) | xp[3]); + bytes[1] = htonl((xp[0+4] << 24) | (xp[1+4] << 16) | (xp[2+4] << 8) | xp[3+4]); + bytes[2] = htonl((xp[0+8] << 24) | (xp[1+8] << 16) | (xp[2+8] << 8) | xp[3+8]); + bytes[3] = htonl((xp[0+12] << 24) | (xp[1+12] << 16) | (xp[2+12] << 8) | xp[3+12]); + } + + return zeek::make_intrusive(bytes); + %} + ## Converts a :zeek:type:`string` to a :zeek:type:`port`. ## ## s: The :zeek:type:`string` to convert. From 4194fdd279ca38f1b0dc0db6d03ce769d79b8c08 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 28 Feb 2022 11:10:08 -0800 Subject: [PATCH 065/204] Fix minor indentation bugs in strings.bif --- src/strings.bif | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strings.bif b/src/strings.bif index e4a6e21851..6292ae1b66 100644 --- a/src/strings.bif +++ b/src/strings.bif @@ -541,7 +541,7 @@ function to_lower%(str: string%): string *ls++ = s[i]; } - *ls++ = '\0'; + *ls++ = '\0'; return zeek::make_intrusive(new zeek::String(1, lower_s, n)); %} @@ -570,7 +570,7 @@ function to_upper%(str: string%): string *us++ = s[i]; } - *us++ = '\0'; + *us++ = '\0'; return zeek::make_intrusive(new zeek::String(1, upper_s, n)); %} From 3324f35cf9b6b16059985f9c18f48ba9bf490b74 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 28 Feb 2022 11:23:22 -0800 Subject: [PATCH 066/204] Clarify is_ascii() BiF docstring re behavior on empty strings --- src/strings.bif | 1 + 1 file changed, 1 insertion(+) diff --git a/src/strings.bif b/src/strings.bif index 6292ae1b66..7bc45996c1 100644 --- a/src/strings.bif +++ b/src/strings.bif @@ -614,6 +614,7 @@ function to_string_literal%(str: string%): string %} ## Determines whether a given string contains only ASCII characters. +## The empty string is ASCII. ## ## str: The string to examine. ## From 19bfa071e08207989e487725ef9dfcbbbd365408 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 28 Feb 2022 11:24:45 -0800 Subject: [PATCH 067/204] Expand testcases around is_num(), is_alpha(), is_alnum(), is_ascii() BiFs --- testing/btest/Baseline/bifs.is_ascii/out | 1 + testing/btest/Baseline/bifs.string_utils/out | 3 +++ testing/btest/bifs/is_ascii.zeek | 1 + testing/btest/bifs/string_utils.zeek | 3 +++ 4 files changed, 8 insertions(+) diff --git a/testing/btest/Baseline/bifs.is_ascii/out b/testing/btest/Baseline/bifs.is_ascii/out index 1956db8698..34333b473a 100644 --- a/testing/btest/Baseline/bifs.is_ascii/out +++ b/testing/btest/Baseline/bifs.is_ascii/out @@ -1,3 +1,4 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. F T +T diff --git a/testing/btest/Baseline/bifs.string_utils/out b/testing/btest/Baseline/bifs.string_utils/out index 147d0e9ea7..7e51c14446 100644 --- a/testing/btest/Baseline/bifs.string_utils/out +++ b/testing/btest/Baseline/bifs.string_utils/out @@ -17,14 +17,17 @@ Content checking ---------------- is_num abc : 0 is_num 123 : 1 +is_num '' : 0 is_alpha ab : 1 is_alpha 1a : 0 is_alpha a1 : 0 +is_alpha '' : 0 is_alnum ab : 1 is_alnum 1a : 1 is_alnum a1 : 1 is_alnum 12 : 1 is_alnum ##12: 0 +is_alnum '' : 0 String counting (input str 'aabbaa') ------------------------------------ diff --git a/testing/btest/bifs/is_ascii.zeek b/testing/btest/bifs/is_ascii.zeek index 505e21e715..da1b1cfa7e 100644 --- a/testing/btest/bifs/is_ascii.zeek +++ b/testing/btest/bifs/is_ascii.zeek @@ -9,4 +9,5 @@ event zeek_init() print is_ascii(a); print is_ascii(b); + print is_ascii(""); } diff --git a/testing/btest/bifs/string_utils.zeek b/testing/btest/bifs/string_utils.zeek index 5b5f70983e..021d7f68d0 100644 --- a/testing/btest/bifs/string_utils.zeek +++ b/testing/btest/bifs/string_utils.zeek @@ -23,14 +23,17 @@ event zeek_init() print "----------------"; print fmt("is_num abc : %d", is_num("abc")); print fmt("is_num 123 : %d", is_num("123")); + print fmt("is_num '' : %d", is_num("")); print fmt("is_alpha ab : %d", is_alpha("ab")); print fmt("is_alpha 1a : %d", is_alpha("1a")); print fmt("is_alpha a1 : %d", is_alpha("a1")); + print fmt("is_alpha '' : %d", is_alpha("")); print fmt("is_alnum ab : %d", is_alnum("ab")); print fmt("is_alnum 1a : %d", is_alnum("1a")); print fmt("is_alnum a1 : %d", is_alnum("a1")); print fmt("is_alnum 12 : %d", is_alnum("12")); print fmt("is_alnum ##12: %d", is_alnum("##12")); + print fmt("is_alnum '' : %d", is_alnum("")); print ""; print "String counting (input str 'aabbaa')"; From b977e76ad5f4581a824a3c01687dad1ad2b35898 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 28 Feb 2022 13:02:36 -0800 Subject: [PATCH 068/204] The is_num(), is_alpha(), and is_alnum() BiFs now return F on empty string --- NEWS | 2 ++ src/strings.bif | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 0acb7f13d0..34c6e3c611 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ New Functionality Changed Functionality --------------------- +- The is_num(), is_alpha(), and is_alnum() BiFs now return F for the empty string. + Deprecated Functionality ------------------------ diff --git a/src/strings.bif b/src/strings.bif index 7bc45996c1..11a38deaa3 100644 --- a/src/strings.bif +++ b/src/strings.bif @@ -1254,13 +1254,17 @@ function ends_with%(str: string, sub: string%) : bool return zeek::val_mgr->Bool(s.rfind(sub_s) == (s.size() - sub_s.size())); %} -## Returns whether an entire string consists only of digits. +## Returns whether a string consists entirely of digits. +## The empty string is not numeric. ## function is_num%(str: string%) : bool %{ // Python's version of this method (which this is based on) just checks to see if every // character in the string is a numeric value. If something more than this is desired, we // could use something like std::from_chars or std::strto{ul,f} to check it. + if ( str->Len() == 0 ) + return zeek::val_mgr->False(); + const char* s = str->CheckString(); for ( int i = 0; i < str->Len(); i++ ) if ( ! std::isdigit(s[i]) ) @@ -1269,10 +1273,14 @@ function is_num%(str: string%) : bool return zeek::val_mgr->True(); %} -## Returns whether an entire string is alphabetic characters. +## Returns whether a string consists entirely of alphabetic characters. +## The empty string is not alphabetic. ## function is_alpha%(str: string%) : bool %{ + if ( str->Len() == 0 ) + return zeek::val_mgr->False(); + const char* s = str->CheckString(); for ( int i = 0; i < str->Len(); i++ ) if ( ! std::isalpha(s[i]) ) @@ -1281,10 +1289,14 @@ function is_alpha%(str: string%) : bool return zeek::val_mgr->True(); %} -## Returns whether an entire string is alphanumeric characters +## Returns whether a string consists entirely of alphanumeric characters. +## The empty string is not alphanumeric. ## function is_alnum%(str: string%) : bool %{ + if ( str->Len() == 0 ) + return zeek::val_mgr->False(); + const char* s = str->CheckString(); for ( int i = 0; i < str->Len(); i++ ) if ( ! std::isalnum(s[i]) ) From 3e0b46b9638b0ed4b0ebb833e7d6d08bd0e195d0 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 28 Feb 2022 15:33:03 -0800 Subject: [PATCH 069/204] restored record constructor checking for missing-but-mandatory fields --- src/Expr.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Expr.cc b/src/Expr.cc index 4885067887..007382096f 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3375,6 +3375,8 @@ RecordConstructorExpr::RecordConstructorExpr(RecordTypePtr known_rt, ListExprPtr const auto& exprs = op->AsListExpr()->Exprs(); map = std::vector(exprs.length()); + std::set fields_seen; // used to check for missing fields + int i = 0; for ( const auto& e : exprs ) { @@ -3401,7 +3403,28 @@ RecordConstructorExpr::RecordConstructorExpr(RecordTypePtr known_rt, ListExprPtr SetError(); (*map)[i++] = index; + fields_seen.insert(index); } + + if ( IsError() ) + return; + + auto n = known_rt->NumFields(); + for ( i = 0; i < n; ++i ) + if ( fields_seen.count(i) == 0 ) + { + const auto td_i = known_rt->FieldDecl(i); + if ( IsAggr(td_i->type) ) + // These are always initialized. + continue; + + if ( ! td_i->GetAttr(ATTR_OPTIONAL) ) + { + auto err = std::string("mandatory field \"") + known_rt->FieldName(i) + + "\" missing"; + ExprError(err.c_str()); + } + } } ValPtr RecordConstructorExpr::InitVal(const TypePtr& t, ValPtr aggr) const From c77f543a17bd703948383e5797d20495f6c90eb7 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 28 Feb 2022 15:33:46 -0800 Subject: [PATCH 070/204] fix base scripts to include mandatory fields in record constructors --- scripts/base/protocols/conn/main.zeek | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/base/protocols/conn/main.zeek b/scripts/base/protocols/conn/main.zeek index 5f2999b206..cda5261bff 100644 --- a/scripts/base/protocols/conn/main.zeek +++ b/scripts/base/protocols/conn/main.zeek @@ -239,10 +239,11 @@ function determine_service(c: connection): string function set_conn(c: connection, eoc: bool) { if ( ! c?$conn ) - c$conn = Info(); + { + local p = get_port_transport_proto(c$id$resp_p); + c$conn = Info($ts=c$start_time, $uid=c$uid, $proto=p); + } - c$conn$ts=c$start_time; - c$conn$uid=c$uid; c$conn$id=c$id; if ( c?$tunnel && |c$tunnel| > 0 ) { @@ -250,7 +251,6 @@ function set_conn(c: connection, eoc: bool) c$conn$tunnel_parents = set(); add c$conn$tunnel_parents[c$tunnel[|c$tunnel|-1]$uid]; } - c$conn$proto=get_port_transport_proto(c$id$resp_p); if( |Site::local_nets| > 0 ) { c$conn$local_orig=Site::is_local_addr(c$id$orig_h); From b3ff872bd7fdad24cfbfe1a32eab9919bd3bddbd Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 28 Feb 2022 17:38:32 -0800 Subject: [PATCH 071/204] associated btest --- .../Baseline/language.record-bad-ctor4/out | 3 ++ testing/btest/language/record-bad-ctor4.zeek | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 testing/btest/Baseline/language.record-bad-ctor4/out create mode 100644 testing/btest/language/record-bad-ctor4.zeek diff --git a/testing/btest/Baseline/language.record-bad-ctor4/out b/testing/btest/Baseline/language.record-bad-ctor4/out new file mode 100644 index 0000000000..7368118fe8 --- /dev/null +++ b/testing/btest/Baseline/language.record-bad-ctor4/out @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/record-bad-ctor4.zeek, line 29: mandatory field "cnt" missing (info2($str=hello)) +error in <...>/record-bad-ctor4.zeek, line 29: mandatory field "a" missing ([$str=hello]) diff --git a/testing/btest/language/record-bad-ctor4.zeek b/testing/btest/language/record-bad-ctor4.zeek new file mode 100644 index 0000000000..2e944c29d2 --- /dev/null +++ b/testing/btest/language/record-bad-ctor4.zeek @@ -0,0 +1,31 @@ +# @TEST-EXEC-FAIL: zeek -b %INPUT >out 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out + +# Named record constructors should include values for every non-optional, +# non-aggregate field. + +type info1 : record { + str: string; + cnt: count &optional; + a: addr &optional; + + v: vector of bool; + r: record { x: count; }; + s: set[bool]; + t: table[bool] of string; +}; + +type info2 : record { + str: string; + cnt: count; + a: addr; +}; + +event zeek_init() + { + local resp1 = info1($str="hello"); + print resp1; + + local resp2 = info2($str="hello"); + print resp2; + } From 590d4aa13e56424f591a2982415d0f2f3851b2ce Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 1 Mar 2022 17:45:11 +0000 Subject: [PATCH 072/204] TLS decryption: add test, fix small issues Add a test loading keys from an external file. Make some debug messages slightly better and remove unnecessary debug output. --- scripts/policy/protocols/ssl/decryption.zeek | 1 - src/analyzer/protocol/ssl/SSL.cc | 8 +++- .../protocol/ssl/tls-handshake-protocol.pac | 3 -- .../Traces/tls/tls-1.2-stream-keylog.pcap | Bin 0 -> 182026 bytes .../protocols/ssl/decryption-keylog.zeek | 42 ++++++++++++++++++ 5 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 testing/btest/Traces/tls/tls-1.2-stream-keylog.pcap create mode 100644 testing/btest/scripts/policy/protocols/ssl/decryption-keylog.zeek diff --git a/scripts/policy/protocols/ssl/decryption.zeek b/scripts/policy/protocols/ssl/decryption.zeek index 3440b11f36..b9be06ca89 100644 --- a/scripts/policy/protocols/ssl/decryption.zeek +++ b/scripts/policy/protocols/ssl/decryption.zeek @@ -92,7 +92,6 @@ event SSL::add_secret(client_random: string, val: string) event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) { c$ssl$client_random = client_random; - print "Client random!"; if ( client_random in keys ) set_keys(c, keys[client_random]); diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 37ef7286cc..2d8d194e59 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -240,14 +240,18 @@ bool SSL_Analyzer::TryDecryptApplicationData(int len, const u_char* data, bool i auto cipher = handshake_interp->chosen_cipher(); if ( cipher != 0xC030 ) { - DBG_LOG(DBG_ANALYZER, "Unsupported cipher suite: %d\n", cipher); + DBG_LOG(DBG_ANALYZER, "Unsupported cipher suite for decryption: %d\n", cipher); return false; } // Neither secret or key present: abort if ( secret.size() == 0 && keys.size() == 0 ) { - DBG_LOG(DBG_ANALYZER, "Could not decrypt packet due to missing keys/secret.\n"); + DBG_LOG( + DBG_ANALYZER, + "Could not decrypt packet due to missing keys/secret. Client_random: %s\n", + util::fmt_bytes(reinterpret_cast(handshake_interp->client_random().data()), + handshake_interp->client_random().length())); // FIXME: change util function to return a printably std::string for DBG_LOG // print_hex("->client_random:", handshake_interp->client_random().data(), // handshake_interp->client_random().size()); diff --git a/src/analyzer/protocol/ssl/tls-handshake-protocol.pac b/src/analyzer/protocol/ssl/tls-handshake-protocol.pac index b42f292720..357bd77909 100644 --- a/src/analyzer/protocol/ssl/tls-handshake-protocol.pac +++ b/src/analyzer/protocol/ssl/tls-handshake-protocol.pac @@ -953,9 +953,6 @@ refine connection Handshake_Conn += { chosen_version_ = UNKNOWN_VERSION; record_version_ = 0; - // FIXME: How should bytestrings be initialized? - // client_random_ = ?? - // server_random_ = ?? gmt_unix_time_ = 0; %} diff --git a/testing/btest/Traces/tls/tls-1.2-stream-keylog.pcap b/testing/btest/Traces/tls/tls-1.2-stream-keylog.pcap new file mode 100644 index 0000000000000000000000000000000000000000..bbebc0a3e88b156d4689b04c959a1fea9e3df976 GIT binary patch literal 182026 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

MV3gAAHUF*5w^P4r>?I6Cp_UcuM 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 Z6EVZl5V+ywBU_OUPB+@a-FOZZjsW1#xLE)I literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/policy/protocols/ssl/decryption-keylog.zeek b/testing/btest/scripts/policy/protocols/ssl/decryption-keylog.zeek new file mode 100644 index 0000000000..70e2baf5c4 --- /dev/null +++ b/testing/btest/scripts/policy/protocols/ssl/decryption-keylog.zeek @@ -0,0 +1,42 @@ +# @TEST-REQUIRES: grep -q "#define OPENSSL_HAVE_KDF_H" $BUILD/zeek-config.h + +# @TEST-EXEC: ZEEK_TLS_KEYLOG_FILE=keylogfile.log zeek -B dpd -C -r $TRACES/tls/tls-1.2-stream-keylog.pcap %INPUT + +@TEST-START-FILE keylogfile.log +#fields client_random secret +\x0e\x78\x2d\x35\x63\x95\x5d\x8a\x30\xa9\xcf\xb6\x4f\x47\xf3\x96\x34\x8a\x1e\x79\x1a\xa2\x32\x55\xe2\x2f\xc5\x7a \x34\x4f\x12\x65\xbf\x43\x40\xb3\x61\x6b\xa0\x16\x5d\x2b\x4d\xb9\xb1\xe8\x4a\x3d\xa2\x42\x0e\x38\xab\x01\x50\x62\x84\xcc\x34\xcd\xe0\x34\x10\xfe\x1a\x02\x30\x49\x74\x6c\x46\x43\xa7\x0c\x67\x0d +\x24\x8c\x7e\x24\xee\xfb\x13\xcd\xee\xde\xb1\xf4\xb6\xd6\xd5\xee\x67\x8d\xd3\xff\xc7\xe7\x39\x23\x18\x3f\x99\xb4 \xe7\xed\x24\x26\x0d\x25\xd9\xfd\xf5\x0f\xc0\xf4\x56\x51\x0e\x4e\xec\x7f\x58\x9c\xaf\x39\x25\x14\x16\xa6\x71\xdd\xea\xfe\xe9\xc0\x93\xbe\x89\x4c\xab\xcc\xff\xb2\xf0\x9a\xea\x98\xf5\xb2\x53\x1e +\x57\xd7\xc7\x7a\x2d\x5e\x35\x29\x2c\xd7\xe7\x94\xee\xf8\x6f\x31\x45\xf6\xbe\x25\x08\xed\x1d\x92\xd2\x0b\x9b\x04 \xc1\x93\x17\x93\xd9\x7d\xd2\x98\xb3\xe0\xdb\x2c\x5d\xbe\x71\x31\xa7\x9a\xf5\x91\xf9\x87\x90\xee\xb7\x79\x9f\x6b\xb4\x1f\x47\xa7\x69\x62\x4b\xa3\x99\x0c\xa9\x43\xf9\xea\x3b\x4d\x5f\x2f\xfe\xfb +\x30\xd7\xb8\x92\xc1\xec\x17\x90\x5b\x0f\xcb\xda\xe6\x42\xb2\x09\x4c\xdd\x7d\x2e\xa1\x9f\x1a\x3b\x70\x23\x7d\xf2 \xc1\x93\x17\x93\xd9\x7d\xd2\x98\xb3\xe0\xdb\x2c\x5d\xbe\x71\x31\xa7\x9a\xf5\x91\xf9\x87\x90\xee\xb7\x79\x9f\x6b\xb4\x1f\x47\xa7\x69\x62\x4b\xa3\x99\x0c\xa9\x43\xf9\xea\x3b\x4d\x5f\x2f\xfe\xfb +\x49\xc7\x71\x25\xdc\xb0\xa7\xbc\xd6\xb6\x67\x5c\x30\x58\x8d\xad\x47\x5a\x93\x60\xac\xa5\x78\xf5\x62\x7e\xff\x62 \xc1\x93\x17\x93\xd9\x7d\xd2\x98\xb3\xe0\xdb\x2c\x5d\xbe\x71\x31\xa7\x9a\xf5\x91\xf9\x87\x90\xee\xb7\x79\x9f\x6b\xb4\x1f\x47\xa7\x69\x62\x4b\xa3\x99\x0c\xa9\x43\xf9\xea\x3b\x4d\x5f\x2f\xfe\xfb +\x38\x1c\x49\xcc\xf9\x62\xd0\x5c\xf0\xd4\xe2\xd5\xa1\x15\xc1\x5e\x8d\x02\xcc\x50\xed\x6c\x90\x63\x73\x9d\xfb\x96 \xdc\xf5\xfc\x10\xf2\xb3\x8b\xd8\x87\xae\xcf\xb5\xcd\x1a\xe3\xa8\x06\x8e\x85\xfc\xbb\xfc\x22\xec\x0f\x79\x99\x04\x13\x5b\x6b\x03\x52\x02\xee\xe9\x04\x59\x78\x44\xf1\xf3\xc8\xac\x22\x68\x6c\x7e +\x61\x9e\x08\x51\xee\x36\x3c\x2c\xf3\x71\x87\x22\x82\x27\xca\x4e\x68\x0f\x9a\x7c\x0b\xd1\x50\x69\xaa\x7a\x59\x70 \xad\x03\xce\xda\x48\x90\xfa\x58\x1e\x98\x9f\x5e\x38\x62\x02\x3e\x2a\x4e\x3e\x8a\xd8\x13\x25\x23\x8d\x90\x80\x66\xe1\xd3\x5c\xc8\x75\x97\x9e\x34\xc0\x8e\x6f\xdf\xd9\xd8\xc6\xf3\x56\xe3\x85\xc1 +\xcb\x3f\x93\xd2\x55\xcb\xb6\x56\x25\x87\xf0\xdd\x01\x02\x12\xfd\xee\x9d\x23\x3a\xff\x64\xe6\xed\x36\xcd\x5c\x45 \x0d\x36\xfa\xaa\x2e\xad\xbd\xa2\xa8\x09\x5f\x95\x1d\xe1\xcb\xac\x46\xb8\x1b\x00\x8f\xbf\x39\x1d\x91\x95\x1b\x34\x85\x47\x6b\xab\x73\x28\x8a\x1e\x17\xcd\x0c\xe8\x0e\x0f\xc0\x40\x1d\xbe\x9e\x3f +\xf9\x7e\x7d\x38\x56\xe2\xfc\xcb\xbe\x80\x79\x8e\xc2\xe3\xf5\x15\x25\x10\x82\xad\x63\xbb\xc7\xc2\x31\xd8\xbe\xe0 \x9a\x7c\xf9\x46\xa0\x47\x18\xa1\x9f\x4d\x20\xc3\xf8\x0c\x1c\xf8\xc8\x23\xc3\xe2\xb1\xc3\x37\xef\x64\x32\x2d\x75\x1b\x41\x05\x43\x31\x5f\x6e\xcf\x7d\xbf\x45\xec\x9b\xe1\x94\xa3\xcc\x7c\x1a\x0f +\x57\x97\x63\x67\xf2\xea\x9c\x95\x46\x7a\x6c\xc5\x59\xda\x6f\xeb\xbc\x44\x2e\x11\x3a\xc5\xea\xa7\xed\x97\xad\x38 \x0e\x5e\xc0\x6c\xa5\x4e\xe3\x86\x05\x5a\xaa\x97\x1c\x7e\x09\x39\xba\x3e\x1f\xb1\x62\x4d\x0a\x5b\x9c\x0c\xae\x97\x5f\x0e\x25\xbc\x4c\x51\x21\xfa\x34\x5e\xa1\x26\x47\xc4\x7a\x5a\x1c\xe5\xbd\xce +\x70\x18\x17\x27\xd6\xe2\x04\xd1\xd8\xa5\xb8\x2a\x05\x01\xaf\x7b\x13\x6d\x3a\x9c\x56\x6c\x32\x5b\x3f\xef\xb5\x04 \x92\x3d\x8a\x93\xba\xc5\x54\xc1\x04\x9a\x8d\xeb\x63\x28\x8c\xd7\x4d\x60\x51\xb0\x7a\x10\x67\x84\x8d\xac\x15\xc8\x75\xf2\x5c\x2a\x60\xe3\x38\xde\xb3\x27\x37\x44\xb1\x53\xe6\x9d\x42\x06\x0e\x18 +\x4f\x12\x67\xb1\x13\xdc\x1a\x3e\x5d\xee\xbf\xff\xa7\x4d\xaa\xa1\x96\xff\x43\x0a\x30\xbe\x04\x07\x60\x29\x5f\x5e \x1d\x61\x52\xa6\x1e\x86\x75\x53\x04\xb8\x8e\x12\x6f\xdb\xa4\x49\x05\xeb\x5e\x4b\x33\xf6\xaf\xee\x67\x20\x37\xfd\x84\x48\x9a\xaa\x62\xa6\xb2\x64\x0f\x62\x87\x12\xe8\x05\x98\xae\x0c\xbf\xae\x5f +\xfe\x13\x61\x60\x80\x41\x0b\x9d\xc2\xcc\xc2\xc3\x00\xab\x20\x6b\xb8\x43\xc4\xc4\x22\x81\x1f\x15\xd4\xed\x34\xc3 \x39\xfb\x4d\x9c\x1d\xff\x4d\xe4\x1c\x86\xf9\x67\x9b\x32\xca\xa3\x99\x9c\x91\xcd\x7a\xf5\x4d\xc5\x58\x98\x1c\xcf\xf6\xd9\xa7\x4c\x92\x6e\x93\x7f\x98\x02\x96\x22\x20\x52\x5e\x9d\xe0\xec\x4a\xc1 +\x92\xc2\x33\xdd\xf3\xf4\x31\xd6\x0c\x9b\x90\x86\x6a\xde\x5d\x80\x32\x22\xb8\x18\x45\xf5\x11\x72\xa0\x4f\xe9\x65 \xda\x22\x06\x86\xef\x25\x99\xb4\x65\x2c\x45\x94\x73\xcd\xe9\xc6\x64\x55\x84\x21\x42\x35\x86\x57\x9a\x60\xd4\xc7\x88\xd8\x1b\x3a\xbe\xdf\x53\x7b\xd7\x9c\xf9\x29\x47\x05\x07\x0f\x23\x3b\x22\xc4 +\x39\x8e\xeb\xdf\x69\xd9\xe3\xe2\xce\xd8\xe9\xb2\x93\xa6\xb7\x58\x30\x9b\xaf\x14\x98\xbd\x27\xa0\xe1\x12\x54\x3f \xa9\xcc\x51\xa6\x83\xf1\xbb\x6b\x37\xf0\xe2\x8b\xa5\xea\x31\xc8\xdc\x19\x5e\xb1\xaf\xa0\x5c\x51\xa1\x4a\x73\x22\xc0\x24\xf1\x41\x4a\xd9\x15\x16\xa8\x83\x38\x84\xe1\xca\x9d\xf0\xd5\x35\x40\x73 +\xdc\xf5\x87\xb0\x6d\x66\xd6\xab\x66\x34\xd7\x64\xc8\x51\xa1\x22\xe3\x97\x3d\x4b\x16\xee\x8e\x1e\x0b\xfb\xfc\x13 \xd5\xaf\x0d\xed\x74\x58\x8d\xe8\x97\x6d\xa0\xb2\x46\x83\x58\x0f\x52\xbc\xc7\x66\xb1\x19\x74\x70\x0d\xaa\xd1\x10\x9b\x71\x53\xe6\x80\x34\x5d\x81\xd2\x86\x8a\x33\xfc\x62\x88\xa7\x80\xac\x63\xb6 +\x51\xcb\xcc\x61\xae\xd0\xeb\x08\x75\x09\xde\x68\x3c\x36\x03\xf5\xa3\xd5\xa5\x15\xdc\x3e\x87\xdb\xcf\xc7\x7a\x1e \x25\x90\xa9\x7e\x5a\x93\xe9\xdd\x61\x6c\x46\xf2\xf6\x03\x7c\x19\xb1\xf5\x9a\x4a\x6c\x58\x71\x8e\xfe\xa4\xfe\xa6\x30\x70\x5f\xaf\xd4\xf9\xb9\x3a\x16\xa8\x0f\x69\x8d\x29\xfb\x1a\x34\x62\x87\x36 +\x01\x01\x12\xfb\x01\x61\xc6\xcd\xde\xdd\x2a\x9b\x2a\x2f\x02\x65\xa5\x0f\x62\xb1\x1b\x26\xd3\xa2\x69\x78\xe0\x17 \x8a\x67\x2f\xc6\xc1\x75\xed\xb9\x2f\x8c\xb5\x3d\xdc\x56\xb4\x3e\xab\x11\xa7\xb6\xff\x32\x47\x7b\x9c\x9c\x32\xe9\xbe\xa6\xb1\xed\xe1\x29\x7e\x4b\x89\xb7\xb0\xd6\x21\xc1\xda\x5c\x90\x70\x1b\xe4 +\x7a\xf0\xf4\x6e\x91\x8e\x38\x51\xfd\xd6\x42\xfb\x3e\x9b\x78\x29\x49\x3f\x78\x19\xd6\x2b\x61\xd5\x8b\xad\xfd\x70 \x78\xd8\x68\x51\x05\xc5\x3c\xeb\xcd\x22\xe0\x2e\x4b\x6f\xae\x53\x3f\xe8\x23\x73\xeb\xeb\x1b\xb2\x9a\x76\xca\x65\x01\x16\xa2\x97\x93\x60\xd5\x5d\xd4\xac\x52\x22\x16\x40\x15\x03\xb6\x23\xc1\xac +\x31\x15\xDD\x9D\x68\x19\xB3\xBF\x45\x32\x99\x74\x0D\x04\xAE\x37\xAD\x69\xE5\x23\x4C\xD5\x40\xF8\xB5\x89\x4B\xA4 \x7C\x57\xC5\x98\xCD\x00\xE0\x0F\x55\x48\x6A\xF0\x02\x4E\x84\xB7\xAE\x07\xB5\xCD\xB1\x1E\x17\x2D\x24\xF0\xB3\xB3\xB8\x4B\x54\x4A\x82\x84\x15\xAD\x52\x24\x52\xBB\x34\x0D\x95\x30\x45\x3E\x15\x14 +\x07\xDF\x9C\xC1\x59\xB6\x42\x8E\x57\x84\xED\xB1\x60\x37\xF3\x24\x2F\x70\x27\x5D\x07\xC4\xA8\xB9\xF0\xA7\xA6\x7F \x13\x9C\x33\x7E\x5C\x4E\x23\x5F\xCB\xFF\xD0\xD0\x54\x38\x0E\x04\x46\x2E\x6C\x8D\x51\x52\xEE\xAD\x79\x3F\x07\xA8\xCD\x18\x7D\x99\x99\x82\x1F\xA1\x51\xE2\xF6\xD4\x3F\x7B\x5C\x8A\xFE\x83\x6F\x4F +@TEST-END-FILE + +@load protocols/ssl/decryption +@load base/protocols/http + +event zeek_init() + { + suspend_processing(); + } + +event Input::end_of_data(name: string, source: string) + { + if ( name == "tls-keylog-file" ) + continue_processing(); + } From 130d93f0de63264a14693bf9f8da370c87670469 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 4 Mar 2022 16:46:53 +0100 Subject: [PATCH 073/204] Improve error message when receiving unexpected record content via Broker. Broker sends record values as a vector of the corresponding fields. If the received values doesn't match the actual record fields, Zeek has so far been reporting this not-so-helpful error message: warning: failed to convert remote event 'got_result' arg #1, got vector, expected record This change turns the latter part into a list of the field types we actually received, which makes debugging much easier. (No test, seems overkill to add a spawn a Broker client to exercise this.) --- src/broker/Manager.cc | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index 9b8fa1ba1e..20ba72f28e 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -1391,17 +1391,35 @@ void Manager::ProcessEvent(const broker::topic& topic, broker::zeek::Event ev) { auto got_type = args[i].get_type_name(); const auto& expected_type = arg_types[i]; - auto val = detail::data_to_val(std::move(args[i]), expected_type.get()); + auto val = detail::data_to_val(args[i], expected_type.get()); if ( val ) vl.emplace_back(std::move(val)); else { auto expected_name = type_name(expected_type->Tag()); + std::string msg_addl = util::fmt("got %s, expected %s", got_type, expected_name); - reporter->Warning("failed to convert remote event '%s' arg #%zu," - " got %s, expected %s", - name.data(), i, got_type, expected_name); + if ( strcmp(expected_name, "record") == 0 && strcmp("vector", got_type) == 0 ) + { + // This means the vector elements didn't align with the record + // fields. Produce an error message that shows what we + // received. + std::string elements; + for ( const auto& e : broker::get(args[i]) ) + { + if ( ! elements.empty() ) + elements += ", "; + + elements += e.get_type_name(); + } + + msg_addl = util::fmt("got mismatching field types [%s] for record type '%s'", + elements.c_str(), expected_type->GetName().c_str()); + } + + reporter->Warning("failed to convert remote event '%s' arg #%zu, %s", name.data(), i, + msg_addl.c_str()); // If we got a vector and expected a function this is // possibly because of a mismatch between From c048744c2a091eb8aac587b84b57cbac02424dd7 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 4 Mar 2022 05:40:04 +0000 Subject: [PATCH 074/204] Update 3rdparty submodule for bsd-getopt-long fix --- src/3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty b/src/3rdparty index cb626c94f6..0af190f905 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit cb626c94f67e0ac0437beba076da1184eb1f8ad7 +Subproject commit 0af190f90572abc90366471f36e6feb1b817d2ab From 45ab85c09e2a58db1be2a43d4310c67c55cfbbb9 Mon Sep 17 00:00:00 2001 From: Yacin Nadji Date: Tue, 8 Mar 2022 17:30:02 -0500 Subject: [PATCH 075/204] Add tests for raw_bytes_to_v6_addr --- testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out | 4 ++++ testing/btest/bifs/raw_bytes_to_v6_addr.zeek | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out create mode 100644 testing/btest/bifs/raw_bytes_to_v6_addr.zeek diff --git a/testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out b/testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out new file mode 100644 index 0000000000..31ab948f9b --- /dev/null +++ b/testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +4142:4344:4546:4748:494b:4c4d:4e4f:5051 +2852:8180:ff7f:0:2700:: +dada:beef::4e5e:cff:fe6a:8671 diff --git a/testing/btest/bifs/raw_bytes_to_v6_addr.zeek b/testing/btest/bifs/raw_bytes_to_v6_addr.zeek new file mode 100644 index 0000000000..38e0db9ee2 --- /dev/null +++ b/testing/btest/bifs/raw_bytes_to_v6_addr.zeek @@ -0,0 +1,10 @@ +# +# @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff out + +event zeek_init() + { + print raw_bytes_to_v6_addr("ABCDEFGHIKLMNOPQ"); + print raw_bytes_to_v6_addr("ABCDEFGHIKLMNOP"); + print raw_bytes_to_v6_addr("\xda\xda\xbe\xef\x00\x00\x00\x00N^\x0c\xff\xfej\x86q"); + } From a2320ffe889d0f9600d515d0d4c093c22d56636c Mon Sep 17 00:00:00 2001 From: Yacin Nadji Date: Wed, 9 Mar 2022 11:15:48 -0500 Subject: [PATCH 076/204] Zero out bytes by default for consistent return value on error --- src/zeek.bif | 2 +- testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zeek.bif b/src/zeek.bif index db0af51ea1..1737349f1b 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -2731,7 +2731,7 @@ function raw_bytes_to_v4_addr%(b: string%): addr ## .. zeek:see:: raw_bytes_to_v6_addr to_addr to_subnet function raw_bytes_to_v6_addr%(x: string%): addr %{ - uint32_t bytes[4]; + uint32_t bytes[4] = {0, 0, 0, 0}; if ( x->Len() < 16 ) zeek::emit_builtin_error("too short a string as input to raw_bytes_to_v6_addr()"); diff --git a/testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out b/testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out index 31ab948f9b..059b996fd8 100644 --- a/testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out +++ b/testing/btest/Baseline/bifs.raw_bytes_to_v6_addr/out @@ -1,4 +1,4 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. 4142:4344:4546:4748:494b:4c4d:4e4f:5051 -2852:8180:ff7f:0:2700:: +:: dada:beef::4e5e:cff:fe6a:8671 From f71ac032a619b23784717733aec9f2ff3ab85b65 Mon Sep 17 00:00:00 2001 From: Yacin Nadji Date: Wed, 9 Mar 2022 11:16:20 -0500 Subject: [PATCH 077/204] add raw_bytes_to_v6_addr in docs when raw_bytes_to_v4_addr is present --- src/zeek.bif | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/zeek.bif b/src/zeek.bif index 1737349f1b..c934f106b2 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -2561,7 +2561,7 @@ function count_to_port%(num: count, proto: transport_proto%): port ## Returns: The :zeek:type:`string` *ip* as :zeek:type:`addr`, or the unspecified ## address ``::`` if the input string does not parse correctly. ## -## .. zeek:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr +## .. zeek:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr raw_bytes_to_v6_addr ## to_subnet function to_addr%(ip: string%): addr %{ @@ -2601,7 +2601,7 @@ function is_valid_ip%(ip: string%): bool ## Returns: The *sn* string as a :zeek:type:`subnet`, or the unspecified subnet ## ``::/0`` if the input string does not parse correctly. ## -## .. zeek:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr +## .. zeek:see:: to_count to_int to_port count_to_v4_addr raw_bytes_to_v4_addr raw_bytes_to_v6_addr ## to_addr function to_subnet%(sn: string%): subnet %{ @@ -2683,7 +2683,7 @@ function to_double%(str: string%): double ## ## Returns: The :zeek:type:`count` *ip* as :zeek:type:`addr`. ## -## .. zeek:see:: raw_bytes_to_v4_addr to_addr to_subnet +## .. zeek:see:: raw_bytes_to_v4_addr to_addr to_subnet raw_bytes_to_v6_addr function count_to_v4_addr%(ip: count%): addr %{ if ( ip > 4294967295LU ) From c99a5c8d1163f58114874a97e7fdada5e03e3110 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 11 Mar 2022 14:34:00 -0700 Subject: [PATCH 078/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 5cf75d9727..b1ec7eeaf9 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 5cf75d97275d2bd436ff7ad70669ac33f1ccc4d0 +Subproject commit b1ec7eeaf937e07e8c49687887c4e86d01c90f3c From 912a2fbfef3b1f5471dfcf919991c422111d7a6e Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 16 Mar 2022 11:56:16 -0700 Subject: [PATCH 079/204] Fix document generation We broke multi-repo git interaction when we introduced use of "actions/checkout", because it has subtle implications on auth mechanisms (for details, check action logs when it conducts a recursive checkout). Thankfully it also helps overcome these: passing a user token to actions/checkout simplifies multi-repo git interaction, making it work as it should: you no longer need to think about it. We now use this approach. Also tweak the git commit logic: we no longer mask all errors. Seems we mainly did that to mask "git commit" on no changes erroring out. Instead we now check whether there's anything to commit, and only do so then. We do this both in the zeek-docs repo and for the docs submodule bump. --- .github/workflows/generate-docs.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index 20baa71484..ea749a2e62 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -18,6 +18,7 @@ jobs: - uses: actions/checkout@v2 with: submodules: "recursive" + token: ${{ secrets.ZEEK_BOT_TOKEN }} - name: Switch doc submodule to master run: cd doc && git checkout master @@ -78,20 +79,21 @@ jobs: if: github.event_name == 'schedule' run: | cd doc - git remote set-url origin "https://zeek-bot:${{ secrets.ZEEK_BOT_TOKEN }}@github.com/zeek/zeek-docs" git add scripts/ script-reference/ git status - git commit -m "Generate docs" && git push || /bin/true + # git commit errors when there's nothing to commit, so guard it + # with a check that detects whether there's anything to commit/push. + git diff-index --quiet HEAD || { git commit -m "Generate docs" && git push; } - name: Update zeek-docs Submodule if: github.event_name == 'schedule' run: | git config --global user.name zeek-bot git config --global user.email info@zeek.org - git remote add auth "https://zeek-bot:${{ secrets.ZEEK_BOT_TOKEN }}@github.com/zeek/zeek" git add doc git status - git commit -m 'Update doc submodule [nomail] [skip ci]' && git push auth master || /bin/true + # Similar logic here: proceed only if there's a change in the submodule. + git diff-index --quiet HEAD || { git commit -m 'Update doc submodule [nomail] [skip ci]' && git push; } - name: Send email if: failure() From b6a31421dfa75e0ed10acde404d35089f451108c Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 16 Mar 2022 15:00:21 -0700 Subject: [PATCH 080/204] Update docs submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index b1ec7eeaf9..c021642fda 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit b1ec7eeaf937e07e8c49687887c4e86d01c90f3c +Subproject commit c021642fda1392cde9414db9f148e93491f3e7c2 From e403dd5fe1a726aa971e953d2c4027931ad2daa6 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 28 Feb 2022 14:17:48 -0800 Subject: [PATCH 081/204] Build Gen-ZAM from a submodule and support use of pre-existing executable This separates Gen-ZAM from the main Zeek distribution and places it in a submodule at auxil/gen-zam, reflecting binpac and bifcl. Configuring with --with-gen-zam=... allws reuse of an existing executable. --- .gitmodules | 3 + CMakeLists.txt | 4 + NEWS | 8 + auxil/gen-zam | 1 + cmake | 2 +- configure | 5 + src/CMakeLists.txt | 50 +- src/script_opt/ZAM/Gen-ZAM.cc | 2223 --------------------------------- src/script_opt/ZAM/Gen-ZAM.h | 986 --------------- 9 files changed, 34 insertions(+), 3248 deletions(-) create mode 160000 auxil/gen-zam delete mode 100644 src/script_opt/ZAM/Gen-ZAM.cc delete mode 100644 src/script_opt/ZAM/Gen-ZAM.h diff --git a/.gitmodules b/.gitmodules index 4318212fe0..980a23e6eb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -49,3 +49,6 @@ [submodule "auxil/zeek-client"] path = auxil/zeek-client url = https://github.com/zeek/zeek-client +[submodule "auxil/gen-zam"] + path = auxil/gen-zam + url = https://github.com/zeek/gen-zam diff --git a/CMakeLists.txt b/CMakeLists.txt index 86d1a15c4c..6445d20f54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -294,6 +294,10 @@ if ( NOT BIFCL_EXE_PATH ) add_subdirectory(auxil/bifcl) endif () +if ( NOT GEN_ZAM_EXE_PATH ) + add_subdirectory(auxil/gen-zam) +endif () + if (ENABLE_JEMALLOC) if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") if (DEFINED JEMALLOC_ROOT_DIR) diff --git a/NEWS b/NEWS index 0acb7f13d0..20b8a6e086 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,14 @@ Breaking Changes New Functionality ----------------- +- The new --with-gen-zam configure flag and its corresponding GEN_ZAM_EXE_PATH + cmake variable allow reuse of a previously built Gen-ZAM code generator. This + aids cross-compilation: the Zeek build process normally compiles Gen-ZAM on + the fly, but when cross-compiling will do so for the target platform, breaking + its use on the host platform. Gen-ZAM is similar to binpac and bifcl in this + regard. Like binpac and bifcl, it's now also available as a standalone git + repository and hooked into the Zeek distribution as a submodule. + Changed Functionality --------------------- diff --git a/auxil/gen-zam b/auxil/gen-zam new file mode 160000 index 0000000000..a0fb7b0933 --- /dev/null +++ b/auxil/gen-zam @@ -0,0 +1 @@ +Subproject commit a0fb7b093324aade9f52cd4a533b4440624cd3d0 diff --git a/cmake b/cmake index d13b955a1b..c3ebadd1d1 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit d13b955a1b8447fbf5b8c47a85983b32b05ef4e9 +Subproject commit c3ebadd1d111481dc8d8fd26f4f8a3cddf7227f5 diff --git a/configure b/configure index 8f0fb27e41..80c009bc1a 100755 --- a/configure +++ b/configure @@ -85,6 +85,8 @@ Usage: $0 [OPTION]... [VAR=VALUE]... (Zeek uses an embedded version by default) --with-caf=PATH path to C++ Actor Framework install root (a Broker dependency that is embedded by default) + --with-gen-zam=PATH path to Gen-ZAM code generator + (Zeek uses an embedded version by default) --with-flex=PATH path to flex executable --with-libkqueue=PATH path to libkqueue install root (Zeek uses an embedded version by default) @@ -338,6 +340,9 @@ while [ $# -ne 0 ]; do --with-flex=*) append_cache_entry FLEX_EXECUTABLE PATH $optarg ;; + --with-gen-zam=*) + append_cache_entry GEN_ZAM_EXE_PATH PATH $optarg + ;; --with-geoip=*) append_cache_entry LibMMDB_ROOT_DIR PATH $optarg ;; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d8a82b92bb..ea7e6c09c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -150,6 +150,15 @@ list(APPEND BINPAC_OUTPUTS "${BINPAC_OUTPUT_CC}") binpac_target(binpac_zeek-lib.pac) list(APPEND BINPAC_OUTPUTS "${BINPAC_OUTPUT_CC}") +######################################################################## +## Gen-ZAM setup + +include(Gen-ZAM) + +set(GEN_ZAM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/script_opt/ZAM/Ops.in) + +gen_zam_target(${GEN_ZAM_SRC}) + ######################################################################## ## Including subdirectories. ######################################################################## @@ -248,37 +257,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h set(_gen_zeek_script_cpp ${CMAKE_CURRENT_BINARY_DIR}/../CPP-gen.cc) add_custom_command(OUTPUT ${_gen_zeek_script_cpp} - COMMAND ${CMAKE_COMMAND} -E touch ${_gen_zeek_script_cpp}) - -# define a command that's used to run the ZAM instruction generator; -# building the zeek binary depends on the outputs of this script -add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ZAM-AssignFlavorsDefs.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-Conds.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-DirectDefs.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-EvalDefs.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-EvalMacros.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-GenExprsDefsC1.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-GenExprsDefsC2.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-GenExprsDefsC3.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-GenExprsDefsV.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-GenFieldsDefsC1.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-GenFieldsDefsC2.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-GenFieldsDefsV.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-MethodDecls.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-MethodDefs.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-Op1FlavorsDefs.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-OpSideEffects.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-OpsDefs.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-OpsNamesDefs.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-Vec1EvalDefs.h - ${CMAKE_CURRENT_BINARY_DIR}/ZAM-Vec2EvalDefs.h - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/Gen-ZAM - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/script_opt/ZAM/Ops.in - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Gen-ZAM - ${CMAKE_CURRENT_SOURCE_DIR}/script_opt/ZAM/Ops.in - COMMENT "[sh] Generating ZAM operations" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -) + COMMAND ${CMAKE_COMMAND} -E touch ${_gen_zeek_script_cpp}) set_source_files_properties(3rdparty/nb_dns.c PROPERTIES COMPILE_FLAGS -fno-strict-aliasing) @@ -445,10 +424,6 @@ set(THIRD_PARTY_SRCS 3rdparty/strsep.c ) -set(GEN_ZAM_SRCS - script_opt/ZAM/Gen-ZAM.cc -) - # Highwayhash. Highwayhash is a bit special since it has architecture dependent code... set(HH_SRCS @@ -504,6 +479,8 @@ set(zeek_SRCS ${BIF_SRCS} ${BINPAC_AUXSRC} ${BINPAC_OUTPUTS} + ${GEN_ZAM_SRC} + ${GEN_ZAM_OUTPUT_H} ${TRANSFORMED_BISON_OUTPUTS} ${FLEX_RuleScanner_OUTPUTS} ${FLEX_RuleScanner_INPUT} @@ -522,7 +499,6 @@ set(zeek_SRCS ) collect_headers(zeek_HEADERS ${zeek_SRCS}) -collect_headers(GEN_ZAM_HEADERS ${GEN_ZAM_SRCS}) add_library(zeek_objs OBJECT ${zeek_SRCS}) @@ -538,8 +514,6 @@ set_target_properties(zeek PROPERTIES ENABLE_EXPORTS TRUE) install(TARGETS zeek DESTINATION bin) -add_executable(Gen-ZAM ${GEN_ZAM_SRCS} ${GEN_ZAM_HEADERS}) - # Install wrapper script for Bro-to-Zeek renaming. include(InstallSymlink) InstallSymlink("${CMAKE_INSTALL_PREFIX}/bin/zeek-wrapper" "${CMAKE_INSTALL_PREFIX}/bin/bro") diff --git a/src/script_opt/ZAM/Gen-ZAM.cc b/src/script_opt/ZAM/Gen-ZAM.cc deleted file mode 100644 index 92948b4d84..0000000000 --- a/src/script_opt/ZAM/Gen-ZAM.cc +++ /dev/null @@ -1,2223 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -#include "zeek/script_opt/ZAM/Gen-ZAM.h" - -#include -#include - -using namespace std; - -// Helper functions to convert dashes to underscores or vice versa. -static char dash_to_under(char c) - { - return c == '-' ? '_' : c; - } - -static char under_to_dash(char c) - { - return c == '_' ? '-' : c; - } - -// Structure for binding together Zeek script types, internal names Gen-ZAM -// uses to track them, mnemonics for referring to them in instruction names, -// the corresponding Val accessor, and whether the type requires memory -// management. -struct TypeInfo - { - string tag; - ZAM_ExprType et; - string suffix; - string accessor; // doesn't include "As" prefix or "()" suffix - bool is_managed; - }; - -static vector ZAM_type_info = { - {"TYPE_ADDR", ZAM_EXPR_TYPE_ADDR, "A", "Addr", true}, - {"TYPE_ANY", ZAM_EXPR_TYPE_ANY, "a", "Any", true}, - {"TYPE_COUNT", ZAM_EXPR_TYPE_UINT, "U", "Count", false}, - {"TYPE_DOUBLE", ZAM_EXPR_TYPE_DOUBLE, "D", "Double", false}, - {"TYPE_FILE", ZAM_EXPR_TYPE_FILE, "f", "File", true}, - {"TYPE_FUNC", ZAM_EXPR_TYPE_FUNC, "F", "Func", true}, - {"TYPE_INT", ZAM_EXPR_TYPE_INT, "I", "Int", false}, - {"TYPE_LIST", ZAM_EXPR_TYPE_LIST, "L", "List", true}, - {"TYPE_OPAQUE", ZAM_EXPR_TYPE_OPAQUE, "O", "Opaque", true}, - {"TYPE_PATTERN", ZAM_EXPR_TYPE_PATTERN, "P", "Pattern", true}, - {"TYPE_RECORD", ZAM_EXPR_TYPE_RECORD, "R", "Record", true}, - {"TYPE_STRING", ZAM_EXPR_TYPE_STRING, "S", "String", true}, - {"TYPE_SUBNET", ZAM_EXPR_TYPE_SUBNET, "N", "SubNet", true}, - {"TYPE_TABLE", ZAM_EXPR_TYPE_TABLE, "T", "Table", true}, - {"TYPE_TYPE", ZAM_EXPR_TYPE_TYPE, "t", "Type", true}, - {"TYPE_VECTOR", ZAM_EXPR_TYPE_VECTOR, "V", "Vector", true}, -}; - -// Given a ZAM_ExprType, returns the corresponding TypeInfo. -const TypeInfo& find_type_info(ZAM_ExprType et) - { - assert(et != ZAM_EXPR_TYPE_NONE); - - auto pred = [et](const TypeInfo& ti) -> bool - { - return ti.et == et; - }; - auto ti = std::find_if(ZAM_type_info.begin(), ZAM_type_info.end(), pred); - - assert(ti != ZAM_type_info.end()); - return *ti; - } - -// Given a ZAM_ExprType, return its ZVal accessor. Takes into account -// some naming inconsistencies between ZVal's and Val's. -string find_type_accessor(ZAM_ExprType et) - { - switch ( et ) - { - case ZAM_EXPR_TYPE_NONE: - return ""; - - case ZAM_EXPR_TYPE_UINT: - return "uint_val"; - - case ZAM_EXPR_TYPE_PATTERN: - return "re_val"; - - default: - { - string acc = find_type_info(et).accessor; - transform(acc.begin(), acc.end(), acc.begin(), ::tolower); - return acc + "_val"; - } - } - } - -// Maps ZAM operand types to pairs of (1) the C++ name used to declare -// the operand in a method declaration, and (2) the variable name to -// use for the operand. -unordered_map> ArgsManager::ot_to_args = { - {ZAM_OT_AUX, {"OpaqueVals*", "v"}}, - {ZAM_OT_CONSTANT, {"const ConstExpr*", "c"}}, - {ZAM_OT_EVENT_HANDLER, {"EventHandler*", "h"}}, - {ZAM_OT_INT, {"int", "i"}}, - {ZAM_OT_LIST, {"const ListExpr*", "l"}}, - {ZAM_OT_RECORD_FIELD, {"const NameExpr*", "n"}}, - {ZAM_OT_VAR, {"const NameExpr*", "n"}}, - - // The following gets special treatment. - {ZAM_OT_ASSIGN_FIELD, {"const NameExpr*", "n"}}, -}; - -ArgsManager::ArgsManager(const vector& ot, ZAM_InstClass zc) - { - int n = 0; - bool add_field = false; - - for ( const auto& ot_i : ot ) - { - if ( ot_i == ZAM_OT_NONE ) - { // it had better be the only operand type - assert(ot.size() == 1); - break; - } - - if ( n++ == 0 && zc == ZIC_COND ) - // Skip the conditional's nominal assignment slot. - continue; - - // Start off the argument info using the usual case - // of (1) same method parameter name as GenInst argument, - // and (2) not requiring a record field. - auto& arg_i = ot_to_args[ot_i]; - Arg arg = {arg_i.second, arg_i.first, arg_i.second, false}; - - if ( ot_i == ZAM_OT_ASSIGN_FIELD ) - { - arg.is_field = true; - - if ( n == 1 ) - { // special-case the parameter - arg.decl_name = "flhs"; - arg.decl_type = "const FieldLHSAssignExpr*"; - } - } - - args.emplace_back(move(arg)); - } - - Differentiate(); - } - -void ArgsManager::Differentiate() - { - // First, figure out which parameter names are used how often. - map name_count; // how often the name apepars - map usage_count; // how often the name's been used so far - for ( auto& arg : args ) - { - auto& name = arg.param_name; - if ( name_count.count(name) == 0 ) - { - name_count[name] = 1; - usage_count[name] = 0; - } - else - ++name_count[name]; - } - - // Now for each name - whether appearing as an argument or in - // a declaration - if it's used more than once, then differentiate - // it. Note, some names only appear multiple times as arguments - // when invoking methods, but not in the declarations of the methods - // themselves. - for ( auto& arg : args ) - { - auto& decl = arg.decl_name; - auto& name = arg.param_name; - bool decl_and_arg_same = decl == name; - - if ( name_count[name] == 1 ) - continue; // it's unique - - auto n = to_string(++usage_count[name]); - name += n; - if ( decl_and_arg_same ) - decl += n; - } - - // Finally, build the full versions of the declaration and parameters. - - // Tracks how many record fields we're dealing with. - int num_fields = 0; - - for ( auto& arg : args ) - { - if ( ! full_decl.empty() ) - full_decl += ", "; - - full_decl += arg.decl_type + " " + arg.decl_name; - - if ( ! full_params.empty() ) - full_params += ", "; - - full_params += arg.param_name; - params.push_back(arg.param_name); - - if ( arg.is_field ) - ++num_fields; - } - - assert(num_fields <= 2); - - // Add in additional arguments/parameters for record fields. - if ( num_fields == 1 ) - full_params += ", field"; - else if ( num_fields == 2 ) - { - full_decl += ", int field2"; - full_params += ", field1, field2"; - } - } - -ZAM_OpTemplate::ZAM_OpTemplate(ZAMGen* _g, string _base_name) : g(_g), base_name(move(_base_name)) - { - // Make the base name viable in a C++ name. - transform(base_name.begin(), base_name.end(), base_name.begin(), dash_to_under); - - cname = base_name; - transform(cname.begin(), cname.end(), cname.begin(), ::toupper); - } - -void ZAM_OpTemplate::Build() - { - op_loc = g->CurrLoc(); - - string line; - while ( g->ScanLine(line) ) - { - if ( line.size() <= 1 ) - break; - - auto words = g->SplitIntoWords(line); - if ( words.empty() ) - break; - - Parse(words[0], line, words); - } - } - -void ZAM_OpTemplate::Instantiate() - { - InstantiateOp(OperandTypes(), IncludesVectorOp()); - } - -void ZAM_OpTemplate::UnaryInstantiate() - { - // First operand is always the frame slot to which this operation - // assigns the result of the applying unary operator. - vector ots = {ZAM_OT_VAR}; - ots.resize(2); - - // Now build versions for a constant operand (maybe not actually - // needed due to constant folding, but sometimes that gets deferred - // to run-time) ... - if ( ! NoConst() ) - { - ots[1] = ZAM_OT_CONSTANT; - InstantiateOp(ots, IncludesVectorOp()); - } - - // ... and for a variable (frame-slot) operand. - ots[1] = ZAM_OT_VAR; - InstantiateOp(ots, IncludesVectorOp()); - } - -void ZAM_OpTemplate::Parse(const string& attr, const string& line, const Words& words) - { - int num_args = -1; // -1 = don't enforce - int nwords = words.size(); - - if ( attr == "type" ) - { - if ( nwords <= 1 ) - g->Gripe("missing argument", line); - - num_args = 1; - - const char* types = words[1].c_str(); - while ( *types ) - { - ZAM_OperandType ot = ZAM_OT_NONE; - switch ( *types ) - { - case 'C': - ot = ZAM_OT_CONSTANT; - break; - case 'F': - ot = ZAM_OT_ASSIGN_FIELD; - break; - case 'H': - ot = ZAM_OT_EVENT_HANDLER; - break; - case 'L': - ot = ZAM_OT_LIST; - break; - case 'O': - ot = ZAM_OT_AUX; - break; - case 'R': - ot = ZAM_OT_RECORD_FIELD; - break; - case 'V': - ot = ZAM_OT_VAR; - break; - case 'i': - ot = ZAM_OT_INT; - break; - - case 'X': - ot = ZAM_OT_NONE; - break; - - default: - g->Gripe("bad operand type", words[1]); - break; - } - - AddOpType(ot); - - ++types; - } - } - - else if ( attr == "op1-read" ) - { - num_args = 0; - SetOp1Flavor("OP1_READ"); - } - - else if ( attr == "op1-read-write" ) - { - num_args = 0; - SetOp1Flavor("OP1_READ_WRITE"); - } - - else if ( attr == "op1-internal" ) - { - num_args = 0; - SetOp1Flavor("OP1_INTERNAL"); - } - - else if ( attr == "set-type" ) - { - num_args = 1; - if ( nwords > 1 ) - SetTypeParam(ExtractTypeParam(words[1])); - } - - else if ( attr == "set-type2" ) - { - num_args = 1; - if ( nwords > 1 ) - SetType2Param(ExtractTypeParam(words[1])); - } - - else if ( attr == "custom-method" ) - SetCustomMethod(g->SkipWords(line, 1)); - - else if ( attr == "method-post" ) - SetPostMethod(g->SkipWords(line, 1)); - - else if ( attr == "side-effects" ) - { - if ( nwords == 3 ) - SetAssignmentLess(words[1], words[2]); - else - // otherwise shouldn't be any arguments - num_args = 0; - - SetHasSideEffects(); - } - - else if ( attr == "no-eval" ) - { - num_args = 0; - SetNoEval(); - } - - else if ( attr == "vector" ) - { - num_args = 0; - SetIncludesVectorOp(); - } - - else if ( attr == "assign-val" ) - { - num_args = 1; - if ( words.size() > 1 ) - SetAssignVal(words[1]); - } - - else if ( attr == "eval" ) - { - AddEval(g->SkipWords(line, 1)); - - auto addl = GatherEval(); - if ( ! addl.empty() ) - AddEval(addl); - } - - else if ( attr == "macro" ) - g->ReadMacro(line); - - else - g->Gripe("unknown template attribute", attr); - - if ( num_args >= 0 && num_args != nwords - 1 ) - g->Gripe("extraneous or missing arguments", line); - } - -string ZAM_OpTemplate::GatherEval() - { - string res; - string l; - while ( g->ScanLine(l) ) - { - if ( l.size() <= 1 || ! isspace(l.c_str()[0]) ) - { - g->PutBack(l); - return res; - } - - res += l; - } - - return res; - } - -int ZAM_OpTemplate::ExtractTypeParam(const string& arg) - { - if ( arg == "$$" ) - return 1; - - if ( arg[0] != '$' ) - g->Gripe("bad set-type parameter, should be $n", arg); - - int param = atoi(&arg[1]); - - if ( param <= 0 || param > 2 ) - g->Gripe("bad set-type parameter, should be $1 or $2", arg); - - // Convert operand to underlying instruction element, i.e., add - // one to account for the $$ assignment slot. - return param + 1; - } - -// Maps an operand type to a character mnemonic used to distinguish -// it from others. -unordered_map ZAM_OpTemplate::ot_to_char = { - {ZAM_OT_AUX, 'O'}, {ZAM_OT_CONSTANT, 'C'}, {ZAM_OT_EVENT_HANDLER, 'H'}, - {ZAM_OT_ASSIGN_FIELD, 'F'}, {ZAM_OT_INT, 'i'}, {ZAM_OT_LIST, 'L'}, - {ZAM_OT_NONE, 'X'}, {ZAM_OT_RECORD_FIELD, 'R'}, {ZAM_OT_VAR, 'V'}, -}; - -void ZAM_OpTemplate::InstantiateOp(const vector& ot, bool do_vec) - { - auto method = MethodName(ot); - - InstantiateOp(method, ot, ZIC_REGULAR); - - if ( IncludesFieldOp() ) - InstantiateOp(method, ot, ZIC_FIELD); - - if ( do_vec ) - InstantiateOp(method, ot, ZIC_VEC); - - if ( IsConditionalOp() ) - InstantiateOp(method, ot, ZIC_COND); - } - -void ZAM_OpTemplate::InstantiateOp(const string& method, const vector& ot, - ZAM_InstClass zc) - { - string suffix = ""; - - if ( zc == ZIC_FIELD ) - suffix = "_field"; - else if ( zc == ZIC_VEC ) - suffix = "_vec"; - else if ( zc == ZIC_COND ) - suffix = "_cond"; - - if ( ! IsInternalOp() ) - InstantiateMethod(method, suffix, ot, zc); - - if ( IsAssignOp() ) - InstantiateAssignOp(ot, suffix); - else - { - InstantiateEval(ot, suffix, zc); - - if ( HasAssignmentLess() ) - { - auto op_string = "_" + OpSuffix(ot); - auto op = g->GenOpCode(this, op_string); - GenAssignmentlessVersion(op); - } - } - } - -void ZAM_OpTemplate::GenAssignmentlessVersion(string op) - { - EmitTo(AssignFlavor); - Emit("assignmentless_op[" + op + "] = " + AssignmentLessOp() + ";"); - Emit("assignmentless_op_type[" + op + "] = " + AssignmentLessOpType() + ";"); - } - -void ZAM_OpTemplate::InstantiateMethod(const string& m, const string& suffix, - const vector& ot_orig, ZAM_InstClass zc) - { - if ( IsInternalOp() ) - return; - - auto ot = ot_orig; - if ( zc == ZIC_FIELD ) - // Need to make room for the field offset. - ot.emplace_back(ZAM_OT_INT); - - auto decls = MethodDeclare(ot, zc); - - EmitTo(MethodDecl); - Emit("const ZAMStmt " + m + suffix + "(" + decls + ");"); - - EmitTo(MethodDef); - Emit("const ZAMStmt ZAMCompiler::" + m + suffix + "(" + decls + ")"); - BeginBlock(); - - InstantiateMethodCore(ot, suffix, zc); - - if ( HasPostMethod() ) - Emit(GetPostMethod()); - - if ( ! HasCustomMethod() ) - Emit("return AddInst(z);"); - - EndBlock(); - NL(); - } - -void ZAM_OpTemplate::InstantiateMethodCore(const vector& ot, string suffix, - ZAM_InstClass zc) - { - if ( HasCustomMethod() ) - { - Emit(GetCustomMethod()); - return; - } - - assert(! ot.empty()); - - string full_suffix = "_" + OpSuffix(ot) + suffix; - - Emit("ZInstI z;"); - - if ( ot[0] == ZAM_OT_AUX ) - { - auto op = g->GenOpCode(this, full_suffix, zc); - Emit("z = ZInstI(" + op + ");"); - return; - } - - if ( ot[0] == ZAM_OT_NONE ) - { - auto op = g->GenOpCode(this, full_suffix, zc); - Emit("z = GenInst(" + op + ");"); - return; - } - - if ( ot.size() > 1 && ot[1] == ZAM_OT_AUX ) - { - auto op = g->GenOpCode(this, full_suffix, zc); - Emit("z = ZInstI(" + op + ", Frame1Slot(n, " + op + "));"); - return; - } - - ArgsManager args(ot, zc); - BuildInstruction(ot, args.Params(), full_suffix, zc); - - auto tp = GetTypeParam(); - if ( tp > 0 ) - Emit("z.SetType(" + args.NthParam(tp - 1) + "->GetType());"); - - auto tp2 = GetType2Param(); - if ( tp2 > 0 ) - Emit("z.t2 = " + args.NthParam(tp2 - 1) + "->GetType();"); - } - -void ZAM_OpTemplate::BuildInstruction(const vector& ot, const string& params, - const string& suffix, ZAM_InstClass zc) - { - auto op = g->GenOpCode(this, suffix, zc); - Emit("z = GenInst(" + op + ", " + params + ");"); - } - -void ZAM_OpTemplate::InstantiateEval(const vector& ot, const string& suffix, - ZAM_InstClass zc) - { - auto eval = GetEval(); - - if ( ot.size() > 1 ) - { // Check for use of "$1" to indicate the operand - string op1; - if ( ot[1] == ZAM_OT_CONSTANT ) - op1 = "z.c"; - else if ( ot[1] == ZAM_OT_VAR ) - op1 = "frame[z.v2]"; - - eval = regex_replace(eval, regex("\\$1"), op1); - } - - InstantiateEval(Eval, OpSuffix(ot) + suffix, eval, zc); - } - -void ZAM_OpTemplate::InstantiateEval(EmitTarget et, const string& op_suffix, const string& eval, - ZAM_InstClass zc) - { - auto op_code = g->GenOpCode(this, "_" + op_suffix, zc); - - EmitTo(et); - Emit("case " + op_code + ":"); - BeginBlock(); - Emit(eval); - EndBlock(); - EmitUp("break;"); - NL(); - } - -void ZAM_OpTemplate::InstantiateAssignOp(const vector& ot, const string& suffix) - { - // First, create a generic version of the operand, which the - // ZAM compiler uses to find specific-flavored versions. - auto op_string = "_" + OpSuffix(ot); - auto generic_op = g->GenOpCode(this, op_string); - auto flavor_ind = "assignment_flavor[" + generic_op + "]"; - - EmitTo(AssignFlavor); - Emit(flavor_ind + " = empty_map;"); - - auto eval = GetEval(); - auto v = GetAssignVal(); - - for ( auto& ti : ZAM_type_info ) - { - auto op = g->GenOpCode(this, op_string + "_" + ti.suffix); - - if ( IsInternalOp() ) - { - EmitTo(AssignFlavor); - Emit(flavor_ind + "[" + ti.tag + "] = " + op + ";"); - - if ( HasAssignmentLess() ) - GenAssignmentlessVersion(op); - } - - EmitTo(Eval); - Emit("case " + op + ":"); - BeginBlock(); - GenAssignOpCore(ot, eval, ti.accessor, ti.is_managed); - Emit("break;"); - EndBlock(); - } - } - -void ZAM_OpTemplate::GenAssignOpCore(const vector& ot, const string& eval, - const string& accessor, bool is_managed) - { - if ( HasAssignVal() ) - { - GenAssignOpValCore(eval, accessor, is_managed); - return; - } - - if ( ! eval.empty() ) - g->Gripe("assign-op should not have an \"eval\"", eval); - - auto lhs_field = (ot[0] == ZAM_OT_ASSIGN_FIELD); - auto rhs_field = lhs_field && ot.size() > 2 && (ot[2] == ZAM_OT_INT); - auto constant_op = (ot[1] == ZAM_OT_CONSTANT); - - string rhs = constant_op ? "z.c" : "frame[z.v2]"; - - auto acc = ".As" + accessor + "()"; - - if ( accessor == "Any" && constant_op && ! rhs_field ) - { - // "any_val = constant" or "x$any_val = constant". - // - // These require special-casing, because to avoid going - // through a CoerceToAny operation, we allow expressing - // these directly. They don't fit with the usual assignment - // paradigm since the RHS differs in type from the LHS. - Emit("auto v = z.c.ToVal(z.t);"); - - if ( lhs_field ) - { - Emit("auto r = frame[z.v1].AsRecord();"); - Emit("auto& f = r->RawField(z.v2);"); - } - else - Emit("auto& f = frame[z.v1];"); - - Emit("zeek::Unref(f.ManagedVal());"); - Emit("f = ZVal(v.release());"); - } - - else if ( rhs_field ) - { - // The following is counter-intuitive, but comes from the - // fact that we build out the instruction parameters as - // an echo of the method parameters, and for this case that - // means that the RHS field offset comes *before*, not after, - // the LHS field offset. - auto lhs_offset = constant_op ? 3 : 4; - auto rhs_offset = lhs_offset - 1; - - Emit("auto v = " + rhs + ".AsRecord()->RawOptField(z.v" + to_string(rhs_offset) + - "); // note, RHS field before LHS field"); - - Emit("if ( ! v )"); - BeginBlock(); - Emit("ZAM_run_time_error(z.loc, \"field value missing\");"); - Emit("break;"); - EndBlock(); - - auto slot = "z.v" + to_string(lhs_offset); - Emit("auto r = frame[z.v1].AsRecord();"); - Emit("auto& f = r->RawField(" + slot + "); // note, LHS field after RHS field"); - - if ( is_managed ) - { - Emit("zeek::Ref((*v)" + acc + ");"); - Emit("zeek::Unref(f.ManagedVal());"); - } - - Emit("f = *v;"); - } - - else - { - if ( is_managed ) - Emit("zeek::Ref(" + rhs + acc + ");"); - - if ( lhs_field ) - { - auto lhs_offset = constant_op ? 2 : 3; - auto slot = "z.v" + to_string(lhs_offset); - Emit("auto r = frame[z.v1].AsRecord();"); - Emit("auto& f = r->RawField(" + slot + ");"); - - if ( is_managed ) - Emit("zeek::Unref(f.ManagedVal());"); - - Emit("f = " + rhs + ";"); - } - - else - { - if ( is_managed ) - Emit("zeek::Unref(frame[z.v1].ManagedVal());"); - - Emit("frame[z.v1] = ZVal(" + rhs + acc + ");"); - } - } - - if ( lhs_field ) - Emit("r->Modified();"); - } - -void ZAM_OpTemplate::GenAssignOpValCore(const string& eval, const string& accessor, bool is_managed) - { - auto v = GetAssignVal(); - - Emit(eval); - - // Maps Zeek types to how to get the underlying value from a ValPtr. - static unordered_map val_accessors = { - {"Addr", "->AsAddrVal()"}, {"Any", ".get()"}, - {"Count", "->AsCount()"}, {"Double", "->AsDouble()"}, - {"Int", "->AsInt()"}, {"Pattern", "->AsPatternVal()"}, - {"String", "->AsStringVal()"}, {"SubNet", "->AsSubNetVal()"}, - {"Table", "->AsTableVal()"}, {"Vector", "->AsVectorVal()"}, - {"File", "->AsFile()"}, {"Func", "->AsFunc()"}, - {"List", "->AsListVal()"}, {"Opaque", "->AsOpaqueVal()"}, - {"Record", "->AsRecordVal()"}, {"Type", "->AsTypeVal()"}, - }; - - auto val_accessor = val_accessors[accessor]; - - string rhs; - if ( IsInternalOp() ) - rhs = v + val_accessor; - else - rhs = v + ".As" + accessor + "()"; - - if ( is_managed ) - { - Emit("auto rhs = " + rhs + ";"); - Emit("zeek::Ref(rhs);"); - Emit("Unref(frame[z.v1].ManagedVal());"); - Emit("frame[z.v1] = ZVal(rhs);"); - } - else - Emit("frame[z.v1] = ZVal(" + rhs + ");"); - } - -string ZAM_OpTemplate::MethodName(const vector& ot) const - { - return base_name + OpSuffix(ot); - } - -string ZAM_OpTemplate::MethodDeclare(const vector& ot, ZAM_InstClass zc) - { - ArgsManager args(ot, zc); - return args.Decls(); - } - -string ZAM_OpTemplate::OpSuffix(const vector& ot) const - { - string os; - for ( auto& o : ot ) - os += ot_to_char[o]; - return os; - } - -string ZAM_OpTemplate::SkipWS(const string& s) const - { - auto sp = s.c_str(); - while ( *sp && isspace(*sp) ) - ++sp; - - return sp; - } - -void ZAM_OpTemplate::Emit(const string& s) - { - g->Emit(curr_et, s); - } - -void ZAM_OpTemplate::EmitNoNL(const string& s) - { - g->SetNoNL(true); - Emit(s); - g->SetNoNL(false); - } - -void ZAM_OpTemplate::IndentUp() - { - g->IndentUp(); - } - -void ZAM_OpTemplate::IndentDown() - { - g->IndentDown(); - } - -void ZAM_UnaryOpTemplate::Instantiate() - { - UnaryInstantiate(); - } - -void ZAM_DirectUnaryOpTemplate::Instantiate() - { - EmitTo(DirectDef); - Emit("case EXPR_" + cname + ":\treturn " + direct + "(lhs, rhs);"); - } - -// Maps op-type mnemonics to the corresponding internal value used by Gen-ZAM. -static unordered_map expr_type_names = { - {'*', ZAM_EXPR_TYPE_DEFAULT}, {'A', ZAM_EXPR_TYPE_ADDR}, {'a', ZAM_EXPR_TYPE_ANY}, - {'D', ZAM_EXPR_TYPE_DOUBLE}, {'f', ZAM_EXPR_TYPE_FILE}, {'F', ZAM_EXPR_TYPE_FUNC}, - {'I', ZAM_EXPR_TYPE_INT}, {'L', ZAM_EXPR_TYPE_LIST}, {'X', ZAM_EXPR_TYPE_NONE}, - {'O', ZAM_EXPR_TYPE_OPAQUE}, {'P', ZAM_EXPR_TYPE_PATTERN}, {'R', ZAM_EXPR_TYPE_RECORD}, - {'S', ZAM_EXPR_TYPE_STRING}, {'N', ZAM_EXPR_TYPE_SUBNET}, {'T', ZAM_EXPR_TYPE_TABLE}, - {'t', ZAM_EXPR_TYPE_TYPE}, {'U', ZAM_EXPR_TYPE_UINT}, {'V', ZAM_EXPR_TYPE_VECTOR}, -}; - -// Inverse of the above. -static unordered_map expr_name_types; - -ZAM_ExprOpTemplate::ZAM_ExprOpTemplate(ZAMGen* _g, string _base_name) - : ZAM_OpTemplate(_g, _base_name) - { - static bool did_map_init = false; - - if ( ! did_map_init ) - { // Create the inverse mapping. - for ( auto& tn : expr_type_names ) - expr_name_types[tn.second] = tn.first; - - did_map_init = true; - } - } - -void ZAM_ExprOpTemplate::Parse(const string& attr, const string& line, const Words& words) - { - if ( attr == "op-type" ) - { - if ( words.size() == 1 ) - g->Gripe("op-type needs arguments", line); - - for ( auto i = 1U; i < words.size(); ++i ) - { - auto& w_i = words[i]; - if ( w_i.size() != 1 ) - g->Gripe("bad op-type argument", w_i); - - auto et_c = w_i.c_str()[0]; - if ( expr_type_names.count(et_c) == 0 ) - g->Gripe("bad op-type argument", w_i); - - AddExprType(expr_type_names[et_c]); - } - } - - else if ( attr == "includes-field-op" ) - { - if ( words.size() != 1 ) - g->Gripe("includes-field-op does not take any arguments", line); - - SetIncludesFieldOp(); - } - - else if ( attr == "eval-type" ) - { - if ( words.size() < 3 ) - g->Gripe("eval-type needs type and evaluation", line); - - auto& type = words[1]; - if ( type.size() != 1 ) - g->Gripe("bad eval-type type", type); - - auto type_c = type.c_str()[0]; - if ( expr_type_names.count(type_c) == 0 ) - g->Gripe("bad eval-type type", type); - - auto et = expr_type_names[type_c]; - - if ( expr_types.count(et) == 0 ) - g->Gripe("eval-type type not present in eval-type", type); - - auto eval = g->SkipWords(line, 2); - eval += GatherEval(); - AddEvalSet(et, eval); - } - - else if ( attr == "eval-mixed" ) - { - if ( words.size() < 4 ) - g->Gripe("eval-mixed needs types and evaluation", line); - - auto& type1 = words[1]; - auto& type2 = words[2]; - if ( type1.size() != 1 || type2.size() != 1 ) - g->Gripe("bad eval-mixed types", line); - - auto type_c1 = type1.c_str()[0]; - auto type_c2 = type2.c_str()[0]; - if ( expr_type_names.count(type_c1) == 0 || expr_type_names.count(type_c2) == 0 ) - g->Gripe("bad eval-mixed types", line); - - auto et1 = expr_type_names[type_c1]; - auto et2 = expr_type_names[type_c2]; - - if ( eval_set.count(et1) > 0 ) - g->Gripe("eval-mixed uses type also included in op-type", line); - - auto eval = g->SkipWords(line, 3); - eval += GatherEval(); - AddEvalSet(et1, et2, eval); - } - - else if ( attr == "eval-pre" ) - { - if ( words.size() < 2 ) - g->Gripe("eval-pre needs evaluation", line); - - auto eval = g->SkipWords(line, 1); - eval += GatherEval(); - - SetPreEval(eval); - } - - else - // Not an attribute specific to expr-op's. - ZAM_OpTemplate::Parse(attr, line, words); - } - -void ZAM_ExprOpTemplate::Instantiate() - { - InstantiateOp(OperandTypes(), IncludesVectorOp()); - - if ( op_types.size() > 1 && op_types[1] == ZAM_OT_CONSTANT ) - InstantiateC1(op_types, op_types.size() - 1); - if ( op_types.size() > 2 && op_types[2] == ZAM_OT_CONSTANT ) - InstantiateC2(op_types, op_types.size() - 1); - if ( op_types.size() > 3 && op_types[3] == ZAM_OT_CONSTANT ) - InstantiateC3(op_types); - - bool all_var = true; - for ( auto i = 1U; i < op_types.size(); ++i ) - if ( op_types[i] != ZAM_OT_VAR ) - all_var = false; - - if ( all_var ) - InstantiateV(op_types); - - if ( op_types.size() == 3 && op_types[1] == ZAM_OT_RECORD_FIELD && op_types[2] == ZAM_OT_INT ) - InstantiateV(op_types); - } - -void ZAM_ExprOpTemplate::InstantiateC1(const vector& ots, int arity, bool do_vec) - { - string args = "lhs, r1->AsConstExpr()"; - - if ( arity == 1 && ots[0] == ZAM_OT_RECORD_FIELD ) - args += ", rhs->AsFieldExpr()->Field()"; - - else if ( arity > 1 ) - { - args += ", "; - - if ( ots[2] == ZAM_OT_RECORD_FIELD ) - args += "rhs->AsFieldExpr()->Field()"; - else - args += "r2->AsNameExpr()"; - } - - auto m = MethodName(ots); - - EmitTo(C1Def); - - EmitNoNL("case EXPR_" + cname + ":"); - - if ( do_vec ) - DoVectorCase(m, args); - else - EmitUp("return " + m + "(" + args + ");"); - - if ( IncludesFieldOp() ) - { - EmitTo(C1FieldDef); - Emit("case EXPR_" + cname + ":\treturn " + m + "_field(" + args + ", field);"); - } - } - -void ZAM_ExprOpTemplate::InstantiateC2(const vector& ots, int arity) - { - string args = "lhs, r1->AsNameExpr(), r2->AsConstExpr()"; - - if ( arity == 3 ) - args += ", r3->AsNameExpr()"; - - auto method = MethodName(ots); - auto m = method.c_str(); - - EmitTo(C2Def); - Emit("case EXPR_" + cname + ":\treturn " + m + "(" + args + ");"); - - if ( IncludesFieldOp() ) - { - EmitTo(C2FieldDef); - Emit("case EXPR_" + cname + ":\treturn " + m + "_field(" + args + ", field);"); - } - } - -void ZAM_ExprOpTemplate::InstantiateC3(const vector& ots) - { - EmitTo(C3Def); - Emit("case EXPR_" + cname + ":\treturn " + MethodName(ots) + - "(lhs, r1->AsNameExpr(), r2->AsNameExpr(), r3->AsConstExpr());"); - } - -void ZAM_ExprOpTemplate::InstantiateV(const vector& ots) - { - auto m = MethodName(ots); - - string args = "lhs, r1->AsNameExpr()"; - - if ( ots.size() >= 3 ) - { - if ( ots[2] == ZAM_OT_INT ) - { - string acc_flav = IncludesFieldOp() ? "Has" : ""; - args += ", rhs->As" + acc_flav + "FieldExpr()->Field()"; - } - else - args += ", r2->AsNameExpr()"; - - if ( ots.size() == 4 ) - args += ", r3->AsNameExpr()"; - } - - EmitTo(VDef); - EmitNoNL("case EXPR_" + cname + ":"); - - if ( IncludesVectorOp() ) - DoVectorCase(m, args); - else - EmitUp("return " + m + "(" + args + ");"); - - if ( IncludesFieldOp() ) - { - EmitTo(VFieldDef); - Emit("case EXPR_" + cname + ":\treturn " + m + "_field(" + args + ", field);"); - } - } - -void ZAM_ExprOpTemplate::DoVectorCase(const string& m, const string& args) - { - NL(); - IndentUp(); - Emit("if ( rt->Tag() == TYPE_VECTOR )"); - EmitUp("return " + m + "_vec(" + args + ");"); - Emit("else"); - EmitUp("return " + m + "(" + args + ");"); - IndentDown(); - } - -void ZAM_ExprOpTemplate::BuildInstructionCore(const string& params, const string& suffix, - ZAM_InstClass zc) - { - Emit("auto tag = t->Tag();"); - Emit("auto i_t = t->InternalType();"); - - int ncases = 0; - - for ( auto& [et1, et2_map] : eval_mixed_set ) - for ( auto& [et2, eval] : et2_map ) - GenMethodTest(et1, et2, params, suffix, ++ncases > 1, zc); - - bool do_default = false; - - for ( auto et : ExprTypes() ) - { - if ( et == ZAM_EXPR_TYPE_DEFAULT ) - do_default = true; - else - GenMethodTest(et, et, params, suffix, ++ncases > 1, zc); - } - - Emit("else"); - - if ( do_default ) - { - auto op = g->GenOpCode(this, suffix, zc); - EmitUp("z = GenInst(" + op + ", " + params + ");"); - } - - else - EmitUp("reporter->InternalError(\"bad tag when generating method core\");"); - } - -void ZAM_ExprOpTemplate::GenMethodTest(ZAM_ExprType et1, ZAM_ExprType et2, const string& params, - const string& suffix, bool do_else, ZAM_InstClass zc) - { - // Maps ZAM_ExprType's to the information needed (variable name, - // constant to compare it against) to identify using an "if" test - // that a given AST Expr node employs the given type of operand. - static map> if_tests = { - {ZAM_EXPR_TYPE_ADDR, {"i_t", "TYPE_INTERNAL_ADDR"}}, - {ZAM_EXPR_TYPE_ANY, {"tag", "TYPE_ANY"}}, - {ZAM_EXPR_TYPE_DOUBLE, {"i_t", "TYPE_INTERNAL_DOUBLE"}}, - {ZAM_EXPR_TYPE_FILE, {"tag", "TYPE_FILE"}}, - {ZAM_EXPR_TYPE_FUNC, {"tag", "TYPE_FUNC"}}, - {ZAM_EXPR_TYPE_INT, {"i_t", "TYPE_INTERNAL_INT"}}, - {ZAM_EXPR_TYPE_LIST, {"tag", "TYPE_LIST"}}, - {ZAM_EXPR_TYPE_OPAQUE, {"tag", "TYPE_OPAQUE"}}, - {ZAM_EXPR_TYPE_PATTERN, {"tag", "TYPE_PATTERN"}}, - {ZAM_EXPR_TYPE_RECORD, {"tag", "TYPE_RECORD"}}, - {ZAM_EXPR_TYPE_STRING, {"i_t", "TYPE_INTERNAL_STRING"}}, - {ZAM_EXPR_TYPE_SUBNET, {"i_t", "TYPE_INTERNAL_SUBNET"}}, - {ZAM_EXPR_TYPE_TABLE, {"tag", "TYPE_TABLE"}}, - {ZAM_EXPR_TYPE_TYPE, {"tag", "TYPE_TYPE"}}, - {ZAM_EXPR_TYPE_UINT, {"i_t", "TYPE_INTERNAL_UNSIGNED"}}, - {ZAM_EXPR_TYPE_VECTOR, {"tag", "TYPE_VECTOR"}}, - }; - - if ( if_tests.count(et1) == 0 ) - g->Gripe("bad op-type", op_loc); - - auto if_test = if_tests[et1]; - auto if_var = if_test.first; - auto if_val = if_test.second; - - string test = "if ( " + if_var + " == " + if_val + " )"; - if ( do_else ) - test = "else " + test; - - Emit(test); - - auto op_suffix = suffix + "_" + expr_name_types[et1]; - if ( et2 != et1 ) - op_suffix += expr_name_types[et2]; - - auto op = g->GenOpCode(this, op_suffix, zc); - EmitUp("z = GenInst(" + op + ", " + params + ");"); - } - -EvalInstance::EvalInstance(ZAM_ExprType _lhs_et, ZAM_ExprType _op1_et, ZAM_ExprType _op2_et, - string _eval, bool _is_def) - { - lhs_et = _lhs_et; - op1_et = _op1_et; - op2_et = _op2_et; - eval = move(_eval); - is_def = _is_def; - } - -string EvalInstance::LHSAccessor(bool is_ptr) const - { - if ( lhs_et == ZAM_EXPR_TYPE_NONE || lhs_et == ZAM_EXPR_TYPE_DEFAULT ) - return ""; - - string deref = is_ptr ? "->" : "."; - string acc = find_type_accessor(lhs_et); - - return deref + acc; - } - -string EvalInstance::Accessor(ZAM_ExprType et, bool is_ptr) const - { - if ( et == ZAM_EXPR_TYPE_NONE || et == ZAM_EXPR_TYPE_DEFAULT ) - return ""; - - string deref = is_ptr ? "->" : "."; - return deref + "As" + find_type_info(et).accessor + "()"; - } - -string EvalInstance::OpMarker() const - { - if ( op1_et == ZAM_EXPR_TYPE_DEFAULT || op1_et == ZAM_EXPR_TYPE_NONE ) - return ""; - - if ( op1_et == op2_et ) - return "_" + find_type_info(op1_et).suffix; - - return "_" + find_type_info(op1_et).suffix + find_type_info(op2_et).suffix; - } - -void ZAM_ExprOpTemplate::InstantiateEval(const vector& ot_orig, - const string& suffix, ZAM_InstClass zc) - { - if ( expr_types.empty() ) - { // No operand types to expand over. - ZAM_OpTemplate::InstantiateEval(ot_orig, suffix, zc); - return; - } - - auto ot = ot_orig; - if ( zc == ZIC_FIELD ) - // Make room for the offset. - ot.emplace_back(ZAM_OT_INT); - - auto ot_str = OpSuffix(ot); - - // Some of these might not wind up being used, but no harm in - // initializing them in case they are. - string lhs, op1, op2; - string branch_target = "z.v"; - - EmitTarget emit_target = Eval; - - if ( zc == ZIC_VEC ) - { - lhs = "vec1[i]"; - op1 = "vec2[i]"; - op2 = "vec3[i]"; - - emit_target = Arity() == 1 ? Vec1Eval : Vec2Eval; - } - - else - { - lhs = "frame[z.v1]"; - - auto op1_offset = zc == ZIC_COND ? 1 : 2; - auto op2_offset = op1_offset + 1; - bool ot1_const = ot[1] == ZAM_OT_CONSTANT; - bool ot2_const = Arity() >= 2 && ot[2] == ZAM_OT_CONSTANT; - - if ( ot1_const ) - { - op1 = "z.c"; - --op2_offset; - branch_target += "2"; - } - else - { - op1 = "frame[z.v" + to_string(op1_offset) + "]"; - - if ( Arity() > 1 && ot[2] == ZAM_OT_VAR ) - branch_target += "3"; - else - branch_target += "2"; - } - - if ( ot2_const ) - op2 = "z.c"; - else - op2 = "frame[z.v" + to_string(op2_offset) + "]"; - - if ( zc == ZIC_FIELD ) - { - // Compute the slot holding the field offset. - - auto f = - // The first slots are taken up by the - // assignment slot and the operands ... - Arity() + 1 + - // ... and slots are numbered starting at 1. - +1; - - if ( ot1_const || ot2_const ) - // One of the operand slots won't be needed - // due to the presence of a constant. - // (It's never the case that both operands - // are constants - those instead get folded.) - --f; - - lhs += ".AsRecord()->RawField(z.v" + to_string(f) + ")"; - } - } - - vector eval_instances; - - for ( auto et : expr_types ) - { - auto is_def = eval_set.count(et) == 0; - string eval = is_def ? GetEval() : eval_set[et]; - auto lhs_et = IsConditionalOp() ? ZAM_EXPR_TYPE_INT : et; - eval_instances.emplace_back(lhs_et, et, et, eval, is_def); - } - - if ( zc != ZIC_VEC ) - for ( auto em1 : eval_mixed_set ) - { - auto et1 = em1.first; - for ( auto em2 : em1.second ) - { - auto et2 = em2.first; - - // For the LHS, either its expression type is - // ignored, or if it's a conditional, so just - // note it for the latter. - auto lhs_et = ZAM_EXPR_TYPE_INT; - eval_instances.emplace_back(lhs_et, et1, et2, em2.second, false); - } - } - - for ( auto& ei : eval_instances ) - { - auto lhs_accessor = ei.LHSAccessor(); - if ( HasExplicitResultType() ) - lhs_accessor = ""; - - string lhs_ei = lhs; - if ( zc != ZIC_VEC ) - lhs_ei += lhs_accessor; - - auto op1_ei = op1 + ei.Op1Accessor(zc == ZIC_VEC); - auto op2_ei = op2 + ei.Op2Accessor(zc == ZIC_VEC); - - auto eval = SkipWS(ei.Eval()); - - auto has_target = eval.find("$$") != string::npos; - - if ( zc == ZIC_VEC ) - { - const char* rhs; - if ( has_target ) - rhs = "\\$\\$ = ([^;\n]*)"; - else - rhs = "^[^;\n]*"; - - auto replacement = VecEvalRE(has_target); - - eval = regex_replace(eval, regex(rhs), replacement); - } - - auto is_none = ei.LHS_ET() == ZAM_EXPR_TYPE_NONE; - auto is_default = ei.LHS_ET() == ZAM_EXPR_TYPE_DEFAULT; - - if ( ! is_none && ! is_default && find_type_info(ei.LHS_ET()).is_managed && - ! HasExplicitResultType() ) - { - auto delim = zc == ZIC_VEC ? "->" : "."; - auto pre = "auto hold_lhs = " + lhs + delim + "ManagedVal();\n\t"; - auto post = "\tUnref(hold_lhs);"; - eval = pre + eval + post; - } - - eval = regex_replace(eval, regex("\\$1"), op1_ei); - eval = regex_replace(eval, regex("\\$2"), op2_ei); - - string pre = GetPreEval(); - pre = regex_replace(pre, regex("\\$1"), op1_ei); - pre = regex_replace(pre, regex("\\$2"), op2_ei); - - if ( has_target ) - eval = regex_replace(eval, regex("\\$\\$"), lhs_ei); - - else if ( zc == ZIC_COND ) - { // Aesthetics: get rid of trailing newlines. - eval = regex_replace(eval, regex("\n"), ""); - eval = "if ( ! (" + eval + ") ) " + "{ pc = " + branch_target + "; continue; }"; - } - - else if ( ! is_none && (ei.IsDefault() || IsConditionalOp()) ) - { - eval = lhs_ei + " = " + eval; - - // Ensure a single terminating semicolon. - eval = regex_replace(eval, regex(";*\n"), ";\n"); - } - - eval = pre + eval; - - auto full_suffix = ot_str + suffix + ei.OpMarker(); - - ZAM_OpTemplate::InstantiateEval(emit_target, full_suffix, eval, zc); - - if ( zc == ZIC_VEC ) - { - string dispatch_params = "frame[z.v1].AsVectorRef(), frame[z.v2].AsVector()"; - - if ( Arity() == 2 ) - dispatch_params += ", frame[z.v3].AsVector()"; - - auto op_code = g->GenOpCode(this, "_" + full_suffix); - auto dispatch = "vec_exec(" + op_code + ", z.t, " + dispatch_params + ", z);"; - - ZAM_OpTemplate::InstantiateEval(Eval, full_suffix, dispatch, zc); - } - } - } - -void ZAM_UnaryExprOpTemplate::Parse(const string& attr, const string& line, const Words& words) - { - if ( attr == "no-const" ) - { - if ( words.size() != 1 ) - g->Gripe("extraneous argument to no-const", line); - - SetNoConst(); - } - - else if ( attr == "explicit-result-type" ) - { - if ( words.size() != 1 ) - g->Gripe("extraneous argument to explicit-result-type", line); - SetHasExplicitResultType(); - } - - else - ZAM_ExprOpTemplate::Parse(attr, line, words); - } - -void ZAM_UnaryExprOpTemplate::Instantiate() - { - UnaryInstantiate(); - - vector ots = {ZAM_OT_VAR, ZAM_OT_CONSTANT}; - - if ( ! NoConst() ) - InstantiateC1(ots, 1, IncludesVectorOp()); - - ots[1] = ZAM_OT_VAR; - InstantiateV(ots); - } - -void ZAM_UnaryExprOpTemplate::BuildInstruction(const vector& ot, - const string& params, const string& suffix, - ZAM_InstClass zc) - { - const auto& ets = ExprTypes(); - - if ( ets.size() == 1 && ets.count(ZAM_EXPR_TYPE_NONE) == 1 ) - { - ZAM_ExprOpTemplate::BuildInstruction(ot, params, suffix, zc); - return; - } - - auto constant_op = ot[1] == ZAM_OT_CONSTANT; - string type_src = constant_op ? "c" : "n2"; - - if ( ot[0] == ZAM_OT_ASSIGN_FIELD ) - { - type_src = constant_op ? "n" : "n1"; - Emit("auto " + type_src + " = flhs->GetOp1()->AsNameExpr();"); - Emit("auto t = flhs->GetType();"); - Emit("int field = flhs->Field();"); - } - - else - { - if ( IsAssignOp() ) - type_src = constant_op ? "n" : "n1"; - - auto type_suffix = zc == ZIC_VEC ? "->Yield();" : ";"; - Emit("auto t = " + type_src + "->GetType()" + type_suffix); - } - - BuildInstructionCore(params, suffix, zc); - - if ( IsAssignOp() && IsFieldOp() ) - // These can't take the type from the LHS variable, since - // that's the enclosing record and not the field within it. - Emit("z.t = t;"); - - else if ( zc == ZIC_VEC ) - { - if ( constant_op ) - Emit("z.t = n->GetType();"); - else - Emit("z.t = n1->GetType();"); - } - } - -ZAM_AssignOpTemplate::ZAM_AssignOpTemplate(ZAMGen* _g, string _base_name) - : ZAM_UnaryExprOpTemplate(_g, _base_name) - { - // Assignments apply to every valid form of ExprType. - for ( auto& etn : expr_type_names ) - { - auto et = etn.second; - if ( et != ZAM_EXPR_TYPE_NONE && et != ZAM_EXPR_TYPE_DEFAULT ) - AddExprType(et); - } - } - -void ZAM_AssignOpTemplate::Parse(const string& attr, const string& line, const Words& words) - { - if ( attr == "field-op" ) - { - if ( words.size() != 1 ) - g->Gripe("field-op does not take any arguments", line); - - SetFieldOp(); - } - - else - ZAM_OpTemplate::Parse(attr, line, words); - } - -void ZAM_AssignOpTemplate::Instantiate() - { - if ( op_types.size() != 1 ) - g->Gripe("operation needs precisely one \"type\"", op_loc); - - vector ots; - ots.push_back(op_types[0]); - - // Build constant/variable versions ... - ots.push_back(ZAM_OT_CONSTANT); - - if ( ots[0] == ZAM_OT_RECORD_FIELD ) - ots.push_back(ZAM_OT_INT); - - InstantiateOp(ots, false); - if ( IsFieldOp() ) - InstantiateC1(ots, 1); - - ots[1] = ZAM_OT_VAR; - InstantiateOp(ots, false); - - // ... and for assignments to fields, additional field versions. - if ( ots[0] == ZAM_OT_ASSIGN_FIELD ) - { - ots.push_back(ZAM_OT_INT); - InstantiateOp(ots, false); - - ots[1] = ZAM_OT_CONSTANT; - InstantiateOp(ots, false); - } - - else if ( IsFieldOp() ) - InstantiateV(ots); - } - -void ZAM_BinaryExprOpTemplate::Instantiate() - { - // As usual, the first slot receives the operator's result. - vector ots = {ZAM_OT_VAR}; - ots.resize(3); - - // Build each combination for constant/variable operand, - // except skip constant/constant as that is always folded. - - // We only include vector operations when both operands - // are non-constants. - - ots[1] = ZAM_OT_CONSTANT; - ots[2] = ZAM_OT_VAR; - InstantiateOp(ots, false); - - if ( ! IsInternalOp() ) - InstantiateC1(ots, 2, false); - - ots[1] = ZAM_OT_VAR; - ots[2] = ZAM_OT_CONSTANT; - InstantiateOp(ots, false); - - if ( ! IsInternalOp() ) - InstantiateC2(ots, 2); - - ots[2] = ZAM_OT_VAR; - InstantiateOp(ots, IncludesVectorOp()); - - if ( ! IsInternalOp() ) - InstantiateV(ots); - } - -void ZAM_BinaryExprOpTemplate::BuildInstruction(const vector& ot, - const string& params, const string& suffix, - ZAM_InstClass zc) - { - auto constant_op = ot[1] == ZAM_OT_CONSTANT; - string type_src = constant_op ? "c" : "n2"; - auto type_suffix = zc == ZIC_VEC ? "->Yield();" : ";"; - Emit("auto t = " + type_src + "->GetType()" + type_suffix); - BuildInstructionCore(params, suffix, zc); - - if ( zc == ZIC_VEC ) - Emit("z.t = n1->GetType();"); - } - -void ZAM_RelationalExprOpTemplate::Instantiate() - { - ZAM_BinaryExprOpTemplate::Instantiate(); - - EmitTo(Cond); - - Emit("case EXPR_" + cname + ":"); - IndentUp(); - Emit("if ( n1 && n2 )"); - EmitUp("return " + cname + "VVV_cond(n1, n2);"); - Emit("else if ( n1 )"); - EmitUp("return " + cname + "VVC_cond(n1, c);"); - Emit("else"); - EmitUp("return " + cname + "VCV_cond(c, n2);"); - IndentDown(); - NL(); - } - -void ZAM_RelationalExprOpTemplate::BuildInstruction(const vector& ot, - const string& params, const string& suffix, - ZAM_InstClass zc) - { - string op1; - - if ( zc == ZIC_COND ) - { - if ( ot[1] == ZAM_OT_CONSTANT ) - op1 = "c"; - else if ( ot[2] == ZAM_OT_CONSTANT ) - op1 = "n"; - else - op1 = "n1"; - } - else - op1 = "n2"; - - auto type_suffix = zc == ZIC_VEC ? "->Yield();" : ";"; - Emit("auto t = " + op1 + "->GetType()" + type_suffix); - BuildInstructionCore(params, suffix, zc); - - if ( zc == ZIC_VEC ) - Emit("z.t = n1->GetType();"); - } - -void ZAM_InternalBinaryOpTemplate::Parse(const string& attr, const string& line, const Words& words) - { - if ( attr == "op-accessor" ) - { - if ( words.size() != 2 ) - g->Gripe("op-accessor takes one argument", line); - - SetOpAccessor(words[1]); - } - - else if ( attr == "op1-accessor" ) - { - if ( words.size() != 2 ) - g->Gripe("op-accessor1 takes one argument", line); - - SetOp1Accessor(words[1]); - } - - else if ( attr == "op2-accessor" ) - { - if ( words.size() != 2 ) - g->Gripe("op-accessor2 takes one argument", line); - - SetOp2Accessor(words[1]); - } - - else - ZAM_BinaryExprOpTemplate::Parse(attr, line, words); - } - -void ZAM_InternalBinaryOpTemplate::InstantiateEval(const vector& ot, - const string& suffix, ZAM_InstClass zc) - { - assert(ot.size() == 3); - - auto op1_const = ot[1] == ZAM_OT_CONSTANT; - auto op2_const = ot[2] == ZAM_OT_CONSTANT; - - string op1 = op1_const ? "z.c" : "frame[z.v2]"; - string op2 = op2_const ? "z.c" : (op1_const ? "frame[z.v2]" : "frame[z.v3]"); - - string prelude = "auto op1 = " + op1 + "." + op1_accessor + ";\n"; - prelude += "auto op2 = " + op2 + "." + op2_accessor + ";\n"; - - auto eval = prelude + GetEval(); - - auto& ets = ExprTypes(); - if ( ! ets.empty() ) - { - if ( ets.size() != 1 ) - g->Gripe("internal-binary-op's can have at most one op-type", op_loc); - - for ( auto& et : ets ) - { - auto acc = find_type_accessor(et); - auto lhs = "frame[z.v1]." + acc; - eval = regex_replace(eval, regex("\\$\\$"), lhs); - } - } - - ZAM_OpTemplate::InstantiateEval(Eval, OpSuffix(ot) + suffix, eval, zc); - } - -void ZAM_InternalOpTemplate::Parse(const string& attr, const string& line, const Words& words) - { - if ( attr != "num-call-args" ) - { - if ( attr == "indirect-call" ) - { - if ( words.size() != 1 ) - g->Gripe("indirect-call takes one argument", line); - // Note, currently only works with a *subsequent* - // num-call-args, whose setting needs to be 'n'. - is_indirect_call = true; - } - else - ZAM_OpTemplate::Parse(attr, line, words); - - return; - } - - if ( words.size() != 2 ) - g->Gripe("num-call-args takes one argument", line); - - eval = "std::vector args;\n"; - - auto& arg = words[1]; - int n = arg == "n" ? -1 : stoi(arg); - - auto arg_offset = HasAssignVal() ? 1 : 0; - auto arg_slot = arg_offset + 1; - - string func = "z.func"; - - if ( n == 1 ) - { - eval += "args.push_back("; - if ( op_types[arg_offset] == ZAM_OT_CONSTANT ) - eval += "z.c"; - else - eval += "frame[z.v" + to_string(arg_slot) + "]"; - - eval += ".ToVal(z.t));\n"; - } - - else if ( n != 0 ) - { - eval += "auto aux = z.aux;\n"; - - if ( n < 0 ) - { - if ( is_indirect_call ) - { - func = "func"; - - eval += "auto sel = z.v" + to_string(arg_slot) + ";\n"; - eval += "auto func = (sel < 0) ? "; - eval += "aux->id_val->GetVal()->AsFunc() : "; - eval += "frame[sel].AsFunc();\n"; - } - - eval += "auto n = aux->n;\n"; - eval += "for ( auto i = 0; i < n; ++i )\n"; - eval += "\targs.push_back(aux->ToVal(frame, i));\n"; - } - - else - for ( auto i = 0; i < n; ++i ) - { - eval += "args.push_back(aux->ToVal(frame, "; - eval += to_string(i); - eval += "));\n"; - } - } - - eval += "f->SetCallLoc(z.loc);\n"; - - if ( HasAssignVal() ) - { - auto av = GetAssignVal(); - eval += "auto " + av + " = " + func + "->Invoke(&args, f);\n"; - eval += "if ( ! " + av + " ) { ZAM_error = true; break; }\n"; - } - else - eval += "(void) " + func + "->Invoke(&args, f);\n"; - } - -bool TemplateInput::ScanLine(string& line) - { - if ( ! put_back.empty() ) - { - line = put_back; - put_back.clear(); - return true; - } - - char buf[8192]; - - // Read lines, discarding comments, which have to start at the - // beginning of a line. - do - { - if ( ! fgets(buf, sizeof buf, f) ) - return false; - ++loc.line_num; - } while ( buf[0] == '#' ); - - line = buf; - return true; - } - -vector TemplateInput::SplitIntoWords(const string& line) const - { - vector words; - - for ( auto start = line.c_str(); *start && *start != '\n'; ) - { - auto end = start + 1; - while ( *end && ! isspace(*end) ) - ++end; - - words.emplace_back(string(start, end - start)); - - start = end; - while ( *start && isspace(*start) ) - ++start; - } - - return words; - } - -string TemplateInput::SkipWords(const string& line, int n) const - { - auto s = line.c_str(); - - for ( int i = 0; i < n; ++i ) - { - // Find end of current word. - while ( *s && *s != '\n' ) - { - if ( isspace(*s) ) - break; - ++s; - } - - if ( *s == '\n' ) - break; - - // Find start of next word. - while ( *s && isspace(*s) ) - ++s; - } - - return string(s); - } - -void TemplateInput::Gripe(const char* msg, const string& input) const - { - auto input_s = input.c_str(); - int n = strlen(input_s); - - fprintf(stderr, "%s, line %d: %s - %s", loc.file_name, loc.line_num, msg, input_s); - if ( n == 0 || input_s[n - 1] != '\n' ) - fprintf(stderr, "\n"); - - exit(1); - } - -void TemplateInput::Gripe(const char* msg, const InputLoc& l) const - { - fprintf(stderr, "%s, line %d: %s\n", l.file_name, l.line_num, msg); - exit(1); - } - -ZAMGen::ZAMGen(int argc, char** argv) - { - auto prog_name = argv[0]; - - if ( argc != 2 ) - { - fprintf(stderr, "usage: %s \n", prog_name); - exit(1); - } - - auto file_name = argv[1]; - auto f = strcmp(file_name, "-") ? fopen(file_name, "r") : stdin; - - if ( ! f ) - { - fprintf(stderr, "%s: cannot open \"%s\"\n", prog_name, file_name); - exit(1); - } - - ti = make_unique(f, prog_name, file_name); - - InitEmitTargets(); - - while ( ParseTemplate() ) - ; - - for ( auto& t : templates ) - t->Instantiate(); - - GenMacros(); - - CloseEmitTargets(); - } - -void ZAMGen::ReadMacro(const string& line) - { - vector mac; - mac.emplace_back(SkipWords(line, 1)); - - string s; - while ( ScanLine(s) ) - { - if ( s.size() <= 1 || ! isspace(s.c_str()[0]) ) - { - PutBack(s); - break; - } - - mac.push_back(s); - } - - macros.emplace_back(move(mac)); - } - -void ZAMGen::GenMacros() - { - for ( auto& m : macros ) - { - for ( auto i = 0U; i < m.size(); ++i ) - { - auto ms = m[i]; - if ( i == 0 ) - ms = "#define " + ms; - - if ( i < m.size() - 1 ) - ms = regex_replace(ms, regex("\n"), " \\\n"); - - Emit(EvalMacros, ms); - } - - Emit(EvalMacros, "\n"); - } - } - -string ZAMGen::GenOpCode(const ZAM_OpTemplate* ot, const string& suffix, ZAM_InstClass zc) - { - auto op = "OP_" + ot->CanonicalName() + suffix; - - static unordered_set known_opcodes; - - if ( known_opcodes.count(op) > 0 ) - // We've already done this one, don't re-define its auxiliary - // information. - return op; - - known_opcodes.insert(op); - - IndentUp(); - - // Generate the enum defining the opcode ... - Emit(OpDef, op + ","); - - // ... the "flavor" of how it treats its first operand ... - auto op_comment = ",\t// " + op; - auto op1_always_read = (zc == ZIC_FIELD || zc == ZIC_COND); - auto flavor = op1_always_read ? "OP1_READ" : ot->GetOp1Flavor(); - Emit(Op1Flavor, flavor + op_comment); - - // ... whether it has side effects ... - auto se = ot->HasSideEffects() ? "true" : "false"; - Emit(OpSideEffects, se + op_comment); - - // ... and the switch case that maps the enum to a string - // representation. - auto name = ot->BaseName(); - transform(name.begin(), name.end(), name.begin(), ::tolower); - name += suffix; - transform(name.begin(), name.end(), name.begin(), under_to_dash); - Emit(OpName, "case " + op + ":\treturn \"" + name + "\";"); - - IndentDown(); - - return op; - } - -void ZAMGen::Emit(EmitTarget et, const string& s) - { - assert(et != None); - - if ( gen_files.count(et) == 0 ) - { - fprintf(stderr, "bad generation file type\n"); - exit(1); - } - - FILE* f = gen_files[et]; - - for ( auto i = indent_level; i > 0; --i ) - fputs("\t", f); - - fputs(s.c_str(), f); - - if ( ! no_NL && (s.empty() || s.back() != '\n') ) - fputs("\n", f); - } - -void ZAMGen::InitEmitTargets() - { - // Maps an EmitTarget enum to its corresponding filename. - static const unordered_map gen_file_names = { - {None, nullptr}, - {AssignFlavor, "ZAM-AssignFlavorsDefs.h"}, - {C1Def, "ZAM-GenExprsDefsC1.h"}, - {C1FieldDef, "ZAM-GenFieldsDefsC1.h"}, - {C2Def, "ZAM-GenExprsDefsC2.h"}, - {C2FieldDef, "ZAM-GenFieldsDefsC2.h"}, - {C3Def, "ZAM-GenExprsDefsC3.h"}, - {Cond, "ZAM-Conds.h"}, - {DirectDef, "ZAM-DirectDefs.h"}, - {Eval, "ZAM-EvalDefs.h"}, - {EvalMacros, "ZAM-EvalMacros.h"}, - {MethodDecl, "ZAM-MethodDecls.h"}, - {MethodDef, "ZAM-MethodDefs.h"}, - {Op1Flavor, "ZAM-Op1FlavorsDefs.h"}, - {OpDef, "ZAM-OpsDefs.h"}, - {OpName, "ZAM-OpsNamesDefs.h"}, - {OpSideEffects, "ZAM-OpSideEffects.h"}, - {VDef, "ZAM-GenExprsDefsV.h"}, - {VFieldDef, "ZAM-GenFieldsDefsV.h"}, - {Vec1Eval, "ZAM-Vec1EvalDefs.h"}, - {Vec2Eval, "ZAM-Vec2EvalDefs.h"}, - }; - - for ( auto& gfn : gen_file_names ) - { - auto fn = gfn.second; - if ( ! fn ) - continue; - - auto f = fopen(fn, "w"); - if ( ! f ) - { - fprintf(stderr, "can't open generation file %s\n", fn); - exit(1); - } - - gen_files[gfn.first] = f; - } - - InitSwitch(C1Def, "C1 assignment"); - InitSwitch(C2Def, "C2 assignment"); - InitSwitch(C3Def, "C3 assignment"); - InitSwitch(VDef, "V assignment"); - - InitSwitch(C1FieldDef, "C1 field assignment"); - InitSwitch(C2FieldDef, "C2 field assignment"); - InitSwitch(VFieldDef, "V field assignment"); - } - -void ZAMGen::InitSwitch(EmitTarget et, string desc) - { - Emit(et, "{"); - Emit(et, "switch ( rhs->Tag() ) {"); - - switch_targets[et] = desc; - } - -void ZAMGen::CloseEmitTargets() - { - FinishSwitches(); - - for ( auto& gf : gen_files ) - fclose(gf.second); - } - -void ZAMGen::FinishSwitches() - { - for ( auto& st : switch_targets ) - { - auto et = st.first; - auto& desc = st.second; - - Emit(et, "default:"); - IndentUp(); - Emit(et, "reporter->InternalError(\"inconsistency in " + desc + - ": %s\", obj_desc(rhs).c_str());"); - IndentDown(); - Emit(et, "}"); - Emit(et, "}"); - } - } - -bool ZAMGen::ParseTemplate() - { - string line; - - if ( ! ScanLine(line) ) - return false; - - if ( line.size() <= 1 ) - // A blank line - no template to parse. - return true; - - auto words = SplitIntoWords(line); - - if ( words.size() < 2 ) - Gripe("too few words at start of template", line); - - auto op = words[0]; - - if ( op == "macro" ) - { - ReadMacro(line); - return true; - } - - auto op_name = words[1]; - - // We track issues with the wrong number of template arguments - // up front, to avoid mis-invoking constructors, but we don't - // report these until later because if the template names a - // bad operation, it's better to report that as the core problem. - const char* args_mismatch = nullptr; - - if ( op == "direct-unary-op" ) - { - if ( words.size() != 3 ) - args_mismatch = "direct-unary-op takes 2 arguments"; - } - - else if ( words.size() != 2 ) - args_mismatch = "templates take 1 argument"; - - unique_ptr t; - - if ( op == "op" ) - t = make_unique(this, op_name); - else if ( op == "unary-op" ) - t = make_unique(this, op_name); - else if ( op == "direct-unary-op" && ! args_mismatch ) - t = make_unique(this, op_name, words[2]); - else if ( op == "assign-op" ) - t = make_unique(this, op_name); - else if ( op == "expr-op" ) - t = make_unique(this, op_name); - else if ( op == "unary-expr-op" ) - t = make_unique(this, op_name); - else if ( op == "binary-expr-op" ) - t = make_unique(this, op_name); - else if ( op == "rel-expr-op" ) - t = make_unique(this, op_name); - else if ( op == "internal-binary-op" ) - t = make_unique(this, op_name); - else if ( op == "internal-op" ) - t = make_unique(this, op_name); - else if ( op == "internal-assignment-op" ) - t = make_unique(this, op_name); - - else - Gripe("bad template name", op); - - if ( args_mismatch ) - Gripe(args_mismatch, line); - - t->Build(); - templates.emplace_back(move(t)); - - return true; - } - -int main(int argc, char** argv) - { - try - { - ZAMGen zg(argc, argv); - exit(0); - } - catch ( const std::regex_error& e ) - { - fprintf(stderr, "%s: regular expression error - %s\n", argv[0], e.what()); - exit(1); - } - } diff --git a/src/script_opt/ZAM/Gen-ZAM.h b/src/script_opt/ZAM/Gen-ZAM.h deleted file mode 100644 index e5f2eaec4d..0000000000 --- a/src/script_opt/ZAM/Gen-ZAM.h +++ /dev/null @@ -1,986 +0,0 @@ -// See the file "COPYING" in the main distribution directory for copyright. - -// Gen-ZAM is a standalone program that takes as input a file specifying -// ZAM operations and from them generates a (large) set of C++ include -// files used to instantiate those operations as low-level ZAM instructions. -// (Those files are described in the EmitTarget enumeration below.) -// -// See Ops.in for documentation regarding the format of the ZAM templates. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -using std::string; -using std::vector; - -// An instruction can have one of four basic classes. -enum ZAM_InstClass - { - ZIC_REGULAR, // a non-complicated instruction - ZIC_COND, // a conditional branch - ZIC_VEC, // a vector operation - ZIC_FIELD, // a record field assignment - }; - -// For a given instruction operand, its general type. -enum ZAM_OperandType - { - ZAM_OT_CONSTANT, // uses the instruction's associated constant - ZAM_OT_EVENT_HANDLER, // uses the associated event handler - ZAM_OT_INT, // directly specified integer - ZAM_OT_VAR, // frame slot associated with a variable - - ZAM_OT_ASSIGN_FIELD, // record field offset to assign to - ZAM_OT_RECORD_FIELD, // record field offset to access - - // The following wind up the same in the ultimate instruction, - // but they differ in the calling sequences used to generate - // the instruction. - ZAM_OT_AUX, // uses the instruction's "aux" field - ZAM_OT_LIST, // a list, managed via the "aux" field - - ZAM_OT_NONE, // instruction has no direct operands - }; - -// For instructions corresponding to evaluating expressions, the type -// of a given operand. The generator uses these to transform the operand's -// low-level ZVal into a higher-level type expected by the associated -// evaluation code. -enum ZAM_ExprType - { - ZAM_EXPR_TYPE_ADDR, - ZAM_EXPR_TYPE_ANY, - ZAM_EXPR_TYPE_DOUBLE, - ZAM_EXPR_TYPE_FUNC, - ZAM_EXPR_TYPE_INT, - ZAM_EXPR_TYPE_PATTERN, - ZAM_EXPR_TYPE_RECORD, - ZAM_EXPR_TYPE_STRING, - ZAM_EXPR_TYPE_SUBNET, - ZAM_EXPR_TYPE_TABLE, - ZAM_EXPR_TYPE_UINT, - ZAM_EXPR_TYPE_VECTOR, - ZAM_EXPR_TYPE_FILE, - ZAM_EXPR_TYPE_OPAQUE, - ZAM_EXPR_TYPE_LIST, - ZAM_EXPR_TYPE_TYPE, - - // Used to specify "apart from the explicitly specified operand - // types, do this action for any other types". - ZAM_EXPR_TYPE_DEFAULT, - - // Used for expressions where the evaluation code for the - // expression deals directly with the operand's ZVal, rather - // than the generator providing a higher-level version. - ZAM_EXPR_TYPE_NONE, - }; - -// We only use the following in the context where the vector's elements -// are individual words from the same line. We don't use it in other -// contexts where we're tracking a bunch of strings. -using Words = vector; - -// Used for error-reporting. -struct InputLoc - { - const char* file_name; - int line_num = 0; - }; - -// An EmitTarget is a generated file to which code will be emitted. -// The different values are used to instruct the generator which target -// is currently of interest. -enum EmitTarget - { - // Indicates that no generated file has yet been specified. - None, - - // Declares/defines methods that take AST nodes and generate - // corresponding ZAM instructions. - MethodDecl, - MethodDef, - - // Switch cases for expressions that are compiled directly, using - // custom methods rather than methods produced by the generator. - DirectDef, - - // Switch cases for invoking various flavors of methods produced - // by the generator for generating ZAM instructions for AST - // expressions. C1/C2/C3 refer to the first/second/third operand - // being a constant. V refers to none of the operands being - // a constant. - C1Def, - C2Def, - C3Def, - VDef, - - // The same, but for when the expression is being assigned to - // a record field rather than a variable. There's no "C3" option - // because of how we reduce AST ternary operations. - C1FieldDef, - C2FieldDef, - VFieldDef, - - // Switch cases for compiling relational operations used in - // conditionals. - Cond, - - // Switch cases that provide the C++ code for executing specific - // individual ZAM instructions. - Eval, - - // #define's used to provide the templator's macro functionality. - EvalMacros, - - // Switch cases the provide the C++ code for executing unary - // and binary vector operations. - Vec1Eval, - Vec2Eval, - - // A set of instructions to dynamically generate maps that - // translate a generic ZAM operation (e.g., OP_LOAD_GLOBAL_VV) - // to a specific ZAM instruction, given a specific type - // (e.g., for OP_LOAD_GLOBAL_VV plus TYPE_ADDR, the map yields - // OP_LOAD_GLOBAL_VV_A). - AssignFlavor, - - // A list of values, one per ZAM instruction, that indicate whether - // that instruction writes to its first operand (the most common - // case), reads the operand but doesn't write to it, both reads it - // and writes to it, or none of these apply because the first - // operand isn't a frame variable. See the ZAMOp1Flavor enum - // defined in ZOp.h. - Op1Flavor, - - // A list of boolean values, one per ZAM instruction, that indicate - // whether the instruction has side effects, and thus should not - // be deleted even if its associated assignment is to a dead value - // (one not subsequently used). - OpSideEffects, - - // A list of names enumerating each ZAM instruction. These - // are ZAM opcodes. - OpDef, - - // A list of cases, indexed by ZAM opcode, that return a - // human-readable string of naming the opcode, for use in debugging - // output. For example, for OP_NEGATE_VV_I the corresponding - // string is "negate-VV-I". - OpName, - }; - -// A helper class for managing the (ordered) collection of ZAM_OperandType's -// associated with an instruction in order to generate C++ calling sequences -// (both parameters for declarations, and arguments for invocations). -class ArgsManager - { -public: - // Constructed by providing the various ZAM_OperandType's along - // with the instruction's class. - ArgsManager(const vector& ot, ZAM_InstClass ic); - - // Returns a string defining the parameters for a declaration; - // these have full C++ type information along with the parameter - // name. - string Decls() const { return full_decl; } - - // Returns a string for passing the parameters in a function - // call. This is a comma-separated list of the parameter names, - // with no associated C++ types. - string Params() const { return full_params; } - - // Returns the name of the given parameter, indexed starting with 0. - const string& NthParam(int n) const { return params[n]; } - -private: - // Makes sure that each parameter has a unique name. For any - // parameter 'x' that occurs more than once, renames the instances - // "x1", "x2", etc. - void Differentiate(); - - // Maps ZAM_OperandType's to their associated C++ type and - // canonical parameter name. - static std::unordered_map> ot_to_args; - - // For a single argument/parameter, tracks its declaration name, - // C++ type, and the name to use when providing it as a parameter. - // These last two names are potentially distinct when we're - // assigning to record field (which is tracked by the is_field - // member variable), hence the need to track both. - struct Arg - { - string decl_name; - string decl_type; - string param_name; - bool is_field; - }; - - // All of the argument/parameters associated with the collection - // of ZAM_OperandType's. - vector args; - - // Each of the individual parameters. - vector params; - - // See Decls() and Params() above. - string full_decl; - string full_params; - }; - -// There are two mutually interacting classes: ZAMGen is the overall -// driver for the ZAM generator, while ZAM_OpTemplate represents a -// single operation template, with subclasses for specific types of -// operations. -class ZAMGen; - -class ZAM_OpTemplate - { -public: - // Instantiated by passing in the ZAMGen driver and the generic - // name for the operation. - ZAM_OpTemplate(ZAMGen* _g, string _base_name); - virtual ~ZAM_OpTemplate() { } - - // Constructs the template's data structures by parsing its - // description (beyond the initial description of the type of - // operation). - void Build(); - - // Tells the object to generate the code/files necessary for - // each of its underlying instructions. - virtual void Instantiate(); - - // Returns the generic name for the operation. - const string& BaseName() const { return base_name; } - - // Returns the canonical name for the operation. This is a - // version of the name that, for expression-based operations, - // can be concatenated with "EXPR_" to get the name of the - // corresponding AST node. - const string& CanonicalName() const { return cname; } - - // Returns a string version of the ZAMOp1Flavor associated - // with this operation. - const string& GetOp1Flavor() const { return op1_flavor; } - - // True if this is an operation with side effects (see OpSideEffects - // above). - bool HasSideEffects() const { return has_side_effects; } - -protected: - // Append to the list of operand types associated with this operation. - void AddOpType(ZAM_OperandType ot) { op_types.push_back(ot); } - // Retrieve the list of operand types associated with this operation. - const vector& OperandTypes() const { return op_types; } - - // Specify the ZAMOp1Flavor associated with this operation. See - // GetOp1Flavor() above for the corresponding accessor. - void SetOp1Flavor(string fl) { op1_flavor = fl; } - - // Specify/fetch the parameter (operand) from which to take the - // primary type of this operation. - void SetTypeParam(int param) { type_param = param; } - int GetTypeParam() const { return type_param; } - - // Specify/fetch the parameter (operand) from which to take the - // secondary type of this operation. - void SetType2Param(int param) { type2_param = param; } - int GetType2Param() const { return type2_param; } - - // Tracking of assignment values (C++ variables that hold the - // value that should be assigned to usual frame slot). - void SetAssignVal(string _av) { av = _av; } - bool HasAssignVal() const { return ! av.empty(); } - const string& GetAssignVal() const { return av; } - - // Management of C++ evaluation blocks. These are built up - // line-by-line. - void AddEval(string line) { eval += line; } - bool HasEval() const { return ! eval.empty(); } - const string& GetEval() const { return eval; } - - // Management of custom methods to be used rather than generating - // a method. - void SetCustomMethod(string cm) { custom_method = SkipWS(cm); } - bool HasCustomMethod() const { return ! custom_method.empty(); } - const string& GetCustomMethod() const { return custom_method; } - - // Management of code to execute at the end of a generated method. - void SetPostMethod(string cm) { post_method = SkipWS(cm); } - bool HasPostMethod() const { return ! post_method.empty(); } - const string& GetPostMethod() const { return post_method; } - - // Predicates indicating whether a subclass supports a given - // property. These are whether the operation: (1) should include - // a version that assigns to a record field as well as the normal - // assigning to a frame slot, (2) is a conditional branch, (3) does - // not have a corresponding AST node, (4) is a direct assignment - // (not an assignment to an expression), (5) is a direct assignment - // to a record field. - virtual bool IncludesFieldOp() const { return false; } - virtual bool IsConditionalOp() const { return false; } - virtual bool IsInternalOp() const { return false; } - virtual bool IsAssignOp() const { return false; } - virtual bool IsFieldOp() const { return false; } - - // Whether this operation does not have any C++ evaluation associated - // with it. Used for custom methods that compile into internal - // ZAM operations. - bool NoEval() const { return no_eval; } - void SetNoEval() { no_eval = true; } - - // Whether this operation does not have a version where one of - // its operands is a constant. - bool NoConst() const { return no_const; } - void SetNoConst() { no_const = true; } - - // Whether this operation also has a vectorized form. - bool IncludesVectorOp() const { return includes_vector_op; } - void SetIncludesVectorOp() { includes_vector_op = true; } - - // Whether this operation has side effects, and thus should - // not be elided even if its result is used in a dead assignment. - void SetHasSideEffects() { has_side_effects = true; } - - // An "assignment-less" operation is one that, if its result - // is used in a dead assignment, should be converted to a different - // operation that explictly omits any assignment. - bool HasAssignmentLess() const { return ! assignment_less_op.empty(); } - void SetAssignmentLess(string op, string op_type) - { - assignment_less_op = op; - assignment_less_op_type = op_type; - } - const string& AssignmentLessOp() const { return assignment_less_op; } - const string& AssignmentLessOpType() const { return assignment_less_op_type; } - - // Builds the instructions associated with this operation, assuming - // a single operand. - void UnaryInstantiate(); - - // Parses the next line in an operation template. "attr" is - // the first word on the line, which often specifies the - // attribute specified by the line. "line" is the entire line, - // for parsing when that's necessary, and for error reporting. - // "words" is "line" split into a vector of whitespace-delimited - // words. - virtual void Parse(const string& attr, const string& line, const Words& words); - - // Scans in a C++ evaluation block, which continues until encountering - // a line that does not start with whitespace, or that's empty. - string GatherEval(); - - // Parses a $-specifier of which operand to use to associate - // a Zeek scripting type with ZAM instructions. - int ExtractTypeParam(const string& arg); - - // Generates instructions for each of the different flavors of the - // given operation. "ot" specifies the types of operands for the - // instruction, and "do_vec" whether to generate a vector version. - void InstantiateOp(const vector& ot, bool do_vec); - - // Generates one specific flavor ("zc") of the given operation, - // using a method named 'm', the given operand types, and the class. - void InstantiateOp(const string& m, const vector& ot, ZAM_InstClass zc); - - // Generates the "assignment-less" version of the given op-code. - void GenAssignmentlessVersion(string op); - - // Generates the method 'm' for an operation, where "suffix" is - // a (potentially empty) string differentiating the method from - // others for that operation, and "ot" and "zc" are the same - // as above. - void InstantiateMethod(const string& m, const string& suffix, const vector& ot, - ZAM_InstClass zc); - - // Generates the main logic of an operation's method, given the - // specific operand types, an associated suffix for differentiating - // ZAM instructions, and the instruction class. - void InstantiateMethodCore(const vector& ot, string suffix, ZAM_InstClass zc); - - // Generates the specific code to create a ZInst for the given - // operation, operands, parameters to "GenInst", and suffix and - // class per the above. - virtual void BuildInstruction(const vector& ot, const string& params, - const string& suffix, ZAM_InstClass zc); - - // Top-level driver for generating the C++ evaluation code for - // a given flavor of operation. - virtual void InstantiateEval(const vector& ot, const string& suffix, - ZAM_InstClass zc); - - // Generates the C++ case statement for evaluating the given flavor - // of operation. - void InstantiateEval(EmitTarget et, const string& op_suffix, const string& eval, - ZAM_InstClass zc); - - // Generates a set of assignment C++ evaluations, one per each - // possible Zeek scripting type of operand. - void InstantiateAssignOp(const vector& ot, const string& suffix); - - // Generates a C++ evaluation for an assignment of the type - // corresponding to "accessor". If "is_managed" is true then - // generates the associated memory management, too. - void GenAssignOpCore(const vector& ot, const string& eval, - const string& accessor, bool is_managed); - - // The same, but for when there's an explicit assignment value. - void GenAssignOpValCore(const string& eval, const string& accessor, bool is_managed); - - // Returns the name of the method associated with the particular - // list of operand types. - string MethodName(const vector& ot) const; - - // Returns the parameter declarations to use in declaring a method. - string MethodDeclare(const vector& ot, ZAM_InstClass zc); - - // Returns a suffix that differentiates an operation name for - // a specific list of operand types. - string OpSuffix(const vector& ot) const; - - // Returns a copy of the given string with leading whitespace - // removed. - string SkipWS(const string& s) const; - - // Set the target to use for subsequent code emission. - void EmitTo(EmitTarget et) { curr_et = et; } - - // Emit the given string to the currently selected EmitTarget. - void Emit(const string& s); - - // Same, but temporarily indented up. - void EmitUp(const string& s) - { - IndentUp(); - Emit(s); - IndentDown(); - } - - // Same, but reframe from inserting a newline. - void EmitNoNL(const string& s); - - // Emit a newline. Implementation doesn't actually include a - // newline since that's implicit in a call to Emit(). - void NL() { Emit(""); } - - // Increase/decrease the indentation level, with the last two - // being used for brace-delimited code blocks. - void IndentUp(); - void IndentDown(); - void BeginBlock() - { - IndentUp(); - Emit("{"); - } - void EndBlock() - { - Emit("}"); - IndentDown(); - } - - // Maps an operand type to a character mnemonic used to distinguish - // it from others. - static std::unordered_map ot_to_char; - - // The associated driver object. - ZAMGen* g; - - // See BaseName() and CanonicalName() above. - string base_name; - string cname; - - // Tracks the beginning of this operation template's definition, - // for error reporting. - InputLoc op_loc; - - // The current emission target. - EmitTarget curr_et = None; - - // The operand types for operations that have a single fixed list. - // Some operations (like those evaluating expressions) instead have - // dynamically generated range of possible operand types. - vector op_types; - - // See the description of Op1Flavor above. - string op1_flavor = "OP1_WRITE"; - - // Tracks the result of ExtractTypeParam() used for "type" and - // "type2" attributes. - int type_param = 0; // 0 = not set - int type2_param = 0; - - // If non-empty, the value to assign to the target in an assignment - // operation. - string av; - - // The C++ evaluation; may span multiple lines. - string eval; - - // Any associated custom method. - string custom_method; - - // Any associated additional code to add at the end of a - // generated method. - string post_method; - - // If true, then this operation does not have C++ evaluation - // associated with it. - bool no_eval = false; - - // If true, then this operation should not include a version - // supporting operands of constant type. - bool no_const = false; - - // If true, then this operation includes a vectorized version. - bool includes_vector_op = false; - - // If true, then this operation has side effects. - bool has_side_effects = false; - - // If non-empty, then specifies the associated operation that - // is a version of this operation but without assigning the result; - // and the operand type (like "OP_V") of that associated operation. - string assignment_less_op; - string assignment_less_op_type; - }; - -// A subclass used for "unary-op" templates. -class ZAM_UnaryOpTemplate : public ZAM_OpTemplate - { -public: - ZAM_UnaryOpTemplate(ZAMGen* _g, string _base_name) : ZAM_OpTemplate(_g, _base_name) { } - -protected: - void Instantiate() override; - }; - -// A subclass for unary operations that are directly instantiated using -// custom methods. -class ZAM_DirectUnaryOpTemplate : public ZAM_OpTemplate - { -public: - ZAM_DirectUnaryOpTemplate(ZAMGen* _g, string _base_name, string _direct) - : ZAM_OpTemplate(_g, _base_name), direct(_direct) - { - } - -protected: - void Instantiate() override; - -private: - // The ZAMCompiler method to call to compile the operation. - string direct; - }; - -// A helper class for the ZAM_ExprOpTemplate class (which follows). -// This class tracks a single instance of creating an evaluation for -// an AST expression. -class EvalInstance - { -public: - // Initialized using the types of the LHS (result) and the - // first and second operand. Often all three types are the - // same, but they can differ for some particular expressions, - // and for relationals. "eval" provides the C++ evaluation code. - // "is_def" is true if this instance is for the default catch-all - // where the operand types don't match any of the explicitly - // specified evaluations; - EvalInstance(ZAM_ExprType lhs_et, ZAM_ExprType op1_et, ZAM_ExprType op2_et, string eval, - bool is_def); - - // Returns the accessor to use for assigning to the LHS. "is_ptr" - // indicates whether the value to which we're applying the - // accessor is a pointer, rather than a ZVal. - string LHSAccessor(bool is_ptr = false) const; - - // Same but for access to the first or second operand. - string Op1Accessor(bool is_ptr = false) const { return Accessor(op1_et, is_ptr); } - string Op2Accessor(bool is_ptr = false) const { return Accessor(op2_et, is_ptr); } - - // Provides an accessor for an operand of the given type. - string Accessor(ZAM_ExprType et, bool is_ptr = false) const; - - // Returns the "marker" use to make unique the opcode for this - // flavor of expression-evaluation instruction. - string OpMarker() const; - - const string& Eval() const { return eval; } - ZAM_ExprType LHS_ET() const { return lhs_et; } - bool IsDefault() const { return is_def; } - -private: - ZAM_ExprType lhs_et; - ZAM_ExprType op1_et; - ZAM_ExprType op2_et; - string eval; - bool is_def; - }; - -// A subclass for AST "Expr" nodes in reduced form. -class ZAM_ExprOpTemplate : public ZAM_OpTemplate - { -public: - ZAM_ExprOpTemplate(ZAMGen* _g, string _base_name); - - // The number of operands the operation takes (not including its - // assignment target). A value of 0 is used for expressions that - // require special handling. - virtual int Arity() const { return 0; } - - int HasExplicitResultType() const { return explicit_res_type; } - void SetHasExplicitResultType() { explicit_res_type = true; } - - void AddExprType(ZAM_ExprType et) { expr_types.insert(et); } - const std::unordered_set& ExprTypes() const { return expr_types; } - - void AddEvalSet(ZAM_ExprType et, string ev) { eval_set[et] += ev; } - void AddEvalSet(ZAM_ExprType et1, ZAM_ExprType et2, string ev) - { - eval_mixed_set[et1][et2] += ev; - } - - bool IncludesFieldOp() const override { return includes_field_op; } - void SetIncludesFieldOp() { includes_field_op = true; } - - bool HasPreEval() const { return ! pre_eval.empty(); } - void SetPreEval(string pe) { pre_eval = SkipWS(pe); } - const string& GetPreEval() const { return pre_eval; } - -protected: - // Returns a regular expression used to access the value of the - // expression suitable for assignment in a loop across the elements - // of a Zeek "vector" type. "have_target" is true if the template - // has an explicit "$$" assignment target. - virtual const char* VecEvalRE(bool have_target) const - { - return have_target ? "$$$$ = ZVal($1)" : "ZVal($&)"; - } - - void Parse(const string& attr, const string& line, const Words& words) override; - void Instantiate() override; - - // Instantiates versions of the operation that have a constant - // as the first, second, or third operand ... - void InstantiateC1(const vector& ots, int arity, bool do_vec = false); - void InstantiateC2(const vector& ots, int arity); - void InstantiateC3(const vector& ots); - - // ... or if all of the operands are non-constant. - void InstantiateV(const vector& ots); - - // Generates code that instantiates either the vectorized version - // of an operation, or the non-vector one, depending on whether - // the RHS of the reduced expression/assignment is a vector. - void DoVectorCase(const string& m, const string& args); - - // Iterates over the different Zeek types specified for an expression's - // operands and generates instructions for each. - void BuildInstructionCore(const string& params, const string& suffix, ZAM_InstClass zc); - - // Generates an if-else cascade element that matches one of the - // specific Zeek types associated with the instruction. - void GenMethodTest(ZAM_ExprType et1, ZAM_ExprType et2, const string& params, - const string& suffix, bool do_else, ZAM_InstClass zc); - - void InstantiateEval(const vector& ot, const string& suffix, - ZAM_InstClass zc) override; - -private: - // The Zeek types that can appear as operands for the expression. - std::unordered_set expr_types; - - // The C++ evaluation template for a given operand type. - std::unordered_map eval_set; - - // Some expressions take two operands of different types. This - // holds their C++ evaluation template. - std::unordered_map> eval_mixed_set; - - // Whether this expression's operand is a field access (and thus - // needs both the record as an operand and an additional constant - // offset into the record to get to the field). - bool includes_field_op = false; - - // If non-zero, code to generate prior to evaluating the expression. - string pre_eval; - - // If true, then the evaluations will take care of ensuring - // proper result types when assigning to $$. - bool explicit_res_type = false; - }; - -// A version of ZAM_ExprOpTemplate for unary expressions. -class ZAM_UnaryExprOpTemplate : public ZAM_ExprOpTemplate - { -public: - ZAM_UnaryExprOpTemplate(ZAMGen* _g, string _base_name) : ZAM_ExprOpTemplate(_g, _base_name) { } - - bool IncludesFieldOp() const override { return ExprTypes().count(ZAM_EXPR_TYPE_NONE) == 0; } - - int Arity() const override { return 1; } - -protected: - void Parse(const string& attr, const string& line, const Words& words) override; - void Instantiate() override; - - void BuildInstruction(const vector& ot, const string& params, - const string& suffix, ZAM_InstClass zc) override; - }; - -// A version of ZAM_UnaryExprOpTemplate where the point of the expression -// is to capture a direct assignment operation. -class ZAM_AssignOpTemplate : public ZAM_UnaryExprOpTemplate - { -public: - ZAM_AssignOpTemplate(ZAMGen* _g, string _base_name); - - bool IsAssignOp() const override { return true; } - bool IncludesFieldOp() const override { return false; } - bool IsFieldOp() const override { return field_op; } - void SetFieldOp() { field_op = true; } - -protected: - void Parse(const string& attr, const string& line, const Words& words) override; - void Instantiate() override; - -private: - bool field_op = false; - }; - -// A version of ZAM_ExprOpTemplate for binary expressions. -class ZAM_BinaryExprOpTemplate : public ZAM_ExprOpTemplate - { -public: - ZAM_BinaryExprOpTemplate(ZAMGen* _g, string _base_name) : ZAM_ExprOpTemplate(_g, _base_name) { } - - bool IncludesFieldOp() const override { return true; } - - int Arity() const override { return 2; } - -protected: - void Instantiate() override; - - void BuildInstruction(const vector& ot, const string& params, - const string& suffix, ZAM_InstClass zc) override; - }; - -// A version of ZAM_BinaryExprOpTemplate for relationals. -class ZAM_RelationalExprOpTemplate : public ZAM_BinaryExprOpTemplate - { -public: - ZAM_RelationalExprOpTemplate(ZAMGen* _g, string _base_name) - : ZAM_BinaryExprOpTemplate(_g, _base_name) - { - } - - bool IncludesFieldOp() const override { return false; } - bool IsConditionalOp() const override { return true; } - -protected: - const char* VecEvalRE(bool have_target) const override - { - if ( have_target ) - return "$$$$ = ZVal(bro_int_t($1))"; - else - return "ZVal(bro_int_t($&))"; - } - - void Instantiate() override; - - void BuildInstruction(const vector& ot, const string& params, - const string& suffix, ZAM_InstClass zc) override; - }; - -// A version of ZAM_BinaryExprOpTemplate for binary operations generated -// by custom methods rather than directly from the AST. -class ZAM_InternalBinaryOpTemplate : public ZAM_BinaryExprOpTemplate - { -public: - ZAM_InternalBinaryOpTemplate(ZAMGen* _g, string _base_name) - : ZAM_BinaryExprOpTemplate(_g, _base_name) - { - } - - bool IsInternalOp() const override { return true; } - - // The accessors used to get to the underlying Zeek script value - // of the first and second operand. - void SetOp1Accessor(string accessor) { op1_accessor = accessor; } - void SetOp2Accessor(string accessor) { op2_accessor = accessor; } - void SetOpAccessor(string accessor) - { - SetOp1Accessor(accessor); - SetOp2Accessor(accessor); - } - -protected: - void Parse(const string& attr, const string& line, const Words& words) override; - - void InstantiateEval(const vector& ot, const string& suffix, - ZAM_InstClass zc) override; - -private: - string op1_accessor; - string op2_accessor; - }; - -// A version of ZAM_OpTemplate for operations used internally (and not -// corresponding to AST elements). -class ZAM_InternalOpTemplate : public ZAM_OpTemplate - { -public: - ZAM_InternalOpTemplate(ZAMGen* _g, string _base_name) : ZAM_OpTemplate(_g, _base_name) { } - - bool IsInternalOp() const override { return true; } - -protected: - void Parse(const string& attr, const string& line, const Words& words) override; - -private: - // True if the internal operation corresponds to an indirect call, - // i.e., one through a variable rather than one directly specified. - bool is_indirect_call = false; - }; - -// An internal operation that assigns a result to a frame element. -class ZAM_InternalAssignOpTemplate : public ZAM_InternalOpTemplate - { -public: - ZAM_InternalAssignOpTemplate(ZAMGen* _g, string _base_name) - : ZAM_InternalOpTemplate(_g, _base_name) - { - } - - bool IsAssignOp() const override { return true; } - }; - -// Helper classes for managing input from the template file, including -// low-level scanning. - -class TemplateInput - { -public: - // Program name and file name are for generating error messages. - TemplateInput(FILE* _f, const char* _prog_name, const char* _file_name) - : f(_f), prog_name(_prog_name) - { - loc.file_name = _file_name; - } - - const InputLoc& CurrLoc() const { return loc; } - - // Fetch the next line of input, including trailing newline. - // Returns true on success, false on EOF or error. Skips over - // comments. - bool ScanLine(string& line); - - // Takes a line and splits it into white-space delimited words, - // returned in a vector. Removes trailing whitespace. - Words SplitIntoWords(const string& line) const; - - // Returns the line with the given number of initial words skipped. - string SkipWords(const string& line, int n) const; - - // Puts back the given line so that the next call to ScanLine will - // return it. Does not nest. - void PutBack(const string& line) { put_back = line; } - - // Report an error and exit. - [[noreturn]] void Gripe(const char* msg, const string& input) const; - [[noreturn]] void Gripe(const char* msg, const InputLoc& loc) const; - -private: - string put_back; // if non-empty, use this for the next ScanLine - - FILE* f; - const char* prog_name; - InputLoc loc; - }; - -// Driver class for the ZAM instruction generator. - -class ZAMGen - { -public: - ZAMGen(int argc, char** argv); - - // Reads in and records a macro definition, which ends upon - // encountering a blank line or a line that does not begin - // with whitespace. - void ReadMacro(const string& line); - - // Emits C++ #define's to implement the recorded macros. - void GenMacros(); - - // Generates a ZAM op-code for the given template, suffix, and - // instruction class. Also creates auxiliary information associated - // with the instruction. - string GenOpCode(const ZAM_OpTemplate* ot, const string& suffix, - ZAM_InstClass zc = ZIC_REGULAR); - - // These methods provide low-level parsing (and error-reporting) - // access to ZAM_OpTemplate objects. - const InputLoc& CurrLoc() const { return ti->CurrLoc(); } - bool ScanLine(string& line) { return ti->ScanLine(line); } - Words SplitIntoWords(const string& line) const { return ti->SplitIntoWords(line); } - string SkipWords(const string& line, int n) const { return ti->SkipWords(line, n); } - void PutBack(const string& line) { ti->PutBack(line); } - - // Methods made public to ZAM_OpTemplate objects for emitting code. - void Emit(EmitTarget et, const string& s); - - void IndentUp() { ++indent_level; } - void IndentDown() { --indent_level; } - void SetNoNL(bool _no_NL) { no_NL = _no_NL; } - - [[noreturn]] void Gripe(const char* msg, const string& input) const { ti->Gripe(msg, input); } - [[noreturn]] void Gripe(const char* msg, const InputLoc& loc) const { ti->Gripe(msg, loc); } - -private: - // Opens all of the code generation targets, and creates prologs - // for those requiring them (such as for embedding into switch - // statements). - void InitEmitTargets(); - void InitSwitch(EmitTarget et, string desc); - - // Closes all of the code generation targets, and creates epilogs - // for those requiring them. - void CloseEmitTargets(); - void FinishSwitches(); - - // Parses a single template, returning true on success and false - // if we've reached the end of the input. (Errors during parsing - // result instead in exiting.) - bool ParseTemplate(); - - // Maps code generation targets with their corresponding FILE*. - std::unordered_map gen_files; - - // Maps code generation targets to strings used to describe any - // associated switch (for error reporting). - std::unordered_map switch_targets; - - // The low-level TemplateInput object used to manage input. - std::unique_ptr ti; - - // Tracks all of the templates created so far. - vector> templates; - - // Tracks the macros recorded so far. - vector> macros; - - // Current indentation level. Maintained globally rather than - // per EmitTarget, so the caller needs to ensure it is managed - // consistently. - int indent_level = 0; - - // If true, refrain from appending a newline to any emitted lines. - bool no_NL = false; - }; From 145c7063c6051c78ab43b8829d144f5b00c433f7 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 21 Mar 2022 12:09:56 -0700 Subject: [PATCH 082/204] Add cmake-time reporting of bifcl, binpac, and gen-zam used for build Cross-compilation requires providing those pre-built for the build host, so it helps to see confirmation of the three --with-... overrides. --- CMakeLists.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6445d20f54..79ee3c74c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -637,6 +637,21 @@ else () set(_install_btest_tools_msg "no pcaps") endif () +set(_bifcl_exe_path "included") +if ( BIFCL_EXE_PATH ) + set(_bifcl_exe_path ${BIFCL_EXE_PATH}) +endif () + +set(_binpac_exe_path "included") +if ( BINPAC_EXE_PATH ) + set(_binpac_exe_path ${BINPAC_EXE_PATH}) +endif () + +set(_gen_zam_exe_path "included") +if ( GEN_ZAM_EXE_PATH ) + set(_gen_zam_exe_path ${GEN_ZAM_EXE_PATH}) +endif () + message( "\n====================| Zeek Build Summary |====================" "\n" @@ -658,8 +673,11 @@ message( "\n" "\nZeekControl: ${INSTALL_ZEEKCTL}" "\nAux. Tools: ${INSTALL_AUX_TOOLS}" + "\nBifCL: ${_bifcl_exe_path}" + "\nBinPAC: ${_binpac_exe_path}" "\nBTest: ${INSTALL_BTEST}" "\nBTest tooling: ${_install_btest_tools_msg}" + "\nGen-ZAM: ${_gen_zam_exe_path}" "\nzkg: ${INSTALL_ZKG}" "\n" "\nlibmaxminddb: ${USE_GEOIP}" From c2993013721fb2446bb8ca71e120d1b5b0e43a76 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 22 Mar 2022 11:54:43 -0700 Subject: [PATCH 083/204] Update zeek-testing-private hash [nomail] [skip ci] --- testing/external/commit-hash.zeek-testing-private | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/external/commit-hash.zeek-testing-private b/testing/external/commit-hash.zeek-testing-private index 3dc8e54252..569fc23187 100644 --- a/testing/external/commit-hash.zeek-testing-private +++ b/testing/external/commit-hash.zeek-testing-private @@ -1 +1 @@ -c8717246dc49a7dc4f536687b49dc5e0492cf9a0 +76a9ffd27c15ff1603216ee77f59cc9d515747c6 From 67410a0aa30c2036f7a96af4de5779380cde3263 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 23 Mar 2022 09:12:17 +0100 Subject: [PATCH 084/204] Update doc submodule [nomail] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index c021642fda..e2cb699675 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit c021642fda1392cde9414db9f148e93491f3e7c2 +Subproject commit e2cb69967552764f5fb89f714414d71e6cdb2543 From f02079e3c82185d652b0b948f9051c612e593a6a Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 23 Mar 2022 10:03:45 +0100 Subject: [PATCH 085/204] Improve the formatting of the SSL::Info::ssl_history documentation --- scripts/base/protocols/ssl/main.zeek | 58 +++++++++++++++------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/scripts/base/protocols/ssl/main.zeek b/scripts/base/protocols/ssl/main.zeek index 2b610707e3..3812b08214 100644 --- a/scripts/base/protocols/ssl/main.zeek +++ b/scripts/base/protocols/ssl/main.zeek @@ -71,32 +71,38 @@ export { ## SSL history showing which types of packets we received in which order. ## Letters have the following meaning with client-sent letters being capitalized: - ## H hello_request - ## C client_hello - ## S server_hello - ## V hello_verify_request - ## T NewSessionTicket - ## X certificate - ## K server_key_exchange - ## R certificate_request - ## N server_hello_done - ## Y certificate_verify - ## G client_key_exchange - ## F finished - ## W certificate_url - ## U certificate_status - ## A supplemental_data - ## Z unassigned_handshake_type - ## I change_cipher_spec - ## B heartbeat - ## D application_data - ## E end_of_early_data - ## O encrypted_extensions - ## P key_update - ## M message_hash - ## J hello_retry_request - ## L alert - ## Q unknown_content_type + ## + ## ====== ==================================================== + ## Letter Meaning + ## ====== ==================================================== + ## H hello_request + ## C client_hello + ## S server_hello + ## V hello_verify_request + ## T NewSessionTicket + ## X certificate + ## K server_key_exchange + ## R certificate_request + ## N server_hello_done + ## Y certificate_verify + ## G client_key_exchange + ## F finished + ## W certificate_url + ## U certificate_status + ## A supplemental_data + ## Z unassigned_handshake_type + ## I change_cipher_spec + ## B heartbeat + ## D application_data + ## E end_of_early_data + ## O encrypted_extensions + ## P key_update + ## M message_hash + ## J hello_retry_request + ## L alert + ## Q unknown_content_type + ## ====== ==================================================== + ## ssl_history: string &log &default=""; }; From 475063804e6d927ffd6701eb0859c7382df9f56a Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 8 Feb 2022 16:59:58 -0800 Subject: [PATCH 086/204] low-level naming tweaks / comments / const-ified accessor --- src/EventHandler.h | 2 +- src/analyzer/Analyzer.h | 2 ++ src/zeek-setup.cc | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/EventHandler.h b/src/EventHandler.h index ed981ae7e4..f47ff173d8 100644 --- a/src/EventHandler.h +++ b/src/EventHandler.h @@ -20,7 +20,7 @@ class EventHandler public: explicit EventHandler(std::string name); - const char* Name() { return name.data(); } + const char* Name() const { return name.data(); } const FuncPtr& GetFunc() { return local; } diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 6d56fa129a..942893a79c 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -605,6 +605,8 @@ public: * use this method to attach additional data to the connections. A * call to BuildConnVal() will in turn trigger a call to * UpdateConnVal(). + * ### The above comment needs updating, there's no BuildConnVal() + * ### anymore -VP * * @param conn_val The connenction value being updated. */ diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 2ae69ca061..b28397693c 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -281,13 +281,13 @@ static void done_with_network() ZEEK_LSAN_DISABLE(); } -static void terminate_bro() +static void terminate_zeek() { - util::detail::set_processing_status("TERMINATING", "terminate_bro"); + util::detail::set_processing_status("TERMINATING", "terminate_zeek"); run_state::terminating = true; - iosource_mgr->Wakeup("terminate_bro"); + iosource_mgr->Wakeup("terminate_zeek"); // File analysis termination may produce events, so do it early on in // the termination process. @@ -943,7 +943,7 @@ int cleanup(bool did_run_loop) done_with_network(); run_state::detail::delete_run(); - terminate_bro(); + terminate_zeek(); sqlite3_shutdown(); @@ -974,7 +974,7 @@ void zeek_terminate_loop(const char* reason) zeek::detail::done_with_network(); delete_run(); - zeek::detail::terminate_bro(); + zeek::detail::terminate_zeek(); // Close files after net_delete(), because net_delete() // might write to connection content files. From 3ff390717d83694174f457ef0b58451ab1e3ba83 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 8 Feb 2022 17:01:26 -0800 Subject: [PATCH 087/204] set_network_time() BiF in support of event replaying --- src/zeek.bif | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/zeek.bif b/src/zeek.bif index 37a329f9d4..911a010761 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -321,7 +321,7 @@ static int next_fmt(const char*& fmt, const zeek::Args* args, zeek::ODesc* d, in ## ## Returns: The wall-clock time. ## -## .. zeek:see:: network_time +## .. zeek:see:: network_time set_network_time function current_time%(%): time %{ return zeek::make_intrusive(zeek::util::current_time()); @@ -333,12 +333,26 @@ function current_time%(%): time ## ## Returns: The timestamp of the packet processed. ## -## .. zeek:see:: current_time +## .. zeek:see:: current_time set_network_time function network_time%(%): time %{ return zeek::make_intrusive(zeek::run_state::network_time); %} +## Sets the timestamp associated with the last packet processed. Used for +## event replaying. +## +## nt: The time to which to set "network time". +## +## Returns: The timestamp of the packet processed. +## +## .. zeek:see:: current_time network_time +function set_network_time%(nt: time%): bool + %{ + zeek::run_state::network_time = nt; + return zeek::val_mgr->True(); + %} + ## Returns a system environment variable. ## ## var: The name of the variable whose value to request. From cde677bd97e96487963a76b690d6ad491acd6256 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 8 Feb 2022 17:05:49 -0800 Subject: [PATCH 088/204] provide access to Val internals for event tracing purposes --- src/Val.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Val.h b/src/Val.h index acbca8edec..c6a5fbdaac 100644 --- a/src/Val.h +++ b/src/Val.h @@ -47,6 +47,7 @@ class PrefixTable; class CompositeHash; class HashKey; +class ValTrace; class ZBody; } // namespace detail @@ -1388,6 +1389,7 @@ public: static void DoneParsing(); protected: + friend class zeek::detail::ValTrace; friend class zeek::detail::ZBody; /** @@ -1407,9 +1409,9 @@ protected: record_val->emplace_back(std::nullopt); } - // For use by low-level ZAM instructions. Caller assumes - // responsibility for memory management. The first version - // allows manipulation of whether the field is present at all. + // For internal use by low-level ZAM instructions and event tracing. + // Caller assumes responsibility for memory management. The first + // version allows manipulation of whether the field is present at all. // The second version ensures that the optional value is present. std::optional& RawOptField(int field) { return (*record_val)[field]; } @@ -1620,10 +1622,13 @@ public: } const String* StringAt(unsigned int index) const { return StringValAt(index)->AsString(); } - // Only intended for low-level access by compiled code. + // Only intended for low-level access by internal or compiled code. const auto& RawVec() const { return vector_val; } auto& RawVec() { return vector_val; } + const auto& RawYieldType() const { return yield_type; } + const auto& RawYieldTypes() const { return yield_types; } + protected: /** * Returns the element at a given index or nullptr if it does not exist. From 25e096b50aabbcd6df34b63ef1b9812e071051f1 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 8 Feb 2022 17:06:45 -0800 Subject: [PATCH 089/204] classes providing event-tracing/dumping functionality --- src/CMakeLists.txt | 1 + src/EventTrace.cc | 1080 ++++++++++++++++++++++++++++++++++++++++++++ src/EventTrace.h | 464 +++++++++++++++++++ 3 files changed, 1545 insertions(+) create mode 100644 src/EventTrace.cc create mode 100644 src/EventTrace.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d8a82b92bb..c69137403f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -313,6 +313,7 @@ set(MAIN_SRCS EventHandler.cc EventLauncher.cc EventRegistry.cc + EventTrace.cc Expr.cc File.cc Flare.cc diff --git a/src/EventTrace.cc b/src/EventTrace.cc new file mode 100644 index 0000000000..c487fb6801 --- /dev/null +++ b/src/EventTrace.cc @@ -0,0 +1,1080 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/EventTrace.h" + +#include + +#include "zeek/Desc.h" +#include "zeek/EventHandler.h" +#include "zeek/Func.h" +#include "zeek/IPAddr.h" +#include "zeek/Reporter.h" +#include "zeek/ZeekString.h" + +namespace zeek::detail + { + +std::unique_ptr etm; + +// Helper function for generating a correct script-level representation +// of a string constant. +static std::string escape_string(const u_char* b, int len) + { + std::string res = "\""; + + for ( int i = 0; i < len; ++i ) + { + unsigned char c = b[i]; + + switch ( c ) + { + case '\a': + res += "\\a"; + break; + case '\b': + res += "\\b"; + break; + case '\f': + res += "\\f"; + break; + case '\n': + res += "\\n"; + break; + case '\r': + res += "\\r"; + break; + case '\t': + res += "\\t"; + break; + case '\v': + res += "\\v"; + break; + + case '\\': + res += "\\\\"; + break; + case '"': + res += "\\\""; + break; + + default: + if ( isprint(c) ) + res += c; + else + { + char buf[8192]; + snprintf(buf, sizeof buf, "%03o", c); + res += "\\"; + res += buf; + } + break; + } + } + + return res + "\""; + } + +ValTrace::ValTrace(const ValPtr& _v) + { + v = _v; + t = v->GetType(); + + switch ( t->Tag() ) + { + case TYPE_LIST: + TraceList(cast_intrusive(v)); + break; + + case TYPE_RECORD: + TraceRecord(cast_intrusive(v)); + break; + + case TYPE_TABLE: + TraceTable(cast_intrusive(v)); + break; + + case TYPE_VECTOR: + TraceVector(cast_intrusive(v)); + break; + + default: + break; + } + } + +ValTrace::~ValTrace() { } + +bool ValTrace::operator==(const ValTrace& vt) const + { + auto& vt_v = vt.GetVal(); + if ( vt_v == v ) + return true; + + auto tag = t->Tag(); + + if ( vt.GetType()->Tag() != tag ) + return false; + + switch ( tag ) + { + case TYPE_BOOL: + case TYPE_INT: + case TYPE_ENUM: + return v->AsInt() == vt_v->AsInt(); + + case TYPE_COUNT: + case TYPE_PORT: + return v->AsCount() == vt_v->AsCount(); + + case TYPE_DOUBLE: + case TYPE_INTERVAL: + case TYPE_TIME: + return v->AsDouble() == vt_v->AsDouble(); + + case TYPE_STRING: + return (*v->AsString()) == (*vt_v->AsString()); + + case TYPE_ADDR: + return v->AsAddr() == vt_v->AsAddr(); + + case TYPE_SUBNET: + return v->AsSubNet() == vt_v->AsSubNet(); + + case TYPE_FUNC: + return v->AsFile() == vt_v->AsFile(); + + case TYPE_FILE: + return v->AsFile() == vt_v->AsFile(); + + case TYPE_PATTERN: + return v->AsPattern() == vt_v->AsPattern(); + + case TYPE_ANY: + return v->AsSubNet() == vt_v->AsSubNet(); + + case TYPE_TYPE: + return v->AsType() == vt_v->AsType(); + + case TYPE_OPAQUE: + return false; // needs pointer equivalence + + case TYPE_LIST: + return SameList(vt); + + case TYPE_RECORD: + return SameRecord(vt); + + case TYPE_TABLE: + return SameTable(vt); + + case TYPE_VECTOR: + return SameVector(vt); + + default: + reporter->InternalError("bad type in ValTrace::operator=="); + } + } + +void ValTrace::ComputeDelta(const ValTrace* prev, DeltaVector& deltas) const + { + auto tag = t->Tag(); + + if ( prev ) + { + ASSERT(prev->GetType()->Tag() == tag); + + auto& prev_v = prev->GetVal(); + + if ( prev_v != v ) + { + if ( *this != *prev ) + deltas.emplace_back(std::make_unique(this, v)); + return; + } + } + + switch ( tag ) + { + case TYPE_BOOL: + case TYPE_INT: + case TYPE_ENUM: + case TYPE_COUNT: + case TYPE_PORT: + case TYPE_DOUBLE: + case TYPE_INTERVAL: + case TYPE_TIME: + case TYPE_STRING: + case TYPE_ADDR: + case TYPE_SUBNET: + case TYPE_FUNC: + case TYPE_PATTERN: + case TYPE_TYPE: + // These don't change in place. No need to create + // them as stand-alone variables, since we can just + // use the constant representation instead. + break; + + case TYPE_FILE: + case TYPE_OPAQUE: + case TYPE_ANY: + // These we have no way of creating as constants. + reporter->Error("cannot generate an event trace for an event of type %s", + type_name(tag)); + break; + + case TYPE_LIST: + // We shouldn't see these exposed directly, as they're + // not manipulable at script-level. An exception + // might be for "any" types that are then decomposed + // via compound assignment; for now, we don't support + // those. + reporter->InternalError("list type seen in ValTrace::ComputeDelta"); + break; + + case TYPE_RECORD: + if ( prev ) + ComputeRecordDelta(prev, deltas); + else + deltas.emplace_back(std::make_unique(this)); + break; + + case TYPE_TABLE: + if ( prev ) + ComputeTableDelta(prev, deltas); + + else if ( t->Yield() ) + deltas.emplace_back(std::make_unique(this)); + else + deltas.emplace_back(std::make_unique(this)); + break; + + case TYPE_VECTOR: + if ( prev ) + ComputeVectorDelta(prev, deltas); + else + deltas.emplace_back(std::make_unique(this)); + break; + + default: + reporter->InternalError("bad type in ValTrace::ComputeDelta"); + } + } + +void ValTrace::TraceList(const ListValPtr& lv) + { + auto vals = lv->Vals(); + for ( auto& v : vals ) + elems.emplace_back(std::make_shared(v)); + } + +void ValTrace::TraceRecord(const RecordValPtr& rv) + { + auto n = rv->NumFields(); + auto rt = rv->GetType(); + + for ( auto i = 0U; i < n; ++i ) + { + auto f = rv->RawOptField(i); + if ( f ) + { + auto val = f->ToVal(rt->GetFieldType(i)); + elems.emplace_back(std::make_shared(val)); + } + else + elems.emplace_back(nullptr); + } + } + +void ValTrace::TraceTable(const TableValPtr& tv) + { + for ( auto& elem : tv->ToMap() ) + { + auto& key = elem.first; + elems.emplace_back(std::make_shared(key)); + + auto& val = elem.second; + if ( val ) + elems2.emplace_back(std::make_shared(val)); + } + } + +void ValTrace::TraceVector(const VectorValPtr& vv) + { + auto& vec = vv->RawVec(); + auto n = vec->size(); + auto& yt = vv->RawYieldType(); + auto& yts = vv->RawYieldTypes(); + + for ( auto i = 0U; i < n; ++i ) + { + auto& elem = (*vec)[i]; + if ( elem ) + { + auto& t = yts ? (*yts)[i] : yt; + auto val = elem->ToVal(t); + elems.emplace_back(std::make_shared(val)); + } + else + elems.emplace_back(nullptr); + } + } + +bool ValTrace::SameList(const ValTrace& vt) const + { + return SameElems(vt); + } + +bool ValTrace::SameRecord(const ValTrace& vt) const + { + return SameElems(vt); + } + +bool ValTrace::SameTable(const ValTrace& vt) const + { + auto& vt_elems = vt.elems; + auto n = elems.size(); + if ( n != vt_elems.size() ) + return false; + + auto& vt_elems2 = vt.elems2; + auto n2 = elems2.size(); + if ( n2 != vt_elems2.size() ) + return false; + + ASSERT(n2 == 0 || n == n2); + + // We accommodate the possibility that keys are out-of-order + // between the two sets of elements. + + // The following is O(N^2), but presumably if tables are somehow + // involved (in fact we can only get here if they're used as + // indices into other tables), then they'll likely be small. + for ( auto i = 0U; i < n; ++i ) + { + auto& elem_i = elems[i]; + + // See if we can find a match for it. If we do, we don't + // have to worry that another entry matched it too, since + // all table/set indices will be distinct. + auto j = 0U; + for ( ; j < n; ++j ) + { + auto& vt_elem_j = vt_elems[j]; + if ( *elem_i == *vt_elem_j ) + break; + } + + if ( j == n ) + // No match for the index. + return false; + + if ( n2 > 0 ) + { + // Need a match for the corresponding yield values. + if ( *elems2[i] != *vt_elems2[j] ) + return false; + } + } + + return true; + } + +bool ValTrace::SameVector(const ValTrace& vt) const + { + return SameElems(vt); + } + +bool ValTrace::SameElems(const ValTrace& vt) const + { + auto& vt_elems = vt.elems; + auto n = elems.size(); + if ( n != vt_elems.size() ) + return false; + + for ( auto i = 0U; i < n; ++i ) + { + auto& trace_i = elems[i]; + auto& vt_trace_i = vt_elems[i]; + + if ( trace_i && vt_trace_i ) + { + if ( *trace_i != *vt_trace_i ) + return false; + } + + else if ( trace_i || vt_trace_i ) + return false; + } + + return true; + } + +bool ValTrace::SameSingleton(const ValTrace& vt) const + { + return ! IsAggr(t) && *this == vt; + } + +void ValTrace::ComputeRecordDelta(const ValTrace* prev, DeltaVector& deltas) const + { + auto& prev_elems = prev->elems; + auto n = elems.size(); + if ( n != prev_elems.size() ) + reporter->InternalError("size inconsistency in ValTrace::ComputeRecordDelta"); + + for ( auto i = 0U; i < n; ++i ) + { + const auto trace_i = elems[i].get(); + const auto prev_trace_i = prev_elems[i].get(); + + if ( trace_i ) + { + if ( prev_trace_i ) + { + auto& v = trace_i->GetVal(); + auto& prev_v = prev_trace_i->GetVal(); + + if ( v == prev_v ) + { + trace_i->ComputeDelta(prev_trace_i, deltas); + continue; + } + + if ( trace_i->SameSingleton(*prev_trace_i) ) + // No further work needed. + continue; + } + + deltas.emplace_back(std::make_unique(this, i, trace_i->GetVal())); + } + + else if ( prev_trace_i ) + deltas.emplace_back(std::make_unique(this, i)); + } + } + +void ValTrace::ComputeTableDelta(const ValTrace* prev, DeltaVector& deltas) const + { + auto& prev_elems = prev->elems; + auto& prev_elems2 = prev->elems2; + + auto n = elems.size(); + auto is_set = elems2.size() == 0; + auto prev_n = prev_elems.size(); + + // We can't compare pointers for the indices because they're + // new objects generated afresh by TableVal::ToMap. So we do + // explict full comparisons for equality, distinguishing values + // newly added, common to both, or (implicitly) removed. We'll + // then go through the common to check them further. + // + // Our approach is O(N^2), but presumably these tables aren't + // large, and in any case generating event traces is not something + // requiring high performance, so we opt for conceptual simplicity. + + // Track which index values are newly added: + std::set added_indices; + + // Track which entry traces are in common. Indexed by previous + // trace elem index, yielding current trace elem index. + std::map common_entries; + + for ( auto i = 0U; i < n; ++i ) + { + const auto trace_i = elems[i].get(); + + bool common = false; + + for ( auto j = 0U; j < prev_n; ++j ) + { + const auto prev_trace_j = prev_elems[j].get(); + + if ( *trace_i == *prev_trace_j ) + { + common_entries[j] = i; + common = true; + break; + } + } + + if ( ! common ) + { + auto v = trace_i->GetVal(); + + if ( is_set ) + deltas.emplace_back(std::make_unique(this, v)); + else + { + auto yield = elems2[i]->GetVal(); + deltas.emplace_back(std::make_unique(this, v, yield)); + } + + added_indices.insert(v.get()); + } + } + + for ( auto j = 0U; j < prev_n; ++j ) + { + auto common_pair = common_entries.find(j); + if ( common_pair == common_entries.end() ) + { + auto& prev_trace = prev_elems[j]; + auto& v = prev_trace->GetVal(); + deltas.emplace_back(std::make_unique(this, v)); + continue; + } + + if ( is_set ) + continue; + + // If we get here, we're analyzing a table for which there's + // a common index. The remaining question is whether the + // yield has changed. + auto i = common_pair->second; + auto& trace2 = elems2[i]; + const auto prev_trace2 = prev_elems2[j]; + + auto& yield = trace2->GetVal(); + auto& prev_yield = prev_trace2->GetVal(); + + if ( yield == prev_yield ) + // Same yield, look for differences in its sub-elements. + trace2->ComputeDelta(prev_trace2.get(), deltas); + + else if ( ! trace2->SameSingleton(*prev_trace2) ) + deltas.emplace_back( + std::make_unique(this, elems[i]->GetVal(), yield)); + } + } + +void ValTrace::ComputeVectorDelta(const ValTrace* prev, DeltaVector& deltas) const + { + auto& prev_elems = prev->elems; + auto n = elems.size(); + auto prev_n = prev_elems.size(); + + // The following hasn't been tested for robustness to vector holes. + + if ( n < prev_n ) + { + // The vector shrank in size. Easiest to just build it + // from scratch. + deltas.emplace_back(std::make_unique(this)); + return; + } + + // Look for existing entries that need reassigment. + auto i = 0U; + for ( ; i < prev_n; ++i ) + { + const auto trace_i = elems[i].get(); + const auto prev_trace_i = prev_elems[i].get(); + + auto& elem_i = trace_i->GetVal(); + auto& prev_elem_i = prev_trace_i->GetVal(); + + if ( elem_i == prev_elem_i ) + trace_i->ComputeDelta(prev_trace_i, deltas); + else if ( ! trace_i->SameSingleton(*prev_trace_i) ) + deltas.emplace_back(std::make_unique(this, i, elem_i)); + } + + // Now append any new entries. + for ( ; i < n; ++i ) + { + auto& trace_i = elems[i]; + auto& elem_i = trace_i->GetVal(); + deltas.emplace_back(std::make_unique(this, i, elem_i)); + } + } + +std::string ValDelta::Generate(ValTraceMgr* vtm) const + { + return ""; + } + +std::string DeltaReplaceValue::Generate(ValTraceMgr* vtm) const + { + return std::string(" = ") + vtm->ValName(new_val); + } + +std::string DeltaSetField::Generate(ValTraceMgr* vtm) const + { + auto rt = vt->GetType()->AsRecordType(); + auto f = rt->FieldName(field); + return std::string("$") + f + " = " + vtm->ValName(new_val); + } + +std::string DeltaRemoveField::Generate(ValTraceMgr* vtm) const + { + auto rt = vt->GetType()->AsRecordType(); + auto f = rt->FieldName(field); + return std::string("delete ") + vtm->ValName(vt) + "$" + f; + } + +std::string DeltaRecordCreate::Generate(ValTraceMgr* vtm) const + { + auto rv = cast_intrusive(vt->GetVal()); + auto rt = rv->GetType(); + auto n = rt->NumFields(); + + std::string args; + + for ( auto i = 0; i < n; ++i ) + { + auto v_i = rv->GetField(i); + if ( v_i ) + { + if ( ! args.empty() ) + args += ", "; + + args += std::string("$") + rt->FieldName(i) + "=" + vtm->ValName(v_i); + } + } + + auto name = rt->GetName(); + if ( name.empty() ) + name = "record"; + + return std::string(" = ") + name + "(" + args + ")"; + } + +std::string DeltaSetSetEntry::Generate(ValTraceMgr* vtm) const + { + return std::string("add ") + vtm->ValName(vt) + "[" + vtm->ValName(index) + "]"; + } + +std::string DeltaSetTableEntry::Generate(ValTraceMgr* vtm) const + { + return std::string("[") + vtm->ValName(index) + "] = " + vtm->ValName(new_val); + } + +std::string DeltaRemoveTableEntry::Generate(ValTraceMgr* vtm) const + { + return std::string("delete ") + vtm->ValName(vt) + "[" + vtm->ValName(index) + "]"; + } + +std::string DeltaSetCreate::Generate(ValTraceMgr* vtm) const + { + auto sv = cast_intrusive(vt->GetVal()); + auto members = sv->ToMap(); + + std::string args; + + for ( auto& m : members ) + { + if ( ! args.empty() ) + args += ", "; + + args += vtm->ValName(m.first); + } + + auto name = sv->GetType()->GetName(); + if ( name.empty() ) + name = "set"; + + return std::string(" = ") + name + "(" + args + ")"; + } + +std::string DeltaTableCreate::Generate(ValTraceMgr* vtm) const + { + auto tv = cast_intrusive(vt->GetVal()); + auto members = tv->ToMap(); + + std::string args; + + for ( auto& m : members ) + { + if ( ! args.empty() ) + args += ", "; + + args += std::string("[") + vtm->ValName(m.first) + "] = " + vtm->ValName(m.second); + } + + auto name = tv->GetType()->GetName(); + if ( name.empty() ) + name = "table"; + + return std::string(" = ") + name + "(" + args + ")"; + } + +std::string DeltaVectorSet::Generate(ValTraceMgr* vtm) const + { + return std::string("[") + std::to_string(index) + "] = " + vtm->ValName(elem); + } + +std::string DeltaVectorAppend::Generate(ValTraceMgr* vtm) const + { + return std::string("[") + std::to_string(index) + "] = " + vtm->ValName(elem); + } + +std::string DeltaVectorCreate::Generate(ValTraceMgr* vtm) const + { + auto& elems = vt->GetElems(); + std::string vec; + + for ( auto& e : elems ) + { + if ( vec.size() > 0 ) + vec += ", "; + + vec += vtm->ValName(e->GetVal()); + } + + return std::string(" = vector(") + vec + ")"; + } + +EventTrace::EventTrace(const ScriptFunc* _ev, double _nt, int event_num) : ev(_ev), nt(_nt) + { + auto ev_name = std::regex_replace(ev->Name(), std::regex(":"), "_"); + + name = ev_name + "_" + std::to_string(event_num) + "__et"; + } + +void EventTrace::Generate(FILE* f, ValTraceMgr& vtm, const DeltaGenVec& dvec, std::string successor, + int num_pre) const + { + int offset = 0; + for ( auto& d : dvec ) + { + auto& val = d.GetVal(); + + if ( d.IsFirstDef() && vtm.IsGlobal(val) ) + { + auto& val_name = vtm.ValName(val); + + std::string type_name; + auto& t = val->GetType(); + auto& tn = t->GetName(); + if ( tn.empty() ) + { + ODesc d; + t->Describe(&d); + type_name = d.Description(); + } + else + type_name = tn; + + auto anno = offset < num_pre ? " # from script" : ""; + + fprintf(f, "global %s: %s;%s\n", val_name.c_str(), type_name.c_str(), anno); + } + + ++offset; + } + + fprintf(f, "event %s()\n", name.c_str()); + fprintf(f, "\t{\n"); + + offset = 0; + for ( auto& d : dvec ) + { + fprintf(f, "\t"); + + auto& val = d.GetVal(); + + if ( d.IsFirstDef() && ! vtm.IsGlobal(val) ) + fprintf(f, "local "); + + if ( d.NeedsLHS() ) + fprintf(f, "%s", vtm.ValName(val).c_str()); + + auto anno = offset < num_pre ? " # from script" : ""; + + fprintf(f, "%s;%s\n", d.RHS().c_str(), anno); + + ++offset; + } + + if ( ! dvec.empty() ) + fprintf(f, "\n"); + + fprintf(f, "\tevent %s(%s);\n\n", ev->Name(), args.c_str()); + + if ( successor.empty() ) + { + // The following isn't necessary with our current approach + // to managing chains of events, which avoids having to set + // exit_only_after_terminate=T. + // fprintf(f, "\tterminate();\n"); + } + else + { + fprintf(f, "\tset_network_time(double_to_time(%.06f));\n", nt); + fprintf(f, "\tevent __EventTrace::%s();\n", successor.c_str()); + } + + fprintf(f, "\t}\n"); + } + +void EventTrace::Generate(FILE* f, ValTraceMgr& vtm, const EventTrace* predecessor, + std::string successor) const + { + if ( predecessor ) + { + auto& pre_deltas = predecessor->post_deltas; + int num_pre = pre_deltas.size(); + + if ( num_pre > 0 ) + { + auto total_deltas = pre_deltas; + total_deltas.insert(total_deltas.end(), deltas.begin(), deltas.end()); + Generate(f, vtm, total_deltas, successor, num_pre); + return; + } + } + + Generate(f, vtm, deltas, successor); + } + +void ValTraceMgr::TraceEventValues(std::shared_ptr et, const zeek::Args* args) + { + curr_ev = std::move(et); + + auto num_vals = vals.size(); + + std::string ev_args; + for ( auto& a : *args ) + { + AddVal(a); + + if ( ! ev_args.empty() ) + ev_args += ", "; + + ev_args += ValName(a); + } + + curr_ev->SetArgs(ev_args); + + // Now look for any values newly-processed with this event and + // remember them so we can catch uses of them in future events. + for ( auto i = num_vals; i < vals.size(); ++i ) + { + processed_vals.insert(vals[i].get()); + ASSERT(val_names.count(vals[i].get()) > 0); + } + } + +void ValTraceMgr::FinishCurrentEvent(const zeek::Args* args) + { + auto num_vals = vals.size(); + + curr_ev->SetDoingPost(); + + for ( auto& a : *args ) + AddVal(a); + + for ( auto i = num_vals; i < vals.size(); ++i ) + processed_vals.insert(vals[i].get()); + } + +const std::string& ValTraceMgr::ValName(const ValPtr& v) + { + auto find = val_names.find(v.get()); + if ( find == val_names.end() ) + { + if ( IsAggr(v->GetType()) ) + { // Aggregate shouldn't exist; create it + ASSERT(val_map.count(v.get()) == 0); + NewVal(v); + find = val_names.find(v.get()); + } + + else + { // Non-aggregate can be expressed using a constant + auto tag = v->GetType()->Tag(); + std::string rep; + + if ( tag == TYPE_STRING ) + { + auto s = v->AsStringVal(); + rep = escape_string(s->Bytes(), s->Len()); + } + + else if ( tag == TYPE_LIST ) + { + auto lv = cast_intrusive(v); + for ( auto& v_i : lv->Vals() ) + { + if ( ! rep.empty() ) + rep += ", "; + + rep += ValName(v_i); + } + } + + else if ( tag == TYPE_FUNC ) + rep = v->AsFunc()->Name(); + + else if ( tag == TYPE_TIME ) + rep = std::string("double_to_time(") + std::to_string(v->AsDouble()) + ")"; + + else if ( tag == TYPE_INTERVAL ) + rep = std::string("double_to_interval(") + std::to_string(v->AsDouble()) + ")"; + + else + { + ODesc d; + v->Describe(&d); + rep = d.Description(); + } + + val_names[v.get()] = rep; + vals.push_back(v); + find = val_names.find(v.get()); + } + + ASSERT(find != val_names.end()); + } + + ValUsed(v); + + return find->second; + } + +void ValTraceMgr::AddVal(ValPtr v) + { + auto mapping = val_map.find(v.get()); + + if ( mapping == val_map.end() ) + NewVal(v); + else + { + auto vt = std::make_shared(v); + AssessChange(vt.get(), mapping->second.get()); + val_map[v.get()] = vt; + } + } + +void ValTraceMgr::NewVal(ValPtr v) + { + // Make sure the Val sticks around into the future. + vals.push_back(v); + + auto vt = std::make_shared(v); + AssessChange(vt.get(), nullptr); + val_map[v.get()] = vt; + } + +void ValTraceMgr::ValUsed(const ValPtr& v) + { + ASSERT(val_names.count(v.get()) > 0); + if ( processed_vals.count(v.get()) > 0 ) + // We saw this value when processing a previous event. + globals.insert(v.get()); + } + +void ValTraceMgr::AssessChange(const ValTrace* vt, const ValTrace* prev_vt) + { + DeltaVector deltas; + + vt->ComputeDelta(prev_vt, deltas); + + // Used to track deltas across the batch, to suppress redundant ones + // (which can arise due to two aggregates both including the same + // sub-element). + std::unordered_set previous_deltas; + + for ( auto& d : deltas ) + { + auto vp = d->GetValTrace()->GetVal(); + auto v = vp.get(); + auto rhs = d->Generate(this); + + bool needs_lhs = d->NeedsLHS(); + bool is_first_def = false; + + if ( needs_lhs && val_names.count(v) == 0 ) + { + TrackVar(v); + is_first_def = true; + } + + ASSERT(val_names.count(v) > 0); + + // The "/" in the following is just to have a delimiter + // to make sure the string is unambiguous. + auto full_delta = val_names[v] + "/" + rhs; + if ( previous_deltas.count(full_delta) > 0 ) + continue; + + previous_deltas.insert(full_delta); + + ValUsed(vp); + curr_ev->AddDelta(vp, rhs, needs_lhs, is_first_def); + } + + auto& v = vt->GetVal(); + if ( IsAggr(v->GetType()) ) + ValUsed(vt->GetVal()); + } + +void ValTraceMgr::TrackVar(const Val* v) + { + auto val_name = std::string("__val") + std::to_string(num_vars++); + val_names[v] = val_name; + } + +EventTraceMgr::EventTraceMgr(const std::string& trace_file) + { + f = fopen(trace_file.c_str(), "w"); + if ( ! f ) + reporter->FatalError("can't open event trace file %s", trace_file.c_str()); + } + +EventTraceMgr::~EventTraceMgr() + { + if ( events.empty() ) + return; + + fprintf(f, "module __EventTrace;\n\n"); + + for ( auto& e : events ) + fprintf(f, "global %s: event();\n", e->GetName()); + + fprintf(f, "\nevent zeek_init() &priority=-999999\n"); + fprintf(f, "\t{\n"); + fprintf(f, "\tevent __EventTrace::%s();\n", events.front()->GetName()); + fprintf(f, "\t}\n"); + + for ( auto i = 0U; i < events.size(); ++i ) + { + fprintf(f, "\n"); + + auto predecessor = i > 0 ? events[i - 1] : nullptr; + auto successor = i + 1 < events.size() ? events[i + 1]->GetName() : ""; + events[i]->Generate(f, vtm, predecessor.get(), successor); + } + + fclose(f); + } + +void EventTraceMgr::StartEvent(const ScriptFunc* ev, const zeek::Args* args) + { + if ( script_events.count(ev->Name()) > 0 ) + return; + + auto nt = run_state::network_time; + if ( nt == 0.0 ) + return; + + auto et = std::make_shared(ev, nt, events.size()); + events.emplace_back(et); + + vtm.TraceEventValues(et, args); + } + +void EventTraceMgr::EndEvent(const ScriptFunc* ev, const zeek::Args* args) + { + if ( script_events.count(ev->Name()) > 0 ) + return; + + if ( run_state::network_time > 0.0 ) + vtm.FinishCurrentEvent(args); + } + +void EventTraceMgr::ScriptEventQueued(const EventHandlerPtr& h) + { + script_events.insert(h->Name()); + } + + } // namespace zeek::detail diff --git a/src/EventTrace.h b/src/EventTrace.h new file mode 100644 index 0000000000..ff28496f6a --- /dev/null +++ b/src/EventTrace.h @@ -0,0 +1,464 @@ +// Classes for tracing/dumping Zeek events. + +#pragma once + +#include "zeek/Val.h" + +namespace zeek::detail + { + +class ValTrace; +class ValTraceMgr; + +// Abstract class for capturing a single difference between two script-level +// values. Includes notions of inserting, changing, or deleting a value. +class ValDelta + { +public: + ValDelta(const ValTrace* _vt) : vt(_vt) { } + virtual ~ValDelta() { } + + // Return a string that performs the update operation, expressed + // as Zeek scripting. Does not include a terminating semicolon. + virtual std::string Generate(ValTraceMgr* vtm) const; + + // Whether the generated string needs the affected value to + // explicitly appear on the left-hand-side. Note that this + // might not be as a simple "LHS = RHS" assignment, but instead + // as "LHS$field = RHS" or "LHS[index] = RHS". + // + // Returns false for generated strings like "delete LHS[index]". + virtual bool NeedsLHS() const { return true; } + + const ValTrace* GetValTrace() const { return vt; } + +protected: + const ValTrace* vt; + }; + +using DeltaVector = std::vector>; + +// Tracks the elements of a value as seen at a given point in execution. +// For non-aggregates, this is simply the Val object, but for aggregates +// it is (recursively) each of the sub-elements, in a manner that can then +// be readily compared against future instances. +class ValTrace + { +public: + ValTrace(const ValPtr& v); + ~ValTrace(); + + const ValPtr& GetVal() const { return v; } + const TypePtr& GetType() const { return t; } + const auto& GetElems() const { return elems; } + + // Returns true if this trace and the given one represent the + // same underlying value. Can involve subelement-by-subelement + // (recursive) comparisons. + bool operator==(const ValTrace& vt) const; + bool operator!=(const ValTrace& vt) const { return ! ((*this) == vt); } + + // Computes the deltas between a previous ValTrace and this one. + // If "prev" is nil then we're creating this value from scratch + // (though if it's an aggregate, we may reuse existing values + // for some of its components). + // + // Returns the accumulated differences in "deltas". If on return + // nothing was added to "deltas" then the two ValTrace's are equivalent + // (no changes between them). + void ComputeDelta(const ValTrace* prev, DeltaVector& deltas) const; + +private: + // Methods for tracing different types of aggregate values. + void TraceList(const ListValPtr& lv); + void TraceRecord(const RecordValPtr& rv); + void TraceTable(const TableValPtr& tv); + void TraceVector(const VectorValPtr& vv); + + // Predicates for comparing different types of aggregates for equality. + bool SameList(const ValTrace& vt) const; + bool SameRecord(const ValTrace& vt) const; + bool SameTable(const ValTrace& vt) const; + bool SameVector(const ValTrace& vt) const; + + // Helper function that knows about the internal vector-of-subelements + // we use for aggregates. + bool SameElems(const ValTrace& vt) const; + + // True if this value is a singleton and it's the same value as + // represented in "vt". + bool SameSingleton(const ValTrace& vt) const; + + // Add to "deltas" the differences needed to turn a previous instance + // of the given type of aggregate to the current instance. + void ComputeRecordDelta(const ValTrace* prev, DeltaVector& deltas) const; + void ComputeTableDelta(const ValTrace* prev, DeltaVector& deltas) const; + void ComputeVectorDelta(const ValTrace* prev, DeltaVector& deltas) const; + + // Holds sub-elements for aggregates. + std::vector> elems; + + // A parallel vector used for the yield values of tables. + std::vector> elems2; + + ValPtr v; + TypePtr t; // v's type, for convenience + }; + +// Captures the basic notion of a new, non-equivalent value being assigned. +class DeltaReplaceValue : public ValDelta + { +public: + DeltaReplaceValue(const ValTrace* _vt, ValPtr _new_val) + : ValDelta(_vt), new_val(std::move(_new_val)) + { + } + + std::string Generate(ValTraceMgr* vtm) const override; + +private: + ValPtr new_val; + }; + +// Captures the notion of setting a record field. +class DeltaSetField : public ValDelta + { +public: + DeltaSetField(const ValTrace* _vt, int _field, ValPtr _new_val) + : ValDelta(_vt), field(_field), new_val(std::move(_new_val)) + { + } + + std::string Generate(ValTraceMgr* vtm) const override; + +private: + int field; + ValPtr new_val; + }; + +// Captures the notion of deleting a record field. +class DeltaRemoveField : public ValDelta + { +public: + DeltaRemoveField(const ValTrace* _vt, int _field) : ValDelta(_vt), field(_field) { } + + std::string Generate(ValTraceMgr* vtm) const override; + bool NeedsLHS() const override { return false; } + +private: + int field; + }; + +// Captures the notion of creating a record from scratch. +class DeltaRecordCreate : public ValDelta + { +public: + DeltaRecordCreate(const ValTrace* _vt) : ValDelta(_vt) { } + + std::string Generate(ValTraceMgr* vtm) const override; + }; + +// Captures the notion of adding an element to a set. Use DeltaRemoveTableEntry to +// delete values. +class DeltaSetSetEntry : public ValDelta + { +public: + DeltaSetSetEntry(const ValTrace* _vt, ValPtr _index) : ValDelta(_vt), index(_index) { } + + std::string Generate(ValTraceMgr* vtm) const override; + bool NeedsLHS() const override { return false; } + +private: + ValPtr index; + }; + +// Captures the notion of setting a table entry (which includes both changing +// an existing one and adding a new one). Use DeltaRemoveTableEntry to +// delete values. +class DeltaSetTableEntry : public ValDelta + { +public: + DeltaSetTableEntry(const ValTrace* _vt, ValPtr _index, ValPtr _new_val) + : ValDelta(_vt), index(_index), new_val(std::move(_new_val)) + { + } + + std::string Generate(ValTraceMgr* vtm) const override; + +private: + ValPtr index; + ValPtr new_val; + }; + +// Captures the notion of removing a table/set entry. +class DeltaRemoveTableEntry : public ValDelta + { +public: + DeltaRemoveTableEntry(const ValTrace* _vt, ValPtr _index) + : ValDelta(_vt), index(std::move(_index)) + { + } + + std::string Generate(ValTraceMgr* vtm) const override; + bool NeedsLHS() const override { return false; } + +private: + ValPtr index; + }; + +// Captures the notion of creating a set from scratch. +class DeltaSetCreate : public ValDelta + { +public: + DeltaSetCreate(const ValTrace* _vt) : ValDelta(_vt) { } + + std::string Generate(ValTraceMgr* vtm) const override; + }; + +// Captures the notion of creating a table from scratch. +class DeltaTableCreate : public ValDelta + { +public: + DeltaTableCreate(const ValTrace* _vt) : ValDelta(_vt) { } + + std::string Generate(ValTraceMgr* vtm) const override; + }; + +// Captures the notion of changing an element of a vector. +class DeltaVectorSet : public ValDelta + { +public: + DeltaVectorSet(const ValTrace* _vt, int _index, ValPtr _elem) + : ValDelta(_vt), index(_index), elem(std::move(_elem)) + { + } + + std::string Generate(ValTraceMgr* vtm) const override; + +private: + int index; + ValPtr elem; + }; + +// Captures the notion of adding an entry to the end of a vector. +class DeltaVectorAppend : public ValDelta + { +public: + DeltaVectorAppend(const ValTrace* _vt, int _index, ValPtr _elem) + : ValDelta(_vt), index(_index), elem(std::move(_elem)) + { + } + + std::string Generate(ValTraceMgr* vtm) const override; + +private: + int index; + ValPtr elem; + }; + +// Captures the notion of replacing a vector wholesale. +class DeltaVectorCreate : public ValDelta + { +public: + DeltaVectorCreate(const ValTrace* _vt) : ValDelta(_vt) { } + + std::string Generate(ValTraceMgr* vtm) const override; + +private: + }; + +// Manages the changes to (or creation of) a variable used to represent +// a value. +class DeltaGen + { +public: + DeltaGen(ValPtr _val, std::string _rhs, bool _needs_lhs, bool _is_first_def) + : val(std::move(_val)), rhs(std::move(_rhs)), needs_lhs(_needs_lhs), + is_first_def(_is_first_def) + { + } + + const ValPtr& GetVal() const { return val; } + const std::string& RHS() const { return rhs; } + bool NeedsLHS() const { return needs_lhs; } + bool IsFirstDef() const { return is_first_def; } + +private: + ValPtr val; + + // The expression to set the variable to. + std::string rhs; + + // Whether that expression needs the variable explicitly provides + // on the lefthand side. + bool needs_lhs; + + // Whether this is the first definition of the variable (in which + // case we also need to declare the variable). + bool is_first_def; + }; + +using DeltaGenVec = std::vector; + +// Tracks a single event. +class EventTrace + { +public: + // Constructed in terms of the associated script function, "network + // time" when the event occurred, and the position of this event + // within all of those being traced. + EventTrace(const ScriptFunc* _ev, double _nt, int event_num); + + // Sets a string representation of the arguments (values) being + // passed to the event. + void SetArgs(std::string _args) { args = std::move(_args); } + + // Adds to the trace an update for the given value. + void AddDelta(ValPtr val, std::string rhs, bool needs_lhs, bool is_first_def) + { + auto& d = is_post ? post_deltas : deltas; + d.emplace_back(DeltaGen(val, rhs, needs_lhs, is_first_def)); + } + + // Initially we analyze events pre-execution. When this flag + // is set, we switch to instead analyzing post-execution. The + // difference allows us to annotate the output with "# from script" + // comments that flag changes created by script execution rather + // than event engine activity. + void SetDoingPost() { is_post = true; } + + const char* GetName() const { return name.c_str(); } + + // Generates an internal event handler that sets up the values + // associated with the traced event, followed by queueing the traced + // event, and then queueing the successor internal event handler, + // if any. + // + // "predecessor", if non-nil, gives the event that came just before + // this one (used for "# from script" annotations"). "successor", + // if not empty, gives the name of the successor internal event. + void Generate(FILE* f, ValTraceMgr& vtm, const EventTrace* predecessor, + std::string successor) const; + +private: + // "dvec" is either just our deltas, or the "post_deltas" of our + // predecessor plus our deltas. + void Generate(FILE* f, ValTraceMgr& vtm, const DeltaGenVec& dvec, std::string successor, + int num_pre = 0) const; + + const ScriptFunc* ev; + double nt; + bool is_post = false; + + // The deltas needed to construct the values associated with this + // event prior to its execution. + DeltaGenVec deltas; + + // The deltas capturing any changes to the original values as induced + // by executing its event handlers. + DeltaGenVec post_deltas; + + // The event's name and a string representation of its arguments. + std::string name; + std::string args; + }; + +// Manages all of the events and associated values seen during the execution. +class ValTraceMgr + { +public: + // Invoked to trace a new event with the associated arguments. + void TraceEventValues(std::shared_ptr et, const zeek::Args* args); + + // Invoked when the current event finishes execution. The arguments + // are again provided, for convenience so we don't have to remember + // them from the previous method. + void FinishCurrentEvent(const zeek::Args* args); + + // Returns the name of the script variable associated with the + // given value. + const std::string& ValName(const ValPtr& v); + const std::string& ValName(const ValTrace* vt) { return ValName(vt->GetVal()); } + + // Returns true if the script variable associated with the given value + // needs to be global (because it's used across multiple events). + bool IsGlobal(const ValPtr& v) const { return globals.count(v.get()) > 0; } + +private: + // Traces the given value, which we may-or-may-not have seen before. + void AddVal(ValPtr v); + + // Creates a new value, associating a script variable with it. + void NewVal(ValPtr v); + + // Called when the given value is used in an expression that sets + // or updates another value. This lets us track which values are + // used across multiple events, and thus need to be global. + void ValUsed(const ValPtr& v); + + // Compares the two value traces to build up deltas capturing + // the difference between the previous one and the current one. + void AssessChange(const ValTrace* vt, const ValTrace* prev_vt); + + // Create and track a script variable associated with the given value. + void TrackVar(const Val* vt); + + // Maps values to their associated traces. + std::unordered_map> val_map; + + // Maps values to the "names" we associated with them. For simple + // values, the name is just a Zeek script constant. For aggregates, + // it's a dedicated script variable. + std::unordered_map val_names; + int num_vars = 0; // the number of dedicated script variables + + // Tracks which values we've processed up through the preceding event. + // Any re-use we then see for the current event (via a ValUsed() call) + // then tells us that the value is used across events, and thus its + // associated script variable needs to be global. + std::unordered_set processed_vals; + + // Tracks which values have associated script variables that need + // to be global. + std::unordered_set globals; + + // The event we're currently tracing. + std::shared_ptr curr_ev; + + // Hang on to values we're tracking to make sure the pointers don't + // get reused when the main use of the value ends. + std::vector vals; + }; + +// Manages tracing of all of the events seen during execution, including +// the final generation of the trace script. +class EventTraceMgr + { +public: + EventTraceMgr(const std::string& trace_file); + ~EventTraceMgr(); + + // Called at the beginning of invoking an event's handlers. + void StartEvent(const ScriptFunc* ev, const zeek::Args* args); + + // Called after finishing with invoking an event's handlers. + void EndEvent(const ScriptFunc* ev, const zeek::Args* args); + + // Used to track events generated at script-level. + void ScriptEventQueued(const EventHandlerPtr& h); + +private: + FILE* f = nullptr; + ValTraceMgr vtm; + + // All of the events we've traced so far. + std::vector> events; + + // The names of all of the script events that have been generated. + std::unordered_set script_events; + }; + +// If non-nil then we're doing event tracing. +extern std::unique_ptr etm; + + } // namespace zeek::detail From 39cbd7a9dc6f0d4c39c9051ce176038be57c631c Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 8 Feb 2022 17:07:40 -0800 Subject: [PATCH 090/204] hooks to support event tracing --- src/Expr.cc | 15 ++++++++++++++- src/Func.cc | 7 +++++++ src/Stmt.cc | 7 +++++++ src/zeek-setup.cc | 12 ++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/Expr.cc b/src/Expr.cc index 007382096f..f6b2bf84b6 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -8,6 +8,7 @@ #include "zeek/Desc.h" #include "zeek/Event.h" #include "zeek/EventRegistry.h" +#include "zeek/EventTrace.h" #include "zeek/Frame.h" #include "zeek/Func.h" #include "zeek/Hash.h" @@ -4323,7 +4324,14 @@ ValPtr ScheduleExpr::Eval(Frame* f) const auto args = eval_list(f, event->Args()); if ( args ) - timer_mgr->Add(new ScheduleTimer(event->Handler(), std::move(*args), dt)); + { + auto handler = event->Handler(); + + if ( etm ) + etm->ScriptEventQueued(handler); + + timer_mgr->Add(new ScheduleTimer(handler, std::move(*args), dt)); + } return nullptr; } @@ -4862,7 +4870,12 @@ ValPtr EventExpr::Eval(Frame* f) const auto v = eval_list(f, args.get()); if ( handler ) + { + if ( etm ) + etm->ScriptEventQueued(handler); + event_mgr.Enqueue(handler, std::move(*v)); + } return nullptr; } diff --git a/src/Func.cc b/src/Func.cc index 282c65dde8..992acc9e0e 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -33,6 +33,7 @@ #include "zeek/Debug.h" #include "zeek/Desc.h" #include "zeek/Event.h" +#include "zeek/EventTrace.h" #include "zeek/Expr.h" #include "zeek/File.h" #include "zeek/Frame.h" @@ -401,6 +402,9 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const const CallExpr* call_expr = parent ? parent->GetCall() : nullptr; call_stack.emplace_back(CallInfo{call_expr, this, *args}); + if ( etm && Flavor() == FUNC_FLAVOR_EVENT ) + etm->StartEvent(this, args); + if ( g_trace_state.DoTrace() ) { ODesc d; @@ -481,6 +485,9 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const result = val_mgr->True(); } + else if ( etm && Flavor() == FUNC_FLAVOR_EVENT ) + etm->EndEvent(this, args); + // Warn if the function returns something, but we returned from // the function without an explicit return, or without a value. else if ( GetType()->Yield() && GetType()->Yield()->Tag() != TYPE_VOID && diff --git a/src/Stmt.cc b/src/Stmt.cc index 7cbb13d7da..a6832517e7 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -8,6 +8,7 @@ #include "zeek/Debug.h" #include "zeek/Desc.h" #include "zeek/Event.h" +#include "zeek/EventTrace.h" #include "zeek/Expr.h" #include "zeek/File.h" #include "zeek/Frame.h" @@ -1076,11 +1077,17 @@ EventStmt::EventStmt(EventExprPtr arg_e) : ExprStmt(STMT_EVENT, arg_e), event_ex ValPtr EventStmt::Exec(Frame* f, StmtFlowType& flow) { RegisterAccess(); + auto args = eval_list(f, event_expr->Args()); auto h = event_expr->Handler(); if ( args && h ) + { + if ( etm ) + etm->ScriptEventQueued(h); + event_mgr.Enqueue(h, std::move(*args)); + } flow = FLOW_NEXT; return nullptr; diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index b28397693c..891479f8ff 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -26,6 +26,7 @@ #include "zeek/Desc.h" #include "zeek/Event.h" #include "zeek/EventRegistry.h" +#include "zeek/EventTrace.h" #include "zeek/File.h" #include "zeek/Frag.h" #include "zeek/Frame.h" @@ -299,8 +300,19 @@ static void terminate_zeek() event_mgr.Enqueue(zeek_done, Args{}); timer_mgr->Expire(); + + // Drain() limits how many "generations" of newly created events + // it will process. When we're terminating, however, we're okay + // with long chains of events, and this makes the workings of + // event-tracing simpler. + // + // That said, we also need to ensure that it runs at least once, + // as it has side effects such as tickling triggers. event_mgr.Drain(); + while ( event_mgr.HasEvents() ) + event_mgr.Drain(); + if ( profiling_logger ) { // FIXME: There are some occasional crashes in the memory From ecd273c3ca5aca388f346f244751922429003f16 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 8 Feb 2022 17:09:13 -0800 Subject: [PATCH 091/204] --event-trace / -E option to generate event trace --- src/Options.cc | 17 ++++++++++++----- src/Options.h | 1 + src/zeek-setup.cc | 3 +++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Options.cc b/src/Options.cc index ccc9ddae5e..0cf23a4fd6 100644 --- a/src/Options.cc +++ b/src/Options.cc @@ -114,6 +114,8 @@ void usage(const char* prog, int code) #endif fprintf(stderr, " -C|--no-checksums | ignore checksums\n"); fprintf(stderr, " -D|--deterministic | initialize random seeds to zero\n"); + fprintf(stderr, " -E|--event-trace | generate a replayable event trace to " + "the given file\n"); fprintf(stderr, " -F|--force-dns | force DNS\n"); fprintf(stderr, " -G|--load-seeds | load seeds from given file\n"); fprintf(stderr, " -H|--save-seeds | save seeds to given file\n"); @@ -380,6 +382,7 @@ Options parse_cmdline(int argc, char** argv) {"no-checksums", no_argument, nullptr, 'C'}, {"force-dns", no_argument, nullptr, 'F'}, {"deterministic", no_argument, nullptr, 'D'}, + {"event-trace", required_argument, nullptr, 'E'}, {"load-seeds", required_argument, nullptr, 'G'}, {"save-seeds", required_argument, nullptr, 'H'}, {"print-plugins", no_argument, nullptr, 'N'}, @@ -400,7 +403,7 @@ Options parse_cmdline(int argc, char** argv) {"mem-profile", no_argument, nullptr, 'M'}, #endif - {"pseudo-realtime", optional_argument, nullptr, 'E'}, + {"pseudo-realtime", optional_argument, nullptr, '~'}, {"jobs", optional_argument, nullptr, 'j'}, {"test", no_argument, nullptr, '#'}, @@ -408,7 +411,7 @@ Options parse_cmdline(int argc, char** argv) }; char opts[256]; - util::safe_strncpy(opts, "B:c:e:f:G:H:I:i:j::n:O:0:o:p:r:s:T:t:U:w:X:CDFMNPQSWabdhmuv", + util::safe_strncpy(opts, "B:c:E:e:f:G:H:I:i:j::n:O:0:o:p:r:s:T:t:U:w:X:CDFMNPQSWabdhmuv", sizeof(opts)); int op; @@ -523,9 +526,7 @@ Options parse_cmdline(int argc, char** argv) rval.deterministic_mode = true; break; case 'E': - rval.pseudo_realtime = 1.0; - if ( optarg ) - rval.pseudo_realtime = atof(optarg); + rval.event_trace_file = optarg; break; case 'F': if ( rval.dns_mode != detail::DNS_DEFAULT ) @@ -586,6 +587,12 @@ Options parse_cmdline(int argc, char** argv) break; #endif + case '~': + rval.pseudo_realtime = 1.0; + if ( optarg ) + rval.pseudo_realtime = atof(optarg); + break; + case '#': fprintf(stderr, "ERROR: --test only allowed as first argument.\n"); usage(zargs[0], 1); diff --git a/src/Options.h b/src/Options.h index b9bd1c5e9b..0065b527b9 100644 --- a/src/Options.h +++ b/src/Options.h @@ -73,6 +73,7 @@ struct Options std::optional process_status_file; std::optional zeekygen_config_file; std::optional unprocessed_output_file; + std::optional event_trace_file; std::set plugins_to_load; std::vector scripts_to_load; diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 891479f8ff..561270c3c6 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -670,6 +670,9 @@ SetupResult setup(int argc, char** argv, Options* zopts) }; auto ipbb = make_intrusive(init_bifs, ipbid->Name(), false); + if ( options.event_trace_file ) + etm = make_unique(*options.event_trace_file); + run_state::is_parsing = true; yyparse(); run_state::is_parsing = false; From 75652927e25da82075274207d6ca93d3f6db5ae6 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 22 Mar 2022 13:59:23 -0700 Subject: [PATCH 092/204] low-level style tweaks --- src/EventTrace.cc | 4 ++-- src/analyzer/Analyzer.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EventTrace.cc b/src/EventTrace.cc index c487fb6801..793acde00d 100644 --- a/src/EventTrace.cc +++ b/src/EventTrace.cc @@ -74,7 +74,7 @@ static std::string escape_string(const u_char* b, int len) return res + "\""; } -ValTrace::ValTrace(const ValPtr& _v) +ValTrace::ValTrace(const ValPtr& _v) : v(_v) { v = _v; t = v->GetType(); @@ -552,7 +552,7 @@ void ValTrace::ComputeVectorDelta(const ValTrace* prev, DeltaVector& deltas) con auto n = elems.size(); auto prev_n = prev_elems.size(); - // The following hasn't been tested for robustness to vector holes. + // TODO: The following hasn't been tested for robustness to vector holes. if ( n < prev_n ) { diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 942893a79c..4659f7af2b 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -605,8 +605,8 @@ public: * use this method to attach additional data to the connections. A * call to BuildConnVal() will in turn trigger a call to * UpdateConnVal(). - * ### The above comment needs updating, there's no BuildConnVal() - * ### anymore -VP + * TODO: The above comment needs updating, there's no BuildConnVal() + * anymore -VP * * @param conn_val The connenction value being updated. */ From e13dd305657a5425980a2cbb30096e509af5f827 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:16:35 -0800 Subject: [PATCH 093/204] tweak for comparing redundant-but-complex attributes --- src/Attr.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Attr.cc b/src/Attr.cc index b0d2947a00..22e1ef35d8 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -192,6 +192,9 @@ void Attributes::AddAttr(AttrPtr attr, bool is_redef) { auto acceptable_duplicate_attr = [](const AttrPtr& attr, const AttrPtr& existing) -> bool { + if ( attr == existing ) + return true; + AttrTag new_tag = attr->Tag(); if ( new_tag == ATTR_DEPRECATED ) From 8e745f6f4877901e685d41cb77bdcfeb301f2ccb Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:17:39 -0800 Subject: [PATCH 094/204] allow {} expression lists for =/+=/-= RHS --- src/parse.y | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/parse.y b/src/parse.y index a7e93446fe..240d6017dd 100644 --- a/src/parse.y +++ b/src/parse.y @@ -5,7 +5,7 @@ // Switching parser table type fixes ambiguity problems. %define lr.type ielr -%expect 140 +%expect 196 %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF @@ -58,7 +58,7 @@ %type local_id_list case_type_list %type init_class %type TOK_CONSTANT -%type expr opt_expr init opt_init anonymous_function lambda_body index_slice opt_deprecated when_condition +%type expr opt_expr rhs opt_init anonymous_function lambda_body index_slice opt_deprecated when_condition %type event %type stmt stmt_list func_body for_head %type type opt_type enum_body @@ -67,7 +67,7 @@ %type type_decl formal_args_decl %type type_decl_list formal_args_decl_list %type formal_args -%type expr_list opt_expr_list +%type expr_list opt_expr_list rhs_expr_list %type case %type case_list %type attr @@ -488,7 +488,7 @@ expr: $$ = new AddExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } - | expr TOK_ADD_TO expr + | expr TOK_ADD_TO rhs { set_location(@1, @3); $$ = new AddToExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); @@ -500,7 +500,7 @@ expr: $$ = new SubExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); } - | expr TOK_REMOVE_FROM expr + | expr TOK_REMOVE_FROM rhs { set_location(@1, @3); $$ = new RemoveFromExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}); @@ -596,7 +596,7 @@ expr: $$ = new CondExpr({AdoptRef{}, $1}, {AdoptRef{}, $3}, {AdoptRef{}, $5}); } - | expr '=' expr + | expr '=' rhs { set_location(@1, @3); @@ -608,7 +608,7 @@ expr: $$ = get_assign_expr({AdoptRef{}, $1}, {AdoptRef{}, $3}, in_init).release(); } - | TOK_LOCAL local_id '=' expr + | TOK_LOCAL local_id '=' rhs { set_location(@2, @4); if ( ! locals_at_this_scope.empty() ) @@ -794,7 +794,6 @@ expr: | anonymous_function - | TOK_SCHEDULE expr '{' event '}' { set_location(@1, @5); @@ -906,6 +905,19 @@ expr: } ; +rhs: '{' { ++in_init; } rhs_expr_list '}' + { + --in_init; + $$ = $3; + } + | expr + ; + +rhs_expr_list: expr_list opt_comma + | + { $$ = new ListExpr(); } + ; + expr_list: expr_list ',' expr { @@ -1508,20 +1520,12 @@ init_class: ; opt_init: - { ++in_init; } init { --in_init; } + { ++in_init; } rhs { --in_init; } { $$ = $2; } | { $$ = 0; } ; -init: - '{' opt_expr_list '}' - { $$ = $2; } - | '{' expr_list ',' '}' - { $$ = $2; } - | expr - ; - index_slice: expr '[' opt_expr ':' opt_expr ']' { @@ -2064,12 +2068,14 @@ opt_no_test: { $$ = true; } | { $$ = false; } + ; opt_no_test_block: TOK_NO_TEST { $$ = true; script_coverage_mgr.IncIgnoreDepth(); } | { $$ = false; } + ; opt_deprecated: TOK_ATTR_DEPRECATED @@ -2090,6 +2096,11 @@ opt_deprecated: } | { $$ = nullptr; } + ; + +opt_comma: ',' + | + ; %% From 4d051620e8fe9a255a29c1c7ca02486854f06c9d Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:19:05 -0800 Subject: [PATCH 095/204] reworking of expressions to unify =/+=/-= with initialization --- src/Expr.cc | 1011 +++++++++++++++++++++------------------------------ src/Expr.h | 80 ++-- 2 files changed, 449 insertions(+), 642 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index 007382096f..4f79c8448a 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -28,16 +28,6 @@ namespace zeek::detail { -static bool init_tag_check(const Expr* expr, const char* name, TypeTag expect_tag, TypeTag init_tag) - { - if ( expect_tag == init_tag ) - return true; - - auto msg = util::fmt("unexpected use of %s in '%s' initialization", name, type_name(init_tag)); - expr->Error(msg); - return false; - } - const char* expr_name(BroExprTag t) { static const char* expr_names[int(NUM_EXPRS)] = { @@ -265,11 +255,6 @@ bool Expr::InvertSense() return false; } -void Expr::EvalIntoAggregate(const TypePtr& /* t */, ValPtr /* aggr */, Frame* /* f */) const - { - Internal("Expr::EvalIntoAggregate called"); - } - void Expr::Assign(Frame* /* f */, ValPtr /* v */) { Internal("Expr::Assign called"); @@ -413,25 +398,6 @@ bool Expr::IsRecordElement(TypeDecl* /* td */) const return false; } -bool Expr::IsPure() const - { - return true; - } - -ValPtr Expr::InitVal(const TypePtr& t, ValPtr aggr) const - { - if ( aggr ) - { - Error("bad initializer"); - return nullptr; - } - - if ( IsError() ) - return nullptr; - - return check_and_promote(Eval(nullptr), t, true); - } - bool Expr::IsError() const { return type && type->Tag() == TYPE_ERROR; @@ -584,11 +550,6 @@ void NameExpr::Assign(Frame* f, ValPtr v) f->SetElement(id, std::move(v)); } -bool NameExpr::IsPure() const - { - return id->IsConst(); - } - TraversalCode NameExpr::Traverse(TraversalCallback* cb) const { TraversalCode tc = cb->PreExpr(this); @@ -840,17 +801,28 @@ void BinaryExpr::ExprDescribe(ODesc* d) const ValPtr BinaryExpr::Fold(Val* v1, Val* v2) const { - InternalTypeTag it = v1->GetType()->InternalType(); + auto& t1 = v1->GetType(); + InternalTypeTag it = t1->InternalType(); if ( it == TYPE_INTERNAL_STRING ) return StringFold(v1, v2); - if ( v1->GetType()->Tag() == TYPE_PATTERN ) + if ( t1->Tag() == TYPE_PATTERN ) return PatternFold(v1, v2); - if ( v1->GetType()->IsSet() ) + if ( t1->IsSet() ) return SetFold(v1, v2); + if ( t1->IsTable() ) + return TableFold(v1, v2); + + if ( t1->Tag() == TYPE_VECTOR ) + { + // We only get here when using a matching vector on the RHS. + v2->AsVectorVal()->AddTo(v1, false); + return {NewRef{}, v1}; + } + if ( it == TYPE_INTERNAL_ADDR ) return AddrFold(v1, v2); @@ -1145,6 +1117,19 @@ ValPtr BinaryExpr::SetFold(Val* v1, Val* v2) const reporter->InternalError("confusion over canonicalization in set comparison"); break; + case EXPR_ADD_TO: + // Avoid doing the AddTo operation if tv2 is empty, + // because then it might not type-check for trivial + // reasons. + if ( tv2->Size() > 0 ) + tv2->AddTo(tv1, false); + return {NewRef{}, tv1}; + + case EXPR_REMOVE_FROM: + if ( tv2->Size() > 0 ) + tv2->RemoveFrom(tv1); + return {NewRef{}, tv1}; + default: BadTag("BinaryExpr::SetFold", expr_name(tag)); return nullptr; @@ -1153,6 +1138,33 @@ ValPtr BinaryExpr::SetFold(Val* v1, Val* v2) const return val_mgr->Bool(res); } +ValPtr BinaryExpr::TableFold(Val* v1, Val* v2) const + { + TableVal* tv1 = v1->AsTableVal(); + TableVal* tv2 = v2->AsTableVal(); + + switch ( tag ) + { + case EXPR_ADD_TO: + // Avoid doing the AddTo operation if tv2 is empty, + // because then it might not type-check for trivial + // reasons. + if ( tv2->Size() > 0 ) + tv2->AddTo(tv1, false); + return {NewRef{}, tv1}; + + case EXPR_REMOVE_FROM: + if ( tv2->Size() > 0 ) + tv2->RemoveFrom(tv1); + return {NewRef{}, tv1}; + + default: + BadTag("BinaryExpr::TableFold", expr_name(tag)); + } + + return nullptr; + } + ValPtr BinaryExpr::AddrFold(Val* v1, Val* v2) const { IPAddr a1 = v1->AsAddr(); @@ -1267,6 +1279,90 @@ void BinaryExpr::CheckScalarAggOp() const } } +bool BinaryExpr::CheckForRHSList() + { + if ( op2->Tag() != EXPR_LIST ) + return false; + + auto lhs_t = op1->GetType(); + auto rhs = cast_intrusive(op2); + auto& rhs_exprs = rhs->Exprs(); + + if ( lhs_t->Tag() == TYPE_TABLE ) + { + if ( lhs_t->IsSet() && rhs_exprs.size() >= 1 && same_type(lhs_t, rhs_exprs[0]->GetType()) ) + { + // This is potentially the idiom of "set1 += { set2 }" + // or "set1 += { set2, set3, set4 }". + op2 = {NewRef{}, rhs_exprs[0]}; + + for ( auto i = 1U; i < rhs_exprs.size(); ++i ) + { + ExprPtr re_i = {NewRef{}, rhs_exprs[i]}; + op2 = make_intrusive(EXPR_OR, op2, re_i); + } + + SetType(op1->GetType()); + + return true; + } + + if ( lhs_t->IsTable() && rhs_exprs.size() == 1 && + same_type(lhs_t, rhs_exprs[0]->GetType()) ) + { + // This is the idiom of "table1 += { table2 }" (or -=). + // Unlike for sets we don't allow more than one table + // in the RHS list because table "union" isn't + // well-defined. + op2 = {NewRef{}, rhs_exprs[0]}; + SetType(op1->GetType()); + + return true; + } + + if ( lhs_t->IsTable() ) + op2 = make_intrusive(rhs, nullptr, lhs_t); + else + op2 = make_intrusive(rhs, nullptr, lhs_t); + } + + else if ( lhs_t->Tag() == TYPE_VECTOR ) + { + if ( tag == EXPR_REMOVE_FROM ) + { + ExprError("constructor list not allowed for -= operations on vectors"); + return false; + } + + op2 = make_intrusive(rhs, lhs_t); + } + + else + { + ExprError("invalid constructor list on RHS of assignment"); + return false; + } + + if ( op2->IsError() ) + { + // Message should have already been generated, but propagate. + SetError(); + return false; + } + + // Don't bother type-checking for the degenerate case of the RHS + // being empty, since it won't actually matter. + if ( ! rhs_exprs.empty() && ! same_type(op1->GetType(), op2->GetType()) ) + { + ExprError("type clash for constructor list on RHS of assignment"); + return false; + } + + SetType(op1->GetType()); + + return true; + } + CloneExpr::CloneExpr(ExprPtr arg_op) : UnaryExpr(EXPR_CLONE, std::move(arg_op)) { if ( IsError() ) @@ -1368,11 +1464,6 @@ ValPtr IncrExpr::Eval(Frame* f) const } } -bool IncrExpr::IsPure() const - { - return false; - } - ComplementExpr::ComplementExpr(ExprPtr arg_op) : UnaryExpr(EXPR_COMPLEMENT, std::move(arg_op)) { if ( IsError() ) @@ -1558,23 +1649,54 @@ void AddExpr::Canonicize() } AddToExpr::AddToExpr(ExprPtr arg_op1, ExprPtr arg_op2) - : BinaryExpr(EXPR_ADD_TO, is_vector(arg_op1) ? std::move(arg_op1) : arg_op1->MakeLvalue(), - std::move(arg_op2)) + : BinaryExpr(EXPR_ADD_TO, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; - TypeTag bt1 = op1->GetType()->Tag(); - TypeTag bt2 = op2->GetType()->Tag(); + auto& t1 = op1->GetType(); + auto& t2 = op2->GetType(); + TypeTag bt1 = t1->Tag(); + TypeTag bt2 = t2->Tag(); + + if ( bt1 != TYPE_TABLE && bt1 != TYPE_VECTOR && bt1 != TYPE_PATTERN ) + op1 = op1->MakeLvalue(); if ( BothArithmetic(bt1, bt2) ) PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); else if ( BothString(bt1, bt2) || BothInterval(bt1, bt2) ) SetType(base_type(bt1)); + else if ( bt2 == TYPE_LIST ) + (void)CheckForRHSList(); + + else if ( bt1 == TYPE_TABLE ) + { + if ( same_type(t1, t2) ) + SetType(t1); + else + ExprError("RHS type mismatch for table/set +="); + } + + else if ( bt1 == TYPE_PATTERN ) + { + if ( bt2 != TYPE_PATTERN ) + ExprError("pattern += op requires op to be a pattern"); + else + SetType(t1); + } + else if ( IsVector(bt1) ) { - bt1 = op1->GetType()->AsVectorType()->Yield()->Tag(); + if ( same_type(t1, t2) ) + { + SetType(t1); + return; + } + + is_vector_elem_append = true; + + bt1 = t1->AsVectorType()->Yield()->Tag(); if ( IsArithmetic(bt1) ) { @@ -1583,7 +1705,7 @@ AddToExpr::AddToExpr(ExprPtr arg_op1, ExprPtr arg_op2) if ( bt2 != bt1 ) op2 = make_intrusive(std::move(op2), bt1); - SetType(op1->GetType()); + SetType(t1); } else @@ -1595,7 +1717,7 @@ AddToExpr::AddToExpr(ExprPtr arg_op1, ExprPtr arg_op2) util::fmt("incompatible vector append: %s and %s", type_name(bt1), type_name(bt2))); else - SetType(op1->GetType()); + SetType(t1); } else @@ -1614,7 +1736,7 @@ ValPtr AddToExpr::Eval(Frame* f) const if ( ! v2 ) return nullptr; - if ( is_vector(v1) ) + if ( is_vector_elem_append ) { VectorVal* vv = v1->AsVectorVal(); @@ -1624,6 +1746,12 @@ ValPtr AddToExpr::Eval(Frame* f) const return v1; } + if ( type->Tag() == TYPE_PATTERN ) + { + v2->AddTo(v1.get(), false); + return v1; + } + if ( auto result = Fold(v1.get(), v2.get()) ) { op1->Assign(f, result); @@ -1684,18 +1812,35 @@ SubExpr::SubExpr(ExprPtr arg_op1, ExprPtr arg_op2) } RemoveFromExpr::RemoveFromExpr(ExprPtr arg_op1, ExprPtr arg_op2) - : BinaryExpr(EXPR_REMOVE_FROM, arg_op1->MakeLvalue(), std::move(arg_op2)) + : BinaryExpr(EXPR_REMOVE_FROM, std::move(arg_op1), std::move(arg_op2)) { if ( IsError() ) return; - TypeTag bt1 = op1->GetType()->Tag(); - TypeTag bt2 = op2->GetType()->Tag(); + auto& t1 = op1->GetType(); + auto& t2 = op2->GetType(); + TypeTag bt1 = t1->Tag(); + TypeTag bt2 = t2->Tag(); + + if ( bt1 != TYPE_TABLE ) + op1 = op1->MakeLvalue(); if ( BothArithmetic(bt1, bt2) ) PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2)); else if ( BothInterval(bt1, bt2) ) SetType(base_type(bt1)); + + else if ( bt2 == TYPE_LIST ) + (void)CheckForRHSList(); + + else if ( bt1 == TYPE_TABLE ) + { + if ( same_type(t1, t2) ) + SetType(t1); + else + ExprError("RHS type mismatch for table/set -="); + } + else ExprError("requires two arithmetic operands"); } @@ -2451,7 +2596,15 @@ AssignExpr::AssignExpr(ExprPtr arg_op1, ExprPtr arg_op2, bool arg_is_init, ValPt return; } - if ( typecheck ) + if ( op2->Tag() == EXPR_LIST && CheckForRHSList() ) + { + if ( op2->Tag() == EXPR_TABLE_CONSTRUCTOR ) + cast_intrusive(op2)->SetAttrs(attrs); + else if ( op2->Tag() == EXPR_SET_CONSTRUCTOR ) + cast_intrusive(op2)->SetAttrs(attrs); + } + + else if ( typecheck ) // We discard the status from TypeCheck since it has already // generated error messages. (void)TypeCheck(attrs); @@ -2493,25 +2646,6 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) return true; } - if ( bt1 == TYPE_TABLE && op2->Tag() == EXPR_LIST ) - { - std::unique_ptr> attr_copy; - - if ( attrs ) - attr_copy = std::make_unique>(attrs->GetAttrs()); - - if ( op1->GetType()->IsSet() ) - op2 = make_intrusive(cast_intrusive(op2), - std::move(attr_copy), op1->GetType()); - else - op2 = make_intrusive(cast_intrusive(op2), - std::move(attr_copy), op1->GetType()); - - // The constructor expressions are performing the type - // checking and will set op2 to an error state on failure. - return ! op2->IsError(); - } - if ( bt1 == TYPE_VECTOR ) { if ( bt2 == bt1 && op2->GetType()->AsVectorType()->IsUnspecifiedVector() ) @@ -2522,8 +2656,8 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) if ( op2->Tag() == EXPR_LIST ) { - op2 = make_intrusive( - IntrusivePtr{AdoptRef{}, op2.release()->AsListExpr()}, op1->GetType()); + op2 = make_intrusive(cast_intrusive(op2), + op1->GetType()); return true; } } @@ -2555,7 +2689,7 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) return false; } - ListExpr* ctor_list = dynamic_cast(sce->Op()); + auto ctor_list = cast_intrusive(sce->GetOp1()); if ( ! ctor_list ) { @@ -2572,8 +2706,8 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) } int errors_before = reporter->Errors(); - op2 = make_intrusive(IntrusivePtr{NewRef{}, ctor_list}, - std::move(attr_copy), op1->GetType()); + op2 = make_intrusive(ctor_list, std::move(attr_copy), + op1->GetType()); int errors_after = reporter->Errors(); if ( errors_after > errors_before ) @@ -2669,163 +2803,6 @@ TypePtr AssignExpr::InitType() const return make_intrusive(IntrusivePtr{NewRef{}, tl->AsTypeList()}, op2->GetType()); } -void AssignExpr::EvalIntoAggregate(const TypePtr& t, ValPtr aggr, Frame* f) const - { - if ( IsError() ) - return; - - TypeDecl td; - - if ( IsRecordElement(&td) ) - { - if ( t->Tag() != TYPE_RECORD ) - { - RuntimeError("not a record initializer"); - return; - } - - const RecordType* rt = t->AsRecordType(); - int field = rt->FieldOffset(td.id); - - if ( field < 0 ) - { - RuntimeError("no such field"); - return; - } - - RecordVal* aggr_r = aggr->AsRecordVal(); - - auto v = op2->Eval(f); - - if ( v ) - aggr_r->Assign(field, std::move(v)); - - return; - } - - if ( op1->Tag() != EXPR_LIST ) - RuntimeError("bad table insertion"); - - TableVal* tv = aggr->AsTableVal(); - - auto index = op1->Eval(f); - auto v = check_and_promote(op2->Eval(f), t->Yield(), true); - - if ( ! index || ! v ) - return; - - if ( ! tv->Assign(std::move(index), std::move(v)) ) - RuntimeError("type clash in table assignment"); - } - -ValPtr AssignExpr::InitVal(const TypePtr& t, ValPtr aggr) const - { - if ( ! aggr ) - { - Error("assignment in initialization"); - return nullptr; - } - - if ( IsError() ) - return nullptr; - - TypeDecl td; - - if ( IsRecordElement(&td) ) - { - if ( t->Tag() != TYPE_RECORD ) - { - Error("not a record initializer", t.get()); - return nullptr; - } - - const RecordType* rt = t->AsRecordType(); - int field = rt->FieldOffset(td.id); - - if ( field < 0 ) - { - Error("no such field"); - return nullptr; - } - - if ( aggr->GetType()->Tag() != TYPE_RECORD ) - Internal("bad aggregate in AssignExpr::InitVal"); - - RecordVal* aggr_r = aggr->AsRecordVal(); - - auto v = op2->InitVal(rt->GetFieldType(td.id), nullptr); - - if ( ! v ) - return nullptr; - - aggr_r->Assign(field, v); - return v; - } - - else if ( op1->Tag() == EXPR_LIST ) - { - if ( t->Tag() != TYPE_TABLE ) - { - Error("not a table initialization", t.get()); - return nullptr; - } - - if ( aggr->GetType()->Tag() != TYPE_TABLE ) - Internal("bad aggregate in AssignExpr::InitVal"); - - auto tv = cast_intrusive(std::move(aggr)); - const TableType* tt = tv->GetType()->AsTableType(); - const auto& yt = tv->GetType()->Yield(); - - auto index = op1->InitVal(tt->GetIndices(), nullptr); - - if ( yt->Tag() == TYPE_RECORD ) - { - if ( op2->GetType()->Tag() != TYPE_RECORD ) - { - Error(util::fmt("type mismatch in table value initialization: " - "assigning '%s' to table with values of type '%s'", - type_name(op2->GetType()->Tag()), type_name(yt->Tag()))); - return nullptr; - } - - if ( ! same_type(*yt, *op2->GetType()) && - ! record_promotion_compatible(yt->AsRecordType(), op2->GetType()->AsRecordType()) ) - { - Error("type mismatch in table value initialization: " - "incompatible record types"); - return nullptr; - } - } - else - { - if ( ! same_type(*yt, *op2->GetType(), true) ) - { - Error(util::fmt("type mismatch in table value initialization: " - "assigning '%s' to table with values of type '%s'", - type_name(op2->GetType()->Tag()), type_name(yt->Tag()))); - return nullptr; - } - } - - auto v = op2->InitVal(yt, nullptr); - - if ( ! index || ! v ) - return nullptr; - - if ( ! tv->ExpandAndInit(std::move(index), std::move(v)) ) - return nullptr; - - return tv; - } - - else - { - Error("illegal initializer"); - return nullptr; - } - } - bool AssignExpr::IsRecordElement(TypeDecl* td) const { if ( op1->Tag() == EXPR_NAME ) @@ -2843,11 +2820,6 @@ bool AssignExpr::IsRecordElement(TypeDecl* td) const return false; } -bool AssignExpr::IsPure() const - { - return false; - } - IndexSliceAssignExpr::IndexSliceAssignExpr(ExprPtr op1, ExprPtr op2, bool is_init) : AssignExpr(std::move(op1), std::move(op2), is_init) { @@ -3427,34 +3399,6 @@ RecordConstructorExpr::RecordConstructorExpr(RecordTypePtr known_rt, ListExprPtr } } -ValPtr RecordConstructorExpr::InitVal(const TypePtr& t, ValPtr aggr) const - { - if ( IsError() ) - { - Error("bad record initializer"); - return nullptr; - } - - if ( ! init_tag_check(this, "record constructor", TYPE_RECORD, t->Tag()) ) - return nullptr; - - auto v = Eval(nullptr); - - if ( v ) - { - RecordVal* rv = v->AsRecordVal(); - RecordTypePtr rt{NewRef{}, t->AsRecordType()}; - auto aggr_rec = cast_intrusive(std::move(aggr)); - auto ar = rv->CoerceTo(std::move(rt), std::move(aggr_rec)); - - if ( ar ) - return ar; - } - - Error("bad record initializer"); - return nullptr; - } - ValPtr RecordConstructorExpr::Eval(Frame* f) const { if ( IsError() ) @@ -3522,10 +3466,161 @@ TraversalCode RecordConstructorExpr::Traverse(TraversalCallback* cb) const HANDLE_TC_EXPR_POST(tc); } +static ExprPtr expand_one_elem(const ExprPList& index_exprs, ExprPtr yield, ExprPtr elem, + int elem_offset) + { + auto expanded_elem = make_intrusive(); + + for ( int i = 0; i < index_exprs.length(); ++i ) + if ( i == elem_offset ) + expanded_elem->Append(elem); + else + expanded_elem->Append({NewRef{}, index_exprs[i]}); + + if ( yield ) + return make_intrusive(expanded_elem, yield, true); + else + return expanded_elem; + } + +static bool expand_op_elem(ListExprPtr elems, ExprPtr elem, TypePtr t) + { + ExprPtr index; + ExprPtr yield; + + if ( elem->Tag() == EXPR_ASSIGN ) + { + if ( t ) + { + if ( ! t->IsTable() ) + { + elem->Error("table constructor used in a non-table context"); + return false; + } + + t = t->AsTableType()->GetIndices(); + } + + index = elem->GetOp1(); + yield = elem->GetOp2(); + } + else + index = elem; // this is a set - no yield + + // If the index isn't a list, then there's nothing to consider + // expanding. + if ( index->Tag() != EXPR_LIST ) + { + elems->Append(elem); + return false; + } + + // Look inside the index for any sub-lists or sets, and expand those. + // There might be more than one, but we'll pick that up recursively + // later. + auto& index_exprs = index->AsListExpr()->Exprs(); + int index_n = index_exprs.length(); + int list_offset = -1; + int set_offset = -1; + for ( int i = 0; i < index_n; ++i ) + { + auto& ie_i = index_exprs[i]; + + if ( ie_i->Tag() == EXPR_LIST ) + { + list_offset = i; + break; + } + + if ( ie_i->GetType()->IsSet() ) + { + // Check for this set corresponding to what's expected + // in this location, in which case it shouldn't be + // expanded. + const TypeList* tl = nullptr; + if ( t && t->Tag() == TYPE_LIST ) + tl = t->AsTypeList(); + + // So we're good-to-go in expanding if either + // (1) we weren't given a type, or it's not a list, + // or (2) it's a list, but doesn't correspond in + // length to the list of expressions, or (3) it does + // but its corresponding element at this position + // doesn't have the same type as this set. + if ( ! tl || static_cast(tl->GetTypes().size()) != index_n || + ! same_type(tl->GetTypes()[i], ie_i->GetType()) ) + { + set_offset = i; + break; + } + } + } + + if ( set_offset >= 0 ) + { // expand the set + auto s_e = index_exprs[set_offset]; + auto v = s_e->Eval(nullptr); + if ( ! v ) + { + s_e->Error( + "cannot expand constructor elements using a value that depends on local variables"); + elems->SetError(); + return false; + } + + for ( auto& s_elem : v->AsTableVal()->ToMap() ) + { + auto c_elem = make_intrusive(s_elem.first); + elems->Append(expand_one_elem(index_exprs, yield, c_elem, set_offset)); + } + + return true; + } + + if ( list_offset < 0 ) + { // No embedded lists. + elems->Append(elem); + return false; + } + + // Expand the identified list. + auto sub_list = index_exprs[list_offset]->AsListExpr(); + for ( auto& sub_list_i : sub_list->Exprs() ) + { + ExprPtr e = {NewRef{}, sub_list_i}; + elems->Append(expand_one_elem(index_exprs, yield, e, list_offset)); + } + + return true; + } + +ListExprPtr expand_op(ListExprPtr op, const TypePtr& t) + { + auto new_list = make_intrusive(); + bool did_expansion = false; + + for ( auto e : op->Exprs() ) + { + if ( expand_op_elem(new_list, {NewRef{}, e}, t) ) + did_expansion = true; + + if ( new_list->IsError() ) + { + op->SetError(); + return op; + } + } + + if ( did_expansion ) + return expand_op(new_list, t); + else + return op; + } + TableConstructorExpr::TableConstructorExpr(ListExprPtr constructor_list, std::unique_ptr> arg_attrs, TypePtr arg_type, AttributesPtr arg_attrs2) - : UnaryExpr(EXPR_TABLE_CONSTRUCTOR, std::move(constructor_list)) + : UnaryExpr(EXPR_TABLE_CONSTRUCTOR, expand_op(constructor_list, arg_type)) { if ( IsError() ) return; @@ -3548,7 +3643,7 @@ TableConstructorExpr::TableConstructorExpr(ListExprPtr constructor_list, make_intrusive(make_intrusive(base_type(TYPE_ANY)), nullptr)); else { - SetType(init_type(op.get())); + SetType(init_type(op)); if ( ! type ) { @@ -3557,14 +3652,17 @@ TableConstructorExpr::TableConstructorExpr(ListExprPtr constructor_list, } else if ( type->Tag() != TYPE_TABLE || type->AsTableType()->IsSet() ) + { SetError("values in table(...) constructor do not specify a table"); + return; + } } } if ( arg_attrs ) - attrs = make_intrusive(std::move(*arg_attrs), type, false, false); + SetAttrs(make_intrusive(std::move(*arg_attrs), type, false, false)); else - attrs = arg_attrs2; + SetAttrs(arg_attrs2); const auto& indices = type->AsTableType()->GetIndices()->GetTypes(); const ExprPList& cle = op->AsListExpr()->Exprs(); @@ -3573,7 +3671,11 @@ TableConstructorExpr::TableConstructorExpr(ListExprPtr constructor_list, for ( const auto& expr : cle ) { if ( expr->Tag() != EXPR_ASSIGN ) - continue; + { + expr->Error("illegal table constructor element"); + SetError(); + return; + } auto idx_expr = expr->AsAssignExpr()->GetOp1(); auto val_expr = expr->AsAssignExpr()->GetOp2(); @@ -3623,35 +3725,30 @@ ValPtr TableConstructorExpr::Eval(Frame* f) const if ( IsError() ) return nullptr; - auto aggr = make_intrusive(GetType(), attrs); + auto tv = make_intrusive(GetType(), attrs); const ExprPList& exprs = op->AsListExpr()->Exprs(); for ( const auto& expr : exprs ) - expr->EvalIntoAggregate(type, aggr, f); + { + auto op1 = expr->GetOp1(); + auto op2 = expr->GetOp2(); - aggr->InitDefaultFunc(f); + if ( ! op1 || ! op2 ) + return nullptr; - return aggr; - } + auto index = op1->Eval(f); + auto v = op2->Eval(f); -ValPtr TableConstructorExpr::InitVal(const TypePtr& t, ValPtr aggr) const - { - if ( IsError() ) - return nullptr; + if ( ! index || ! v ) + return nullptr; - if ( ! init_tag_check(this, "table constructor", TYPE_TABLE, t->Tag()) ) - return nullptr; + if ( ! tv->Assign(std::move(index), std::move(v)) ) + RuntimeError("type clash in table assignment"); + } - auto tt = GetType(); + tv->InitDefaultFunc(f); - auto tval = aggr ? TableValPtr{AdoptRef{}, aggr.release()->AsTableVal()} - : make_intrusive(std::move(tt), attrs); - const ExprPList& exprs = op->AsListExpr()->Exprs(); - - for ( const auto& expr : exprs ) - expr->EvalIntoAggregate(t, tval, nullptr); - - return tval; + return tv; } void TableConstructorExpr::ExprDescribe(ODesc* d) const @@ -3664,7 +3761,7 @@ void TableConstructorExpr::ExprDescribe(ODesc* d) const SetConstructorExpr::SetConstructorExpr(ListExprPtr constructor_list, std::unique_ptr> arg_attrs, TypePtr arg_type, AttributesPtr arg_attrs2) - : UnaryExpr(EXPR_SET_CONSTRUCTOR, std::move(constructor_list)) + : UnaryExpr(EXPR_SET_CONSTRUCTOR, expand_op(constructor_list, arg_type)) { if ( IsError() ) return; @@ -3686,7 +3783,7 @@ SetConstructorExpr::SetConstructorExpr(ListExprPtr constructor_list, SetType(make_intrusive(make_intrusive(base_type(TYPE_ANY)), nullptr)); else - SetType(init_type(op.get())); + SetType(init_type(op)); } if ( ! type ) @@ -3696,9 +3793,9 @@ SetConstructorExpr::SetConstructorExpr(ListExprPtr constructor_list, SetError("values in set(...) constructor do not specify a set"); if ( arg_attrs ) - attrs = make_intrusive(std::move(*arg_attrs), type, false, false); + SetAttrs(make_intrusive(std::move(*arg_attrs), type, false, false)); else - attrs = arg_attrs2; + SetAttrs(arg_attrs2); const auto& indices = type->AsTableType()->GetIndices()->GetTypes(); ExprPList& cle = op->AsListExpr()->Exprs(); @@ -3715,9 +3812,16 @@ SetConstructorExpr::SetConstructorExpr(ListExprPtr constructor_list, loop_over_list(cle, i) { Expr* ce = cle[i]; + + if ( ce->Tag() != EXPR_LIST ) + { + ce->Error("not a list of indices"); + SetError(); + return; + } + ListExpr* le = ce->AsListExpr(); - assert(ce->Tag() == EXPR_LIST); if ( check_and_promote_exprs(le, type->AsTableType()->GetIndices()) ) { if ( le != cle[i] ) @@ -3748,34 +3852,6 @@ ValPtr SetConstructorExpr::Eval(Frame* f) const return aggr; } -ValPtr SetConstructorExpr::InitVal(const TypePtr& t, ValPtr aggr) const - { - if ( IsError() ) - return nullptr; - - if ( ! init_tag_check(this, "set constructor", TYPE_TABLE, t->Tag()) ) - return nullptr; - - const auto& index_type = t->AsTableType()->GetIndices(); - auto tt = GetType(); - auto tval = aggr ? TableValPtr{AdoptRef{}, aggr.release()->AsTableVal()} - : make_intrusive(std::move(tt), attrs); - const ExprPList& exprs = op->AsListExpr()->Exprs(); - - for ( const auto& e : exprs ) - { - auto element = check_and_promote(e->Eval(nullptr), index_type, true); - - if ( ! element || ! tval->Assign(std::move(element), nullptr) ) - { - Error(util::fmt("initialization type mismatch in set"), e); - return nullptr; - } - } - - return tval; - } - void SetConstructorExpr::ExprDescribe(ODesc* d) const { d->Add("set("); @@ -3846,34 +3922,6 @@ ValPtr VectorConstructorExpr::Eval(Frame* f) const return vec; } -ValPtr VectorConstructorExpr::InitVal(const TypePtr& t, ValPtr aggr) const - { - if ( IsError() ) - return nullptr; - - if ( ! init_tag_check(this, "vector constructor", TYPE_VECTOR, t->Tag()) ) - return nullptr; - - auto vt = GetType(); - auto vec = aggr ? VectorValPtr{AdoptRef{}, aggr.release()->AsVectorVal()} - : make_intrusive(std::move(vt)); - const ExprPList& exprs = op->AsListExpr()->Exprs(); - - loop_over_list(exprs, i) - { - Expr* e = exprs[i]; - auto v = check_and_promote(e->Eval(nullptr), t->Yield(), true); - - if ( ! v || ! vec->Assign(i, std::move(v)) ) - { - Error(util::fmt("initialization type mismatch at index %d", i), e); - return nullptr; - } - } - - return vec; - } - void VectorConstructorExpr::ExprDescribe(ODesc* d) const { d->Add("vector("); @@ -3893,25 +3941,6 @@ bool FieldAssignExpr::PromoteTo(TypePtr t) return op != nullptr; } -void FieldAssignExpr::EvalIntoAggregate(const TypePtr& t, ValPtr aggr, Frame* f) const - { - if ( IsError() ) - return; - - if ( auto v = op->Eval(f) ) - { - RecordVal* rec = aggr->AsRecordVal(); - const RecordType* rt = t->AsRecordType(); - - int idx = rt->FieldOffset(field_name.c_str()); - - if ( idx < 0 ) - reporter->InternalError("Missing record field: %s", field_name.c_str()); - - rec->Assign(idx, std::move(v)); - } - } - bool FieldAssignExpr::IsRecordElement(TypeDecl* td) const { if ( td ) @@ -4101,31 +4130,6 @@ RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r) } } -ValPtr RecordCoerceExpr::InitVal(const TypePtr& t, ValPtr aggr) const - { - if ( IsError() ) - { - Error("bad record initializer"); - return nullptr; - } - - if ( ! init_tag_check(this, "record", TYPE_RECORD, t->Tag()) ) - return nullptr; - - if ( auto v = Eval(nullptr) ) - { - RecordVal* rv = v->AsRecordVal(); - RecordTypePtr rt{NewRef{}, t->AsRecordType()}; - auto aggr_rec = cast_intrusive(std::move(aggr)); - - if ( auto ar = rv->CoerceTo(std::move(rt), std::move(aggr_rec)) ) - return ar; - } - - Error("bad record initializer"); - return nullptr; - } - ValPtr RecordCoerceExpr::Fold(Val* v) const { if ( same_type(GetType(), Op()->GetType()) ) @@ -4300,11 +4304,6 @@ ScheduleExpr::ScheduleExpr(ExprPtr arg_when, EventExprPtr arg_event) ExprError("schedule expression requires a time or time interval"); } -bool ScheduleExpr::IsPure() const - { - return false; - } - ValPtr ScheduleExpr::Eval(Frame* f) const { if ( run_state::terminating ) @@ -4999,202 +4998,6 @@ TypePtr ListExpr::InitType() const } } -ValPtr ListExpr::InitVal(const TypePtr& t, ValPtr aggr) const - { - // While fairly similar to the EvalIntoAggregate() code, - // we keep this separate since it also deals with initialization - // idioms such as embedded aggregates and cross-product - // expansion. - if ( IsError() ) - return nullptr; - - // Check whether each element of this list itself matches t, - // in which case we should expand as a ListVal. - if ( ! aggr && type->AsTypeList()->AllMatch(t, true) ) - { - auto v = make_intrusive(TYPE_ANY); - const auto& tl = type->AsTypeList()->GetTypes(); - - if ( exprs.length() != static_cast(tl.size()) ) - { - Error("index mismatch", t.get()); - return nullptr; - } - - loop_over_list(exprs, i) - { - auto vi = exprs[i]->InitVal(tl[i], nullptr); - if ( ! vi ) - return nullptr; - - v->Append(std::move(vi)); - } - - return v; - } - - if ( t->Tag() == TYPE_LIST ) - { - if ( aggr ) - { - Error("bad use of list in initialization", t.get()); - return nullptr; - } - - const auto& tl = t->AsTypeList()->GetTypes(); - - if ( exprs.length() != static_cast(tl.size()) ) - { - Error("index mismatch", t.get()); - return nullptr; - } - - auto v = make_intrusive(TYPE_ANY); - - loop_over_list(exprs, i) - { - auto vi = exprs[i]->InitVal(tl[i], nullptr); - - if ( ! vi ) - return nullptr; - - v->Append(std::move(vi)); - } - - return v; - } - - if ( t->Tag() != TYPE_RECORD && t->Tag() != TYPE_TABLE && t->Tag() != TYPE_VECTOR ) - { - if ( exprs.length() == 1 ) - // Allow "global x:int = { 5 }" - return exprs[0]->InitVal(t, aggr); - else - { - Error("aggregate initializer for scalar type", t.get()); - return nullptr; - } - } - - if ( ! aggr ) - Internal("missing aggregate in ListExpr::InitVal"); - - if ( t->IsSet() ) - return AddSetInit(t, std::move(aggr)); - - if ( t->Tag() == TYPE_VECTOR ) - { - // v: vector = [10, 20, 30]; - VectorVal* vec = aggr->AsVectorVal(); - - loop_over_list(exprs, i) - { - ExprPtr e = {NewRef{}, exprs[i]}; - const auto& vyt = vec->GetType()->AsVectorType()->Yield(); - auto promoted_e = check_and_promote_expr(e, vyt); - - if ( promoted_e ) - e = promoted_e; - - if ( ! vec->Assign(i, e->Eval(nullptr)) ) - { - e->Error(util::fmt("type mismatch at index %d", i)); - return nullptr; - } - } - - return aggr; - } - - // If we got this far, then it's either a table or record - // initialization. Both of those involve AssignExpr's, which - // know how to add themselves to a table or record. Another - // possibility is an expression that evaluates itself to a - // table, which we can then add to the aggregate. - for ( const auto& e : exprs ) - { - if ( e->Tag() == EXPR_ASSIGN || e->Tag() == EXPR_FIELD_ASSIGN ) - { - if ( ! e->InitVal(t, aggr) ) - return nullptr; - } - else - { - if ( t->Tag() == TYPE_RECORD ) - { - e->Error("bad record initializer", t.get()); - return nullptr; - } - - auto v = e->Eval(nullptr); - - if ( ! same_type(v->GetType(), t) ) - { - v->GetType()->Error("type clash in table initializer", t.get()); - return nullptr; - } - - if ( ! v->AsTableVal()->AddTo(aggr->AsTableVal(), true) ) - return nullptr; - } - } - - return aggr; - } - -ValPtr ListExpr::AddSetInit(TypePtr t, ValPtr aggr) const - { - if ( aggr->GetType()->Tag() != TYPE_TABLE ) - Internal("bad aggregate in ListExpr::AddSetInit"); - - TableVal* tv = aggr->AsTableVal(); - const TableType* tt = tv->GetType()->AsTableType(); - TypeListPtr it = tt->GetIndices(); - - for ( const auto& expr : exprs ) - { - ValPtr element; - - if ( expr->GetType()->IsSet() ) - // A set to flatten. - element = expr->Eval(nullptr); - else if ( expr->GetType()->Tag() == TYPE_LIST ) - element = expr->InitVal(it, nullptr); - else - element = expr->InitVal(it->GetTypes()[0], nullptr); - - if ( ! element ) - return nullptr; - - if ( element->GetType()->IsSet() ) - { - if ( ! same_type(element->GetType(), t) ) - { - element->Error("type clash in set initializer", t.get()); - return nullptr; - } - - if ( ! element->AsTableVal()->AddTo(tv, true) ) - return nullptr; - - continue; - } - - if ( expr->GetType()->Tag() == TYPE_LIST ) - element = check_and_promote(std::move(element), it, true); - else - element = check_and_promote(std::move(element), it->GetTypes()[0], true); - - if ( ! element ) - return nullptr; - - if ( ! tv->ExpandAndInit(std::move(element), nullptr) ) - return nullptr; - } - - return aggr; - } - void ListExpr::ExprDescribe(ODesc* d) const { d->AddCount(exprs.length()); diff --git a/src/Expr.h b/src/Expr.h index c7eb4cea21..7b8c38ff6e 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -164,12 +164,6 @@ public: // or nil if the expression's value isn't fixed. virtual ValPtr Eval(Frame* f) const = 0; - // Same, but the context is that we are adding an element - // into the given aggregate of the given type. Note that - // return type is void since it's updating an existing - // value, rather than creating a new one. - virtual void EvalIntoAggregate(const TypePtr& t, ValPtr aggr, Frame* f) const; - // Assign to the given value, if appropriate. virtual void Assign(Frame* f, ValPtr v); @@ -183,15 +177,8 @@ public: // TypeDecl with a description of the element. virtual bool IsRecordElement(TypeDecl* td) const; - // Returns a value corresponding to this expression interpreted - // as an initialization, or nil if the expression is inconsistent - // with the given type. If "aggr" is non-nil, then this expression - // is an element of the given aggregate, and it is added to it - // accordingly. - virtual ValPtr InitVal(const TypePtr& t, ValPtr aggr) const; - // True if the expression has no side effects, false otherwise. - virtual bool IsPure() const; + virtual bool IsPure() const { return true; } // True if the expression is a constant, false otherwise. bool IsConst() const { return tag == EXPR_CONST; } @@ -467,7 +454,6 @@ public: ValPtr Eval(Frame* f) const override; void Assign(Frame* f, ValPtr v) override; ExprPtr MakeLvalue() override; - bool IsPure() const override; TraversalCode Traverse(TraversalCallback* cb) const override; @@ -599,6 +585,9 @@ protected: // Same for when the constants are sets. virtual ValPtr SetFold(Val* v1, Val* v2) const; + // Same for when the constants are tables. + virtual ValPtr TableFold(Val* v1, Val* v2) const; + // Same for when the constants are addresses or subnets. virtual ValPtr AddrFold(Val* v1, Val* v2) const; virtual ValPtr SubNetFold(Val* v1, Val* v2) const; @@ -630,6 +619,12 @@ protected: // `[1, 2, 3] == 1` or `["a", "b", "c"] + "a"`. void CheckScalarAggOp() const; + // For assignment operations (=, +=, -=) checks for a valid + // expression-list on the RHS (op2), potentially transforming + // op2 in the process. Returns true if the list is present + // and type-checks correctly, false otherwise. + bool CheckForRHSList(); + ExprPtr op1; ExprPtr op2; }; @@ -654,7 +649,7 @@ public: ValPtr Eval(Frame* f) const override; ValPtr DoSingleEval(Frame* f, Val* v) const; - bool IsPure() const override; + bool IsPure() const override { return false; } // Optimization-related: ExprPtr Duplicate() override; @@ -757,21 +752,33 @@ public: ValPtr Eval(Frame* f) const override; // Optimization-related: + bool IsPure() const override { return false; } ExprPtr Duplicate() override; + bool HasReducedOps(Reducer* c) const override { return false; } bool WillTransform(Reducer* c) const override { return true; } + bool IsReduced(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; + +private: + // Whether this operation is appending a single element to a vector. + bool is_vector_elem_append = false; }; class RemoveFromExpr final : public BinaryExpr { public: + bool IsPure() const override { return false; } RemoveFromExpr(ExprPtr op1, ExprPtr op2); ValPtr Eval(Frame* f) const override; // Optimization-related: ExprPtr Duplicate() override; + bool HasReducedOps(Reducer* c) const override { return false; } bool WillTransform(Reducer* c) const override { return true; } + bool IsReduced(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; + ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; }; class SubExpr final : public BinaryExpr @@ -948,11 +955,9 @@ public: const AttributesPtr& attrs = nullptr, bool type_check = true); ValPtr Eval(Frame* f) const override; - void EvalIntoAggregate(const TypePtr& t, ValPtr aggr, Frame* f) const override; TypePtr InitType() const override; bool IsRecordElement(TypeDecl* td) const override; - ValPtr InitVal(const TypePtr& t, ValPtr aggr) const override; - bool IsPure() const override; + bool IsPure() const override { return false; } // Optimization-related: ExprPtr Duplicate() override; @@ -1168,8 +1173,6 @@ public: StmtPtr ReduceToSingletons(Reducer* c) override; protected: - ValPtr InitVal(const TypePtr& t, ValPtr aggr) const override; - void ExprDescribe(ODesc* d) const override; ListExprPtr op; @@ -1182,6 +1185,7 @@ public: TableConstructorExpr(ListExprPtr constructor_list, std::unique_ptr> attrs, TypePtr arg_type = nullptr, AttributesPtr arg_attrs = nullptr); + void SetAttrs(AttributesPtr _attrs) { attrs = std::move(_attrs); } const AttributesPtr& GetAttrs() const { return attrs; } ValPtr Eval(Frame* f) const override; @@ -1194,8 +1198,6 @@ public: StmtPtr ReduceToSingletons(Reducer* c) override; protected: - ValPtr InitVal(const TypePtr& t, ValPtr aggr) const override; - void ExprDescribe(ODesc* d) const override; AttributesPtr attrs; @@ -1207,6 +1209,7 @@ public: SetConstructorExpr(ListExprPtr constructor_list, std::unique_ptr> attrs, TypePtr arg_type = nullptr, AttributesPtr arg_attrs = nullptr); + void SetAttrs(AttributesPtr _attrs) { attrs = std::move(_attrs); } const AttributesPtr& GetAttrs() const { return attrs; } ValPtr Eval(Frame* f) const override; @@ -1219,8 +1222,6 @@ public: StmtPtr ReduceToSingletons(Reducer* c) override; protected: - ValPtr InitVal(const TypePtr& t, ValPtr aggr) const override; - void ExprDescribe(ODesc* d) const override; AttributesPtr attrs; @@ -1239,8 +1240,6 @@ public: bool HasReducedOps(Reducer* c) const override; protected: - ValPtr InitVal(const TypePtr& t, ValPtr aggr) const override; - void ExprDescribe(ODesc* d) const override; }; @@ -1259,12 +1258,10 @@ public: // (in which case an error is reported). bool PromoteTo(TypePtr t); - void EvalIntoAggregate(const TypePtr& t, ValPtr aggr, Frame* f) const override; bool IsRecordElement(TypeDecl* td) const override; // Optimization-related: ExprPtr Duplicate() override; - bool WillTransform(Reducer* c) const override { return true; } ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; @@ -1301,7 +1298,6 @@ public: const std::vector& Map() const { return map; } protected: - ValPtr InitVal(const TypePtr& t, ValPtr aggr) const override; ValPtr Fold(Val* v) const override; // For each super-record slot, gives subrecord slot with which to @@ -1355,7 +1351,7 @@ class ScheduleExpr final : public Expr public: ScheduleExpr(ExprPtr when, EventExprPtr event); - bool IsPure() const override; + bool IsPure() const override { return false; } ValPtr Eval(Frame* f) const override; @@ -1490,7 +1486,6 @@ public: ValPtr Eval(Frame* f) const override; TypePtr InitType() const override; - ValPtr InitVal(const TypePtr& t, ValPtr aggr) const override; ExprPtr MakeLvalue() override; void Assign(Frame* f, ValPtr v) override; @@ -1506,8 +1501,6 @@ public: StmtPtr ReduceToSingletons(Reducer* c) override; protected: - ValPtr AddSetInit(TypePtr t, ValPtr aggr) const; - void ExprDescribe(ODesc* d) const override; ExprPList exprs; @@ -1625,10 +1618,12 @@ public: AppendToExpr(ExprPtr op1, ExprPtr op2); ValPtr Eval(Frame* f) const override; + ExprPtr Duplicate() override; + + bool IsPure() const override { return false; } bool IsReduced(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; - - ExprPtr Duplicate() override; + ExprPtr ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) override; }; // An internal class for reduced form. @@ -1642,6 +1637,7 @@ public: ExprPtr Duplicate() override; + bool IsPure() const override { return false; } bool IsReduced(Reducer* c) const override; bool HasReducedOps(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; @@ -1673,6 +1669,7 @@ public: ExprPtr Duplicate() override; + bool IsPure() const override { return false; } bool IsReduced(Reducer* c) const override; bool HasReducedOps(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; @@ -1772,7 +1769,14 @@ inline Val* Expr::ExprVal() const } // Decides whether to return an AssignExpr or a RecordAssignExpr. -ExprPtr get_assign_expr(ExprPtr op1, ExprPtr op2, bool is_init); +extern ExprPtr get_assign_expr(ExprPtr op1, ExprPtr op2, bool is_init); + +// Takes a RHS constructor list and returns a version with any embedded +// indices within it (used to concisely represent multiple set/table entries) +// expanded. +// +// Second argument gives the type that the list will expand to, if known. +extern ListExprPtr expand_op(ListExprPtr op, const TypePtr& t); /** * Type-check the given expression(s) against the given type(s). Complain @@ -1793,7 +1797,7 @@ extern bool check_and_promote_exprs_to_type(ListExpr* elements, TypePtr type); // Returns a ListExpr simplified down to a list a values, or nil // if they couldn't all be reduced. -std::optional> eval_list(Frame* f, const ListExpr* l); +extern std::optional> eval_list(Frame* f, const ListExpr* l); // Returns true if e1 is "greater" than e2 - here "greater" is just // a heuristic, used with commutative operators to put them into From 72b937bfdf92680571c06cc96030cb94afa7ec26 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:20:09 -0800 Subject: [PATCH 096/204] avoid evaluating calls to determine whether an expression value is ignored --- src/Stmt.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stmt.cc b/src/Stmt.cc index 7cbb13d7da..0467dad9ee 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -396,7 +396,7 @@ void do_print_stmt(const std::vector& vals) ExprStmt::ExprStmt(ExprPtr arg_e) : Stmt(STMT_EXPR), e(std::move(arg_e)) { - if ( e && e->IsPure() && e->GetType()->Tag() != TYPE_ERROR ) + if ( e && e->Tag() != EXPR_CALL && e->IsPure() && e->GetType()->Tag() != TYPE_ERROR ) Warn("expression value ignored"); SetLocationInfo(e->GetLocationInfo()); From 96f52b0e112da8236d1117a2201d28948fab0354 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:21:06 -0800 Subject: [PATCH 097/204] rework type inference due to switch from separate initializers to expressions --- src/Type.cc | 137 +++++++++++++++++++++++++++++----------------------- src/Type.h | 2 +- 2 files changed, 78 insertions(+), 61 deletions(-) diff --git a/src/Type.cc b/src/Type.cc index 19f585f0ae..ea32088693 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -2510,26 +2510,85 @@ static Type* reduce_type(Type* t) return t; } -TypePtr init_type(detail::Expr* init) +static TableTypePtr init_table_type(detail::ListExpr* l) { - if ( init->Tag() != detail::EXPR_LIST ) + auto& elems = l->Exprs(); + TypePtr index; + TypePtr yield; + + for ( auto e : elems ) { - auto t = init->InitType(); - - if ( ! t ) - return nullptr; - - if ( t->Tag() == TYPE_LIST && t->AsTypeList()->GetTypes().size() != 1 ) + if ( e->Tag() != detail::EXPR_ASSIGN ) { - init->Error("list used in scalar initialization"); + e->Error("table constructor element lacks '=' structure"); return nullptr; } - return t; + auto& ind = e->GetOp1()->GetType(); + auto& y = e->GetOp2()->GetType(); + + if ( ! index ) + { + index = ind; + yield = y; + continue; + } + + index = merge_types(index, ind); + yield = merge_types(yield, y); + + if ( ! index || ! yield ) + // Error message already generated. + return nullptr; } - detail::ListExpr* init_list = init->AsListExpr(); - const ExprPList& el = init_list->Exprs(); + if ( index->Tag() != TYPE_LIST ) + return nullptr; + + return make_intrusive(cast_intrusive(index), yield); + } + +static SetTypePtr init_set_type(detail::ListExpr* l) + { + auto& elems = l->Exprs(); + TypePtr index; + + for ( auto e : elems ) + { + auto& ind = e->GetType(); + + if ( ! index ) + { + index = ind; + continue; + } + + index = merge_types(index, ind); + + if ( ! index ) + return nullptr; + } + + TypeListPtr ind_list; + + if ( index->Tag() == TYPE_LIST ) + ind_list = cast_intrusive(index); + else + { + ind_list = make_intrusive(index); + ind_list->Append(index); + } + + return make_intrusive(ind_list, nullptr); + } + +TypePtr init_type(const detail::ExprPtr& init) + { + if ( init->Tag() != detail::EXPR_LIST ) + return init->InitType(); + + auto init_list = init->AsListExpr(); + const auto& el = init_list->Exprs(); if ( el.length() == 0 ) { @@ -2538,58 +2597,16 @@ TypePtr init_type(detail::Expr* init) } // Could be a record, a set, or a list of table elements. - detail::Expr* e0 = el[0]; + auto e0 = el[0]; if ( e0->IsRecordElement(nullptr) ) - // ListExpr's know how to build a record from their - // components. + // ListExpr's know how to build a record from their components. return init_list->InitType(); - auto t = e0->InitType(); - - if ( t ) - t = {NewRef{}, reduce_type(t.get())}; - - if ( ! t ) - return nullptr; - - for ( int i = 1; t && i < el.length(); ++i ) - { - auto el_t = el[i]->InitType(); - TypePtr ti; - - if ( el_t ) - ti = {NewRef{}, reduce_type(el_t.get())}; - - if ( ! ti ) - return nullptr; - - if ( same_type(t, ti) ) - continue; - - t = merge_types(t, ti); - } - - if ( ! t ) - { - init->Error("type error in initialization"); - return nullptr; - } - - if ( t->Tag() == TYPE_TABLE && ! t->AsTableType()->IsSet() ) - // A list of table elements. - return t; - - // A set. If the index type isn't yet a type list, make - // it one, as that's what's required for creating a set type. - if ( t->Tag() != TYPE_LIST ) - { - auto tl = make_intrusive(t); - tl->Append(std::move(t)); - t = std::move(tl); - } - - return make_intrusive(cast_intrusive(std::move(t)), nullptr); + if ( e0->Tag() == detail::EXPR_ASSIGN ) + return init_table_type(init_list); + else + return init_set_type(init_list); } bool is_atomic_type(const Type& t) diff --git a/src/Type.h b/src/Type.h index e13ec6d7fb..b77e558e4c 100644 --- a/src/Type.h +++ b/src/Type.h @@ -900,7 +900,7 @@ TypePtr merge_types(const TypePtr& t1, const TypePtr& t2); TypePtr merge_type_list(detail::ListExpr* elements); // Given an expression, infer its type when used for an initialization. -TypePtr init_type(detail::Expr* init); +TypePtr init_type(const detail::ExprPtr& init); // Returns true if argument is an atomic type. bool is_atomic_type(const Type& t); From 0bbbd84c9d1a62bf394af7a03c435f79e877e955 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:21:59 -0800 Subject: [PATCH 098/204] use new interface for associating attributes with constructors --- src/ID.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/ID.cc b/src/ID.cc index b58cf2e872..dd9b39a73d 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -248,13 +248,9 @@ void ID::UpdateValAttrs() if ( ! attrs ) return; - if ( val && val->GetType()->Tag() == TYPE_TABLE ) - val->AsTableVal()->SetAttrs(attrs); + auto tag = GetType()->Tag(); - if ( val && val->GetType()->Tag() == TYPE_FILE ) - val->AsFile()->SetAttrs(attrs.get()); - - if ( GetType()->Tag() == TYPE_FUNC ) + if ( tag == TYPE_FUNC ) { const auto& attr = attrs->Find(ATTR_ERROR_HANDLER); @@ -262,7 +258,7 @@ void ID::UpdateValAttrs() event_registry->SetErrorHandler(Name()); } - if ( GetType()->Tag() == TYPE_RECORD ) + if ( tag == TYPE_RECORD ) { const auto& attr = attrs->Find(ATTR_LOG); @@ -281,6 +277,17 @@ void ID::UpdateValAttrs() } } } + + if ( ! val ) + return; + + auto vtag = val->GetType()->Tag(); + + if ( vtag == TYPE_TABLE ) + val->AsTableVal()->SetAttrs(attrs); + + else if ( vtag == TYPE_FILE ) + val->AsFile()->SetAttrs(attrs.get()); } const AttrPtr& ID::GetAttr(AttrTag t) const From 9b6a3e8b74019b581c03684285f4a35190543885 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:22:42 -0800 Subject: [PATCH 099/204] factoring and re-working of type merging --- src/Type.cc | 380 +++++++++++++++++++++++++++++----------------------- 1 file changed, 213 insertions(+), 167 deletions(-) diff --git a/src/Type.cc b/src/Type.cc index ea32088693..77d5663919 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -2233,12 +2233,218 @@ TypeTag max_type(TypeTag t1, TypeTag t2) } } +TypePtr merge_enum_types(const Type* t1, const Type* t2) + { + // Could compare pointers t1 == t2, but maybe there's someone out + // there creating clones of the type, so safer to compare name. + if ( t1->GetName() != t2->GetName() ) + { + std::string msg = util::fmt("incompatible enum types: '%s' and '%s'", t1->GetName().data(), + t2->GetName().data()); + + t1->Error(msg.data(), t2); + return nullptr; + } + + // Doing a lookup here as a roundabout way of ref-ing t1, without + // changing the function params which has t1 as const and also + // (potentially) avoiding a pitfall mentioned earlier about clones. + const auto& id = detail::global_scope()->Find(t1->GetName()); + + if ( id && id->IsType() && id->GetType()->Tag() == TYPE_ENUM ) + // It should make most sense to return the real type here rather + // than a copy since it may be redef'd later in parsing. If we + // return a copy, then whoever is using this return value won't + // actually see those changes from the redef. + return id->GetType(); + + std::string msg = util::fmt("incompatible enum types: '%s' and '%s'" + " ('%s' enum type ID is invalid)", + t1->GetName().data(), t2->GetName().data(), t1->GetName().data()); + t1->Error(msg.data(), t2); + return nullptr; + } + +TypePtr merge_table_types(const Type* t1, const Type* t2) + { + const IndexType* it1 = (const IndexType*)t1; + const IndexType* it2 = (const IndexType*)t2; + + const auto& tl1 = it1->GetIndexTypes(); + const auto& tl2 = it2->GetIndexTypes(); + TypeListPtr tl3; + + if ( tl1.size() != tl2.size() ) + { + t1->Error("incompatible types", t2); + return nullptr; + } + + tl3 = make_intrusive(); + + for ( auto i = 0u; i < tl1.size(); ++i ) + { + auto tl3_i = merge_types(tl1[i], tl2[i]); + if ( ! tl3_i ) + return nullptr; + + tl3->Append(std::move(tl3_i)); + } + + const auto& y1 = t1->Yield(); + const auto& y2 = t2->Yield(); + TypePtr y3; + + if ( y1 || y2 ) + { + if ( ! y1 || ! y2 ) + { + t1->Error("incompatible types", t2); + return nullptr; + } + + y3 = merge_types(y1, y2); + if ( ! y3 ) + return nullptr; + } + + if ( t1->IsSet() ) + return make_intrusive(std::move(tl3), nullptr); + else + return make_intrusive(std::move(tl3), std::move(y3)); + } + +TypePtr merge_func_types(const Type* t1, const Type* t2) + { + if ( ! same_type(t1, t2) ) + { + t1->Error("incompatible types", t2); + return nullptr; + } + + const FuncType* ft1 = (const FuncType*)t1; + const FuncType* ft2 = (const FuncType*)t1; + auto args = cast_intrusive(merge_types(ft1->Params(), ft2->Params())); + auto yield = t1->Yield() ? merge_types(t1->Yield(), t2->Yield()) : nullptr; + + return make_intrusive(std::move(args), std::move(yield), ft1->Flavor()); + } + +TypePtr merge_record_types(const Type* t1, const Type* t2) + { + const RecordType* rt1 = (const RecordType*)t1; + const RecordType* rt2 = (const RecordType*)t2; + + // We allow the records to have different numbers of fields. + // We first go through all of the fields in rt1, and then we + // check for whether rt2 has any additional fields. + + type_decl_list* tdl3 = new type_decl_list(); + + for ( int i = 0; i < rt1->NumFields(); ++i ) + { + auto td1 = rt1->FieldDecl(i); + auto td2_offset_i = rt2->FieldOffset(rt1->FieldName(i)); + + TypePtr tdl3_i; + auto attrs3 = make_intrusive(nullptr, true, false); + + if ( td1->attrs ) + attrs3->AddAttrs(td1->attrs); + + if ( td2_offset_i >= 0 ) + { + auto td2 = rt2->FieldDecl(td2_offset_i); + tdl3_i = merge_types(td1->type, td2->type); + + if ( td2->attrs ) + attrs3->AddAttrs(td2->attrs); + + if ( ! util::streq(td1->id, td2->id) || ! tdl3_i ) + { + t1->Error("incompatible record fields", t2); + delete tdl3; + return nullptr; + } + } + else + { + tdl3_i = td1->type; + attrs3->AddAttr(make_intrusive(detail::ATTR_OPTIONAL)); + } + + if ( attrs3->GetAttrs().empty() ) + attrs3 = nullptr; + + auto td3 = new TypeDecl(util::copy_string(td1->id), std::move(tdl3_i), attrs3); + + tdl3->push_back(td3); + } + + // Now add in any extras from rt2. + for ( int i = 0; i < rt2->NumFields(); ++i ) + { + auto td2 = rt2->FieldDecl(i); + auto td1_offset_i = rt1->FieldOffset(rt2->FieldName(i)); + + if ( td1_offset_i < 0 ) + { + auto attrs3 = make_intrusive(nullptr, true, false); + if ( td2->attrs ) + attrs3->AddAttrs(td2->attrs); + + attrs3->AddAttr(make_intrusive(detail::ATTR_OPTIONAL)); + auto td_merge = new TypeDecl(util::copy_string(td2->id), std::move(td2->type), attrs3); + tdl3->push_back(td_merge); + } + } + + return make_intrusive(tdl3); + } + +TypePtr merge_list_types(const Type* t1, const Type* t2) + { + const TypeList* tl1 = t1->AsTypeList(); + const TypeList* tl2 = t2->AsTypeList(); + + if ( tl1->IsPure() != tl2->IsPure() ) + { + tl1->Error("incompatible lists", tl2); + return nullptr; + } + + const auto& l1 = tl1->GetTypes(); + const auto& l2 = tl2->GetTypes(); + + if ( l1.size() == 0 || l2.size() == 0 ) + { + if ( l1.size() == 0 ) + tl1->Error("empty list"); + else + tl2->Error("empty list"); + return nullptr; + } + + if ( l1.size() != l2.size() ) + { + tl1->Error("different number of indices", tl2); + return nullptr; + } + + auto tl3 = make_intrusive(); + + for ( auto i = 0u; i < l1.size(); ++i ) + tl3->Append(merge_types(l1[i], l2[i])); + + return tl3; + } + TypePtr merge_types(const TypePtr& arg_t1, const TypePtr& arg_t2) { auto t1 = arg_t1.get(); auto t2 = arg_t2.get(); - t1 = flatten_type(t1); - t2 = flatten_type(t2); + // t1 = flatten_type(t1); + // t2 = flatten_type(t2); TypeTag tg1 = t1->Tag(); TypeTag tg2 = t2->Tag(); @@ -2267,179 +2473,19 @@ TypePtr merge_types(const TypePtr& arg_t1, const TypePtr& arg_t2) return base_type(tg1); case TYPE_ENUM: - { - // Could compare pointers t1 == t2, but maybe there's someone out - // there creating clones of the type, so safer to compare name. - if ( t1->GetName() != t2->GetName() ) - { - std::string msg = util::fmt("incompatible enum types: '%s' and '%s'", - t1->GetName().data(), t2->GetName().data()); - - t1->Error(msg.data(), t2); - return nullptr; - } - - // Doing a lookup here as a roundabout way of ref-ing t1, without - // changing the function params which has t1 as const and also - // (potentially) avoiding a pitfall mentioned earlier about clones. - const auto& id = detail::global_scope()->Find(t1->GetName()); - - if ( id && id->IsType() && id->GetType()->Tag() == TYPE_ENUM ) - // It should make most sense to return the real type here rather - // than a copy since it may be redef'd later in parsing. If we - // return a copy, then whoever is using this return value won't - // actually see those changes from the redef. - return id->GetType(); - - std::string msg = util::fmt("incompatible enum types: '%s' and '%s'" - " ('%s' enum type ID is invalid)", - t1->GetName().data(), t2->GetName().data(), - t1->GetName().data()); - t1->Error(msg.data(), t2); - return nullptr; - } + return merge_enum_types(t1, t2); case TYPE_TABLE: - { - const IndexType* it1 = (const IndexType*)t1; - const IndexType* it2 = (const IndexType*)t2; - - const auto& tl1 = it1->GetIndexTypes(); - const auto& tl2 = it2->GetIndexTypes(); - TypeListPtr tl3; - - if ( tl1.size() != tl2.size() ) - { - t1->Error("incompatible types", t2); - return nullptr; - } - - tl3 = make_intrusive(); - - for ( auto i = 0u; i < tl1.size(); ++i ) - { - auto tl3_i = merge_types(tl1[i], tl2[i]); - if ( ! tl3_i ) - return nullptr; - - tl3->Append(std::move(tl3_i)); - } - - const auto& y1 = t1->Yield(); - const auto& y2 = t2->Yield(); - TypePtr y3; - - if ( y1 || y2 ) - { - if ( ! y1 || ! y2 ) - { - t1->Error("incompatible types", t2); - return nullptr; - } - - y3 = merge_types(y1, y2); - if ( ! y3 ) - return nullptr; - } - - if ( t1->IsSet() ) - return make_intrusive(std::move(tl3), nullptr); - else - return make_intrusive(std::move(tl3), std::move(y3)); - } + return merge_table_types(t1, t2); case TYPE_FUNC: - { - if ( ! same_type(t1, t2) ) - { - t1->Error("incompatible types", t2); - return nullptr; - } - - const FuncType* ft1 = (const FuncType*)t1; - const FuncType* ft2 = (const FuncType*)t1; - auto args = cast_intrusive(merge_types(ft1->Params(), ft2->Params())); - auto yield = t1->Yield() ? merge_types(t1->Yield(), t2->Yield()) : nullptr; - - return make_intrusive(std::move(args), std::move(yield), ft1->Flavor()); - } + return merge_func_types(t1, t2); case TYPE_RECORD: - { - const RecordType* rt1 = (const RecordType*)t1; - const RecordType* rt2 = (const RecordType*)t2; - - if ( rt1->NumFields() != rt2->NumFields() ) - return nullptr; - - type_decl_list* tdl3 = new type_decl_list(rt1->NumFields()); - - for ( int i = 0; i < rt1->NumFields(); ++i ) - { - const TypeDecl* td1 = rt1->FieldDecl(i); - const TypeDecl* td2 = rt2->FieldDecl(i); - auto tdl3_i = merge_types(td1->type, td2->type); - - if ( ! util::streq(td1->id, td2->id) || ! tdl3_i ) - { - t1->Error("incompatible record fields", t2); - delete tdl3; - return nullptr; - } - - tdl3->push_back(new TypeDecl(util::copy_string(td1->id), std::move(tdl3_i))); - } - - return make_intrusive(tdl3); - } + return merge_record_types(t1, t2); case TYPE_LIST: - { - const TypeList* tl1 = t1->AsTypeList(); - const TypeList* tl2 = t2->AsTypeList(); - - if ( tl1->IsPure() != tl2->IsPure() ) - { - tl1->Error("incompatible lists", tl2); - return nullptr; - } - - const auto& l1 = tl1->GetTypes(); - const auto& l2 = tl2->GetTypes(); - - if ( l1.size() == 0 || l2.size() == 0 ) - { - if ( l1.size() == 0 ) - tl1->Error("empty list"); - else - tl2->Error("empty list"); - return nullptr; - } - - if ( tl1->IsPure() ) - { - // We will be expanding the pure list when converting - // the initialization expression into a set of values. - // So the merge type of the list is the type of one - // of the elements, providing they're consistent. - return merge_types(l1[0], l2[0]); - } - - // Impure lists - must have the same size and match element - // by element. - if ( l1.size() != l2.size() ) - { - tl1->Error("different number of indices", tl2); - return nullptr; - } - - auto tl3 = make_intrusive(); - - for ( auto i = 0u; i < l1.size(); ++i ) - tl3->Append(merge_types(l1[i], l2[i])); - - return tl3; - } + return merge_list_types(t1, t2); case TYPE_VECTOR: if ( ! same_type(t1->Yield(), t2->Yield()) ) From c3e2871a5ed48760ade35a0d4e7507d2739fde5f Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:23:28 -0800 Subject: [PATCH 100/204] simplification of Val classes now that they don't have to support initialization --- src/Val.cc | 101 ++--------------------------------------------------- src/Val.h | 20 ++++------- 2 files changed, 10 insertions(+), 111 deletions(-) diff --git a/src/Val.cc b/src/Val.cc index 9433ab4202..e2cc1e58e5 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -1768,57 +1768,6 @@ bool TableVal::IsSubsetOf(const TableVal& tv) const return true; } -bool TableVal::ExpandAndInit(ValPtr index, ValPtr new_val) - { - const auto& index_type = index->GetType(); - - if ( index_type->IsSet() ) - { - index = index->AsTableVal()->ToListVal(); - return ExpandAndInit(std::move(index), std::move(new_val)); - } - - if ( index_type->Tag() != TYPE_LIST ) - // Nothing to expand. - return CheckAndAssign(std::move(index), std::move(new_val)); - - ListVal* iv = index->AsListVal(); - if ( iv->BaseTag() != TYPE_ANY ) - { - if ( table_type->GetIndices()->GetTypes().size() != 1 ) - reporter->InternalError("bad singleton list index"); - - for ( int i = 0; i < iv->Length(); ++i ) - if ( ! ExpandAndInit(iv->Idx(i), new_val) ) - return false; - - return true; - } - - else - { // Compound table. - int i; - - for ( i = 0; i < iv->Length(); ++i ) - { - const auto& v = iv->Idx(i); - // ### if CompositeHash::ComputeHash did flattening - // of 1-element lists (like ComputeSingletonHash does), - // then we could optimize here. - const auto& t = v->GetType(); - - if ( t->IsSet() || t->Tag() == TYPE_LIST ) - break; - } - - if ( i >= iv->Length() ) - // Nothing to expand. - return CheckAndAssign(std::move(index), std::move(new_val)); - else - return ExpandCompoundAndInit(iv, i, std::move(new_val)); - } - } - ValPtr TableVal::Default(const ValPtr& index) { const auto& def_attr = GetAttr(detail::ATTR_DEFAULT); @@ -2446,49 +2395,6 @@ void TableVal::Describe(ODesc* d) const } } -bool TableVal::ExpandCompoundAndInit(ListVal* lv, int k, ValPtr new_val) - { - Val* ind_k_v = lv->Idx(k).get(); - auto ind_k = ind_k_v->GetType()->IsSet() ? ind_k_v->AsTableVal()->ToListVal() - : ListValPtr{NewRef{}, ind_k_v->AsListVal()}; - - for ( int i = 0; i < ind_k->Length(); ++i ) - { - const auto& ind_k_i = ind_k->Idx(i); - auto expd = make_intrusive(TYPE_ANY); - - for ( auto j = 0; j < lv->Length(); ++j ) - { - const auto& v = lv->Idx(j); - - if ( j == k ) - expd->Append(ind_k_i); - else - expd->Append(v); - } - - if ( ! ExpandAndInit(std::move(expd), new_val) ) - return false; - } - - return true; - } - -bool TableVal::CheckAndAssign(ValPtr index, ValPtr new_val) - { - Val* v = nullptr; - if ( subnets ) - // We need an exact match here. - v = (Val*)subnets->Lookup(index.get(), true); - else - v = Find(index).get(); - - if ( v ) - index->Warn("multiple initializations for index"); - - return Assign(std::move(index), std::move(new_val)); - } - void TableVal::InitDefaultFunc(detail::Frame* f) { // Value aready initialized. @@ -2959,13 +2865,12 @@ ValPtr RecordVal::GetFieldOrDefault(const char* field) const return GetFieldOrDefault(idx); } -RecordValPtr RecordVal::CoerceTo(RecordTypePtr t, RecordValPtr aggr, bool allow_orphaning) const +RecordValPtr RecordVal::DoCoerceTo(RecordTypePtr t, bool allow_orphaning) const { if ( ! record_promotion_compatible(t.get(), GetType()->AsRecordType()) ) return nullptr; - if ( ! aggr ) - aggr = make_intrusive(std::move(t)); + auto aggr = make_intrusive(std::move(t)); RecordType* ar_t = aggr->GetType()->AsRecordType(); const RecordType* rv_t = GetType()->AsRecordType(); @@ -3023,7 +2928,7 @@ RecordValPtr RecordVal::CoerceTo(RecordTypePtr t, bool allow_orphaning) if ( same_type(GetType(), t) ) return {NewRef{}, this}; - return CoerceTo(std::move(t), nullptr, allow_orphaning); + return DoCoerceTo(std::move(t), allow_orphaning); } TableValPtr RecordVal::GetRecordFieldsVal() const diff --git a/src/Val.h b/src/Val.h index acbca8edec..8f78a59f10 100644 --- a/src/Val.h +++ b/src/Val.h @@ -828,10 +828,6 @@ public: // of the given set. bool IsSubsetOf(const TableVal& v) const; - // Expands any lists in the index into multiple initializations. - // Returns true if the initializations typecheck, false if not. - bool ExpandAndInit(ValPtr index, ValPtr new_val); - /** * Finds an index in the table and returns its associated value. * @param index The index to lookup in the table. @@ -1003,8 +999,6 @@ protected: void RebuildTable(ParseTimeTableState ptts); void CheckExpireAttr(detail::AttrTag at); - bool ExpandCompoundAndInit(ListVal* lv, int k, ValPtr new_val); - bool CheckAndAssign(ValPtr index, ValPtr new_val); // Calculates default value for index. Returns nullptr if none. ValPtr Default(const ValPtr& index); @@ -1359,18 +1353,16 @@ public: Obj* GetOrigin() const { return origin; } // Returns a new value representing the value coerced to the given - // type. If coercion is not possible, returns 0. The non-const + // type. If coercion is not possible, returns nil. The non-const // version may return the current value ref'ed if its type matches // directly. // - // *aggr* is optional; if non-zero, we add to it. See - // Expr::InitVal(). We leave it out in the non-const version to make - // the choice unambigious. - // // The *allow_orphaning* parameter allows for a record to be demoted // down to a record type that contains less fields. - RecordValPtr CoerceTo(RecordTypePtr other, RecordValPtr aggr, - bool allow_orphaning = false) const; + RecordValPtr CoerceTo(RecordTypePtr other, bool allow_orphaning = false) const + { + return DoCoerceTo(other, allow_orphaning); + } RecordValPtr CoerceTo(RecordTypePtr other, bool allow_orphaning = false); [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See " @@ -1390,6 +1382,8 @@ public: protected: friend class zeek::detail::ZBody; + RecordValPtr DoCoerceTo(RecordTypePtr other, bool allow_orphaning) const; + /** * Appends a value to the record's fields. The caller is responsible * for ensuring that fields are appended in the correct order and From 63f902daff256da03a31338ec45b7bd75c90b00b Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:24:04 -0800 Subject: [PATCH 101/204] switch variable initialization over to being expression-based --- src/Var.cc | 157 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 101 insertions(+), 56 deletions(-) diff --git a/src/Var.cc b/src/Var.cc index ce1027b77e..dba0e620fb 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -23,18 +23,6 @@ namespace zeek::detail { -static ValPtr init_val(ExprPtr init, TypePtr t, ValPtr aggr) - { - try - { - return init->InitVal(t, std::move(aggr)); - } - catch ( InterpreterException& e ) - { - return nullptr; - } - } - static bool add_prototype(const IDPtr& id, Type* t, std::vector* attrs, const ExprPtr& init) { @@ -129,9 +117,103 @@ static bool add_prototype(const IDPtr& id, Type* t, std::vector* attrs, return true; } +static void initialize_var(const IDPtr& id, InitClass c, ExprPtr init) + { + if ( ! id->HasVal() ) + { + if ( c == INIT_REMOVE ) + return; + + bool no_init = ! init; + + if ( ! no_init && init->Tag() == EXPR_LIST ) + no_init = init->AsListExpr()->Exprs().empty(); + + if ( no_init ) + { + auto& t = id->GetType(); + + if ( ! IsAggr(t) ) + return; + + ValPtr init_val; + + if ( t->Tag() == TYPE_RECORD ) + { + try + { + init_val = make_intrusive(cast_intrusive(t)); + } + catch ( InterpreterException& ) + { + id->Error("initialization failed"); + return; + } + } + + else if ( t->Tag() == TYPE_TABLE ) + init_val = make_intrusive(cast_intrusive(t), id->GetAttrs()); + + else if ( t->Tag() == TYPE_VECTOR ) + init_val = make_intrusive(cast_intrusive(t)); + + id->SetVal(init_val); + return; + } + + if ( c == INIT_EXTRA ) + c = INIT_FULL; + } + + bool is_const = id->IsConst() || id->IsOption(); + auto lhs = make_intrusive(id, is_const); + ExprPtr assignment; + + if ( c == INIT_FULL ) + assignment = make_intrusive(lhs, init, false); + else if ( c == INIT_EXTRA ) + assignment = make_intrusive(lhs, init); + else if ( c == INIT_REMOVE ) + assignment = make_intrusive(lhs, init); + else + reporter->InternalError("bad InitClass in initialize_var"); + + if ( assignment->IsError() ) + return; + + try + { + (void)assignment->Eval(nullptr); + } + catch ( InterpreterException& ) + { + id->Error("initialization failed"); + } + } + static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init, std::unique_ptr> attr, DeclType dt, bool do_init) { + if ( c == INIT_NONE && init ) + { + // This can happen because the grammar allows any "init_class", + // including none, to be followed by an expression. + init->Warn("initialization not preceded by =/+=/-= is deprecated"); + + // The historical instances of these, such as the + // language/redef-same-prefixtable-idx.zeek btest, treat + // this as += rather than =, and with the initializer + // implicitly inside a list. + init = make_intrusive(init); + c = INIT_EXTRA; + } + + if ( init && init->Tag() == EXPR_LIST ) + { + auto& init_t = t ? t : id->GetType(); + init = expand_op(cast_intrusive(init), init_t); + } + if ( id->GetType() ) { if ( id->IsRedefinable() || (! init && attr && ! IsFunc(id->GetType()->Tag())) ) @@ -166,7 +248,7 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init, if ( id->GetType() && id->GetType()->Tag() != TYPE_ERROR ) { - if ( dt != VAR_REDEF && (! init || ! do_init || (! t && ! (t = init_type(init.get())))) ) + if ( dt != VAR_REDEF && (! init || ! do_init || (! t && ! (t = init_type(init)))) ) { id->Error("already defined", init.get()); return; @@ -205,7 +287,7 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init, return; } - t = init_type(init.get()); + t = init_type(init); if ( ! t ) { id->SetType(error_type()); @@ -228,6 +310,8 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init, auto* ctor = static_cast(init.get()); if ( ctor->GetAttrs() ) id->AddAttrs(ctor->GetAttrs()); + else + ctor->SetAttrs(id->GetAttrs()); } break; @@ -236,6 +320,8 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init, auto* ctor = static_cast(init.get()); if ( ctor->GetAttrs() ) id->AddAttrs(ctor->GetAttrs()); + else + ctor->SetAttrs(id->GetAttrs()); } break; @@ -258,48 +344,7 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init, id->SetVal(init, c); else if ( dt != VAR_REDEF || init || ! attr ) - { - ValPtr aggr; - - if ( t->Tag() == TYPE_RECORD ) - { - try - { - aggr = make_intrusive(cast_intrusive(t)); - } - catch ( InterpreterException& ) - { - id->Error("initialization failed"); - return; - } - - if ( init && t ) - // Have an initialization and type is not deduced. - init = make_intrusive( - std::move(init), IntrusivePtr{NewRef{}, t->AsRecordType()}); - } - - else if ( t->Tag() == TYPE_TABLE ) - aggr = make_intrusive(cast_intrusive(t), id->GetAttrs()); - - else if ( t->Tag() == TYPE_VECTOR ) - aggr = make_intrusive(cast_intrusive(t)); - - ValPtr v; - - if ( init ) - { - v = init_val(init, t, aggr); - - if ( ! v ) - return; - } - - if ( aggr ) - id->SetVal(std::move(aggr), c); - else if ( v ) - id->SetVal(std::move(v), c); - } + initialize_var(id, c, init); } if ( dt == VAR_CONST ) From f62c04c9eb911afa50234e83c2ee43154865bd20 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:24:39 -0800 Subject: [PATCH 102/204] tweaks to base scripts revealed by switch to expression-based initialization --- scripts/base/frameworks/software/main.zeek | 2 +- scripts/base/protocols/dhcp/consts.zeek | 4 ++-- scripts/base/protocols/ssl/main.zeek | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/base/frameworks/software/main.zeek b/scripts/base/frameworks/software/main.zeek index 9fed88668b..b6a86ba644 100644 --- a/scripts/base/frameworks/software/main.zeek +++ b/scripts/base/frameworks/software/main.zeek @@ -95,7 +95,7 @@ export { ## even if it exposes itself with an alternate name. The ## yielded string is the name that will be logged and generally ## used for everything. - global alternate_names: table[string] of string { + global alternate_names: table[string] of string = { ["Flash Player"] = "Flash", } &default=function(a: string): string { return a; }; diff --git a/scripts/base/protocols/dhcp/consts.zeek b/scripts/base/protocols/dhcp/consts.zeek index 0bf16ded96..8507e91c9f 100644 --- a/scripts/base/protocols/dhcp/consts.zeek +++ b/scripts/base/protocols/dhcp/consts.zeek @@ -28,7 +28,7 @@ export { } &default = function(n: count): string { return fmt("unknown-message-type-%d", n); }; ## Option types mapped to their names. - const option_types: table[int] of string = { + const option_types = { [0] = "Pad", [1] = "Subnet Mask", [2] = "Time Offset", @@ -185,5 +185,5 @@ export { [221] = "Virtual Subnet Selection (VSS) Option", [252] = "auto-proxy-config", [255] = "End", - } &default = function(n: int): string { return fmt("unknown-option-type-%d", n); }; + } &default = function(n: count): string { return fmt("unknown-option-type-%d", n); }; } diff --git a/scripts/base/protocols/ssl/main.zeek b/scripts/base/protocols/ssl/main.zeek index 3812b08214..9257a89922 100644 --- a/scripts/base/protocols/ssl/main.zeek +++ b/scripts/base/protocols/ssl/main.zeek @@ -108,7 +108,7 @@ export { ## The default root CA bundle. By default, the mozilla-ca-list.zeek ## script sets this to Mozilla's root CA list. - const root_certs: table[string] of string = {} &redef; + const root_certs: table[string] of string &redef; ## The record type which contains the field for the Certificate ## Transparency log bundle. From 64775a8192b6349ec6efd420d47842ad8e837bf0 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:25:30 -0800 Subject: [PATCH 103/204] updates to btests to support switch to expression-based initialization --- testing/btest/Baseline/core.fake_dns/out | 4 +-- testing/btest/Baseline/core.scalar-vector/out | 14 ++++----- .../language.cross-product-init/output | 2 +- .../.stderr | 10 +++---- .../Baseline/language.record-bad-ctor/out | 3 +- .../language.record-type-checking/out | 3 -- .../.stderr | 3 ++ .../Baseline/language.set-type-checking/out | 6 ++-- .../output | 6 ++-- .../output | 3 ++ .../Baseline/language.table-type-checking/out | 3 +- .../language.vector-type-checking/out | 3 +- testing/btest/core/fake_dns.zeek | 2 +- testing/btest/core/scalar-vector.zeek | 4 +++ .../btest/language/cross-product-init.zeek | 2 +- testing/btest/language/record-bad-ctor.zeek | 7 ++++- .../language/redef-same-prefixtable-idx.zeek | 1 + testing/btest/language/table-init-attrs.zeek | 6 ++-- .../language/type-check-operator-in.zeek | 30 +++++++++---------- .../frameworks/software/version-parsing.zeek | 2 +- 20 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 testing/btest/Baseline/language.redef-same-prefixtable-idx/.stderr diff --git a/testing/btest/Baseline/core.fake_dns/out b/testing/btest/Baseline/core.fake_dns/out index fe6c13aeb8..bc04a9ec86 100644 --- a/testing/btest/Baseline/core.fake_dns/out +++ b/testing/btest/Baseline/core.fake_dns/out @@ -1,8 +1,8 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. { 51f3:f001:5b82:e802:c401:6750:7b95:89bb, -4cc7:de52:d869:b2f9:f215:19b8:c828:3bdd, -7a5f:b783:9808:380e:b1a2:ce20:b58e:2a4a +7a5f:b783:9808:380e:b1a2:ce20:b58e:2a4a, +4cc7:de52:d869:b2f9:f215:19b8:c828:3bdd } lookup_hostname_txt, fake_text_lookup_result_bro.wp.dg.cx lookup_hostname, { diff --git a/testing/btest/Baseline/core.scalar-vector/out b/testing/btest/Baseline/core.scalar-vector/out index 49b3872f4c..4f5fc89efa 100644 --- a/testing/btest/Baseline/core.scalar-vector/out +++ b/testing/btest/Baseline/core.scalar-vector/out @@ -1,11 +1,11 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning in <...>/scalar-vector.zeek, line 7: mixing vector and scalar operands is deprecated (string) (vector) -warning in <...>/scalar-vector.zeek, line 8: mixing vector and scalar operands is deprecated (vector) (string) -warning in <...>/scalar-vector.zeek, line 9: mixing vector and scalar operands is deprecated (string) (vector) -warning in <...>/scalar-vector.zeek, line 13: mixing vector and scalar operands is deprecated (count) (vector) -warning in <...>/scalar-vector.zeek, line 14: mixing vector and scalar operands is deprecated (count) (vector) -warning in <...>/scalar-vector.zeek, line 15: mixing vector and scalar operands is deprecated (vector) (count) -warning in <...>/scalar-vector.zeek, line 16: mixing vector and scalar operands is deprecated (vector) (count) +warning in <...>/scalar-vector.zeek, line 11: mixing vector and scalar operands is deprecated (string) (vector) +warning in <...>/scalar-vector.zeek, line 12: mixing vector and scalar operands is deprecated (vector) (string) +warning in <...>/scalar-vector.zeek, line 13: mixing vector and scalar operands is deprecated (string) (vector) +warning in <...>/scalar-vector.zeek, line 17: mixing vector and scalar operands is deprecated (count) (vector) +warning in <...>/scalar-vector.zeek, line 18: mixing vector and scalar operands is deprecated (count) (vector) +warning in <...>/scalar-vector.zeek, line 19: mixing vector and scalar operands is deprecated (vector) (count) +warning in <...>/scalar-vector.zeek, line 20: mixing vector and scalar operands is deprecated (vector) (count) [F, T, F] [aa, ba, ca] [aa, ab, ac] diff --git a/testing/btest/Baseline/language.cross-product-init/output b/testing/btest/Baseline/language.cross-product-init/output index 3705de05a1..c4cff483cc 100644 --- a/testing/btest/Baseline/language.cross-product-init/output +++ b/testing/btest/Baseline/language.cross-product-init/output @@ -1,7 +1,7 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. { [bar, 1.2.0.0/19] , -[foo, 1.2.0.0/19] , [foo, 5.6.0.0/21] , +[foo, 1.2.0.0/19] , [bar, 5.6.0.0/21] } diff --git a/testing/btest/Baseline/language.mismatched-container-ctor-types/.stderr b/testing/btest/Baseline/language.mismatched-container-ctor-types/.stderr index 807ddb4f5a..8c193d4b3c 100644 --- a/testing/btest/Baseline/language.mismatched-container-ctor-types/.stderr +++ b/testing/btest/Baseline/language.mismatched-container-ctor-types/.stderr @@ -1,9 +1,9 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/mismatched-container-ctor-types.zeek, line 6: unexpected use of vector constructor in 'table' initialization (vector()) -error in <...>/mismatched-container-ctor-types.zeek, line 7: unexpected use of table constructor in 'vector' initialization (table()) -error in <...>/mismatched-container-ctor-types.zeek, line 8: unexpected use of set constructor in 'vector' initialization (set()) -error in <...>/mismatched-container-ctor-types.zeek, line 9: unexpected use of record constructor in 'vector' initialization ([]) -error in <...>/mismatched-container-ctor-types.zeek, line 10: unexpected use of record constructor in 'vector' initialization (R()) +error in <...>/mismatched-container-ctor-types.zeek, line 6: type clash in assignment (t = vector()) +error in <...>/mismatched-container-ctor-types.zeek, line 7: type clash in assignment (v0 = table()) +error in <...>/mismatched-container-ctor-types.zeek, line 8: type clash in assignment (v1 = set()) +error in <...>/mismatched-container-ctor-types.zeek, line 9: type clash in assignment (v2 = []) +error in <...>/mismatched-container-ctor-types.zeek, line 10: type clash in assignment (v3 = R()) error in <...>/mismatched-container-ctor-types.zeek, line 12: type clash in assignment (lt = vector()) error in <...>/mismatched-container-ctor-types.zeek, line 13: type clash in assignment (lv0 = table()) error in <...>/mismatched-container-ctor-types.zeek, line 14: type clash in assignment (lv1 = set()) diff --git a/testing/btest/Baseline/language.record-bad-ctor/out b/testing/btest/Baseline/language.record-bad-ctor/out index 40931641f1..cbb840cdcc 100644 --- a/testing/btest/Baseline/language.record-bad-ctor/out +++ b/testing/btest/Baseline/language.record-bad-ctor/out @@ -1,3 +1,4 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. error in <...>/record-bad-ctor.zeek, line 6: no type given (asdfasdf) -error in <...>/record-bad-ctor.zeek, line 7: non-optional field "ports" missing in initialization ([ports=]) +expression error in <...>/record-bad-ctor.zeek, line 11: value used but not set (asdfasdf2) +error in <...>/record-bad-ctor.zeek, line 11: initialization failed (blah2) diff --git a/testing/btest/Baseline/language.record-type-checking/out b/testing/btest/Baseline/language.record-type-checking/out index 713a1a0a01..f625ea05fa 100644 --- a/testing/btest/Baseline/language.record-type-checking/out +++ b/testing/btest/Baseline/language.record-type-checking/out @@ -1,11 +1,8 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. error in port and <...>/record-type-checking.zeek, line 9: arithmetic mixed with non-arithmetic (port and 0) -error in <...>/record-type-checking.zeek, line 9: bad record initializer ([$a=]) error in port and <...>/record-type-checking.zeek, line 12: arithmetic mixed with non-arithmetic (port and 1) -error in <...>/record-type-checking.zeek, line 12: bad record initializer ((coerce [$a=] to error)) error in port and <...>/record-type-checking.zeek, line 18: arithmetic mixed with non-arithmetic (port and 2) error in <...>/record-type-checking.zeek, line 22 and count: type clash for field "a" ((coerce [$a=3] to MyRec) and count) -error in <...>/record-type-checking.zeek, line 22: bad record initializer ((coerce [$a=3] to error)) error in port and <...>/record-type-checking.zeek, line 27: arithmetic mixed with non-arithmetic (port and 1000) error in port and <...>/record-type-checking.zeek, line 33: arithmetic mixed with non-arithmetic (port and 1001) error in port and <...>/record-type-checking.zeek, line 40: arithmetic mixed with non-arithmetic (port and 1002) diff --git a/testing/btest/Baseline/language.redef-same-prefixtable-idx/.stderr b/testing/btest/Baseline/language.redef-same-prefixtable-idx/.stderr new file mode 100644 index 0000000000..ebf136334a --- /dev/null +++ b/testing/btest/Baseline/language.redef-same-prefixtable-idx/.stderr @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +warning in /Users/vern/warehouse/zeek/master/testing/btest/.tmp/language.redef-same-prefixtable-idx/redef-same-prefixtable-idx.zeek, line 7: initialization not preceded by =/+=/-= is deprecated (3.0.0.0/8 = 1.0.0.0/8) +warning in /Users/vern/warehouse/zeek/master/testing/btest/.tmp/language.redef-same-prefixtable-idx/redef-same-prefixtable-idx.zeek, line 8: initialization not preceded by =/+=/-= is deprecated (3.0.0.0/8 = 2.0.0.0/8) diff --git a/testing/btest/Baseline/language.set-type-checking/out b/testing/btest/Baseline/language.set-type-checking/out index 3bd6cc0dc1..d930791048 100644 --- a/testing/btest/Baseline/language.set-type-checking/out +++ b/testing/btest/Baseline/language.set-type-checking/out @@ -8,8 +8,10 @@ error in <...>/set-type-checking.zeek, line 10: inconsistent type in set constru error in port and <...>/set-type-checking.zeek, line 16: arithmetic mixed with non-arithmetic (port and 2) error in <...>/set-type-checking.zeek, line 16 and port: type mismatch (2 and port) error in <...>/set-type-checking.zeek, line 16: inconsistent type in set constructor (set(2)) -error in port: arithmetic mixed with non-arithmetic (port and 3) -error in <...>/set-type-checking.zeek, line 20: initialization type mismatch in set (set(3) and 3) +error in port and <...>/set-type-checking.zeek, line 20: arithmetic mixed with non-arithmetic (port and 3) +error in <...>/set-type-checking.zeek, line 20 and port: type mismatch (3 and port) +error in <...>/set-type-checking.zeek, line 20: inconsistent type in set constructor (set(3)) +error in <...>/set-type-checking.zeek, line 20: type clash in assignment (gea = set(3)) error in port and <...>/set-type-checking.zeek, line 25: arithmetic mixed with non-arithmetic (port and 1000) error in <...>/set-type-checking.zeek, line 25 and port: type mismatch (1000 and port) error in <...>/set-type-checking.zeek, line 25: inconsistent type in set constructor (set(1000)) diff --git a/testing/btest/Baseline/language.table-aggr-init-type-check/output b/testing/btest/Baseline/language.table-aggr-init-type-check/output index 0fb4c3a300..6fbe2173f8 100644 --- a/testing/btest/Baseline/language.table-aggr-init-type-check/output +++ b/testing/btest/Baseline/language.table-aggr-init-type-check/output @@ -1,3 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/table-aggr-init-type-check.zeek, line 21: type mismatch in table value initialization: assigning 'types' to table with values of type 'record' (three = 1, 2) -error in <...>/table-aggr-init-type-check.zeek, line 25: type mismatch in table value initialization: incompatible record types (four = [$b=No.]) +error in <...>/table-aggr-init-type-check.zeek, lines 4-7 and <...>/table-aggr-init-type-check.zeek, line 21: type clash (MyRec and 1, 2) +error in <...>/table-aggr-init-type-check.zeek, line 21: inconsistent types in table constructor (table(three = 1, 2)) +error in <...>/table-aggr-init-type-check.zeek, lines 4-7 and <...>/table-aggr-init-type-check.zeek, line 25: incompatible record types (MyRec and [$b=No.]) +error in <...>/table-aggr-init-type-check.zeek, line 25: inconsistent types in table constructor (table(four = [$b=No.])) diff --git a/testing/btest/Baseline/language.table-list-assign-type-check/output b/testing/btest/Baseline/language.table-list-assign-type-check/output index 4e61c25b09..b33c42c8ce 100644 --- a/testing/btest/Baseline/language.table-list-assign-type-check/output +++ b/testing/btest/Baseline/language.table-list-assign-type-check/output @@ -1,8 +1,11 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. error in count and <...>/table-list-assign-type-check.zeek, line 16: arithmetic mixed with non-arithmetic (count and Internal Web Server) error in <...>/table-list-assign-type-check.zeek, lines 15-20: inconsistent types in table constructor (table(www, 80 = Internal Web Server, dns1, 53 = Internal DNS 1, dns2, 53 = Internal DNS 2, dhcp-for-wifi, 443 = DHCP Management interface for WiFi)) +error in <...>/table-list-assign-type-check.zeek, lines 15-20: type clash in assignment (service_table_bad_yield = table(www, 80 = Internal Web Server, dns1, 53 = Internal DNS 1, dns2, 53 = Internal DNS 2, dhcp-for-wifi, 443 = DHCP Management interface for WiFi)) error in count and <...>/table-list-assign-type-check.zeek, line 24: arithmetic mixed with non-arithmetic (count and 80) error in <...>/table-list-assign-type-check.zeek, lines 23-28: inconsistent types in table constructor (table(www, 80 = Internal Web Server, dns1, 53 = Internal DNS 1, dns2, 53 = Internal DNS 2, dhcp-for-wifi, 443 = DHCP Management interface for WiFi)) +error in <...>/table-list-assign-type-check.zeek, lines 23-28: type clash in assignment (service_table_bad_index = table(www, 80 = Internal Web Server, dns1, 53 = Internal DNS 1, dns2, 53 = Internal DNS 2, dhcp-for-wifi, 443 = DHCP Management interface for WiFi)) error in string and <...>/table-list-assign-type-check.zeek, line 31: arithmetic mixed with non-arithmetic (string and 1) error in <...>/table-list-assign-type-check.zeek, line 31 and string: type mismatch (1 and string) error in <...>/table-list-assign-type-check.zeek, line 31: inconsistent type in set constructor (set(1, 2, 3)) +error in <...>/table-list-assign-type-check.zeek, line 31: type clash in assignment (test_set_bad = set(1, 2, 3)) diff --git a/testing/btest/Baseline/language.table-type-checking/out b/testing/btest/Baseline/language.table-type-checking/out index 82a60de830..72bfcb7b5b 100644 --- a/testing/btest/Baseline/language.table-type-checking/out +++ b/testing/btest/Baseline/language.table-type-checking/out @@ -4,8 +4,7 @@ error in <...>/table-type-checking.zeek, line 7: inconsistent types in table con error in port and <...>/table-type-checking.zeek, line 10: type clash (port and one) error in <...>/table-type-checking.zeek, line 10: inconsistent types in table constructor (table(one = 1)) error in <...>/table-type-checking.zeek, line 17: type clash in assignment (gda = gda2) -error in <...>/table-type-checking.zeek, line 21 and <...>/table-type-checking.zeek, line 4: index type doesn't match table (three and list of port) -expression error in <...>/table-type-checking.zeek, line 21: type clash in table assignment (three = 3) +error in <...>/table-type-checking.zeek, line 21: type clash in assignment (gea = table(three = 3)) error in port and <...>/table-type-checking.zeek, line 26: type clash (port and thousand) error in <...>/table-type-checking.zeek, line 26: inconsistent types in table constructor (table(thousand = 1000)) error in port and <...>/table-type-checking.zeek, line 32: type clash (port and thousand-one) diff --git a/testing/btest/Baseline/language.vector-type-checking/out b/testing/btest/Baseline/language.vector-type-checking/out index 588779a80e..71eb85a096 100644 --- a/testing/btest/Baseline/language.vector-type-checking/out +++ b/testing/btest/Baseline/language.vector-type-checking/out @@ -6,8 +6,7 @@ error in count and <...>/vector-type-checking.zeek, line 10: arithmetic mixed wi error in <...>/vector-type-checking.zeek, line 10 and count: type mismatch (one and count) error in <...>/vector-type-checking.zeek, line 10: inconsistent types in vector constructor (vector(one)) error in <...>/vector-type-checking.zeek, line 17: type clash in assignment (gda = gda2) -error in count and <...>/vector-type-checking.zeek, line 21: arithmetic mixed with non-arithmetic (count and three) -error in <...>/vector-type-checking.zeek, line 21: initialization type mismatch at index 0 (vector(three) and three) +error in <...>/vector-type-checking.zeek, line 21: type clash in assignment (gea = vector(three)) error in count and <...>/vector-type-checking.zeek, line 26: arithmetic mixed with non-arithmetic (count and thousand) error in <...>/vector-type-checking.zeek, line 26 and count: type mismatch (thousand and count) error in <...>/vector-type-checking.zeek, line 26: inconsistent types in vector constructor (vector(thousand)) diff --git a/testing/btest/core/fake_dns.zeek b/testing/btest/core/fake_dns.zeek index 46dd50c5ee..dd8a88ae40 100644 --- a/testing/btest/core/fake_dns.zeek +++ b/testing/btest/core/fake_dns.zeek @@ -1,4 +1,4 @@ -# @TEST-EXEC: ZEEK_DNS_FAKE=1 zeek -b %INPUT >out +# @TEST-EXEC: ZEEK_DNS_FAKE=1 zeek -D -b %INPUT >out # @TEST-EXEC: btest-diff out redef exit_only_after_terminate = T; diff --git a/testing/btest/core/scalar-vector.zeek b/testing/btest/core/scalar-vector.zeek index 3382066816..004ef5eec1 100644 --- a/testing/btest/core/scalar-vector.zeek +++ b/testing/btest/core/scalar-vector.zeek @@ -1,3 +1,7 @@ +# Skip this test when using ZAM, as it will generate a hard error in addition +# to the warning. +# @TEST-REQUIRES: test "${ZEEK_ZAM}" != "1" +# # @TEST-EXEC: zeek -b %INPUT > out 2>&1 # @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath" btest-diff out diff --git a/testing/btest/language/cross-product-init.zeek b/testing/btest/language/cross-product-init.zeek index f5027cfd3c..ec029e9f0c 100644 --- a/testing/btest/language/cross-product-init.zeek +++ b/testing/btest/language/cross-product-init.zeek @@ -1,4 +1,4 @@ -# @TEST-EXEC: zeek -b %INPUT >output 2>&1 +# @TEST-EXEC: zeek -b -D %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output global my_subs = { 1.2.3.4/19, 5.6.7.8/21 }; diff --git a/testing/btest/language/record-bad-ctor.zeek b/testing/btest/language/record-bad-ctor.zeek index 40bafa47de..49de10ebb7 100644 --- a/testing/btest/language/record-bad-ctor.zeek +++ b/testing/btest/language/record-bad-ctor.zeek @@ -5,4 +5,9 @@ global asdfasdf; const blah = [$ports=asdfasdf]; -print blah; +const x = blah; + +global asdfasdf2: port; +const blah2 = [$ports=asdfasdf2]; + +print blah, blah2; diff --git a/testing/btest/language/redef-same-prefixtable-idx.zeek b/testing/btest/language/redef-same-prefixtable-idx.zeek index c96af48f3e..74d0feb82c 100644 --- a/testing/btest/language/redef-same-prefixtable-idx.zeek +++ b/testing/btest/language/redef-same-prefixtable-idx.zeek @@ -1,4 +1,5 @@ # @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff .stderr # @TEST-EXEC: btest-diff out const my_table: table[subnet] of subnet &redef; diff --git a/testing/btest/language/table-init-attrs.zeek b/testing/btest/language/table-init-attrs.zeek index 5f1e742479..5f1ec64309 100644 --- a/testing/btest/language/table-init-attrs.zeek +++ b/testing/btest/language/table-init-attrs.zeek @@ -11,7 +11,7 @@ redef my_set_ctor_init += { "test3", }; -redef my_set_ctor_init += set("test4"); +redef my_set_ctor_init += { "test4" }; const my_table_ctor_init: table[count] of string = table([1] = "test1") &redef &default="nope"; @@ -29,7 +29,7 @@ redef my_set_init += { "test3", }; -redef my_set_init += set("test4"); +redef my_set_init += { "test4" }; const my_table_init: table[count] of string = { [1] = "test1" } &redef &default="nope"; @@ -38,7 +38,7 @@ redef my_table_init += { [3] = "test3", }; -redef my_table_init += table([4] = "test4"); +redef my_table_init += { [4] = "test4" }; # For tables that yield tables, we can apply attributes to the both other and # inner tables... diff --git a/testing/btest/language/type-check-operator-in.zeek b/testing/btest/language/type-check-operator-in.zeek index b0f0430eb6..c7121b3725 100644 --- a/testing/btest/language/type-check-operator-in.zeek +++ b/testing/btest/language/type-check-operator-in.zeek @@ -15,26 +15,26 @@ local string_records: set[string, MyRec] = set(); local record_strings: set[MyRec, string] = set(); # These are all valid. -["asdf"] in strings; -["hi", 0] in string_counts; -myrec in records; -[myrec] in records; -MyRec() in records; -[$a = 2] in records; -[MyRec()] in records; -[[$a = 2]] in records; -["hi", myrec] in string_records; +print ["asdf"] in strings; +print ["hi", 0] in string_counts; +print myrec in records; +print [myrec] in records; +print MyRec() in records; +print [$a = 2] in records; +print [MyRec()] in records; +print [[$a = 2]] in records; +print ["hi", myrec] in string_records; # All below should fail type-checking. -myrec in "asdf"; -myrec in string_records; -myrec in record_strings; +print myrec in "asdf"; +print myrec in string_records; +print myrec in record_strings; # Patterns do not apply transparently to collections of strings, so fail # to type-check too: -/foo/ in strings; +print /foo/ in strings; # Complex index types need to match, too. (For tests with matching types, # see set.zeek / table.zeek.) @@ -43,5 +43,5 @@ local table_set: set[table[string] of string] = set(); local stringvec_set: set[vector of string] = set(); local string_count_map: table[string] of count = table(); -string_count_map in table_set; -vector(1, 2, 3) in stringvec_set; +print string_count_map in table_set; +print vector(1, 2, 3) in stringvec_set; diff --git a/testing/btest/scripts/base/frameworks/software/version-parsing.zeek b/testing/btest/scripts/base/frameworks/software/version-parsing.zeek index 5730348c3d..852ae980eb 100644 --- a/testing/btest/scripts/base/frameworks/software/version-parsing.zeek +++ b/testing/btest/scripts/base/frameworks/software/version-parsing.zeek @@ -35,7 +35,7 @@ global matched_software: table[string] of Software::Description = { ["curl/7.15.1 (i486-pc-linux-gnu) libcurl/7.15.1 OpenSSL/0.9.8a zlib/1.2.3 libidn/0.5.18"] = [$name="curl", $version=[$major=7,$minor=15,$minor2=1,$addl="i486-pc-linux-gnu"], $unparsed_version=""], ["Apache"] = - [$name="Apache", $unparsed_version=""], + [$name="Apache", $version=[], $unparsed_version=""], ["Zope/(Zope 2.7.8-final, python 2.3.5, darwin) ZServer/1.1 Plone/Unknown"] = [$name="Zope/(Zope", $version=[$major=2,$minor=7,$minor2=8,$addl="final"], $unparsed_version=""], ["The Bat! (v2.00.9) Personal"] = From ae75635c5a41b1e42de377179bc5c2a209cb4f9c Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:28:14 -0800 Subject: [PATCH 104/204] new btests to cover extended functionality & associatd errors --- .../Baseline/language.init-integration/out | 55 +++++++++ .../Baseline/language.init-mismatch/.stderr | 21 ++++ testing/btest/language/init-integration.zeek | 115 ++++++++++++++++++ testing/btest/language/init-mismatch.zeek | 40 ++++++ 4 files changed, 231 insertions(+) create mode 100644 testing/btest/Baseline/language.init-integration/out create mode 100644 testing/btest/Baseline/language.init-mismatch/.stderr create mode 100644 testing/btest/language/init-integration.zeek create mode 100644 testing/btest/language/init-mismatch.zeek diff --git a/testing/btest/Baseline/language.init-integration/out b/testing/btest/Baseline/language.init-integration/out new file mode 100644 index 0000000000..bf0bf88bb3 --- /dev/null +++ b/testing/btest/Baseline/language.init-integration/out @@ -0,0 +1,55 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +init_key in state: 1 +init_key2 in state2: 1 +{ +[worker-2] = [node_type=Cluster::WORKER, ip=127.0.0.1, p=7/tcp, manager=manager-1], +[worker-3] = [node_type=Cluster::WORKER, ip=1.2.3.4, p=9/udp, manager=], +[manager-1] = [node_type=Cluster::MANAGER, ip=127.0.0.1, p=3/tcp, manager=], +[worker-1] = [node_type=Cluster::WORKER, ip=127.0.0.1, p=5/udp, manager=manager-1] +} +{ +[worker-3] = [node_type=Cluster::WORKER, ip=1.2.3.4, p=9/udp, manager=], +[manager-1] = [node_type=Cluster::MANAGER, ip=127.0.0.1, p=3/tcp, manager=], +[worker-1] = [node_type=Cluster::WORKER, ip=127.0.0.1, p=5/udp, manager=manager-1] +} +{ +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, time_machine=, id=] +} +{ +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, time_machine=, id=], +[worker-5] = [node_type=Cluster::WORKER, ip=3.4.5.6, zone_id=, p=15/tcp, interface=, manager=, time_machine=, id=] +} +{ +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, time_machine=, id=], +[worker-6] = [node_type=Cluster::WORKER, ip=4.5.6.7, zone_id=, p=17/udp, interface=, manager=, time_machine=, id=] +} +{ +[3.0, 4] +} +{ +[3.0, 4] +} +{ + +} +{ +[9.0, 4] +} +{ +[3.0, 4.0] = 5.0 +} +{ +[3.0, 4.0] = 5.0 +} +{ + +} +{ +[bar, 1.2.0.0/19] , +[foo, 5.6.0.0/21] , +[foo, 1.2.0.0/19] , +[bar, 5.6.0.0/21] +} +/(^?(^?(bar)$?)$?)|(^?(^?(foo)$?)$?)/ +[1, 3, 5, 9, 2, 4, 6, 20, 21, 22, 23] +[[3, 2, 1], [1, 2, 3], [20, 21, 22, 23], [80, 81], [90, 91, 92]] diff --git a/testing/btest/Baseline/language.init-mismatch/.stderr b/testing/btest/Baseline/language.init-mismatch/.stderr new file mode 100644 index 0000000000..ee09bb0b27 --- /dev/null +++ b/testing/btest/Baseline/language.init-mismatch/.stderr @@ -0,0 +1,21 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/init-mismatch.zeek, line 6: invalid constructor list on RHS of assignment (a = 3, 5) +error in <...>/init-mismatch.zeek, line 6: assignment of non-arithmetic value to arithmetic (count/types) (a = 3, 5) +warning in <...>/init-mismatch.zeek, line 7: initialization not preceded by =<...>/-= is deprecated (4, 6) +error in <...>/init-mismatch.zeek, line 13: different number of indices (list of count,count and list of count,count,count) +error in <...>/init-mismatch.zeek, line 14: table constructor element lacks '=' structure (bar) +error in <...>/init-mismatch.zeek, line 17: empty list in untyped initialization () +error in <...>/init-mismatch.zeek, line 23: cannot expand constructor elements using a value that depends on local variables (subnets) +error in <...>/init-mismatch.zeek, line 23: type clash in assignment (my_subnets = set(foo, subnets)) +error in <...>/init-mismatch.zeek, line 26: invalid constructor list on RHS of assignment (c += 2, 4) +error in <...>/init-mismatch.zeek, line 27: constructor list not allowed for -= operations on vectors (v -= 3, 5) +error in <...>/init-mismatch.zeek, line 29: RHS type mismatch for table/set += (s1 += s2) +error in <...>/init-mismatch.zeek, line 30: RHS type mismatch for table/set -= (s1 -= s2) +error in <...>/init-mismatch.zeek, line 32: table constructor used in a non-table context (3 = F) +error in double and <...>/init-mismatch.zeek, line 32: arithmetic mixed with non-arithmetic (double and 3 = F) +error in <...>/init-mismatch.zeek, line 32 and double: type mismatch (3 = F and double) +error in <...>/init-mismatch.zeek, line 32: inconsistent type in set constructor (set(3 = F)) +error in <...>/init-mismatch.zeek, line 34: not a list of indices (s2) +error in <...>/init-mismatch.zeek, line 34: type clash in assignment (s3 = set(s2)) +error in <...>/init-mismatch.zeek, line 36: pattern += op requires op to be a pattern (p += 3) +error in <...>/init-mismatch.zeek, line 38: illegal table constructor element (1.2.3.4) diff --git a/testing/btest/language/init-integration.zeek b/testing/btest/language/init-integration.zeek new file mode 100644 index 0000000000..62a9846fc3 --- /dev/null +++ b/testing/btest/language/init-integration.zeek @@ -0,0 +1,115 @@ +# @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff .stderr + +# A bunch of tests for the unification of global initializations and +# =/+=/-= expressions. + +# This is used just to pull in an example that works for globals, to make +# sure it works for locals. +@load base/frameworks/cluster + +# This first covers the bug that motivated the unification. + +type Key: record { + k0: string; + k1: string &optional; +}; + +global init_key = [$k0="x"]; + +# This used to crash or produce an ASAN error. +global state: table[Key] of count = { + [init_key] = 5, +}; + +global my_subnets = { 1.2.3.4/19, 5.6.7.8/21 }; + +event zeek_init() + { + print(fmt("init_key in state: %d", init_key in state)); + + # Check that the local version works. + local init_key2 = [$k0="y"]; + local state2: table[Key] of count = { [init_key2] = 6 }; + print(fmt("init_key2 in state2: %d", init_key2 in state2)); + + # Now checking that a complex initialization that works for + # globals also works for locals. + local cluster_nodes = { + ["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=3/tcp], + ["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=5/udp, $manager="manager-1"], + ["worker-2"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=7/tcp, $manager="manager-1"], +}; + + cluster_nodes += { ["worker-3"] = [$node_type=Cluster::WORKER, $ip=1.2.3.4, $p=9/udp] }; + print cluster_nodes; + + cluster_nodes -= { ["worker-2"] = [$node_type=Cluster::MANAGER, $ip=0.0.0.0, $p=11/tcp] }; + print cluster_nodes; + + # Similar, but without type inference. + local cluster_nodes2: table[string] of Cluster::Node; + cluster_nodes2 = { ["worker-4"] = [$node_type=Cluster::WORKER, $ip=2.3.4.5, $p=13/udp] }; + + local cluster_nodes3: table[string] of Cluster::Node = { + ["worker-5"] = [$node_type=Cluster::WORKER, $ip=3.4.5.6, $p=15/tcp] + }; + + print cluster_nodes2; + cluster_nodes2 += cluster_nodes3; + print cluster_nodes2; + cluster_nodes2 -= cluster_nodes3; + cluster_nodes2 += table(["worker-6"] = Cluster::Node($node_type=Cluster::WORKER, $ip=4.5.6.7, $p=17/udp)); + print cluster_nodes2; + + # Test automatic type conversions. + local s: set[double, int]; + s += { [3, 4] }; + print s; + s -= { [3, 3] }; + print s; + s -= { [3, 4] }; + print s; + # Note, the following correctly generates a type-mismatch error + # if we use set([9, 4]) since that's a set[count, count], not + # a set[double, int]. + s += set([9.0, +4]); + print s; + + # Similar, for tables. + local t: table[double, double] of double; + t += { [3, 4] = 5 }; + print t; + t -= { [3, 3] = 9 }; + print t; + t -= { [3, 4] = 7 }; + print t; + + # Test use of sets for expansion. my_subnets needs to be a global, + # because expansion happens at compile-time. + local x: set[string, subnet]; + x += { [["foo", "bar"], my_subnets] }; + print x; + + # Test adding to patterns dynamically. + local p = /foo/; + p += /bar/; + print p; + + # Tests for vectors. + local v: vector of count; + local v2 = vector(20, 21, 22, 23); + v = { 1, 3, 5 }; + v += 9; + v += { 2, 4, 6 }; + v += v2; + print v; + + local v3: vector of vector of count; + local v4 = vector(vector(80, 81), vector(90, 91, 92)); + v3 += { vector(3,2,1), vector(1,2,3) }; + v3 += v2; + v3 += v4; + print v3; + } diff --git a/testing/btest/language/init-mismatch.zeek b/testing/btest/language/init-mismatch.zeek new file mode 100644 index 0000000000..2153ca6efd --- /dev/null +++ b/testing/btest/language/init-mismatch.zeek @@ -0,0 +1,40 @@ +# @TEST-EXEC-FAIL: zeek -b %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr + +# Tests for various mismatches in initializations. + +global a: count = [3, 5]; +global b [4, 6]; +global c = 9; +global s1: set[double]; +global s2: set[int]; +global s3: set[count, count]; +global t: table[addr] of bool; +global t2 = { [1, 3] = F, [2, 4, 6] = T }; +global t3 = table( ["foo"] = 3, "bar" ); +global v: vector of count; +global p: pattern; +global x = { }; + +function foo() + { + local subnets = { 1.2.3.4/24, 2.3.4.5/5 }; + local my_subnets: set[string, subnet]; + my_subnets = { ["foo", subnets] }; + } + +c += { 2, 4 }; +v -= { 3, 5 }; + +s1 += s2; +s1 -= s2; + +s1 += { [3] = F }; + +s3 = { s2 }; + +p += 3; + +t += { 1.2.3.4, F }; + +print a, b; From 18cfee51c2e6616a2799e7178dfc0eef3f3a4d66 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:35:45 -0800 Subject: [PATCH 105/204] updates for script optimization --- src/script_opt/Expr.cc | 122 ++++++++++++++++++++++++++++++-------- src/script_opt/Stmt.cc | 3 +- src/script_opt/UseDefs.cc | 18 +++++- 3 files changed, 115 insertions(+), 28 deletions(-) diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index 95f2274150..8cc45b654f 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -881,40 +881,77 @@ ExprPtr AddToExpr::Duplicate() return SetSucc(new AddToExpr(op1_d, op2_d)); } +bool AddToExpr::IsReduced(Reducer* c) const + { + auto t = op1->GetType(); + auto tag = t->Tag(); + + if ( tag == TYPE_PATTERN ) + return op1->HasReducedOps(c) && op2->IsReduced(c); + + if ( tag == TYPE_TABLE ) + return op1->IsReduced(c) && op2->IsReduced(c); + + if ( tag == TYPE_VECTOR && same_type(t, op2->GetType()) ) + return op1->IsReduced(c) && op2->IsReduced(c); + + return NonReduced(this); + } + ExprPtr AddToExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { - if ( IsVector(op1->GetType()->Tag()) ) + auto tag = op1->GetType()->Tag(); + + switch ( tag ) { - StmtPtr red_stmt1; - StmtPtr red_stmt2; + case TYPE_PATTERN: + case TYPE_TABLE: + case TYPE_VECTOR: + { + StmtPtr red_stmt1; + StmtPtr red_stmt2; - if ( op1->Tag() == EXPR_FIELD ) - red_stmt1 = op1->ReduceToSingletons(c); - else - op1 = op1->Reduce(c, red_stmt1); + if ( tag == TYPE_PATTERN && op1->Tag() == EXPR_FIELD ) + red_stmt1 = op1->ReduceToSingletons(c); + else + op1 = op1->Reduce(c, red_stmt1); - op2 = op2->Reduce(c, red_stmt2); + auto& t = op1->GetType(); + op2 = op2->Reduce(c, red_stmt2); - auto append = make_intrusive(op1->Duplicate(), op2); - append->SetOriginal(ThisPtr()); + red_stmt = MergeStmts(red_stmt1, red_stmt2); - auto append_stmt = make_intrusive(append); + if ( tag == TYPE_VECTOR && ! same_type(t, op2->GetType()) ) + { + auto append = make_intrusive(op1->Duplicate(), op2); + append->SetOriginal(ThisPtr()); - red_stmt = MergeStmts(red_stmt1, red_stmt2, append_stmt); + auto append_stmt = make_intrusive(append); - return op1; + red_stmt = MergeStmts(red_stmt, append_stmt); + + return op1; + } + + return ThisPtr(); + } + + default: + { + auto rhs = op1->AsRefExprPtr()->GetOp1(); + auto do_incr = make_intrusive(rhs->Duplicate(), op2); + auto assign = make_intrusive(op1, do_incr, false, nullptr, nullptr, false); + + return assign->ReduceToSingleton(c, red_stmt); + } } + } - else - { - // We could do an ASSERT that op1 is an EXPR_REF, but - // the following is basically equivalent. - auto rhs = op1->AsRefExprPtr()->GetOp1(); - auto do_incr = make_intrusive(rhs->Duplicate(), op2); - auto assign = make_intrusive(op1, do_incr, false, nullptr, nullptr, false); - - return assign->ReduceToSingleton(c, red_stmt); - } +ExprPtr AddToExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) + { + auto at_stmt = make_intrusive(Duplicate()); + red_stmt = at_stmt->Reduce(c); + return op1; } ExprPtr SubExpr::Duplicate() @@ -972,15 +1009,43 @@ ExprPtr RemoveFromExpr::Duplicate() return SetSucc(new RemoveFromExpr(op1_d, op2_d)); } +bool RemoveFromExpr::IsReduced(Reducer* c) const + { + if ( op1->GetType()->Tag() == TYPE_TABLE ) + return op1->IsReduced(c) && op2->IsReduced(c); + + return NonReduced(this); + } + ExprPtr RemoveFromExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { - auto rhs = op1->AsRefExprPtr()->GetOp1(); - auto do_decr = make_intrusive(rhs->Duplicate(), op2); + if ( op1->GetType()->Tag() == TYPE_TABLE ) + { + StmtPtr red_stmt1; + StmtPtr red_stmt2; + + op1 = op1->Reduce(c, red_stmt1); + op2 = op2->Reduce(c, red_stmt2); + + red_stmt = MergeStmts(red_stmt1, red_stmt2); + + return ThisPtr(); + } + + auto lhs = op1->AsRefExprPtr()->GetOp1(); + auto do_decr = make_intrusive(lhs->Duplicate(), op2); auto assign = make_intrusive(op1, do_decr, false, nullptr, nullptr, false); return assign->Reduce(c, red_stmt); } +ExprPtr RemoveFromExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) + { + auto rf_stmt = make_intrusive(Duplicate()); + red_stmt = rf_stmt->Reduce(c); + return op1; + } + ExprPtr TimesExpr::Duplicate() { auto op1_d = op1->Duplicate(); @@ -2676,6 +2741,13 @@ ExprPtr AppendToExpr::Reduce(Reducer* c, StmtPtr& red_stmt) return ThisPtr(); } +ExprPtr AppendToExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) + { + auto at_stmt = make_intrusive(Duplicate()); + red_stmt = at_stmt->Reduce(c); + return op1->AsRefExprPtr()->GetOp1(); + } + IndexAssignExpr::IndexAssignExpr(ExprPtr arg_op1, ExprPtr arg_op2, ExprPtr arg_op3) : BinaryExpr(EXPR_INDEX_ASSIGN, std::move(arg_op1), std::move(arg_op2)) { diff --git a/src/script_opt/Stmt.cc b/src/script_opt/Stmt.cc index feea66a927..8251e05c71 100644 --- a/src/script_opt/Stmt.cc +++ b/src/script_opt/Stmt.cc @@ -161,7 +161,8 @@ StmtPtr ExprStmt::DoReduce(Reducer* c) return TransformMe(make_intrusive(), c); if ( (t == EXPR_ASSIGN || t == EXPR_CALL || t == EXPR_INDEX_ASSIGN || - t == EXPR_FIELD_LHS_ASSIGN || t == EXPR_APPEND_TO) && + t == EXPR_FIELD_LHS_ASSIGN || t == EXPR_APPEND_TO || t == EXPR_ADD_TO || + t == EXPR_REMOVE_FROM) && e->IsReduced(c) ) return ThisPtr(); diff --git a/src/script_opt/UseDefs.cc b/src/script_opt/UseDefs.cc index de204cc558..21ebb59548 100644 --- a/src/script_opt/UseDefs.cc +++ b/src/script_opt/UseDefs.cc @@ -466,6 +466,15 @@ UDs UseDefs::ExprUDs(const Expr* e) AddInExprUDs(uds, e->GetOp1()->AsRefExprPtr()->GetOp1().get()); break; + case EXPR_ADD_TO: + case EXPR_REMOVE_FROM: + { + AddInExprUDs(uds, e->GetOp1().get()); + auto rhs_UDs = ExprUDs(e->GetOp2().get()); + uds = UD_Union(uds, rhs_UDs); + break; + } + case EXPR_RECORD_CONSTRUCTOR: { auto r = static_cast(e); @@ -527,6 +536,10 @@ void UseDefs::AddInExprUDs(UDs uds, const Expr* e) { switch ( e->Tag() ) { + case EXPR_REF: + AddInExprUDs(uds, e->GetOp1().get()); + break; + case EXPR_NAME: AddID(uds, e->AsNameExpr()->Id()); break; @@ -548,8 +561,9 @@ void UseDefs::AddInExprUDs(UDs uds, const Expr* e) AddInExprUDs(uds, e->GetOp1()->AsRefExprPtr()->GetOp1().get()); break; - case EXPR_ASSIGN: - // These occur inside of table constructors. + case EXPR_ASSIGN: // can occur inside a table constructor + case EXPR_ADD_TO: + case EXPR_REMOVE_FROM: AddInExprUDs(uds, e->GetOp1().get()); AddInExprUDs(uds, e->GetOp2().get()); break; From 1f27edf756af5d0bb6ccd38f171914247c48124c Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 14:48:18 -0800 Subject: [PATCH 106/204] btest tweaks I overlooked --- testing/btest/Baseline/language.init-integration/.stderr | 1 + .../Baseline/language.redef-same-prefixtable-idx/.stderr | 4 ++-- testing/btest/language/redef-same-prefixtable-idx.zeek | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 testing/btest/Baseline/language.init-integration/.stderr diff --git a/testing/btest/Baseline/language.init-integration/.stderr b/testing/btest/Baseline/language.init-integration/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/language.init-integration/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/language.redef-same-prefixtable-idx/.stderr b/testing/btest/Baseline/language.redef-same-prefixtable-idx/.stderr index ebf136334a..2bf6110ff6 100644 --- a/testing/btest/Baseline/language.redef-same-prefixtable-idx/.stderr +++ b/testing/btest/Baseline/language.redef-same-prefixtable-idx/.stderr @@ -1,3 +1,3 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning in /Users/vern/warehouse/zeek/master/testing/btest/.tmp/language.redef-same-prefixtable-idx/redef-same-prefixtable-idx.zeek, line 7: initialization not preceded by =/+=/-= is deprecated (3.0.0.0/8 = 1.0.0.0/8) -warning in /Users/vern/warehouse/zeek/master/testing/btest/.tmp/language.redef-same-prefixtable-idx/redef-same-prefixtable-idx.zeek, line 8: initialization not preceded by =/+=/-= is deprecated (3.0.0.0/8 = 2.0.0.0/8) +warning in <...>/redef-same-prefixtable-idx.zeek, line 7: initialization not preceded by =<...>/-= is deprecated (3.0.0.0/8 = 1.0.0.0/8) +warning in <...>/redef-same-prefixtable-idx.zeek, line 8: initialization not preceded by =<...>/-= is deprecated (3.0.0.0/8 = 2.0.0.0/8) diff --git a/testing/btest/language/redef-same-prefixtable-idx.zeek b/testing/btest/language/redef-same-prefixtable-idx.zeek index 74d0feb82c..838f3fc0ba 100644 --- a/testing/btest/language/redef-same-prefixtable-idx.zeek +++ b/testing/btest/language/redef-same-prefixtable-idx.zeek @@ -1,5 +1,5 @@ # @TEST-EXEC: zeek -b %INPUT >out -# @TEST-EXEC: btest-diff .stderr +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr # @TEST-EXEC: btest-diff out const my_table: table[subnet] of subnet &redef; From 16a16948a155cad720387efecbc265c3e3664f6b Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 16:12:34 -0800 Subject: [PATCH 107/204] updates for ZAM optimization --- src/script_opt/ZAM/AM-Opt.cc | 10 ++- src/script_opt/ZAM/Compile.h | 5 +- src/script_opt/ZAM/Expr.cc | 74 ++++++++++++++----- src/script_opt/ZAM/Ops.in | 72 ++++++++++++++---- testing/btest/Baseline.zam/bifs.to_addr/error | 2 + .../btest/Baseline.zam/bifs.to_addr/output | 10 +++ .../bifs.to_double_from_string/error | 3 + .../bifs.to_double_from_string/output | 6 ++ 8 files changed, 143 insertions(+), 39 deletions(-) create mode 100644 testing/btest/Baseline.zam/bifs.to_addr/error create mode 100644 testing/btest/Baseline.zam/bifs.to_addr/output create mode 100644 testing/btest/Baseline.zam/bifs.to_double_from_string/error create mode 100644 testing/btest/Baseline.zam/bifs.to_double_from_string/output diff --git a/src/script_opt/ZAM/AM-Opt.cc b/src/script_opt/ZAM/AM-Opt.cc index fa8b81ac57..f32ccf1fc4 100644 --- a/src/script_opt/ZAM/AM-Opt.cc +++ b/src/script_opt/ZAM/AM-Opt.cc @@ -670,7 +670,15 @@ void ZAMCompiler::ReMapVar(const ID* id, int slot, bro_uint_t inst) // powerful allocation method like graph coloring. However, far and // away the bulk of our variables are short-lived temporaries, // for which greedy should work fine. - bool is_managed = ZVal::IsManagedType(id->GetType()); + // + // Note, we also need to make sure that denizens sharing a slot + // are all consistently either managed, or non-managed, types. + // One subtlety in this regard is that identifiers that are types + // should always be deemed "managed", even if the type they refer + // to is not managed, because what matters for uses of those + // identifiers is interpreting them as "any" values having an + // internal type of TYPE_TYPE. + bool is_managed = ZVal::IsManagedType(id->GetType()) || id->IsType(); int apt_slot = -1; for ( unsigned int i = 0; i < shared_frame_denizens.size(); ++i ) diff --git a/src/script_opt/ZAM/Compile.h b/src/script_opt/ZAM/Compile.h index ec6cad51bb..e1d06e128c 100644 --- a/src/script_opt/ZAM/Compile.h +++ b/src/script_opt/ZAM/Compile.h @@ -178,6 +178,8 @@ private: const ZAMStmt CompileIncrExpr(const IncrExpr* e); const ZAMStmt CompileAppendToExpr(const AppendToExpr* e); + const ZAMStmt CompileAddToExpr(const AddToExpr* e); + const ZAMStmt CompileRemoveFromExpr(const RemoveFromExpr* e); const ZAMStmt CompileAssignExpr(const AssignExpr* e); const ZAMStmt CompileAssignToIndex(const NameExpr* lhs, const IndexExpr* rhs); const ZAMStmt CompileFieldLHSAssignExpr(const FieldLHSAssignExpr* e); @@ -233,9 +235,6 @@ private: const ZAMStmt AssignVecElems(const Expr* e); const ZAMStmt AssignTableElem(const Expr* e); - const ZAMStmt AppendToField(const NameExpr* n1, const NameExpr* n2, const ConstExpr* c, - int offset); - const ZAMStmt ConstructTable(const NameExpr* n, const Expr* e); const ZAMStmt ConstructSet(const NameExpr* n, const Expr* e); const ZAMStmt ConstructRecord(const NameExpr* n, const Expr* e); diff --git a/src/script_opt/ZAM/Expr.cc b/src/script_opt/ZAM/Expr.cc index 3682e9f1ca..bacca511b8 100644 --- a/src/script_opt/ZAM/Expr.cc +++ b/src/script_opt/ZAM/Expr.cc @@ -20,6 +20,12 @@ const ZAMStmt ZAMCompiler::CompileExpr(const Expr* e) case EXPR_APPEND_TO: return CompileAppendToExpr(static_cast(e)); + case EXPR_ADD_TO: + return CompileAddToExpr(static_cast(e)); + + case EXPR_REMOVE_FROM: + return CompileRemoveFromExpr(static_cast(e)); + case EXPR_ASSIGN: return CompileAssignExpr(static_cast(e)); @@ -76,44 +82,72 @@ const ZAMStmt ZAMCompiler::CompileIncrExpr(const IncrExpr* e) const ZAMStmt ZAMCompiler::CompileAppendToExpr(const AppendToExpr* e) { - auto op1 = e->GetOp1(); + auto n1 = e->GetOp1()->AsNameExpr(); auto op2 = e->GetOp2(); + auto n2 = op2->Tag() == EXPR_NAME ? op2->AsNameExpr() : nullptr; + auto cc = op2->Tag() != EXPR_NAME ? op2->AsConstExpr() : nullptr; + if ( n1->GetType()->Yield()->Tag() == TYPE_ANY ) + return n2 ? AppendToAnyVecVV(n1, n2) : AppendToAnyVecVC(n1, cc); + + return n2 ? AppendToVV(n1, n2) : AppendToVC(n1, cc); + } + +const ZAMStmt ZAMCompiler::CompileAddToExpr(const AddToExpr* e) + { + auto op1 = e->GetOp1(); + auto t1 = op1->GetType()->Tag(); + + auto op2 = e->GetOp2(); auto n2 = op2->Tag() == EXPR_NAME ? op2->AsNameExpr() : nullptr; auto cc = op2->Tag() != EXPR_NAME ? op2->AsConstExpr() : nullptr; if ( op1->Tag() == EXPR_FIELD ) { + assert(t1 == TYPE_PATTERN); auto f = op1->AsFieldExpr()->Field(); auto n1 = op1->GetOp1()->AsNameExpr(); - return AppendToField(n1, n2, cc, f); + + ZInstI z; + + if ( n2 ) + { + z = ZInstI(OP_ADDPATTERNTOFIELD_VVi, FrameSlot(n1), FrameSlot(n2), f); + z.op_type = OP_VVV_I3; + } + else + { + z = ZInstI(OP_ADDPATTERNTOFIELD_VCi, FrameSlot(n1), f, cc); + z.op_type = OP_VVC_I2; + } + + z.SetType(n2 ? n2->GetType() : cc->GetType()); + + return AddInst(z); } auto n1 = op1->AsNameExpr(); - return n2 ? AppendToVV(n1, n2) : AppendToVC(n1, cc); + if ( t1 == TYPE_PATTERN ) + return n2 ? ExtendPatternVV(n1, n2) : ExtendPatternVC(n1, cc); + + if ( t1 == TYPE_VECTOR ) + return n2 ? AddVecToVecVV(n1, n2) : AddVecToVecVC(n1, cc); + + assert(t1 == TYPE_TABLE); + + return n2 ? AddTableToTableVV(n1, n2) : AddTableToTableVC(n1, cc); } -const ZAMStmt ZAMCompiler::AppendToField(const NameExpr* n1, const NameExpr* n2, const ConstExpr* c, - int offset) +const ZAMStmt ZAMCompiler::CompileRemoveFromExpr(const RemoveFromExpr* e) { - ZInstI z; + auto n1 = e->GetOp1()->AsNameExpr(); + auto op2 = e->GetOp2(); - if ( n2 ) - { - z = ZInstI(OP_APPENDTOFIELD_VVi, FrameSlot(n1), FrameSlot(n2), offset); - z.op_type = OP_VVV_I3; - } - else - { - ASSERT(c); - z = ZInstI(OP_APPENDTOFIELD_VCi, FrameSlot(n1), offset, c); - z.op_type = OP_VVC_I2; - } + auto n2 = op2->Tag() == EXPR_NAME ? op2->AsNameExpr() : nullptr; + auto cc = op2->Tag() != EXPR_NAME ? op2->AsConstExpr() : nullptr; - z.SetType(n2 ? n2->GetType() : c->GetType()); - - return AddInst(z); + return n2 ? RemoveTableFromTableVV(n1, n2) : RemoveTableFromTableVC(n1, cc); } const ZAMStmt ZAMCompiler::CompileAssignExpr(const AssignExpr* e) diff --git a/src/script_opt/ZAM/Ops.in b/src/script_opt/ZAM/Ops.in index 3a191aded3..5d4529883a 100644 --- a/src/script_opt/ZAM/Ops.in +++ b/src/script_opt/ZAM/Ops.in @@ -353,31 +353,73 @@ unary-op AppendTo # value itself. op1-read set-type $1 -eval auto copy = CopyVal($1); - auto vv = frame[z.v1].vector_val; - vv->RawVec()->push_back(copy); - vv->Modified(); +eval auto vv = frame[z.v1].vector_val; + if ( vv->Size() == 0 ) + // Use the slightly more expensive Assign(), since it + // knows how to deal with empty vectors that do not yet + // have concrete types. + vv->Assign(0, $1.ToVal(z.t)); + else + { + vv->RawVec()->push_back(CopyVal($1)); + vv->Modified(); + } -internal-op AppendToField +# For vectors-of-any, we always go through the Assign() interface because +# it's needed for tracking the potentially differing types. +unary-op AppendToAnyVec +op1-read +set-type $1 +eval auto vv = frame[z.v1].vector_val; + vv->Assign(vv->Size(), $1.ToVal(z.t)); + +internal-op AddPatternToField type VVi op1-read -eval EvalAppendToField(frame[z.v2], v3) +eval EvalAddPatternToField(frame[z.v2], v3) -macro EvalAppendToField(val, f) - auto v = CopyVal(val); - auto fvv = frame[z.v1].record_val->GetField(z.f)->AsVectorVal(); - if ( fvv ) +macro EvalAddPatternToField(v, f) + auto fpat = frame[z.v1].record_val->GetField(z.f)->AsPatternVal(); + if ( fpat ) { - fvv->RawVec()->push_back(v); - fvv->Modified(); + v.re_val->AddTo(fpat, false); + frame[z.v1].record_val->Modified(); } else ZAM_run_time_error(z.loc, util::fmt("field value missing: $%s", frame[z.v1].record_val->GetType()->AsRecordType()->FieldName(z.f))); -internal-op AppendToField +internal-op AddPatternToField type VCi op1-read -eval EvalAppendToField(z.c, v2) +eval EvalAddPatternToField(z.c, v2) + +unary-op ExtendPattern +op1-read +eval $1.re_val->AddTo(frame[z.v1].re_val, false); + +unary-op AddVecToVec +op1-read +eval $1.vector_val->AddTo(frame[z.v1].vector_val, false); + +unary-op AddTableToTable +op1-read +eval auto t = frame[z.v1].table_val; + auto v = $1.table_val; + if ( v->Size() > 0 ) + { + v->AddTo(t, false); + t->Modified(); + } + +unary-op RemoveTableFromTable +op1-read +eval auto t = frame[z.v1].table_val; + auto v = $1.table_val; + if ( v->Size() > 0 ) + { + v->RemoveFrom(t); + t->Modified(); + } unary-expr-op Cast op-type X @@ -1714,7 +1756,7 @@ eval step_iters[z.v2].InitLoop(frame[z.v1].string_val->AsString()); internal-op Init-String-Loop type VC -eval step_iters[z.v2].InitLoop(z.c.string_val->AsString()); +eval step_iters[z.v1].InitLoop(z.c.string_val->AsString()); internal-op Next-String-Iter # v1 = iteration variable diff --git a/testing/btest/Baseline.zam/bifs.to_addr/error b/testing/btest/Baseline.zam/bifs.to_addr/error new file mode 100644 index 0000000000..60ef944fd6 --- /dev/null +++ b/testing/btest/Baseline.zam/bifs.to_addr/error @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/to_addr.zeek, line 20: failed converting string to IP address (not an IP) diff --git a/testing/btest/Baseline.zam/bifs.to_addr/output b/testing/btest/Baseline.zam/bifs.to_addr/output new file mode 100644 index 0000000000..0ee35ee59b --- /dev/null +++ b/testing/btest/Baseline.zam/bifs.to_addr/output @@ -0,0 +1,10 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +to_addr(0.0.0.0) = 0.0.0.0 (SUCCESS) +to_addr(1.2.3.4) = 1.2.3.4 (SUCCESS) +to_addr(01.02.03.04) = 1.2.3.4 (SUCCESS) +to_addr(001.002.003.004) = 1.2.3.4 (SUCCESS) +to_addr(10.20.30.40) = 10.20.30.40 (SUCCESS) +to_addr(100.200.30.40) = 100.200.30.40 (SUCCESS) +to_addr(10.0.0.0) = 10.0.0.0 (SUCCESS) +to_addr(10.00.00.000) = 10.0.0.0 (SUCCESS) +to_addr(not an IP) = :: (SUCCESS) diff --git a/testing/btest/Baseline.zam/bifs.to_double_from_string/error b/testing/btest/Baseline.zam/bifs.to_double_from_string/error new file mode 100644 index 0000000000..55535e96f5 --- /dev/null +++ b/testing/btest/Baseline.zam/bifs.to_double_from_string/error @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/to_double_from_string.zeek, line 15: bad conversion to double (NotADouble) +error in <...>/to_double_from_string.zeek, line 16: bad conversion to double () diff --git a/testing/btest/Baseline.zam/bifs.to_double_from_string/output b/testing/btest/Baseline.zam/bifs.to_double_from_string/output new file mode 100644 index 0000000000..16797583f1 --- /dev/null +++ b/testing/btest/Baseline.zam/bifs.to_double_from_string/output @@ -0,0 +1,6 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +to_double(3.14) = 3.14 (SUCCESS) +to_double(-3.14) = -3.14 (SUCCESS) +to_double(0) = 0.0 (SUCCESS) +to_double(NotADouble) = 0.0 (SUCCESS) +to_double() = 0.0 (SUCCESS) From bcebe27ced1c0d0d5a03fdb53891b4d3b908a936 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 11 Mar 2022 16:14:35 -0800 Subject: [PATCH 108/204] updates for compile-to-C++ --- src/script_opt/CPP/Compile.h | 1 + src/script_opt/CPP/Exprs.cc | 66 +++++++++++++++++++++++++++++---- src/script_opt/CPP/RuntimeOps.h | 22 +++++++++++ src/script_opt/CPP/RuntimeVec.h | 11 +++++- 4 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/script_opt/CPP/Compile.h b/src/script_opt/CPP/Compile.h index 6aad9eb1e9..447427204e 100644 --- a/src/script_opt/CPP/Compile.h +++ b/src/script_opt/CPP/Compile.h @@ -792,6 +792,7 @@ private: std::string GenIndexExpr(const Expr* e, GenType gt); std::string GenAssignExpr(const Expr* e, GenType gt, bool top_level); std::string GenAddToExpr(const Expr* e, GenType gt, bool top_level); + std::string GenRemoveFromExpr(const Expr* e, GenType gt, bool top_level); std::string GenSizeExpr(const Expr* e, GenType gt); std::string GenScheduleExpr(const Expr* e); std::string GenLambdaExpr(const Expr* e); diff --git a/src/script_opt/CPP/Exprs.cc b/src/script_opt/CPP/Exprs.cc index a9c41a8377..fed8ddcbe9 100644 --- a/src/script_opt/CPP/Exprs.cc +++ b/src/script_opt/CPP/Exprs.cc @@ -77,8 +77,6 @@ string CPPCompile::GenExpr(const Expr* e, GenType gt, bool top_level) return GenBinary(e, gt, "+", "add"); case EXPR_SUB: return GenBinary(e, gt, "-", "sub"); - case EXPR_REMOVE_FROM: - return GenBinary(e, gt, "-="); case EXPR_TIMES: return GenBinary(e, gt, "*", "mul"); case EXPR_DIVIDE: @@ -127,6 +125,8 @@ string CPPCompile::GenExpr(const Expr* e, GenType gt, bool top_level) return GenAssignExpr(e, gt, top_level); case EXPR_ADD_TO: return GenAddToExpr(e, gt, top_level); + case EXPR_REMOVE_FROM: + return GenRemoveFromExpr(e, gt, top_level); case EXPR_REF: return GenExpr(e->GetOp1(), gt); case EXPR_SIZE: @@ -476,16 +476,34 @@ string CPPCompile::GenAssignExpr(const Expr* e, GenType gt, bool top_level) string CPPCompile::GenAddToExpr(const Expr* e, GenType gt, bool top_level) { const auto& t = e->GetType(); + auto lhs = e->GetOp1(); + auto rhs = e->GetOp2(); + + std::string add_to_func; if ( t->Tag() == TYPE_VECTOR ) { - auto gen = string("vector_append__CPP(") + GenExpr(e->GetOp1(), GEN_VAL_PTR) + ", " + - GenExpr(e->GetOp2(), GEN_VAL_PTR) + ")"; + if ( same_type(lhs->GetType(), rhs->GetType()) ) + add_to_func = "vector_vec_append__CPP"; + else + add_to_func = "vector_append__CPP"; + } + + else if ( t->Tag() == TYPE_PATTERN ) + add_to_func = "re_append__CPP"; + + else if ( t->Tag() == TYPE_TABLE ) + add_to_func = "table_append__CPP"; + + if ( ! add_to_func.empty() ) + { + auto gen = add_to_func + "(" + GenExpr(lhs, GEN_VAL_PTR) + ", " + + GenExpr(rhs, GEN_VAL_PTR) + ")"; return GenericValPtrToGT(gen, t, gt); } - // Second GetOp1 is because for non-vectors, LHS will be a RefExpr. - auto lhs = e->GetOp1()->GetOp1(); + // Second GetOp1 is because if we get this far, LHS will be a RefExpr. + lhs = lhs->GetOp1(); if ( t->Tag() == TYPE_STRING ) { @@ -499,7 +517,7 @@ string CPPCompile::GenAddToExpr(const Expr* e, GenType gt, bool top_level) { // LHS is a compound, or a global (and thus doesn't // equate to a C++ variable); expand x += y to x = x + y - auto rhs = make_intrusive(lhs, e->GetOp2()); + rhs = make_intrusive(lhs, rhs); auto assign = make_intrusive(lhs, rhs, false, nullptr, nullptr, false); // Make sure any newly created types are known to @@ -513,6 +531,40 @@ string CPPCompile::GenAddToExpr(const Expr* e, GenType gt, bool top_level) return GenBinary(e, gt, "+="); } +string CPPCompile::GenRemoveFromExpr(const Expr* e, GenType gt, bool top_level) + { + const auto& t = e->GetType(); + auto lhs = e->GetOp1(); + auto rhs = e->GetOp2(); + + if ( t->Tag() == TYPE_TABLE && same_type(lhs->GetType(), rhs->GetType()) ) + { + auto gen = std::string("table_remove_from__CPP(") + GenExpr(lhs, GEN_VAL_PTR) + ", " + + GenExpr(rhs, GEN_VAL_PTR) + ")"; + return GenericValPtrToGT(gen, t, gt); + } + + // Second GetOp1 is because if we get this far, LHS will be a RefExpr. + lhs = lhs->GetOp1(); + + if ( lhs->Tag() != EXPR_NAME || lhs->AsNameExpr()->Id()->IsGlobal() ) + { + // LHS is a compound, or a global (and thus doesn't + // equate to a C++ variable); expand x -= y to x = x - y + rhs = make_intrusive(lhs, rhs); + auto assign = make_intrusive(lhs, rhs, false, nullptr, nullptr, false); + + // Make sure any newly created types are known to + // the profiler. + (void)pfs.HashType(rhs->GetType()); + (void)pfs.HashType(assign->GetType()); + + return GenExpr(assign, gt, top_level); + } + + return GenBinary(e, gt, "-="); + } + string CPPCompile::GenSizeExpr(const Expr* e, GenType gt) { const auto& t = e->GetType(); diff --git a/src/script_opt/CPP/RuntimeOps.h b/src/script_opt/CPP/RuntimeOps.h index c0ea9231f9..02df049eb9 100644 --- a/src/script_opt/CPP/RuntimeOps.h +++ b/src/script_opt/CPP/RuntimeOps.h @@ -113,6 +113,21 @@ inline TableValPtr table_coerce__CPP(const ValPtr& v, const TypePtr& t) return make_intrusive(cast_intrusive(t), tv->GetAttrs()); } +// For tables, executes t1 += t2. +inline TableValPtr table_append__CPP(const TableValPtr& t1, const TableValPtr& t2) + { + t2->AddTo(t1.get(), false); + return t1; + } + +// For tables, executes t1 -= t2. +inline TableValPtr table_remove_from__CPP(const TableValPtr& t1, const TableValPtr& t2) + { + if ( t2->Size() > 0 ) + t2->RemoveFrom(t1.get()); + return t1; + } + // The same, for an empty record. inline VectorValPtr vector_coerce__CPP(const ValPtr& v, const TypePtr& t) { @@ -147,6 +162,13 @@ extern RecordValPtr record_constructor_map__CPP(std::vector vals, std::v // Constructs a vector of the given type, populated with the given values. extern VectorValPtr vector_constructor__CPP(std::vector vals, VectorTypePtr t); +// For patterns, executes p1 += p2. +inline PatternValPtr re_append__CPP(const PatternValPtr& p1, const PatternValPtr& p2) + { + p2->AddTo(p1.get(), false); + return p1; + } + // Schedules an event to occur at the given absolute time, parameterized // with the given set of values. A separate function to facilitate avoiding // the scheduling if Zeek is terminating. diff --git a/src/script_opt/CPP/RuntimeVec.h b/src/script_opt/CPP/RuntimeVec.h index 2dfe1374c3..41be84c55f 100644 --- a/src/script_opt/CPP/RuntimeVec.h +++ b/src/script_opt/CPP/RuntimeVec.h @@ -15,10 +15,17 @@ namespace zeek::detail // Appends v2 to the vector v1. A separate function because of the // need to support assignment cascades. -inline ValPtr vector_append__CPP(VectorValPtr v1, ValPtr v2) +inline ValPtr vector_append__CPP(VectorValPtr v1, const ValPtr& v2) { v1->Assign(v1->Size(), v2); - return v2; + return v1; + } + +// Appends vector v2 to the vector v1. +inline ValPtr vector_vec_append__CPP(VectorValPtr v1, const VectorValPtr& v2) + { + v2->AddTo(v1.get(), false); + return v1; } // Unary vector operations. From bedcc6820fd1b7851307601c8fc4aef82e511c32 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Thu, 24 Mar 2022 00:33:38 +0000 Subject: [PATCH 109/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index e2cb699675..1be3190ba9 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit e2cb69967552764f5fb89f714414d71e6cdb2543 +Subproject commit 1be3190ba972376cc1064c3ac3a68cce68a18422 From e2b222020156481ea49f3495b1dc4c8a9a1e1f93 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Fri, 25 Mar 2022 00:36:00 +0000 Subject: [PATCH 110/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 1be3190ba9..5346534ff7 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 1be3190ba972376cc1064c3ac3a68cce68a18422 +Subproject commit 5346534ff75a3028baefacc236b19822cccebee7 From 8929bcb48e49871b8c0dbf5e9197c8f710d9f97d Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Sat, 26 Mar 2022 00:34:23 +0000 Subject: [PATCH 111/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 5346534ff7..efbe3411cf 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 5346534ff75a3028baefacc236b19822cccebee7 +Subproject commit efbe3411cf2f6fdbdb3ec1252a293e7a5d9e29ab From 0a2cd1e99f88a0e7fbd75585325cc8a6619743e6 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 28 Mar 2022 09:57:33 -0700 Subject: [PATCH 112/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index efbe3411cf..ccbc0c34be 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit efbe3411cf2f6fdbdb3ec1252a293e7a5d9e29ab +Subproject commit ccbc0c34be05c09b42e258df4f6effd38e076145 From 0d29346ca3f8f3a094b9f7354fa814a461c1d755 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 28 Mar 2022 10:50:14 -0700 Subject: [PATCH 113/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index ccbc0c34be..8fb79e16e2 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit ccbc0c34be05c09b42e258df4f6effd38e076145 +Subproject commit 8fb79e16e22511f86dae92b9fe71f8412f1476b4 From 67012b96ff85c83a4582f1e5a4b534484c87c7b7 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 28 Mar 2022 16:28:35 -0700 Subject: [PATCH 114/204] Update NEWS to reflect recent updates --- NEWS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/NEWS b/NEWS index dc30436945..b20efb7a91 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,10 @@ Breaking Changes New Functionality ----------------- +- Zeek now supports generation and replay of event traces via the new + ``--event-trace`` / ``-E`` command-line options. For details, see: + https://docs.zeek.org/en/master/quickstart.html#tracing-events + - The new --with-gen-zam configure flag and its corresponding GEN_ZAM_EXE_PATH cmake variable allow reuse of a previously built Gen-ZAM code generator. This aids cross-compilation: the Zeek build process normally compiles Gen-ZAM on @@ -23,6 +27,13 @@ New Functionality Changed Functionality --------------------- +- The behavior of the ``=``, ``+=``, and ``-=`` operators has been expanded and + unified. It now covers ``{ ... }`` initializer lists, supports cross-product + initialization, enables ``+=`` for table, set, vector and pattern values, + similarly allows ``-=`` for table and set values, and supports listing + multiple sets for ``+=`` initialization. For details, see: + https://docs.zeek.org/en/master/script-reference/operators.html#assignment-operators + - The is_num(), is_alpha(), and is_alnum() BiFs now return F for the empty string. Deprecated Functionality From b956539b46defe486517a5be461c58f6343e90d8 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 31 Mar 2022 15:55:25 -0700 Subject: [PATCH 115/204] Move new TLS decryption capabilities up to Zeek 5 in NEWS file --- NEWS | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index b20efb7a91..feebbd0928 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,14 @@ New Functionality ``--event-trace`` / ``-E`` command-line options. For details, see: https://docs.zeek.org/en/master/quickstart.html#tracing-events +- Zeek now features limited TLS decryption capabilities. This feature is experimental + and only works for TLS 1.2 connections that use the TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + ciphersuite. Furthermore Zeek requires access to the pre-master secret of each TLS + connection. Typically this functionality will be most useful when analyzing trace-files + where the TLS client recorded the key material. For more details and examples how to + use this functionality, see the TLS Decryption documentation at + https://docs.zeek.org/en/master/frameworks/tls-decryption.html + - The new --with-gen-zam configure flag and its corresponding GEN_ZAM_EXE_PATH cmake variable allow reuse of a previously built Gen-ZAM code generator. This aids cross-compilation: the Zeek build process normally compiles Gen-ZAM on @@ -161,14 +169,6 @@ New Functionality - The GRE analyzer now supports the Aruba WLAN protocol type. -- Zeek now features limited TLS decryption capabilities. This feature is experimental - and only works for TLS 1.2 connections that use the TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - ciphersuite. Furthermore Zeek requires access to the pre-master secret of each TLS - connection. Typically this functionality will be most useful when analyzing trace-files - where the TLS client recorded the key material. For more details and examples how to - use this functionality, see the TLS Decryption documentation at - https://docs.zeek.org/en/master/frameworks/tls-decryption.html - Changed Functionality --------------------- From 18fe9d84f602c90724dcec0e349789932ab9f931 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 31 Mar 2022 19:28:23 -0700 Subject: [PATCH 116/204] bug fix for empty table constructors with &default attributes (plus a typo) --- src/Val.cc | 8 ++++++++ src/Val.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Val.cc b/src/Val.cc index e2cc1e58e5..3d3290a200 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -2407,6 +2407,14 @@ void TableVal::InitDefaultFunc(detail::Frame* f) return; const auto& ytype = GetType()->Yield(); + + if ( ! ytype ) + // This happens for empty table() constructors. Don't + // instantiate a default value at this point, as we'll + // first need to type-check the attribute when the value + // is finally used. + return; + const auto& dtype = def_attr->GetExpr()->GetType(); if ( dtype->Tag() == TYPE_RECORD && ytype->Tag() == TYPE_RECORD && ! same_type(dtype, ytype) && diff --git a/src/Val.h b/src/Val.h index 3e578a52d7..afa77c8818 100644 --- a/src/Val.h +++ b/src/Val.h @@ -935,7 +935,7 @@ public: void InitTimer(double delay); void DoExpire(double t); - // If the &default attribute is not a function, or the functon has + // If the &default attribute is not a function, or the function has // already been initialized, this does nothing. Otherwise, evaluates // the function in the frame allowing it to capture its closure. void InitDefaultFunc(detail::Frame* f); From ffdcc36bd57e81515453c1c058a273ab6d3fc69f Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 31 Mar 2022 19:29:17 -0700 Subject: [PATCH 117/204] factoring to make checking of &default attributes externally accessible --- src/Attr.cc | 223 +++++++++++++++++++++++++++------------------------- src/Attr.h | 11 +++ 2 files changed, 125 insertions(+), 109 deletions(-) diff --git a/src/Attr.cc b/src/Attr.cc index 22e1ef35d8..da28845fe9 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -344,116 +344,12 @@ void Attributes::CheckAttr(Attr* a) case ATTR_DEFAULT: { - // &default is allowed for global tables, since it's used in initialization - // of table fields. it's not allowed otherwise. - if ( global_var && ! type->IsTable() ) - { - Error("&default is not valid for global variables except for tables"); - break; - } - - const auto& atype = a->GetExpr()->GetType(); - - if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) ) - { - if ( same_type(atype, type) ) - // Ok. - break; - - // Record defaults may be promotable. - if ( (type->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && - record_promotion_compatible(atype->AsRecordType(), type->AsRecordType())) ) - // Ok. - break; - - if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() ) - // Ok. - break; - - auto e = check_and_promote_expr(a->GetExpr(), type); - - if ( e ) - { - a->SetAttrExpr(std::move(e)); - // Ok. - break; - } - - a->GetExpr()->Error("&default value has inconsistent type", type.get()); - return; - } - - TableType* tt = type->AsTableType(); - const auto& ytype = tt->Yield(); - - if ( ! in_record ) - { - // &default applies to the type itself. - if ( ! same_type(atype, ytype) ) - { - // It can still be a default function. - if ( atype->Tag() == TYPE_FUNC ) - { - FuncType* f = atype->AsFuncType(); - if ( ! f->CheckArgs(tt->GetIndexTypes()) || ! same_type(f->Yield(), ytype) ) - Error("&default function type clash"); - - // Ok. - break; - } - - // Table defaults may be promotable. - if ( (ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && - record_promotion_compatible(atype->AsRecordType(), - ytype->AsRecordType())) ) - // Ok. - break; - - auto e = check_and_promote_expr(a->GetExpr(), ytype); - - if ( e ) - { - a->SetAttrExpr(std::move(e)); - // Ok. - break; - } - - Error("&default value has inconsistent type 2"); - } - - // Ok. - break; - } - - else - { - // &default applies to record field. - - if ( same_type(atype, type) ) - // Ok. - break; - - if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) ) - { - auto e = check_and_promote_expr(a->GetExpr(), type); - - if ( e ) - { - a->SetAttrExpr(std::move(e)); - break; - } - } - - // Table defaults may be promotable. - if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && - record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) ) - // Ok. - break; - - Error("&default value has inconsistent type"); - } - } + std::string err_msg; + if ( ! check_default_attr(a, type, global_var, in_record, err_msg) && + ! err_msg.empty() ) + Error(err_msg.c_str()); break; + } case ATTR_EXPIRE_READ: { @@ -751,4 +647,113 @@ bool Attributes::operator==(const Attributes& other) const return true; } +bool check_default_attr(Attr* a, const TypePtr& type, bool global_var, bool in_record, + std::string& err_msg) + { + // &default is allowed for global tables, since it's used in + // initialization of table fields. It's not allowed otherwise. + if ( global_var && ! type->IsTable() ) + { + err_msg = "&default is not valid for global variables except for tables"; + return false; + } + + const auto& atype = a->GetExpr()->GetType(); + + if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) ) + { + if ( same_type(atype, type) ) + // Ok. + return true; + + // Record defaults may be promotable. + if ( (type->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && + record_promotion_compatible(atype->AsRecordType(), type->AsRecordType())) ) + // Ok. + return true; + + if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() ) + // Ok. + return true; + + auto e = check_and_promote_expr(a->GetExpr(), type); + + if ( e ) + { + a->SetAttrExpr(std::move(e)); + // Ok. + return true; + } + + a->GetExpr()->Error("&default value has inconsistent type", type.get()); + return false; + } + + TableType* tt = type->AsTableType(); + const auto& ytype = tt->Yield(); + + if ( ! in_record ) + { // &default applies to the type itself. + if ( same_type(atype, ytype) ) + return true; + + // It can still be a default function. + if ( atype->Tag() == TYPE_FUNC ) + { + FuncType* f = atype->AsFuncType(); + if ( ! f->CheckArgs(tt->GetIndexTypes()) || ! same_type(f->Yield(), ytype) ) + { + err_msg = "&default function type clash"; + return false; + } + + // Ok. + return true; + } + + // Table defaults may be promotable. + if ( (ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && + record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType())) ) + // Ok. + return true; + + auto e = check_and_promote_expr(a->GetExpr(), ytype); + + if ( e ) + { + a->SetAttrExpr(std::move(e)); + // Ok. + return true; + } + + err_msg = "&default value has inconsistent type"; + return false; + } + + // &default applies to record field. + + if ( same_type(atype, type) ) + return true; + + if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) ) + { + auto e = check_and_promote_expr(a->GetExpr(), type); + + if ( e ) + { + a->SetAttrExpr(std::move(e)); + return true; + } + } + + // Table defaults may be promotable. + if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && + record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) ) + // Ok. + return true; + + err_msg = "&default value has inconsistent type"; + return false; + } + } diff --git a/src/Attr.h b/src/Attr.h index 0df396c2d9..6bc37ea726 100644 --- a/src/Attr.h +++ b/src/Attr.h @@ -139,5 +139,16 @@ protected: bool global_var; }; +// Checks whether default attribute "a" is compatible with the given type. +// "global_var" specifies whether the attribute is being associated with +// a global variable, and "in_record" whether it's occurring inside of +// a record declaration. +// +// Returns true on compatibility (which might include modifying "a"), false +// on an error. If an error message hasn't been directly generated, then +// it will be returned in err_msg. +extern bool check_default_attr(Attr* a, const TypePtr& type, bool global_var, bool in_record, + std::string& err_msg); + } // namespace detail } // namespace zeek From 4d2115ffd331a2d805a5e243121457b38666f1c4 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 31 Mar 2022 19:30:00 -0700 Subject: [PATCH 118/204] catch empty constructors used for type inference suppress repeated error messages --- src/Type.cc | 53 +++++++++++++++++++++++++++++++++++++++++------------ src/Type.h | 9 +++++++++ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/Type.cc b/src/Type.cc index 77d5663919..808fff7bff 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -515,6 +515,29 @@ TableType::TableType(TypeListPtr ind, TypePtr yield) } bool TableType::CheckExpireFuncCompatibility(const detail::AttrPtr& attr) + { + if ( reported_error ) + return false; + + bool success = DoExpireCheck(attr); + if ( ! success ) + reported_error = true; + + return success; + } + +TypePtr TableType::ShallowClone() + { + return make_intrusive(indices, yield_type); + } + +bool TableType::IsUnspecifiedTable() const + { + // Unspecified types have an empty list of indices. + return indices->GetTypes().empty(); + } + +bool TableType::DoExpireCheck(const detail::AttrPtr& attr) { assert(attr->Tag() == detail::ATTR_EXPIRE_FUNC); @@ -569,17 +592,6 @@ bool TableType::CheckExpireFuncCompatibility(const detail::AttrPtr& attr) return true; } -TypePtr TableType::ShallowClone() - { - return make_intrusive(indices, yield_type); - } - -bool TableType::IsUnspecifiedTable() const - { - // Unspecified types have an empty list of indices. - return indices->GetTypes().empty(); - } - SetType::SetType(TypeListPtr ind, detail::ListExprPtr arg_elements) : TableType(std::move(ind), nullptr), elements(std::move(arg_elements)) { @@ -716,6 +728,9 @@ bool FuncType::CheckArgs(const TypePList* args, bool is_init, bool do_warn) cons bool FuncType::CheckArgs(const std::vector& args, bool is_init, bool do_warn) const { + if ( reported_error ) + return false; + const auto& my_args = arg_types->GetTypes(); if ( my_args.size() != args.size() ) @@ -723,6 +738,7 @@ bool FuncType::CheckArgs(const std::vector& args, bool is_init, bool do if ( do_warn ) Warn(util::fmt("Wrong number of arguments for function. Expected %zu, got %zu.", args.size(), my_args.size())); + const_cast(this)->reported_error = true; return false; } @@ -737,6 +753,8 @@ bool FuncType::CheckArgs(const std::vector& args, bool is_init, bool do success = false; } + const_cast(this)->reported_error = ! success; + return success; } @@ -2631,7 +2649,18 @@ static SetTypePtr init_set_type(detail::ListExpr* l) TypePtr init_type(const detail::ExprPtr& init) { if ( init->Tag() != detail::EXPR_LIST ) - return init->InitType(); + { + auto t = init->InitType(); + + if ( (t->Tag() == TYPE_TABLE && cast_intrusive(t)->IsUnspecifiedTable()) || + (t->Tag() == TYPE_VECTOR && cast_intrusive(t)->IsUnspecifiedVector()) ) + { + init->Error("empty constructor in untyped initialization"); + return nullptr; + } + + return t; + } auto init_list = init->AsListExpr(); const auto& el = init_list->Exprs(); diff --git a/src/Type.h b/src/Type.h index b77e558e4c..dd4dd80b91 100644 --- a/src/Type.h +++ b/src/Type.h @@ -406,6 +406,12 @@ public: // Returns true if this table type is "unspecified", which is // what one gets using an empty "set()" or "table()" constructor. bool IsUnspecifiedTable() const; + +private: + bool DoExpireCheck(const detail::AttrPtr& attr); + + // Used to prevent repeated error messages. + bool reported_error = false; }; class SetType final : public TableType @@ -538,6 +544,9 @@ protected: std::optional captures; // if nil then no captures specified // Used for internal lambdas built for "when" statements: bool expressionless_return_okay = false; + + // Used to prevent repeated error messages. + bool reported_error = false; }; class TypeType final : public Type From e786ba2fa93d182c69933de61b74f9238d75d4e7 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 31 Mar 2022 19:30:58 -0700 Subject: [PATCH 119/204] type-checking for use of empty table constructors in expressions --- src/Expr.cc | 49 ++++++++++++++++++++++++++++++++++--------------- src/Expr.h | 2 +- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index 572c615a1a..997c1509e9 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -2682,21 +2682,11 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) // Some elements in constructor list must not match, see if // we can create a new constructor now that the expected type // of LHS is known and let it do coercions where possible. - SetConstructorExpr* sce = dynamic_cast(op2.get()); - - if ( ! sce ) - { - ExprError("Failed typecast to SetConstructorExpr"); - return false; - } - + auto sce = cast_intrusive(op2); auto ctor_list = cast_intrusive(sce->GetOp1()); if ( ! ctor_list ) - { - ExprError("Failed typecast to ListExpr"); - return false; - } + Internal("failed typecast to ListExpr"); std::unique_ptr> attr_copy; @@ -4226,13 +4216,23 @@ RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, const std::vector& return val; } -TableCoerceExpr::TableCoerceExpr(ExprPtr arg_op, TableTypePtr r) +TableCoerceExpr::TableCoerceExpr(ExprPtr arg_op, TableTypePtr tt, bool type_check) : UnaryExpr(EXPR_TABLE_COERCE, std::move(arg_op)) { if ( IsError() ) return; - SetType(std::move(r)); + if ( type_check ) + { + op = check_and_promote_expr(op, tt); + if ( ! op ) + { + SetError(); + return; + } + } + + SetType(std::move(tt)); if ( GetType()->Tag() != TYPE_TABLE ) ExprError("coercion to non-table"); @@ -5260,7 +5260,26 @@ ExprPtr check_and_promote_expr(ExprPtr e, TypePtr t) { if ( t->Tag() == TYPE_TABLE && et->Tag() == TYPE_TABLE && et->AsTableType()->IsUnspecifiedTable() ) - return make_intrusive(e, IntrusivePtr{NewRef{}, t->AsTableType()}); + { + if ( e->Tag() == EXPR_TABLE_CONSTRUCTOR ) + { + auto& attrs = cast_intrusive(e)->GetAttrs(); + auto& def = attrs ? attrs->Find(ATTR_DEFAULT) : nullptr; + if ( def ) + { + std::string err_msg; + if ( ! check_default_attr(def.get(), t, false, false, err_msg) ) + { + if ( ! err_msg.empty() ) + t->Error(err_msg.c_str(), e.get()); + return nullptr; + } + } + } + + return make_intrusive(e, IntrusivePtr{NewRef{}, t->AsTableType()}, + false); + } if ( t->Tag() == TYPE_VECTOR && et->Tag() == TYPE_VECTOR && et->AsVectorType()->IsUnspecifiedVector() ) diff --git a/src/Expr.h b/src/Expr.h index 7b8c38ff6e..a8b90d42dc 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -1310,7 +1310,7 @@ extern RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, const std::vector class TableCoerceExpr final : public UnaryExpr { public: - TableCoerceExpr(ExprPtr op, TableTypePtr r); + TableCoerceExpr(ExprPtr op, TableTypePtr r, bool type_check = true); ~TableCoerceExpr() override; // Optimization-related: From 24be03f7c53923b8b926f9f37e83ccdbd06ee900 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 31 Mar 2022 19:31:21 -0700 Subject: [PATCH 120/204] fix for ill-formed (complex) &default function --- scripts/base/protocols/smb/consts.zeek | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base/protocols/smb/consts.zeek b/scripts/base/protocols/smb/consts.zeek index 9b68419baa..42ba43639e 100644 --- a/scripts/base/protocols/smb/consts.zeek +++ b/scripts/base/protocols/smb/consts.zeek @@ -112,7 +112,7 @@ export { const rpc_sub_cmds: table[string] of rpc_cmd_table = { ["4b324fc8-1670-01d3-1278-5a47bf6ee188"] = srv_cmds, ["6bffd098-a112-3610-9833-46c3f87e345a"] = wksta_cmds, - } &redef &default=function(i: string):rpc_cmd_table { return table() &default=function(j: string):string { return fmt("unknown-uuid-%s", j); }; }; + } &redef &default=function(i: string):rpc_cmd_table { return table() &default=function(j: count):string { return fmt("unknown-uuid-%d", j); }; }; } From 215e6ea098a10845f5dfb9e659516d95383b6edd Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 31 Mar 2022 19:31:58 -0700 Subject: [PATCH 121/204] updates for btests - new cases to check, new baselines --- .../language.expire-func-type-check/output | 14 --------- .../btest/Baseline/language.table-init/output | 3 ++ .../Baseline/language.table-type-checking/out | 29 ++++++++++--------- .../language.vector-unspecified/output | 2 +- testing/btest/Baseline/plugins.hooks/output | 6 ++-- testing/btest/language/table-init.zeek | 3 ++ .../btest/language/table-type-checking.zeek | 9 ++++++ .../btest/language/vector-unspecified.zeek | 6 ++-- 8 files changed, 39 insertions(+), 33 deletions(-) diff --git a/testing/btest/Baseline/language.expire-func-type-check/output b/testing/btest/Baseline/language.expire-func-type-check/output index 05eff0b0fe..091ce43451 100644 --- a/testing/btest/Baseline/language.expire-func-type-check/output +++ b/testing/btest/Baseline/language.expire-func-type-check/output @@ -1,23 +1,9 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. warning in <...>/expire-func-type-check.zeek, line 16: Wrong number of arguments for function. Expected 2, got 0. (function() : interval) error in <...>/expire-func-type-check.zeek, line 38: &expire_func argument type clash (&expire_func=invalid_expire_func_no_params) -warning in <...>/expire-func-type-check.zeek, line 16: Wrong number of arguments for function. Expected 2, got 0. (function() : interval) -error in <...>/expire-func-type-check.zeek, line 38: &expire_func argument type clash (&expire_func=invalid_expire_func_no_params) -warning in <...>/expire-func-type-check.zeek, line 16: Wrong number of arguments for function. Expected 2, got 0. (function() : interval) -error in <...>/expire-func-type-check.zeek, line 38: &expire_func argument type clash (&expire_func=invalid_expire_func_no_params) -error in <...>/expire-func-type-check.zeek, line 39: &expire_func must yield a value of type interval (&expire_func=invalid_expire_func_no_return) -error in <...>/expire-func-type-check.zeek, line 39: &expire_func must yield a value of type interval (&expire_func=invalid_expire_func_no_return) error in <...>/expire-func-type-check.zeek, line 39: &expire_func must yield a value of type interval (&expire_func=invalid_expire_func_no_return) warning in <...>/expire-func-type-check.zeek, line 22: Wrong number of arguments for function. Expected 3, got 2. (function(t:table[addr,port] of set[addr]; s:set[addr,port];) : interval) error in <...>/expire-func-type-check.zeek, line 40: &expire_func argument type clash (&expire_func=invalid_expire_func_index_params) -warning in <...>/expire-func-type-check.zeek, line 22: Wrong number of arguments for function. Expected 3, got 2. (function(t:table[addr,port] of set[addr]; s:set[addr,port];) : interval) -error in <...>/expire-func-type-check.zeek, line 40: &expire_func argument type clash (&expire_func=invalid_expire_func_index_params) -error in <...>/expire-func-type-check.zeek, line 41: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_an_event) -error in <...>/expire-func-type-check.zeek, line 41: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_an_event) error in <...>/expire-func-type-check.zeek, line 41: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_an_event) error in <...>/expire-func-type-check.zeek, line 42: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_hook) -error in <...>/expire-func-type-check.zeek, line 42: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_hook) -error in <...>/expire-func-type-check.zeek, line 42: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_hook) -error in <...>/expire-func-type-check.zeek, line 43: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_number) -error in <...>/expire-func-type-check.zeek, line 43: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_number) error in <...>/expire-func-type-check.zeek, line 43: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_number) diff --git a/testing/btest/Baseline/language.table-init/output b/testing/btest/Baseline/language.table-init/output index b9a388fa54..cdf3f6ae34 100644 --- a/testing/btest/Baseline/language.table-init/output +++ b/testing/btest/Baseline/language.table-init/output @@ -9,3 +9,6 @@ global table default [3] = three } local table default +{ + +} diff --git a/testing/btest/Baseline/language.table-type-checking/out b/testing/btest/Baseline/language.table-type-checking/out index 72bfcb7b5b..0e97e6c56e 100644 --- a/testing/btest/Baseline/language.table-type-checking/out +++ b/testing/btest/Baseline/language.table-type-checking/out @@ -1,14 +1,17 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in port and <...>/table-type-checking.zeek, line 7: type clash (port and zero) -error in <...>/table-type-checking.zeek, line 7: inconsistent types in table constructor (table(zero = 0)) -error in port and <...>/table-type-checking.zeek, line 10: type clash (port and one) -error in <...>/table-type-checking.zeek, line 10: inconsistent types in table constructor (table(one = 1)) -error in <...>/table-type-checking.zeek, line 17: type clash in assignment (gda = gda2) -error in <...>/table-type-checking.zeek, line 21: type clash in assignment (gea = table(three = 3)) -error in port and <...>/table-type-checking.zeek, line 26: type clash (port and thousand) -error in <...>/table-type-checking.zeek, line 26: inconsistent types in table constructor (table(thousand = 1000)) -error in port and <...>/table-type-checking.zeek, line 32: type clash (port and thousand-one) -error in <...>/table-type-checking.zeek, line 32: inconsistent types in table constructor (table(thousand-one = 1001)) -error in port and <...>/table-type-checking.zeek, line 39: type clash (port and thousand-two) -error in <...>/table-type-checking.zeek, line 39: inconsistent types in table constructor (table(thousand-two = 1002)) -error in <...>/table-type-checking.zeek, line 45: type clash in assignment (lea = table(thousand-three = 1003)) +error in <...>/table-type-checking.zeek, line 7: empty constructor in untyped initialization (table()) +error in port and <...>/table-type-checking.zeek, line 10: type clash (port and zero) +error in <...>/table-type-checking.zeek, line 10: inconsistent types in table constructor (table(zero = 0)) +error in port and <...>/table-type-checking.zeek, line 13: type clash (port and one) +error in <...>/table-type-checking.zeek, line 13: inconsistent types in table constructor (table(one = 1)) +error in <...>/table-type-checking.zeek, line 20: type clash in assignment (gda = gda2) +error in <...>/table-type-checking.zeek, line 24: type clash in assignment (gea = table(three = 3)) +error in port and <...>/table-type-checking.zeek, line 29: type clash (port and thousand) +error in <...>/table-type-checking.zeek, line 29: inconsistent types in table constructor (table(thousand = 1000)) +error in port and <...>/table-type-checking.zeek, line 35: type clash (port and thousand-one) +error in <...>/table-type-checking.zeek, line 35: inconsistent types in table constructor (table(thousand-one = 1001)) +error in port and <...>/table-type-checking.zeek, line 42: type clash (port and thousand-two) +error in <...>/table-type-checking.zeek, line 42: inconsistent types in table constructor (table(thousand-two = 1002)) +error in <...>/table-type-checking.zeek, line 48: type clash in assignment (lea = table(thousand-three = 1003)) +error in count and <...>/table-type-checking.zeek, line 54: arithmetic mixed with non-arithmetic (count and foo) +error in <...>/table-type-checking.zeek, line 4 and <...>/table-type-checking.zeek, line 54: &default value has inconsistent type (table[port] of count and table()) diff --git a/testing/btest/Baseline/language.vector-unspecified/output b/testing/btest/Baseline/language.vector-unspecified/output index afe628909c..30b7901529 100644 --- a/testing/btest/Baseline/language.vector-unspecified/output +++ b/testing/btest/Baseline/language.vector-unspecified/output @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[5, Hi, 127.0.0.1] +error in /Users/vern/warehouse/zeek/master/testing/btest/.tmp/language.vector-unspecified/vector-unspecified.zeek, line 7: empty constructor in untyped initialization (vector()) diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 6ce199cb81..576ba4fb24 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -668,7 +668,7 @@ 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<14393221830775341876>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<5561482868084494682>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugins, , ()) -> 0.000000 MetaHookPost CallFunction(Supervisor::__is_supervisor, , ()) -> @@ -2125,7 +2125,7 @@ 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<14393221830775341876>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<5561482868084494682>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugins, , ()) 0.000000 MetaHookPre CallFunction(Supervisor::__is_supervisor, , ()) @@ -3581,7 +3581,7 @@ 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)}) -0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::UNIQUE, lambda_<14393221830775341876>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::UNIQUE, lambda_<5561482868084494682>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average}) 0.000000 | HookCallFunction SumStats::register_observe_plugins() 0.000000 | HookCallFunction Supervisor::__is_supervisor() diff --git a/testing/btest/language/table-init.zeek b/testing/btest/language/table-init.zeek index 0a2514e0b9..7c0a51d861 100644 --- a/testing/btest/language/table-init.zeek +++ b/testing/btest/language/table-init.zeek @@ -17,4 +17,7 @@ event zeek_init() print global_table[0]; print local_table; print local_table[0]; + + # Catch regression where this used to crash. + print table() &default=record($crash=F); } diff --git a/testing/btest/language/table-type-checking.zeek b/testing/btest/language/table-type-checking.zeek index faefaf3a60..7df9c63082 100644 --- a/testing/btest/language/table-type-checking.zeek +++ b/testing/btest/language/table-type-checking.zeek @@ -3,6 +3,9 @@ type MyTable: table[port] of count; +# global, type deduction, empty ctor. +global gempty = table(); + # global, type deduction, named ctor global gdn = MyTable(["zero"] = 0); # type clash in init @@ -44,3 +47,9 @@ event zeek_init() { local lea: MyTable = table(["thousand-three"] = 1003); # type clash } + +# local, type explicit, empty ctor has incompatible &default +event zeek_init() + { + local lei: MyTable = table() &default="foo"; # type clash + } diff --git a/testing/btest/language/vector-unspecified.zeek b/testing/btest/language/vector-unspecified.zeek index d0898b5d42..66261546cc 100644 --- a/testing/btest/language/vector-unspecified.zeek +++ b/testing/btest/language/vector-unspecified.zeek @@ -1,7 +1,9 @@ -# @TEST-EXEC: zeek -b %INPUT >output 2>&1 +# @TEST-EXEC-FAIL: zeek -b %INPUT >output 2>&1 # @TEST-EXEC: btest-diff output -# Test assignment behavior of unspecified vectors +# Test assignment behavior of unspecified vectors. This used to treat +# "a" as a vector-of-any, but that seems dangerous - if the user really +# wants that behavior, they can explicitly type it as such. local a = vector(); a[0] = 5; From 77007eccf8b1244de26ac3894900ab7d9eaa5f37 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 31 Mar 2022 19:31:58 -0700 Subject: [PATCH 122/204] updates for btests - new cases to check, new baselines --- .../language.expire-func-type-check/output | 14 --------- .../btest/Baseline/language.table-init/output | 3 ++ .../Baseline/language.table-type-checking/out | 29 ++++++++++--------- .../language.vector-unspecified/output | 2 +- testing/btest/Baseline/plugins.hooks/output | 6 ++-- testing/btest/language/table-init.zeek | 3 ++ .../btest/language/table-type-checking.zeek | 9 ++++++ .../btest/language/vector-unspecified.zeek | 8 +++-- 8 files changed, 40 insertions(+), 34 deletions(-) diff --git a/testing/btest/Baseline/language.expire-func-type-check/output b/testing/btest/Baseline/language.expire-func-type-check/output index 05eff0b0fe..091ce43451 100644 --- a/testing/btest/Baseline/language.expire-func-type-check/output +++ b/testing/btest/Baseline/language.expire-func-type-check/output @@ -1,23 +1,9 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. warning in <...>/expire-func-type-check.zeek, line 16: Wrong number of arguments for function. Expected 2, got 0. (function() : interval) error in <...>/expire-func-type-check.zeek, line 38: &expire_func argument type clash (&expire_func=invalid_expire_func_no_params) -warning in <...>/expire-func-type-check.zeek, line 16: Wrong number of arguments for function. Expected 2, got 0. (function() : interval) -error in <...>/expire-func-type-check.zeek, line 38: &expire_func argument type clash (&expire_func=invalid_expire_func_no_params) -warning in <...>/expire-func-type-check.zeek, line 16: Wrong number of arguments for function. Expected 2, got 0. (function() : interval) -error in <...>/expire-func-type-check.zeek, line 38: &expire_func argument type clash (&expire_func=invalid_expire_func_no_params) -error in <...>/expire-func-type-check.zeek, line 39: &expire_func must yield a value of type interval (&expire_func=invalid_expire_func_no_return) -error in <...>/expire-func-type-check.zeek, line 39: &expire_func must yield a value of type interval (&expire_func=invalid_expire_func_no_return) error in <...>/expire-func-type-check.zeek, line 39: &expire_func must yield a value of type interval (&expire_func=invalid_expire_func_no_return) warning in <...>/expire-func-type-check.zeek, line 22: Wrong number of arguments for function. Expected 3, got 2. (function(t:table[addr,port] of set[addr]; s:set[addr,port];) : interval) error in <...>/expire-func-type-check.zeek, line 40: &expire_func argument type clash (&expire_func=invalid_expire_func_index_params) -warning in <...>/expire-func-type-check.zeek, line 22: Wrong number of arguments for function. Expected 3, got 2. (function(t:table[addr,port] of set[addr]; s:set[addr,port];) : interval) -error in <...>/expire-func-type-check.zeek, line 40: &expire_func argument type clash (&expire_func=invalid_expire_func_index_params) -error in <...>/expire-func-type-check.zeek, line 41: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_an_event) -error in <...>/expire-func-type-check.zeek, line 41: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_an_event) error in <...>/expire-func-type-check.zeek, line 41: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_an_event) error in <...>/expire-func-type-check.zeek, line 42: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_hook) -error in <...>/expire-func-type-check.zeek, line 42: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_hook) -error in <...>/expire-func-type-check.zeek, line 42: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_hook) -error in <...>/expire-func-type-check.zeek, line 43: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_number) -error in <...>/expire-func-type-check.zeek, line 43: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_number) error in <...>/expire-func-type-check.zeek, line 43: &expire_func attribute is not a function (&expire_func=invalid_expire_func_because_its_a_number) diff --git a/testing/btest/Baseline/language.table-init/output b/testing/btest/Baseline/language.table-init/output index b9a388fa54..cdf3f6ae34 100644 --- a/testing/btest/Baseline/language.table-init/output +++ b/testing/btest/Baseline/language.table-init/output @@ -9,3 +9,6 @@ global table default [3] = three } local table default +{ + +} diff --git a/testing/btest/Baseline/language.table-type-checking/out b/testing/btest/Baseline/language.table-type-checking/out index 72bfcb7b5b..0e97e6c56e 100644 --- a/testing/btest/Baseline/language.table-type-checking/out +++ b/testing/btest/Baseline/language.table-type-checking/out @@ -1,14 +1,17 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in port and <...>/table-type-checking.zeek, line 7: type clash (port and zero) -error in <...>/table-type-checking.zeek, line 7: inconsistent types in table constructor (table(zero = 0)) -error in port and <...>/table-type-checking.zeek, line 10: type clash (port and one) -error in <...>/table-type-checking.zeek, line 10: inconsistent types in table constructor (table(one = 1)) -error in <...>/table-type-checking.zeek, line 17: type clash in assignment (gda = gda2) -error in <...>/table-type-checking.zeek, line 21: type clash in assignment (gea = table(three = 3)) -error in port and <...>/table-type-checking.zeek, line 26: type clash (port and thousand) -error in <...>/table-type-checking.zeek, line 26: inconsistent types in table constructor (table(thousand = 1000)) -error in port and <...>/table-type-checking.zeek, line 32: type clash (port and thousand-one) -error in <...>/table-type-checking.zeek, line 32: inconsistent types in table constructor (table(thousand-one = 1001)) -error in port and <...>/table-type-checking.zeek, line 39: type clash (port and thousand-two) -error in <...>/table-type-checking.zeek, line 39: inconsistent types in table constructor (table(thousand-two = 1002)) -error in <...>/table-type-checking.zeek, line 45: type clash in assignment (lea = table(thousand-three = 1003)) +error in <...>/table-type-checking.zeek, line 7: empty constructor in untyped initialization (table()) +error in port and <...>/table-type-checking.zeek, line 10: type clash (port and zero) +error in <...>/table-type-checking.zeek, line 10: inconsistent types in table constructor (table(zero = 0)) +error in port and <...>/table-type-checking.zeek, line 13: type clash (port and one) +error in <...>/table-type-checking.zeek, line 13: inconsistent types in table constructor (table(one = 1)) +error in <...>/table-type-checking.zeek, line 20: type clash in assignment (gda = gda2) +error in <...>/table-type-checking.zeek, line 24: type clash in assignment (gea = table(three = 3)) +error in port and <...>/table-type-checking.zeek, line 29: type clash (port and thousand) +error in <...>/table-type-checking.zeek, line 29: inconsistent types in table constructor (table(thousand = 1000)) +error in port and <...>/table-type-checking.zeek, line 35: type clash (port and thousand-one) +error in <...>/table-type-checking.zeek, line 35: inconsistent types in table constructor (table(thousand-one = 1001)) +error in port and <...>/table-type-checking.zeek, line 42: type clash (port and thousand-two) +error in <...>/table-type-checking.zeek, line 42: inconsistent types in table constructor (table(thousand-two = 1002)) +error in <...>/table-type-checking.zeek, line 48: type clash in assignment (lea = table(thousand-three = 1003)) +error in count and <...>/table-type-checking.zeek, line 54: arithmetic mixed with non-arithmetic (count and foo) +error in <...>/table-type-checking.zeek, line 4 and <...>/table-type-checking.zeek, line 54: &default value has inconsistent type (table[port] of count and table()) diff --git a/testing/btest/Baseline/language.vector-unspecified/output b/testing/btest/Baseline/language.vector-unspecified/output index afe628909c..7d88d94649 100644 --- a/testing/btest/Baseline/language.vector-unspecified/output +++ b/testing/btest/Baseline/language.vector-unspecified/output @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[5, Hi, 127.0.0.1] +error in <...>/vector-unspecified.zeek, line 7: empty constructor in untyped initialization (vector()) diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 6ce199cb81..576ba4fb24 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -668,7 +668,7 @@ 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)})) -> -0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<14393221830775341876>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) -> +0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<5561482868084494682>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugin, , (SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) -> 0.000000 MetaHookPost CallFunction(SumStats::register_observe_plugins, , ()) -> 0.000000 MetaHookPost CallFunction(Supervisor::__is_supervisor, , ()) -> @@ -2125,7 +2125,7 @@ 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)})) -0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<14393221830775341876>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) +0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::UNIQUE, lambda_<5561482868084494682>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugin, , (SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average})) 0.000000 MetaHookPre CallFunction(SumStats::register_observe_plugins, , ()) 0.000000 MetaHookPre CallFunction(Supervisor::__is_supervisor, , ()) @@ -3581,7 +3581,7 @@ 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::STD_DEV, lambda_<5704045257244168718>{ SumStats::calc_std_dev(SumStats::rv)}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::SUM, lambda_<6958532551242393774>{ SumStats::rv$sum += SumStats::val}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::TOPK, lambda_<6366101205573988923>{ topk_add(SumStats::rv$topk, to_any_coerceSumStats::obs)}) -0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::UNIQUE, lambda_<14393221830775341876>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce set() to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals}) +0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::UNIQUE, lambda_<5561482868084494682>{ if (!SumStats::rv?$unique_vals) SumStats::rv$unique_vals = (coerce (coerce set() to set[SumStats::Observation]) to set[SumStats::Observation])if (SumStats::r?$unique_max) SumStats::rv$unique_max = SumStats::r$unique_maxif (!SumStats::r?$unique_max || sizeofSumStats::rv$unique_vals <= SumStats::r$unique_max) add SumStats::rv$unique_vals[SumStats::obs]SumStats::rv$unique = sizeofSumStats::rv$unique_vals}) 0.000000 | HookCallFunction SumStats::register_observe_plugin(SumStats::VARIANCE, lambda_<6557258612059469785>{ if (1 < SumStats::rv$num) SumStats::rv$var_s += ((SumStats::val - SumStats::rv$prev_avg) * (SumStats::val - SumStats::rv$average))SumStats::calc_variance(SumStats::rv)SumStats::rv$prev_avg = SumStats::rv$average}) 0.000000 | HookCallFunction SumStats::register_observe_plugins() 0.000000 | HookCallFunction Supervisor::__is_supervisor() diff --git a/testing/btest/language/table-init.zeek b/testing/btest/language/table-init.zeek index 0a2514e0b9..7c0a51d861 100644 --- a/testing/btest/language/table-init.zeek +++ b/testing/btest/language/table-init.zeek @@ -17,4 +17,7 @@ event zeek_init() print global_table[0]; print local_table; print local_table[0]; + + # Catch regression where this used to crash. + print table() &default=record($crash=F); } diff --git a/testing/btest/language/table-type-checking.zeek b/testing/btest/language/table-type-checking.zeek index faefaf3a60..7df9c63082 100644 --- a/testing/btest/language/table-type-checking.zeek +++ b/testing/btest/language/table-type-checking.zeek @@ -3,6 +3,9 @@ type MyTable: table[port] of count; +# global, type deduction, empty ctor. +global gempty = table(); + # global, type deduction, named ctor global gdn = MyTable(["zero"] = 0); # type clash in init @@ -44,3 +47,9 @@ event zeek_init() { local lea: MyTable = table(["thousand-three"] = 1003); # type clash } + +# local, type explicit, empty ctor has incompatible &default +event zeek_init() + { + local lei: MyTable = table() &default="foo"; # type clash + } diff --git a/testing/btest/language/vector-unspecified.zeek b/testing/btest/language/vector-unspecified.zeek index d0898b5d42..e28278ca48 100644 --- a/testing/btest/language/vector-unspecified.zeek +++ b/testing/btest/language/vector-unspecified.zeek @@ -1,7 +1,9 @@ -# @TEST-EXEC: zeek -b %INPUT >output 2>&1 -# @TEST-EXEC: btest-diff output +# @TEST-EXEC-FAIL: zeek -b %INPUT >output 2>&1 +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output -# Test assignment behavior of unspecified vectors +# Test assignment behavior of unspecified vectors. This used to treat +# "a" as a vector-of-any, but that seems dangerous - if the user really +# wants that behavior, they can explicitly type it as such. local a = vector(); a[0] = 5; From 84dc430e009ab6d2e84daa3bb2d42c088b7df91f Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 1 Apr 2022 14:04:50 -0700 Subject: [PATCH 123/204] fix & btest for ZAM bug with inlined nested loop --- src/script_opt/ZAM/Driver.cc | 2 +- .../Baseline/language.inlined-nested-loop/out | 2 ++ .../btest/language/inlined-nested-loop.zeek | 24 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/language.inlined-nested-loop/out create mode 100644 testing/btest/language/inlined-nested-loop.zeek diff --git a/src/script_opt/ZAM/Driver.cc b/src/script_opt/ZAM/Driver.cc index 4d6fc91f76..b44e094af2 100644 --- a/src/script_opt/ZAM/Driver.cc +++ b/src/script_opt/ZAM/Driver.cc @@ -261,7 +261,7 @@ void ZAMCompiler::ComputeLoopLevels() // We're extending an existing loop. Find // its current end. auto depth = t->loop_depth; - while ( j < i && insts1[j]->loop_depth == depth ) + while ( j < i && insts1[j]->loop_depth >= depth ) ++j; ASSERT(insts1[j]->loop_depth == depth - 1); diff --git a/testing/btest/Baseline/language.inlined-nested-loop/out b/testing/btest/Baseline/language.inlined-nested-loop/out new file mode 100644 index 0000000000..a14b6e7b57 --- /dev/null +++ b/testing/btest/Baseline/language.inlined-nested-loop/out @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +I compiled and ran! diff --git a/testing/btest/language/inlined-nested-loop.zeek b/testing/btest/language/inlined-nested-loop.zeek new file mode 100644 index 0000000000..2e116afe21 --- /dev/null +++ b/testing/btest/language/inlined-nested-loop.zeek @@ -0,0 +1,24 @@ +# @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff out + +# This used to lead to an assertion failure in the ZAM compiler due to +# a bug in how it computed the lifetime of loops nested via inlining. + +function is_local(host: addr): bool + { + for ( local_net in set(10.0.0.0/8) ) + if ( host in local_net ) + return T; + return F; + } + +event zeek_init() + { + for ( host_addr in set(127.0.0.1) ) + { + if ( is_local(host_addr) ) + next; + } + + print "I compiled and ran!"; + } From 03194949c9cf53353b5a221036fc3c01a783871e Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 1 Apr 2022 18:00:11 -0700 Subject: [PATCH 124/204] reduce interpreter frames for compiled function bodies --- src/script_opt/ScriptOpt.cc | 2 ++ src/script_opt/ZAM/AM-Opt.cc | 47 ++++++++++++++++++------------------ src/script_opt/ZAM/ZBody.h | 4 +-- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/script_opt/ScriptOpt.cc b/src/script_opt/ScriptOpt.cc index 937671a600..347b0d3348 100644 --- a/src/script_opt/ScriptOpt.cc +++ b/src/script_opt/ScriptOpt.cc @@ -508,6 +508,8 @@ static void analyze_scripts_for_ZAM(std::unique_ptr& pfs) if ( ! did_one ) reporter->FatalError("no matching functions/files for -O ZAM"); + + finalize_functions(funcs); } void analyze_scripts() diff --git a/src/script_opt/ZAM/AM-Opt.cc b/src/script_opt/ZAM/AM-Opt.cc index f32ccf1fc4..3593da3dc5 100644 --- a/src/script_opt/ZAM/AM-Opt.cc +++ b/src/script_opt/ZAM/AM-Opt.cc @@ -18,7 +18,7 @@ namespace zeek::detail // can't do this when compiling individual functions since for event handlers // and hooks it needs to be computed across all of their bodies. // -// Note, this is now not really needed, because we no longer use any +// Note, this is now not actually needed, because we no longer use any // interpreter frame entries other than those for the function's arguments. // We keep the code in case that changes, for example when deciding to // compile functions that include "return when" conditions. @@ -26,40 +26,39 @@ std::unordered_map remapped_intrp_frame_sizes; void finalize_functions(const std::vector& funcs) { - // Given we've now compiled all of the function bodies, we - // can reset the interpreter frame sizes of each function - // to be the maximum needed to accommodate all of its - // remapped bodies. + // Given we've now compiled all of the function bodies, we can reset + // the interpreter frame sizes to what's actually used. This can be + // a huge win for massively inlined event handlers, which otherwise + // can have frames sized for 100s of variables, none of which (other + // than the arguments) need TLC such as via calls to Frame::Reset(). // Find any functions with bodies that weren't compiled and - // make sure we don't reduce their frame size. For any loaded - // from ZAM save files, use the associated maximum interpreter - // frame size as a minimum. + // make sure we don't reduce their frame size. + std::unordered_set leave_alone; + + for ( auto& f : funcs ) + if ( f.Body()->Tag() != STMT_ZAM ) + // This function has a body that wasn't compiled, + // don't mess with its size. + leave_alone.insert(f.Func()); + for ( auto& f : funcs ) { auto func = f.Func(); - // If we have non-compiled versions of the function's body, - // preserve the size they need. - int size = func->FrameSize(); - - if ( f.Body()->Tag() != STMT_ZAM && remapped_intrp_frame_sizes.count(func) > 0 && - size > remapped_intrp_frame_sizes[func] ) - remapped_intrp_frame_sizes[func] = size; - } - - for ( auto& f : funcs ) - { - auto func = f.Func(); + if ( leave_alone.count(func) > 0 ) + continue; if ( remapped_intrp_frame_sizes.count(func) == 0 ) // No entry for this function, keep current frame size. continue; - // Note, functions with multiple bodies appear in "funcs" - // multiple times, but the following doesn't hurt to do - // more than once. - func->SetFrameSize(remapped_intrp_frame_sizes[func]); + auto& ft = func->GetType(); + auto& params = ft->Params(); + func->SetFrameSize(params->NumFields()); + + // Don't bother processing any future instances. + leave_alone.insert(func); } } diff --git a/src/script_opt/ZAM/ZBody.h b/src/script_opt/ZAM/ZBody.h index 3e39bc8b03..11699a848b 100644 --- a/src/script_opt/ZAM/ZBody.h +++ b/src/script_opt/ZAM/ZBody.h @@ -34,8 +34,8 @@ public: ~ZBody() override; // These are split out from the constructor to allow construction - // of a ZBody from either save-file full instructions (first method) - // or intermediary instructions (second method). + // of a ZBody from either save-file full instructions (first method, + // not currently supported) or intermediary instructions (second method). void SetInsts(std::vector& insts); void SetInsts(std::vector& instsI); From ffb9ba1f2668d5cadb4dd7ee44bb080f1bf91ba1 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 29 Mar 2022 14:26:17 -0700 Subject: [PATCH 125/204] GH-2009: Use auto to fix ZIP analyzer failure on some platforms --- src/analyzer/protocol/zip/ZIP.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analyzer/protocol/zip/ZIP.cc b/src/analyzer/protocol/zip/ZIP.cc index 5226fbd4fb..4a30f52312 100644 --- a/src/analyzer/protocol/zip/ZIP.cc +++ b/src/analyzer/protocol/zip/ZIP.cc @@ -59,7 +59,7 @@ void ZIP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) zip->next_in = (Bytef*)data; zip->avail_in = len; - Bytef* orig_next_in = zip->next_in; + auto orig_next_in = zip->next_in; size_t orig_avail_in = zip->avail_in; while ( true ) From 669cfbe1095b27b4b6be3f97b5106e3cbcd359e1 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 4 Apr 2022 14:06:28 -0700 Subject: [PATCH 126/204] Correct origin documentation of the version field in the HTTP log. --- scripts/base/protocols/http/main.zeek | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/base/protocols/http/main.zeek b/scripts/base/protocols/http/main.zeek index c12da898d5..f54216b0dd 100644 --- a/scripts/base/protocols/http/main.zeek +++ b/scripts/base/protocols/http/main.zeek @@ -43,9 +43,12 @@ export { uri: string &log &optional; ## Value of the "referer" header. The comment is deliberately ## misspelled like the standard declares, but the name used here - ## is "referrer" spelled correctly. + ## is "referrer", spelled correctly. referrer: string &log &optional; - ## Value of the version portion of the request. + ## Value of the version portion of the reply. If you require + ## message-level detail, consider the :zeek:see:`http_request` and + ## :zeek:see:`http_reply` events, which report each message's + ## version string. version: string &log &optional; ## Value of the User-Agent header from the client. user_agent: string &log &optional; From cc50129dc3cf03c47c6ee7626198d8eb68ccf681 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Wed, 6 Apr 2022 00:34:19 +0000 Subject: [PATCH 127/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 5dd13f5a65..ef017ac495 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 5dd13f5a65c092e640f838f3956851d53ead9b3f +Subproject commit ef017ac495d24aac249228847da51c5a7ed58703 From 21b3bcea2b4f127ef811e327e4dd8e9474cd8e0a Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 7 Apr 2022 13:30:19 -0700 Subject: [PATCH 128/204] Bump submodules to pull in InstallSymlink fix [nomail] --- auxil/zeek-aux | 2 +- auxil/zeekctl | 2 +- cmake | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/auxil/zeek-aux b/auxil/zeek-aux index 6e9235cf39..9037820cd1 160000 --- a/auxil/zeek-aux +++ b/auxil/zeek-aux @@ -1 +1 @@ -Subproject commit 6e9235cf39a038fa96d4ae1acf8f446a7e75cc24 +Subproject commit 9037820cd19ce0c1113748b961064c6f3fce04ea diff --git a/auxil/zeekctl b/auxil/zeekctl index e7fd4d552e..271cd0c9a6 160000 --- a/auxil/zeekctl +++ b/auxil/zeekctl @@ -1 +1 @@ -Subproject commit e7fd4d552ec7c3e55cb556943bf8b499d2db17e1 +Subproject commit 271cd0c9a6899b154657f05f027010269e3d3f73 diff --git a/cmake b/cmake index 34cc0fac42..c067f8b6c6 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 34cc0fac4251ed72c68cf80e98e6e5084c1175a9 +Subproject commit c067f8b6c6dbfd84b99ae3394516af238ad7fe1d From 3b50d810de39506919cffb6e96043085e7119cc1 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 8 Apr 2022 20:50:44 +0000 Subject: [PATCH 129/204] Update libkqueue to 2.6.0 release [skip ci] [nomail] --- auxil/libkqueue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/libkqueue b/auxil/libkqueue index aeaeed2119..67d5a67f7f 160000 --- a/auxil/libkqueue +++ b/auxil/libkqueue @@ -1 +1 @@ -Subproject commit aeaeed21198d6f41d0cf70bda63fe0f424922ac5 +Subproject commit 67d5a67f7fc3e3e56f129ec72988a9ced3a6cc81 From 9a11df808bd67b8bbe4bac91be9adbfbd7be62c7 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 8 Apr 2022 15:21:41 -0700 Subject: [PATCH 130/204] Mask our signal handlers' triggering signals around thread creation This avoids tsan complaints around race conditions in signal handlers running from threads other than the main one. --- src/zeek-setup.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 561270c3c6..66a23b5aa7 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -398,6 +398,22 @@ static std::vector get_script_signature_files() return rval; } +// Helper for masking/unmasking the set of signals that apply to our signal +// handlers: sig_handler() in this file, as well as stem_signal_handler() and +// supervisor_signal_handler() in the Supervisor. +static void set_signal_mask(bool do_block) + { + sigset_t mask_set; + + sigemptyset(&mask_set); + sigaddset(&mask_set, SIGCHLD); + sigaddset(&mask_set, SIGTERM); + sigaddset(&mask_set, SIGINT); + + int res = pthread_sigmask(do_block ? SIG_BLOCK : SIG_UNBLOCK, &mask_set, 0); + assert(res == 0); + } + SetupResult setup(int argc, char** argv, Options* zopts) { ZEEK_LSAN_DISABLE(); @@ -500,6 +516,12 @@ SetupResult setup(int argc, char** argv, Options* zopts) } #endif + // Mask signals relevant for our signal handlers here. We unmask them + // again further down, when all components that launch threads have done + // so. The launched threads inherit the active signal mask and thus + // prevent our signal handlers from running in unintended threads. + set_signal_mask(true); + if ( options.supervisor_mode ) { Supervisor::Config cfg = {}; @@ -737,6 +759,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) #ifdef USE_PERFTOOLS_DEBUG } #endif + set_signal_mask(false); if ( reporter->Errors() > 0 ) { From 2aec7640dd60c3ea3cffd82461588567e406db34 Mon Sep 17 00:00:00 2001 From: Anthony Coddington Date: Mon, 11 Apr 2022 23:09:57 +1200 Subject: [PATCH 131/204] GH-2038: Don't sleep when non-selectable PktSrc has data available PktSrc::GetNextTimeout always returned a fixed timeout of 20 microseconds for non-selectable packet sources regardless of whether they have packets available. This adds unnecessary delay every FindReadySources poll_interval when packets are available to be read. Instead, for non-selectable packet sources, check whether packets are available and return a timeout of 0 to indicate data is available. This is closer to the behaviour of the old capture loop. This was mitigated somewhat by the fact FindReadySources poll interval defaults to 100 packets, and live sources are added to the ready list regardless of whether they have packets available (unless it is time to force a poll). --- src/iosource/PktSrc.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index 8ac60485b7..a265bd6f74 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -273,25 +273,33 @@ bool PktSrc::GetCurrentPacket(const Packet** pkt) double PktSrc::GetNextTimeout() { + bool pkt_available = have_packet; + + if ( props.selectable_fd == -1 || run_state::pseudo_realtime ) + pkt_available = ExtractNextPacketInternal(); + + if ( run_state::is_processing_suspended() ) + return -1; + // If there's no file descriptor for the source, which is the case for some interfaces like // myricom, we can't rely on the polling mechanism to wait for data to be available. As gross // as it is, just spin with a short timeout here so that it will continually poll the // interface. The old IOSource code had a 20 microsecond timeout between calls to select() // so just use that. if ( props.selectable_fd == -1 ) - return 0.00002; - + { + if ( ! pkt_available && ! run_state::pseudo_realtime ) + return 0.00002; + } // If we're live we want poll to do what it has to with the file descriptor. If we're not live // but we're not in pseudo-realtime mode, let the loop just spin as fast as it can. If we're // in pseudo-realtime mode, find the next time that a packet is ready and have poll block until // then. - if ( IsLive() || run_state::is_processing_suspended() ) + else if ( IsLive() ) return -1; - else if ( ! run_state::pseudo_realtime ) - return 0; - if ( ! have_packet ) - ExtractNextPacketInternal(); + if ( ! run_state::pseudo_realtime ) + return 0; // This duplicates the calculation used in run_state::check_pseudo_time(). double pseudo_time = current_packet.time - run_state::detail::first_timestamp; From 8e225efd5782a75d81407b926d2297ee816986fc Mon Sep 17 00:00:00 2001 From: Yacin Nadji Date: Mon, 11 Apr 2022 13:07:58 -0400 Subject: [PATCH 132/204] Add test to ensure enum_to_int's return values are ordered --- testing/btest/Baseline/bifs.enum_to_int/out | 12 ++++++++++++ testing/btest/bifs/enum_to_int.zeek | 16 ++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/testing/btest/Baseline/bifs.enum_to_int/out b/testing/btest/Baseline/bifs.enum_to_int/out index 203ded3505..2fcc6a9e5d 100644 --- a/testing/btest/Baseline/bifs.enum_to_int/out +++ b/testing/btest/Baseline/bifs.enum_to_int/out @@ -5,3 +5,15 @@ C, 2 AV, 10 BV, 11 CV, 12 +T +T +T +T +T +T +T +T +T +T +T +T diff --git a/testing/btest/bifs/enum_to_int.zeek b/testing/btest/bifs/enum_to_int.zeek index 17fd1ff8a9..ccfea91b54 100644 --- a/testing/btest/bifs/enum_to_int.zeek +++ b/testing/btest/bifs/enum_to_int.zeek @@ -18,12 +18,24 @@ export { event zeek_init() { - - print A, enum_to_int(A); print B, enum_to_int(B); print C, enum_to_int(C); print AV, enum_to_int(AV); print BV, enum_to_int(BV); print CV, enum_to_int(CV); + + print enum_to_int(A) != enum_to_int(B); + print enum_to_int(A) != enum_to_int(C); + print enum_to_int(B) != enum_to_int(C); + print enum_to_int(A) < enum_to_int(B); + print enum_to_int(A) < enum_to_int(C); + print enum_to_int(B) < enum_to_int(C); + + print enum_to_int(AV) != enum_to_int(BV); + print enum_to_int(AV) != enum_to_int(CV); + print enum_to_int(BV) != enum_to_int(CV); + print enum_to_int(AV) < enum_to_int(BV); + print enum_to_int(AV) < enum_to_int(CV); + print enum_to_int(BV) < enum_to_int(CV); } From 1440080791d3640a0068014112b807346d8c3ed7 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 11 Apr 2022 12:36:23 -0700 Subject: [PATCH 133/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index ef017ac495..bea29e3807 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit ef017ac495d24aac249228847da51c5a7ed58703 +Subproject commit bea29e38078c6f17462f081c5f13ccf8e25ddc0b From 007bc0c083cd924a3a6ea551829cf29e897e4085 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 8 Apr 2022 17:16:24 -0700 Subject: [PATCH 134/204] GH-2026: Ensure both protocol and analyzer confirmation and violation events can be called --- src/analyzer/Analyzer.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index 703d378d7d..90a78fc218 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -685,20 +685,19 @@ void Analyzer::ProtocolConfirmation(zeek::Tag arg_tag) protocol_confirmed = true; - if ( ! protocol_confirmation ) - return; - const auto& tval = arg_tag ? arg_tag.AsVal() : tag.AsVal(); // Enqueue both of these events. In the base scripts, only the analyzer version is handled. // The protocol remains just for handling scripts that haven't been updated. Once that event // is removed, this method is also removed. - event_mgr.Enqueue(analyzer_confirmation, ConnVal(), tval, val_mgr->Count(id)); - event_mgr.Enqueue(protocol_confirmation, ConnVal(), tval, val_mgr->Count(id)); + if ( analyzer_confirmation ) + event_mgr.Enqueue(analyzer_confirmation, ConnVal(), tval, val_mgr->Count(id)); + if ( protocol_confirmation ) + event_mgr.Enqueue(protocol_confirmation, ConnVal(), tval, val_mgr->Count(id)); } void Analyzer::ProtocolViolation(const char* reason, const char* data, int len) { - if ( ! protocol_violation ) + if ( ! protocol_violation && ! analyzer_violation ) return; StringValPtr r; @@ -717,8 +716,10 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len) // Enqueue both of these events. In the base scripts, only the analyzer version is handled. // The protocol remains just for handling scripts that haven't been updated. Once that event // is removed, this method is also removed. - event_mgr.Enqueue(analyzer_violation, ConnVal(), tval, val_mgr->Count(id), std::move(r)); - event_mgr.Enqueue(protocol_violation, ConnVal(), tval, val_mgr->Count(id), std::move(r)); + if ( analyzer_confirmation ) + event_mgr.Enqueue(analyzer_violation, ConnVal(), tval, val_mgr->Count(id), std::move(r)); + if ( protocol_confirmation ) + event_mgr.Enqueue(protocol_violation, ConnVal(), tval, val_mgr->Count(id), std::move(r)); } void Analyzer::AnalyzerConfirmation(zeek::Tag arg_tag) From d2e8c5e88708b36601846fa95ec8f61e20b10615 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 12 Apr 2022 09:34:05 +0200 Subject: [PATCH 135/204] Allow analyzer violations to explicitly set tag. We could already pass an overriding tag to `Analyzer::AnalyzerConfirmation()`, but we didn't have that ability for `AnalyzerViolation`, leading to the two potentially mismatching in the analyzer they report. --- src/analyzer/Analyzer.cc | 4 ++-- src/analyzer/Analyzer.h | 6 +++++- src/analyzer/protocol/tcp/TCP.cc | 5 +++-- src/analyzer/protocol/tcp/TCP.h | 3 ++- src/packet_analysis/Analyzer.cc | 4 ++-- src/packet_analysis/Analyzer.h | 3 ++- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index 90a78fc218..19b854a957 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -736,7 +736,7 @@ void Analyzer::AnalyzerConfirmation(zeek::Tag arg_tag) event_mgr.Enqueue(analyzer_confirmation, ConnVal(), tval, val_mgr->Count(id)); } -void Analyzer::AnalyzerViolation(const char* reason, const char* data, int len) +void Analyzer::AnalyzerViolation(const char* reason, const char* data, int len, zeek::Tag arg_tag) { if ( ! analyzer_violation ) return; @@ -753,7 +753,7 @@ void Analyzer::AnalyzerViolation(const char* reason, const char* data, int len) else r = make_intrusive(reason); - const auto& tval = tag.AsVal(); + const auto& tval = arg_tag ? arg_tag.AsVal() : tag.AsVal(); event_mgr.Enqueue(analyzer_violation, ConnVal(), tval, val_mgr->Count(id), std::move(r)); } diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 4659f7af2b..12fa44848f 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -590,8 +590,12 @@ public: * @param data An optional pointer to the malformed data. * * @param len If \a data is given, the length of it. + * + * @param tag If tag is given, it overrides the analyzer tag passed to the + * scripting layer; the default is the one of the analyzer itself. */ - virtual void AnalyzerViolation(const char* reason, const char* data = nullptr, int len = 0); + virtual void AnalyzerViolation(const char* reason, const char* data = nullptr, int len = 0, + zeek::Tag tag = zeek::Tag()); /** * Returns true if ProtocolConfirmation() has been called at least diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index 358ddbf003..49f416fa69 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -34,7 +34,8 @@ void TCP_ApplicationAnalyzer::Init() SetTCP(static_cast(Parent())); } -void TCP_ApplicationAnalyzer::AnalyzerViolation(const char* reason, const char* data, int len) +void TCP_ApplicationAnalyzer::AnalyzerViolation(const char* reason, const char* data, int len, + zeek::Tag tag) { if ( auto* tcp = TCP() ) { @@ -44,7 +45,7 @@ void TCP_ApplicationAnalyzer::AnalyzerViolation(const char* reason, const char* return; } - Analyzer::AnalyzerViolation(reason, data, len); + Analyzer::AnalyzerViolation(reason, data, len, tag); } void TCP_ApplicationAnalyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64_t seq, diff --git a/src/analyzer/protocol/tcp/TCP.h b/src/analyzer/protocol/tcp/TCP.h index b979001aae..3b145cb789 100644 --- a/src/analyzer/protocol/tcp/TCP.h +++ b/src/analyzer/protocol/tcp/TCP.h @@ -68,7 +68,8 @@ public: // This suppresses violations if the TCP connection wasn't // fully established. - void AnalyzerViolation(const char* reason, const char* data = nullptr, int len = 0) override; + void AnalyzerViolation(const char* reason, const char* data = nullptr, int len = 0, + zeek::Tag tag = zeek::Tag()) override; // "name" and "val" both now belong to this object, which needs to // delete them when done with them. diff --git a/src/packet_analysis/Analyzer.cc b/src/packet_analysis/Analyzer.cc index f55e948fed..aa5c500b3d 100644 --- a/src/packet_analysis/Analyzer.cc +++ b/src/packet_analysis/Analyzer.cc @@ -182,7 +182,7 @@ void Analyzer::AnalyzerConfirmation(session::Session* session, zeek::Tag arg_tag } void Analyzer::AnalyzerViolation(const char* reason, session::Session* session, const char* data, - int len) + int len, zeek::Tag arg_tag) { if ( ! analyzer_violation ) return; @@ -201,7 +201,7 @@ void Analyzer::AnalyzerViolation(const char* reason, session::Session* session, else r = make_intrusive(reason); - const auto& tval = tag.AsVal(); + const auto& tval = arg_tag ? arg_tag.AsVal() : tag.AsVal(); event_mgr.Enqueue(analyzer_violation, session->GetVal(), tval, val_mgr->Count(0), std::move(r)); } diff --git a/src/packet_analysis/Analyzer.h b/src/packet_analysis/Analyzer.h index baa10156a9..63a1a14953 100644 --- a/src/packet_analysis/Analyzer.h +++ b/src/packet_analysis/Analyzer.h @@ -156,7 +156,8 @@ public: * @param len If \a data is given, the length of it. */ virtual void AnalyzerViolation(const char* reason, session::Session* session, - const char* data = nullptr, int len = 0); + const char* data = nullptr, int len = 0, + zeek::Tag tag = zeek::Tag()); /** * Returns true if ProtocolConfirmation() has been called at least From 3f069868967b52b2564aa7229a501d1cbb4a00a6 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 12 Apr 2022 15:29:33 -0700 Subject: [PATCH 136/204] Add unit test for other get_word() version --- src/util.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/util.cc b/src/util.cc index ce8026ca2e..17fc590886 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1223,6 +1223,20 @@ char* get_word(char*& s) return w; } +TEST_CASE("util get_word 2") + { + char orig[10]; + strcpy(orig, "two words"); + + char* a = (char*)orig; + const char* b; + int blen; + + get_word(9, a, blen, b); + CHECK(blen == 3); + CHECK(a == b); + } + void get_word(int length, const char* s, int& pwlen, const char*& pw) { pw = s; From fccb9ccab035a9add7b7dee9d26398a761c1b2e0 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 14 Apr 2022 09:54:45 +0200 Subject: [PATCH 137/204] Re-instantiate providing location information to `LoadFile` hooks. #1835 subtly changed the semantics of the `LoadFile` plugin hook to no longer have the current script location available for signature files being loaded through `@load-sigs`. This was undocumented behavior, so it's technically not a regression, but since at least one external plugin is depending on it, this change restores the old behavior. --- src/Obj.h | 1 + src/RuleMatcher.cc | 10 +++++++ src/ScannedFile.cc | 5 ++-- src/ScannedFile.h | 4 ++- src/scan.l | 7 ++++- .../plugins.plugin-load-file-extended/output | 8 +++--- .../plugins/plugin-load-file-extended.zeek | 16 +++++++++++- .../plugin-load-file-extended/src/Plugin.cc | 26 ++++++++++++++++--- 8 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/Obj.h b/src/Obj.h index 0926e23512..a62ca4886a 100644 --- a/src/Obj.h +++ b/src/Obj.h @@ -38,6 +38,7 @@ public: #define YYLTYPE zeek::detail::yyltype using yyltype = Location; YYLTYPE GetCurrentLocation(); +void SetCurrentLocation(YYLTYPE currloc); // Used to mean "no location associated with this object". inline constexpr Location no_location("", 0, 0, 0, 0); diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index 42c3c568b0..a418c30cc6 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -266,6 +266,13 @@ bool RuleMatcher::ReadFiles(const std::vector& files) if ( ! f.full_path ) f.full_path = util::find_file(f.file, util::zeek_path(), ".sig"); + // We mimic previous Zeek versions by temporarily setting the current + // script location to the place where the loading happened. This + // behavior was never documented, but seems worth not breaking as some + // plugins ended up relying on it. + Location orig_location = detail::GetCurrentLocation(); + detail::SetCurrentLocation(f.load_location); + std::pair> rc = {-1, std::nullopt}; rc.first = PLUGIN_HOOK_WITH_RESULT( HOOK_LOAD_FILE, HookLoadFile(zeek::plugin::Plugin::SIGNATURES, f.file, *f.full_path), @@ -277,6 +284,9 @@ bool RuleMatcher::ReadFiles(const std::vector& files) HookLoadFileExtended(zeek::plugin::Plugin::SIGNATURES, f.file, *f.full_path), std::make_pair(-1, std::nullopt)); + // Restore original location information. + detail::SetCurrentLocation(orig_location); + switch ( rc.first ) { case -1: diff --git a/src/ScannedFile.cc b/src/ScannedFile.cc index 590511050e..0e25b47a27 100644 --- a/src/ScannedFile.cc +++ b/src/ScannedFile.cc @@ -49,8 +49,9 @@ bool ScannedFile::AlreadyScanned() const SignatureFile::SignatureFile(std::string file) : file(std::move(file)) { } -SignatureFile::SignatureFile(std::string file, std::string full_path) - : file(std::move(file)), full_path(std::move(full_path)) +SignatureFile::SignatureFile(std::string file, std::string full_path, Location load_location) + : file(std::move(file)), full_path(std::move(full_path)), + load_location(std::move(load_location)) { } diff --git a/src/ScannedFile.h b/src/ScannedFile.h index 9829b2c1d2..b51369ef8f 100644 --- a/src/ScannedFile.h +++ b/src/ScannedFile.h @@ -2,6 +2,7 @@ #pragma once +#include #include #include #include @@ -40,9 +41,10 @@ struct SignatureFile { std::string file; std::optional full_path; + Location load_location; SignatureFile(std::string file); - SignatureFile(std::string file, std::string full_path); + SignatureFile(std::string file, std::string full_path, Location load_location); }; extern std::vector sig_files; diff --git a/src/scan.l b/src/scan.l index a53c247798..52d2896692 100644 --- a/src/scan.l +++ b/src/scan.l @@ -374,7 +374,7 @@ when return TOK_WHEN; @load-sigs{WS}{FILE} { const char* file = zeek::util::skip_whitespace(yytext + 10); std::string path = find_relative_file(file, ".sig"); - sig_files.emplace_back(file, path); + sig_files.emplace_back(file, path, GetCurrentLocation()); } @load-plugin{WS}{ID} { @@ -586,6 +586,11 @@ YYLTYPE zeek::detail::GetCurrentLocation() return currloc; } +void zeek::detail::SetCurrentLocation(YYLTYPE currloc) { + ::filename = currloc.filename; + line_number = currloc.first_line; +} + static int load_files(const char* orig_file) { std::string file_path = find_relative_script_file(orig_file); diff --git a/testing/btest/Baseline/plugins.plugin-load-file-extended/output b/testing/btest/Baseline/plugins.plugin-load-file-extended/output index d32f2141d1..3d5b86d6dd 100644 --- a/testing/btest/Baseline/plugins.plugin-load-file-extended/output +++ b/testing/btest/Baseline/plugins.plugin-load-file-extended/output @@ -1,7 +1,9 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -HookLoadExtended/script: file=|xxx| resolved=|./xxx.zeek| -HookLoadExtended/script: file=|yyy| resolved=|| -HookLoadExtended/signature: file=|abc.sig| resolved=|./abc.sig| +HookLoadExtended/script: file=|xxx| resolved=|./xxx.zeek| srcloc=|n/a| +HookLoadExtended/script: file=|xxx3| resolved=|./xxx3.zeek| srcloc=|./xxx2.zeek| +HookLoadExtended/script: file=|yyy| resolved=|| srcloc=|n/a| +HookLoadExtended/signature: file=|abc.sig| resolved=|./abc.sig| srcloc=|n/a| +HookLoadExtended/signature: file=|def.sig| resolved=|./def.sig| srcloc=|./xxx2.zeek| new zeek_init(): script has been replaced new zeek_init(): script has been added signature works! diff --git a/testing/btest/plugins/plugin-load-file-extended.zeek b/testing/btest/plugins/plugin-load-file-extended.zeek index 0d3d297c5a..2550363fd3 100644 --- a/testing/btest/plugins/plugin-load-file-extended.zeek +++ b/testing/btest/plugins/plugin-load-file-extended.zeek @@ -1,7 +1,7 @@ # @TEST-EXEC: ${DIST}/auxil/zeek-aux/plugin-support/init-plugin -u . Testing LoadFileExtended # @TEST-EXEC: cp -r %DIR/plugin-load-file-extended/* . # @TEST-EXEC: ./configure --zeek-dist=${DIST} && make -# @TEST-EXEC: ZEEK_PLUGIN_PATH=$(pwd) zeek -r $TRACES/wikipedia.trace -b Testing::LoadFileExtended xxx yyy -s abc.sig >> output +# @TEST-EXEC: ZEEK_PLUGIN_PATH=$(pwd) zeek -r $TRACES/wikipedia.trace -b Testing::LoadFileExtended xxx xxx2 yyy -s abc.sig >> output # @TEST-EXEC: btest-diff output # @TEST-START-FILE xxx.zeek @@ -12,6 +12,20 @@ event zeek_init() { # @TEST-END-FILE +# @TEST-START-FILE xxx2.zeek +# Test loading from script land. +@load xxx3 +@load-sigs def.sig +# @TEST-END-FILE + +# @TEST-START-FILE xxx3.zeek +# empty +# @TEST-END-FILE + # @TEST-START-FILE abc.sig # empty # @TEST-END-FILE + +# @TEST-START-FILE def.sig +# empty +# @TEST-END-FILE diff --git a/testing/btest/plugins/plugin-load-file-extended/src/Plugin.cc b/testing/btest/plugins/plugin-load-file-extended/src/Plugin.cc index a86d4f50f2..2785b30c9e 100644 --- a/testing/btest/plugins/plugin-load-file-extended/src/Plugin.cc +++ b/testing/btest/plugins/plugin-load-file-extended/src/Plugin.cc @@ -26,9 +26,15 @@ std::pair> Plugin::HookLoadFileExtended(const Lo const std::string& file, const std::string& resolved) { + // Zeek implicitly provides the location where the current '@load' + // originated. If no location is available, filename will be a nullptr. + auto src = zeek::detail::GetCurrentLocation().filename; + if ( ! src ) + src = "n/a"; + if ( type == LoadType::SCRIPT && file == "xxx" ) { - printf("HookLoadExtended/script: file=|%s| resolved=|%s|\n", file.c_str(), resolved.c_str()); + printf("HookLoadExtended/script: file=|%s| resolved=|%s| srcloc=|%s|\n", file.c_str(), resolved.c_str(), src); return std::make_pair(1, R"( event zeek_init() { @@ -41,9 +47,16 @@ std::pair> Plugin::HookLoadFileExtended(const Lo )"); } + if ( type == LoadType::SCRIPT && file == "xxx3" ) + { + printf("HookLoadExtended/script: file=|%s| resolved=|%s| srcloc=|%s|\n", file.c_str(), resolved.c_str(), src); + // We don't replace this one. + return std::make_pair(-1, std::nullopt); + } + if ( type == LoadType::SCRIPT && file == "yyy" ) { - printf("HookLoadExtended/script: file=|%s| resolved=|%s|\n", file.c_str(), resolved.c_str()); + printf("HookLoadExtended/script: file=|%s| resolved=|%s| srcloc=|%s|\n", file.c_str(), resolved.c_str(), src); return std::make_pair(1, R"( event zeek_init() { @@ -54,7 +67,7 @@ std::pair> Plugin::HookLoadFileExtended(const Lo if ( type == LoadType::SIGNATURES && file == "abc.sig" ) { - printf("HookLoadExtended/signature: file=|%s| resolved=|%s|\n", file.c_str(), resolved.c_str()); + printf("HookLoadExtended/signature: file=|%s| resolved=|%s| srcloc=|%s|\n", file.c_str(), resolved.c_str(), src); return std::make_pair(1, R"( signature my-sig { @@ -65,6 +78,13 @@ std::pair> Plugin::HookLoadFileExtended(const Lo )"); } + if ( type == LoadType::SIGNATURES && file == "def.sig" ) + { + printf("HookLoadExtended/signature: file=|%s| resolved=|%s| srcloc=|%s|\n", file.c_str(), resolved.c_str(), src); + // We don't replace this one. + return std::make_pair(-1, std::nullopt); + } + return std::make_pair(-1, std::nullopt); } From b4f52ff311f4b58078e06b6a94faad9c53f1a15c Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 11 Apr 2022 13:40:19 +0200 Subject: [PATCH 138/204] Fix robust iterators when modifying dictionary during iteration. When inserting/deleting elements, we now remove their `DictEntries` from any robust iterators' bookkeeping. First, we don't need that information anymore, and second the `DictEntries` contain pointers that may become invalid. I don't know how to write a unit test for this unfortunately because it depends on where exactly things land in the hash table. Btw, memory mgmt for DictEntries is pretty fragile: They contain pointers to both memory they own (`key`) and memory they don't own (`value`). The former type of pointers is shallow-copied on assignment/copy-construction, meaning that there can be multiple instances seemingly owning the same memory. That only works because deletion is manual, and not part of standard destruction. The second type of pointer has a similar problem, except that it's managed externally. It's important to not end up with multiple `DictEntries` pointing to the same value (which is actually what that iterator bookkeeping did). Addresses #2032. --- src/Dict.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Dict.cc b/src/Dict.cc index 62e4dd0d87..bd90014d9b 100644 --- a/src/Dict.cc +++ b/src/Dict.cc @@ -1299,6 +1299,15 @@ void Dictionary::AdjustOnInsert(IterCookie* c, const detail::DictEntry& entry, i { ASSERT(c); ASSERT_VALID(c); + + // Remove any previous instances of this value that we may have recorded as + // their pointers will get invalid. We won't need that knowledge anymore + // anyways, will update with new information below as needed. + c->inserted->erase(std::remove(c->inserted->begin(), c->inserted->end(), entry), + c->inserted->end()); + c->visited->erase(std::remove(c->visited->begin(), c->visited->end(), entry), + c->visited->end()); + if ( insert_position < c->next ) c->inserted->push_back(entry); if ( insert_position < c->next && c->next <= last_affected_position ) @@ -1314,6 +1323,12 @@ void Dictionary::AdjustOnInsert(IterCookie* c, const detail::DictEntry& entry, i void Dictionary::AdjustOnInsert(RobustDictIterator* c, const detail::DictEntry& entry, int insert_position, int last_affected_position) { + // See note in Dictionary::AdjustOnInsert() above. + c->inserted->erase(std::remove(c->inserted->begin(), c->inserted->end(), entry), + c->inserted->end()); + c->visited->erase(std::remove(c->visited->begin(), c->visited->end(), entry), + c->visited->end()); + if ( insert_position < c->next ) c->inserted->push_back(entry); if ( insert_position < c->next && c->next <= last_affected_position ) @@ -1442,8 +1457,13 @@ void Dictionary::AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, i int last_affected_position) { ASSERT_VALID(c); + + // See note in Dictionary::AdjustOnInsert() above. c->inserted->erase(std::remove(c->inserted->begin(), c->inserted->end(), entry), c->inserted->end()); + c->visited->erase(std::remove(c->visited->begin(), c->visited->end(), entry), + c->visited->end()); + if ( position < c->next && c->next <= last_affected_position ) { int moved = HeadOfClusterByPosition(c->next - 1); @@ -1462,8 +1482,12 @@ void Dictionary::AdjustOnRemove(IterCookie* c, const detail::DictEntry& entry, i void Dictionary::AdjustOnRemove(RobustDictIterator* c, const detail::DictEntry& entry, int position, int last_affected_position) { + // See note in Dictionary::AdjustOnInsert() above. c->inserted->erase(std::remove(c->inserted->begin(), c->inserted->end(), entry), c->inserted->end()); + c->visited->erase(std::remove(c->visited->begin(), c->visited->end(), entry), + c->visited->end()); + if ( position < c->next && c->next <= last_affected_position ) { int moved = HeadOfClusterByPosition(c->next - 1); From 6491db66172be7d7408a98c06b97ff9ea5f9d7b8 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 12 Apr 2022 17:37:49 +0200 Subject: [PATCH 139/204] Fix assertions in dictionary that can trigger for benign reasons. These assertions were checking for a situation that I believe can happen legitimately: a robust iterator pointing to an index that, after some table resizing, happens to be inside the overflow area and hence empty. We'll now move it to the end of the table in the case. --- src/Dict.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Dict.cc b/src/Dict.cc index bd90014d9b..c9d3fab0df 100644 --- a/src/Dict.cc +++ b/src/Dict.cc @@ -1832,7 +1832,20 @@ detail::DictEntry Dictionary::GetNextRobustIteration(RobustDictIterator* iter) if ( iter->next < 0 ) iter->next = Next(-1); - ASSERT(iter->next >= Capacity() || ! table[iter->next].Empty()); + if ( iter->next < Capacity() && table[iter->next].Empty() ) + { + // [Robin] I believe this means that the table has resized in a way + // that we're now inside the overflow area where elements are empty, + // because elsewhere empty slots aren't allowed. Assuming that's right, + // then it means we'll always be at the end of the table now and could + // also just set `next` to capacity. However, just to be sure, we + // instead reuse logic from below to move forward "to a valid position" + // and then double check, through an assertion in debug mode, that it's + // actually the end. If this ever triggered, the above assumption would + // be wrong (but the Next() call would probably still be right). + iter->next = Next(iter->next); + ASSERT(iter->next == Capacity()); + } // Filter out visited keys. int capacity = Capacity(); From 09b132728c23f5c3aeae9f8dd652d4f667d2ea9f Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 13 Apr 2022 16:13:23 +0200 Subject: [PATCH 140/204] Fix another crash during dictionary iteration. Closes #2017. --- src/Dict.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Dict.cc b/src/Dict.cc index c9d3fab0df..a327b51ad5 100644 --- a/src/Dict.cc +++ b/src/Dict.cc @@ -1499,6 +1499,14 @@ void Dictionary::AdjustOnRemove(RobustDictIterator* c, const detail::DictEntry& // if not already the end of the dictionary, adjust next to a valid one. if ( c->next < Capacity() && table[c->next].Empty() ) c->next = Next(c->next); + + if ( c->curr == entry ) + { + if ( c->next >= 0 && c->next < Capacity() && ! table[c->next].Empty() ) + c->curr = table[c->next]; + else + c->curr = detail::DictEntry(nullptr); // -> c == end_robust() + } } /////////////////////////////////////////////////////////////////////////////////////////////////// From 445903f80879993b61b2f6c11cf526f1b7ecf981 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 13 Apr 2022 16:14:09 +0200 Subject: [PATCH 141/204] Add tests exercising dictionary iteration during modification. These are some of the reproducers from #2017 and #2032 by Arne Welzel. --- testing/btest/Traces/echo-connections.pcap.gz | Bin 0 -> 1904995 bytes .../btest/core/dict-iteration-expire1.zeek | 52 +++++++++ .../btest/core/dict-iteration-expire4.zeek | 108 ++++++++++++++++++ .../btest/core/dict-iteration-expire5.zeek | 68 +++++++++++ 4 files changed, 228 insertions(+) create mode 100644 testing/btest/Traces/echo-connections.pcap.gz create mode 100644 testing/btest/core/dict-iteration-expire1.zeek create mode 100644 testing/btest/core/dict-iteration-expire4.zeek create mode 100644 testing/btest/core/dict-iteration-expire5.zeek diff --git a/testing/btest/Traces/echo-connections.pcap.gz b/testing/btest/Traces/echo-connections.pcap.gz new file mode 100644 index 0000000000000000000000000000000000000000..27b8f0a29679454b38006ba19e587c2d46a37452 GIT binary patch literal 1904995 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 0vD}TT=WnHkE{u*q;mZi2U^jI#A#f?p2`rg8kI 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

IkFo5NHuFY}4U*0& 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

$Yv-A=GX^cQ08hlis2pWVGz^eFu(&vSA46 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

=?jChRW}W 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

Vv+xo~I%msY$H5?N(KmHwQ+JB(hV50XUq+tVs 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 z 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%0D?>`kK|?ZpD1knmj)h8x1Oe!i~ap>1vn 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.p;wkD$1L@l_PA=&E4`LRit6E<0p$;dJu&0_#Jv= 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ſM7my>TqZkn<|mKnVG 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

eli-C{7 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⁢fDRVqDmP&XQ$-_K80_crQPOYN0?>~M_Z3`K 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

Gkw5Sb@o7#er6Xf!44a*u3EL~ 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 z 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 cVND Date: Wed, 13 Apr 2022 11:23:03 -0700 Subject: [PATCH 142/204] Disable object-size analysis if optimization set to -O0 --- CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 79ee3c74c9..812e9720f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,7 +178,6 @@ if ( ZEEK_SANITIZERS ) # list(APPEND _check_list "nullability-assign") # Not normally part of "undefined" # list(APPEND _check_list "nullability-return") # Not normally part of "undefined" # list(APPEND _check_list "objc-cast") # Not truly UB - list(APPEND _check_list "object-size") # list(APPEND _check_list "pointer-overflow") # Not implemented in older GCCs list(APPEND _check_list "return") list(APPEND _check_list "returns-nonnull-attribute") @@ -190,6 +189,13 @@ if ( ZEEK_SANITIZERS ) list(APPEND _check_list "vla-bound") # list(APPEND _check_list "vptr") # TODO: fix associated errors + # Clang complains if this one is defined and the optimizer is set to -O0. We + # only set that optimization level if NO_OPTIMIZATIONS is passed, so disable + # the option if that's set. + if ( NOT DEFINED ENV{NO_OPTIMIZATIONS} ) + list(APPEND _check_list "object-size") + endif () + string(REPLACE ";" "," _ub_checks "${_check_list}") set(ZEEK_SANITIZER_UB_CHECKS "${_ub_checks}" CACHE INTERNAL "" FORCE) else () From 903f4bcc8ea2bc260f7ca9bf8d9fff445cb22f26 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 12 Apr 2022 01:03:08 +0000 Subject: [PATCH 143/204] Split asan/ubsan CI builds, add tsan build --- .cirrus.yml | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 65d1ef8b06..9f7f1dbc71 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -12,7 +12,9 @@ memory: &MEMORY 4GB config: &CONFIG --build-type=release --disable-broker-tests --prefix=$CIRRUS_WORKING_DIR/install static_config: &STATIC_CONFIG --build-type=release --disable-broker-tests --enable-static-broker --enable-static-binpac --prefix=$CIRRUS_WORKING_DIR/install -sanitizer_config: &SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=address,undefined --enable-fuzzers --enable-coverage +asan_sanitizer_config: &ASAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=address --enable-fuzzers --enable-coverage +ubsan_sanitizer_config: &UBSAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=undefined --enable-fuzzers +tsan_sanitizer_config: &TSAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=thread --enable-fuzzers mobile_ipv6_config: &MOBILE_IPV6_CONFIG --build-type=release --enable-mobile-ipv6 --disable-broker-tests --prefix=$CIRRUS_WORKING_DIR/install openssl30_config: &OPENSSL30_CONFIG --build-type=release --disable-broker-tests --with-openssl=/opt/openssl --prefix=$CIRRUS_WORKING_DIR/install @@ -268,7 +270,7 @@ openssl30_task: env: ZEEK_CI_CONFIGURE_FLAGS: *OPENSSL30_CONFIG -sanitizer_task: +asan_sanitizer_task: container: # Just uses a recent/common distro to run memory error/leak checks. dockerfile: ci/ubuntu-20.04/Dockerfile @@ -277,10 +279,38 @@ sanitizer_task: memory: 12GB << : *CI_TEMPLATE test_fuzzers_script: ./ci/test-fuzzers.sh - coverage_script: ./ci/upload-coverage.sh env: CXXFLAGS: -DZEEK_DICT_DEBUG - ZEEK_CI_CONFIGURE_FLAGS: *SANITIZER_CONFIG - ZEEK_TAILORED_UB_CHECKS: 1 + ZEEK_CI_CONFIGURE_FLAGS: *ASAN_SANITIZER_CONFIG ZEEK_CI_DISABLE_SCRIPT_PROFILING: 1 + ASAN_OPTIONS: detect_leaks=1 + +ubsan_sanitizer_task: + container: + # Just uses a recent/common distro to run undefined behavior checks. + dockerfile: ci/ubuntu-20.04/Dockerfile + cpu: 4 + # AddressSanitizer uses a lot more memory than a typical config. + memory: 12GB + << : *CI_TEMPLATE + test_fuzzers_script: ./ci/test-fuzzers.sh + env: + CXXFLAGS: -DZEEK_DICT_DEBUG + ZEEK_CI_CONFIGURE_FLAGS: *UBSAN_SANITIZER_CONFIG + ZEEK_CI_DISABLE_SCRIPT_PROFILING: 1 + ZEEK_TAILORED_UB_CHECKS: 1 UBSAN_OPTIONS: print_stacktrace=1 + +tsan_sanitizer_task: + container: + # Just uses a recent/common distro to run memory error/leak checks. + dockerfile: ci/ubuntu-20.04/Dockerfile + cpu: 4 + # AddressSanitizer uses a lot more memory than a typical config. + memory: 12GB + << : *CI_TEMPLATE + test_fuzzers_script: ./ci/test-fuzzers.sh + env: + CXXFLAGS: -DZEEK_DICT_DEBUG + ZEEK_CI_CONFIGURE_FLAGS: *TSAN_SANITIZER_CONFIG + ZEEK_CI_DISABLE_SCRIPT_PROFILING: 1 From f8de297c6fd0022b23f7c0e8d6eb86d6d15108bb Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 14 Apr 2022 12:38:14 -0700 Subject: [PATCH 144/204] Escape special characters in paths before using them as regexes --- cmake | 2 +- src/CMakeLists.txt | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cmake b/cmake index 960ca0a43b..d23b14b4c1 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 960ca0a43b1691b771245826a50fcf53d49ed59b +Subproject commit d23b14b4c146d59ebb68b81650e2e314047ed460 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dfc253ed69..63478cc610 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -575,6 +575,10 @@ install(CODE " ) ") +# Make sure to escape a bunch of special characters in the path before trying to use it as a +# regular expression below. +string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" escaped_path "${CMAKE_CURRENT_SOURCE_DIR}/zeek") + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/zeek FILES_MATCHING @@ -582,7 +586,7 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ PATTERN "*.pac" PATTERN "3rdparty/*" EXCLUDE # The "zeek -> ." symlink isn't needed in the install-tree - REGEX "^${CMAKE_CURRENT_SOURCE_DIR}/zeek$" EXCLUDE + REGEX "^${escaped_path}$" EXCLUDE ) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ From acaa9ec01e00447b0deca37385f08797895b00b1 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 14 Apr 2022 14:25:00 -0700 Subject: [PATCH 145/204] Bump gen-zam submodule to pull in GCC 12 fix [nomail] --- auxil/gen-zam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/gen-zam b/auxil/gen-zam index 6937c11b62..f8c8fb36fb 160000 --- a/auxil/gen-zam +++ b/auxil/gen-zam @@ -1 +1 @@ -Subproject commit 6937c11b62b729bf30eb8d517f36c94de2fdeb42 +Subproject commit f8c8fb36fb07a2c1703c63dd8624cf1329c0c4d0 From 2d93a19f4595b1e8c623b2e42813d50767de1148 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 14 Apr 2022 15:20:08 -0700 Subject: [PATCH 146/204] Expand plugin.reporter-hook testcase to verify -NN output --- .../Baseline/plugins.reporter-hook/output | 23 +++++++++++-------- .../plugins.reporter-hook/reporter.log | 8 +++---- testing/btest/plugins/reporter-hook.zeek | 3 ++- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/testing/btest/Baseline/plugins.reporter-hook/output b/testing/btest/Baseline/plugins.reporter-hook/output index bcc9b6a25a..57b265589c 100644 --- a/testing/btest/Baseline/plugins.reporter-hook/output +++ b/testing/btest/Baseline/plugins.reporter-hook/output @@ -1,11 +1,14 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. - | Hook Some Info <...>/reporter-hook.zeek, line 16 - | Hook error An Error <...>/reporter-hook.zeek, line 18 - | Hook error An Error that does not show up in the log <...>/reporter-hook.zeek, line 19 - | Hook expression error field value missing (b$a) <...>/reporter-hook.zeek, line 23 - | Hook warning A warning <...>/reporter-hook.zeek, line 17 -<...>/reporter-hook.zeek, line 16: Some Info -error in <...>/reporter-hook.zeek, line 18: An Error -error in <...>/reporter-hook.zeek, line 19: An Error that does not show up in the log -expression error in <...>/reporter-hook.zeek, line 23: field value missing (b$a) -warning in <...>/reporter-hook.zeek, line 17: A warning +Reporter::Hook - Exercise Reporter Hook (dynamic, version 1.0.0) + Implements Reporter (priority 0) + + | Hook Some Info <...>/reporter-hook.zeek, line 17 + | Hook error An Error <...>/reporter-hook.zeek, line 19 + | Hook error An Error that does not show up in the log <...>/reporter-hook.zeek, line 20 + | Hook expression error field value missing (b$a) <...>/reporter-hook.zeek, line 24 + | Hook warning A warning <...>/reporter-hook.zeek, line 18 +<...>/reporter-hook.zeek, line 17: Some Info +error in <...>/reporter-hook.zeek, line 19: An Error +error in <...>/reporter-hook.zeek, line 20: An Error that does not show up in the log +expression error in <...>/reporter-hook.zeek, line 24: field value missing (b$a) +warning in <...>/reporter-hook.zeek, line 18: A warning diff --git a/testing/btest/Baseline/plugins.reporter-hook/reporter.log b/testing/btest/Baseline/plugins.reporter-hook/reporter.log index 2b9dfb451d..1225fa1cfa 100644 --- a/testing/btest/Baseline/plugins.reporter-hook/reporter.log +++ b/testing/btest/Baseline/plugins.reporter-hook/reporter.log @@ -7,8 +7,8 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts level message location #types time enum string string -XXXXXXXXXX.XXXXXX Reporter::INFO Some Info <...>/reporter-hook.zeek, line 16 -XXXXXXXXXX.XXXXXX Reporter::WARNING A warning <...>/reporter-hook.zeek, line 17 -XXXXXXXXXX.XXXXXX Reporter::ERROR An Error <...>/reporter-hook.zeek, line 18 -XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (b$a) <...>/reporter-hook.zeek, line 23 +XXXXXXXXXX.XXXXXX Reporter::INFO Some Info <...>/reporter-hook.zeek, line 17 +XXXXXXXXXX.XXXXXX Reporter::WARNING A warning <...>/reporter-hook.zeek, line 18 +XXXXXXXXXX.XXXXXX Reporter::ERROR An Error <...>/reporter-hook.zeek, line 19 +XXXXXXXXXX.XXXXXX Reporter::ERROR field value missing (b$a) <...>/reporter-hook.zeek, line 24 #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/plugins/reporter-hook.zeek b/testing/btest/plugins/reporter-hook.zeek index 92a971eca8..4407a1013f 100644 --- a/testing/btest/plugins/reporter-hook.zeek +++ b/testing/btest/plugins/reporter-hook.zeek @@ -1,7 +1,8 @@ # @TEST-EXEC: ${DIST}/auxil/zeek-aux/plugin-support/init-plugin -u . Reporter Hook # @TEST-EXEC: cp -r %DIR/reporter-hook-plugin/* . # @TEST-EXEC: ./configure --zeek-dist=${DIST} && make -# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Reporter::Hook" ZEEK_PLUGIN_PATH=`pwd` zeek -b %INPUT 2>&1 | $SCRIPTS/diff-remove-abspath | sort | uniq >output +# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Reporter::Hook" ZEEK_PLUGIN_PATH=`pwd` zeek -NN Reporter::Hook >output +# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Reporter::Hook" ZEEK_PLUGIN_PATH=`pwd` zeek -b %INPUT 2>&1 | $SCRIPTS/diff-remove-abspath | sort | uniq >>output # @TEST-EXEC: btest-diff output # @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-remove-timestamps" btest-diff reporter.log From 397e4c971876d678beabc413995a23aba58f7965 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 14 Apr 2022 15:20:44 -0700 Subject: [PATCH 147/204] Add "Reporter" entry to fix plugin hook_name() vs HookType imbalance The hook_name() list was missing an entry corresponding to HOOK_REPORTER. Co-authored-by: Peter Cullen --- src/plugin/Plugin.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index c7ef7e4f8f..4e0c1f924c 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -31,6 +31,7 @@ const char* hook_name(HookType h) "SetupAnalyzerTree", "LogInit", "LogWrite", + "Reporter", "UnprocessedPacket", // MetaHooks "MetaHookPre", From 337c7267e003083e6677b60be603f7da340ecf90 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 23 Mar 2022 16:27:28 -0700 Subject: [PATCH 148/204] Management framework: allow agents to communicate with cluster nodes This provides Broker-level plumbing that allows agents to reach out to their managed Zeek nodes and collect responses. As a first event, it establishes Management::Node::API::notify_agent_hello, to notify the agent when the cluster node is ready to communicate. Also a bit of comment rewording to replace use of "data cluster" with simply "cluster", to avoid ambiguity with data nodes in SumStats, and expansion of test-all-policy.zeek and related/dependent tests, since we're introducing new scripts. --- .../frameworks/management/agent/main.zeek | 25 +++++++----- .../management/controller/main.zeek | 4 +- scripts/policy/frameworks/management/log.zeek | 1 + .../frameworks/management/node/__load__.zeek | 1 + .../frameworks/management/node/api.zeek | 21 ++++++++++ .../frameworks/management/node/config.zeek | 9 +++++ .../frameworks/management/node/main.zeek | 39 +++++++++++++++++++ .../policy/frameworks/management/types.zeek | 3 +- scripts/test-all-policy.zeek | 4 ++ scripts/zeekygen/__load__.zeek | 2 + .../Baseline/coverage.bare-mode-errors/errors | 6 +-- 11 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 scripts/policy/frameworks/management/node/__load__.zeek create mode 100644 scripts/policy/frameworks/management/node/api.zeek create mode 100644 scripts/policy/frameworks/management/node/config.zeek create mode 100644 scripts/policy/frameworks/management/node/main.zeek diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index 75d0247a36..f5e033db2e 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -5,6 +5,8 @@ @load base/frameworks/broker @load policy/frameworks/management +@load policy/frameworks/management/node/api +@load policy/frameworks/management/node/config @load ./api @load ./config @@ -120,7 +122,7 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M g_nodes = table(); - # Refresh the data cluster and nodes tables + # Refresh the cluster and nodes tables g_data_cluster = table(); for ( node in config$nodes ) @@ -166,6 +168,11 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M if ( node?$env ) nc$env = node$env; + # Always add the policy/management/node scripts to any cluster + # node, since we require it to be able to communicate with the + # node. + nc$scripts[|nc$scripts|] = "policy/frameworks/management/node"; + # XXX could use options to enable per-node overrides for # directory, stdout, stderr, others? @@ -209,7 +216,7 @@ event SupervisorControl::status_response(reqid: string, result: Supervisor::Stat local cns = Management::NodeStatus( $node=node, $state=Management::PENDING); - # Identify the role of the node. For data cluster roles (worker, + # Identify the role of the node. For cluster roles (worker, # manager, etc) we derive this from the cluster node table. For # agent and controller, we identify via environment variables # that the controller framework establishes upon creation (see @@ -342,10 +349,11 @@ event zeek_init() Broker::peer(supervisor_addr, Broker::default_port, Broker::default_listen_retry); - # Agents need receive communication targeted at it, and any responses - # from the supervisor. + # Agents need receive communication targeted at it, any responses + # from the supervisor, and any responses from cluster nodes. Broker::subscribe(agent_topic); Broker::subscribe(SupervisorControl::topic_prefix); + Broker::subscribe(Management::Node::node_topic); # Auto-publish a bunch of events. Glob patterns or module-level # auto-publish would be helpful here. @@ -373,11 +381,10 @@ event zeek_init() Management::Agent::controller$bound_port, Management::connect_retry); } - else - { - # Controller connects to us; listen for it. - Broker::listen(cat(epi$network$address), epi$network$bound_port); - } + + # The agent always listens, to allow cluster nodes to peer with it. + # If the controller connects to us, it also uses this port. + Broker::listen(cat(epi$network$address), epi$network$bound_port); Management::Log::info("agent is live"); } diff --git a/scripts/policy/frameworks/management/controller/main.zeek b/scripts/policy/frameworks/management/controller/main.zeek index 5aa5292b04..cac27ac814 100644 --- a/scripts/policy/frameworks/management/controller/main.zeek +++ b/scripts/policy/frameworks/management/controller/main.zeek @@ -386,10 +386,10 @@ event Management::Controller::API::set_configuration_request(reqid: string, conf g_config_reqid_pending = req$id; # Compare the instance configuration to our current one. If it matches, - # we can proceed to deploying the new data cluster topology. If it does + # we can proceed to deploying the new cluster topology. If it does # not, we need to establish connectivity with agents we connect to, or # wait until all instances that connect to us have done so. Either triggers - # a notify_agents_ready event, upon which we then deploy the data cluster. + # a notify_agents_ready event, upon which we then deploy the topology. # The current & new set of instance names. local insts_current: set[string]; diff --git a/scripts/policy/frameworks/management/log.zeek b/scripts/policy/frameworks/management/log.zeek index e69c55b122..7d3b565b32 100644 --- a/scripts/policy/frameworks/management/log.zeek +++ b/scripts/policy/frameworks/management/log.zeek @@ -82,6 +82,7 @@ global l2s: table[Level] of string = { global r2s: table[Management::Role] of string = { [Management::AGENT] = "AGENT", [Management::CONTROLLER] = "CONTROLLER", + [Management::NODE] = "NODE", }; function debug(message: string) diff --git a/scripts/policy/frameworks/management/node/__load__.zeek b/scripts/policy/frameworks/management/node/__load__.zeek new file mode 100644 index 0000000000..a10fe855df --- /dev/null +++ b/scripts/policy/frameworks/management/node/__load__.zeek @@ -0,0 +1 @@ +@load ./main diff --git a/scripts/policy/frameworks/management/node/api.zeek b/scripts/policy/frameworks/management/node/api.zeek new file mode 100644 index 0000000000..4eac9d0771 --- /dev/null +++ b/scripts/policy/frameworks/management/node/api.zeek @@ -0,0 +1,21 @@ +##! The Management event API of cluster nodes. The API consists of request/ +##! response event pairs, like elsewhere in the Management, Supervisor, and +##! Control frameworks. + +@load policy/frameworks/management/types + +module Management::Node::API; + +export { + # Notification events, node -> agent + + ## The cluster nodes send this event upon peering as a "check-in" to + ## the agent, to indicate the node is now available to communicate + ## with. It is an agent-level equivalent of :zeek:see:`Broker::peer_added`, + ## and similar to :zeek:see:`Management::Agent::API::notify_agent_hello` + ## for agents. + ## + ## node: the name of the node, as given in :zeek:see:`Cluster::node`. + ## + global notify_node_hello: event(node: string); +} diff --git a/scripts/policy/frameworks/management/node/config.zeek b/scripts/policy/frameworks/management/node/config.zeek new file mode 100644 index 0000000000..d17fd663a1 --- /dev/null +++ b/scripts/policy/frameworks/management/node/config.zeek @@ -0,0 +1,9 @@ +##! Configuration settings for nodes controlled by the Management framework. + +module Management::Node; + +export { + ## The nodes' Broker topic. Cluster nodes automatically subscribe + ## to it, to receive request events from the Management framework. + const node_topic = "zeek/management/node" &redef; +} diff --git a/scripts/policy/frameworks/management/node/main.zeek b/scripts/policy/frameworks/management/node/main.zeek new file mode 100644 index 0000000000..92d41acfbe --- /dev/null +++ b/scripts/policy/frameworks/management/node/main.zeek @@ -0,0 +1,39 @@ +##! This module provides Management framework functionality that needs to be +##! present in every cluster node to allow Management agents to interact with +##! the cluster nodes they manage. + +@load policy/frameworks/management/agent/config +@load policy/frameworks/management/log + +@load ./config + +module Management::Node; + +# Tag our logs correctly +redef Management::Log::role = Management::NODE; + +event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) + { + local epi = Management::Agent::endpoint_info(); + + # If this is the agent peering, notify it that we're ready + if ( peer$network$address == epi$network$address && + peer$network$bound_port == epi$network$bound_port ) + event Management::Node::API::notify_node_hello(Cluster::node); + } + +event zeek_init() + { + local epi = Management::Agent::endpoint_info(); + + Broker::peer(epi$network$address, epi$network$bound_port, Management::connect_retry); + Broker::subscribe(node_topic); + + # Events automatically sent to the Management agent. + local events: vector of any = [ + Management::Node::API::notify_node_hello + ]; + + for ( i in events ) + Broker::auto_publish(node_topic, events[i]); + } diff --git a/scripts/policy/frameworks/management/types.zeek b/scripts/policy/frameworks/management/types.zeek index 824ea7dfb4..6d89fbda1a 100644 --- a/scripts/policy/frameworks/management/types.zeek +++ b/scripts/policy/frameworks/management/types.zeek @@ -6,12 +6,13 @@ module Management; export { ## Management infrastructure node type. This intentionally does not - ## include the data cluster node types (worker, logger, etc) -- those + ## include the managed cluster node types (worker, logger, etc) -- those ## continue to be managed by the cluster framework. type Role: enum { NONE, ##< No active role in cluster management AGENT, ##< A cluster management agent. CONTROLLER, ##< The cluster's controller. + NODE, ##< A managed cluster node (worker, manager, etc). }; ## A Zeek-side option with value. diff --git a/scripts/test-all-policy.zeek b/scripts/test-all-policy.zeek index 16bc4f3ede..0f2de90609 100644 --- a/scripts/test-all-policy.zeek +++ b/scripts/test-all-policy.zeek @@ -24,6 +24,10 @@ @load frameworks/management/__load__.zeek @load frameworks/management/config.zeek @load frameworks/management/log.zeek +# @load frameworks/management/node/__load__.zeek +@load frameworks/management/node/api.zeek +@load frameworks/management/node/config.zeek +# @load frameworks/management/node/main.zeek @load frameworks/management/request.zeek @load frameworks/management/types.zeek @load frameworks/management/util.zeek diff --git a/scripts/zeekygen/__load__.zeek b/scripts/zeekygen/__load__.zeek index ad28277176..39314a04ac 100644 --- a/scripts/zeekygen/__load__.zeek +++ b/scripts/zeekygen/__load__.zeek @@ -7,6 +7,8 @@ @load frameworks/control/controller.zeek @load frameworks/management/agent/main.zeek @load frameworks/management/controller/main.zeek +@load frameworks/management/node/__load__.zeek +@load frameworks/management/node/main.zeek @load frameworks/files/extract-all-files.zeek @load policy/misc/dump-events.zeek @load policy/protocols/conn/speculative-service.zeek diff --git a/testing/btest/Baseline/coverage.bare-mode-errors/errors b/testing/btest/Baseline/coverage.bare-mode-errors/errors index a72d64757e..bc9bd28f83 100644 --- a/testing/btest/Baseline/coverage.bare-mode-errors/errors +++ b/testing/btest/Baseline/coverage.bare-mode-errors/errors @@ -1,9 +1,9 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### NOTE: This file has been sorted with diff-sort. -warning in <...>/extract-certs-pem.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:13 "Remove in v5.1. Use log-certs-base64.zeek instead." +warning in <...>/extract-certs-pem.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:15 "Remove in v5.1. Use log-certs-base64.zeek instead." warning in <...>/extract-certs-pem.zeek, line 1: deprecated script loaded from command line arguments "Remove in v5.1. Use log-certs-base64.zeek instead." -warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:61 ("Remove in v5.1. OCSP logging is now enabled by default") -warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:61 ("Remove in v5.1. OCSP logging is now enabled by default") +warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:65 ("Remove in v5.1. OCSP logging is now enabled by default") +warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:65 ("Remove in v5.1. OCSP logging is now enabled by default") warning in <...>/log-ocsp.zeek, line 1: deprecated script loaded from command line arguments ("Remove in v5.1. OCSP logging is now enabled by default") warning in <...>/notary.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:5 ("Remove in v5.1. Please switch to other more modern approaches like SCT validation (validate-sct.zeek).") warning in <...>/notary.zeek, line 1: deprecated script loaded from command line arguments ("Remove in v5.1. Please switch to other more modern approaches like SCT validation (validate-sct.zeek).") From 0020cc4af09d0f9eaf380a34e3c1b7dcd091cbfe Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 11 Apr 2022 21:06:29 -0700 Subject: [PATCH 149/204] Management framework: some renaming to avoid the term "data cluster" --- scripts/policy/frameworks/management/agent/main.zeek | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index f5e033db2e..d57fd7b166 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -42,7 +42,7 @@ global g_nodes: table[string] of Management::Node; # The node map employed by the supervisor to describe the cluster # topology to newly forked nodes. We refresh it when we receive # new configurations. -global g_data_cluster: table[string] of Supervisor::ClusterEndpoint; +global g_cluster: table[string] of Supervisor::ClusterEndpoint; event SupervisorControl::create_response(reqid: string, result: string) @@ -124,7 +124,7 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M # Refresh the cluster and nodes tables - g_data_cluster = table(); + g_cluster = table(); for ( node in config$nodes ) { if ( node$instance == Management::Agent::name ) @@ -146,7 +146,7 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M if ( node?$interface ) cep$interface = node$interface; - g_data_cluster[node$name] = cep; + g_cluster[node$name] = cep; } # Apply the new configuration via the supervisor @@ -176,7 +176,7 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M # XXX could use options to enable per-node overrides for # directory, stdout, stderr, others? - nc$cluster = g_data_cluster; + nc$cluster = g_cluster; supervisor_create(nc); } From 788348f9d68b43c8d115f129395953156e57b21e Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Tue, 12 Apr 2022 21:56:55 -0700 Subject: [PATCH 150/204] Management framework: allow dispatching "actions" on cluster nodes. This adds request/response event pairs to enable the controller to dispatch "actions" (pre-implemented Zeek script actions) on subsets of Zeek cluster nodes and collect the results. Using generic events to carry multiple such "run X on the nodes" scenarios simplifies adding these in the future. --- .../frameworks/management/agent/api.zeek | 28 +++- .../frameworks/management/agent/main.zeek | 123 ++++++++++++++++-- .../frameworks/management/controller/api.zeek | 2 +- .../management/controller/main.zeek | 105 +++++++++++++-- .../frameworks/management/node/api.zeek | 21 +++ .../frameworks/management/node/main.zeek | 50 ++++++- 6 files changed, 297 insertions(+), 32 deletions(-) diff --git a/scripts/policy/frameworks/management/agent/api.zeek b/scripts/policy/frameworks/management/agent/api.zeek index 876f121500..6607c27144 100644 --- a/scripts/policy/frameworks/management/agent/api.zeek +++ b/scripts/policy/frameworks/management/agent/api.zeek @@ -60,8 +60,32 @@ export { ## records, covering the nodes at this instance. The result may also ## indicate failure, with error messages indicating what went wrong. ## - global get_nodes_response: event(reqid: string, - result: Management::Result); + global get_nodes_response: event(reqid: string, result: Management::Result); + + + ## The controller sends this to every agent to request a dispatch (the + ## execution of a pre-implemented activity) to all cluster nodes. This + ## is the generic controller-agent "back-end" implementation of explicit + ## client-controller "front-end" interactions. + ## + ## reqid: a request identifier string, echoed in the response event. + ## + ## action: the requested dispatch command, with any arguments. + global node_dispatch_request: event(reqid: string, action: vector of string); + + ## Response to a node_dispatch_request event. Each agent sends this back + ## to the controller to report the dispatch outcomes on all nodes managed + ## by that agent. + ## + ## reqid: the request identifier used in the request event. + ## + ## result: a :zeek:type:`vector` of :zeek:see:`Management::Result` + ## records. Each record covers one Zeek cluster node managed by this + ## agent. Upon success, each :zeek:see:`Management::Result` record's + ## data member contains the dispatches' response in a data type + ## appropriate for the respective dispatch. + global node_dispatch_response: event(reqid: string, result: Management::ResultVec); + ## The controller sends this event to confirm to the agent that it is ## part of the current cluster topology. The agent acknowledges with the diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index d57fd7b166..2dafd0414d 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -21,10 +21,22 @@ export { type SupervisorState: record { node: string; ##< Name of the node the Supervisor is acting on. }; + + ## Request state for node dispatches, tracking the requested action + ## as well as received responses. + type NodeDispatchState: record { + ## The dispatched action. The first string is a command, + ## any remaining strings its arguments. + action: vector of string; + + ## Request state for every node managed by this agent. + requests: set[string] &default=set(); + }; } redef record Management::Request::Request += { supervisor_state: SupervisorState &optional; + node_dispatch_state: NodeDispatchState &optional; }; # Tag our logs correctly @@ -285,6 +297,81 @@ event Management::Agent::API::get_nodes_request(reqid: string) Management::Log::info(fmt("issued supervisor status, %s", req$id)); } +event Management::Node::API::node_dispatch_response(reqid: string, result: Management::Result) + { + Management::Log::info(fmt("rx Management::Node::API::node_dispatch_response %s", reqid)); + + # Retrieve state for the request we just got a response to + local nreq = Management::Request::lookup(reqid); + if ( Management::Request::is_null(nreq) ) + return; + + # Find the original request from the controller + local req = Management::Request::lookup(nreq$parent_id); + if ( Management::Request::is_null(req) ) + return; + + # Mark the responding node as done. Nodes normally fill their own name + # into the result; we only double-check for resilience. Nodes failing to + # report themselves would eventually lead to request timeout. + if ( result?$node && result$node in req$node_dispatch_state$requests ) + delete req$node_dispatch_state$requests[result$node]; + + # The usual special treatment for Broker values that are of type "any": + # confirm their type here based on the requested dispatch command. + switch req$node_dispatch_state$action[0] + { + default: + Management::Log::error(fmt("unexpected dispatch command %s", + req$node_dispatch_state$action[0])); + break; + } + + # The result has the reporting node filled in but not the agent/instance + # (which the node doesn't know about), so add it now. + result$instance = Management::Agent::instance()$name; + + # Add this result to the overall response + req$results[|req$results|] = result; + + # If we still have pending queries out to the agents, do nothing: we'll + # handle this soon, or our request will time out and we respond with + # error. + if ( |req$node_dispatch_state$requests| > 0 ) + return; + + # Release the agent-nodes request state, since we now have all responses. + Management::Request::finish(nreq$id); + + # Send response event back to controller and clean up main request state. + Management::Log::info(fmt("tx Management::Agent::API::node_dispatch_response %s", + Management::Request::to_string(req))); + event Management::Agent::API::node_dispatch_response(req$id, req$results); + Management::Request::finish(req$id); + } + +event Management::Agent::API::node_dispatch_request(reqid: string, action: vector of string) + { + Management::Log::info(fmt("rx Management::Agent::API::node_dispatch_request %s %s", reqid, action)); + + local res: Management::Result; + local req = Management::Request::create(reqid); + + req$node_dispatch_state = NodeDispatchState($action=action); + + for ( node in g_nodes ) + add req$node_dispatch_state$requests[node]; + + # We use a single request record to track all node responses. We know + # when all nodes have responded via the requests set we built up above. + local nreq = Management::Request::create(); + nreq$parent_id = reqid; + + Management::Log::info(fmt("tx Management::Node::API::node_dispatch_request %s %s", nreq$id, action)); + Broker::publish(Management::Node::node_topic, + Management::Node::API::node_dispatch_request, nreq$id, action); + } + event Management::Agent::API::agent_welcome_request(reqid: string) { Management::Log::info(fmt("rx Management::Agent::API::agent_welcome_request %s", reqid)); @@ -357,21 +444,31 @@ event zeek_init() # Auto-publish a bunch of events. Glob patterns or module-level # auto-publish would be helpful here. - Broker::auto_publish(agent_topic, Management::Agent::API::get_nodes_response); - Broker::auto_publish(agent_topic, Management::Agent::API::set_configuration_response); - Broker::auto_publish(agent_topic, Management::Agent::API::agent_welcome_response); - Broker::auto_publish(agent_topic, Management::Agent::API::agent_standby_response); + local agent_to_controller_events: vector of any = [ + Management::Agent::API::get_nodes_response, + Management::Agent::API::set_configuration_response, + Management::Agent::API::agent_welcome_response, + Management::Agent::API::agent_standby_response, + Management::Agent::API::node_dispatch_response, + Management::Agent::API::notify_agent_hello, + Management::Agent::API::notify_change, + Management::Agent::API::notify_error, + Management::Agent::API::notify_log + ]; - Broker::auto_publish(agent_topic, Management::Agent::API::notify_agent_hello); - Broker::auto_publish(agent_topic, Management::Agent::API::notify_change); - Broker::auto_publish(agent_topic, Management::Agent::API::notify_error); - Broker::auto_publish(agent_topic, Management::Agent::API::notify_log); + for ( i in agent_to_controller_events ) + Broker::auto_publish(agent_topic, agent_to_controller_events[i]); - Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::create_request); - Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::status_request); - Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::destroy_request); - Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::restart_request); - Broker::auto_publish(SupervisorControl::topic_prefix, SupervisorControl::stop_request); + local agent_to_sup_events: vector of any = [ + SupervisorControl::create_request, + SupervisorControl::status_request, + SupervisorControl::destroy_request, + SupervisorControl::restart_request, + SupervisorControl::stop_request + ]; + + for ( i in agent_to_sup_events ) + Broker::auto_publish(SupervisorControl::topic_prefix, agent_to_sup_events[i]); # Establish connectivity with the controller. if ( Management::Agent::controller$address != "0.0.0.0" ) diff --git a/scripts/policy/frameworks/management/controller/api.zeek b/scripts/policy/frameworks/management/controller/api.zeek index 575f90009a..9b374d54f4 100644 --- a/scripts/policy/frameworks/management/controller/api.zeek +++ b/scripts/policy/frameworks/management/controller/api.zeek @@ -71,7 +71,7 @@ export { ## ## reqid: the request identifier used in the request event. ## - ## result: a :zeek:type`vector` of :zeek:see:`Management::Result` + ## result: a :zeek:type:`vector` of :zeek:see:`Management::Result` ## records. Each record covers one cluster instance. Each record's data ## member is a vector of :zeek:see:`Management::NodeStatus` ## records, covering the nodes at that instance. Results may also indicate diff --git a/scripts/policy/frameworks/management/controller/main.zeek b/scripts/policy/frameworks/management/controller/main.zeek index cac27ac814..d7a292d7f4 100644 --- a/scripts/policy/frameworks/management/controller/main.zeek +++ b/scripts/policy/frameworks/management/controller/main.zeek @@ -36,6 +36,25 @@ export { requests: set[string] &default=set(); }; + ## Request state for node dispatch requests, to track the requested + ## action and received responses. Node dispatches are requests to + ## execute pre-implemented actions on every node in the cluster, + ## and report their outcomes. See + ## :zeek:see:`Management::Agent::API::node_dispatch_request` and + ## :zeek:see:`Management::Agent::API::node_dispatch_response` for the + ## agent/controller interaction. + type NodeDispatchState: record { + ## The dispatched action. The first string is a command, + ## any remaining strings its arguments. + action: vector of string; + + ## Request state for every controller/agent transaction. + ## The set of strings tracks the node names from which + ## we still expect responses, before we can respond back + ## to the client. + requests: set[string] &default=set(); + }; + ## Dummy state for internal state-keeping test cases. type TestState: record { }; } @@ -43,6 +62,7 @@ export { redef record Management::Request::Request += { set_configuration_state: SetConfigurationState &optional; get_nodes_state: GetNodesState &optional; + node_dispatch_state: NodeDispatchState &optional; test_state: TestState &optional; }; @@ -485,7 +505,7 @@ event Management::Agent::API::get_nodes_response(reqid: string, result: Manageme if ( Management::Request::is_null(areq) ) return; - # Release the request, which is now done. + # Release the request, since this agent is now done. Management::Request::finish(areq$id); # Find the original request from the client @@ -554,22 +574,75 @@ event Management::Controller::API::get_nodes_request(reqid: string) } } +event Management::Agent::API::node_dispatch_response(reqid: string, results: Management::ResultVec) + { + Management::Log::info(fmt("rx Management::Agent::API::node_dispatch_response %s", reqid)); + + # Retrieve state for the request we just got a response to + local areq = Management::Request::lookup(reqid); + if ( Management::Request::is_null(areq) ) + return; + + # Release the request, since this agent is now done. + Management::Request::finish(areq$id); + + # Find the original request from the client + local req = Management::Request::lookup(areq$parent_id); + if ( Management::Request::is_null(req) ) + return; + + # Add this agent's results to the overall response + for ( i in results ) + { + # Same special treatment for Broker values that are of + # type "any": confirm their (known) type here. + switch req$node_dispatch_state$action[0] + { + default: + Management::Log::error(fmt("unexpected dispatch command %s", + req$node_dispatch_state$action[0])); + break; + } + + req$results[|req$results|] = results[i]; + } + + # Mark this request as done + if ( areq$id in req$node_dispatch_state$requests ) + delete req$node_dispatch_state$requests[areq$id]; + + # If we still have pending queries out to the agents, do nothing: we'll + # handle this soon, or our request will time out and we respond with + # error. + if ( |req$node_dispatch_state$requests| > 0 ) + return; + + # Send response event to the client based upon the dispatch type. + switch req$node_dispatch_state$action[0] + { + default: + Management::Log::error(fmt("unexpected dispatch command %s", + req$node_dispatch_state$action[0])); + break; + } + + Management::Request::finish(req$id); + } + event Management::Request::request_expired(req: Management::Request::Request) { # Various handlers for timed-out request state. We use the state members # to identify how to respond. No need to clean up the request itself, # since we're getting here via the request module's expiration # mechanism that handles the cleanup. - local res: Management::Result; + local res = Management::Result($reqid=req$id, + $success = F, + $error = "request timed out"); if ( req?$set_configuration_state ) { # This timeout means we no longer have a pending request. g_config_reqid_pending = ""; - - res = Management::Result($reqid=req$id); - res$success = F; - res$error = "request timed out"; req$results += res; Management::Log::info(fmt("tx Management::Controller::API::set_configuration_response %s", @@ -579,9 +652,6 @@ event Management::Request::request_expired(req: Management::Request::Request) if ( req?$get_nodes_state ) { - res = Management::Result($reqid=req$id); - res$success = F; - res$error = "request timed out"; req$results += res; Management::Log::info(fmt("tx Management::Controller::API::get_nodes_response %s", @@ -589,12 +659,21 @@ event Management::Request::request_expired(req: Management::Request::Request) event Management::Controller::API::get_nodes_response(req$id, req$results); } + if ( req?$node_dispatch_state ) + { + req$results += res; + + switch req$node_dispatch_state$action[0] + { + default: + Management::Log::error(fmt("unexpected dispatch command %s", + req$node_dispatch_state$action[0])); + break; + } + } + if ( req?$test_state ) { - res = Management::Result($reqid=req$id); - res$success = F; - res$error = "request timed out"; - Management::Log::info(fmt("tx Management::Controller::API::test_timeout_response %s", req$id)); event Management::Controller::API::test_timeout_response(req$id, res); } diff --git a/scripts/policy/frameworks/management/node/api.zeek b/scripts/policy/frameworks/management/node/api.zeek index 4eac9d0771..85cb010463 100644 --- a/scripts/policy/frameworks/management/node/api.zeek +++ b/scripts/policy/frameworks/management/node/api.zeek @@ -7,6 +7,27 @@ module Management::Node::API; export { + ## Management agents send this event to every Zeek cluster node to run a + ## "dispatch" -- a particular, pre-implemented action. This is the agent-node + ## complement to :zeek:see:`Management::Agent::API::node_dispatch_request`. + ## + ## reqid: a request identifier string, echoed in the response event. + ## + ## action: the requested dispatch command, with any arguments. + global node_dispatch_request: event(reqid: string, action: vector of string); + + ## Response to a node_dispatch_request event. The nodes send this back + ## to the agent. This is the agent-node equivalent of + ## :zeek:see:`Management::Agent::API::node_dispatch_response`. + ## + ## reqid: the request identifier used in the request event. + ## + ## result: a :zeek:see:`Management::Result` record covering one Zeek + ## cluster node managed by the agent. Upon success, the data field + ## contains a value appropriate for the requested dispatch. + global node_dispatch_response: event(reqid: string, result: Management::Result); + + # Notification events, node -> agent ## The cluster nodes send this event upon peering as a "check-in" to diff --git a/scripts/policy/frameworks/management/node/main.zeek b/scripts/policy/frameworks/management/node/main.zeek index 92d41acfbe..68749c11b5 100644 --- a/scripts/policy/frameworks/management/node/main.zeek +++ b/scripts/policy/frameworks/management/node/main.zeek @@ -1,10 +1,12 @@ -##! This module provides Management framework functionality that needs to be -##! present in every cluster node to allow Management agents to interact with -##! the cluster nodes they manage. +##! This module provides Management framework functionality present in every +##! cluster node, to allowing Management agents to interact with the nodes. + +@load base/frameworks/cluster @load policy/frameworks/management/agent/config @load policy/frameworks/management/log +@load ./api @load ./config module Management::Node; @@ -12,6 +14,47 @@ module Management::Node; # Tag our logs correctly redef Management::Log::role = Management::NODE; +## The type of dispatch callbacks. These implement a particular dispatch action, +## using the provided string vector as arguments, filling results into the +## provided result record. +type DispatchCallback: function(args: vector of string, res: Management::Result); + +global g_dispatch_table: table[string] of DispatchCallback = { +}; + +event Management::Node::API::node_dispatch_request(reqid: string, action: vector of string) + { + Management::Log::info(fmt("rx Management::Node::API::node_dispatch_request %s %s", reqid, action)); + + local res = Management::Result( + $reqid = reqid, $node = Cluster::node); + + if ( |action| == 0 ) + { + res$success = F; + res$error = "no dispatch arguments provided"; + } + else if ( action[0] !in g_dispatch_table ) + { + res$success = F; + res$error = fmt("dispatch %s unknown", action[0]); + } + + if ( ! res$success ) + { + Management::Log::info(fmt("tx Management::Node::API::node_dispatch_response %s", + Management::result_to_string(res))); + event Management::Node::API::node_dispatch_response(reqid, res); + return; + } + + g_dispatch_table[action[0]](action[1:], res); + + Management::Log::info(fmt("tx Management::Node::API::node_dispatch_response %s", + Management::result_to_string(res))); + event Management::Node::API::node_dispatch_response(reqid, res); + } + event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) { local epi = Management::Agent::endpoint_info(); @@ -31,6 +74,7 @@ event zeek_init() # Events automatically sent to the Management agent. local events: vector of any = [ + Management::Node::API::node_dispatch_response, Management::Node::API::notify_node_hello ]; From 497b2723d780bf89aa2340f9beed3880ad6589c8 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Tue, 12 Apr 2022 22:01:02 -0700 Subject: [PATCH 151/204] Management framework: add get_id_value dispatch This adds support for retrieving the value of a global identifier from any subset of cluster nodes. It relies on the lookup_ID() BiF to retrieve the val, and to_json() to render the value to an easily parsed string. Ideally we'd send the val directly, but this hits several roadblocks, including the fact that Broker won't serialize arbitrary values. --- .../frameworks/management/agent/api.zeek | 6 +- .../frameworks/management/agent/main.zeek | 4 ++ .../frameworks/management/controller/api.zeek | 25 ++++++++ .../management/controller/main.zeek | 59 ++++++++++++++++++- .../frameworks/management/node/main.zeek | 29 +++++++++ 5 files changed, 121 insertions(+), 2 deletions(-) diff --git a/scripts/policy/frameworks/management/agent/api.zeek b/scripts/policy/frameworks/management/agent/api.zeek index 6607c27144..f29b05e7cc 100644 --- a/scripts/policy/frameworks/management/agent/api.zeek +++ b/scripts/policy/frameworks/management/agent/api.zeek @@ -66,7 +66,11 @@ export { ## The controller sends this to every agent to request a dispatch (the ## execution of a pre-implemented activity) to all cluster nodes. This ## is the generic controller-agent "back-end" implementation of explicit - ## client-controller "front-end" interactions. + ## client-controller "front-end" interactions, including: + ## + ## - :zeek:see:`Management::Controller::API::get_id_value_request`: two + ## arguments, the first being "get_id_value" and the second the name + ## of the ID to look up. ## ## reqid: a request identifier string, echoed in the response event. ## diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index 2dafd0414d..004b874888 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -321,6 +321,10 @@ event Management::Node::API::node_dispatch_response(reqid: string, result: Manag # confirm their type here based on the requested dispatch command. switch req$node_dispatch_state$action[0] { + case "get_id_value": + if ( result?$data ) + result$data = result$data as string; + break; default: Management::Log::error(fmt("unexpected dispatch command %s", req$node_dispatch_state$action[0])); diff --git a/scripts/policy/frameworks/management/controller/api.zeek b/scripts/policy/frameworks/management/controller/api.zeek index 9b374d54f4..e9bdff1893 100644 --- a/scripts/policy/frameworks/management/controller/api.zeek +++ b/scripts/policy/frameworks/management/controller/api.zeek @@ -80,6 +80,31 @@ export { result: Management::ResultVec); + ## zeek-client sends this event to retrieve the current value of a + ## variable in Zeek's global namespace, referenced by the given + ## identifier (i.e., variable name). The controller asks all agents + ## to retrieve this value from each cluster node, accumulates the + ## returned responses, and responds with a get_id_value_response + ## event back to the client. + ## + ## reqid: a request identifier string, echoed in the response event. + ## + ## id: the name of the variable whose value to retrieve. + global get_id_value_request: event(reqid: string, id: string); + + ## Response to a get_id_value_request event. The controller sends this + ## back to the client. + ## + ## reqid: the request identifier used in the request event. + ## + ## result: a :zeek:type:`vector` of :zeek:see:`Management::Result` + ## records. Each record covers one Zeek cluster node. Each record's + ## data field contains a string with the JSON rendering (as produced + ## by :zeek:id:`to_json`, including the error strings it potentially + ## returns). + global get_id_value_response: event(reqid: string, result: Management::ResultVec); + + # Testing events. These don't provide operational value but expose # internal functionality, triggered by test cases. diff --git a/scripts/policy/frameworks/management/controller/main.zeek b/scripts/policy/frameworks/management/controller/main.zeek index d7a292d7f4..2f2ad42ff4 100644 --- a/scripts/policy/frameworks/management/controller/main.zeek +++ b/scripts/policy/frameworks/management/controller/main.zeek @@ -42,7 +42,11 @@ export { ## and report their outcomes. See ## :zeek:see:`Management::Agent::API::node_dispatch_request` and ## :zeek:see:`Management::Agent::API::node_dispatch_response` for the - ## agent/controller interaction. + ## agent/controller interaction, and + ## :zeek:see:`Management::Controller::API::get_id_value_request` and + ## :zeek:see:`Management::Controller::API::get_id_value_response` + ## for an example of a specific API the controller generalizes into + ## a dispatch. type NodeDispatchState: record { ## The dispatched action. The first string is a command, ## any remaining strings its arguments. @@ -598,6 +602,10 @@ event Management::Agent::API::node_dispatch_response(reqid: string, results: Man # type "any": confirm their (known) type here. switch req$node_dispatch_state$action[0] { + case "get_id_value": + if ( results[i]?$data ) + results[i]$data = results[i]$data as string; + break; default: Management::Log::error(fmt("unexpected dispatch command %s", req$node_dispatch_state$action[0])); @@ -620,6 +628,12 @@ event Management::Agent::API::node_dispatch_response(reqid: string, results: Man # Send response event to the client based upon the dispatch type. switch req$node_dispatch_state$action[0] { + case "get_id_value": + Management::Log::info(fmt( + "tx Management::Controller::API::get_id_value_response %s", + Management::Request::to_string(req))); + event Management::Controller::API::get_id_value_response(req$id, req$results); + break; default: Management::Log::error(fmt("unexpected dispatch command %s", req$node_dispatch_state$action[0])); @@ -629,6 +643,42 @@ event Management::Agent::API::node_dispatch_response(reqid: string, results: Man Management::Request::finish(req$id); } +event Management::Controller::API::get_id_value_request(reqid: string, id: string) + { + Management::Log::info(fmt("rx Management::Controller::API::get_id_value_request %s %s", reqid, id)); + + # Special case: if we have no instances, respond right away. + if ( |g_instances| == 0 ) + { + Management::Log::info(fmt("tx Management::Controller::API::get_id_value_response %s", reqid)); + event Management::Controller::API::get_id_value_response(reqid, vector( + Management::Result($reqid=reqid, $success=F, $error="no instances connected"))); + return; + } + + local action = vector("get_id_value", id); + local req = Management::Request::create(reqid); + req$node_dispatch_state = NodeDispatchState($action=action); + + for ( name in g_instances ) + { + if ( name !in g_instances_ready ) + next; + + local agent_topic = Management::Agent::topic_prefix + "/" + name; + local areq = Management::Request::create(); + + areq$parent_id = req$id; + add req$node_dispatch_state$requests[areq$id]; + + Management::Log::info(fmt( + "tx Management::Agent::API::node_dispatch_request %s %s to %s", + areq$id, action, name)); + + Broker::publish(agent_topic, Management::Agent::API::node_dispatch_request, areq$id, action); + } + } + event Management::Request::request_expired(req: Management::Request::Request) { # Various handlers for timed-out request state. We use the state members @@ -665,6 +715,12 @@ event Management::Request::request_expired(req: Management::Request::Request) switch req$node_dispatch_state$action[0] { + case "get_id_value": + Management::Log::info(fmt( + "tx Management::Controller::API::get_id_value_response %s", + Management::Request::to_string(req))); + event Management::Controller::API::get_id_value_response(req$id, req$results); + break; default: Management::Log::error(fmt("unexpected dispatch command %s", req$node_dispatch_state$action[0])); @@ -717,6 +773,7 @@ event zeek_init() Management::Controller::API::get_instances_response, Management::Controller::API::set_configuration_response, Management::Controller::API::get_nodes_response, + Management::Controller::API::get_id_value_response, Management::Controller::API::test_timeout_response ]; diff --git a/scripts/policy/frameworks/management/node/main.zeek b/scripts/policy/frameworks/management/node/main.zeek index 68749c11b5..7bc321c869 100644 --- a/scripts/policy/frameworks/management/node/main.zeek +++ b/scripts/policy/frameworks/management/node/main.zeek @@ -19,7 +19,36 @@ redef Management::Log::role = Management::NODE; ## provided result record. type DispatchCallback: function(args: vector of string, res: Management::Result); +## Implementation of the "get_id_value" dispatch. Its only argument is the name +## of the ID to look up. +function dispatch_get_id_value(args: vector of string, res: Management::Result) + { + if ( |args| == 0 ) + { + res$success = F; + res$error = "get_id_value expects name of global identifier"; + return; + } + + local val = lookup_ID(args[0]); + + # The following lookup_ID() result strings indicate errors: + if ( type_name(val) == "string" ) + { + local valstr: string = val; + if ( valstr == "" || valstr == "" ) + { + res$success = F; + res$error = valstr[1:-1]; + } + } + + if ( res$success ) + res$data = to_json(val); + } + global g_dispatch_table: table[string] of DispatchCallback = { + ["get_id_value"] = dispatch_get_id_value, }; event Management::Node::API::node_dispatch_request(reqid: string, action: vector of string) From fcef7f4925c0c6eb893af3bba7b9e9ac11d7a9f3 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 15 Apr 2022 18:27:26 -0700 Subject: [PATCH 152/204] Management framework: improve handling of node run states When agents receive a configuration, we don't currently honor requested run states (there's no such thing as registering a node but not running it, for example). To reflect this, we now start off nodes in state PENDING as we launch them via the Supervisor, and move them to RUNNING when they check in with us via Management::Node::API::notify_node_hello. --- .../frameworks/management/agent/main.zeek | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index 004b874888..7771e7bdf5 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -132,11 +132,10 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M for ( nodename in g_nodes ) supervisor_destroy(nodename); - g_nodes = table(); - # Refresh the cluster and nodes tables - + g_nodes = table(); g_cluster = table(); + for ( node in config$nodes ) { if ( node$instance == Management::Agent::name ) @@ -166,6 +165,8 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M for ( nodename in g_nodes ) { node = g_nodes[nodename]; + node$state = Management::PENDING; + nc = Supervisor::NodeConfig($name=nodename); if ( Management::Agent::cluster_directory != "" ) @@ -237,6 +238,11 @@ event SupervisorControl::status_response(reqid: string, result: Supervisor::Stat { cns$cluster_role = sns$node$cluster[node]$role; + # For cluster nodes, copy run state from g_nodes, our + # live node status table. + if ( node in g_nodes ) + cns$state = g_nodes[node]$state; + # The supervisor's responses use 0/tcp (not 0/unknown) # when indicating an unused port because its internal # serialization always assumes TCP. @@ -251,12 +257,22 @@ event SupervisorControl::status_response(reqid: string, result: Supervisor::Stat if ( role == "CONTROLLER" ) { cns$mgmt_role = Management::CONTROLLER; + + # Automatically declare the controller in running state + # here -- we'd not have received a request that brought + # us here otherwise. + cns$state = Management::RUNNING; + # The controller always listens, so the Zeek client can connect. cns$p = Management::Agent::endpoint_info()$network$bound_port; } else if ( role == "AGENT" ) { cns$mgmt_role = Management::AGENT; + + # Similarly to above, always declare agent running. We are. :) + cns$state = Management::RUNNING; + # If we have a controller address, the agent connects to it # and does not listen. See zeek_init() below for similar logic. if ( Management::Agent::controller$address == "0.0.0.0" ) @@ -268,13 +284,9 @@ event SupervisorControl::status_response(reqid: string, result: Supervisor::Stat } } - # A PID is available if a supervised node has fully launched - # and is therefore running. + # A PID is available if a supervised node has fully launched. if ( sns?$pid ) - { cns$pid = sns$pid; - cns$state = Management::RUNNING; - } node_statuses += cns; } @@ -409,6 +421,14 @@ event Management::Agent::API::agent_standby_request(reqid: string) event Management::Agent::API::agent_standby_response(reqid, res); } +event Management::Node::API::notify_node_hello(node: string) + { + Management::Log::info(fmt("rx Management::Node::API::notify_node_hello %s", node)); + + if ( node in g_nodes ) + g_nodes[node]$state = Management::RUNNING; + } + event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) { # This does not (cannot?) immediately verify that the new peer From 76ff976e83ba270146b9c806dccace72cc3bdad6 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 11 Apr 2022 22:09:04 -0700 Subject: [PATCH 153/204] Avoid whitespace around function type strings in JSON rendering Callable types were rendered with a trailing "\n" in to_json() output. Tweaking the Describe() calls to stop producing the newline is prone to test failures, so this focuses on the JSON string production to suppress it, which doesn't affect any tests. --- src/Val.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Val.cc b/src/Val.cc index 3d3290a200..1d0055f71b 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -420,8 +420,9 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val* } rapidjson::Value j; + auto tag = val->GetType()->Tag(); - switch ( val->GetType()->Tag() ) + switch ( tag ) { case TYPE_BOOL: writer.Bool(val->AsBool()); @@ -475,8 +476,15 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val* ODesc d; d.SetStyle(RAW_STYLE); val->Describe(&d); - writer.String(util::json_escape_utf8( - std::string(reinterpret_cast(d.Bytes()), d.Len()))); + std::string desc(reinterpret_cast(d.Bytes()), d.Len()); + + // None of our function types should have surrounding + // whitespace, but ODesc might produce it due to its + // many output modes and flags. Strip it. + if ( tag == TYPE_FUNC ) + desc = util::strstrip(desc); + + writer.String(util::json_escape_utf8(desc)); break; } From 323b919eefccd156a4afa91b91b1ccd317e91334 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Sat, 16 Apr 2022 16:17:57 -0700 Subject: [PATCH 154/204] state-holding fix: track unique identifiers for Func's in CompHash's, not Func's themselves --- src/CompHash.cc | 33 ++++++++++++++++++++++++++++++--- src/CompHash.h | 14 +++++++++++++- src/Func.cc | 15 --------------- src/Func.h | 14 ++------------ 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/CompHash.cc b/src/CompHash.cc index 56b626fa7f..e4ab1c536f 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -260,13 +260,16 @@ bool CompositeHash::RecoverOneVal(const HashKey& hk, Type* t, ValPtr* pval, bool { uint32_t id; hk.Read("func", id); - const auto& f = Func::GetFuncPtrByID(id); - if ( ! f ) + ASSERT(func_id_to_func != nullptr); + + if ( id >= func_id_to_func->size() ) reporter->InternalError("failed to look up unique function id %" PRIu32 " in CompositeHash::RecoverOneVal()", id); + const auto& f = func_id_to_func->at(id); + *pval = make_intrusive(f); const auto& pvt = (*pval)->GetType(); @@ -547,7 +550,31 @@ bool CompositeHash::SingleValHash(HashKey& hk, const Val* v, Type* bt, bool type switch ( v->GetType()->Tag() ) { case TYPE_FUNC: - hk.Write("func", v->AsFunc()->GetUniqueFuncID()); + { + auto f = v->AsFunc(); + + if ( ! func_to_func_id ) + const_cast(this)->BuildFuncMappings(); + + auto id_mapping = func_to_func_id->find(f); + uint32_t id; + + if ( id_mapping == func_to_func_id->end() ) + { + // We need the pointer to stick around + // for our lifetime, so we have to get + // a non-const version we can ref. + FuncPtr fptr = {NewRef{}, const_cast(f)}; + + id = func_id_to_func->size(); + func_id_to_func->push_back(std::move(fptr)); + func_to_func_id->insert_or_assign(f, id); + } + else + id = id_mapping->second; + + hk.Write("func", id); + } break; case TYPE_PATTERN: diff --git a/src/CompHash.h b/src/CompHash.h index cbbefe5a02..da51dc6116 100644 --- a/src/CompHash.h +++ b/src/CompHash.h @@ -4,7 +4,7 @@ #include -#include "zeek/IntrusivePtr.h" +#include "zeek/Func.h" #include "zeek/Type.h" namespace zeek @@ -61,6 +61,18 @@ protected: bool EnsureTypeReserve(HashKey& hk, const Val* v, Type* bt, bool type_check) const; + // The following are for allowing hashing of function values. + // These can occur, for example, in sets of predicates that get + // iterated over. We use pointers in order to keep storage + // lower for the common case of these not being needed. + std::unique_ptr> func_to_func_id; + std::unique_ptr> func_id_to_func; + void BuildFuncMappings() + { + func_to_func_id = std::make_unique>(); + func_id_to_func = std::make_unique>(); + } + TypeListPtr type; bool is_singleton = false; // if just one type in index }; diff --git a/src/Func.cc b/src/Func.cc index 992acc9e0e..600c9aaabd 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -133,20 +133,6 @@ std::string render_call_stack() return rval; } -Func::Func() - { - unique_id = unique_ids.size(); - unique_ids.push_back({NewRef{}, this}); - } - -Func::Func(Kind arg_kind) : kind(arg_kind) - { - unique_id = unique_ids.size(); - unique_ids.push_back({NewRef{}, this}); - } - -Func::~Func() = default; - void Func::AddBody(detail::StmtPtr /* new_body */, const std::vector& /* new_inits */, size_t /* new_frame_size */, int /* priority */) @@ -238,7 +224,6 @@ void Func::CopyStateInto(Func* other) const other->type = type; other->name = name; - other->unique_id = unique_id; } void Func::CheckPluginResult(bool handled, const ValPtr& hook_result, FunctionFlavor flavor) const diff --git a/src/Func.h b/src/Func.h index 9c9b1c0e97..7d89f88609 100644 --- a/src/Func.h +++ b/src/Func.h @@ -61,9 +61,7 @@ public: BUILTIN_FUNC }; - explicit Func(Kind arg_kind); - - ~Func() override; + explicit Func(Kind arg_kind) : kind(arg_kind) { } virtual bool IsPure() const = 0; FunctionFlavor Flavor() const { return GetType()->Flavor(); } @@ -122,14 +120,8 @@ public: virtual detail::TraversalCode Traverse(detail::TraversalCallback* cb) const; - uint32_t GetUniqueFuncID() const { return unique_id; } - static const FuncPtr& GetFuncPtrByID(uint32_t id) - { - return id >= unique_ids.size() ? Func::nil : unique_ids[id]; - } - protected: - Func(); + Func() = default; // Copies this function's state into other. void CopyStateInto(Func* other) const; @@ -140,10 +132,8 @@ protected: std::vector bodies; detail::ScopePtr scope; Kind kind = SCRIPT_FUNC; - uint32_t unique_id = 0; FuncTypePtr type; std::string name; - static inline std::vector unique_ids; }; namespace detail From 748db5cf735b84b2b79a27d31b28064cc32add5b Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 23 Mar 2022 16:55:21 -0700 Subject: [PATCH 155/204] Management framework: bump zeek-client to pull in get-id-value command --- auxil/zeek-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeek-client b/auxil/zeek-client index c2af7381c5..cef49bc607 160000 --- a/auxil/zeek-client +++ b/auxil/zeek-client @@ -1 +1 @@ -Subproject commit c2af7381c584b6545517843872747598bb0e25d5 +Subproject commit cef49bc607025306f4017816b350b8c833aaa753 From 438cd9b9f7bf8aedfa0d179c721ce9d5af63eefe Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 11 Apr 2022 22:18:56 -0700 Subject: [PATCH 156/204] Management framework: minor tweaks to logging component Use an enum with explicitly assigned values since we rely on enum_to_int() to reason about log levels, and bump the default level from DEBUG to INFO. --- scripts/policy/frameworks/management/log.zeek | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/policy/frameworks/management/log.zeek b/scripts/policy/frameworks/management/log.zeek index 7d3b565b32..e8732df1bc 100644 --- a/scripts/policy/frameworks/management/log.zeek +++ b/scripts/policy/frameworks/management/log.zeek @@ -16,10 +16,10 @@ export { ## The controller/agent log supports four different log levels. type Level: enum { - DEBUG, - INFO, - WARNING, - ERROR, + DEBUG = 10, + INFO = 20, + WARNING = 30, + ERROR = 40, }; ## The record type containing the column fields of the agent/controller log. @@ -36,8 +36,9 @@ export { message: string; } &log; - ## The log level in use for this node. - global log_level = DEBUG &redef; + ## The log level in use for this node. This is the minimum + ## log level required to produce output. + global log_level = INFO &redef; ## A debug-level log message writer. ## From 7edd1a2651c06d6742774132d8a2a5916e02b873 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Tue, 12 Apr 2022 19:41:03 -0700 Subject: [PATCH 157/204] Management framework: allow selecting cluster nodes in get_id_value This adds an optional set of cluster node names to narrow the querying to. It similarly expands the dispatch mechanism, since it likely most sense for any such request to apply only to a subset of nodes. Requests for invalid nodes trigger Response records in error state. --- .../frameworks/management/agent/api.zeek | 7 +- .../frameworks/management/agent/main.zeek | 107 +++++++++++++++--- .../frameworks/management/controller/api.zeek | 7 +- .../management/controller/main.zeek | 53 ++++++++- .../frameworks/management/node/api.zeek | 8 +- .../frameworks/management/node/main.zeek | 13 ++- 6 files changed, 175 insertions(+), 20 deletions(-) diff --git a/scripts/policy/frameworks/management/agent/api.zeek b/scripts/policy/frameworks/management/agent/api.zeek index f29b05e7cc..8ba47ee67d 100644 --- a/scripts/policy/frameworks/management/agent/api.zeek +++ b/scripts/policy/frameworks/management/agent/api.zeek @@ -75,7 +75,12 @@ export { ## reqid: a request identifier string, echoed in the response event. ## ## action: the requested dispatch command, with any arguments. - global node_dispatch_request: event(reqid: string, action: vector of string); + ## + ## nodes: a set of cluster node names (e.g. "worker-01") to retrieve + ## the values from. An empty set, supplied by default, means + ## retrieval from all nodes managed by the agent. + global node_dispatch_request: event(reqid: string, action: vector of string, + nodes: set[string] &default=set()); ## Response to a node_dispatch_request event. Each agent sends this back ## to the controller to report the dispatch outcomes on all nodes managed diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index 7771e7bdf5..f3a8bd2809 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -51,9 +51,9 @@ global g_instances: table[string] of Management::Instance; # A map for the nodes we run on this instance, via this agent. global g_nodes: table[string] of Management::Node; -# The node map employed by the supervisor to describe the cluster -# topology to newly forked nodes. We refresh it when we receive -# new configurations. +# The complete node map employed by the supervisor to describe the cluster +# topology to newly forked nodes. We refresh it when we receive new +# configurations. global g_cluster: table[string] of Supervisor::ClusterEndpoint; @@ -311,7 +311,11 @@ event Management::Agent::API::get_nodes_request(reqid: string) event Management::Node::API::node_dispatch_response(reqid: string, result: Management::Result) { - Management::Log::info(fmt("rx Management::Node::API::node_dispatch_response %s", reqid)); + local node = "unknown node"; + if ( result?$node ) + node = result$node; + + Management::Log::info(fmt("rx Management::Node::API::node_dispatch_response %s from %s", reqid, node)); # Retrieve state for the request we just got a response to local nreq = Management::Request::lookup(reqid); @@ -326,8 +330,17 @@ event Management::Node::API::node_dispatch_response(reqid: string, result: Manag # Mark the responding node as done. Nodes normally fill their own name # into the result; we only double-check for resilience. Nodes failing to # report themselves would eventually lead to request timeout. - if ( result?$node && result$node in req$node_dispatch_state$requests ) - delete req$node_dispatch_state$requests[result$node]; + if ( result?$node ) + { + if ( result$node in req$node_dispatch_state$requests ) + delete req$node_dispatch_state$requests[result$node]; + else + { + # An unknown or duplicate response -- do nothing. + Management::Log::debug(fmt("response %s not expected, ignoring", reqid)); + return; + } + } # The usual special treatment for Broker values that are of type "any": # confirm their type here based on the requested dispatch command. @@ -366,26 +379,94 @@ event Management::Node::API::node_dispatch_response(reqid: string, result: Manag Management::Request::finish(req$id); } -event Management::Agent::API::node_dispatch_request(reqid: string, action: vector of string) +event Management::Agent::API::node_dispatch_request(reqid: string, action: vector of string, nodes: set[string]) { - Management::Log::info(fmt("rx Management::Agent::API::node_dispatch_request %s %s", reqid, action)); + Management::Log::info(fmt("rx Management::Agent::API::node_dispatch_request %s %s %s", reqid, action, nodes)); + + local node: string; + local cluster_nodes: set[string]; + local nodes_final: set[string]; + + for ( node in g_nodes ) + add cluster_nodes[node]; + + # If this request includes cluster nodes to query, check if this agent + # manages any of those nodes. If it doesn't, respond with an empty + # results vector immediately. Note that any globally unknown nodes + # that the client might have requested already got filtered by the + # controller, so we don't need to worry about them here. + + if ( |nodes| > 0 ) + { + nodes_final = nodes & cluster_nodes; + + if ( |nodes_final| == 0 ) + { + Management::Log::info(fmt( + "tx Management::Agent::API::node_dispatch_response %s, no node overlap", + reqid)); + event Management::Agent::API::node_dispatch_response(reqid, vector()); + return; + } + } + else if ( |g_nodes| == 0 ) + { + # Special case: the client did not request specific nodes. If + # we aren't running any nodes, respond right away, since there's + # nothing to dispatch to. + Management::Log::info(fmt( + "tx Management::Agent::API::node_dispatch_response %s, no nodes registered", + reqid)); + event Management::Agent::API::node_dispatch_response(reqid, vector()); + return; + } + else + { + # We send to all known nodes. + nodes_final = cluster_nodes; + } local res: Management::Result; local req = Management::Request::create(reqid); req$node_dispatch_state = NodeDispatchState($action=action); - for ( node in g_nodes ) - add req$node_dispatch_state$requests[node]; + # Build up dispatch state for tracking responses. We only dispatch to + # nodes that are in state RUNNING, as those have confirmed they're ready + # to communicate. For others, establish error state in now. + for ( node in nodes_final ) + { + if ( g_nodes[node]$state == Management::RUNNING ) + add req$node_dispatch_state$requests[node]; + else + { + res = Management::Result($reqid=reqid, $node=node); + res$success = F; + res$error = fmt("cluster node %s not in runnning state", node); + req$results += res; + } + } - # We use a single request record to track all node responses. We know - # when all nodes have responded via the requests set we built up above. + # Corner case: nothing is in state RUNNING. + if ( |req$node_dispatch_state$requests| == 0 ) + { + Management::Log::info(fmt( + "tx Management::Agent::API::node_dispatch_response %s, no nodes running", + reqid)); + event Management::Agent::API::node_dispatch_response(reqid, req$results); + Management::Request::finish(req$id); + return; + } + + # We use a single request record to track all node responses, and a + # single event that Broker publishes to all nodes. We know when all + # nodes have responded by checking the requests set we built up above. local nreq = Management::Request::create(); nreq$parent_id = reqid; Management::Log::info(fmt("tx Management::Node::API::node_dispatch_request %s %s", nreq$id, action)); Broker::publish(Management::Node::node_topic, - Management::Node::API::node_dispatch_request, nreq$id, action); + Management::Node::API::node_dispatch_request, nreq$id, action, nodes); } event Management::Agent::API::agent_welcome_request(reqid: string) diff --git a/scripts/policy/frameworks/management/controller/api.zeek b/scripts/policy/frameworks/management/controller/api.zeek index e9bdff1893..0ce3259a4c 100644 --- a/scripts/policy/frameworks/management/controller/api.zeek +++ b/scripts/policy/frameworks/management/controller/api.zeek @@ -90,7 +90,12 @@ export { ## reqid: a request identifier string, echoed in the response event. ## ## id: the name of the variable whose value to retrieve. - global get_id_value_request: event(reqid: string, id: string); + ## + ## nodes: a set of cluster node names (e.g. "worker-01") to retrieve + ## the values from. An empty set, supplied by default, means + ## retrieval from all current cluster nodes. + global get_id_value_request: event(reqid: string, id: string, + nodes: set[string] &default=set()); ## Response to a get_id_value_request event. The controller sends this ## back to the client. diff --git a/scripts/policy/frameworks/management/controller/main.zeek b/scripts/policy/frameworks/management/controller/main.zeek index 2f2ad42ff4..441e03517c 100644 --- a/scripts/policy/frameworks/management/controller/main.zeek +++ b/scripts/policy/frameworks/management/controller/main.zeek @@ -230,6 +230,17 @@ function is_instance_connectivity_change(inst: Management::Instance): bool return F; } +function filter_config_nodes_by_name(nodes: set[string]): set[string] + { + local res: set[string]; + local cluster_nodes: set[string]; + + for ( node in g_config_current$nodes ) + add cluster_nodes[node$name]; + + return nodes & cluster_nodes; + } + event Management::Controller::API::notify_agents_ready(instances: set[string]) { local insts = Management::Util::set_to_vector(instances); @@ -643,7 +654,7 @@ event Management::Agent::API::node_dispatch_response(reqid: string, results: Man Management::Request::finish(req$id); } -event Management::Controller::API::get_id_value_request(reqid: string, id: string) +event Management::Controller::API::get_id_value_request(reqid: string, id: string, nodes: set[string]) { Management::Log::info(fmt("rx Management::Controller::API::get_id_value_request %s %s", reqid, id)); @@ -660,6 +671,42 @@ event Management::Controller::API::get_id_value_request(reqid: string, id: strin local req = Management::Request::create(reqid); req$node_dispatch_state = NodeDispatchState($action=action); + local nodes_final: set[string]; + local node: string; + local res: Management::Result; + + # Input sanitization: check for any requested nodes that aren't part of + # the current configuration. We send back error results for those and + # don't propagate them to the agents. + if ( |nodes| > 0 ) + { + # Requested nodes that are in the current configuration: + nodes_final = filter_config_nodes_by_name(nodes); + # Requested nodes that are not in current configuration: + local nodes_invalid = nodes - nodes_final; + + # Assemble error results for all invalid nodes + for ( node in nodes_invalid ) + { + res = Management::Result($reqid=reqid, $node=node); + res$success = F; + res$error = "unknown cluster node"; + req$results += res; + } + + # If only invalid nodes got requested, we're now done. + if ( |nodes_final| == 0 ) + { + Management::Log::info(fmt( + "tx Management::Controller::API::get_id_value_response %s", + Management::Request::to_string(req))); + event Management::Controller::API::get_id_value_response(req$id, req$results); + Management::Request::finish(req$id); + return; + } + } + + # Send dispatch requests to all agents, with the final set of nodes for ( name in g_instances ) { if ( name !in g_instances_ready ) @@ -675,7 +722,9 @@ event Management::Controller::API::get_id_value_request(reqid: string, id: strin "tx Management::Agent::API::node_dispatch_request %s %s to %s", areq$id, action, name)); - Broker::publish(agent_topic, Management::Agent::API::node_dispatch_request, areq$id, action); + Broker::publish(agent_topic, + Management::Agent::API::node_dispatch_request, + areq$id, action, nodes_final); } } diff --git a/scripts/policy/frameworks/management/node/api.zeek b/scripts/policy/frameworks/management/node/api.zeek index 85cb010463..f952f312ef 100644 --- a/scripts/policy/frameworks/management/node/api.zeek +++ b/scripts/policy/frameworks/management/node/api.zeek @@ -14,7 +14,13 @@ export { ## reqid: a request identifier string, echoed in the response event. ## ## action: the requested dispatch command, with any arguments. - global node_dispatch_request: event(reqid: string, action: vector of string); + ## + ## nodes: the cluster node names this dispatch targets. An empty set, + ## supplied by default, means it applies to all nodes. Since nodes + ## receive all dispatch requests, they can use any node names provided + ## here to filter themselves out of responding. + global node_dispatch_request: event(reqid: string, action: vector of string, + nodes: set[string] &default=set()); ## Response to a node_dispatch_request event. The nodes send this back ## to the agent. This is the agent-node equivalent of diff --git a/scripts/policy/frameworks/management/node/main.zeek b/scripts/policy/frameworks/management/node/main.zeek index 7bc321c869..cd9819ff3d 100644 --- a/scripts/policy/frameworks/management/node/main.zeek +++ b/scripts/policy/frameworks/management/node/main.zeek @@ -51,9 +51,18 @@ global g_dispatch_table: table[string] of DispatchCallback = { ["get_id_value"] = dispatch_get_id_value, }; -event Management::Node::API::node_dispatch_request(reqid: string, action: vector of string) +event Management::Node::API::node_dispatch_request(reqid: string, action: vector of string, + nodes: set[string]) { - Management::Log::info(fmt("rx Management::Node::API::node_dispatch_request %s %s", reqid, action)); + Management::Log::info(fmt("rx Management::Node::API::node_dispatch_request %s %s %s", reqid, action, nodes)); + + if ( |nodes| > 0 && Cluster::node !in nodes ) + { + Management::Log::debug(fmt( + "dispatch %s not targeting this node (%s !in %s), skipping", + reqid, Cluster::node, nodes)); + return; + } local res = Management::Result( $reqid = reqid, $node = Cluster::node); From e2d0db73a5dc9e3e0a1e5c800cc40146786711e7 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 15 Apr 2022 18:45:22 -0700 Subject: [PATCH 158/204] Management framework: bump external testsuite --- testing/external/commit-hash.zeek-testing-cluster | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/external/commit-hash.zeek-testing-cluster b/testing/external/commit-hash.zeek-testing-cluster index 407428c53f..fd5057b5a2 100644 --- a/testing/external/commit-hash.zeek-testing-cluster +++ b/testing/external/commit-hash.zeek-testing-cluster @@ -1 +1 @@ -3528e248d7d35e102c39c8e8050fc1a6dfa477bf +ed820f196ac5e44e1af4cb35a043337db9898458 From 468f90b99e0df4e5025602b0635c5c695bccd428 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 18 Apr 2022 15:34:58 -0700 Subject: [PATCH 159/204] Disable TSan CI task temporarily while we sort out some intermittent test failures --- .cirrus.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 9f7f1dbc71..1d5531501d 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -301,16 +301,16 @@ ubsan_sanitizer_task: ZEEK_TAILORED_UB_CHECKS: 1 UBSAN_OPTIONS: print_stacktrace=1 -tsan_sanitizer_task: - container: - # Just uses a recent/common distro to run memory error/leak checks. - dockerfile: ci/ubuntu-20.04/Dockerfile - cpu: 4 - # AddressSanitizer uses a lot more memory than a typical config. - memory: 12GB - << : *CI_TEMPLATE - test_fuzzers_script: ./ci/test-fuzzers.sh - env: - CXXFLAGS: -DZEEK_DICT_DEBUG - ZEEK_CI_CONFIGURE_FLAGS: *TSAN_SANITIZER_CONFIG - ZEEK_CI_DISABLE_SCRIPT_PROFILING: 1 +# tsan_sanitizer_task: +# container: +# # Just uses a recent/common distro to run memory error/leak checks. +# dockerfile: ci/ubuntu-20.04/Dockerfile +# cpu: 4 +# # AddressSanitizer uses a lot more memory than a typical config. +# memory: 12GB +# << : *CI_TEMPLATE +# test_fuzzers_script: ./ci/test-fuzzers.sh +# env: +# CXXFLAGS: -DZEEK_DICT_DEBUG +# ZEEK_CI_CONFIGURE_FLAGS: *TSAN_SANITIZER_CONFIG +# ZEEK_CI_DISABLE_SCRIPT_PROFILING: 1 From c22847cbf06331c6f36b025223f8d0525aea1420 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Tue, 19 Apr 2022 00:33:22 +0000 Subject: [PATCH 160/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index bea29e3807..1d16c2a720 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit bea29e38078c6f17462f081c5f13ccf8e25ddc0b +Subproject commit 1d16c2a7203306081bd8aa1d31e3bdfaa18d0739 From ba3b14218389baa37b6e308da31cdfa7b837970c Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 13 Apr 2022 11:45:03 -0700 Subject: [PATCH 161/204] Update libkqueue for Coverity and build warning fixes --- auxil/libkqueue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/libkqueue b/auxil/libkqueue index 67d5a67f7f..374aeb5202 160000 --- a/auxil/libkqueue +++ b/auxil/libkqueue @@ -1 +1 @@ -Subproject commit 67d5a67f7fc3e3e56f129ec72988a9ced3a6cc81 +Subproject commit 374aeb52020e289e8574f059f87a96010d9a46b9 From c6023774a3e8fde1f6800f6732c5f6d968cb55ba Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 20 Apr 2022 17:18:57 -0700 Subject: [PATCH 162/204] Enable vptr undefined behavior check --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 812e9720f2..646aeefeb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,7 +187,7 @@ if ( ZEEK_SANITIZERS ) list(APPEND _check_list "unreachable") # list(APPEND _check_list "unsigned-integer-overflow") # Not truly UB list(APPEND _check_list "vla-bound") - # list(APPEND _check_list "vptr") # TODO: fix associated errors + list(APPEND _check_list "vptr") # Clang complains if this one is defined and the optimizer is set to -O0. We # only set that optimization level if NO_OPTIMIZATIONS is passed, so disable From 8ba60165988706d4aa0c0100b3566055113b2702 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 21 Apr 2022 12:40:48 -0700 Subject: [PATCH 163/204] Suppress progress dots in zkg's output in Docker package-install check These introduced unpredictability in the output, occasionally breaking the test. --- docker/btest/docker/structure_tests.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/btest/docker/structure_tests.sh b/docker/btest/docker/structure_tests.sh index ba20fec05a..17a54aa86d 100644 --- a/docker/btest/docker/structure_tests.sh +++ b/docker/btest/docker/structure_tests.sh @@ -17,7 +17,9 @@ docker run --rm "${TEST_TAG}" btest --version | sed 's/^[0-9].*/XXX/g' docker run --rm "${TEST_TAG}" zkg config # Check that a plugin can be installed. We pick any plugin with minimal deps here. -docker run --rm "${TEST_TAG}" zkg install --force sethhall/domain-tld | sed 's/(.*)/(XXX)/' +docker run --rm "${TEST_TAG}" zkg install --force sethhall/domain-tld | + sed 's/"\.*$/"/' | + sed 's/(.*)/(XXX)/' # Check that the Broker Python module loads docker run --rm "${TEST_TAG}" python3 -c "import broker" From 1691f73b67086d74de47d70c45abc185eae41f47 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Fri, 22 Apr 2022 10:34:35 +0200 Subject: [PATCH 164/204] Fix generate-docs action for running on forks. The generate-docs action previously always required secrets to run so that it could possibly perform a push (if run from a schedule), and to send out an email on failure. Since secrets are unavailable for forks this meant that this action would always fail for PRs from forks. In this patch we use an unauthenticated clone unless running from a schedule. This is fine as for PRs this action would just regenerate the docs to check for errors, but not to actually update them (no push performed). We also change the failure notification step to only execute for scheduled runs. --- .github/workflows/generate-docs.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index ea749a2e62..8c8afc2df4 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -15,10 +15,19 @@ jobs: runs-on: ubuntu-18.04 steps: + # We only perform a push if the action was triggered via a schedule + # event, so we only need to authenticate in that case. Use + # unauthenticated access otherwise so this action can e.g., also run from + # clones. - uses: actions/checkout@v2 + if: github.event_name == 'schedule' with: submodules: "recursive" token: ${{ secrets.ZEEK_BOT_TOKEN }} + - uses: actions/checkout@v2 + if: github.event_name != 'schedule' + with: + submodules: "recursive" - name: Switch doc submodule to master run: cd doc && git checkout master @@ -96,7 +105,9 @@ jobs: git diff-index --quiet HEAD || { git commit -m 'Update doc submodule [nomail] [skip ci]' && git push; } - name: Send email - if: failure() + # Only send notifications for scheduled runs. Runs from pull requests + # show failures in the Github UI. + if: failure() && github.event_name == 'schedule' uses: dawidd6/action-send-mail@v3.4.1 with: server_address: ${{secrets.SMTP_HOST}} From f588cef65e825a6dd42d76f731a47a963fe43cd4 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 17 Nov 2021 10:25:36 -0700 Subject: [PATCH 165/204] Add DNS fuzzer --- src/fuzzers/CMakeLists.txt | 1 + src/fuzzers/dns-fuzzer.cc | 63 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/fuzzers/dns-fuzzer.cc diff --git a/src/fuzzers/CMakeLists.txt b/src/fuzzers/CMakeLists.txt index ac8b6ca345..0b23958b3a 100644 --- a/src/fuzzers/CMakeLists.txt +++ b/src/fuzzers/CMakeLists.txt @@ -78,5 +78,6 @@ target_link_libraries(zeek_fuzzer_shared ${zeek_fuzzer_shared_deps} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) +add_fuzz_target(dns) add_fuzz_target(pop3) add_fuzz_target(packet) diff --git a/src/fuzzers/dns-fuzzer.cc b/src/fuzzers/dns-fuzzer.cc new file mode 100644 index 0000000000..c87781ea14 --- /dev/null +++ b/src/fuzzers/dns-fuzzer.cc @@ -0,0 +1,63 @@ +#include + +#include "zeek/Conn.h" +#include "zeek/RunState.h" +#include "zeek/analyzer/Analyzer.h" +#include "zeek/analyzer/Manager.h" +#include "zeek/analyzer/protocol/pia/PIA.h" +#include "zeek/analyzer/protocol/tcp/TCP.h" +#include "zeek/fuzzers/FuzzBuffer.h" +#include "zeek/fuzzers/fuzzer-setup.h" +#include "zeek/packet_analysis/protocol/tcp/TCPSessionAdapter.h" +#include "zeek/session/Manager.h" + +static constexpr auto ZEEK_FUZZ_ANALYZER = "dns"; + +static zeek::Connection* add_connection() + { + static constexpr double network_time_start = 1439471031; + zeek::run_state::detail::update_network_time(network_time_start); + + zeek::Packet p; + zeek::ConnTuple conn_id; + conn_id.src_addr = zeek::IPAddr("1.2.3.4"); + conn_id.dst_addr = zeek::IPAddr("5.6.7.8"); + conn_id.src_port = htons(23132); + conn_id.dst_port = htons(80); + conn_id.is_one_way = false; + conn_id.proto = TRANSPORT_TCP; + zeek::detail::ConnKey key(conn_id); + zeek::Connection* conn = new zeek::Connection(key, network_time_start, &conn_id, 1, &p); + conn->SetTransport(TRANSPORT_TCP); + zeek::session_mgr->Insert(conn); + return conn; + } + +static zeek::analyzer::Analyzer* add_analyzer(zeek::Connection* conn) + { + auto* tcp = new zeek::packet_analysis::TCP::TCPSessionAdapter(conn); + auto* pia = new zeek::analyzer::pia::PIA_TCP(conn); + auto a = zeek::analyzer_mgr->InstantiateAnalyzer(ZEEK_FUZZ_ANALYZER, conn); + tcp->AddChildAnalyzer(a); + tcp->AddChildAnalyzer(pia->AsAnalyzer()); + conn->SetSessionAdapter(tcp, pia); + return a; + } + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) + { + auto conn = add_connection(); + auto a = add_analyzer(conn); + + try + { + a->DeliverPacket(size, data, true, -1, nullptr, size); + } + catch ( const binpac::Exception& e ) + { + } + + zeek::event_mgr.Drain(); + zeek::detail::fuzzer_cleanup_one_input(); + return 0; + } From 93ee353f30e6b0ff3a252e5b1509afb9a68f1009 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 14 Jan 2022 10:21:00 -0700 Subject: [PATCH 166/204] Add const versions of dereference operators for DictEntry --- src/Dict.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Dict.h b/src/Dict.h index 635dc0efed..5f905fcfb0 100644 --- a/src/Dict.h +++ b/src/Dict.h @@ -168,7 +168,9 @@ public: DictIterator& operator=(DictIterator&& that); reference operator*() { return *curr; } + reference operator*() const { return *curr; } pointer operator->() { return curr; } + pointer operator->() const { return curr; } DictIterator& operator++(); DictIterator operator++(int) From 2d43aaf7cc0dfecfb390a3bfc5e12c2a66f63d45 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 2 Feb 2022 18:43:06 +0000 Subject: [PATCH 167/204] Use doctest macro to tie Reporter output to test cases --- src/Reporter.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Reporter.cc b/src/Reporter.cc index 3bbb121208..945041b881 100644 --- a/src/Reporter.cc +++ b/src/Reporter.cc @@ -9,6 +9,7 @@ #include #include +#include "zeek/3rdparty/doctest.h" #include "zeek/Conn.h" #include "zeek/Desc.h" #include "zeek/Event.h" @@ -676,10 +677,14 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Conne } s += buffer; - s += "\n"; - if ( out ) + if ( doctest::is_running_in_test ) + MESSAGE(s); + else + { + s += "\n"; fprintf(out, "%s", s.c_str()); + } } if ( alloced ) From 824bc372c548e8a1a8a6249ef6db9d277939a540 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 19 Apr 2022 12:09:56 -0700 Subject: [PATCH 168/204] Update doc gen VM to ubuntu-latest, output cmake version during configure --- .github/workflows/generate-docs.yml | 4 ++-- configure | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index 8c8afc2df4..6159ddc528 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -12,7 +12,7 @@ defaults: jobs: generate: if: github.repository == 'zeek/zeek' - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: # We only perform a push if the action was triggered via a schedule @@ -60,7 +60,7 @@ jobs: sudo pip3 install -r doc/requirements.txt - name: Configure - run: ./configure + run: ./configure --disable-broker-tests --disable-cpp-tests - name: Build run: cd build && make -j $(nproc) diff --git a/configure b/configure index 80c009bc1a..0565fd1dff 100755 --- a/configure +++ b/configure @@ -442,6 +442,8 @@ echo "Build Directory : $builddir" echo "Source Directory: $sourcedir" cd $builddir +echo "Using $(cmake --version | head -1)" +echo if [ -n "$CMakeGenerator" ]; then "$CMakeCommand" -G "$CMakeGenerator" $CMakeCacheEntries $sourcedir else From e6e9144da6fa5f24602ac0dcdecdfc8bf881429c Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 14 Jan 2022 10:21:26 -0700 Subject: [PATCH 169/204] Add unit testing for DNS_Mgr and related classes --- cmake | 2 +- src/3rdparty | 2 +- src/CMakeLists.txt | 1 + src/DNS_Mapping.cc | 387 ++++++++++++++++++++++++++ src/DNS_Mapping.h | 78 ++++++ src/DNS_Mgr.cc | 663 ++++++++++++++++++++++++++------------------- src/DNS_Mgr.h | 47 +--- src/Val.h | 1 + 8 files changed, 870 insertions(+), 311 deletions(-) create mode 100644 src/DNS_Mapping.cc create mode 100644 src/DNS_Mapping.h diff --git a/cmake b/cmake index b1c9e55d1e..649c319f88 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit b1c9e55d1e837d46fc36312b567245013cf9646a +Subproject commit 649c319f88e2966931892d55adb2ee50f278662b diff --git a/src/3rdparty b/src/3rdparty index 0af190f905..6cbb3d6587 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 0af190f90572abc90366471f36e6feb1b817d2ab +Subproject commit 6cbb3d65877f80326c047364583f506ce58758ba diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63478cc610..f5158bcb50 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -286,6 +286,7 @@ set(MAIN_SRCS Desc.cc Dict.cc Discard.cc + DNS_Mapping.cc DNS_Mgr.cc EquivClass.cc Event.cc diff --git a/src/DNS_Mapping.cc b/src/DNS_Mapping.cc new file mode 100644 index 0000000000..1e98788904 --- /dev/null +++ b/src/DNS_Mapping.cc @@ -0,0 +1,387 @@ +#include "zeek/DNS_Mapping.h" + +#include "zeek/3rdparty/doctest.h" +#include "zeek/DNS_Mgr.h" + +namespace zeek::detail + { + +DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl) + { + Init(h); + req_host = host; + req_ttl = ttl; + + if ( names.empty() ) + names.push_back(host); + } + +DNS_Mapping::DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl) + { + Init(h); + req_addr = addr; + req_ttl = ttl; + } + +DNS_Mapping::DNS_Mapping(FILE* f) + { + Clear(); + init_failed = true; + + req_ttl = 0; + creation_time = 0; + + char buf[512]; + + if ( ! fgets(buf, sizeof(buf), f) ) + { + no_mapping = true; + return; + } + + char req_buf[512 + 1], name_buf[512 + 1]; + int is_req_host; + int failed_local; + int num_addrs; + + if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %" PRIu32, &creation_time, &is_req_host, req_buf, + &failed_local, name_buf, &map_type, &num_addrs, &req_ttl) != 8 ) + return; + + failed = static_cast(failed_local); + + if ( is_req_host ) + req_host = req_buf; + else + req_addr = IPAddr(req_buf); + + names.push_back(name_buf); + + for ( int i = 0; i < num_addrs; ++i ) + { + if ( ! fgets(buf, sizeof(buf), f) ) + return; + + char* newline = strchr(buf, '\n'); + if ( newline ) + *newline = '\0'; + + addrs.emplace_back(IPAddr(buf)); + } + + init_failed = false; + } + +ListValPtr DNS_Mapping::Addrs() + { + if ( failed ) + return nullptr; + + if ( ! addrs_val ) + { + addrs_val = make_intrusive(TYPE_ADDR); + + for ( const auto& addr : addrs ) + addrs_val->Append(make_intrusive(addr)); + } + + return addrs_val; + } + +TableValPtr DNS_Mapping::AddrsSet() + { + auto l = Addrs(); + + if ( ! l || l->Length() == 0 ) + return DNS_Mgr::empty_addr_set(); + + return l->ToSetVal(); + } + +StringValPtr DNS_Mapping::Host() + { + if ( failed || names.empty() ) + return nullptr; + + if ( ! host_val ) + host_val = make_intrusive(names[0]); + + return host_val; + } + +void DNS_Mapping::Init(struct hostent* h) + { + no_mapping = false; + init_failed = false; + creation_time = util::current_time(); + host_val = nullptr; + addrs_val = nullptr; + + if ( ! h ) + { + Clear(); + return; + } + + map_type = h->h_addrtype; + if ( h->h_name ) + // for now, just use the official name + // TODO: this could easily be expanded to include all of the aliases as well + names.push_back(h->h_name); + + for ( int i = 0; h->h_addr_list[i] != NULL; ++i ) + { + if ( h->h_addrtype == AF_INET ) + addrs.push_back(IPAddr(IPv4, (uint32_t*)h->h_addr_list[i], IPAddr::Network)); + else if ( h->h_addrtype == AF_INET6 ) + addrs.push_back(IPAddr(IPv6, (uint32_t*)h->h_addr_list[i], IPAddr::Network)); + } + + failed = false; + } + +void DNS_Mapping::Clear() + { + names.clear(); + host_val = nullptr; + addrs.clear(); + addrs_val = nullptr; + no_mapping = false; + map_type = 0; + failed = true; + } + +void DNS_Mapping::Save(FILE* f) const + { + fprintf(f, "%.0f %d %s %d %s %d %zu %" PRIu32 "\n", creation_time, ! req_host.empty(), + req_host.empty() ? req_addr.AsString().c_str() : req_host.c_str(), failed, + names.empty() ? "*" : names[0].c_str(), map_type, addrs.size(), req_ttl); + + for ( const auto& addr : addrs ) + fprintf(f, "%s\n", addr.AsString().c_str()); + } + +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// + +TEST_CASE("dns_mapping init null hostent") + { + DNS_Mapping mapping("www.apple.com", nullptr, 123); + + CHECK(! mapping.Valid()); + CHECK(mapping.Addrs() == nullptr); + CHECK(mapping.AddrsSet()->EqualTo(DNS_Mgr::empty_addr_set())); + CHECK(mapping.Host() == nullptr); + } + +TEST_CASE("dns_mapping init host") + { + IPAddr addr("1.2.3.4"); + in4_addr in4; + addr.CopyIPv4(&in4); + + struct hostent he; + he.h_name = util::copy_string("testing.home"); + he.h_aliases = NULL; + he.h_addrtype = AF_INET; + he.h_length = sizeof(in_addr); + + std::vector addrs = {&in4, NULL}; + he.h_addr_list = reinterpret_cast(addrs.data()); + + DNS_Mapping mapping("testing.home", &he, 123); + CHECK(mapping.Valid()); + CHECK(mapping.ReqAddr() == IPAddr::v6_unspecified); + CHECK(strcmp(mapping.ReqHost(), "testing.home") == 0); + CHECK(mapping.ReqStr() == "testing.home"); + + auto lva = mapping.Addrs(); + REQUIRE(lva != nullptr); + CHECK(lva->Length() == 1); + auto lvae = lva->Idx(0)->AsAddrVal(); + REQUIRE(lvae != nullptr); + CHECK(lvae->Get().AsString() == "1.2.3.4"); + + auto tvas = mapping.AddrsSet(); + REQUIRE(tvas != nullptr); + CHECK_FALSE(tvas->EqualTo(DNS_Mgr::empty_addr_set())); + + auto svh = mapping.Host(); + REQUIRE(svh != nullptr); + CHECK(svh->ToStdString() == "testing.home"); + + delete[] he.h_name; + } + +TEST_CASE("dns_mapping init addr") + { + IPAddr addr("1.2.3.4"); + in4_addr in4; + addr.CopyIPv4(&in4); + + struct hostent he; + he.h_name = util::copy_string("testing.home"); + he.h_aliases = NULL; + he.h_addrtype = AF_INET; + he.h_length = sizeof(in_addr); + + std::vector addrs = {&in4, NULL}; + he.h_addr_list = reinterpret_cast(addrs.data()); + + DNS_Mapping mapping(addr, &he, 123); + CHECK(mapping.Valid()); + CHECK(mapping.ReqAddr() == addr); + CHECK(mapping.ReqHost() == nullptr); + CHECK(mapping.ReqStr() == "1.2.3.4"); + + auto lva = mapping.Addrs(); + REQUIRE(lva != nullptr); + CHECK(lva->Length() == 1); + auto lvae = lva->Idx(0)->AsAddrVal(); + REQUIRE(lvae != nullptr); + CHECK(lvae->Get().AsString() == "1.2.3.4"); + + auto tvas = mapping.AddrsSet(); + REQUIRE(tvas != nullptr); + CHECK_FALSE(tvas->EqualTo(DNS_Mgr::empty_addr_set())); + + auto svh = mapping.Host(); + REQUIRE(svh != nullptr); + CHECK(svh->ToStdString() == "testing.home"); + + delete[] he.h_name; + } + +TEST_CASE("dns_mapping save reload") + { + IPAddr addr("1.2.3.4"); + in4_addr in4; + addr.CopyIPv4(&in4); + + struct hostent he; + he.h_name = util::copy_string("testing.home"); + he.h_aliases = NULL; + he.h_addrtype = AF_INET; + he.h_length = sizeof(in_addr); + + std::vector addrs = {&in4, NULL}; + he.h_addr_list = reinterpret_cast(addrs.data()); + + // Create a temporary file in memory and fseek to the end of it so we're at + // EOF for the next bit. + char buffer[4096]; + memset(buffer, 0, 4096); + FILE* tmpfile = fmemopen(buffer, 4096, "r+"); + fseek(tmpfile, 0, SEEK_END); + + // Try loading from the file at EOF. This should cause a mapping failure. + DNS_Mapping mapping(tmpfile); + CHECK(mapping.NoMapping()); + rewind(tmpfile); + + // Try reading from the empty file. This should cause an init failure. + DNS_Mapping mapping2(tmpfile); + CHECK(mapping2.InitFailed()); + rewind(tmpfile); + + // Save a valid mapping into the file and rewind to the start. + DNS_Mapping mapping3(addr, &he, 123); + mapping3.Save(tmpfile); + rewind(tmpfile); + + // Test loading the mapping back out of the file + DNS_Mapping mapping4(tmpfile); + fclose(tmpfile); + CHECK(mapping4.Valid()); + CHECK(mapping4.ReqAddr() == addr); + CHECK(mapping4.ReqHost() == nullptr); + CHECK(mapping4.ReqStr() == "1.2.3.4"); + + auto lva = mapping4.Addrs(); + REQUIRE(lva != nullptr); + CHECK(lva->Length() == 1); + auto lvae = lva->Idx(0)->AsAddrVal(); + REQUIRE(lvae != nullptr); + CHECK(lvae->Get().AsString() == "1.2.3.4"); + + auto tvas = mapping4.AddrsSet(); + REQUIRE(tvas != nullptr); + CHECK(tvas != DNS_Mgr::empty_addr_set()); + + auto svh = mapping4.Host(); + REQUIRE(svh != nullptr); + CHECK(svh->ToStdString() == "testing.home"); + + delete[] he.h_name; + } + +TEST_CASE("dns_mapping multiple addresses") + { + IPAddr addr("1.2.3.4"); + in4_addr in4_1; + addr.CopyIPv4(&in4_1); + + IPAddr addr2("5.6.7.8"); + in4_addr in4_2; + addr2.CopyIPv4(&in4_2); + + struct hostent he; + he.h_name = util::copy_string("testing.home"); + he.h_aliases = NULL; + he.h_addrtype = AF_INET; + he.h_length = sizeof(in_addr); + + std::vector addrs = {&in4_1, &in4_2, NULL}; + he.h_addr_list = reinterpret_cast(addrs.data()); + + DNS_Mapping mapping("testing.home", &he, 123); + CHECK(mapping.Valid()); + + auto lva = mapping.Addrs(); + REQUIRE(lva != nullptr); + CHECK(lva->Length() == 2); + + auto lvae = lva->Idx(0)->AsAddrVal(); + REQUIRE(lvae != nullptr); + CHECK(lvae->Get().AsString() == "1.2.3.4"); + + lvae = lva->Idx(1)->AsAddrVal(); + REQUIRE(lvae != nullptr); + CHECK(lvae->Get().AsString() == "5.6.7.8"); + + delete[] he.h_name; + } + +TEST_CASE("dns_mapping ipv6") + { + IPAddr addr("64:ff9b:1::"); + in6_addr in6; + addr.CopyIPv6(&in6); + + struct hostent he; + he.h_name = util::copy_string("testing.home"); + he.h_aliases = NULL; + he.h_addrtype = AF_INET6; + he.h_length = sizeof(in6_addr); + + std::vector addrs = {&in6, NULL}; + he.h_addr_list = reinterpret_cast(addrs.data()); + + DNS_Mapping mapping(addr, &he, 123); + CHECK(mapping.Valid()); + CHECK(mapping.ReqAddr() == addr); + CHECK(mapping.ReqHost() == nullptr); + CHECK(mapping.ReqStr() == "64:ff9b:1::"); + + auto lva = mapping.Addrs(); + REQUIRE(lva != nullptr); + CHECK(lva->Length() == 1); + auto lvae = lva->Idx(0)->AsAddrVal(); + REQUIRE(lvae != nullptr); + CHECK(lvae->Get().AsString() == "64:ff9b:1::"); + + delete[] he.h_name; + } + + } // namespace zeek::detail diff --git a/src/DNS_Mapping.h b/src/DNS_Mapping.h new file mode 100644 index 0000000000..ef56ade2b3 --- /dev/null +++ b/src/DNS_Mapping.h @@ -0,0 +1,78 @@ +#pragma once + +#include +#include +#include +#include + +#include "zeek/IPAddr.h" +#include "zeek/Val.h" + +namespace zeek::detail + { + +class DNS_Mapping + { +public: + DNS_Mapping() = delete; + DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl); + DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl); + DNS_Mapping(FILE* f); + + bool NoMapping() const { return no_mapping; } + bool InitFailed() const { return init_failed; } + + ~DNS_Mapping() = default; + + // Returns nil if this was an address request. + // TODO: fix this an uses of this to just return the empty string + const char* ReqHost() const { return req_host.empty() ? nullptr : req_host.c_str(); } + const IPAddr& ReqAddr() const { return req_addr; } + std::string ReqStr() const { return req_host.empty() ? req_addr.AsString() : req_host; } + + ListValPtr Addrs(); + TableValPtr AddrsSet(); // addresses returned as a set + StringValPtr Host(); + + double CreationTime() const { return creation_time; } + + void Save(FILE* f) const; + + bool Failed() const { return failed; } + bool Valid() const { return ! failed; } + + bool Expired() const + { + if ( ! req_host.empty() && addrs.empty() ) + return false; // nothing to expire + + return util::current_time() > (creation_time + req_ttl); + } + + int Type() const { return map_type; } + +protected: + friend class DNS_Mgr; + + void Init(struct hostent* h); + void Clear(); + + std::string req_host; + IPAddr req_addr; + uint32_t req_ttl = 0; + + // This class supports multiple names per address, but we only store one of them. + std::vector names; + StringValPtr host_val; + + std::vector addrs; + ListValPtr addrs_val; + + double creation_time = 0.0; + int map_type = 0; + bool no_mapping = false; // when initializing from a file, immediately hit EOF + bool init_failed = false; + bool failed = false; + }; + + } // namespace zeek::detail diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 8d776b7351..4b3b4b9201 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -27,7 +27,10 @@ #endif #include #include +#include +#include "zeek/3rdparty/doctest.h" +#include "zeek/DNS_Mapping.h" #include "zeek/Event.h" #include "zeek/Expr.h" #include "zeek/Hash.h" @@ -102,272 +105,6 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns) } } -class DNS_Mapping - { -public: - DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl); - DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl); - DNS_Mapping(FILE* f); - - bool NoMapping() const { return no_mapping; } - bool InitFailed() const { return init_failed; } - - ~DNS_Mapping(); - - // Returns nil if this was an address request. - const char* ReqHost() const { return req_host; } - IPAddr ReqAddr() const { return req_addr; } - string ReqStr() const { return req_host ? req_host : req_addr.AsString(); } - - ListValPtr Addrs(); - TableValPtr AddrsSet(); // addresses returned as a set - StringValPtr Host(); - - double CreationTime() const { return creation_time; } - - void Save(FILE* f) const; - - bool Failed() const { return failed; } - bool Valid() const { return ! failed; } - - bool Expired() const - { - if ( req_host && num_addrs == 0 ) - return false; // nothing to expire - - return util::current_time() > (creation_time + req_ttl); - } - - int Type() const { return map_type; } - -protected: - friend class DNS_Mgr; - - void Init(struct hostent* h); - void Clear(); - - char* req_host; - IPAddr req_addr; - uint32_t req_ttl; - - int num_names; - char** names; - StringValPtr host_val; - - int num_addrs; - IPAddr* addrs; - ListValPtr addrs_val; - - double creation_time; - int map_type; - bool no_mapping; // when initializing from a file, immediately hit EOF - bool init_failed; - bool failed; - }; - -void DNS_Mgr_mapping_delete_func(void* v) - { - delete (DNS_Mapping*)v; - } - -static TableValPtr empty_addr_set() - { - auto addr_t = base_type(TYPE_ADDR); - auto set_index = make_intrusive(addr_t); - set_index->Append(std::move(addr_t)); - auto s = make_intrusive(std::move(set_index), nullptr); - return make_intrusive(std::move(s)); - } - -DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl) - { - Init(h); - req_host = util::copy_string(host); - req_ttl = ttl; - - if ( names && ! names[0] ) - names[0] = util::copy_string(host); - } - -DNS_Mapping::DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl) - { - Init(h); - req_addr = addr; - req_host = nullptr; - req_ttl = ttl; - } - -DNS_Mapping::DNS_Mapping(FILE* f) - { - Clear(); - init_failed = true; - - req_host = nullptr; - req_ttl = 0; - creation_time = 0; - - char buf[512]; - - if ( ! fgets(buf, sizeof(buf), f) ) - { - no_mapping = true; - return; - } - - char req_buf[512 + 1], name_buf[512 + 1]; - int is_req_host; - int failed_local; - - if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %" PRIu32, &creation_time, &is_req_host, req_buf, - &failed_local, name_buf, &map_type, &num_addrs, &req_ttl) != 8 ) - return; - - failed = static_cast(failed_local); - - if ( is_req_host ) - req_host = util::copy_string(req_buf); - else - req_addr = IPAddr(req_buf); - - num_names = 1; - names = new char*[num_names]; - names[0] = util::copy_string(name_buf); - - if ( num_addrs > 0 ) - { - addrs = new IPAddr[num_addrs]; - - for ( int i = 0; i < num_addrs; ++i ) - { - if ( ! fgets(buf, sizeof(buf), f) ) - { - num_addrs = i; - return; - } - - char* newline = strchr(buf, '\n'); - if ( newline ) - *newline = '\0'; - - addrs[i] = IPAddr(buf); - } - } - else - addrs = nullptr; - - init_failed = false; - } - -DNS_Mapping::~DNS_Mapping() - { - delete[] req_host; - - if ( names ) - { - for ( int i = 0; i < num_names; ++i ) - delete[] names[i]; - delete[] names; - } - - delete[] addrs; - } - -ListValPtr DNS_Mapping::Addrs() - { - if ( failed ) - return nullptr; - - if ( ! addrs_val ) - { - addrs_val = make_intrusive(TYPE_ADDR); - - for ( int i = 0; i < num_addrs; ++i ) - addrs_val->Append(make_intrusive(addrs[i])); - } - - return addrs_val; - } - -TableValPtr DNS_Mapping::AddrsSet() - { - auto l = Addrs(); - - if ( ! l ) - return empty_addr_set(); - - return l->ToSetVal(); - } - -StringValPtr DNS_Mapping::Host() - { - if ( failed || num_names == 0 || ! names[0] ) - return nullptr; - - if ( ! host_val ) - host_val = make_intrusive(names[0]); - - return host_val; - } - -void DNS_Mapping::Init(struct hostent* h) - { - no_mapping = false; - init_failed = false; - creation_time = util::current_time(); - host_val = nullptr; - addrs_val = nullptr; - - if ( ! h ) - { - Clear(); - return; - } - - map_type = h->h_addrtype; - num_names = 1; // for now, just use official name - names = new char*[num_names]; - names[0] = h->h_name ? util::copy_string(h->h_name) : nullptr; - - for ( num_addrs = 0; h->h_addr_list[num_addrs]; ++num_addrs ) - ; - - if ( num_addrs > 0 ) - { - addrs = new IPAddr[num_addrs]; - for ( int i = 0; i < num_addrs; ++i ) - if ( h->h_addrtype == AF_INET ) - addrs[i] = IPAddr(IPv4, (uint32_t*)h->h_addr_list[i], IPAddr::Network); - else if ( h->h_addrtype == AF_INET6 ) - addrs[i] = IPAddr(IPv6, (uint32_t*)h->h_addr_list[i], IPAddr::Network); - } - else - addrs = nullptr; - - failed = false; - } - -void DNS_Mapping::Clear() - { - num_names = num_addrs = 0; - names = nullptr; - addrs = nullptr; - host_val = nullptr; - addrs_val = nullptr; - no_mapping = false; - map_type = 0; - failed = true; - } - -void DNS_Mapping::Save(FILE* f) const - { - fprintf(f, "%.0f %d %s %d %s %d %d %" PRIu32 "\n", creation_time, req_host != nullptr, - req_host ? req_host : req_addr.AsString().c_str(), failed, - (names && names[0]) ? names[0] : "*", map_type, num_addrs, req_ttl); - - for ( int i = 0; i < num_addrs; ++i ) - fprintf(f, "%s\n", addrs[i].AsString().c_str()); - } - DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) { did_init = false; @@ -410,6 +147,8 @@ void DNS_Mgr::InitSource() nb_dns = nb_dns_init(err); else { + // nb_dns expects a sockaddr, so copy the address out of the IPAddr + // object into one so it can be passed. struct sockaddr_storage ss = {0}; if ( dns_resolver_addr.GetFamily() == IPv4 ) @@ -430,7 +169,7 @@ void DNS_Mgr::InitSource() if ( nb_dns ) { - if ( ! iosource_mgr->RegisterFd(nb_dns_fd(nb_dns), this) ) + if ( ! doctest::is_running_in_test && ! iosource_mgr->RegisterFd(nb_dns_fd(nb_dns), this) ) reporter->FatalError("Failed to register nb_dns file descriptor with iosource_mgr"); } else @@ -443,10 +182,18 @@ void DNS_Mgr::InitSource() void DNS_Mgr::InitPostScript() { - dm_rec = id::find_type("dns_mapping"); + if ( ! doctest::is_running_in_test ) + { + dm_rec = id::find_type("dns_mapping"); - // Registering will call Init() - iosource_mgr->Register(this, true); + // Registering will call Init() + iosource_mgr->Register(this, true); + } + else + { + // This would normally be called when registering the iosource above. + InitSource(); + } const char* cache_dir = dir ? dir : "."; cache_name = new char[strlen(cache_dir) + 64]; @@ -535,10 +282,16 @@ TableValPtr DNS_Mgr::LookupHost(const char* name) } } -ValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) +StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) { + if ( mode == DNS_FAKE ) + return make_intrusive(fake_addr_lookup_result(addr)); + InitSource(); + if ( ! nb_dns ) + return make_intrusive(""); + if ( mode != DNS_PRIME ) { AddrMap::iterator it = addr_mappings.find(addr); @@ -703,6 +456,9 @@ void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm) ValPtr DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) { + if ( ! dm_rec ) + return nullptr; + auto r = make_intrusive(dm_rec); r->AssignTime(0, dm->CreationTime()); @@ -962,7 +718,7 @@ const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) // The escapes in the following strings are to avoid having it // interpreted as a trigraph sequence. - return d->names ? d->names[0] : "<\?\?\?>"; + return d->names.empty() ? "<\?\?\?>" : d->names[0].c_str(); } TableValPtr DNS_Mgr::LookupNameInCache(const string& name) @@ -977,7 +733,7 @@ TableValPtr DNS_Mgr::LookupNameInCache(const string& name) DNS_Mapping* d4 = it->second.first; DNS_Mapping* d6 = it->second.second; - if ( ! d4 || ! d4->names || ! d6 || ! d6->names ) + if ( ! d4 || d4->names.empty() || ! d6 || d6->names.empty() ) return nullptr; if ( d4->Expired() || d6->Expired() ) @@ -1011,19 +767,27 @@ const char* DNS_Mgr::LookupTextInCache(const string& name) // The escapes in the following strings are to avoid having it // interpreted as a trigraph sequence. - return d->names ? d->names[0] : "<\?\?\?>"; + return d->names.empty() ? "<\?\?\?>" : d->names[0].c_str(); } static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, TableValPtr result) { callback->Resolved(result.get()); - delete callback; + + // Don't delete this if testing because we need it to look at the results of the + // request. It'll get deleted by the test when finished. + if ( ! doctest::is_running_in_test ) + delete callback; } static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, const char* result) { callback->Resolved(result); - delete callback; + + // Don't delete this if testing because we need it to look at the results of the + // request. It'll get deleted by the test when finished. + if ( ! doctest::is_running_in_test ) + delete callback; } void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback) @@ -1445,4 +1209,351 @@ void DNS_Mgr::Terminate() iosource_mgr->UnregisterFd(nb_dns_fd(nb_dns), this); } +void DNS_Mgr::TestProcess() + { + // Only allow usage of this method when running unit tests. + assert(doctest::is_running_in_test); + Process(); + } + +void DNS_Mgr::AsyncRequest::Resolved(const char* name) + { + for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) + { + (*i)->Resolved(name); + if ( ! doctest::is_running_in_test ) + delete *i; + } + + callbacks.clear(); + processed = true; + } + +void DNS_Mgr::AsyncRequest::Resolved(TableVal* addrs) + { + for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) + { + (*i)->Resolved(addrs); + if ( ! doctest::is_running_in_test ) + delete *i; + } + + callbacks.clear(); + processed = true; + } + +void DNS_Mgr::AsyncRequest::Timeout() + { + for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) + { + (*i)->Timeout(); + if ( ! doctest::is_running_in_test ) + delete *i; + } + + callbacks.clear(); + processed = true; + } + +TableValPtr DNS_Mgr::empty_addr_set() + { + auto addr_t = base_type(TYPE_ADDR); + auto set_index = make_intrusive(addr_t); + set_index->Append(std::move(addr_t)); + auto s = make_intrusive(std::move(set_index), nullptr); + return make_intrusive(std::move(s)); + } + +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// + +static std::vector get_result_addresses(TableVal* addrs) + { + std::vector results; + + auto m = addrs->ToMap(); + for ( const auto& [k, v] : m ) + { + auto lv = cast_intrusive(k); + auto lvv = lv->Vals(); + for ( const auto& addr : lvv ) + { + auto addr_ptr = cast_intrusive(addr); + results.push_back(addr_ptr->Get()); + } + } + + return results; + } + +class TestCallback : public DNS_Mgr::LookupCallback + { +public: + TestCallback() { } + void Resolved(const char* name) override + { + host_result = name; + done = true; + } + void Resolved(TableVal* addrs) override + { + addr_results = get_result_addresses(addrs); + done = true; + } + void Timeout() override + { + timeout = true; + done = true; + } + + std::string host_result; + std::vector addr_results; + bool done = false; + bool timeout = false; + }; + +TEST_CASE("dns_mgr prime,save,load") + { + char prefix[] = "/tmp/zeek-unit-test-XXXXXX"; + auto tmpdir = mkdtemp(prefix); + + // Create a manager to prime the cache, make a few requests, and the save + // the result. This tests that the priming code will create the requests but + // wait for Resolve() to actually make the requests. + DNS_Mgr mgr(DNS_PRIME); + mgr.SetDir(tmpdir); + mgr.InitPostScript(); + + auto host_result = mgr.LookupHost("one.one.one.one"); + REQUIRE(host_result != nullptr); + CHECK(host_result->EqualTo(DNS_Mgr::empty_addr_set())); + + IPAddr ones("1.1.1.1"); + auto addr_result = mgr.LookupAddr(ones); + CHECK(strcmp(addr_result->CheckString(), "") == 0); + + mgr.Verify(); + mgr.Resolve(); + + // Save off the resulting values from Resolve() into a file on disk + // in the tmpdir created by mkdtemp. + REQUIRE(mgr.Save()); + + // Make a second DNS manager and reload the cache that we just saved. + DNS_Mgr mgr2(DNS_FORCE); + mgr2.SetDir(tmpdir); + mgr2.InitPostScript(); + + // Make the same two requests, but verify that we're correctly getting + // data out of the cache. + host_result = mgr2.LookupHost("one.one.one.one"); + REQUIRE(host_result != nullptr); + CHECK_FALSE(host_result->EqualTo(DNS_Mgr::empty_addr_set())); + + addr_result = mgr2.LookupAddr(ones); + REQUIRE(addr_result != nullptr); + CHECK(strcmp(addr_result->CheckString(), "one.one.one.one") == 0); + } + +TEST_CASE("dns_mgr alternate server") + { + char* old_server = getenv("ZEEK_DNS_RESOLVER"); + + setenv("ZEEK_DNS_RESOLVER", "1.1.1.1", 1); + DNS_Mgr mgr(DNS_DEFAULT); + mgr.InitPostScript(); + + auto result = mgr.LookupAddr("1.1.1.1"); + REQUIRE(result != nullptr); + CHECK(strcmp(result->CheckString(), "one.one.one.one") == 0); + + // FIXME: This won't run on systems without IPv6 connectivity. + // setenv("ZEEK_DNS_RESOLVER", "2606:4700:4700::1111", 1); + // DNS_Mgr mgr2(DNS_DEFAULT, true); + // mgr2.InitPostScript(); + // result = mgr2.LookupAddr("1.1.1.1"); + // mgr2.Verify(); + // mgr2.Resolve(); + + // result = mgr2.LookupAddr("1.1.1.1"); + // CHECK(strcmp(result->CheckString(), "one.one.one.one") == 0); + + if ( old_server ) + setenv("ZEEK_DNS_RESOLVER", old_server, 1); + else + unsetenv("ZEEK_DNS_RESOLVER"); + } + +TEST_CASE("dns_mgr default mode") + { + DNS_Mgr mgr(DNS_DEFAULT); + mgr.InitPostScript(); + + IPAddr ones("1.1.1.1"); + auto host_result = mgr.LookupHost("one.one.one.one"); + REQUIRE(host_result != nullptr); + CHECK_FALSE(host_result->EqualTo(DNS_Mgr::empty_addr_set())); + + auto addrs_from_request = get_result_addresses(host_result.get()); + auto it = std::find(addrs_from_request.begin(), addrs_from_request.end(), ones); + CHECK(it != addrs_from_request.end()); + + auto addr_result = mgr.LookupAddr(ones); + REQUIRE(addr_result != nullptr); + CHECK(strcmp(addr_result->CheckString(), "one.one.one.one") == 0); + + IPAddr bad("240.0.0.0"); + addr_result = mgr.LookupAddr(bad); + REQUIRE(addr_result != nullptr); + CHECK(strcmp(addr_result->CheckString(), "240.0.0.0") == 0); + } + +TEST_CASE("dns_mgr async host") + { + DNS_Mgr mgr(DNS_DEFAULT); + mgr.InitPostScript(); + + TestCallback cb{}; + mgr.AsyncLookupName("one.one.one.one", &cb); + + // This shouldn't take any longer than DNS_TIMEOUT+1 seconds, so bound it + // just in case of some failure we're not aware of yet. + int count = 0; + while ( ! cb.done && (count < DNS_TIMEOUT + 1) ) + { + mgr.TestProcess(); + sleep(1); + if ( ! cb.timeout ) + count++; + } + + REQUIRE(count < (DNS_TIMEOUT + 1)); + if ( ! cb.timeout ) + { + REQUIRE_FALSE(cb.addr_results.empty()); + IPAddr ones("1.1.1.1"); + auto it = std::find(cb.addr_results.begin(), cb.addr_results.end(), ones); + CHECK(it != cb.addr_results.end()); + } + + mgr.Flush(); + } + +TEST_CASE("dns_mgr async addr") + { + DNS_Mgr mgr(DNS_DEFAULT); + mgr.InitPostScript(); + + TestCallback cb{}; + mgr.AsyncLookupAddr(IPAddr{"1.1.1.1"}, &cb); + + // This shouldn't take any longer than DNS_TIMEOUT +1 seconds, so bound it + // just in case of some failure we're not aware of yet. + int count = 0; + while ( ! cb.done && (count < DNS_TIMEOUT + 1) ) + { + mgr.TestProcess(); + sleep(1); + if ( ! cb.timeout ) + count++; + } + + REQUIRE(count < (DNS_TIMEOUT + 1)); + if ( ! cb.timeout ) + REQUIRE(cb.host_result == "one.one.one.one"); + + mgr.Flush(); + } + +TEST_CASE("dns_mgr async text") + { + DNS_Mgr mgr(DNS_DEFAULT); + mgr.InitPostScript(); + + TestCallback cb{}; + mgr.AsyncLookupNameText("unittest.zeek.org", &cb); + + // This shouldn't take any longer than DNS_TIMEOUT +1 seconds, so bound it + // just in case of some failure we're not aware of yet. + int count = 0; + while ( ! cb.done && (count < DNS_TIMEOUT + 1) ) + { + mgr.TestProcess(); + sleep(1); + if ( ! cb.timeout ) + count++; + } + + REQUIRE(count < (DNS_TIMEOUT + 1)); + if ( ! cb.timeout ) + REQUIRE(cb.host_result == "testing dns_mgr"); + + mgr.Flush(); + } + +TEST_CASE("dns_mgr timeouts") + { + char* old_server = getenv("ZEEK_DNS_RESOLVER"); + + // This is the address for blackhole.webpagetest.org, which provides a DNS + // server that lets you connect but never returns any responses, always + // resulting in a timeout. + setenv("ZEEK_DNS_RESOLVER", "3.219.212.117", 1); + DNS_Mgr mgr(DNS_DEFAULT); + dns_mgr = &mgr; + + mgr.InitPostScript(); + auto addr_result = mgr.LookupAddr("1.1.1.1"); + REQUIRE(addr_result != nullptr); + CHECK(strcmp(addr_result->CheckString(), "1.1.1.1") == 0); + + auto host_result = mgr.LookupHost("one.one.one.one"); + REQUIRE(host_result != nullptr); + auto addresses = get_result_addresses(host_result.get()); + CHECK(addresses.size() == 0); + + if ( old_server ) + setenv("ZEEK_DNS_RESOLVER", old_server, 1); + else + unsetenv("ZEEK_DNS_RESOLVER"); + } + +TEST_CASE("dns_mgr async timeouts") + { + char* old_server = getenv("ZEEK_DNS_RESOLVER"); + + // This is the address for blackhole.webpagetest.org, which provides a DNS + // server that lets you connect but never returns any responses, always + // resulting in a timeout. + setenv("ZEEK_DNS_RESOLVER", "3.219.212.117", 1); + DNS_Mgr mgr(DNS_DEFAULT); + dns_mgr = &mgr; + mgr.InitPostScript(); + + TestCallback cb{}; + mgr.AsyncLookupNameText("unittest.zeek.org", &cb); + + // This shouldn't take any longer than DNS_TIMEOUT +2 seconds, so bound it + // just in case of some failure we're not aware of yet. + int count = 0; + while ( ! cb.done && (count < DNS_TIMEOUT + 1) ) + { + mgr.TestProcess(); + sleep(1); + if ( ! cb.timeout ) + count++; + } + + REQUIRE(count < (DNS_TIMEOUT + 1)); + CHECK(cb.timeout); + + mgr.Flush(); + + if ( old_server ) + setenv("ZEEK_DNS_RESOLVER", old_server, 1); + else + unsetenv("ZEEK_DNS_RESOLVER"); + } + } // namespace zeek::detail diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index ef9b61db74..a8c4f6f048 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -21,11 +21,13 @@ class RecordType; class Val; class ListVal; class TableVal; +class StringVal; template class IntrusivePtr; using ValPtr = IntrusivePtr; using ListValPtr = IntrusivePtr; using TableValPtr = IntrusivePtr; +using StringValPtr = IntrusivePtr; } // namespace zeek @@ -65,7 +67,7 @@ public: // a set of addr. TableValPtr LookupHost(const char* host); - ValPtr LookupAddr(const IPAddr& addr); + StringValPtr LookupAddr(const IPAddr& addr); // Define the directory where to store the data. void SetDir(const char* arg_dir) { dir = util::copy_string(arg_dir); } @@ -109,6 +111,14 @@ public: void Terminate(); + static TableValPtr empty_addr_set(); + + /** + * This method is used to call the private Process() method during unit testing + * and shouldn't be used otherwise. + */ + void TestProcess(); + protected: friend class LookupCallback; friend class DNS_Mgr_Request; @@ -183,38 +193,9 @@ protected: bool IsAddrReq() const { return name.empty(); } - void Resolved(const char* name) - { - for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) - { - (*i)->Resolved(name); - delete *i; - } - callbacks.clear(); - processed = true; - } - - void Resolved(TableVal* addrs) - { - for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) - { - (*i)->Resolved(addrs); - delete *i; - } - callbacks.clear(); - processed = true; - } - - void Timeout() - { - for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) - { - (*i)->Timeout(); - delete *i; - } - callbacks.clear(); - processed = true; - } + void Resolved(const char* name); + void Resolved(TableVal* addrs); + void Timeout(); }; using AsyncRequestAddrMap = std::map; diff --git a/src/Val.h b/src/Val.h index afa77c8818..b7cae59690 100644 --- a/src/Val.h +++ b/src/Val.h @@ -824,6 +824,7 @@ public: // so errors can arise for compound sets such as sets-of-sets. // See https://github.com/zeek/zeek/issues/151. bool EqualTo(const TableVal& v) const; + bool EqualTo(const TableValPtr& v) const { return EqualTo(*(v.get())); } // Returns true if this set is a subset (not necessarily proper) // of the given set. From 336c6ae5c2dd520961b530e97cdb022f2bd62f4d Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 12 Nov 2021 10:02:51 -0700 Subject: [PATCH 170/204] Replace nb_dns library with C-Ares --- .gitmodules | 3 + CMakeLists.txt | 1 + auxil/c-ares | 1 + cmake | 2 +- src/DNS_Mgr.cc | 600 ++++++++++++++++++++++------------------------ src/DNS_Mgr.h | 155 ++++++++---- src/zeek-setup.cc | 15 +- src/zeek.bif | 6 +- 8 files changed, 423 insertions(+), 360 deletions(-) create mode 160000 auxil/c-ares diff --git a/.gitmodules b/.gitmodules index 980a23e6eb..0c5cccce1a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -52,3 +52,6 @@ [submodule "auxil/gen-zam"] path = auxil/gen-zam url = https://github.com/zeek/gen-zam +[submodule "auxil/c-ares"] + path = auxil/c-ares + url = https://github.com/c-ares/c-ares diff --git a/CMakeLists.txt b/CMakeLists.txt index 646aeefeb4..402a0311a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -480,6 +480,7 @@ include(CheckNameserCompat) include(GetArchitecture) include(RequireCXX17) include(FindKqueue) +include(FindCAres) if ( (OPENSSL_VERSION VERSION_EQUAL "1.1.0") OR (OPENSSL_VERSION VERSION_GREATER "1.1.0") ) set(ZEEK_HAVE_OPENSSL_1_1 true CACHE INTERNAL "" FORCE) diff --git a/auxil/c-ares b/auxil/c-ares new file mode 160000 index 0000000000..2aa086f822 --- /dev/null +++ b/auxil/c-ares @@ -0,0 +1 @@ +Subproject commit 2aa086f822aad5017a6f2061ef656f237a62d0ed diff --git a/cmake b/cmake index 649c319f88..0fa8b3a20c 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 649c319f88e2966931892d55adb2ee50f278662b +Subproject commit 0fa8b3a20ca6d4e32b56cdeee693cb46eec41f5e diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 4b3b4b9201..2e240a3bf2 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -4,31 +4,29 @@ #include "zeek/zeek-config.h" -#include -#include -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - #include #include +#include +#include +#include #include #include #include -#ifdef HAVE_MEMORY_H -#include -#endif -#include #include #include +#ifdef TIME_WITH_SYS_TIME +#include +#include +#elif defined(HAVE_SYS_TIME_H) +#include +#else +#include +#endif + +#include +#include + #include "zeek/3rdparty/doctest.h" #include "zeek/DNS_Mapping.h" #include "zeek/Event.h" @@ -43,65 +41,116 @@ #include "zeek/ZeekString.h" #include "zeek/iosource/Manager.h" -extern "C" - { - extern int select(int, fd_set*, fd_set*, fd_set*, struct timeval*); - -#include - -#include "zeek/3rdparty/nb_dns.h" - } - -using namespace std; +// Number of seconds we'll wait for a reply. +constexpr int DNS_TIMEOUT = 5; namespace zeek::detail { +static void hostbyaddr_callback(void* arg, int status, int timeouts, struct hostent* hostent) + { + printf("host callback\n"); + // TODO: implement this + // TODO: figure out how to get TTL info here + } + +static void addrinfo_callback(void* arg, int status, int timeouts, struct ares_addrinfo* result) + { + printf("addrinfo callback\n"); + + if ( status != ARES_SUCCESS ) + { + // TODO: error or something here, or just give up on it? + ares_freeaddrinfo(result); + return; + } + + // TODO: the existing code doesn't handle hostname aliases at all. Should we? + // TODO: handle IPv6 mode + + std::vector addrs; + for ( ares_addrinfo_node* entry = result->nodes; entry != NULL; entry = entry->ai_next ) + addrs.push_back(&reinterpret_cast(entry->ai_addr)->sin_addr); + + // Push a null on the end so the addr list has a final point during later parsing. + addrs.push_back(NULL); + + struct hostent he; + he.h_name = util::copy_string(result->name); + he.h_aliases = NULL; + he.h_addrtype = AF_INET; + he.h_length = sizeof(in_addr); + he.h_addr_list = reinterpret_cast(addrs.data()); + + auto req = reinterpret_cast(arg); + dns_mgr->AddResult(req, &he, result->nodes[0].ai_ttl); + + delete[] he.h_name; + + ares_freeaddrinfo(result); + } + +static void ares_sock_cb(void* data, int s, int read, int write) + { + printf("Change state fd %d read:%d write:%d\n", s, read, write); + if ( read == 1 ) + iosource_mgr->RegisterFd(s, reinterpret_cast(data)); + else + iosource_mgr->UnregisterFd(s, reinterpret_cast(data)); + } + class DNS_Mgr_Request { public: DNS_Mgr_Request(const char* h, int af, bool is_txt) - : host(util::copy_string(h)), fam(af), qtype(is_txt ? 16 : 0), addr(), request_pending() + : host(util::copy_string(h)), fam(af), qtype(is_txt ? 16 : 0), addr() { } - DNS_Mgr_Request(const IPAddr& a) : host(), fam(), qtype(), addr(a), request_pending() { } + DNS_Mgr_Request(const IPAddr& a) : addr(a) { } ~DNS_Mgr_Request() { delete[] host; } // Returns nil if this was an address request. const char* ReqHost() const { return host; } const IPAddr& ReqAddr() const { return addr; } + int Family() const { return fam; } bool ReqIsTxt() const { return qtype == 16; } - int MakeRequest(nb_dns_info* nb_dns); - int RequestPending() const { return request_pending; } - void RequestDone() { request_pending = 0; } + void MakeRequest(ares_channel channel); + + bool RequestPending() const { return request_pending; } + void RequestDone() { request_pending = false; } protected: - char* host; // if non-nil, this is a host request - int fam; // address family query type for host requests - int qtype; // Query type + char* host = nullptr; // if non-nil, this is a host request + int fam = 0; // address family query type for host requests + int qtype = 0; // Query type IPAddr addr; - int request_pending; + bool request_pending = false; }; -int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns) +void DNS_Mgr_Request::MakeRequest(ares_channel channel) { - if ( ! nb_dns ) - return 0; + request_pending = true; - request_pending = 1; + // TODO: TXT requests? + // TODO: could this use ares_create_query/ares_query instead of the + // ares_get* methods to make it more generic? I think we might need + // to do that for TXT requests. - char err[NB_DNS_ERRSIZE]; if ( host ) - return nb_dns_host_request2(nb_dns, host, fam, qtype, (void*)this, err) >= 0; + { + ares_addrinfo_hints hints = {ARES_AI_CANONNAME, fam, 0, 0}; + ares_getaddrinfo(channel, host, NULL, &hints, addrinfo_callback, this); + } else { const uint32_t* bytes; int len = addr.GetBytes(&bytes); - return nb_dns_addr_request2(nb_dns, (char*)bytes, len == 1 ? AF_INET : AF_INET6, - (void*)this, err) >= 0; + + ares_gethostbyaddr(channel, bytes, len, addr.GetFamily() == IPv4 ? AF_INET : AF_INET6, + hostbyaddr_callback, this); } } @@ -111,22 +160,22 @@ DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) mode = arg_mode; - cache_name = dir = nullptr; - asyncs_pending = 0; num_requests = 0; successful = 0; failed = 0; - nb_dns = nullptr; + ipv6_resolver = false; + + ares_library_init(ARES_LIB_INIT_ALL); } DNS_Mgr::~DNS_Mgr() { - if ( nb_dns ) - nb_dns_finish(nb_dns); + Flush(); - delete[] cache_name; - delete[] dir; + ares_cancel(channel); + ares_destroy(channel); + ares_library_cleanup(); } void DNS_Mgr::InitSource() @@ -134,21 +183,36 @@ void DNS_Mgr::InitSource() if ( did_init ) return; + ares_options options; + int optmask = 0; + + options.flags = ARES_FLAG_STAYOPEN; + optmask |= ARES_OPT_FLAGS; + + options.timeout = DNS_TIMEOUT; + optmask |= ARES_OPT_TIMEOUT; + + options.sock_state_cb = ares_sock_cb; + options.sock_state_cb_data = this; + optmask |= ARES_OPT_SOCK_STATE_CB; + + int status = ares_init_options(&channel, &options, optmask); + if ( status != ARES_SUCCESS ) + reporter->FatalError("Failed to initialize c-ares for DNS resolution: %s", + ares_strerror(status)); + // Note that Init() may be called by way of LookupHost() during the act of // parsing a hostname literal (e.g. google.com), so we can't use a // script-layer option to configure the DNS resolver as it may not be // configured to the user's desired address at the time when we need to to // the lookup. auto dns_resolver = getenv("ZEEK_DNS_RESOLVER"); - auto dns_resolver_addr = dns_resolver ? IPAddr(dns_resolver) : IPAddr(); - char err[NB_DNS_ERRSIZE]; - - if ( dns_resolver_addr == IPAddr() ) - nb_dns = nb_dns_init(err); - else + if ( dns_resolver ) { - // nb_dns expects a sockaddr, so copy the address out of the IPAddr - // object into one so it can be passed. + ares_addr_node servers; + servers.next = nullptr; + + auto dns_resolver_addr = IPAddr(dns_resolver); struct sockaddr_storage ss = {0}; if ( dns_resolver_addr.GetFamily() == IPv4 ) @@ -156,25 +220,21 @@ void DNS_Mgr::InitSource() struct sockaddr_in* sa = (struct sockaddr_in*)&ss; sa->sin_family = AF_INET; dns_resolver_addr.CopyIPv4(&sa->sin_addr); + + servers.family = AF_INET; + memcpy(&(servers.addr.addr4), &sa->sin_addr, sizeof(struct in_addr)); } else { struct sockaddr_in6* sa = (struct sockaddr_in6*)&ss; sa->sin6_family = AF_INET6; dns_resolver_addr.CopyIPv6(&sa->sin6_addr); + + servers.family = AF_INET6; + memcpy(&(servers.addr.addr6), &sa->sin6_addr, sizeof(ares_in6_addr)); } - nb_dns = nb_dns_init2(err, (struct sockaddr*)&ss); - } - - if ( nb_dns ) - { - if ( ! doctest::is_running_in_test && ! iosource_mgr->RegisterFd(nb_dns_fd(nb_dns), this) ) - reporter->FatalError("Failed to register nb_dns file descriptor with iosource_mgr"); - } - else - { - reporter->Warning("problem initializing NB-DNS: %s", err); + ares_set_servers(channel, &servers); } did_init = true; @@ -186,7 +246,7 @@ void DNS_Mgr::InitPostScript() { dm_rec = id::find_type("dns_mapping"); - // Registering will call Init() + // Registering will call InitSource(), which sets up all of the DNS library stuff iosource_mgr->Register(this, true); } else @@ -195,10 +255,10 @@ void DNS_Mgr::InitPostScript() InitSource(); } - const char* cache_dir = dir ? dir : "."; - cache_name = new char[strlen(cache_dir) + 64]; - sprintf(cache_name, "%s/%s", cache_dir, ".zeek-dns-cache"); - LoadCache(fopen(cache_name, "r")); + // Load the DNS cache from disk, if it exists. + std::string cache_dir = dir.empty() ? dir : "."; + cache_name = util::fmt("%s/%s", cache_dir.c_str(), ".zeek-dns-cache"); + LoadCache(cache_name); } static TableValPtr fake_name_lookup_result(const char* name) @@ -229,11 +289,11 @@ TableValPtr DNS_Mgr::LookupHost(const char* name) if ( mode == DNS_FAKE ) return fake_name_lookup_result(name); + // This should have been run already from InitPostScript(), but just run it again just + // in case it hadn't. InitSource(); - if ( ! nb_dns ) - return empty_addr_set(); - + // Check the cache before attempting to look up the name remotely. if ( mode != DNS_PRIME ) { HostMap::iterator it = host_mappings.find(name); @@ -258,23 +318,45 @@ TableValPtr DNS_Mgr::LookupHost(const char* name) } } - // Not found, or priming. + // Not found, or priming. We use ares_getaddrinfo here because we want the TTL value switch ( mode ) { case DNS_PRIME: - requests.push_back(new DNS_Mgr_Request(name, AF_INET, false)); - requests.push_back(new DNS_Mgr_Request(name, AF_INET6, false)); + { + // TODO: not sure we need to do these split like this if we can pass AF_UNSPEC + // in the hints structure. Do we really need the two different request objects? + auto v4 = new DNS_Mgr_Request(name, AF_INET, false); + ares_addrinfo_hints v4_hints = {ARES_AI_CANONNAME, AF_INET, 0, 0}; + ares_getaddrinfo(channel, name, NULL, &v4_hints, addrinfo_callback, v4); + + // TODO: check if ipv6 support is needed if we use AF_UNSPEC above + // auto v6 = new DNS_Mgr_Request(name, AF_INET6, false); + // ares_addrinfo_hints v6_hints = { 0, AF_INET6, 0, 0 }; + // ares_getaddrinfo(channel, name, NULL, &v6_hints, addrinfo_callback, v6); + return empty_addr_set(); + } case DNS_FORCE: reporter->FatalError("can't find DNS entry for %s in cache", name); return nullptr; case DNS_DEFAULT: - requests.push_back(new DNS_Mgr_Request(name, AF_INET, false)); - requests.push_back(new DNS_Mgr_Request(name, AF_INET6, false)); + { + auto v4 = new DNS_Mgr_Request(name, AF_INET, false); + ares_addrinfo_hints v4_hints = {ARES_AI_CANONNAME, AF_INET, 0, 0}; + ares_getaddrinfo(channel, name, NULL, &v4_hints, addrinfo_callback, v4); + + // TODO: check if ipv6 support is needed if we use AF_UNSPEC above + // auto v6 = new DNS_Mgr_Request(name, AF_INET6, false); + // ares_addrinfo_hints v6_hints = { 0, AF_INET6, 0, 0 }; + // ares_getaddrinfo(channel, name, NULL, &v6_hints, addrinfo_callback, v6); + Resolve(); + + // Call LookupHost() a second time to get the newly stored value out of the cache. return LookupHost(name); + } default: reporter->InternalError("bad mode in DNS_Mgr::LookupHost"); @@ -287,11 +369,11 @@ StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) if ( mode == DNS_FAKE ) return make_intrusive(fake_addr_lookup_result(addr)); + // This should have been run already from InitPostScript(), but just run it again just + // in case it hadn't. InitSource(); - if ( ! nb_dns ) - return make_intrusive(""); - + // Check the cache before attempting to look up the name remotely. if ( mode != DNS_PRIME ) { AddrMap::iterator it = addr_mappings.find(addr); @@ -303,28 +385,41 @@ StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) return d->Host(); else { - string s(addr); + std::string s(addr); reporter->Warning("can't resolve IP address: %s", s.c_str()); return make_intrusive(s.c_str()); } } } + const uint32_t* bytes; + int len = addr.GetBytes(&bytes); + // Not found, or priming. switch ( mode ) { case DNS_PRIME: - requests.push_back(new DNS_Mgr_Request(addr)); + { + auto req = new DNS_Mgr_Request(addr); + ares_gethostbyaddr(channel, bytes, len, addr.GetFamily() == IPv4 ? AF_INET : AF_INET6, + hostbyaddr_callback, req); return make_intrusive(""); + } case DNS_FORCE: reporter->FatalError("can't find DNS entry for %s in cache", addr.AsString().c_str()); return nullptr; case DNS_DEFAULT: - requests.push_back(new DNS_Mgr_Request(addr)); + { + auto req = new DNS_Mgr_Request(addr); + ares_gethostbyaddr(channel, bytes, len, addr.GetFamily() == IPv4 ? AF_INET : AF_INET6, + hostbyaddr_callback, req); Resolve(); + + // Call LookupAddr() a second time to get the newly stored value out of the cache. return LookupAddr(addr); + } default: reporter->InternalError("bad mode in DNS_Mgr::LookupAddr"); @@ -332,109 +427,35 @@ StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) } } -void DNS_Mgr::Verify() { } - -#define MAX_PENDING_REQUESTS 20 +constexpr int MAX_PENDING_REQUESTS = 20; void DNS_Mgr::Resolve() { - if ( ! nb_dns ) - return; + int nfds = 0; + struct timeval *tvp, tv; + fd_set read_fds, write_fds; - int i; + tv.tv_sec = DNS_TIMEOUT; + tv.tv_usec = 0; - int first_req = 0; - int num_pending = min(requests.length(), MAX_PENDING_REQUESTS); - int last_req = num_pending - 1; - - // Prime with the initial requests. - for ( i = first_req; i <= last_req; ++i ) - requests[i]->MakeRequest(nb_dns); - - // Start resolving. Each time an answer comes in, we can issue a - // new request, if we have more. - while ( num_pending > 0 ) + for ( int i = 0; i < MAX_PENDING_REQUESTS; i++ ) { - int status = AnswerAvailable(DNS_TIMEOUT); + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + nfds = ares_fds(channel, &read_fds, &write_fds); + if ( nfds == 0 ) + break; - if ( status <= 0 ) - { - // Error or timeout. Process all pending requests as - // unanswered and reprime. - for ( i = first_req; i <= last_req; ++i ) - { - DNS_Mgr_Request* dr = requests[i]; - if ( dr->RequestPending() ) - { - AddResult(dr, nullptr); - dr->RequestDone(); - } - } - - first_req = last_req + 1; - num_pending = min(requests.length() - first_req, MAX_PENDING_REQUESTS); - last_req = first_req + num_pending - 1; - - for ( i = first_req; i <= last_req; ++i ) - requests[i]->MakeRequest(nb_dns); - - continue; - } - - char err[NB_DNS_ERRSIZE]; - struct nb_dns_result r; - status = nb_dns_activity(nb_dns, &r, err); - if ( status < 0 ) - reporter->Warning("NB-DNS error in DNS_Mgr::WaitForReplies (%s)", err); - else if ( status > 0 ) - { - DNS_Mgr_Request* dr = (DNS_Mgr_Request*)r.cookie; - if ( dr->RequestPending() ) - { - AddResult(dr, &r); - dr->RequestDone(); - } - - // Room for another, if we have it. - if ( last_req < requests.length() - 1 ) - { - ++last_req; - requests[last_req]->MakeRequest(nb_dns); - } - else - --num_pending; - } + tvp = ares_timeout(channel, &tv, &tv); + select(nfds, &read_fds, &write_fds, NULL, tvp); + ares_process(channel, &read_fds, &write_fds); } - - // All done with the list of requests. - for ( i = requests.length() - 1; i >= 0; --i ) - delete requests.remove_nth(i); - } - -bool DNS_Mgr::Save() - { - if ( ! cache_name ) - return false; - - FILE* f = fopen(cache_name, "w"); - - if ( ! f ) - return false; - - Save(f, host_mappings); - Save(f, addr_mappings); - // Save(f, text_mappings); // We don't save the TXT mappings (yet?). - - fclose(f); - - return true; } void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm) { if ( ! e ) return; - event_mgr.Enqueue(e, BuildMappingVal(dm)); } @@ -473,14 +494,11 @@ ValPtr DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) return r; } -void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) +void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct hostent* h, uint32_t ttl) { - struct hostent* h = (r && r->host_errno == 0) ? r->hostent : nullptr; - u_int32_t ttl = (r && r->host_errno == 0) ? r->ttl : 0; - DNS_Mapping* new_dm; DNS_Mapping* prev_dm; - int keep_prev = 0; + bool keep_prev = false; if ( dr->ReqHost() ) { @@ -502,7 +520,7 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) { text_mappings[dr->ReqHost()] = prev_dm; - ++keep_prev; + keep_prev = true; } } else @@ -537,7 +555,7 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) else host_mappings[dr->ReqHost()].second = prev_dm; - ++keep_prev; + keep_prev = true; } } } @@ -551,7 +569,7 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r) if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) { addr_mappings[dr->ReqAddr()] = prev_dm; - ++keep_prev; + keep_prev = true; } } @@ -644,11 +662,14 @@ void DNS_Mgr::DumpAddrList(FILE* f, ListVal* al) } } -void DNS_Mgr::LoadCache(FILE* f) +void DNS_Mgr::LoadCache(const std::string& path) { + FILE* f = fopen(path.c_str(), "r"); + if ( ! f ) return; + // Loop until we find a mapping that doesn't initialize correctly. DNS_Mapping* m = new DNS_Mapping(f); for ( ; ! m->NoMapping() && ! m->InitFailed(); m = new DNS_Mapping(f) ) { @@ -677,6 +698,25 @@ void DNS_Mgr::LoadCache(FILE* f) fclose(f); } +bool DNS_Mgr::Save() + { + if ( cache_name.empty() ) + return false; + + FILE* f = fopen(cache_name.c_str(), "w"); + + if ( ! f ) + return false; + + Save(f, host_mappings); + Save(f, addr_mappings); + // Save(f, text_mappings); // We don't save the TXT mappings (yet?). + + fclose(f); + + return true; + } + void DNS_Mgr::Save(FILE* f, const AddrMap& m) { for ( AddrMap::const_iterator it = m.begin(); it != m.end(); ++it ) @@ -688,9 +728,7 @@ void DNS_Mgr::Save(FILE* f, const AddrMap& m) void DNS_Mgr::Save(FILE* f, const HostMap& m) { - HostMap::const_iterator it; - - for ( it = m.begin(); it != m.end(); ++it ) + for ( HostMap::const_iterator it = m.begin(); it != m.end(); ++it ) { if ( it->second.first ) it->second.first->Save(f); @@ -721,7 +759,7 @@ const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) return d->names.empty() ? "<\?\?\?>" : d->names[0].c_str(); } -TableValPtr DNS_Mgr::LookupNameInCache(const string& name) +TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name) { HostMap::iterator it = host_mappings.find(name); if ( it == host_mappings.end() ) @@ -750,7 +788,7 @@ TableValPtr DNS_Mgr::LookupNameInCache(const string& name) return tv6; } -const char* DNS_Mgr::LookupTextInCache(const string& name) +const char* DNS_Mgr::LookupTextInCache(const std::string& name) { TextMap::iterator it = text_mappings.find(name); if ( it == text_mappings.end() ) @@ -792,6 +830,8 @@ static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, const char* res void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback) { + // This should have been run already from InitPostScript(), but just run it again just + // in case it hadn't. InitSource(); if ( mode == DNS_FAKE ) @@ -828,8 +868,10 @@ void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback) IssueAsyncRequests(); } -void DNS_Mgr::AsyncLookupName(const string& name, LookupCallback* callback) +void DNS_Mgr::AsyncLookupName(const std::string& name, LookupCallback* callback) { + // This should have been run already from InitPostScript(), but just run it again just + // in case it hadn't. InitSource(); if ( mode == DNS_FAKE ) @@ -866,8 +908,10 @@ void DNS_Mgr::AsyncLookupName(const string& name, LookupCallback* callback) IssueAsyncRequests(); } -void DNS_Mgr::AsyncLookupNameText(const string& name, LookupCallback* callback) +void DNS_Mgr::AsyncLookupNameText(const std::string& name, LookupCallback* callback) { + // This should have been run already from InitPostScript(), but just run it again just + // in case it hadn't. InitSource(); if ( mode == DNS_FAKE ) @@ -906,51 +950,35 @@ void DNS_Mgr::AsyncLookupNameText(const string& name, LookupCallback* callback) IssueAsyncRequests(); } -static bool DoRequest(nb_dns_info* nb_dns, DNS_Mgr_Request* dr) - { - if ( dr->MakeRequest(nb_dns) ) - // dr stored in nb_dns cookie and deleted later when results available. - return true; - - reporter->Warning("can't issue DNS request"); - delete dr; - return false; - } - void DNS_Mgr::IssueAsyncRequests() { - while ( asyncs_queued.size() && asyncs_pending < MAX_PENDING_REQUESTS ) + while ( ! asyncs_queued.empty() && asyncs_pending < MAX_PENDING_REQUESTS ) { AsyncRequest* req = asyncs_queued.front(); asyncs_queued.pop_front(); ++num_requests; - - bool success; + req->time = util::current_time(); if ( req->IsAddrReq() ) - success = DoRequest(nb_dns, new DNS_Mgr_Request(req->host)); + { + auto* m_req = new DNS_Mgr_Request(req->host); + m_req->MakeRequest(channel); + } else if ( req->is_txt ) - success = DoRequest(nb_dns, - new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt)); + { + auto* m_req = new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt); + m_req->MakeRequest(channel); + } else { // If only one request type succeeds, don't consider it a failure. - success = DoRequest(nb_dns, - new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt)); - success = DoRequest(nb_dns, - new DNS_Mgr_Request(req->name.c_str(), AF_INET6, req->is_txt)) || - success; + auto* m_req4 = new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt); + m_req4->MakeRequest(channel); + auto* m_req6 = new DNS_Mgr_Request(req->name.c_str(), AF_INET6, req->is_txt); + m_req6->MakeRequest(channel); } - if ( ! success ) - { - req->Timeout(); - ++failed; - continue; - } - - req->time = util::current_time(); asyncs_timeouts.push(req); ++asyncs_pending; @@ -1088,10 +1116,7 @@ double DNS_Mgr::GetNextTimeout() void DNS_Mgr::Process() { - if ( ! nb_dns ) - return; - - while ( asyncs_timeouts.size() > 0 ) + while ( ! asyncs_timeouts.empty() ) { AsyncRequest* req = asyncs_timeouts.top(); @@ -1112,88 +1137,51 @@ void DNS_Mgr::Process() delete req; } - if ( AnswerAvailable(0) <= 0 ) - return; + Resolve(); + // TODO: what does the rest below do? + /* char err[NB_DNS_ERRSIZE]; struct nb_dns_result r; int status = nb_dns_activity(nb_dns, &r, err); if ( status < 0 ) - reporter->Warning("NB-DNS error in DNS_Mgr::Process (%s)", err); + reporter->Warning("NB-DNS error in DNS_Mgr::Process (%s)", err); else if ( status > 0 ) - { - DNS_Mgr_Request* dr = (DNS_Mgr_Request*)r.cookie; + { + DNS_Mgr_Request* dr = (DNS_Mgr_Request*)r.cookie; - bool do_host_timeout = true; - if ( dr->ReqHost() && host_mappings.find(dr->ReqHost()) == host_mappings.end() ) - // Don't timeout when this is the first result in an expected pair - // (one result each for A and AAAA queries). - do_host_timeout = false; + bool do_host_timeout = true; + if ( dr->ReqHost() && host_mappings.find(dr->ReqHost()) == host_mappings.end() ) + // Don't timeout when this is the first result in an expected pair + // (one result each for A and AAAA queries). + do_host_timeout = false; - if ( dr->RequestPending() ) - { - AddResult(dr, &r); - dr->RequestDone(); - } + if ( dr->RequestPending() ) + { + AddResult(dr, &r); + dr->RequestDone(); + } - if ( ! dr->ReqHost() ) - CheckAsyncAddrRequest(dr->ReqAddr(), true); - else if ( dr->ReqIsTxt() ) - CheckAsyncTextRequest(dr->ReqHost(), do_host_timeout); - else - CheckAsyncHostRequest(dr->ReqHost(), do_host_timeout); + if ( ! dr->ReqHost() ) + CheckAsyncAddrRequest(dr->ReqAddr(), true); + else if ( dr->ReqIsTxt() ) + CheckAsyncTextRequest(dr->ReqHost(), do_host_timeout); + else + CheckAsyncHostRequest(dr->ReqHost(), do_host_timeout); - IssueAsyncRequests(); + IssueAsyncRequests(); - delete dr; - } - } - -int DNS_Mgr::AnswerAvailable(int timeout) - { - if ( ! nb_dns ) - return -1; - - int fd = nb_dns_fd(nb_dns); - if ( fd < 0 ) - { - reporter->Warning("nb_dns_fd() failed in DNS_Mgr::WaitForReplies"); - return -1; - } - - fd_set read_fds; - - FD_ZERO(&read_fds); - FD_SET(fd, &read_fds); - - struct timeval t; - t.tv_sec = timeout; - t.tv_usec = 0; - - int status = select(fd + 1, &read_fds, 0, 0, &t); - - if ( status < 0 ) - { - if ( errno != EINTR ) - reporter->Warning("problem with DNS select"); - - return -1; - } - - if ( status > 1 ) - { - reporter->Warning("strange return from DNS select"); - return -1; - } - - return status; + delete dr; + } + */ } void DNS_Mgr::GetStats(Stats* stats) { + // TODO: can this use the telemetry framework? stats->requests = num_requests; stats->successful = successful; stats->failed = failed; @@ -1203,12 +1191,6 @@ void DNS_Mgr::GetStats(Stats* stats) stats->cached_texts = text_mappings.size(); } -void DNS_Mgr::Terminate() - { - if ( nb_dns ) - iosource_mgr->UnregisterFd(nb_dns_fd(nb_dns), this); - } - void DNS_Mgr::TestProcess() { // Only allow usage of this method when running unit tests. @@ -1218,11 +1200,11 @@ void DNS_Mgr::TestProcess() void DNS_Mgr::AsyncRequest::Resolved(const char* name) { - for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) + for ( const auto& cb : callbacks ) { - (*i)->Resolved(name); + cb->Resolved(name); if ( ! doctest::is_running_in_test ) - delete *i; + delete cb; } callbacks.clear(); @@ -1231,11 +1213,11 @@ void DNS_Mgr::AsyncRequest::Resolved(const char* name) void DNS_Mgr::AsyncRequest::Resolved(TableVal* addrs) { - for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) + for ( const auto& cb : callbacks ) { - (*i)->Resolved(addrs); + cb->Resolved(addrs); if ( ! doctest::is_running_in_test ) - delete *i; + delete cb; } callbacks.clear(); @@ -1244,11 +1226,11 @@ void DNS_Mgr::AsyncRequest::Resolved(TableVal* addrs) void DNS_Mgr::AsyncRequest::Timeout() { - for ( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) + for ( const auto& cb : callbacks ) { - (*i)->Timeout(); + cb->Timeout(); if ( ! doctest::is_running_in_test ) - delete *i; + delete cb; } callbacks.clear(); @@ -1257,6 +1239,8 @@ void DNS_Mgr::AsyncRequest::Timeout() TableValPtr DNS_Mgr::empty_addr_set() { + // TODO: can this be returned statically as well? Does the result get used in a way + // that would modify the same value being returned repeatedly? auto addr_t = base_type(TYPE_ADDR); auto set_index = make_intrusive(addr_t); set_index->Append(std::move(addr_t)); @@ -1333,7 +1317,6 @@ TEST_CASE("dns_mgr prime,save,load") auto addr_result = mgr.LookupAddr(ones); CHECK(strcmp(addr_result->CheckString(), "") == 0); - mgr.Verify(); mgr.Resolve(); // Save off the resulting values from Resolve() into a file on disk @@ -1373,7 +1356,6 @@ TEST_CASE("dns_mgr alternate server") // DNS_Mgr mgr2(DNS_DEFAULT, true); // mgr2.InitPostScript(); // result = mgr2.LookupAddr("1.1.1.1"); - // mgr2.Verify(); // mgr2.Resolve(); // result = mgr2.LookupAddr("1.1.1.1"); diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index a8c4f6f048..e5bfba9689 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -2,6 +2,7 @@ #pragma once +#include #include #include #include @@ -15,9 +16,6 @@ namespace zeek { - -class EventHandler; -class RecordType; class Val; class ListVal; class TableVal; @@ -31,16 +29,9 @@ using StringValPtr = IntrusivePtr; } // namespace zeek -// Defined in nb_dns.h -struct nb_dns_info; -struct nb_dns_result; - namespace zeek::detail { - class DNS_Mgr_Request; -using DNS_mgr_request_list = PList; - class DNS_Mapping; enum DNS_MgrMode @@ -51,49 +42,111 @@ enum DNS_MgrMode DNS_FAKE, // don't look up names, just return dummy results }; -// Number of seconds we'll wait for a reply. -#define DNS_TIMEOUT 5 - class DNS_Mgr final : public iosource::IOSource { public: explicit DNS_Mgr(DNS_MgrMode mode); ~DNS_Mgr() override; + /** + * Finalizes the manager initialization. This should be called only after all + * of the scripts have been parsed at startup. + */ void InitPostScript(); + + /** + * Attempts to process one more round of requests and then flushes the + * mapping caches. + */ void Flush(); - // Looks up the address or addresses of the given host, and returns - // a set of addr. + /** + * Looks up the address(es) of a given host and returns a set of addr. + * This is a synchronous method and will block until results are ready. + * + * @param host The host name to look up an address for. + * @return A set of addresses. + */ TableValPtr LookupHost(const char* host); + /** + * Looks up the hostname of a given address. This is a synchronous method + * and will block until results are ready. + * + * @param host The addr to lookup a hostname for. + * @return The hostname. + */ StringValPtr LookupAddr(const IPAddr& addr); - // Define the directory where to store the data. - void SetDir(const char* arg_dir) { dir = util::copy_string(arg_dir); } + /** + * Sets the directory where to store DNS data when Save() is called. + */ + void SetDir(const char* arg_dir) { dir = arg_dir; } - void Verify(); + /** + * Waits for responses to become available or a timeout to occur, + * and handles any responses. + */ void Resolve(); + + /** + * Saves the current name and address caches to disk. + */ bool Save(); - const char* LookupAddrInCache(const IPAddr& addr); - TableValPtr LookupNameInCache(const std::string& name); - const char* LookupTextInCache(const std::string& name); - - // Support for async lookups. + /** + * Base class for callback handling for asynchronous lookups. + */ class LookupCallback { public: - LookupCallback() { } - virtual ~LookupCallback() { } + virtual ~LookupCallback() = default; + /** + * Called when an address lookup finishes. + * + * @param name The resulting name from the lookup. + */ virtual void Resolved(const char* name){}; + + /** + * Called when a name lookup finishes. + * + * @param addrs A table of the resulting addresses from the lookup. + */ virtual void Resolved(TableVal* addrs){}; + + /** + * Called when a timeout request occurs. + */ virtual void Timeout() = 0; }; + /** + * Schedules an asynchronous request to lookup a hostname for an IP address. + * This is the equivalent of an "A" or "AAAA" request, depending on if the + * address is ipv4 or ipv6. + * + * @param host The address to lookup names for. + * @param callback A callback object to call when the request completes. + */ void AsyncLookupAddr(const IPAddr& host, LookupCallback* callback); + + /** + * Schedules an asynchronous request to lookup an address for a hostname. + * This is the equivalent of a "PTR" request. + * + * @param host The hostname to look up addresses for. + * @param callback A callback object to call when the request completes. + */ void AsyncLookupName(const std::string& name, LookupCallback* callback); + + /** + * Schedules an asynchronous TXT request for a hostname. + * + * @param host The address to lookup names for. + * @param callback A callback object to call when the request completes. + */ void AsyncLookupNameText(const std::string& name, LookupCallback* callback); struct Stats @@ -107,10 +160,27 @@ public: unsigned long cached_texts; }; + /** + * Returns the current statistics for the DNS_Manager. + * + * @param stats A pointer to a stats object to return the data in. + */ void GetStats(Stats* stats); - void Terminate(); + /** + * Adds a result from a request to the caches. This is public so that the + * callback methods can call it from outside of the DNS_Mgr class. + * + * @param dr The request associated with the result. + * @param h A hostent structure containing the actual result data. + * @param ttl A ttl value contained in the response from the server. + */ + void AddResult(DNS_Mgr_Request* dr, struct hostent* h, uint32_t ttl); + /** + * Returns an empty set of addresses, used in various error cases and during + * cache priming. + */ static TableValPtr empty_addr_set(); /** @@ -123,13 +193,16 @@ protected: friend class LookupCallback; friend class DNS_Mgr_Request; + const char* LookupAddrInCache(const IPAddr& addr); + TableValPtr LookupNameInCache(const std::string& name); + const char* LookupTextInCache(const std::string& name); + void Event(EventHandlerPtr e, DNS_Mapping* dm); void Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2); void Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm); ValPtr BuildMappingVal(DNS_Mapping* dm); - void AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r); void CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm); ListValPtr AddrListDelta(ListVal* al1, ListVal* al2); void DumpAddrList(FILE* f, ListVal* al); @@ -137,15 +210,10 @@ protected: using HostMap = std::map>; using AddrMap = std::map; using TextMap = std::map; - void LoadCache(FILE* f); + void LoadCache(const std::string& path); void Save(FILE* f, const AddrMap& m); void Save(FILE* f, const HostMap& m); - // Selects on the fd to see if there is an answer available (timeout - // is secs). Returns 0 on timeout, -1 on EINTR or other error, and 1 - // if answer is ready. - int AnswerAvailable(int timeout); - // Issue as many queued async requests as slots are available. void IssueAsyncRequests(); @@ -167,29 +235,30 @@ protected: AddrMap addr_mappings; TextMap text_mappings; + using DNS_mgr_request_list = PList; DNS_mgr_request_list requests; - nb_dns_info* nb_dns; - char* cache_name; - char* dir; // directory in which cache_name resides + std::string cache_name; + std::string dir; // directory in which cache_name resides - bool did_init; - int asyncs_pending; + bool did_init = false; + int asyncs_pending = 0; RecordTypePtr dm_rec; + ares_channel channel; + bool ipv6_resolver = false; + using CallbackList = std::list; struct AsyncRequest { - double time; + double time = 0.0; IPAddr host; std::string name; CallbackList callbacks; - bool is_txt; - bool processed; - - AsyncRequest() : time(0.0), is_txt(false), processed(false) { } + bool is_txt = false; + bool processed = false; bool IsAddrReq() const { return name.empty(); } diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 66a23b5aa7..551dd003fc 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -18,6 +18,7 @@ #include "zeek/3rdparty/sqlite3.h" #define DOCTEST_CONFIG_IMPLEMENT + #include "zeek/3rdparty/doctest.h" #include "zeek/Anon.h" #include "zeek/DFA.h" @@ -330,7 +331,6 @@ static void terminate_zeek() input_mgr->Terminate(); thread_mgr->Terminate(); broker_mgr->Terminate(); - dns_mgr->Terminate(); event_mgr.Drain(); @@ -342,6 +342,7 @@ static void terminate_zeek() delete packet_mgr; delete analyzer_mgr; delete file_mgr; + delete dns_mgr; // broker_mgr, timer_mgr, and supervisor are deleted via iosource_mgr delete iosource_mgr; delete event_registry; @@ -460,6 +461,8 @@ SetupResult setup(int argc, char** argv, Options* zopts) if ( dns_type == DNS_DEFAULT && fake_dns() ) dns_type = DNS_FAKE; + dns_mgr = new DNS_Mgr(dns_type); + RETSIGTYPE (*oldhandler)(int); zeek_script_prefixes = options.script_prefixes; @@ -599,8 +602,6 @@ SetupResult setup(int argc, char** argv, Options* zopts) push_scope(nullptr, nullptr); - dns_mgr = new DNS_Mgr(dns_type); - // It would nice if this were configurable. This is similar to the // chicken and the egg problem. It would be configurable by parsing // policy, but we can't parse policy without DNS resolution. @@ -756,6 +757,9 @@ SetupResult setup(int argc, char** argv, Options* zopts) file_mgr->InitPostScript(); dns_mgr->InitPostScript(); + dns_mgr->LookupHost("www.apple.com"); + // dns_mgr->LookupAddr("17.253.144.10"); + #ifdef USE_PERFTOOLS_DEBUG } #endif @@ -859,9 +863,12 @@ SetupResult setup(int argc, char** argv, Options* zopts) if ( (oldhandler = setsignal(SIGHUP, sig_handler)) != SIG_DFL ) (void)setsignal(SIGHUP, oldhandler); + // If we were priming the DNS cache (i.e. -P was passed as an argument), flush anything + // remaining to be resolved and save the cache to disk. We can just exit now because + // we've done everything we need to do. The run loop isn't started in this case, so + // nothing else should be happening. if ( dns_type == DNS_PRIME ) { - dns_mgr->Verify(); dns_mgr->Resolve(); if ( ! dns_mgr->Save() ) diff --git a/src/zeek.bif b/src/zeek.bif index 911a010761..3fd41e0901 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -3657,7 +3657,7 @@ public: } // Overridden from zeek::detail::DNS_Mgr:Lookup:Callback. - virtual void Resolved(const char* name) + void Resolved(const char* name) override { zeek::Val* result = new zeek::StringVal(name); trigger->Cache(call, result); @@ -3665,14 +3665,14 @@ public: trigger->Release(); } - virtual void Resolved(zeek::TableVal* addrs) + void Resolved(zeek::TableVal* addrs) override { // No Ref() for addrs. trigger->Cache(call, addrs); trigger->Release(); } - virtual void Timeout() + void Timeout() override { if ( lookup_name ) { From 9f197aa4582b14a9e5a5073ac5c5342dd3fd61a1 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 11 Jan 2022 17:07:19 -0700 Subject: [PATCH 171/204] Rework DNS_Mgr API to be more consistent and to support more request types --- src/DNS_Mapping.cc | 26 +- src/DNS_Mapping.h | 3 +- src/DNS_Mgr.cc | 1347 ++++++++++++++++++++++++-------------------- src/DNS_Mgr.h | 245 ++++---- src/zeek-setup.cc | 4 +- src/zeek.bif | 16 +- 6 files changed, 920 insertions(+), 721 deletions(-) diff --git a/src/DNS_Mapping.cc b/src/DNS_Mapping.cc index 1e98788904..73c804bae1 100644 --- a/src/DNS_Mapping.cc +++ b/src/DNS_Mapping.cc @@ -6,14 +6,14 @@ namespace zeek::detail { -DNS_Mapping::DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl) +DNS_Mapping::DNS_Mapping(std::string host, struct hostent* h, uint32_t ttl) { Init(h); req_host = host; req_ttl = ttl; if ( names.empty() ) - names.push_back(host); + names.push_back(std::move(host)); } DNS_Mapping::DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl) @@ -46,7 +46,10 @@ DNS_Mapping::DNS_Mapping(FILE* f) if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %" PRIu32, &creation_time, &is_req_host, req_buf, &failed_local, name_buf, &map_type, &num_addrs, &req_ttl) != 8 ) + { + no_mapping = true; return; + } failed = static_cast(failed_local); @@ -129,12 +132,15 @@ void DNS_Mapping::Init(struct hostent* h) // TODO: this could easily be expanded to include all of the aliases as well names.push_back(h->h_name); - for ( int i = 0; h->h_addr_list[i] != NULL; ++i ) + if ( h->h_addr_list ) { - if ( h->h_addrtype == AF_INET ) - addrs.push_back(IPAddr(IPv4, (uint32_t*)h->h_addr_list[i], IPAddr::Network)); - else if ( h->h_addrtype == AF_INET6 ) - addrs.push_back(IPAddr(IPv6, (uint32_t*)h->h_addr_list[i], IPAddr::Network)); + for ( int i = 0; h->h_addr_list[i] != NULL; ++i ) + { + if ( h->h_addrtype == AF_INET ) + addrs.push_back(IPAddr(IPv4, (uint32_t*)h->h_addr_list[i], IPAddr::Network)); + else if ( h->h_addrtype == AF_INET6 ) + addrs.push_back(IPAddr(IPv6, (uint32_t*)h->h_addr_list[i], IPAddr::Network)); + } } failed = false; @@ -167,7 +173,7 @@ void DNS_Mapping::Save(FILE* f) const TEST_CASE("dns_mapping init null hostent") { - DNS_Mapping mapping("www.apple.com", nullptr, 123); + DNS_Mapping mapping(std::string("www.apple.com"), nullptr, 123); CHECK(! mapping.Valid()); CHECK(mapping.Addrs() == nullptr); @@ -190,7 +196,7 @@ TEST_CASE("dns_mapping init host") std::vector addrs = {&in4, NULL}; he.h_addr_list = reinterpret_cast(addrs.data()); - DNS_Mapping mapping("testing.home", &he, 123); + DNS_Mapping mapping(std::string("testing.home"), &he, 123); CHECK(mapping.Valid()); CHECK(mapping.ReqAddr() == IPAddr::v6_unspecified); CHECK(strcmp(mapping.ReqHost(), "testing.home") == 0); @@ -335,7 +341,7 @@ TEST_CASE("dns_mapping multiple addresses") std::vector addrs = {&in4_1, &in4_2, NULL}; he.h_addr_list = reinterpret_cast(addrs.data()); - DNS_Mapping mapping("testing.home", &he, 123); + DNS_Mapping mapping(std::string("testing.home"), &he, 123); CHECK(mapping.Valid()); auto lva = mapping.Addrs(); diff --git a/src/DNS_Mapping.h b/src/DNS_Mapping.h index ef56ade2b3..34a3aff7d5 100644 --- a/src/DNS_Mapping.h +++ b/src/DNS_Mapping.h @@ -15,7 +15,7 @@ class DNS_Mapping { public: DNS_Mapping() = delete; - DNS_Mapping(const char* host, struct hostent* h, uint32_t ttl); + DNS_Mapping(std::string host, struct hostent* h, uint32_t ttl); DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl); DNS_Mapping(FILE* f); @@ -35,6 +35,7 @@ public: StringValPtr Host(); double CreationTime() const { return creation_time; } + uint32_t TTL() const { return req_ttl; } void Save(FILE* f) const; diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 2e240a3bf2..0165808a3a 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -5,6 +5,7 @@ #include "zeek/zeek-config.h" #include +#include #include #include #include @@ -26,6 +27,7 @@ #include #include +#include #include "zeek/3rdparty/doctest.h" #include "zeek/DNS_Mapping.h" @@ -44,128 +46,306 @@ // Number of seconds we'll wait for a reply. constexpr int DNS_TIMEOUT = 5; +// The maximum allowed number of pending asynchronous requests. +constexpr int MAX_PENDING_REQUESTS = 20; + namespace zeek::detail { -static void hostbyaddr_callback(void* arg, int status, int timeouts, struct hostent* hostent) +static void hostbyaddr_cb(void* arg, int status, int timeouts, struct hostent* hostent); +static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinfo* result); +static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, int len); +static void sock_cb(void* data, int s, int read, int write); + +class DNS_Request + { +public: + DNS_Request(std::string host, int af, int request_type, bool async = false); + explicit DNS_Request(const IPAddr& addr, bool async = false); + ~DNS_Request(); + + std::string Host() const { return host; } + const IPAddr& Addr() const { return addr; } + int Family() const { return family; } + int RequestType() const { return request_type; } + bool IsTxt() const { return request_type == 16; } + + void MakeRequest(ares_channel channel); + void ProcessAsyncResult(bool timed_out); + +private: + std::string host; + IPAddr addr; + int family = 0; // address family query type for host requests + int request_type = 0; // Query type + bool async = false; + unsigned char* query = nullptr; + static uint16_t request_id; + }; + +uint16_t DNS_Request::request_id = 0; + +DNS_Request::DNS_Request(std::string host, int af, int request_type, bool async) + : host(std::move(host)), family(af), request_type(request_type), async(async) { - printf("host callback\n"); - // TODO: implement this - // TODO: figure out how to get TTL info here } -static void addrinfo_callback(void* arg, int status, int timeouts, struct ares_addrinfo* result) +DNS_Request::DNS_Request(const IPAddr& addr, bool async) : addr(addr), async(async) { - printf("addrinfo callback\n"); + // TODO: AF_UNSPEC for T_PTR requests? + family = addr.GetFamily() == IPv4 ? AF_INET : AF_INET6; + request_type = T_PTR; + } + +DNS_Request::~DNS_Request() + { + if ( query ) + ares_free_string(query); + } + +void DNS_Request::MakeRequest(ares_channel channel) + { + // It's completely fine if this rolls over. It's just to keep the query ID different + // from one query to the next, and it's unlikely we'd do 2^16 queries so fast that + // all of them would be in flight at the same time. + DNS_Request::request_id++; + + // TODO: how the heck do file lookups work? gethostbyname_file exists but gethostbyaddr_file + // doesn't. But then the code in ares_gethostbyaddr.c can switch on the setting in the channel + // for whether we should look at the file or not. If we don't care about file lookups at all, + // the T_PTR case below can be simplified and moved down into the else block. + + // We do normal host and address lookups via the specialized methods for them + // because those will attempt to do file lookups as well internally before + // reaching out to the DNS server. The remaining lookup types all use + // ares_create_query() and ares_send() for more genericness. + if ( request_type == T_A || request_type == T_AAAA ) + { + // TODO: gethostbyname_file? + // Use getaddrinfo here because it gives us the ttl information. If we don't + // care about TTL, we could use gethostbyname instead. + ares_addrinfo_hints hints = {ARES_AI_CANONNAME, family, 0, 0}; + ares_getaddrinfo(channel, host.c_str(), NULL, &hints, addrinfo_cb, this); + } + else if ( request_type == T_PTR ) + { + if ( addr.GetFamily() == IPv4 ) + { + struct sockaddr_in sa; + inet_pton(AF_INET, addr.AsString().c_str(), &(sa.sin_addr)); + ares_gethostbyaddr(channel, &sa.sin_addr, sizeof(sa.sin_addr), AF_INET, hostbyaddr_cb, + this); + } + else + { + struct sockaddr_in6 sa; + inet_pton(AF_INET6, addr.AsString().c_str(), &(sa.sin6_addr)); + ares_gethostbyaddr(channel, &sa.sin6_addr, sizeof(sa.sin6_addr), AF_INET6, + hostbyaddr_cb, this); + } + } + else + { + unsigned char* query = NULL; + int len = 0; + int status = ares_create_query(host.c_str(), C_IN, request_type, DNS_Request::request_id, 1, + &query, &len, 0); + if ( status != ARES_SUCCESS ) + return; + + // Store this so it can be destroyed when the request is destroyed. + this->query = query; + ares_send(channel, query, len, query_cb, this); + } + } + +void DNS_Request::ProcessAsyncResult(bool timed_out) + { + if ( ! async ) + return; + + if ( request_type == T_A || request_type == T_AAAA ) + dns_mgr->CheckAsyncHostRequest(host, timed_out); + else if ( request_type == T_PTR ) + dns_mgr->CheckAsyncAddrRequest(addr, timed_out); + else if ( request_type == T_TXT ) + dns_mgr->CheckAsyncTextRequest(host, timed_out); + } + +/** + * Called in response to ares_gethostbyaddr requests. Sends the hostent data to the + * DNS manager via AddResult(). + */ +static void hostbyaddr_cb(void* arg, int status, int timeouts, struct hostent* host) + { + auto req = reinterpret_cast(arg); + + if ( ! host || status != ARES_SUCCESS ) + { + printf("Failed hostbyaddr request: %s\n", ares_strerror(status)); + // TODO: pass DNS_TIMEOUT for the TTL here just so things work for testing. This + // will absolutely need to get the data from the request somehow instead. See + // https://github.com/c-ares/c-ares/issues/387. + dns_mgr->AddResult(req, nullptr, DNS_TIMEOUT); + } + else + { + // TODO: pass DNS_TIMEOUT for the TTL here just so things work for testing. This + // will absolutely need to get the data from the request somehow instead. See + // https://github.com/c-ares/c-ares/issues/387. + dns_mgr->AddResult(req, host, DNS_TIMEOUT); + } + + req->ProcessAsyncResult(timeouts > 0); + } + +/** + * Called in response to ares_getaddrinfo requests. Builds a hostent structure from + * the result data and sends it to the DNS manager via Addresult(). + */ +static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinfo* result) + { + auto req = reinterpret_cast(arg); if ( status != ARES_SUCCESS ) { - // TODO: error or something here, or just give up on it? - ares_freeaddrinfo(result); - return; + // TODO: reporter warning or something here, or just give up on it? + printf("Failed addrinfo request: %s", ares_strerror(status)); + dns_mgr->AddResult(req, nullptr, 0); + } + else + { + std::vector addrs; + std::vector addrs6; + for ( ares_addrinfo_node* entry = result->nodes; entry != NULL; entry = entry->ai_next ) + { + if ( entry->ai_family == AF_INET ) + { + struct sockaddr_in* addr = reinterpret_cast(entry->ai_addr); + addrs.push_back(&addr->sin_addr); + } + else if ( entry->ai_family == AF_INET6 ) + { + struct sockaddr_in6* addr = (struct sockaddr_in6*)(entry->ai_addr); + addrs6.push_back(&addr->sin6_addr); + } + } + + if ( ! addrs.empty() ) + { + // Push a null on the end so the addr list has a final point during later parsing. + addrs.push_back(NULL); + + struct hostent he; + memset(&he, 0, sizeof(struct hostent)); + he.h_name = util::copy_string(result->name); + he.h_addrtype = AF_INET; + he.h_length = sizeof(in_addr); + he.h_addr_list = reinterpret_cast(addrs.data()); + + dns_mgr->AddResult(req, &he, result->nodes[0].ai_ttl); + + delete[] he.h_name; + } + + // TODO: We can't do this here because we blow up the mapping added above by doing so. + // We need some sort of "merge mapping" mode in AddResult for this to work to add new + // IPs to an existing mapping. + /* + if ( ! addrs6.empty() ) + { + // Push a null on the end so the addr list has a final point during later parsing. + addrs6.push_back(NULL); + + struct hostent he; + memset(&he, 0, sizeof(struct hostent)); + he.h_name = util::copy_string(result->name); + he.h_addrtype = AF_INET6; + he.h_length = sizeof(in6_addr); + he.h_addr_list = reinterpret_cast(addrs6.data()); + + dns_mgr->AddResult(req, &he, result->nodes[0].ai_ttl); + + delete[] he.h_name; + } + */ } - // TODO: the existing code doesn't handle hostname aliases at all. Should we? - // TODO: handle IPv6 mode - - std::vector addrs; - for ( ares_addrinfo_node* entry = result->nodes; entry != NULL; entry = entry->ai_next ) - addrs.push_back(&reinterpret_cast(entry->ai_addr)->sin_addr); - - // Push a null on the end so the addr list has a final point during later parsing. - addrs.push_back(NULL); - - struct hostent he; - he.h_name = util::copy_string(result->name); - he.h_aliases = NULL; - he.h_addrtype = AF_INET; - he.h_length = sizeof(in_addr); - he.h_addr_list = reinterpret_cast(addrs.data()); - - auto req = reinterpret_cast(arg); - dns_mgr->AddResult(req, &he, result->nodes[0].ai_ttl); - - delete[] he.h_name; + req->ProcessAsyncResult(timeouts > 0); ares_freeaddrinfo(result); } -static void ares_sock_cb(void* data, int s, int read, int write) +/** + * Called in response to all other query types. + */ +static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, int len) { - printf("Change state fd %d read:%d write:%d\n", s, read, write); - if ( read == 1 ) - iosource_mgr->RegisterFd(s, reinterpret_cast(data)); - else - iosource_mgr->UnregisterFd(s, reinterpret_cast(data)); - } + auto req = reinterpret_cast(arg); -class DNS_Mgr_Request - { -public: - DNS_Mgr_Request(const char* h, int af, bool is_txt) - : host(util::copy_string(h)), fam(af), qtype(is_txt ? 16 : 0), addr() + if ( status != ARES_SUCCESS ) { - } - - DNS_Mgr_Request(const IPAddr& a) : addr(a) { } - - ~DNS_Mgr_Request() { delete[] host; } - - // Returns nil if this was an address request. - const char* ReqHost() const { return host; } - const IPAddr& ReqAddr() const { return addr; } - int Family() const { return fam; } - bool ReqIsTxt() const { return qtype == 16; } - - void MakeRequest(ares_channel channel); - - bool RequestPending() const { return request_pending; } - void RequestDone() { request_pending = false; } - -protected: - char* host = nullptr; // if non-nil, this is a host request - int fam = 0; // address family query type for host requests - int qtype = 0; // Query type - IPAddr addr; - bool request_pending = false; - }; - -void DNS_Mgr_Request::MakeRequest(ares_channel channel) - { - request_pending = true; - - // TODO: TXT requests? - // TODO: could this use ares_create_query/ares_query instead of the - // ares_get* methods to make it more generic? I think we might need - // to do that for TXT requests. - - if ( host ) - { - ares_addrinfo_hints hints = {ARES_AI_CANONNAME, fam, 0, 0}; - ares_getaddrinfo(channel, host, NULL, &hints, addrinfo_callback, this); + // TODO: reporter warning or something here, or just give up on it? + // TODO: what should we send to AddResult if we didn't get an answer back? + // struct hostent he; + // memset(&he, 0, sizeof(struct hostent)); + // dns_mgr->AddResult(req, &he, 0); } else { - const uint32_t* bytes; - int len = addr.GetBytes(&bytes); + switch ( req->RequestType() ) + { + case T_TXT: + { + struct ares_txt_reply* reply; + int r = ares_parse_txt_reply(buf, len, &reply); + if ( r == ARES_SUCCESS ) + { + // Use a hostent to send the data into AddResult(). We only care about + // setting the host field, but everything else should be zero just for + // safety. - ares_gethostbyaddr(channel, bytes, len, addr.GetFamily() == IPv4 ? AF_INET : AF_INET6, - hostbyaddr_callback, this); + // We don't currently handle more than the first response, and throw the + // rest away. There really isn't a good reason for this, we just haven't + // ever done so. It would likely require some changes to the output from + // Lookup(), since right now it only returns one value. + struct hostent he; + memset(&he, 0, sizeof(struct hostent)); + he.h_name = util::copy_string(reinterpret_cast(reply->txt)); + + // TODO: pass DNS_TIMEOUT for the TTL here just so things work for + // testing. This will absolutely need to get the data from the request + // somehow instead. See https://github.com/c-ares/c-ares/issues/387. + dns_mgr->AddResult(req, &he, DNS_TIMEOUT); + + ares_free_data(reply); + } + + break; + } + + default: + reporter->Error("Requests of type %d are unsupported", req->RequestType()); + break; + } } + + req->ProcessAsyncResult(timeouts > 0); } -DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) +/** + * Called when the c-ares socket changes state, whcih indicates that it's connected to + * some source of data (either a host file or a DNS server). This indicates that we're + * able to do lookups against c-ares now and should activate the IOSource. + */ +static void sock_cb(void* data, int s, int read, int write) { - did_init = false; - - mode = arg_mode; - - asyncs_pending = 0; - num_requests = 0; - successful = 0; - failed = 0; - ipv6_resolver = false; + auto mgr = reinterpret_cast(data); + mgr->RegisterSocket(s, read == 1); + } +DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) : mode(arg_mode) + { ares_library_init(ARES_LIB_INIT_ALL); } @@ -178,6 +358,20 @@ DNS_Mgr::~DNS_Mgr() ares_library_cleanup(); } +void DNS_Mgr::RegisterSocket(int fd, bool active) + { + if ( active && socket_fds.count(fd) == 0 ) + { + socket_fds.insert(fd); + iosource_mgr->RegisterFd(fd, this); + } + else if ( ! active && socket_fds.count(fd) != 0 ) + { + socket_fds.erase(fd); + iosource_mgr->UnregisterFd(fd, this); + } + } + void DNS_Mgr::InitSource() { if ( did_init ) @@ -186,13 +380,22 @@ void DNS_Mgr::InitSource() ares_options options; int optmask = 0; + // Don't close the socket for the server even if we have no active + // requests. options.flags = ARES_FLAG_STAYOPEN; optmask |= ARES_OPT_FLAGS; - options.timeout = DNS_TIMEOUT; - optmask |= ARES_OPT_TIMEOUT; + // This option is in milliseconds. + options.timeout = DNS_TIMEOUT * 1000; + optmask |= ARES_OPT_TIMEOUTMS; - options.sock_state_cb = ares_sock_cb; + // This causes c-ares to only attempt each server twice before + // giving up. + options.tries = 2; + optmask |= ARES_OPT_TRIES; + + // See the comment on sock_cb for how this gets used. + options.sock_state_cb = sock_cb; options.sock_state_cb_data = this; optmask |= ARES_OPT_SOCK_STATE_CB; @@ -210,19 +413,15 @@ void DNS_Mgr::InitSource() if ( dns_resolver ) { ares_addr_node servers; - servers.next = nullptr; + servers.next = NULL; auto dns_resolver_addr = IPAddr(dns_resolver); struct sockaddr_storage ss = {0}; if ( dns_resolver_addr.GetFamily() == IPv4 ) { - struct sockaddr_in* sa = (struct sockaddr_in*)&ss; - sa->sin_family = AF_INET; - dns_resolver_addr.CopyIPv4(&sa->sin_addr); - servers.family = AF_INET; - memcpy(&(servers.addr.addr4), &sa->sin_addr, sizeof(struct in_addr)); + dns_resolver_addr.CopyIPv4(&(servers.addr.addr4)); } else { @@ -256,102 +455,126 @@ void DNS_Mgr::InitPostScript() } // Load the DNS cache from disk, if it exists. - std::string cache_dir = dir.empty() ? dir : "."; + std::string cache_dir = dir.empty() ? "." : dir; cache_name = util::fmt("%s/%s", cache_dir.c_str(), ".zeek-dns-cache"); LoadCache(cache_name); } -static TableValPtr fake_name_lookup_result(const char* name) +static TableValPtr fake_name_lookup_result(const std::string& name) { hash128_t hash; - KeyedHash::StaticHash128(name, strlen(name), &hash); + KeyedHash::StaticHash128(name.c_str(), name.size(), &hash); auto hv = make_intrusive(TYPE_ADDR); hv->Append(make_intrusive(reinterpret_cast(&hash))); return hv->ToSetVal(); } -static const char* fake_text_lookup_result(const char* name) +static std::string fake_text_lookup_result(const std::string name) { - static char tmp[32 + 256]; - snprintf(tmp, sizeof(tmp), "fake_text_lookup_result_%s", name); - return tmp; + return util::fmt("fake_text_lookup_result_%s", name.c_str()); } -static const char* fake_addr_lookup_result(const IPAddr& addr) +static std::string fake_addr_lookup_result(const IPAddr& addr) { - static char tmp[128]; - snprintf(tmp, sizeof(tmp), "fake_addr_lookup_result_%s", addr.AsString().c_str()); - return tmp; + return util::fmt("fake_addr_lookup_result_%s", addr.AsString().c_str()); } -TableValPtr DNS_Mgr::LookupHost(const char* name) +static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, TableValPtr result) + { + callback->Resolved(std::move(result)); + delete callback; + } + +static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, const std::string& result) + { + callback->Resolved(result); + delete callback; + } + +ValPtr DNS_Mgr::Lookup(const std::string& name, int request_type) + { + if ( request_type == T_A || request_type == T_AAAA ) + return LookupHost(name); + + if ( mode == DNS_FAKE && request_type == T_TXT ) + return make_intrusive(fake_text_lookup_result(name)); + + InitSource(); + + if ( mode != DNS_PRIME && request_type == T_TXT ) + { + if ( auto val = LookupTextInCache(name, false) ) + return val; + } + + switch ( mode ) + { + case DNS_PRIME: + { + auto req = new DNS_Request(name, AF_UNSPEC, request_type); + req->MakeRequest(channel); + return empty_addr_set(); + } + + case DNS_FORCE: + reporter->FatalError("can't find DNS entry for %s (req type %d) in cache", name.c_str(), + request_type); + return nullptr; + + case DNS_DEFAULT: + { + auto req = new DNS_Request(name, AF_UNSPEC, request_type); + req->MakeRequest(channel); + Resolve(); + + // Call LookupHost() a second time to get the newly stored value out of the cache. + return Lookup(name, request_type); + } + + default: + reporter->InternalError("bad mode %d in DNS_Mgr::Lookup", mode); + return nullptr; + } + + return nullptr; + } + +TableValPtr DNS_Mgr::LookupHost(const std::string& name) { if ( mode == DNS_FAKE ) return fake_name_lookup_result(name); - // This should have been run already from InitPostScript(), but just run it again just - // in case it hadn't. InitSource(); // Check the cache before attempting to look up the name remotely. if ( mode != DNS_PRIME ) { - HostMap::iterator it = host_mappings.find(name); - - if ( it != host_mappings.end() ) - { - DNS_Mapping* d4 = it->second.first; - DNS_Mapping* d6 = it->second.second; - - if ( (d4 && d4->Failed()) || (d6 && d6->Failed()) ) - { - reporter->Warning("no such host: %s", name); - return empty_addr_set(); - } - else if ( d4 && d6 ) - { - auto tv4 = d4->AddrsSet(); - auto tv6 = d6->AddrsSet(); - tv4->AddTo(tv6.get(), false); - return tv6; - } - } + if ( auto val = LookupNameInCache(name, false, true) ) + return val; } - // Not found, or priming. We use ares_getaddrinfo here because we want the TTL value + // Not found, or priming. switch ( mode ) { case DNS_PRIME: { - // TODO: not sure we need to do these split like this if we can pass AF_UNSPEC - // in the hints structure. Do we really need the two different request objects? - auto v4 = new DNS_Mgr_Request(name, AF_INET, false); - ares_addrinfo_hints v4_hints = {ARES_AI_CANONNAME, AF_INET, 0, 0}; - ares_getaddrinfo(channel, name, NULL, &v4_hints, addrinfo_callback, v4); - - // TODO: check if ipv6 support is needed if we use AF_UNSPEC above - // auto v6 = new DNS_Mgr_Request(name, AF_INET6, false); - // ares_addrinfo_hints v6_hints = { 0, AF_INET6, 0, 0 }; - // ares_getaddrinfo(channel, name, NULL, &v6_hints, addrinfo_callback, v6); - + // We pass T_A here, but because we're passing AF_UNSPEC MakeRequest() will + // have c-ares attempt to lookup both ipv4 and ipv6 at the same time. + auto req = new DNS_Request(name, AF_UNSPEC, T_A); + req->MakeRequest(channel); return empty_addr_set(); } case DNS_FORCE: - reporter->FatalError("can't find DNS entry for %s in cache", name); + reporter->FatalError("can't find DNS entry for %s in cache", name.c_str()); return nullptr; case DNS_DEFAULT: { - auto v4 = new DNS_Mgr_Request(name, AF_INET, false); - ares_addrinfo_hints v4_hints = {ARES_AI_CANONNAME, AF_INET, 0, 0}; - ares_getaddrinfo(channel, name, NULL, &v4_hints, addrinfo_callback, v4); - - // TODO: check if ipv6 support is needed if we use AF_UNSPEC above - // auto v6 = new DNS_Mgr_Request(name, AF_INET6, false); - // ares_addrinfo_hints v6_hints = { 0, AF_INET6, 0, 0 }; - // ares_getaddrinfo(channel, name, NULL, &v6_hints, addrinfo_callback, v6); - + // We pass T_A here, but because we're passing AF_UNSPEC MakeRequest() will + // have c-ares attempt to lookup both ipv4 and ipv6 at the same time. + auto req = new DNS_Request(name, AF_UNSPEC, T_A); + req->MakeRequest(channel); Resolve(); // Call LookupHost() a second time to get the newly stored value out of the cache. @@ -369,40 +592,22 @@ StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) if ( mode == DNS_FAKE ) return make_intrusive(fake_addr_lookup_result(addr)); - // This should have been run already from InitPostScript(), but just run it again just - // in case it hadn't. InitSource(); // Check the cache before attempting to look up the name remotely. if ( mode != DNS_PRIME ) { - AddrMap::iterator it = addr_mappings.find(addr); - - if ( it != addr_mappings.end() ) - { - DNS_Mapping* d = it->second; - if ( d->Valid() ) - return d->Host(); - else - { - std::string s(addr); - reporter->Warning("can't resolve IP address: %s", s.c_str()); - return make_intrusive(s.c_str()); - } - } + if ( auto val = LookupAddrInCache(addr, false, true) ) + return val; } - const uint32_t* bytes; - int len = addr.GetBytes(&bytes); - // Not found, or priming. switch ( mode ) { case DNS_PRIME: { - auto req = new DNS_Mgr_Request(addr); - ares_gethostbyaddr(channel, bytes, len, addr.GetFamily() == IPv4 ? AF_INET : AF_INET6, - hostbyaddr_callback, req); + auto req = new DNS_Request(addr); + req->MakeRequest(channel); return make_intrusive(""); } @@ -412,9 +617,8 @@ StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) case DNS_DEFAULT: { - auto req = new DNS_Mgr_Request(addr); - ares_gethostbyaddr(channel, bytes, len, addr.GetFamily() == IPv4 ? AF_INET : AF_INET6, - hostbyaddr_callback, req); + auto req = new DNS_Request(addr); + req->MakeRequest(channel); Resolve(); // Call LookupAddr() a second time to get the newly stored value out of the cache. @@ -427,7 +631,129 @@ StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) } } -constexpr int MAX_PENDING_REQUESTS = 20; +void DNS_Mgr::LookupHost(const std::string& name, LookupCallback* callback) + { + if ( mode == DNS_FAKE ) + { + resolve_lookup_cb(callback, fake_name_lookup_result(name)); + return; + } + + // Do we already know the answer? + if ( auto addrs = LookupNameInCache(name, true, false) ) + { + resolve_lookup_cb(callback, std::move(addrs)); + return; + } + + AsyncRequest* req = nullptr; + + // If we already have a request waiting for this host, we don't need to make + // another one. We can just add the callback to it and it'll get handled + // when the first request comes back. + AsyncRequestNameMap::iterator i = asyncs_names.find(name); + if ( i != asyncs_names.end() ) + req = i->second; + else + { + // A new one. + req = new AsyncRequest{}; + req->host = name; + asyncs_queued.push_back(req); + asyncs_names.emplace_hint(i, name, req); + } + + req->callbacks.push_back(callback); + + // There may be requests in the queue that haven't been processed yet + // so go ahead and reissue them, even if this method didn't change + // anything. + IssueAsyncRequests(); + } + +void DNS_Mgr::LookupAddr(const IPAddr& host, LookupCallback* callback) + { + if ( mode == DNS_FAKE ) + { + resolve_lookup_cb(callback, fake_addr_lookup_result(host)); + return; + } + + // Do we already know the answer? + if ( auto name = LookupAddrInCache(host, true, false) ) + { + resolve_lookup_cb(callback, name->CheckString()); + return; + } + + AsyncRequest* req = nullptr; + + // If we already have a request waiting for this host, we don't need to make + // another one. We can just add the callback to it and it'll get handled + // when the first request comes back. + AsyncRequestAddrMap::iterator i = asyncs_addrs.find(host); + if ( i != asyncs_addrs.end() ) + req = i->second; + else + { + // A new one. + req = new AsyncRequest{}; + req->addr = host; + asyncs_queued.push_back(req); + asyncs_addrs.emplace_hint(i, host, req); + } + + req->callbacks.push_back(callback); + + // There may be requests in the queue that haven't been processed yet + // so go ahead and reissue them, even if this method didn't change + // anything. + IssueAsyncRequests(); + } + +void DNS_Mgr::Lookup(const std::string& name, int request_type, LookupCallback* callback) + { + if ( request_type == T_A || request_type == T_AAAA ) + { + LookupHost(name, callback); + return; + } + + if ( mode == DNS_FAKE ) + { + resolve_lookup_cb(callback, fake_text_lookup_result(name)); + return; + } + + // Do we already know the answer? + if ( auto txt = LookupTextInCache(name, true) ) + { + resolve_lookup_cb(callback, txt->CheckString()); + return; + } + + AsyncRequest* req = nullptr; + + // If we already have a request waiting for this host, we don't need to make + // another one. We can just add the callback to it and it'll get handled + // when the first request comes back. + AsyncRequestTextMap::iterator i = asyncs_texts.find(name); + if ( i != asyncs_texts.end() ) + req = i->second; + else + { + // A new one. + req = new AsyncRequest{}; + req->host = name; + req->is_txt = true; + asyncs_queued.push_back(req); + asyncs_texts.emplace_hint(i, name, req); + } + + req->callbacks.push_back(callback); + + IssueAsyncRequests(); + } void DNS_Mgr::Resolve() { @@ -454,25 +780,20 @@ void DNS_Mgr::Resolve() void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm) { - if ( ! e ) - return; - event_mgr.Enqueue(e, BuildMappingVal(dm)); + if ( e ) + event_mgr.Enqueue(e, BuildMappingVal(dm)); } void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2) { - if ( ! e ) - return; - - event_mgr.Enqueue(e, BuildMappingVal(dm), l1->ToSetVal(), l2->ToSetVal()); + if ( e ) + event_mgr.Enqueue(e, BuildMappingVal(dm), l1->ToSetVal(), l2->ToSetVal()); } void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm) { - if ( ! e ) - return; - - event_mgr.Enqueue(e, BuildMappingVal(old_dm), BuildMappingVal(new_dm)); + if ( e ) + event_mgr.Enqueue(e, BuildMappingVal(old_dm), BuildMappingVal(new_dm)); } ValPtr DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) @@ -494,66 +815,70 @@ ValPtr DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) return r; } -void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct hostent* h, uint32_t ttl) +void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl) { - DNS_Mapping* new_dm; - DNS_Mapping* prev_dm; + // TODO: the existing code doesn't handle hostname aliases at all. Should we? + + DNS_Mapping* new_mapping; + DNS_Mapping* prev_mapping; bool keep_prev = false; - if ( dr->ReqHost() ) + if ( ! dr->Host().empty() ) { - new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl); - prev_dm = nullptr; + new_mapping = new DNS_Mapping(dr->Host(), h, ttl); + prev_mapping = nullptr; - if ( dr->ReqIsTxt() ) + if ( dr->IsTxt() ) { - TextMap::iterator it = text_mappings.find(dr->ReqHost()); + TextMap::iterator it = text_mappings.find(dr->Host()); if ( it == text_mappings.end() ) - text_mappings[dr->ReqHost()] = new_dm; + text_mappings[dr->Host()] = new_mapping; else { - prev_dm = it->second; - it->second = new_dm; + prev_mapping = it->second; + it->second = new_mapping; } - if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) + if ( new_mapping->Failed() && prev_mapping && prev_mapping->Valid() ) { - text_mappings[dr->ReqHost()] = prev_dm; + text_mappings[dr->Host()] = prev_mapping; keep_prev = true; } } else { - HostMap::iterator it = host_mappings.find(dr->ReqHost()); + HostMap::iterator it = host_mappings.find(dr->Host()); if ( it == host_mappings.end() ) { - host_mappings[dr->ReqHost()].first = new_dm->Type() == AF_INET ? new_dm : nullptr; + host_mappings[dr->Host()].first = new_mapping->Type() == AF_INET ? new_mapping + : nullptr; - host_mappings[dr->ReqHost()].second = new_dm->Type() == AF_INET ? nullptr : new_dm; + host_mappings[dr->Host()].second = new_mapping->Type() == AF_INET ? nullptr + : new_mapping; } else { - if ( new_dm->Type() == AF_INET ) + if ( new_mapping->Type() == AF_INET ) { - prev_dm = it->second.first; - it->second.first = new_dm; + prev_mapping = it->second.first; + it->second.first = new_mapping; } else { - prev_dm = it->second.second; - it->second.second = new_dm; + prev_mapping = it->second.second; + it->second.second = new_mapping; } } - if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) + if ( new_mapping->Failed() && prev_mapping && prev_mapping->Valid() ) { // Put previous, valid entry back - CompareMappings // will generate a corresponding warning. - if ( prev_dm->Type() == AF_INET ) - host_mappings[dr->ReqHost()].first = prev_dm; + if ( prev_mapping->Type() == AF_INET ) + host_mappings[dr->Host()].first = prev_mapping; else - host_mappings[dr->ReqHost()].second = prev_dm; + host_mappings[dr->Host()].second = prev_mapping; keep_prev = true; } @@ -561,60 +886,60 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct hostent* h, uint32_t ttl) } else { - new_dm = new DNS_Mapping(dr->ReqAddr(), h, ttl); - AddrMap::iterator it = addr_mappings.find(dr->ReqAddr()); - prev_dm = (it == addr_mappings.end()) ? 0 : it->second; - addr_mappings[dr->ReqAddr()] = new_dm; + new_mapping = new DNS_Mapping(dr->Addr(), h, ttl); + AddrMap::iterator it = addr_mappings.find(dr->Addr()); + prev_mapping = (it == addr_mappings.end()) ? 0 : it->second; + addr_mappings[dr->Addr()] = new_mapping; - if ( new_dm->Failed() && prev_dm && prev_dm->Valid() ) + if ( new_mapping->Failed() && prev_mapping && prev_mapping->Valid() ) { - addr_mappings[dr->ReqAddr()] = prev_dm; + addr_mappings[dr->Addr()] = prev_mapping; keep_prev = true; } } - if ( prev_dm && ! dr->ReqIsTxt() ) - CompareMappings(prev_dm, new_dm); + if ( prev_mapping && ! dr->IsTxt() ) + CompareMappings(prev_mapping, new_mapping); if ( keep_prev ) - delete new_dm; + delete new_mapping; else - delete prev_dm; + delete prev_mapping; } -void DNS_Mgr::CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm) +void DNS_Mgr::CompareMappings(DNS_Mapping* prev_mapping, DNS_Mapping* new_mapping) { - if ( prev_dm->Failed() ) + if ( prev_mapping->Failed() ) { - if ( new_dm->Failed() ) + if ( new_mapping->Failed() ) // Nothing changed. return; - Event(dns_mapping_valid, new_dm); + Event(dns_mapping_valid, new_mapping); return; } - else if ( new_dm->Failed() ) + else if ( new_mapping->Failed() ) { - Event(dns_mapping_unverified, prev_dm); + Event(dns_mapping_unverified, prev_mapping); return; } - auto prev_s = prev_dm->Host(); - auto new_s = new_dm->Host(); + auto prev_s = prev_mapping->Host(); + auto new_s = new_mapping->Host(); if ( prev_s || new_s ) { if ( ! prev_s ) - Event(dns_mapping_new_name, new_dm); + Event(dns_mapping_new_name, new_mapping); else if ( ! new_s ) - Event(dns_mapping_lost_name, prev_dm); + Event(dns_mapping_lost_name, prev_mapping); else if ( ! Bstr_eq(new_s->AsString(), prev_s->AsString()) ) - Event(dns_mapping_name_changed, prev_dm, new_dm); + Event(dns_mapping_name_changed, prev_mapping, new_mapping); } - auto prev_a = prev_dm->Addrs(); - auto new_a = new_dm->Addrs(); + auto prev_a = prev_mapping->Addrs(); + auto new_a = new_mapping->Addrs(); if ( ! prev_a || ! new_a ) { @@ -626,7 +951,7 @@ void DNS_Mgr::CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm) auto new_delta = AddrListDelta(new_a.get(), prev_a.get()); if ( prev_delta->Length() > 0 || new_delta->Length() > 0 ) - Event(dns_mapping_altered, new_dm, std::move(prev_delta), std::move(new_delta)); + Event(dns_mapping_altered, new_mapping, std::move(prev_delta), std::move(new_delta)); } ListValPtr DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2) @@ -653,15 +978,6 @@ ListValPtr DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2) return delta; } -void DNS_Mgr::DumpAddrList(FILE* f, ListVal* al) - { - for ( int i = 0; i < al->Length(); ++i ) - { - const IPAddr& al_i = al->Idx(i)->AsAddr(); - fprintf(f, "%s%s", i > 0 ? "," : "", al_i.AsString().c_str()); - } - } - void DNS_Mgr::LoadCache(const std::string& path) { FILE* f = fopen(path.c_str(), "r"); @@ -738,43 +1054,20 @@ void DNS_Mgr::Save(FILE* f, const HostMap& m) } } -const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) - { - AddrMap::iterator it = addr_mappings.find(addr); - - if ( it == addr_mappings.end() ) - return nullptr; - - DNS_Mapping* d = it->second; - - if ( d->Expired() ) - { - addr_mappings.erase(it); - delete d; - return nullptr; - } - - // The escapes in the following strings are to avoid having it - // interpreted as a trigraph sequence. - return d->names.empty() ? "<\?\?\?>" : d->names[0].c_str(); - } - -TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name) +TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name, bool cleanup_expired, + bool check_failed) { HostMap::iterator it = host_mappings.find(name); if ( it == host_mappings.end() ) - { - it = host_mappings.begin(); return nullptr; - } DNS_Mapping* d4 = it->second.first; DNS_Mapping* d6 = it->second.second; - if ( ! d4 || d4->names.empty() || ! d6 || d6->names.empty() ) + if ( (! d4 || d4->names.empty()) && (! d6 || d6->names.empty()) ) return nullptr; - if ( d4->Expired() || d6->Expired() ) + if ( cleanup_expired && ((d4 && d4->Expired()) || (d6 && d6->Expired())) ) { host_mappings.erase(it); delete d4; @@ -782,13 +1075,52 @@ TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name) return nullptr; } + if ( check_failed && ((d4 && d4->Failed()) || (d6 && d6->Failed())) ) + { + reporter->Warning("Can't resolve host: %s", name.c_str()); + return empty_addr_set(); + } + auto tv4 = d4->AddrsSet(); - auto tv6 = d6->AddrsSet(); - tv4->AddTo(tv6.get(), false); - return tv6; + + if ( d6 ) + { + auto tv6 = d6->AddrsSet(); + tv4->AddTo(tv6.get(), false); + return tv6; + } + + return tv4; } -const char* DNS_Mgr::LookupTextInCache(const std::string& name) +StringValPtr DNS_Mgr::LookupAddrInCache(const IPAddr& addr, bool cleanup_expired, bool check_failed) + { + AddrMap::iterator it = addr_mappings.find(addr); + if ( it == addr_mappings.end() ) + return nullptr; + + DNS_Mapping* d = it->second; + + if ( cleanup_expired && d->Expired() ) + { + addr_mappings.erase(it); + delete d; + return nullptr; + } + else if ( check_failed && d->Failed() ) + { + std::string s(addr); + reporter->Warning("can't resolve IP address: %s", s.c_str()); + return make_intrusive(s); + } + + if ( d->Host() ) + return d->Host(); + + return make_intrusive("<\?\?\?>"); + } + +StringValPtr DNS_Mgr::LookupTextInCache(const std::string& name, bool cleanup_expired) { TextMap::iterator it = text_mappings.find(name); if ( it == text_mappings.end() ) @@ -796,164 +1128,24 @@ const char* DNS_Mgr::LookupTextInCache(const std::string& name) DNS_Mapping* d = it->second; - if ( d->Expired() ) + if ( cleanup_expired && d->Expired() ) { text_mappings.erase(it); delete d; return nullptr; } - // The escapes in the following strings are to avoid having it - // interpreted as a trigraph sequence. - return d->names.empty() ? "<\?\?\?>" : d->names[0].c_str(); - } + if ( d->Host() ) + return d->Host(); -static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, TableValPtr result) - { - callback->Resolved(result.get()); - - // Don't delete this if testing because we need it to look at the results of the - // request. It'll get deleted by the test when finished. - if ( ! doctest::is_running_in_test ) - delete callback; - } - -static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, const char* result) - { - callback->Resolved(result); - - // Don't delete this if testing because we need it to look at the results of the - // request. It'll get deleted by the test when finished. - if ( ! doctest::is_running_in_test ) - delete callback; - } - -void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback) - { - // This should have been run already from InitPostScript(), but just run it again just - // in case it hadn't. - InitSource(); - - if ( mode == DNS_FAKE ) - { - resolve_lookup_cb(callback, fake_addr_lookup_result(host)); - return; - } - - // Do we already know the answer? - const char* name = LookupAddrInCache(host); - if ( name ) - { - resolve_lookup_cb(callback, name); - return; - } - - AsyncRequest* req = nullptr; - - // Have we already a request waiting for this host? - AsyncRequestAddrMap::iterator i = asyncs_addrs.find(host); - if ( i != asyncs_addrs.end() ) - req = i->second; - else - { - // A new one. - req = new AsyncRequest; - req->host = host; - asyncs_queued.push_back(req); - asyncs_addrs.insert(AsyncRequestAddrMap::value_type(host, req)); - } - - req->callbacks.push_back(callback); - - IssueAsyncRequests(); - } - -void DNS_Mgr::AsyncLookupName(const std::string& name, LookupCallback* callback) - { - // This should have been run already from InitPostScript(), but just run it again just - // in case it hadn't. - InitSource(); - - if ( mode == DNS_FAKE ) - { - resolve_lookup_cb(callback, fake_name_lookup_result(name.c_str())); - return; - } - - // Do we already know the answer? - auto addrs = LookupNameInCache(name); - if ( addrs ) - { - resolve_lookup_cb(callback, std::move(addrs)); - return; - } - - AsyncRequest* req = nullptr; - - // Have we already a request waiting for this host? - AsyncRequestNameMap::iterator i = asyncs_names.find(name); - if ( i != asyncs_names.end() ) - req = i->second; - else - { - // A new one. - req = new AsyncRequest; - req->name = name; - asyncs_queued.push_back(req); - asyncs_names.insert(AsyncRequestNameMap::value_type(name, req)); - } - - req->callbacks.push_back(callback); - - IssueAsyncRequests(); - } - -void DNS_Mgr::AsyncLookupNameText(const std::string& name, LookupCallback* callback) - { - // This should have been run already from InitPostScript(), but just run it again just - // in case it hadn't. - InitSource(); - - if ( mode == DNS_FAKE ) - { - resolve_lookup_cb(callback, fake_text_lookup_result(name.c_str())); - return; - } - - // Do we already know the answer? - const char* txt = LookupTextInCache(name); - - if ( txt ) - { - resolve_lookup_cb(callback, txt); - return; - } - - AsyncRequest* req = nullptr; - - // Have we already a request waiting for this host? - AsyncRequestTextMap::iterator i = asyncs_texts.find(name); - if ( i != asyncs_texts.end() ) - req = i->second; - else - { - // A new one. - req = new AsyncRequest; - req->name = name; - req->is_txt = true; - asyncs_queued.push_back(req); - asyncs_texts.insert(AsyncRequestTextMap::value_type(name, req)); - } - - req->callbacks.push_back(callback); - - IssueAsyncRequests(); + return make_intrusive("<\?\?\?>"); } void DNS_Mgr::IssueAsyncRequests() { while ( ! asyncs_queued.empty() && asyncs_pending < MAX_PENDING_REQUESTS ) { + DNS_Request* dns_req = nullptr; AsyncRequest* req = asyncs_queued.front(); asyncs_queued.pop_front(); @@ -961,30 +1153,48 @@ void DNS_Mgr::IssueAsyncRequests() req->time = util::current_time(); if ( req->IsAddrReq() ) - { - auto* m_req = new DNS_Mgr_Request(req->host); - m_req->MakeRequest(channel); - } + dns_req = new DNS_Request(req->addr, true); else if ( req->is_txt ) - { - auto* m_req = new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt); - m_req->MakeRequest(channel); - } + dns_req = new DNS_Request(req->host.c_str(), AF_UNSPEC, T_TXT, true); else - { - // If only one request type succeeds, don't consider it a failure. - auto* m_req4 = new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt); - m_req4->MakeRequest(channel); - auto* m_req6 = new DNS_Mgr_Request(req->name.c_str(), AF_INET6, req->is_txt); - m_req6->MakeRequest(channel); - } + // We pass T_A here, but because we're passing AF_UNSPEC MakeRequest() will + // have c-ares attempt to lookup both ipv4 and ipv6 at the same time. + dns_req = new DNS_Request(req->host.c_str(), AF_UNSPEC, T_A, true); + + dns_req->MakeRequest(channel); asyncs_timeouts.push(req); - ++asyncs_pending; } } +void DNS_Mgr::CheckAsyncHostRequest(const std::string& host, bool timeout) + { + // Note that this code is a mirror of that for CheckAsyncAddrRequest. + + AsyncRequestNameMap::iterator i = asyncs_names.find(host); + + if ( i != asyncs_names.end() ) + { + if ( timeout ) + { + ++failed; + i->second->Timeout(); + } + else if ( auto addrs = LookupNameInCache(host, true, false) ) + { + ++successful; + i->second->Resolved(addrs); + } + else + return; + + delete i->second; + asyncs_names.erase(i); + --asyncs_pending; + } + } + void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout) { // Note that this code is a mirror of that for CheckAsyncHostRequest. @@ -995,101 +1205,57 @@ void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout) if ( i != asyncs_addrs.end() ) { - const char* name = LookupAddrInCache(addr); - if ( name ) - { - ++successful; - i->second->Resolved(name); - } - - else if ( timeout ) + if ( timeout ) { ++failed; i->second->Timeout(); } - + else if ( auto name = LookupAddrInCache(addr, true, false) ) + { + ++successful; + i->second->Resolved(name->CheckString()); + } else return; + delete i->second; asyncs_addrs.erase(i); --asyncs_pending; - - // Don't delete the request. That will be done once it - // eventually times out. } } -void DNS_Mgr::CheckAsyncTextRequest(const char* host, bool timeout) +void DNS_Mgr::CheckAsyncTextRequest(const std::string& host, bool timeout) { // Note that this code is a mirror of that for CheckAsyncAddrRequest. AsyncRequestTextMap::iterator i = asyncs_texts.find(host); if ( i != asyncs_texts.end() ) { - const char* name = LookupTextInCache(host); - if ( name ) - { - ++successful; - i->second->Resolved(name); - } - - else if ( timeout ) + if ( timeout ) { AsyncRequestTextMap::iterator it = asyncs_texts.begin(); ++failed; i->second->Timeout(); } - - else - return; - - asyncs_texts.erase(i); - --asyncs_pending; - - // Don't delete the request. That will be done once it - // eventually times out. - } - } - -void DNS_Mgr::CheckAsyncHostRequest(const char* host, bool timeout) - { - // Note that this code is a mirror of that for CheckAsyncAddrRequest. - - AsyncRequestNameMap::iterator i = asyncs_names.find(host); - - if ( i != asyncs_names.end() ) - { - auto addrs = LookupNameInCache(host); - - if ( addrs ) + else if ( auto name = LookupTextInCache(host, true) ) { ++successful; - i->second->Resolved(addrs.get()); + i->second->Resolved(name->CheckString()); } - - else if ( timeout ) - { - ++failed; - i->second->Timeout(); - } - else return; - asyncs_names.erase(i); + delete i->second; + asyncs_texts.erase(i); --asyncs_pending; - - // Don't delete the request. That will be done once it - // eventually times out. } } void DNS_Mgr::Flush() { - Process(); + Resolve(); - HostMap::iterator it; - for ( it = host_mappings.begin(); it != host_mappings.end(); ++it ) + for ( HostMap::iterator it = host_mappings.begin(); it != host_mappings.end(); ++it ) { delete it->second.first; delete it->second.second; @@ -1116,67 +1282,21 @@ double DNS_Mgr::GetNextTimeout() void DNS_Mgr::Process() { - while ( ! asyncs_timeouts.empty() ) + // If iosource_mgr says that we got a result on the socket fd, we don't have to ask c-ares + // to retrieve it for us. We have the file descriptor already, just call ares_process_fd() + // with it. Unfortunately, we may also have sockets close during this call, so we need to + // to make a copy of the list first. Having a list change while looping over it can + // cause segfaults. + decltype(socket_fds) temp_fds{socket_fds}; + + for ( int fd : temp_fds ) { - AsyncRequest* req = asyncs_timeouts.top(); - - if ( req->time + DNS_TIMEOUT > util::current_time() && ! run_state::terminating ) - break; - - if ( ! req->processed ) - { - if ( req->IsAddrReq() ) - CheckAsyncAddrRequest(req->host, true); - else if ( req->is_txt ) - CheckAsyncTextRequest(req->name.c_str(), true); - else - CheckAsyncHostRequest(req->name.c_str(), true); - } - - asyncs_timeouts.pop(); - delete req; + // double check this one wasn't removed already before trying to process it + if ( socket_fds.count(fd) != 0 ) + ares_process_fd(channel, fd, ARES_SOCKET_BAD); } - Resolve(); - - // TODO: what does the rest below do? - /* - char err[NB_DNS_ERRSIZE]; - struct nb_dns_result r; - - int status = nb_dns_activity(nb_dns, &r, err); - - if ( status < 0 ) - reporter->Warning("NB-DNS error in DNS_Mgr::Process (%s)", err); - - else if ( status > 0 ) - { - DNS_Mgr_Request* dr = (DNS_Mgr_Request*)r.cookie; - - bool do_host_timeout = true; - if ( dr->ReqHost() && host_mappings.find(dr->ReqHost()) == host_mappings.end() ) - // Don't timeout when this is the first result in an expected pair - // (one result each for A and AAAA queries). - do_host_timeout = false; - - if ( dr->RequestPending() ) - { - AddResult(dr, &r); - dr->RequestDone(); - } - - if ( ! dr->ReqHost() ) - CheckAsyncAddrRequest(dr->ReqAddr(), true); - else if ( dr->ReqIsTxt() ) - CheckAsyncTextRequest(dr->ReqHost(), do_host_timeout); - else - CheckAsyncHostRequest(dr->ReqHost(), do_host_timeout); - - IssueAsyncRequests(); - - delete dr; - } - */ + IssueAsyncRequests(); } void DNS_Mgr::GetStats(Stats* stats) @@ -1191,14 +1311,7 @@ void DNS_Mgr::GetStats(Stats* stats) stats->cached_texts = text_mappings.size(); } -void DNS_Mgr::TestProcess() - { - // Only allow usage of this method when running unit tests. - assert(doctest::is_running_in_test); - Process(); - } - -void DNS_Mgr::AsyncRequest::Resolved(const char* name) +void DNS_Mgr::AsyncRequest::Resolved(const std::string& name) { for ( const auto& cb : callbacks ) { @@ -1211,7 +1324,7 @@ void DNS_Mgr::AsyncRequest::Resolved(const char* name) processed = true; } -void DNS_Mgr::AsyncRequest::Resolved(TableVal* addrs) +void DNS_Mgr::AsyncRequest::Resolved(TableValPtr addrs) { for ( const auto& cb : callbacks ) { @@ -1252,7 +1365,7 @@ TableValPtr DNS_Mgr::empty_addr_set() ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// -static std::vector get_result_addresses(TableVal* addrs) +static std::vector get_result_addresses(TableValPtr addrs) { std::vector results; @@ -1275,12 +1388,12 @@ class TestCallback : public DNS_Mgr::LookupCallback { public: TestCallback() { } - void Resolved(const char* name) override + void Resolved(const std::string& name) override { host_result = name; done = true; } - void Resolved(TableVal* addrs) override + void Resolved(TableValPtr addrs) override { addr_results = get_result_addresses(addrs); done = true; @@ -1297,7 +1410,27 @@ public: bool timeout = false; }; -TEST_CASE("dns_mgr prime,save,load") +/** + * Derived testing version of DNS_Mgr so that the Process() method can be exposed + * publically. If new unit tests are added, this class should be used over using + * DNS_Mgr directly. + */ +class TestDNS_Mgr final : public DNS_Mgr + { +public: + explicit TestDNS_Mgr(DNS_MgrMode mode) : DNS_Mgr(mode) { } + void Process(); + }; + +void TestDNS_Mgr::Process() + { + // Only allow usage of this method when running unit tests. + assert(doctest::is_running_in_test); + Resolve(); + IssueAsyncRequests(); + } + +TEST_CASE("dns_mgr priming") { char prefix[] = "/tmp/zeek-unit-test-XXXXXX"; auto tmpdir = mkdtemp(prefix); @@ -1305,18 +1438,21 @@ TEST_CASE("dns_mgr prime,save,load") // Create a manager to prime the cache, make a few requests, and the save // the result. This tests that the priming code will create the requests but // wait for Resolve() to actually make the requests. - DNS_Mgr mgr(DNS_PRIME); + TestDNS_Mgr mgr(DNS_PRIME); + dns_mgr = &mgr; mgr.SetDir(tmpdir); mgr.InitPostScript(); auto host_result = mgr.LookupHost("one.one.one.one"); REQUIRE(host_result != nullptr); - CHECK(host_result->EqualTo(DNS_Mgr::empty_addr_set())); + CHECK(host_result->EqualTo(TestDNS_Mgr::empty_addr_set())); IPAddr ones("1.1.1.1"); auto addr_result = mgr.LookupAddr(ones); CHECK(strcmp(addr_result->CheckString(), "") == 0); + // This should wait until we have all of the results back from the above + // requests. mgr.Resolve(); // Save off the resulting values from Resolve() into a file on disk @@ -1324,7 +1460,8 @@ TEST_CASE("dns_mgr prime,save,load") REQUIRE(mgr.Save()); // Make a second DNS manager and reload the cache that we just saved. - DNS_Mgr mgr2(DNS_FORCE); + TestDNS_Mgr mgr2(DNS_FORCE); + dns_mgr = &mgr2; mgr2.SetDir(tmpdir); mgr2.InitPostScript(); @@ -1332,11 +1469,15 @@ TEST_CASE("dns_mgr prime,save,load") // data out of the cache. host_result = mgr2.LookupHost("one.one.one.one"); REQUIRE(host_result != nullptr); - CHECK_FALSE(host_result->EqualTo(DNS_Mgr::empty_addr_set())); + CHECK_FALSE(host_result->EqualTo(TestDNS_Mgr::empty_addr_set())); addr_result = mgr2.LookupAddr(ones); REQUIRE(addr_result != nullptr); CHECK(strcmp(addr_result->CheckString(), "one.one.one.one") == 0); + + // Clean up cache file and the temp directory + unlink(mgr2.CacheFile().c_str()); + rmdir(tmpdir); } TEST_CASE("dns_mgr alternate server") @@ -1344,7 +1485,9 @@ TEST_CASE("dns_mgr alternate server") char* old_server = getenv("ZEEK_DNS_RESOLVER"); setenv("ZEEK_DNS_RESOLVER", "1.1.1.1", 1); - DNS_Mgr mgr(DNS_DEFAULT); + TestDNS_Mgr mgr(DNS_DEFAULT); + dns_mgr = &mgr; + mgr.InitPostScript(); auto result = mgr.LookupAddr("1.1.1.1"); @@ -1353,7 +1496,7 @@ TEST_CASE("dns_mgr alternate server") // FIXME: This won't run on systems without IPv6 connectivity. // setenv("ZEEK_DNS_RESOLVER", "2606:4700:4700::1111", 1); - // DNS_Mgr mgr2(DNS_DEFAULT, true); + // TestDNS_Mgr mgr2(DNS_DEFAULT, true); // mgr2.InitPostScript(); // result = mgr2.LookupAddr("1.1.1.1"); // mgr2.Resolve(); @@ -1369,15 +1512,16 @@ TEST_CASE("dns_mgr alternate server") TEST_CASE("dns_mgr default mode") { - DNS_Mgr mgr(DNS_DEFAULT); + TestDNS_Mgr mgr(DNS_DEFAULT); + dns_mgr = &mgr; mgr.InitPostScript(); IPAddr ones("1.1.1.1"); auto host_result = mgr.LookupHost("one.one.one.one"); REQUIRE(host_result != nullptr); - CHECK_FALSE(host_result->EqualTo(DNS_Mgr::empty_addr_set())); + CHECK_FALSE(host_result->EqualTo(TestDNS_Mgr::empty_addr_set())); - auto addrs_from_request = get_result_addresses(host_result.get()); + auto addrs_from_request = get_result_addresses(host_result); auto it = std::find(addrs_from_request.begin(), addrs_from_request.end(), ones); CHECK(it != addrs_from_request.end()); @@ -1393,18 +1537,19 @@ TEST_CASE("dns_mgr default mode") TEST_CASE("dns_mgr async host") { - DNS_Mgr mgr(DNS_DEFAULT); + TestDNS_Mgr mgr(DNS_DEFAULT); + dns_mgr = &mgr; mgr.InitPostScript(); TestCallback cb{}; - mgr.AsyncLookupName("one.one.one.one", &cb); + mgr.LookupHost("one.one.one.one", &cb); // This shouldn't take any longer than DNS_TIMEOUT+1 seconds, so bound it // just in case of some failure we're not aware of yet. int count = 0; while ( ! cb.done && (count < DNS_TIMEOUT + 1) ) { - mgr.TestProcess(); + mgr.Process(); sleep(1); if ( ! cb.timeout ) count++; @@ -1424,18 +1569,19 @@ TEST_CASE("dns_mgr async host") TEST_CASE("dns_mgr async addr") { - DNS_Mgr mgr(DNS_DEFAULT); + TestDNS_Mgr mgr(DNS_DEFAULT); + dns_mgr = &mgr; mgr.InitPostScript(); TestCallback cb{}; - mgr.AsyncLookupAddr(IPAddr{"1.1.1.1"}, &cb); + mgr.LookupAddr(IPAddr{"1.1.1.1"}, &cb); // This shouldn't take any longer than DNS_TIMEOUT +1 seconds, so bound it // just in case of some failure we're not aware of yet. int count = 0; while ( ! cb.done && (count < DNS_TIMEOUT + 1) ) { - mgr.TestProcess(); + mgr.Process(); sleep(1); if ( ! cb.timeout ) count++; @@ -1450,18 +1596,19 @@ TEST_CASE("dns_mgr async addr") TEST_CASE("dns_mgr async text") { - DNS_Mgr mgr(DNS_DEFAULT); + TestDNS_Mgr mgr(DNS_DEFAULT); + dns_mgr = &mgr; mgr.InitPostScript(); TestCallback cb{}; - mgr.AsyncLookupNameText("unittest.zeek.org", &cb); + mgr.Lookup("unittest.zeek.org", T_TXT, &cb); // This shouldn't take any longer than DNS_TIMEOUT +1 seconds, so bound it // just in case of some failure we're not aware of yet. int count = 0; while ( ! cb.done && (count < DNS_TIMEOUT + 1) ) { - mgr.TestProcess(); + mgr.Process(); sleep(1); if ( ! cb.timeout ) count++; @@ -1482,7 +1629,7 @@ TEST_CASE("dns_mgr timeouts") // server that lets you connect but never returns any responses, always // resulting in a timeout. setenv("ZEEK_DNS_RESOLVER", "3.219.212.117", 1); - DNS_Mgr mgr(DNS_DEFAULT); + TestDNS_Mgr mgr(DNS_DEFAULT); dns_mgr = &mgr; mgr.InitPostScript(); @@ -1492,7 +1639,7 @@ TEST_CASE("dns_mgr timeouts") auto host_result = mgr.LookupHost("one.one.one.one"); REQUIRE(host_result != nullptr); - auto addresses = get_result_addresses(host_result.get()); + auto addresses = get_result_addresses(host_result); CHECK(addresses.size() == 0); if ( old_server ) @@ -1509,19 +1656,19 @@ TEST_CASE("dns_mgr async timeouts") // server that lets you connect but never returns any responses, always // resulting in a timeout. setenv("ZEEK_DNS_RESOLVER", "3.219.212.117", 1); - DNS_Mgr mgr(DNS_DEFAULT); + TestDNS_Mgr mgr(DNS_DEFAULT); dns_mgr = &mgr; mgr.InitPostScript(); TestCallback cb{}; - mgr.AsyncLookupNameText("unittest.zeek.org", &cb); + mgr.Lookup("unittest.zeek.org", T_TXT, &cb); - // This shouldn't take any longer than DNS_TIMEOUT +2 seconds, so bound it + // This shouldn't take any longer than DNS_TIMEOUT +1 seconds, so bound it // just in case of some failure we're not aware of yet. int count = 0; while ( ! cb.done && (count < DNS_TIMEOUT + 1) ) { - mgr.TestProcess(); + mgr.Process(); sleep(1); if ( ! cb.timeout ) count++; diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index e5bfba9689..5f6204f45d 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -2,7 +2,7 @@ #pragma once -#include +#include #include #include #include @@ -14,6 +14,18 @@ #include "zeek/iosource/IOSource.h" #include "zeek/util.h" +// These are defined in ares headers but we don't want to have to include +// those headers here and create install dependencies on them. +struct ares_channeldata; +typedef struct ares_channeldata* ares_channel; +#ifndef T_PTR +#define T_PTR 12 +#endif + +#ifndef T_TXT +#define T_TXT 16 +#endif + namespace zeek { class Val; @@ -31,8 +43,8 @@ using StringValPtr = IntrusivePtr; namespace zeek::detail { -class DNS_Mgr_Request; class DNS_Mapping; +class DNS_Request; enum DNS_MgrMode { @@ -42,9 +54,44 @@ enum DNS_MgrMode DNS_FAKE, // don't look up names, just return dummy results }; -class DNS_Mgr final : public iosource::IOSource +class DNS_Mgr : public iosource::IOSource { public: + /** + * Base class for callback handling for asynchronous lookups. + */ + class LookupCallback + { + public: + virtual ~LookupCallback() = default; + + /** + * Called when an address lookup finishes. + * + * @param name The resulting name from the lookup. + */ + virtual void Resolved(const std::string& name){}; + + /** + * Called when a name lookup finishes. + * + * @param addrs A table of the resulting addresses from the lookup. + */ + virtual void Resolved(TableValPtr addrs){}; + + /** + * Generic callback method for all request types. + * + * @param val A Val containing the data from the query. + */ + virtual void Resolved(ValPtr data, int request_type) { } + + /** + * Called when a timeout request occurs. + */ + virtual void Timeout() = 0; + }; + explicit DNS_Mgr(DNS_MgrMode mode); ~DNS_Mgr() override; @@ -61,27 +108,79 @@ public: void Flush(); /** - * Looks up the address(es) of a given host and returns a set of addr. - * This is a synchronous method and will block until results are ready. + * Looks up the address(es) of a given host and returns a set of addresses. + * This is a shorthand method for doing A/AAAA requests. This is a + * synchronous request and will block until the request completes or times + * out. * - * @param host The host name to look up an address for. - * @return A set of addresses. + * @param host The hostname to lookup an address for. + * @return A set of addresses for the host. */ - TableValPtr LookupHost(const char* host); + TableValPtr LookupHost(const std::string& host); /** - * Looks up the hostname of a given address. This is a synchronous method - * and will block until results are ready. + * Looks up the hostname of a given address. This is a shorthand method for + * doing PTR requests. This is a synchronous request and will block until + * the request completes or times out. * * @param host The addr to lookup a hostname for. - * @return The hostname. + * @return The hostname for the address. */ StringValPtr LookupAddr(const IPAddr& addr); + /** + * Performs a generic request to the DNS server. This is a synchronous + * request and will block until the request completes or times out. + * + * @param name The name or address to make a request for. If this is an + * address it should be in arpa format (x.x.x.x.in-addr.arpa or x-*.ip6.arpa). + * Note that calling LookupAddr for PTR requests does this conversion + * automatically. + * @param request_type The type of request to make. This should be one of + * the type values defined in arpa/nameser.h or ares_nameser.h. + * @return The requested data. + */ + ValPtr Lookup(const std::string& name, int request_type); + + /** + * Looks up the address(es) of a given host. This is a shorthand method + * for doing A/AAAA requests. This is an asynchronous request. The + * response will be handled via the provided callback object. + * + * @param host The hostname to lookup an address for. + * @param callback A callback object for handling the response. + */ + void LookupHost(const std::string& host, LookupCallback* callback); + + /** + * Looks up the hostname of a given address. This is a shorthand method for + * doing PTR requests. This is an asynchronous request. The response will + * be handled via the provided callback object. + * + * @param host The addr to lookup a hostname for. + * @param callback A callback object for handling the response. + */ + void LookupAddr(const IPAddr& addr, LookupCallback* callback); + + /** + * Performs a generic request to the DNS server. This is an asynchronous + * request. The response will be handled via the provided callback + * object. + * + * @param name The name or address to make a request for. If this is an + * address it should be in arpa format (x.x.x.x.in-addr.arpa or x-*.ip6.arpa). + * Note that calling LookupAddr for PTR requests does this conversion + * automatically. + * @param request_type The type of request to make. This should be one of + * the type values defined in arpa/nameser.h or ares_nameser.h. + * @param callback A callback object for handling the response. + */ + void Lookup(const std::string& name, int request_type, LookupCallback* callback); + /** * Sets the directory where to store DNS data when Save() is called. */ - void SetDir(const char* arg_dir) { dir = arg_dir; } + void SetDir(const std::string& arg_dir) { dir = arg_dir; } /** * Waits for responses to become available or a timeout to occur, @@ -94,61 +193,6 @@ public: */ bool Save(); - /** - * Base class for callback handling for asynchronous lookups. - */ - class LookupCallback - { - public: - virtual ~LookupCallback() = default; - - /** - * Called when an address lookup finishes. - * - * @param name The resulting name from the lookup. - */ - virtual void Resolved(const char* name){}; - - /** - * Called when a name lookup finishes. - * - * @param addrs A table of the resulting addresses from the lookup. - */ - virtual void Resolved(TableVal* addrs){}; - - /** - * Called when a timeout request occurs. - */ - virtual void Timeout() = 0; - }; - - /** - * Schedules an asynchronous request to lookup a hostname for an IP address. - * This is the equivalent of an "A" or "AAAA" request, depending on if the - * address is ipv4 or ipv6. - * - * @param host The address to lookup names for. - * @param callback A callback object to call when the request completes. - */ - void AsyncLookupAddr(const IPAddr& host, LookupCallback* callback); - - /** - * Schedules an asynchronous request to lookup an address for a hostname. - * This is the equivalent of a "PTR" request. - * - * @param host The hostname to look up addresses for. - * @param callback A callback object to call when the request completes. - */ - void AsyncLookupName(const std::string& name, LookupCallback* callback); - - /** - * Schedules an asynchronous TXT request for a hostname. - * - * @param host The address to lookup names for. - * @param callback A callback object to call when the request completes. - */ - void AsyncLookupNameText(const std::string& name, LookupCallback* callback); - struct Stats { unsigned long requests; // These count only async requests. @@ -175,7 +219,7 @@ public: * @param h A hostent structure containing the actual result data. * @param ttl A ttl value contained in the response from the server. */ - void AddResult(DNS_Mgr_Request* dr, struct hostent* h, uint32_t ttl); + void AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl); /** * Returns an empty set of addresses, used in various error cases and during @@ -184,18 +228,30 @@ public: static TableValPtr empty_addr_set(); /** - * This method is used to call the private Process() method during unit testing - * and shouldn't be used otherwise. + * Returns the full path to the file used to store the DNS cache. */ - void TestProcess(); + std::string CacheFile() const { return cache_name; } + + /** + * Used by the c-ares socket call back to register/unregister a socket file descriptor. + */ + void RegisterSocket(int fd, bool active); protected: friend class LookupCallback; - friend class DNS_Mgr_Request; + friend class DNS_Request; - const char* LookupAddrInCache(const IPAddr& addr); - TableValPtr LookupNameInCache(const std::string& name); - const char* LookupTextInCache(const std::string& name); + StringValPtr LookupAddrInCache(const IPAddr& addr, bool cleanup_expired = false, + bool check_failed = false); + TableValPtr LookupNameInCache(const std::string& name, bool cleanup_expired = false, + bool check_failed = false); + StringValPtr LookupTextInCache(const std::string& name, bool cleanup_expired = false); + + // Finish the request if we have a result. If not, time it out if + // requested. + void CheckAsyncAddrRequest(const IPAddr& addr, bool timeout); + void CheckAsyncHostRequest(const std::string& host, bool timeout); + void CheckAsyncTextRequest(const std::string& host, bool timeout); void Event(EventHandlerPtr e, DNS_Mapping* dm); void Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2); @@ -205,7 +261,6 @@ protected: void CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm); ListValPtr AddrListDelta(ListVal* al1, ListVal* al2); - void DumpAddrList(FILE* f, ListVal* al); using HostMap = std::map>; using AddrMap = std::map; @@ -217,12 +272,6 @@ protected: // Issue as many queued async requests as slots are available. void IssueAsyncRequests(); - // Finish the request if we have a result. If not, time it out if - // requested. - void CheckAsyncAddrRequest(const IPAddr& addr, bool timeout); - void CheckAsyncHostRequest(const char* host, bool timeout); - void CheckAsyncTextRequest(const char* host, bool timeout); - // IOSource interface. void Process() override; void InitSource() override; @@ -235,9 +284,6 @@ protected: AddrMap addr_mappings; TextMap text_mappings; - using DNS_mgr_request_list = PList; - DNS_mgr_request_list requests; - std::string cache_name; std::string dir; // directory in which cache_name resides @@ -247,26 +293,30 @@ protected: RecordTypePtr dm_rec; ares_channel channel; - bool ipv6_resolver = false; using CallbackList = std::list; struct AsyncRequest { double time = 0.0; - IPAddr host; - std::string name; + IPAddr addr; + std::string host; CallbackList callbacks; bool is_txt = false; bool processed = false; - bool IsAddrReq() const { return name.empty(); } + bool IsAddrReq() const { return host.empty(); } - void Resolved(const char* name); - void Resolved(TableVal* addrs); + void Resolved(const std::string& name); + void Resolved(TableValPtr addrs); void Timeout(); }; + struct AsyncRequestCompare + { + bool operator()(const AsyncRequest* a, const AsyncRequest* b) { return a->time > b->time; } + }; + using AsyncRequestAddrMap = std::map; AsyncRequestAddrMap asyncs_addrs; @@ -279,18 +329,15 @@ protected: using QueuedList = std::list; QueuedList asyncs_queued; - struct AsyncRequestCompare - { - bool operator()(const AsyncRequest* a, const AsyncRequest* b) { return a->time > b->time; } - }; - using TimeoutQueue = std::priority_queue, AsyncRequestCompare>; TimeoutQueue asyncs_timeouts; - unsigned long num_requests; - unsigned long successful; - unsigned long failed; + unsigned long num_requests = 0; + unsigned long successful = 0; + unsigned long failed = 0; + + std::set socket_fds; }; extern DNS_Mgr* dns_mgr; diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 551dd003fc..952db62b4f 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -342,8 +342,7 @@ static void terminate_zeek() delete packet_mgr; delete analyzer_mgr; delete file_mgr; - delete dns_mgr; - // broker_mgr, timer_mgr, and supervisor are deleted via iosource_mgr + // broker_mgr, timer_mgr, supervisor, and dns_mgr are deleted via iosource_mgr delete iosource_mgr; delete event_registry; delete log_mgr; @@ -757,7 +756,6 @@ SetupResult setup(int argc, char** argv, Options* zopts) file_mgr->InitPostScript(); dns_mgr->InitPostScript(); - dns_mgr->LookupHost("www.apple.com"); // dns_mgr->LookupAddr("17.253.144.10"); #ifdef USE_PERFTOOLS_DEBUG diff --git a/src/zeek.bif b/src/zeek.bif index 3fd41e0901..4665831d65 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -3642,8 +3642,8 @@ function dump_packet%(pkt: pcap_packet, file_name: string%) : bool class LookupHostCallback : public zeek::detail::DNS_Mgr::LookupCallback { public: - LookupHostCallback(zeek::detail::trigger::Trigger* arg_trigger, const zeek::detail::CallExpr* arg_call, - bool arg_lookup_name) + LookupHostCallback(zeek::detail::trigger::Trigger* arg_trigger, + const zeek::detail::CallExpr* arg_call, bool arg_lookup_name) { Ref(arg_trigger); trigger = arg_trigger; @@ -3657,7 +3657,7 @@ public: } // Overridden from zeek::detail::DNS_Mgr:Lookup:Callback. - void Resolved(const char* name) override + void Resolved(const std::string& name) override { zeek::Val* result = new zeek::StringVal(name); trigger->Cache(call, result); @@ -3665,10 +3665,10 @@ public: trigger->Release(); } - void Resolved(zeek::TableVal* addrs) override + void Resolved(zeek::TableValPtr addrs) override { // No Ref() for addrs. - trigger->Cache(call, addrs); + trigger->Cache(call, addrs.get()); trigger->Release(); } @@ -3724,7 +3724,7 @@ function lookup_addr%(host: addr%) : string frame->SetDelayed(); trigger->Hold(); - zeek::detail::dns_mgr->AsyncLookupAddr(host->AsAddr(), + zeek::detail::dns_mgr->LookupAddr(host->AsAddr(), new LookupHostCallback(trigger, frame->GetCall(), true)); return nullptr; %} @@ -3753,7 +3753,7 @@ function lookup_hostname_txt%(host: string%) : string frame->SetDelayed(); trigger->Hold(); - zeek::detail::dns_mgr->AsyncLookupNameText(host->CheckString(), + zeek::detail::dns_mgr->Lookup(host->CheckString(), T_TXT, new LookupHostCallback(trigger, frame->GetCall(), true)); return nullptr; %} @@ -3782,7 +3782,7 @@ function lookup_hostname%(host: string%) : addr_set frame->SetDelayed(); trigger->Hold(); - zeek::detail::dns_mgr->AsyncLookupName(host->CheckString(), + zeek::detail::dns_mgr->LookupHost(host->CheckString(), new LookupHostCallback(trigger, frame->GetCall(), false)); return nullptr; %} From 3bdc744b146c930e25f1eb8078318453e55cdb80 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 27 Jan 2022 14:44:30 -0700 Subject: [PATCH 172/204] Add merging to DNS_Mgr::AddResult() to support both ipv4 and ipv6 responses simultaneously --- src/DNS_Mapping.cc | 6 ++ src/DNS_Mapping.h | 4 +- src/DNS_Mgr.cc | 165 +++++++++++++++++++++++++++++---------------- src/DNS_Mgr.h | 5 +- 4 files changed, 120 insertions(+), 60 deletions(-) diff --git a/src/DNS_Mapping.cc b/src/DNS_Mapping.cc index 73c804bae1..d0de26b016 100644 --- a/src/DNS_Mapping.cc +++ b/src/DNS_Mapping.cc @@ -167,6 +167,12 @@ void DNS_Mapping::Save(FILE* f) const fprintf(f, "%s\n", addr.AsString().c_str()); } +void DNS_Mapping::Merge(DNS_Mapping* other) + { + std::copy(other->names.begin(), other->names.end(), std::back_inserter(names)); + std::copy(other->addrs.begin(), other->addrs.end(), std::back_inserter(addrs)); + } + ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/DNS_Mapping.h b/src/DNS_Mapping.h index 34a3aff7d5..c9b3ea6c03 100644 --- a/src/DNS_Mapping.h +++ b/src/DNS_Mapping.h @@ -52,6 +52,8 @@ public: int Type() const { return map_type; } + void Merge(DNS_Mapping* other); + protected: friend class DNS_Mgr; @@ -70,7 +72,7 @@ protected: ListValPtr addrs_val; double creation_time = 0.0; - int map_type = 0; + int map_type = AF_UNSPEC; bool no_mapping = false; // when initializing from a file, immediately hit EOF bool init_failed = false; bool failed = false; diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 0165808a3a..7f5ca7c74d 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -76,7 +76,7 @@ public: private: std::string host; IPAddr addr; - int family = 0; // address family query type for host requests + int family = AF_UNSPEC; // address family query type for host requests int request_type = 0; // Query type bool async = false; unsigned char* query = nullptr; @@ -92,8 +92,6 @@ DNS_Request::DNS_Request(std::string host, int af, int request_type, bool async) DNS_Request::DNS_Request(const IPAddr& addr, bool async) : addr(addr), async(async) { - // TODO: AF_UNSPEC for T_PTR requests? - family = addr.GetFamily() == IPv4 ? AF_INET : AF_INET6; request_type = T_PTR; } @@ -248,27 +246,22 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf delete[] he.h_name; } - // TODO: We can't do this here because we blow up the mapping added above by doing so. - // We need some sort of "merge mapping" mode in AddResult for this to work to add new - // IPs to an existing mapping. - /* - if ( ! addrs6.empty() ) - { - // Push a null on the end so the addr list has a final point during later parsing. - addrs6.push_back(NULL); + if ( ! addrs6.empty() ) + { + // Push a null on the end so the addr list has a final point during later parsing. + addrs6.push_back(NULL); - struct hostent he; - memset(&he, 0, sizeof(struct hostent)); - he.h_name = util::copy_string(result->name); - he.h_addrtype = AF_INET6; - he.h_length = sizeof(in6_addr); - he.h_addr_list = reinterpret_cast(addrs6.data()); + struct hostent he; + memset(&he, 0, sizeof(struct hostent)); + he.h_name = util::copy_string(result->name); + he.h_addrtype = AF_INET6; + he.h_length = sizeof(in6_addr); + he.h_addr_list = reinterpret_cast(addrs6.data()); - dns_mgr->AddResult(req, &he, result->nodes[0].ai_ttl); + dns_mgr->AddResult(req, &he, result->nodes[0].ai_ttl, true); - delete[] he.h_name; - } - */ + delete[] he.h_name; + } } req->ProcessAsyncResult(timeouts > 0); @@ -815,35 +808,45 @@ ValPtr DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) return r; } -void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl) +void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl, bool merge) { // TODO: the existing code doesn't handle hostname aliases at all. Should we? - DNS_Mapping* new_mapping; - DNS_Mapping* prev_mapping; - bool keep_prev = false; + DNS_Mapping* new_mapping = nullptr; + DNS_Mapping* prev_mapping = nullptr; + bool keep_prev = true; if ( ! dr->Host().empty() ) { new_mapping = new DNS_Mapping(dr->Host(), h, ttl); - prev_mapping = nullptr; if ( dr->IsTxt() ) { TextMap::iterator it = text_mappings.find(dr->Host()); if ( it == text_mappings.end() ) - text_mappings[dr->Host()] = new_mapping; + { + auto result = text_mappings.emplace(dr->Host(), new_mapping); + it = result.first; + } + else + prev_mapping = it->second; + + if ( prev_mapping && prev_mapping->Valid() ) + { + if ( new_mapping->Valid() ) + { + if ( merge ) + new_mapping->Merge(prev_mapping); + + it->second = new_mapping; + keep_prev = false; + } + } else { - prev_mapping = it->second; it->second = new_mapping; - } - - if ( new_mapping->Failed() && prev_mapping && prev_mapping->Valid() ) - { - text_mappings[dr->Host()] = prev_mapping; - keep_prev = true; + keep_prev = false; } } else @@ -851,50 +854,88 @@ void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl) HostMap::iterator it = host_mappings.find(dr->Host()); if ( it == host_mappings.end() ) { - host_mappings[dr->Host()].first = new_mapping->Type() == AF_INET ? new_mapping - : nullptr; + std::pair result; - host_mappings[dr->Host()].second = new_mapping->Type() == AF_INET ? nullptr - : new_mapping; + if ( new_mapping->Type() == AF_INET ) + result = host_mappings.emplace(dr->Host(), std::pair{new_mapping, nullptr}); + else + result = host_mappings.emplace(dr->Host(), std::pair{nullptr, new_mapping}); + + it = result.first; } else { if ( new_mapping->Type() == AF_INET ) - { prev_mapping = it->second.first; + else + prev_mapping = it->second.second; + } + + if ( prev_mapping && new_mapping->Type() != prev_mapping->Type() ) + { + if ( new_mapping->Type() == AF_INET ) + { + prev_mapping = it->second.second; it->second.first = new_mapping; } else { - prev_mapping = it->second.second; + prev_mapping = it->second.first; it->second.second = new_mapping; } } - - if ( new_mapping->Failed() && prev_mapping && prev_mapping->Valid() ) + else if ( prev_mapping && prev_mapping->Valid() ) { - // Put previous, valid entry back - CompareMappings - // will generate a corresponding warning. - if ( prev_mapping->Type() == AF_INET ) - host_mappings[dr->Host()].first = prev_mapping; - else - host_mappings[dr->Host()].second = prev_mapping; + if ( new_mapping->Valid() ) + { + if ( merge ) + new_mapping->Merge(prev_mapping); - keep_prev = true; + keep_prev = false; + if ( new_mapping->Type() == AF_INET ) + it->second.first = new_mapping; + else + it->second.second = new_mapping; + } + } + else + { + keep_prev = false; + if ( new_mapping->Type() == AF_INET ) + it->second.first = new_mapping; + else + it->second.second = new_mapping; } } } else { new_mapping = new DNS_Mapping(dr->Addr(), h, ttl); - AddrMap::iterator it = addr_mappings.find(dr->Addr()); - prev_mapping = (it == addr_mappings.end()) ? 0 : it->second; - addr_mappings[dr->Addr()] = new_mapping; - if ( new_mapping->Failed() && prev_mapping && prev_mapping->Valid() ) + AddrMap::iterator it = addr_mappings.find(dr->Addr()); + if ( it == addr_mappings.end() ) { - addr_mappings[dr->Addr()] = prev_mapping; - keep_prev = true; + auto result = addr_mappings.emplace(dr->Addr(), new_mapping); + it = result.first; + } + else + prev_mapping = it->second; + + if ( prev_mapping && prev_mapping->Valid() ) + { + if ( new_mapping->Valid() ) + { + if ( merge ) + new_mapping->Merge(prev_mapping); + + it->second = new_mapping; + keep_prev = false; + } + } + else + { + it->second = new_mapping; + keep_prev = false; } } @@ -1516,16 +1557,24 @@ TEST_CASE("dns_mgr default mode") dns_mgr = &mgr; mgr.InitPostScript(); - IPAddr ones("1.1.1.1"); + IPAddr ones4("1.1.1.1"); + IPAddr ones6("2606:4700:4700::1111"); + auto host_result = mgr.LookupHost("one.one.one.one"); REQUIRE(host_result != nullptr); CHECK_FALSE(host_result->EqualTo(TestDNS_Mgr::empty_addr_set())); auto addrs_from_request = get_result_addresses(host_result); - auto it = std::find(addrs_from_request.begin(), addrs_from_request.end(), ones); + auto it = std::find(addrs_from_request.begin(), addrs_from_request.end(), ones4); + CHECK(it != addrs_from_request.end()); + it = std::find(addrs_from_request.begin(), addrs_from_request.end(), ones6); CHECK(it != addrs_from_request.end()); - auto addr_result = mgr.LookupAddr(ones); + auto addr_result = mgr.LookupAddr(ones4); + REQUIRE(addr_result != nullptr); + CHECK(strcmp(addr_result->CheckString(), "one.one.one.one") == 0); + + addr_result = mgr.LookupAddr(ones6); REQUIRE(addr_result != nullptr); CHECK(strcmp(addr_result->CheckString(), "one.one.one.one") == 0); diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index 5f6204f45d..1d5d2fffc2 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -218,8 +218,11 @@ public: * @param dr The request associated with the result. * @param h A hostent structure containing the actual result data. * @param ttl A ttl value contained in the response from the server. + * @param merge A flag for whether these results should be merged into + * an existing mapping. If false, AddResult will attempt to replace the + * existing mapping with the new data and delete the old mapping. */ - void AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl); + void AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl, bool merge = false); /** * Returns an empty set of addresses, used in various error cases and during From c5b70cc286bd606b20764f48922594f82c95ecfd Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 28 Jan 2022 14:05:38 -0700 Subject: [PATCH 173/204] Move PTR request handling to ares_create_query() --- src/DNS_Mgr.cc | 207 +++++++++++++++++++++++++++++-------------------- 1 file changed, 123 insertions(+), 84 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 7f5ca7c74d..a2ed608c05 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -51,8 +51,6 @@ constexpr int MAX_PENDING_REQUESTS = 20; namespace zeek::detail { - -static void hostbyaddr_cb(void* arg, int status, int timeouts, struct hostent* hostent); static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinfo* result); static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, int len); static void sock_cb(void* data, int s, int read, int write); @@ -60,13 +58,12 @@ static void sock_cb(void* data, int s, int read, int write); class DNS_Request { public: - DNS_Request(std::string host, int af, int request_type, bool async = false); - explicit DNS_Request(const IPAddr& addr, bool async = false); + DNS_Request(std::string host, int request_type, bool async = false); + DNS_Request(const IPAddr& addr, bool async = false); ~DNS_Request(); std::string Host() const { return host; } const IPAddr& Addr() const { return addr; } - int Family() const { return family; } int RequestType() const { return request_type; } bool IsTxt() const { return request_type == 16; } @@ -76,7 +73,6 @@ public: private: std::string host; IPAddr addr; - int family = AF_UNSPEC; // address family query type for host requests int request_type = 0; // Query type bool async = false; unsigned char* query = nullptr; @@ -85,8 +81,8 @@ private: uint16_t DNS_Request::request_id = 0; -DNS_Request::DNS_Request(std::string host, int af, int request_type, bool async) - : host(std::move(host)), family(af), request_type(request_type), async(async) +DNS_Request::DNS_Request(std::string host, int request_type, bool async) + : host(std::move(host)), request_type(request_type), async(async) { } @@ -108,46 +104,28 @@ void DNS_Request::MakeRequest(ares_channel channel) // all of them would be in flight at the same time. DNS_Request::request_id++; - // TODO: how the heck do file lookups work? gethostbyname_file exists but gethostbyaddr_file - // doesn't. But then the code in ares_gethostbyaddr.c can switch on the setting in the channel - // for whether we should look at the file or not. If we don't care about file lookups at all, - // the T_PTR case below can be simplified and moved down into the else block. - - // We do normal host and address lookups via the specialized methods for them - // because those will attempt to do file lookups as well internally before - // reaching out to the DNS server. The remaining lookup types all use - // ares_create_query() and ares_send() for more genericness. if ( request_type == T_A || request_type == T_AAAA ) { - // TODO: gethostbyname_file? - // Use getaddrinfo here because it gives us the ttl information. If we don't - // care about TTL, we could use gethostbyname instead. - ares_addrinfo_hints hints = {ARES_AI_CANONNAME, family, 0, 0}; + // For A/AAAA requests, we use a different method than the other requests. Since + // we're using the AF_UNSPEC family, we get both the ipv4 and ipv6 responses + // back in the same request if use ares_getaddrinfo() so we can store them both + // in the same mapping. + ares_addrinfo_hints hints = {ARES_AI_CANONNAME, AF_UNSPEC, 0, 0}; ares_getaddrinfo(channel, host.c_str(), NULL, &hints, addrinfo_cb, this); } - else if ( request_type == T_PTR ) - { - if ( addr.GetFamily() == IPv4 ) - { - struct sockaddr_in sa; - inet_pton(AF_INET, addr.AsString().c_str(), &(sa.sin_addr)); - ares_gethostbyaddr(channel, &sa.sin_addr, sizeof(sa.sin_addr), AF_INET, hostbyaddr_cb, - this); - } - else - { - struct sockaddr_in6 sa; - inet_pton(AF_INET6, addr.AsString().c_str(), &(sa.sin6_addr)); - ares_gethostbyaddr(channel, &sa.sin6_addr, sizeof(sa.sin6_addr), AF_INET6, - hostbyaddr_cb, this); - } - } else { + std::string query_host; + if ( request_type == T_PTR ) + query_host = addr.PtrName(); + else + query_host = host; + unsigned char* query = NULL; int len = 0; - int status = ares_create_query(host.c_str(), C_IN, request_type, DNS_Request::request_id, 1, - &query, &len, 0); + int status = ares_create_query(query_host.c_str(), C_IN, request_type, + DNS_Request::request_id, 1, &query, &len, 0); + if ( status != ARES_SUCCESS ) return; @@ -171,30 +149,58 @@ void DNS_Request::ProcessAsyncResult(bool timed_out) } /** - * Called in response to ares_gethostbyaddr requests. Sends the hostent data to the - * DNS manager via AddResult(). + * Retrieves the TTL value from the first RR in the response. + * + * This code is adapted from an internal c-ares method called * ares__parse_into_addrinfo, + * which is used for ares_getaddrinfo callbacks. It's also the only method that properly + * parses out TTL data currently. This skips over the question and the first bit of the + * response to get to the first RR, and then returns the TTL from that RR. We only use the + * first RR because it's a good approximation for now, at least until the work in c-ares + * lands to add TTL support to the other RR-parsing methods. + * + * @param abuf The buffer containing the entire response from the server. + * @param alen The length of the buffer + * @param ttl An out param for returning the TTL value. + * @return A status code from c-ares. This will be ARES_SUCCESS on success, or some other + * code on failure. */ -static void hostbyaddr_cb(void* arg, int status, int timeouts, struct hostent* host) +static int get_ttl(unsigned char* abuf, int alen, int* ttl) { - auto req = reinterpret_cast(arg); + int status; + long len; + char* hostname = NULL; - if ( ! host || status != ARES_SUCCESS ) + *ttl = DNS_TIMEOUT; + + unsigned char* aptr = abuf + HFIXEDSZ; + status = ares_expand_name(aptr, abuf, alen, &hostname, &len); + if ( status != ARES_SUCCESS ) { - printf("Failed hostbyaddr request: %s\n", ares_strerror(status)); - // TODO: pass DNS_TIMEOUT for the TTL here just so things work for testing. This - // will absolutely need to get the data from the request somehow instead. See - // https://github.com/c-ares/c-ares/issues/387. - dns_mgr->AddResult(req, nullptr, DNS_TIMEOUT); + ares_free_string(hostname); + return status; } - else + if ( aptr + len + QFIXEDSZ > abuf + alen ) { - // TODO: pass DNS_TIMEOUT for the TTL here just so things work for testing. This - // will absolutely need to get the data from the request somehow instead. See - // https://github.com/c-ares/c-ares/issues/387. - dns_mgr->AddResult(req, host, DNS_TIMEOUT); + ares_free_string(hostname); + return ARES_EBADRESP; } - req->ProcessAsyncResult(timeouts > 0); + aptr += len + QFIXEDSZ; + ares_free_string(hostname); + + status = ares_expand_name(aptr, abuf, alen, &hostname, &len); + if ( status != ARES_SUCCESS ) + return status; + + if ( aptr + RRFIXEDSZ > abuf + alen ) + return ARES_EBADRESP; + + aptr += len; + ares_free_string(hostname); + + *ttl = DNS_RR_TTL(aptr); + + return status; } /** @@ -207,8 +213,7 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf if ( status != ARES_SUCCESS ) { - // TODO: reporter warning or something here, or just give up on it? - printf("Failed addrinfo request: %s", ares_strerror(status)); + reporter->Error("Failed lookup of hostname: %s", ares_strerror(status)); dns_mgr->AddResult(req, nullptr, 0); } else @@ -265,29 +270,61 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf } req->ProcessAsyncResult(timeouts > 0); - ares_freeaddrinfo(result); } -/** - * Called in response to all other query types. - */ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, int len) { auto req = reinterpret_cast(arg); if ( status != ARES_SUCCESS ) { - // TODO: reporter warning or something here, or just give up on it? - // TODO: what should we send to AddResult if we didn't get an answer back? - // struct hostent he; - // memset(&he, 0, sizeof(struct hostent)); - // dns_mgr->AddResult(req, &he, 0); + reporter->Error("Failure from DNS lookup: %s", ares_strerror(status)); + + // Insert something into the cache so that the request loop will end correctly. + // We use the DNS_TIMEOUT value as the TTL here since it's small enough that the + // failed response will expire soon, and because we don't have the TTL from the + // response data. + dns_mgr->AddResult(req, nullptr, DNS_TIMEOUT); } else { + // We don't really care that we couldn't properly parse the TTL here, since the + // later parsing will fail with better error messages. In that case, it's ok + // that we throw away the status value. + int ttl; + get_ttl(buf, len, &ttl); + switch ( req->RequestType() ) { + case T_PTR: + { + struct hostent* he; + if ( req->Addr().GetFamily() == IPv4 ) + { + struct in_addr addr; + req->Addr().CopyIPv4(&addr); + status = ares_parse_ptr_reply(buf, len, &addr, sizeof(addr), AF_INET, &he); + } + else + { + struct in6_addr addr; + req->Addr().CopyIPv6(&addr); + status = ares_parse_ptr_reply(buf, len, &addr, sizeof(addr), AF_INET6, &he); + } + + if ( status == ARES_SUCCESS ) + { + dns_mgr->AddResult(req, he, ttl); + ares_free_hostent(he); + } + else + { + // See above for why DNS_TIMEOUT here. + dns_mgr->AddResult(req, nullptr, DNS_TIMEOUT); + } + break; + } case T_TXT: { struct ares_txt_reply* reply; @@ -305,14 +342,16 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in struct hostent he; memset(&he, 0, sizeof(struct hostent)); he.h_name = util::copy_string(reinterpret_cast(reply->txt)); + dns_mgr->AddResult(req, &he, ttl); - // TODO: pass DNS_TIMEOUT for the TTL here just so things work for - // testing. This will absolutely need to get the data from the request - // somehow instead. See https://github.com/c-ares/c-ares/issues/387. - dns_mgr->AddResult(req, &he, DNS_TIMEOUT); - + delete[] he.h_name; ares_free_data(reply); } + else + { + // See above for why DNS_TIMEOUT here. + dns_mgr->AddResult(req, nullptr, DNS_TIMEOUT); + } break; } @@ -504,7 +543,7 @@ ValPtr DNS_Mgr::Lookup(const std::string& name, int request_type) { case DNS_PRIME: { - auto req = new DNS_Request(name, AF_UNSPEC, request_type); + auto req = new DNS_Request(name, request_type); req->MakeRequest(channel); return empty_addr_set(); } @@ -516,7 +555,7 @@ ValPtr DNS_Mgr::Lookup(const std::string& name, int request_type) case DNS_DEFAULT: { - auto req = new DNS_Request(name, AF_UNSPEC, request_type); + auto req = new DNS_Request(name, request_type); req->MakeRequest(channel); Resolve(); @@ -551,9 +590,9 @@ TableValPtr DNS_Mgr::LookupHost(const std::string& name) { case DNS_PRIME: { - // We pass T_A here, but because we're passing AF_UNSPEC MakeRequest() will - // have c-ares attempt to lookup both ipv4 and ipv6 at the same time. - auto req = new DNS_Request(name, AF_UNSPEC, T_A); + // We pass T_A here, but DNSRequest::MakeRequest() will special-case that in + // a request that gets both T_A and T_AAAA results at one time. + auto req = new DNS_Request(name, T_A); req->MakeRequest(channel); return empty_addr_set(); } @@ -564,9 +603,9 @@ TableValPtr DNS_Mgr::LookupHost(const std::string& name) case DNS_DEFAULT: { - // We pass T_A here, but because we're passing AF_UNSPEC MakeRequest() will - // have c-ares attempt to lookup both ipv4 and ipv6 at the same time. - auto req = new DNS_Request(name, AF_UNSPEC, T_A); + // We pass T_A here, but DNSRequest::MakeRequest() will special-case that in + // a request that gets both T_A and T_AAAA results at one time. + auto req = new DNS_Request(name, T_A); req->MakeRequest(channel); Resolve(); @@ -1196,11 +1235,11 @@ void DNS_Mgr::IssueAsyncRequests() if ( req->IsAddrReq() ) dns_req = new DNS_Request(req->addr, true); else if ( req->is_txt ) - dns_req = new DNS_Request(req->host.c_str(), AF_UNSPEC, T_TXT, true); + dns_req = new DNS_Request(req->host.c_str(), T_TXT, true); else - // We pass T_A here, but because we're passing AF_UNSPEC MakeRequest() will - // have c-ares attempt to lookup both ipv4 and ipv6 at the same time. - dns_req = new DNS_Request(req->host.c_str(), AF_UNSPEC, T_A, true); + // We pass T_A here, but DNSRequest::MakeRequest() will special-case that in + // a request that gets both T_A and T_AAAA results at one time. + dns_req = new DNS_Request(req->host.c_str(), T_A, true); dns_req->MakeRequest(channel); From a201ccaefa076c400fb5a03dc710c78950fd9082 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 1 Feb 2022 16:48:45 -0700 Subject: [PATCH 174/204] Pass dns_mgr down into the DNS_Request objects --- src/DNS_Mgr.cc | 79 +++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index a2ed608c05..3aefb0e3f2 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -55,6 +55,12 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, int len); static void sock_cb(void* data, int s, int read, int write); +struct CallbackArgs + { + DNS_Request* req; + DNS_Mgr* mgr; + }; + class DNS_Request { public: @@ -67,8 +73,8 @@ public: int RequestType() const { return request_type; } bool IsTxt() const { return request_type == 16; } - void MakeRequest(ares_channel channel); - void ProcessAsyncResult(bool timed_out); + void MakeRequest(ares_channel channel, DNS_Mgr* mgr); + void ProcessAsyncResult(bool timed_out, DNS_Mgr* mgr); private: std::string host; @@ -97,8 +103,11 @@ DNS_Request::~DNS_Request() ares_free_string(query); } -void DNS_Request::MakeRequest(ares_channel channel) +void DNS_Request::MakeRequest(ares_channel channel, DNS_Mgr* mgr) { + // This needs to get deleted at the end of the callback method. + auto req_data = new CallbackArgs{this, mgr}; + // It's completely fine if this rolls over. It's just to keep the query ID different // from one query to the next, and it's unlikely we'd do 2^16 queries so fast that // all of them would be in flight at the same time. @@ -111,7 +120,7 @@ void DNS_Request::MakeRequest(ares_channel channel) // back in the same request if use ares_getaddrinfo() so we can store them both // in the same mapping. ares_addrinfo_hints hints = {ARES_AI_CANONNAME, AF_UNSPEC, 0, 0}; - ares_getaddrinfo(channel, host.c_str(), NULL, &hints, addrinfo_cb, this); + ares_getaddrinfo(channel, host.c_str(), NULL, &hints, addrinfo_cb, req_data); } else { @@ -131,21 +140,21 @@ void DNS_Request::MakeRequest(ares_channel channel) // Store this so it can be destroyed when the request is destroyed. this->query = query; - ares_send(channel, query, len, query_cb, this); + ares_send(channel, query, len, query_cb, req_data); } } -void DNS_Request::ProcessAsyncResult(bool timed_out) +void DNS_Request::ProcessAsyncResult(bool timed_out, DNS_Mgr* mgr) { if ( ! async ) return; if ( request_type == T_A || request_type == T_AAAA ) - dns_mgr->CheckAsyncHostRequest(host, timed_out); + mgr->CheckAsyncHostRequest(host, timed_out); else if ( request_type == T_PTR ) - dns_mgr->CheckAsyncAddrRequest(addr, timed_out); + mgr->CheckAsyncAddrRequest(addr, timed_out); else if ( request_type == T_TXT ) - dns_mgr->CheckAsyncTextRequest(host, timed_out); + mgr->CheckAsyncTextRequest(host, timed_out); } /** @@ -209,12 +218,13 @@ static int get_ttl(unsigned char* abuf, int alen, int* ttl) */ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinfo* result) { - auto req = reinterpret_cast(arg); + auto arg_data = reinterpret_cast(arg); + const auto [req, mgr] = *arg_data; if ( status != ARES_SUCCESS ) { reporter->Error("Failed lookup of hostname: %s", ares_strerror(status)); - dns_mgr->AddResult(req, nullptr, 0); + mgr->AddResult(req, nullptr, 0); } else { @@ -246,7 +256,7 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf he.h_length = sizeof(in_addr); he.h_addr_list = reinterpret_cast(addrs.data()); - dns_mgr->AddResult(req, &he, result->nodes[0].ai_ttl); + mgr->AddResult(req, &he, result->nodes[0].ai_ttl); delete[] he.h_name; } @@ -263,19 +273,22 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf he.h_length = sizeof(in6_addr); he.h_addr_list = reinterpret_cast(addrs6.data()); - dns_mgr->AddResult(req, &he, result->nodes[0].ai_ttl, true); + mgr->AddResult(req, &he, result->nodes[0].ai_ttl, true); delete[] he.h_name; } } - req->ProcessAsyncResult(timeouts > 0); + req->ProcessAsyncResult(timeouts > 0, mgr); ares_freeaddrinfo(result); + delete arg_data; + delete req; } static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, int len) { - auto req = reinterpret_cast(arg); + auto arg_data = reinterpret_cast(arg); + const auto [req, mgr] = *arg_data; if ( status != ARES_SUCCESS ) { @@ -285,7 +298,7 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in // We use the DNS_TIMEOUT value as the TTL here since it's small enough that the // failed response will expire soon, and because we don't have the TTL from the // response data. - dns_mgr->AddResult(req, nullptr, DNS_TIMEOUT); + mgr->AddResult(req, nullptr, DNS_TIMEOUT); } else { @@ -315,13 +328,13 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in if ( status == ARES_SUCCESS ) { - dns_mgr->AddResult(req, he, ttl); + mgr->AddResult(req, he, ttl); ares_free_hostent(he); } else { // See above for why DNS_TIMEOUT here. - dns_mgr->AddResult(req, nullptr, DNS_TIMEOUT); + mgr->AddResult(req, nullptr, DNS_TIMEOUT); } break; } @@ -342,7 +355,7 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in struct hostent he; memset(&he, 0, sizeof(struct hostent)); he.h_name = util::copy_string(reinterpret_cast(reply->txt)); - dns_mgr->AddResult(req, &he, ttl); + mgr->AddResult(req, &he, ttl); delete[] he.h_name; ares_free_data(reply); @@ -350,7 +363,7 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in else { // See above for why DNS_TIMEOUT here. - dns_mgr->AddResult(req, nullptr, DNS_TIMEOUT); + mgr->AddResult(req, nullptr, DNS_TIMEOUT); } break; @@ -362,7 +375,9 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in } } - req->ProcessAsyncResult(timeouts > 0); + req->ProcessAsyncResult(timeouts > 0, mgr); + delete arg_data; + delete req; } /** @@ -544,7 +559,7 @@ ValPtr DNS_Mgr::Lookup(const std::string& name, int request_type) case DNS_PRIME: { auto req = new DNS_Request(name, request_type); - req->MakeRequest(channel); + req->MakeRequest(channel, this); return empty_addr_set(); } @@ -556,7 +571,7 @@ ValPtr DNS_Mgr::Lookup(const std::string& name, int request_type) case DNS_DEFAULT: { auto req = new DNS_Request(name, request_type); - req->MakeRequest(channel); + req->MakeRequest(channel, this); Resolve(); // Call LookupHost() a second time to get the newly stored value out of the cache. @@ -593,7 +608,7 @@ TableValPtr DNS_Mgr::LookupHost(const std::string& name) // We pass T_A here, but DNSRequest::MakeRequest() will special-case that in // a request that gets both T_A and T_AAAA results at one time. auto req = new DNS_Request(name, T_A); - req->MakeRequest(channel); + req->MakeRequest(channel, this); return empty_addr_set(); } @@ -606,7 +621,7 @@ TableValPtr DNS_Mgr::LookupHost(const std::string& name) // We pass T_A here, but DNSRequest::MakeRequest() will special-case that in // a request that gets both T_A and T_AAAA results at one time. auto req = new DNS_Request(name, T_A); - req->MakeRequest(channel); + req->MakeRequest(channel, this); Resolve(); // Call LookupHost() a second time to get the newly stored value out of the cache. @@ -639,7 +654,7 @@ StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) case DNS_PRIME: { auto req = new DNS_Request(addr); - req->MakeRequest(channel); + req->MakeRequest(channel, this); return make_intrusive(""); } @@ -650,7 +665,7 @@ StringValPtr DNS_Mgr::LookupAddr(const IPAddr& addr) case DNS_DEFAULT: { auto req = new DNS_Request(addr); - req->MakeRequest(channel); + req->MakeRequest(channel, this); Resolve(); // Call LookupAddr() a second time to get the newly stored value out of the cache. @@ -1241,7 +1256,7 @@ void DNS_Mgr::IssueAsyncRequests() // a request that gets both T_A and T_AAAA results at one time. dns_req = new DNS_Request(req->host.c_str(), T_A, true); - dns_req->MakeRequest(channel); + dns_req->MakeRequest(channel, this); asyncs_timeouts.push(req); ++asyncs_pending; @@ -1519,7 +1534,6 @@ TEST_CASE("dns_mgr priming") // the result. This tests that the priming code will create the requests but // wait for Resolve() to actually make the requests. TestDNS_Mgr mgr(DNS_PRIME); - dns_mgr = &mgr; mgr.SetDir(tmpdir); mgr.InitPostScript(); @@ -1566,7 +1580,6 @@ TEST_CASE("dns_mgr alternate server") setenv("ZEEK_DNS_RESOLVER", "1.1.1.1", 1); TestDNS_Mgr mgr(DNS_DEFAULT); - dns_mgr = &mgr; mgr.InitPostScript(); @@ -1593,7 +1606,6 @@ TEST_CASE("dns_mgr alternate server") TEST_CASE("dns_mgr default mode") { TestDNS_Mgr mgr(DNS_DEFAULT); - dns_mgr = &mgr; mgr.InitPostScript(); IPAddr ones4("1.1.1.1"); @@ -1626,7 +1638,6 @@ TEST_CASE("dns_mgr default mode") TEST_CASE("dns_mgr async host") { TestDNS_Mgr mgr(DNS_DEFAULT); - dns_mgr = &mgr; mgr.InitPostScript(); TestCallback cb{}; @@ -1658,7 +1669,6 @@ TEST_CASE("dns_mgr async host") TEST_CASE("dns_mgr async addr") { TestDNS_Mgr mgr(DNS_DEFAULT); - dns_mgr = &mgr; mgr.InitPostScript(); TestCallback cb{}; @@ -1685,7 +1695,6 @@ TEST_CASE("dns_mgr async addr") TEST_CASE("dns_mgr async text") { TestDNS_Mgr mgr(DNS_DEFAULT); - dns_mgr = &mgr; mgr.InitPostScript(); TestCallback cb{}; @@ -1718,7 +1727,6 @@ TEST_CASE("dns_mgr timeouts") // resulting in a timeout. setenv("ZEEK_DNS_RESOLVER", "3.219.212.117", 1); TestDNS_Mgr mgr(DNS_DEFAULT); - dns_mgr = &mgr; mgr.InitPostScript(); auto addr_result = mgr.LookupAddr("1.1.1.1"); @@ -1745,7 +1753,6 @@ TEST_CASE("dns_mgr async timeouts") // resulting in a timeout. setenv("ZEEK_DNS_RESOLVER", "3.219.212.117", 1); TestDNS_Mgr mgr(DNS_DEFAULT); - dns_mgr = &mgr; mgr.InitPostScript(); TestCallback cb{}; From c7284686a468f49eee3a67b6b3178fe63357563a Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 4 Feb 2022 16:34:44 -0700 Subject: [PATCH 175/204] Handle cancelled/destruction statuses in callback methods --- src/DNS_Mgr.cc | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 3aefb0e3f2..ac401caaf4 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -223,8 +223,18 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf if ( status != ARES_SUCCESS ) { - reporter->Error("Failed lookup of hostname: %s", ares_strerror(status)); - mgr->AddResult(req, nullptr, 0); + // These two statuses should only ever be sent if we're shutting down everything + // and all of the existing queries are being cancelled. There's no reason to + // store a status that's just going to get deleted, nor is there a reason to log + // anything. + if ( status != ARES_ECANCELLED && status != ARES_EDESTRUCTION ) + { + // Insert something into the cache so that the request loop will end correctly. + // We use the DNS_TIMEOUT value as the TTL here since it's small enough that the + // failed response will expire soon, and because we don't have the TTL from the + // response data. + mgr->AddResult(req, nullptr, DNS_TIMEOUT); + } } else { @@ -292,13 +302,18 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in if ( status != ARES_SUCCESS ) { - reporter->Error("Failure from DNS lookup: %s", ares_strerror(status)); - - // Insert something into the cache so that the request loop will end correctly. - // We use the DNS_TIMEOUT value as the TTL here since it's small enough that the - // failed response will expire soon, and because we don't have the TTL from the - // response data. - mgr->AddResult(req, nullptr, DNS_TIMEOUT); + // These two statuses should only ever be sent if we're shutting down everything + // and all of the existing queries are being cancelled. There's no reason to + // store a status that's just going to get deleted, nor is there a reason to log + // anything. + if ( status != ARES_ECANCELLED && status != ARES_EDESTRUCTION ) + { + // Insert something into the cache so that the request loop will end correctly. + // We use the DNS_TIMEOUT value as the TTL here since it's small enough that the + // failed response will expire soon, and because we don't have the TTL from the + // response data. + mgr->AddResult(req, nullptr, DNS_TIMEOUT); + } } else { From fb59239f41a5f34110aa6bd40d2e3b0b8941cb9f Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 7 Feb 2022 10:14:09 -0700 Subject: [PATCH 176/204] Don't split ipv4/ipv6 mappings into separate pointers --- src/DNS_Mgr.cc | 91 +++++++++----------------------------------------- src/DNS_Mgr.h | 2 +- 2 files changed, 17 insertions(+), 76 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index ac401caaf4..609ffde677 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -923,57 +923,27 @@ void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl, bool m HostMap::iterator it = host_mappings.find(dr->Host()); if ( it == host_mappings.end() ) { - std::pair result; - - if ( new_mapping->Type() == AF_INET ) - result = host_mappings.emplace(dr->Host(), std::pair{new_mapping, nullptr}); - else - result = host_mappings.emplace(dr->Host(), std::pair{nullptr, new_mapping}); - + auto result = host_mappings.emplace(dr->Host(), new_mapping); it = result.first; } else - { - if ( new_mapping->Type() == AF_INET ) - prev_mapping = it->second.first; - else - prev_mapping = it->second.second; - } + prev_mapping = it->second; - if ( prev_mapping && new_mapping->Type() != prev_mapping->Type() ) - { - if ( new_mapping->Type() == AF_INET ) - { - prev_mapping = it->second.second; - it->second.first = new_mapping; - } - else - { - prev_mapping = it->second.first; - it->second.second = new_mapping; - } - } - else if ( prev_mapping && prev_mapping->Valid() ) + if ( prev_mapping && prev_mapping->Valid() ) { if ( new_mapping->Valid() ) { if ( merge ) new_mapping->Merge(prev_mapping); + it->second = new_mapping; keep_prev = false; - if ( new_mapping->Type() == AF_INET ) - it->second.first = new_mapping; - else - it->second.second = new_mapping; } } else { + it->second = new_mapping; keep_prev = false; - if ( new_mapping->Type() == AF_INET ) - it->second.first = new_mapping; - else - it->second.second = new_mapping; } } } @@ -1100,21 +1070,9 @@ void DNS_Mgr::LoadCache(const std::string& path) for ( ; ! m->NoMapping() && ! m->InitFailed(); m = new DNS_Mapping(f) ) { if ( m->ReqHost() ) - { - if ( host_mappings.find(m->ReqHost()) == host_mappings.end() ) - { - host_mappings[m->ReqHost()].first = 0; - host_mappings[m->ReqHost()].second = 0; - } - if ( m->Type() == AF_INET ) - host_mappings[m->ReqHost()].first = m; - else - host_mappings[m->ReqHost()].second = m; - } + host_mappings.insert_or_assign(m->ReqHost(), m); else - { - addr_mappings[m->ReqAddr()] = m; - } + addr_mappings.insert_or_assign(m->ReqAddr(), m); } if ( ! m->NoMapping() ) @@ -1156,11 +1114,8 @@ void DNS_Mgr::Save(FILE* f, const HostMap& m) { for ( HostMap::const_iterator it = m.begin(); it != m.end(); ++it ) { - if ( it->second.first ) - it->second.first->Save(f); - - if ( it->second.second ) - it->second.second->Save(f); + if ( it->second ) + it->second->Save(f); } } @@ -1171,36 +1126,25 @@ TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name, bool cleanup_exp if ( it == host_mappings.end() ) return nullptr; - DNS_Mapping* d4 = it->second.first; - DNS_Mapping* d6 = it->second.second; + DNS_Mapping* d = it->second; - if ( (! d4 || d4->names.empty()) && (! d6 || d6->names.empty()) ) + if ( ! d || d->names.empty() ) return nullptr; - if ( cleanup_expired && ((d4 && d4->Expired()) || (d6 && d6->Expired())) ) + if ( cleanup_expired && (d && d->Expired()) ) { host_mappings.erase(it); - delete d4; - delete d6; + delete d; return nullptr; } - if ( check_failed && ((d4 && d4->Failed()) || (d6 && d6->Failed())) ) + if ( check_failed && (d && d->Failed()) ) { reporter->Warning("Can't resolve host: %s", name.c_str()); return empty_addr_set(); } - auto tv4 = d4->AddrsSet(); - - if ( d6 ) - { - auto tv6 = d6->AddrsSet(); - tv4->AddTo(tv6.get(), false); - return tv6; - } - - return tv4; + return d->AddrsSet(); } StringValPtr DNS_Mgr::LookupAddrInCache(const IPAddr& addr, bool cleanup_expired, bool check_failed) @@ -1366,10 +1310,7 @@ void DNS_Mgr::Flush() Resolve(); for ( HostMap::iterator it = host_mappings.begin(); it != host_mappings.end(); ++it ) - { - delete it->second.first; - delete it->second.second; - } + delete it->second; for ( AddrMap::iterator it2 = addr_mappings.begin(); it2 != addr_mappings.end(); ++it2 ) delete it2->second; diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index 1d5d2fffc2..e3472218c8 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -265,7 +265,7 @@ protected: void CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm); ListValPtr AddrListDelta(ListVal* al1, ListVal* al2); - using HostMap = std::map>; + using HostMap = std::map; using AddrMap = std::map; using TextMap = std::map; void LoadCache(const std::string& path); From e8f833b8a6552a891b4c64943c33ea70b9bf681a Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 7 Feb 2022 12:41:03 -0700 Subject: [PATCH 177/204] Store all mappings in a single map instead of split by type This opens up the possibility of storing other request types outside of T_A, T_PTR and T_TXT without requiring redoing the caching. It also fixes the caching code in DNS_Mapping, adding a version number to the start of the cache file so the cache structure can be modified and old caches invalidated more easily. --- src/DNS_Mapping.cc | 45 ++- src/DNS_Mapping.h | 10 +- src/DNS_Mgr.cc | 342 ++++++++++++++--------- src/DNS_Mgr.h | 16 +- testing/btest/Baseline/core.fake_dns/out | 2 +- 5 files changed, 261 insertions(+), 154 deletions(-) diff --git a/src/DNS_Mapping.cc b/src/DNS_Mapping.cc index d0de26b016..45a8b9cf68 100644 --- a/src/DNS_Mapping.cc +++ b/src/DNS_Mapping.cc @@ -1,16 +1,20 @@ #include "zeek/DNS_Mapping.h" +#include + #include "zeek/3rdparty/doctest.h" #include "zeek/DNS_Mgr.h" +#include "zeek/Reporter.h" namespace zeek::detail { -DNS_Mapping::DNS_Mapping(std::string host, struct hostent* h, uint32_t ttl) +DNS_Mapping::DNS_Mapping(std::string host, struct hostent* h, uint32_t ttl, int type) { Init(h); req_host = host; req_ttl = ttl; + req_type = type; if ( names.empty() ) names.push_back(std::move(host)); @@ -21,6 +25,7 @@ DNS_Mapping::DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl) Init(h); req_addr = addr; req_ttl = ttl; + req_type = T_PTR; } DNS_Mapping::DNS_Mapping(FILE* f) @@ -45,7 +50,7 @@ DNS_Mapping::DNS_Mapping(FILE* f) int num_addrs; if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %" PRIu32, &creation_time, &is_req_host, req_buf, - &failed_local, name_buf, &map_type, &num_addrs, &req_ttl) != 8 ) + &failed_local, name_buf, &req_type, &num_addrs, &req_ttl) != 8 ) { no_mapping = true; return; @@ -126,7 +131,6 @@ void DNS_Mapping::Init(struct hostent* h) return; } - map_type = h->h_addrtype; if ( h->h_name ) // for now, just use the official name // TODO: this could easily be expanded to include all of the aliases as well @@ -153,7 +157,7 @@ void DNS_Mapping::Clear() addrs.clear(); addrs_val = nullptr; no_mapping = false; - map_type = 0; + req_type = 0; failed = true; } @@ -161,7 +165,7 @@ void DNS_Mapping::Save(FILE* f) const { fprintf(f, "%.0f %d %s %d %s %d %zu %" PRIu32 "\n", creation_time, ! req_host.empty(), req_host.empty() ? req_addr.AsString().c_str() : req_host.c_str(), failed, - names.empty() ? "*" : names[0].c_str(), map_type, addrs.size(), req_ttl); + names.empty() ? "*" : names[0].c_str(), req_type, addrs.size(), req_ttl); for ( const auto& addr : addrs ) fprintf(f, "%s\n", addr.AsString().c_str()); @@ -173,13 +177,38 @@ void DNS_Mapping::Merge(DNS_Mapping* other) std::copy(other->addrs.begin(), other->addrs.end(), std::back_inserter(addrs)); } +// This value needs to be incremented if something changes in the data stored by Save(). This +// allows us to change the structure of the cache without breaking something in DNS_Mgr. +constexpr int FILE_VERSION = 1; + +void DNS_Mapping::InitializeCache(FILE* f) + { + fprintf(f, "%d\n", FILE_VERSION); + } + +bool DNS_Mapping::ValidateCacheVersion(FILE* f) + { + char buf[512]; + if ( ! fgets(buf, sizeof(buf), f) ) + return false; + + int version; + if ( sscanf(buf, "%d", &version) != 1 ) + { + reporter->Warning("Existing DNS cache did not have correct version, ignoring"); + return false; + } + + return FILE_VERSION == version; + } + ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// TEST_CASE("dns_mapping init null hostent") { - DNS_Mapping mapping(std::string("www.apple.com"), nullptr, 123); + DNS_Mapping mapping("www.apple.com", nullptr, 123, T_A); CHECK(! mapping.Valid()); CHECK(mapping.Addrs() == nullptr); @@ -202,7 +231,7 @@ TEST_CASE("dns_mapping init host") std::vector addrs = {&in4, NULL}; he.h_addr_list = reinterpret_cast(addrs.data()); - DNS_Mapping mapping(std::string("testing.home"), &he, 123); + DNS_Mapping mapping("testing.home", &he, 123, T_A); CHECK(mapping.Valid()); CHECK(mapping.ReqAddr() == IPAddr::v6_unspecified); CHECK(strcmp(mapping.ReqHost(), "testing.home") == 0); @@ -347,7 +376,7 @@ TEST_CASE("dns_mapping multiple addresses") std::vector addrs = {&in4_1, &in4_2, NULL}; he.h_addr_list = reinterpret_cast(addrs.data()); - DNS_Mapping mapping(std::string("testing.home"), &he, 123); + DNS_Mapping mapping("testing.home", &he, 123, T_A); CHECK(mapping.Valid()); auto lva = mapping.Addrs(); diff --git a/src/DNS_Mapping.h b/src/DNS_Mapping.h index c9b3ea6c03..c7cb698297 100644 --- a/src/DNS_Mapping.h +++ b/src/DNS_Mapping.h @@ -15,7 +15,7 @@ class DNS_Mapping { public: DNS_Mapping() = delete; - DNS_Mapping(std::string host, struct hostent* h, uint32_t ttl); + DNS_Mapping(std::string host, struct hostent* h, uint32_t ttl, int type); DNS_Mapping(const IPAddr& addr, struct hostent* h, uint32_t ttl); DNS_Mapping(FILE* f); @@ -29,6 +29,7 @@ public: const char* ReqHost() const { return req_host.empty() ? nullptr : req_host.c_str(); } const IPAddr& ReqAddr() const { return req_addr; } std::string ReqStr() const { return req_host.empty() ? req_addr.AsString() : req_host; } + int ReqType() const { return req_type; } ListValPtr Addrs(); TableValPtr AddrsSet(); // addresses returned as a set @@ -50,10 +51,11 @@ public: return util::current_time() > (creation_time + req_ttl); } - int Type() const { return map_type; } - void Merge(DNS_Mapping* other); + static void InitializeCache(FILE* f); + static bool ValidateCacheVersion(FILE* f); + protected: friend class DNS_Mgr; @@ -63,6 +65,7 @@ protected: std::string req_host; IPAddr req_addr; uint32_t req_ttl = 0; + int req_type = 0; // This class supports multiple names per address, but we only store one of them. std::vector names; @@ -72,7 +75,6 @@ protected: ListValPtr addrs_val; double creation_time = 0.0; - int map_type = AF_UNSPEC; bool no_mapping = false; // when initializing from a file, immediately hit EOF bool init_failed = false; bool failed = false; diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 609ffde677..c0a4c507f9 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -49,6 +49,130 @@ constexpr int DNS_TIMEOUT = 5; // The maximum allowed number of pending asynchronous requests. constexpr int MAX_PENDING_REQUESTS = 20; +// This unfortunately doesn't exist in c-ares, even though it seems rather useful. +static const char* request_type_string(int request_type) + { + switch ( request_type ) + { + case T_A: + return "T_A"; + case T_NS: + return "T_NS"; + case T_MD: + return "T_MD"; + case T_MF: + return "T_MF"; + case T_CNAME: + return "T_CNAME"; + case T_SOA: + return "T_SOA"; + case T_MB: + return "T_MB"; + case T_MG: + return "T_MG"; + case T_MR: + return "T_MR"; + case T_NULL: + return "T_NULL"; + case T_WKS: + return "T_WKS"; + case T_PTR: + return "T_PTR"; + case T_HINFO: + return "T_HINFO"; + case T_MINFO: + return "T_MINFO"; + case T_MX: + return "T_MX"; + case T_TXT: + return "T_TXT"; + case T_RP: + return "T_RP"; + case T_AFSDB: + return "T_AFSDB"; + case T_X25: + return "T_X25"; + case T_ISDN: + return "T_ISDN"; + case T_RT: + return "T_RT"; + case T_NSAP: + return "T_NSAP"; + case T_NSAP_PTR: + return "T_NSAP_PTR"; + case T_SIG: + return "T_SIG"; + case T_KEY: + return "T_KEY"; + case T_PX: + return "T_PX"; + case T_GPOS: + return "T_GPOS"; + case T_AAAA: + return "T_AAAA"; + case T_LOC: + return "T_LOC"; + case T_NXT: + return "T_NXT"; + case T_EID: + return "T_EID"; + case T_NIMLOC: + return "T_NIMLOC"; + case T_SRV: + return "T_SRV"; + case T_ATMA: + return "T_ATMA"; + case T_NAPTR: + return "T_NAPTR"; + case T_KX: + return "T_KX"; + case T_CERT: + return "T_CERT"; + case T_A6: + return "T_A6"; + case T_DNAME: + return "T_DNAME"; + case T_SINK: + return "T_SINK"; + case T_OPT: + return "T_OPT"; + case T_APL: + return "T_APL"; + case T_DS: + return "T_DS"; + case T_SSHFP: + return "T_SSHFP"; + case T_RRSIG: + return "T_RRSIG"; + case T_NSEC: + return "T_NSEC"; + case T_DNSKEY: + return "T_DNSKEY"; + case T_TKEY: + return "T_TKEY"; + case T_TSIG: + return "T_TSIG"; + case T_IXFR: + return "T_IXFR"; + case T_AXFR: + return "T_AXFR"; + case T_MAILB: + return "T_MAILB"; + case T_MAILA: + return "T_MAILA"; + case T_ANY: + return "T_ANY"; + case T_URI: + return "T_URI"; + case T_CAA: + return "T_CAA"; + case T_MAX: + return "T_MAX"; + default: + return ""; + } + } + namespace zeek::detail { static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinfo* result); @@ -90,6 +214,10 @@ uint16_t DNS_Request::request_id = 0; DNS_Request::DNS_Request(std::string host, int request_type, bool async) : host(std::move(host)), request_type(request_type), async(async) { + // We combine the T_A and T_AAAA requests together in one request, so set the type + // to T_A to make things easier in other parts of the code (mostly around lookups). + if ( request_type == T_AAAA ) + request_type = T_A; } DNS_Request::DNS_Request(const IPAddr& addr, bool async) : addr(addr), async(async) @@ -113,7 +241,7 @@ void DNS_Request::MakeRequest(ares_channel channel, DNS_Mgr* mgr) // all of them would be in flight at the same time. DNS_Request::request_id++; - if ( request_type == T_A || request_type == T_AAAA ) + if ( request_type == T_A ) { // For A/AAAA requests, we use a different method than the other requests. Since // we're using the AF_UNSPEC family, we get both the ipv4 and ipv6 responses @@ -149,7 +277,7 @@ void DNS_Request::ProcessAsyncResult(bool timed_out, DNS_Mgr* mgr) if ( ! async ) return; - if ( request_type == T_A || request_type == T_AAAA ) + if ( request_type == T_A ) mgr->CheckAsyncHostRequest(host, timed_out); else if ( request_type == T_PTR ) mgr->CheckAsyncAddrRequest(addr, timed_out); @@ -385,7 +513,8 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in } default: - reporter->Error("Requests of type %d are unsupported", req->RequestType()); + reporter->Error("Requests of type %d (%s) are unsupported", req->RequestType(), + request_type_string(req->RequestType())); break; } } @@ -531,9 +660,9 @@ static TableValPtr fake_name_lookup_result(const std::string& name) return hv->ToSetVal(); } -static std::string fake_text_lookup_result(const std::string name) +static std::string fake_lookup_result(const std::string& name, int request_type) { - return util::fmt("fake_text_lookup_result_%s", name.c_str()); + return util::fmt("fake_lookup_result_%s_%s", request_type_string(request_type), name.c_str()); } static std::string fake_addr_lookup_result(const IPAddr& addr) @@ -558,14 +687,14 @@ ValPtr DNS_Mgr::Lookup(const std::string& name, int request_type) if ( request_type == T_A || request_type == T_AAAA ) return LookupHost(name); - if ( mode == DNS_FAKE && request_type == T_TXT ) - return make_intrusive(fake_text_lookup_result(name)); + if ( mode == DNS_FAKE ) + return make_intrusive(fake_lookup_result(name, request_type)); InitSource(); - if ( mode != DNS_PRIME && request_type == T_TXT ) + if ( mode != DNS_PRIME ) { - if ( auto val = LookupTextInCache(name, false) ) + if ( auto val = LookupOtherInCache(name, request_type, false) ) return val; } @@ -579,8 +708,8 @@ ValPtr DNS_Mgr::Lookup(const std::string& name, int request_type) } case DNS_FORCE: - reporter->FatalError("can't find DNS entry for %s (req type %d) in cache", name.c_str(), - request_type); + reporter->FatalError("can't find DNS entry for %s (req type %d / %s) in cache", + name.c_str(), request_type, request_type_string(request_type)); return nullptr; case DNS_DEFAULT: @@ -783,12 +912,12 @@ void DNS_Mgr::Lookup(const std::string& name, int request_type, LookupCallback* if ( mode == DNS_FAKE ) { - resolve_lookup_cb(callback, fake_text_lookup_result(name)); + resolve_lookup_cb(callback, fake_lookup_result(name, request_type)); return; } // Do we already know the answer? - if ( auto txt = LookupTextInCache(name, true) ) + if ( auto txt = LookupOtherInCache(name, request_type, true) ) { resolve_lookup_cb(callback, txt->CheckString()); return; @@ -885,98 +1014,50 @@ void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl, bool m DNS_Mapping* prev_mapping = nullptr; bool keep_prev = true; - if ( ! dr->Host().empty() ) - { - new_mapping = new DNS_Mapping(dr->Host(), h, ttl); - - if ( dr->IsTxt() ) - { - TextMap::iterator it = text_mappings.find(dr->Host()); - - if ( it == text_mappings.end() ) - { - auto result = text_mappings.emplace(dr->Host(), new_mapping); - it = result.first; - } - else - prev_mapping = it->second; - - if ( prev_mapping && prev_mapping->Valid() ) - { - if ( new_mapping->Valid() ) - { - if ( merge ) - new_mapping->Merge(prev_mapping); - - it->second = new_mapping; - keep_prev = false; - } - } - else - { - it->second = new_mapping; - keep_prev = false; - } - } - else - { - HostMap::iterator it = host_mappings.find(dr->Host()); - if ( it == host_mappings.end() ) - { - auto result = host_mappings.emplace(dr->Host(), new_mapping); - it = result.first; - } - else - prev_mapping = it->second; - - if ( prev_mapping && prev_mapping->Valid() ) - { - if ( new_mapping->Valid() ) - { - if ( merge ) - new_mapping->Merge(prev_mapping); - - it->second = new_mapping; - keep_prev = false; - } - } - else - { - it->second = new_mapping; - keep_prev = false; - } - } - } - else + MappingMap::iterator it; + if ( dr->RequestType() == T_PTR ) { new_mapping = new DNS_Mapping(dr->Addr(), h, ttl); - - AddrMap::iterator it = addr_mappings.find(dr->Addr()); - if ( it == addr_mappings.end() ) + it = all_mappings.find(dr->Addr()); + if ( it == all_mappings.end() ) { - auto result = addr_mappings.emplace(dr->Addr(), new_mapping); + auto result = all_mappings.emplace(dr->Addr(), new_mapping); it = result.first; } else prev_mapping = it->second; + } + else + { + new_mapping = new DNS_Mapping(dr->Host(), h, ttl, dr->RequestType()); + auto key = std::make_pair(dr->RequestType(), dr->Host()); - if ( prev_mapping && prev_mapping->Valid() ) + it = all_mappings.find(key); + if ( it == all_mappings.end() ) { - if ( new_mapping->Valid() ) - { - if ( merge ) - new_mapping->Merge(prev_mapping); - - it->second = new_mapping; - keep_prev = false; - } + auto result = all_mappings.emplace(std::move(key), new_mapping); + it = result.first; } else + prev_mapping = it->second; + } + + if ( prev_mapping && prev_mapping->Valid() ) + { + if ( new_mapping->Valid() ) { + if ( merge ) + new_mapping->Merge(prev_mapping); + it->second = new_mapping; keep_prev = false; } } + else + { + it->second = new_mapping; + keep_prev = false; + } if ( prev_mapping && ! dr->IsTxt() ) CompareMappings(prev_mapping, new_mapping); @@ -1065,14 +1146,17 @@ void DNS_Mgr::LoadCache(const std::string& path) if ( ! f ) return; + if ( ! DNS_Mapping::ValidateCacheVersion(f) ) + return; + // Loop until we find a mapping that doesn't initialize correctly. DNS_Mapping* m = new DNS_Mapping(f); for ( ; ! m->NoMapping() && ! m->InitFailed(); m = new DNS_Mapping(f) ) { if ( m->ReqHost() ) - host_mappings.insert_or_assign(m->ReqHost(), m); + all_mappings.insert_or_assign(std::make_pair(m->ReqType(), m->ReqHost()), m); else - addr_mappings.insert_or_assign(m->ReqAddr(), m); + all_mappings.insert_or_assign(m->ReqAddr(), m); } if ( ! m->NoMapping() ) @@ -1092,38 +1176,28 @@ bool DNS_Mgr::Save() if ( ! f ) return false; - Save(f, host_mappings); - Save(f, addr_mappings); - // Save(f, text_mappings); // We don't save the TXT mappings (yet?). + DNS_Mapping::InitializeCache(f); + Save(f, all_mappings); fclose(f); return true; } -void DNS_Mgr::Save(FILE* f, const AddrMap& m) +void DNS_Mgr::Save(FILE* f, const MappingMap& m) { - for ( AddrMap::const_iterator it = m.begin(); it != m.end(); ++it ) + for ( const auto& [key, mapping] : m ) { - if ( it->second ) - it->second->Save(f); - } - } - -void DNS_Mgr::Save(FILE* f, const HostMap& m) - { - for ( HostMap::const_iterator it = m.begin(); it != m.end(); ++it ) - { - if ( it->second ) - it->second->Save(f); + if ( mapping ) + mapping->Save(f); } } TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name, bool cleanup_expired, bool check_failed) { - HostMap::iterator it = host_mappings.find(name); - if ( it == host_mappings.end() ) + auto it = all_mappings.find(std::make_pair(T_A, name)); + if ( it == all_mappings.end() ) return nullptr; DNS_Mapping* d = it->second; @@ -1133,7 +1207,7 @@ TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name, bool cleanup_exp if ( cleanup_expired && (d && d->Expired()) ) { - host_mappings.erase(it); + all_mappings.erase(it); delete d; return nullptr; } @@ -1149,15 +1223,15 @@ TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name, bool cleanup_exp StringValPtr DNS_Mgr::LookupAddrInCache(const IPAddr& addr, bool cleanup_expired, bool check_failed) { - AddrMap::iterator it = addr_mappings.find(addr); - if ( it == addr_mappings.end() ) + auto it = all_mappings.find(addr); + if ( it == all_mappings.end() ) return nullptr; DNS_Mapping* d = it->second; if ( cleanup_expired && d->Expired() ) { - addr_mappings.erase(it); + all_mappings.erase(it); delete d; return nullptr; } @@ -1174,17 +1248,18 @@ StringValPtr DNS_Mgr::LookupAddrInCache(const IPAddr& addr, bool cleanup_expired return make_intrusive("<\?\?\?>"); } -StringValPtr DNS_Mgr::LookupTextInCache(const std::string& name, bool cleanup_expired) +StringValPtr DNS_Mgr::LookupOtherInCache(const std::string& name, int request_type, + bool cleanup_expired) { - TextMap::iterator it = text_mappings.find(name); - if ( it == text_mappings.end() ) + auto it = all_mappings.find(std::make_pair(request_type, name)); + if ( it == all_mappings.end() ) return nullptr; DNS_Mapping* d = it->second; if ( cleanup_expired && d->Expired() ) { - text_mappings.erase(it); + all_mappings.erase(it); delete d; return nullptr; } @@ -1291,7 +1366,7 @@ void DNS_Mgr::CheckAsyncTextRequest(const std::string& host, bool timeout) ++failed; i->second->Timeout(); } - else if ( auto name = LookupTextInCache(host, true) ) + else if ( auto name = LookupOtherInCache(host, T_TXT, true) ) { ++successful; i->second->Resolved(name->CheckString()); @@ -1309,18 +1384,10 @@ void DNS_Mgr::Flush() { Resolve(); - for ( HostMap::iterator it = host_mappings.begin(); it != host_mappings.end(); ++it ) - delete it->second; + for ( auto& [key, mapping] : all_mappings ) + delete mapping; - for ( AddrMap::iterator it2 = addr_mappings.begin(); it2 != addr_mappings.end(); ++it2 ) - delete it2->second; - - for ( TextMap::iterator it3 = text_mappings.begin(); it3 != text_mappings.end(); ++it3 ) - delete it3->second; - - host_mappings.clear(); - addr_mappings.clear(); - text_mappings.clear(); + all_mappings.clear(); } double DNS_Mgr::GetNextTimeout() @@ -1357,9 +1424,20 @@ void DNS_Mgr::GetStats(Stats* stats) stats->successful = successful; stats->failed = failed; stats->pending = asyncs_pending; - stats->cached_hosts = host_mappings.size(); - stats->cached_addresses = addr_mappings.size(); - stats->cached_texts = text_mappings.size(); + + stats->cached_hosts = 0; + stats->cached_addresses = 0; + stats->cached_texts = 0; + + for ( const auto& [key, mapping] : all_mappings ) + { + if ( mapping->ReqType() == T_PTR ) + stats->cached_addresses++; + else if ( mapping->ReqType() == T_A ) + stats->cached_hosts++; + else + stats->cached_texts++; + } } void DNS_Mgr::AsyncRequest::Resolved(const std::string& name) diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index e3472218c8..f2f7d26e6d 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "zeek/EventHandler.h" #include "zeek/IPAddr.h" @@ -248,7 +249,8 @@ protected: bool check_failed = false); TableValPtr LookupNameInCache(const std::string& name, bool cleanup_expired = false, bool check_failed = false); - StringValPtr LookupTextInCache(const std::string& name, bool cleanup_expired = false); + StringValPtr LookupOtherInCache(const std::string& name, int request_type, + bool cleanup_expired = false); // Finish the request if we have a result. If not, time it out if // requested. @@ -265,12 +267,10 @@ protected: void CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm); ListValPtr AddrListDelta(ListVal* al1, ListVal* al2); - using HostMap = std::map; - using AddrMap = std::map; - using TextMap = std::map; + using MappingKey = std::variant>; + using MappingMap = std::map; void LoadCache(const std::string& path); - void Save(FILE* f, const AddrMap& m); - void Save(FILE* f, const HostMap& m); + void Save(FILE* f, const MappingMap& m); // Issue as many queued async requests as slots are available. void IssueAsyncRequests(); @@ -283,9 +283,7 @@ protected: DNS_MgrMode mode; - HostMap host_mappings; - AddrMap addr_mappings; - TextMap text_mappings; + MappingMap all_mappings; std::string cache_name; std::string dir; // directory in which cache_name resides diff --git a/testing/btest/Baseline/core.fake_dns/out b/testing/btest/Baseline/core.fake_dns/out index bc04a9ec86..45539d8098 100644 --- a/testing/btest/Baseline/core.fake_dns/out +++ b/testing/btest/Baseline/core.fake_dns/out @@ -4,7 +4,7 @@ 7a5f:b783:9808:380e:b1a2:ce20:b58e:2a4a, 4cc7:de52:d869:b2f9:f215:19b8:c828:3bdd } -lookup_hostname_txt, fake_text_lookup_result_bro.wp.dg.cx +lookup_hostname_txt, fake_lookup_result_T_TXT_bro.wp.dg.cx lookup_hostname, { ce06:236:f21f:587:8c10:121d:c47d:b412 } From b531ec97efaa860fbaf4cf78acf74b00b6eea591 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 7 Feb 2022 14:49:55 -0700 Subject: [PATCH 178/204] Similar map changes for async requests --- src/DNS_Mgr.cc | 78 ++++++++++++++++++++++---------------------------- src/DNS_Mgr.h | 19 ++++++------ 2 files changed, 42 insertions(+), 55 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index c0a4c507f9..7343b1feca 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -281,8 +281,8 @@ void DNS_Request::ProcessAsyncResult(bool timed_out, DNS_Mgr* mgr) mgr->CheckAsyncHostRequest(host, timed_out); else if ( request_type == T_PTR ) mgr->CheckAsyncAddrRequest(addr, timed_out); - else if ( request_type == T_TXT ) - mgr->CheckAsyncTextRequest(host, timed_out); + else + mgr->CheckAsyncOtherRequest(host, timed_out, request_type); } /** @@ -842,16 +842,16 @@ void DNS_Mgr::LookupHost(const std::string& name, LookupCallback* callback) // If we already have a request waiting for this host, we don't need to make // another one. We can just add the callback to it and it'll get handled // when the first request comes back. - AsyncRequestNameMap::iterator i = asyncs_names.find(name); - if ( i != asyncs_names.end() ) + auto key = std::make_pair(T_A, name); + auto i = asyncs.find(key); + if ( i != asyncs.end() ) req = i->second; else { // A new one. - req = new AsyncRequest{}; - req->host = name; + req = new AsyncRequest{name, T_A}; asyncs_queued.push_back(req); - asyncs_names.emplace_hint(i, name, req); + asyncs.emplace_hint(i, std::move(key), req); } req->callbacks.push_back(callback); @@ -862,16 +862,16 @@ void DNS_Mgr::LookupHost(const std::string& name, LookupCallback* callback) IssueAsyncRequests(); } -void DNS_Mgr::LookupAddr(const IPAddr& host, LookupCallback* callback) +void DNS_Mgr::LookupAddr(const IPAddr& addr, LookupCallback* callback) { if ( mode == DNS_FAKE ) { - resolve_lookup_cb(callback, fake_addr_lookup_result(host)); + resolve_lookup_cb(callback, fake_addr_lookup_result(addr)); return; } // Do we already know the answer? - if ( auto name = LookupAddrInCache(host, true, false) ) + if ( auto name = LookupAddrInCache(addr, true, false) ) { resolve_lookup_cb(callback, name->CheckString()); return; @@ -882,16 +882,15 @@ void DNS_Mgr::LookupAddr(const IPAddr& host, LookupCallback* callback) // If we already have a request waiting for this host, we don't need to make // another one. We can just add the callback to it and it'll get handled // when the first request comes back. - AsyncRequestAddrMap::iterator i = asyncs_addrs.find(host); - if ( i != asyncs_addrs.end() ) + auto i = asyncs.find(addr); + if ( i != asyncs.end() ) req = i->second; else { // A new one. - req = new AsyncRequest{}; - req->addr = host; + req = new AsyncRequest{addr}; asyncs_queued.push_back(req); - asyncs_addrs.emplace_hint(i, host, req); + asyncs.emplace_hint(i, addr, req); } req->callbacks.push_back(callback); @@ -904,12 +903,6 @@ void DNS_Mgr::LookupAddr(const IPAddr& host, LookupCallback* callback) void DNS_Mgr::Lookup(const std::string& name, int request_type, LookupCallback* callback) { - if ( request_type == T_A || request_type == T_AAAA ) - { - LookupHost(name, callback); - return; - } - if ( mode == DNS_FAKE ) { resolve_lookup_cb(callback, fake_lookup_result(name, request_type)); @@ -928,17 +921,16 @@ void DNS_Mgr::Lookup(const std::string& name, int request_type, LookupCallback* // If we already have a request waiting for this host, we don't need to make // another one. We can just add the callback to it and it'll get handled // when the first request comes back. - AsyncRequestTextMap::iterator i = asyncs_texts.find(name); - if ( i != asyncs_texts.end() ) + auto key = std::make_pair(request_type, name); + auto i = asyncs.find(key); + if ( i != asyncs.end() ) req = i->second; else { // A new one. - req = new AsyncRequest{}; - req->host = name; - req->is_txt = true; + req = new AsyncRequest{name, request_type}; asyncs_queued.push_back(req); - asyncs_texts.emplace_hint(i, name, req); + asyncs.emplace_hint(i, std::move(key), req); } req->callbacks.push_back(callback); @@ -1281,14 +1273,14 @@ void DNS_Mgr::IssueAsyncRequests() ++num_requests; req->time = util::current_time(); - if ( req->IsAddrReq() ) + if ( req->type == T_PTR ) dns_req = new DNS_Request(req->addr, true); - else if ( req->is_txt ) - dns_req = new DNS_Request(req->host.c_str(), T_TXT, true); - else + else if ( req->type == T_A || req->type == T_AAAA ) // We pass T_A here, but DNSRequest::MakeRequest() will special-case that in // a request that gets both T_A and T_AAAA results at one time. dns_req = new DNS_Request(req->host.c_str(), T_A, true); + else + dns_req = new DNS_Request(req->host.c_str(), req->type, true); dns_req->MakeRequest(channel, this); @@ -1300,10 +1292,9 @@ void DNS_Mgr::IssueAsyncRequests() void DNS_Mgr::CheckAsyncHostRequest(const std::string& host, bool timeout) { // Note that this code is a mirror of that for CheckAsyncAddrRequest. + auto i = asyncs.find(std::make_pair(T_A, host)); - AsyncRequestNameMap::iterator i = asyncs_names.find(host); - - if ( i != asyncs_names.end() ) + if ( i != asyncs.end() ) { if ( timeout ) { @@ -1319,7 +1310,7 @@ void DNS_Mgr::CheckAsyncHostRequest(const std::string& host, bool timeout) return; delete i->second; - asyncs_names.erase(i); + asyncs.erase(i); --asyncs_pending; } } @@ -1330,9 +1321,9 @@ void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout) // In the following, if it's not in the respective map anymore, we've // already finished it earlier and don't have anything to do. - AsyncRequestAddrMap::iterator i = asyncs_addrs.find(addr); + auto i = asyncs.find(addr); - if ( i != asyncs_addrs.end() ) + if ( i != asyncs.end() ) { if ( timeout ) { @@ -1348,25 +1339,24 @@ void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout) return; delete i->second; - asyncs_addrs.erase(i); + asyncs.erase(i); --asyncs_pending; } } -void DNS_Mgr::CheckAsyncTextRequest(const std::string& host, bool timeout) +void DNS_Mgr::CheckAsyncOtherRequest(const std::string& host, bool timeout, int request_type) { // Note that this code is a mirror of that for CheckAsyncAddrRequest. - AsyncRequestTextMap::iterator i = asyncs_texts.find(host); - if ( i != asyncs_texts.end() ) + auto i = asyncs.find(std::make_pair(request_type, host)); + if ( i != asyncs.end() ) { if ( timeout ) { - AsyncRequestTextMap::iterator it = asyncs_texts.begin(); ++failed; i->second->Timeout(); } - else if ( auto name = LookupOtherInCache(host, T_TXT, true) ) + else if ( auto name = LookupOtherInCache(host, request_type, true) ) { ++successful; i->second->Resolved(name->CheckString()); @@ -1375,7 +1365,7 @@ void DNS_Mgr::CheckAsyncTextRequest(const std::string& host, bool timeout) return; delete i->second; - asyncs_texts.erase(i); + asyncs.erase(i); --asyncs_pending; } } diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index f2f7d26e6d..65e8c88910 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -256,7 +256,7 @@ protected: // requested. void CheckAsyncAddrRequest(const IPAddr& addr, bool timeout); void CheckAsyncHostRequest(const std::string& host, bool timeout); - void CheckAsyncTextRequest(const std::string& host, bool timeout); + void CheckAsyncOtherRequest(const std::string& host, bool timeout, int request_type); void Event(EventHandlerPtr e, DNS_Mapping* dm); void Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2); @@ -303,10 +303,13 @@ protected: IPAddr addr; std::string host; CallbackList callbacks; - bool is_txt = false; + int type = 0; bool processed = false; - bool IsAddrReq() const { return host.empty(); } + AsyncRequest(std::string host, int request_type) : host(std::move(host)), type(request_type) + { + } + AsyncRequest(const IPAddr& addr) : addr(addr), type(T_PTR) { } void Resolved(const std::string& name); void Resolved(TableValPtr addrs); @@ -318,14 +321,8 @@ protected: bool operator()(const AsyncRequest* a, const AsyncRequest* b) { return a->time > b->time; } }; - using AsyncRequestAddrMap = std::map; - AsyncRequestAddrMap asyncs_addrs; - - using AsyncRequestNameMap = std::map; - AsyncRequestNameMap asyncs_names; - - using AsyncRequestTextMap = std::map; - AsyncRequestTextMap asyncs_texts; + using AsyncRequestMap = std::map; + AsyncRequestMap asyncs; using QueuedList = std::list; QueuedList asyncs_queued; From c4cac72fd73cd54f7397987132d79353b1c30542 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 28 Mar 2022 14:59:48 -0700 Subject: [PATCH 179/204] Use shared_ptrs for DNS_Mapping objects --- src/DNS_Mapping.cc | 2 +- src/DNS_Mapping.h | 5 ++++- src/DNS_Mgr.cc | 46 +++++++++++++++++++--------------------------- src/DNS_Mgr.h | 15 ++++++++------- 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/src/DNS_Mapping.cc b/src/DNS_Mapping.cc index 45a8b9cf68..557b870552 100644 --- a/src/DNS_Mapping.cc +++ b/src/DNS_Mapping.cc @@ -171,7 +171,7 @@ void DNS_Mapping::Save(FILE* f) const fprintf(f, "%s\n", addr.AsString().c_str()); } -void DNS_Mapping::Merge(DNS_Mapping* other) +void DNS_Mapping::Merge(const DNS_MappingPtr& other) { std::copy(other->names.begin(), other->names.end(), std::back_inserter(names)); std::copy(other->addrs.begin(), other->addrs.end(), std::back_inserter(addrs)); diff --git a/src/DNS_Mapping.h b/src/DNS_Mapping.h index c7cb698297..32559701f0 100644 --- a/src/DNS_Mapping.h +++ b/src/DNS_Mapping.h @@ -11,6 +11,9 @@ namespace zeek::detail { +class DNS_Mapping; +using DNS_MappingPtr = std::shared_ptr; + class DNS_Mapping { public: @@ -51,7 +54,7 @@ public: return util::current_time() > (creation_time + req_ttl); } - void Merge(DNS_Mapping* other); + void Merge(const DNS_MappingPtr& other); static void InitializeCache(FILE* f); static bool ValidateCacheVersion(FILE* f); diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 7343b1feca..ab96a8421f 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -961,25 +961,25 @@ void DNS_Mgr::Resolve() } } -void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm) +void DNS_Mgr::Event(EventHandlerPtr e, const DNS_MappingPtr& dm) { if ( e ) event_mgr.Enqueue(e, BuildMappingVal(dm)); } -void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2) +void DNS_Mgr::Event(EventHandlerPtr e, const DNS_MappingPtr& dm, ListValPtr l1, ListValPtr l2) { if ( e ) event_mgr.Enqueue(e, BuildMappingVal(dm), l1->ToSetVal(), l2->ToSetVal()); } -void DNS_Mgr::Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm) +void DNS_Mgr::Event(EventHandlerPtr e, const DNS_MappingPtr& old_dm, DNS_MappingPtr new_dm) { if ( e ) event_mgr.Enqueue(e, BuildMappingVal(old_dm), BuildMappingVal(new_dm)); } -ValPtr DNS_Mgr::BuildMappingVal(DNS_Mapping* dm) +ValPtr DNS_Mgr::BuildMappingVal(const DNS_MappingPtr& dm) { if ( ! dm_rec ) return nullptr; @@ -1002,14 +1002,14 @@ void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl, bool m { // TODO: the existing code doesn't handle hostname aliases at all. Should we? - DNS_Mapping* new_mapping = nullptr; - DNS_Mapping* prev_mapping = nullptr; + DNS_MappingPtr new_mapping = nullptr; + DNS_MappingPtr prev_mapping = nullptr; bool keep_prev = true; MappingMap::iterator it; if ( dr->RequestType() == T_PTR ) { - new_mapping = new DNS_Mapping(dr->Addr(), h, ttl); + new_mapping = std::make_shared(dr->Addr(), h, ttl); it = all_mappings.find(dr->Addr()); if ( it == all_mappings.end() ) { @@ -1021,7 +1021,7 @@ void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl, bool m } else { - new_mapping = new DNS_Mapping(dr->Host(), h, ttl, dr->RequestType()); + new_mapping = std::make_shared(dr->Host(), h, ttl, dr->RequestType()); auto key = std::make_pair(dr->RequestType(), dr->Host()); it = all_mappings.find(key); @@ -1055,12 +1055,12 @@ void DNS_Mgr::AddResult(DNS_Request* dr, struct hostent* h, uint32_t ttl, bool m CompareMappings(prev_mapping, new_mapping); if ( keep_prev ) - delete new_mapping; + new_mapping.reset(); else - delete prev_mapping; + prev_mapping.reset(); } -void DNS_Mgr::CompareMappings(DNS_Mapping* prev_mapping, DNS_Mapping* new_mapping) +void DNS_Mgr::CompareMappings(const DNS_MappingPtr& prev_mapping, const DNS_MappingPtr& new_mapping) { if ( prev_mapping->Failed() ) { @@ -1100,14 +1100,14 @@ void DNS_Mgr::CompareMappings(DNS_Mapping* prev_mapping, DNS_Mapping* new_mappin return; } - auto prev_delta = AddrListDelta(prev_a.get(), new_a.get()); - auto new_delta = AddrListDelta(new_a.get(), prev_a.get()); + auto prev_delta = AddrListDelta(prev_a, new_a); + auto new_delta = AddrListDelta(new_a, prev_a); if ( prev_delta->Length() > 0 || new_delta->Length() > 0 ) Event(dns_mapping_altered, new_mapping, std::move(prev_delta), std::move(new_delta)); } -ListValPtr DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2) +ListValPtr DNS_Mgr::AddrListDelta(ListValPtr al1, ListValPtr al2) { auto delta = make_intrusive(TYPE_ADDR); @@ -1142,8 +1142,8 @@ void DNS_Mgr::LoadCache(const std::string& path) return; // Loop until we find a mapping that doesn't initialize correctly. - DNS_Mapping* m = new DNS_Mapping(f); - for ( ; ! m->NoMapping() && ! m->InitFailed(); m = new DNS_Mapping(f) ) + auto m = std::make_shared(f); + for ( ; ! m->NoMapping() && ! m->InitFailed(); m = std::make_shared(f) ) { if ( m->ReqHost() ) all_mappings.insert_or_assign(std::make_pair(m->ReqType(), m->ReqHost()), m); @@ -1154,7 +1154,6 @@ void DNS_Mgr::LoadCache(const std::string& path) if ( ! m->NoMapping() ) reporter->FatalError("DNS cache corrupted"); - delete m; fclose(f); } @@ -1192,7 +1191,7 @@ TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name, bool cleanup_exp if ( it == all_mappings.end() ) return nullptr; - DNS_Mapping* d = it->second; + auto d = it->second; if ( ! d || d->names.empty() ) return nullptr; @@ -1200,7 +1199,6 @@ TableValPtr DNS_Mgr::LookupNameInCache(const std::string& name, bool cleanup_exp if ( cleanup_expired && (d && d->Expired()) ) { all_mappings.erase(it); - delete d; return nullptr; } @@ -1219,12 +1217,11 @@ StringValPtr DNS_Mgr::LookupAddrInCache(const IPAddr& addr, bool cleanup_expired if ( it == all_mappings.end() ) return nullptr; - DNS_Mapping* d = it->second; + auto d = it->second; if ( cleanup_expired && d->Expired() ) { all_mappings.erase(it); - delete d; return nullptr; } else if ( check_failed && d->Failed() ) @@ -1247,12 +1244,11 @@ StringValPtr DNS_Mgr::LookupOtherInCache(const std::string& name, int request_ty if ( it == all_mappings.end() ) return nullptr; - DNS_Mapping* d = it->second; + auto d = it->second; if ( cleanup_expired && d->Expired() ) { all_mappings.erase(it); - delete d; return nullptr; } @@ -1373,10 +1369,6 @@ void DNS_Mgr::CheckAsyncOtherRequest(const std::string& host, bool timeout, int void DNS_Mgr::Flush() { Resolve(); - - for ( auto& [key, mapping] : all_mappings ) - delete mapping; - all_mappings.clear(); } diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index 65e8c88910..a392ee9f93 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -45,6 +45,7 @@ using StringValPtr = IntrusivePtr; namespace zeek::detail { class DNS_Mapping; +using DNS_MappingPtr = std::shared_ptr; class DNS_Request; enum DNS_MgrMode @@ -258,17 +259,17 @@ protected: void CheckAsyncHostRequest(const std::string& host, bool timeout); void CheckAsyncOtherRequest(const std::string& host, bool timeout, int request_type); - void Event(EventHandlerPtr e, DNS_Mapping* dm); - void Event(EventHandlerPtr e, DNS_Mapping* dm, ListValPtr l1, ListValPtr l2); - void Event(EventHandlerPtr e, DNS_Mapping* old_dm, DNS_Mapping* new_dm); + void Event(EventHandlerPtr e, const DNS_MappingPtr& dm); + void Event(EventHandlerPtr e, const DNS_MappingPtr& dm, ListValPtr l1, ListValPtr l2); + void Event(EventHandlerPtr e, const DNS_MappingPtr& old_dm, DNS_MappingPtr new_dm); - ValPtr BuildMappingVal(DNS_Mapping* dm); + ValPtr BuildMappingVal(const DNS_MappingPtr& dm); - void CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm); - ListValPtr AddrListDelta(ListVal* al1, ListVal* al2); + void CompareMappings(const DNS_MappingPtr& prev_dm, const DNS_MappingPtr& new_dm); + ListValPtr AddrListDelta(ListValPtr al1, ListValPtr al2); using MappingKey = std::variant>; - using MappingMap = std::map; + using MappingMap = std::map; void LoadCache(const std::string& path); void Save(FILE* f, const MappingMap& m); From c2bf602d94b662295a80c5740aa0b429b59244ae Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 29 Mar 2022 14:06:17 -0700 Subject: [PATCH 180/204] Add out_ptr, use for c-ares interface calls --- .gitmodules | 3 ++ CMakeLists.txt | 1 + auxil/out_ptr | 1 + src/DNS_Mgr.cc | 85 ++++++++++++++++++++++++++------------------------ 4 files changed, 50 insertions(+), 40 deletions(-) create mode 160000 auxil/out_ptr diff --git a/.gitmodules b/.gitmodules index 0c5cccce1a..cb20683187 100644 --- a/.gitmodules +++ b/.gitmodules @@ -55,3 +55,6 @@ [submodule "auxil/c-ares"] path = auxil/c-ares url = https://github.com/c-ares/c-ares +[submodule "auxil/out_ptr"] + path = auxil/out_ptr + url = https://github.com/soasis/out_ptr.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 402a0311a9..5f7df8ffdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -481,6 +481,7 @@ include(GetArchitecture) include(RequireCXX17) include(FindKqueue) include(FindCAres) +include_directories(BEFORE "auxil/out_ptr/include") if ( (OPENSSL_VERSION VERSION_EQUAL "1.1.0") OR (OPENSSL_VERSION VERSION_GREATER "1.1.0") ) set(ZEEK_HAVE_OPENSSL_1_1 true CACHE INTERNAL "" FORCE) diff --git a/auxil/out_ptr b/auxil/out_ptr new file mode 160000 index 0000000000..ea379b2f35 --- /dev/null +++ b/auxil/out_ptr @@ -0,0 +1 @@ +Subproject commit ea379b2f35e28d6ee894e05ad4c26ed60a613d30 diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index ab96a8421f..ed7f0ffee1 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -25,6 +25,9 @@ #include #endif +#include +using ztd::out_ptr::out_ptr; + #include #include #include @@ -173,6 +176,15 @@ static const char* request_type_string(int request_type) } } +struct ares_deleter + { + void operator()(char* s) const { ares_free_string(s); } + void operator()(unsigned char* s) const { ares_free_string(s); } + void operator()(ares_addrinfo* s) const { ares_freeaddrinfo(s); } + void operator()(struct hostent* h) const { ares_free_hostent(h); } + void operator()(struct ares_txt_reply* h) const { ares_free_data(h); } + }; + namespace zeek::detail { static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinfo* result); @@ -205,7 +217,7 @@ private: IPAddr addr; int request_type = 0; // Query type bool async = false; - unsigned char* query = nullptr; + std::unique_ptr query; static uint16_t request_id; }; @@ -225,11 +237,7 @@ DNS_Request::DNS_Request(const IPAddr& addr, bool async) : addr(addr), async(asy request_type = T_PTR; } -DNS_Request::~DNS_Request() - { - if ( query ) - ares_free_string(query); - } +DNS_Request::~DNS_Request() { } void DNS_Request::MakeRequest(ares_channel channel, DNS_Mgr* mgr) { @@ -258,17 +266,18 @@ void DNS_Request::MakeRequest(ares_channel channel, DNS_Mgr* mgr) else query_host = host; - unsigned char* query = NULL; + std::unique_ptr query_str; int len = 0; int status = ares_create_query(query_host.c_str(), C_IN, request_type, - DNS_Request::request_id, 1, &query, &len, 0); + DNS_Request::request_id, 1, + out_ptr(query_str), &len, 0); if ( status != ARES_SUCCESS ) return; // Store this so it can be destroyed when the request is destroyed. - this->query = query; - ares_send(channel, query, len, query_cb, req_data); + this->query = std::move(query_str); + ares_send(channel, this->query.get(), len, query_cb, req_data); } } @@ -305,27 +314,22 @@ static int get_ttl(unsigned char* abuf, int alen, int* ttl) { int status; long len; - char* hostname = NULL; + std::unique_ptr hostname; *ttl = DNS_TIMEOUT; unsigned char* aptr = abuf + HFIXEDSZ; - status = ares_expand_name(aptr, abuf, alen, &hostname, &len); + status = ares_expand_name(aptr, abuf, alen, out_ptr(hostname), &len); if ( status != ARES_SUCCESS ) - { - ares_free_string(hostname); return status; - } + if ( aptr + len + QFIXEDSZ > abuf + alen ) - { - ares_free_string(hostname); return ARES_EBADRESP; - } aptr += len + QFIXEDSZ; - ares_free_string(hostname); + hostname.reset(); - status = ares_expand_name(aptr, abuf, alen, &hostname, &len); + status = ares_expand_name(aptr, abuf, alen, out_ptr(hostname), &len); if ( status != ARES_SUCCESS ) return status; @@ -333,8 +337,6 @@ static int get_ttl(unsigned char* abuf, int alen, int* ttl) return ARES_EBADRESP; aptr += len; - ares_free_string(hostname); - *ttl = DNS_RR_TTL(aptr); return status; @@ -348,6 +350,7 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf { auto arg_data = reinterpret_cast(arg); const auto [req, mgr] = *arg_data; + std::unique_ptr res_ptr(result); if ( status != ARES_SUCCESS ) { @@ -387,8 +390,9 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf // Push a null on the end so the addr list has a final point during later parsing. addrs.push_back(NULL); - struct hostent he; - memset(&he, 0, sizeof(struct hostent)); + struct hostent he + { + }; he.h_name = util::copy_string(result->name); he.h_addrtype = AF_INET; he.h_length = sizeof(in_addr); @@ -404,8 +408,9 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf // Push a null on the end so the addr list has a final point during later parsing. addrs6.push_back(NULL); - struct hostent he; - memset(&he, 0, sizeof(struct hostent)); + struct hostent he + { + }; he.h_name = util::copy_string(result->name); he.h_addrtype = AF_INET6; he.h_length = sizeof(in6_addr); @@ -418,9 +423,10 @@ static void addrinfo_cb(void* arg, int status, int timeouts, struct ares_addrinf } req->ProcessAsyncResult(timeouts > 0, mgr); - ares_freeaddrinfo(result); - delete arg_data; + + // TODO: might need to turn these into unique_ptr as well? delete req; + delete arg_data; } static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, int len) @@ -455,25 +461,24 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in { case T_PTR: { - struct hostent* he; + std::unique_ptr he; if ( req->Addr().GetFamily() == IPv4 ) { struct in_addr addr; req->Addr().CopyIPv4(&addr); - status = ares_parse_ptr_reply(buf, len, &addr, sizeof(addr), AF_INET, &he); + status = ares_parse_ptr_reply(buf, len, &addr, sizeof(addr), AF_INET, + out_ptr(he)); } else { struct in6_addr addr; req->Addr().CopyIPv6(&addr); - status = ares_parse_ptr_reply(buf, len, &addr, sizeof(addr), AF_INET6, &he); + status = ares_parse_ptr_reply(buf, len, &addr, sizeof(addr), AF_INET6, + out_ptr(he)); } if ( status == ARES_SUCCESS ) - { - mgr->AddResult(req, he, ttl); - ares_free_hostent(he); - } + mgr->AddResult(req, he.get(), ttl); else { // See above for why DNS_TIMEOUT here. @@ -483,8 +488,8 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in } case T_TXT: { - struct ares_txt_reply* reply; - int r = ares_parse_txt_reply(buf, len, &reply); + std::unique_ptr reply; + int r = ares_parse_txt_reply(buf, len, out_ptr(reply)); if ( r == ARES_SUCCESS ) { // Use a hostent to send the data into AddResult(). We only care about @@ -495,13 +500,13 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in // rest away. There really isn't a good reason for this, we just haven't // ever done so. It would likely require some changes to the output from // Lookup(), since right now it only returns one value. - struct hostent he; - memset(&he, 0, sizeof(struct hostent)); + struct hostent he + { + }; he.h_name = util::copy_string(reinterpret_cast(reply->txt)); mgr->AddResult(req, &he, ttl); delete[] he.h_name; - ares_free_data(reply); } else { From f9f37b11c631de6423e35df37d9224b2bf6c1866 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 5 Apr 2022 21:14:04 -0700 Subject: [PATCH 181/204] Add new features to IOSource::Manager, used by DNS_Mgr - iosource_mgr can now track write events to file descriptors as well as read events. This adds an argument to both RegisterFd() and UnregisterFd() for setting the mode, defaulting to read. - IOSources can now implement a ProcessFd() method that allows them to handle events to single file descriptors instead of of having to loop through/track sets of them at processing time. --- src/DNS_Mgr.cc | 42 ++++++++------ src/DNS_Mgr.h | 8 ++- src/RunState.cc | 15 +++-- src/iosource/IOSource.h | 28 ++++++++- src/iosource/Manager.cc | 126 ++++++++++++++++++++++++++++++---------- src/iosource/Manager.h | 23 ++++++-- 6 files changed, 179 insertions(+), 63 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index ed7f0ffee1..3fc2404dfa 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -537,10 +537,10 @@ static void query_cb(void* arg, int status, int timeouts, unsigned char* buf, in static void sock_cb(void* data, int s, int read, int write) { auto mgr = reinterpret_cast(data); - mgr->RegisterSocket(s, read == 1); + mgr->RegisterSocket(s, read == 1, write == 1); } -DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) : mode(arg_mode) +DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode) : IOSource(true), mode(arg_mode) { ares_library_init(ARES_LIB_INIT_ALL); } @@ -554,17 +554,28 @@ DNS_Mgr::~DNS_Mgr() ares_library_cleanup(); } -void DNS_Mgr::RegisterSocket(int fd, bool active) +void DNS_Mgr::RegisterSocket(int fd, bool read, bool write) { - if ( active && socket_fds.count(fd) == 0 ) + if ( read && socket_fds.count(fd) == 0 ) { socket_fds.insert(fd); - iosource_mgr->RegisterFd(fd, this); + iosource_mgr->RegisterFd(fd, this, IOSource::READ); } - else if ( ! active && socket_fds.count(fd) != 0 ) + else if ( ! read && socket_fds.count(fd) != 0 ) { socket_fds.erase(fd); - iosource_mgr->UnregisterFd(fd, this); + iosource_mgr->UnregisterFd(fd, this, IOSource::READ); + } + + if ( write && write_socket_fds.count(fd) == 0 ) + { + write_socket_fds.insert(fd); + iosource_mgr->RegisterFd(fd, this, IOSource::WRITE); + } + else if ( ! write && write_socket_fds.count(fd) != 0 ) + { + write_socket_fds.erase(fd); + iosource_mgr->UnregisterFd(fd, this, IOSource::WRITE); } } @@ -1385,20 +1396,13 @@ double DNS_Mgr::GetNextTimeout() return run_state::network_time + DNS_TIMEOUT; } -void DNS_Mgr::Process() +void DNS_Mgr::ProcessFd(int fd, int flags) { - // If iosource_mgr says that we got a result on the socket fd, we don't have to ask c-ares - // to retrieve it for us. We have the file descriptor already, just call ares_process_fd() - // with it. Unfortunately, we may also have sockets close during this call, so we need to - // to make a copy of the list first. Having a list change while looping over it can - // cause segfaults. - decltype(socket_fds) temp_fds{socket_fds}; - - for ( int fd : temp_fds ) + if ( socket_fds.count(fd) != 0 ) { - // double check this one wasn't removed already before trying to process it - if ( socket_fds.count(fd) != 0 ) - ares_process_fd(channel, fd, ARES_SOCKET_BAD); + int read_fd = (flags & IOSource::ProcessFlags::READ) != 0 ? fd : ARES_SOCKET_BAD; + int write_fd = (flags & IOSource::ProcessFlags::WRITE) != 0 ? fd : ARES_SOCKET_BAD; + ares_process_fd(channel, read_fd, write_fd); } IssueAsyncRequests(); diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index a392ee9f93..9834f68a09 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -240,7 +240,9 @@ public: /** * Used by the c-ares socket call back to register/unregister a socket file descriptor. */ - void RegisterSocket(int fd, bool active); + void RegisterSocket(int fd, bool read, bool write); + + ares_channel& GetChannel() { return channel; } protected: friend class LookupCallback; @@ -277,7 +279,8 @@ protected: void IssueAsyncRequests(); // IOSource interface. - void Process() override; + void Process() override { } + void ProcessFd(int fd, int flags) override; void InitSource() override; const char* Tag() override { return "DNS_Mgr"; } double GetNextTimeout() override; @@ -337,6 +340,7 @@ protected: unsigned long failed = 0; std::set socket_fds; + std::set write_socket_fds; }; extern DNS_Mgr* dns_mgr; diff --git a/src/RunState.cc b/src/RunState.cc index 30abb987e0..76ac99e79d 100644 --- a/src/RunState.cc +++ b/src/RunState.cc @@ -283,7 +283,7 @@ void run_loop() { util::detail::set_processing_status("RUNNING", "run_loop"); - std::vector ready; + iosource::Manager::ReadySources ready; ready.reserve(iosource_mgr->TotalSize()); while ( iosource_mgr->Size() || (BifConst::exit_only_after_terminate && ! terminating) ) @@ -310,11 +310,16 @@ void run_loop() if ( ! ready.empty() ) { - for ( auto src : ready ) + for ( const auto& src : ready ) { - DBG_LOG(DBG_MAINLOOP, "processing source %s", src->Tag()); - current_iosrc = src; - src->Process(); + auto* iosrc = src.src; + + DBG_LOG(DBG_MAINLOOP, "processing source %s", iosrc->Tag()); + current_iosrc = iosrc; + if ( iosrc->ImplementsProcessFd() && src.fd != -1 ) + iosrc->ProcessFd(src.fd, src.flags); + else + iosrc->Process(); } } else if ( (have_pending_timers || communication_enabled || diff --git a/src/iosource/IOSource.h b/src/iosource/IOSource.h index 8e863f78e1..16fc76a6c5 100644 --- a/src/iosource/IOSource.h +++ b/src/iosource/IOSource.h @@ -12,10 +12,20 @@ namespace zeek::iosource class IOSource { public: + enum ProcessFlags + { + READ = 0x01, + WRITE = 0x02 + }; + /** * Constructor. + * + * @param process_fd A flag for indicating whether the child class implements + * the ProcessFd() method. This is used by the run loop for dispatching to the + * appropriate process method. */ - IOSource() { closed = false; } + IOSource(bool process_fd = false) : implements_process_fd(process_fd) { } /** * Destructor. @@ -66,6 +76,19 @@ public: */ virtual void Process() = 0; + /** + * Optional process method that allows an IOSource to only process + * the file descriptor that is found ready and not every possible + * descriptor. If this method is implemented, true must be passed + * to the IOSource constructor via the child class. + * + * @param fd The file descriptor to process. + * @param flags Flags indicating what type of event is being + * processed. + */ + virtual void ProcessFd(int fd, int flags) { } + bool ImplementsProcessFd() const { return implements_process_fd; } + /** * Returns a descriptive tag representing the source for debugging. * @@ -84,7 +107,8 @@ protected: void SetClosed(bool is_closed) { closed = is_closed; } private: - bool closed; + bool closed = false; + bool implements_process_fd = false; }; } // namespace zeek::iosource diff --git a/src/iosource/Manager.cc b/src/iosource/Manager.cc index 8f669512fa..6c9876c398 100644 --- a/src/iosource/Manager.cc +++ b/src/iosource/Manager.cc @@ -103,7 +103,7 @@ void Manager::Wakeup(const std::string& where) wakeup->Ping(where); } -void Manager::FindReadySources(std::vector* ready) +void Manager::FindReadySources(ReadySources* ready) { ready->clear(); @@ -155,7 +155,7 @@ void Manager::FindReadySources(std::vector* ready) if ( timeout == 0 && ! time_to_poll ) { added = true; - ready->push_back(timeout_src); + ready->push_back({timeout_src, -1, 0}); } } @@ -167,13 +167,13 @@ void Manager::FindReadySources(std::vector* ready) // Avoid calling Poll() if we can help it since on very // high-traffic networks, we spend too much time in // Poll() and end up dropping packets. - ready->push_back(pkt_src); + ready->push_back({pkt_src, -1, 0}); } else { if ( ! run_state::pseudo_realtime && ! time_to_poll ) // A pcap file is always ready to process unless it's suspended - ready->push_back(pkt_src); + ready->push_back({pkt_src, -1, 0}); } } } @@ -189,7 +189,7 @@ void Manager::FindReadySources(std::vector* ready) Poll(ready, timeout, timeout_src); } -void Manager::Poll(std::vector* ready, double timeout, IOSource* timeout_src) +void Manager::Poll(ReadySources* ready, double timeout, IOSource* timeout_src) { struct timespec kqueue_timeout; ConvertTimeout(timeout, kqueue_timeout); @@ -205,7 +205,7 @@ void Manager::Poll(std::vector* ready, double timeout, IOSource* time else if ( ret == 0 ) { if ( timeout_src ) - ready->push_back(timeout_src); + ready->push_back({timeout_src, -1, 0}); } else { @@ -217,7 +217,15 @@ void Manager::Poll(std::vector* ready, double timeout, IOSource* time { std::map::const_iterator it = fd_map.find(events[i].ident); if ( it != fd_map.end() ) - ready->push_back(it->second); + ready->push_back({it->second, static_cast(events[i].ident), + IOSource::ProcessFlags::READ}); + } + else if ( events[i].filter == EVFILT_WRITE ) + { + std::map::const_iterator it = write_fd_map.find(events[i].ident); + if ( it != write_fd_map.end() ) + ready->push_back({it->second, static_cast(events[i].ident), + IOSource::ProcessFlags::WRITE}); } } } @@ -240,41 +248,97 @@ void Manager::ConvertTimeout(double timeout, struct timespec& spec) } } -bool Manager::RegisterFd(int fd, IOSource* src) +bool Manager::RegisterFd(int fd, IOSource* src, int flags) { - struct kevent event; - EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, NULL); - int ret = kevent(event_queue, &event, 1, NULL, 0, NULL); - if ( ret != -1 ) - { - events.push_back({}); - DBG_LOG(DBG_MAINLOOP, "Registered fd %d from %s", fd, src->Tag()); - fd_map[fd] = src; + std::vector new_events; - Wakeup("RegisterFd"); - return true; - } - else + if ( (flags & IOSource::READ) != 0 ) { - reporter->Error("Failed to register fd %d from %s: %s", fd, src->Tag(), strerror(errno)); - return false; + if ( fd_map.count(fd) == 0 ) + { + new_events.push_back({}); + EV_SET(&(new_events.back()), fd, EVFILT_READ, EV_ADD, 0, 0, NULL); + } } + if ( (flags & IOSource::WRITE) != 0 ) + { + if ( write_fd_map.count(fd) == 0 ) + { + new_events.push_back({}); + EV_SET(&(new_events.back()), fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); + } + } + + if ( ! new_events.empty() ) + { + int ret = kevent(event_queue, new_events.data(), new_events.size(), NULL, 0, NULL); + if ( ret != -1 ) + { + DBG_LOG(DBG_MAINLOOP, "Registered fd %d from %s", fd, src->Tag()); + for ( const auto& a : new_events ) + events.push_back({}); + + if ( (flags & IOSource::READ) != 0 ) + fd_map[fd] = src; + if ( (flags & IOSource::WRITE) != 0 ) + write_fd_map[fd] = src; + + Wakeup("RegisterFd"); + return true; + } + else + { + reporter->Error("Failed to register fd %d from %s: %s (flags %d)", fd, src->Tag(), + strerror(errno), flags); + return false; + } + } + + return true; } -bool Manager::UnregisterFd(int fd, IOSource* src) +bool Manager::UnregisterFd(int fd, IOSource* src, int flags) { - if ( fd_map.find(fd) != fd_map.end() ) + std::vector new_events; + + if ( (flags & IOSource::READ) != 0 ) { - struct kevent event; - EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); - int ret = kevent(event_queue, &event, 1, NULL, 0, NULL); + if ( fd_map.count(fd) != 0 ) + { + new_events.push_back({}); + EV_SET(&(new_events.back()), fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + } + } + if ( (flags & IOSource::WRITE) != 0 ) + { + if ( write_fd_map.count(fd) != 0 ) + { + new_events.push_back({}); + EV_SET(&(new_events.back()), fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + } + } + + if ( ! new_events.empty() ) + { + int ret = kevent(event_queue, new_events.data(), new_events.size(), NULL, 0, NULL); if ( ret != -1 ) + { DBG_LOG(DBG_MAINLOOP, "Unregistered fd %d from %s", fd, src->Tag()); + for ( const auto& a : new_events ) + events.pop_back(); - fd_map.erase(fd); + if ( (flags & IOSource::READ) != 0 ) + fd_map.erase(fd); + if ( (flags & IOSource::WRITE) != 0 ) + write_fd_map.erase(fd); - Wakeup("UnregisterFd"); - return true; + Wakeup("UnregisterFd"); + return true; + } + + // We don't care about failure here. If it failed to unregister, it's likely because + // the file descriptor was already closed, and kqueue already automatically removed + // it. } else { @@ -282,6 +346,8 @@ bool Manager::UnregisterFd(int fd, IOSource* src) src->Tag()); return false; } + + return true; } void Manager::Register(IOSource* src, bool dont_count, bool manage_lifetime) diff --git a/src/iosource/Manager.h b/src/iosource/Manager.h index 5053bbd132..1e2bbbface 100644 --- a/src/iosource/Manager.h +++ b/src/iosource/Manager.h @@ -29,6 +29,15 @@ class PktDumper; class Manager { public: + struct ReadySource + { + IOSource* src = nullptr; + int fd = -1; + int flags = 0; + }; + + using ReadySources = std::vector; + /** * Constructor. */ @@ -110,22 +119,25 @@ public: * * @param ready A vector used to return the set of sources that are ready. */ - void FindReadySources(std::vector* ready); + void FindReadySources(ReadySources* ready); /** * Registers a file descriptor and associated IOSource with the manager - * to be checked during FindReadySources. + * to be checked during FindReadySources. This will register the file + * descriptor to check for read events. * * @param fd A file descriptor pointing at some resource that should be * checked for readiness. * @param src The IOSource that owns the file descriptor. + * @param flags A combination of values from IOSource::ProcessFlags for + * which modes we should register for this file descriptor. */ - bool RegisterFd(int fd, IOSource* src); + bool RegisterFd(int fd, IOSource* src, int flags = IOSource::READ); /** * Unregisters a file descriptor from the FindReadySources checks. */ - bool UnregisterFd(int fd, IOSource* src); + bool UnregisterFd(int fd, IOSource* src, int flags = IOSource::READ); /** * Forces the poll in FindReadySources to wake up immediately. This method @@ -147,7 +159,7 @@ private: * @param timeout_src The source associated with the current timeout value. * This is typically a timer manager object. */ - void Poll(std::vector* ready, double timeout, IOSource* timeout_src); + void Poll(ReadySources* ready, double timeout, IOSource* timeout_src); /** * Converts a double timeout value into a timespec struct used for calls @@ -208,6 +220,7 @@ private: int event_queue = -1; std::map fd_map; + std::map write_fd_map; // This is only used for the output of the call to kqueue in FindReadySources(). // The actual events are stored as part of the queue. From ea7cea12c463c336489e2fdd0748debb02a6acd1 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sun, 3 Apr 2022 16:56:17 -0700 Subject: [PATCH 182/204] Set larger UDP buffer to avoid TCP fallback if possible This commit sets the UDP buffer to a larger size, as well as adds an EDNS block to the DNS request passing this size. This allows DNS servers to return larger responses, and in turn allow c-ares to avoid TCP fallback due to requests failing because of the lack of buffer size. --- src/DNS_Mgr.cc | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 3fc2404dfa..02dd4f217f 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -52,6 +52,10 @@ constexpr int DNS_TIMEOUT = 5; // The maximum allowed number of pending asynchronous requests. constexpr int MAX_PENDING_REQUESTS = 20; +// The maximum number of bytes requested via UDP. TCP fallback won't happen on +// requests until a response is larger than this. +constexpr int MAX_UDP_BUFFER_SIZE = 4096; + // This unfortunately doesn't exist in c-ares, even though it seems rather useful. static const char* request_type_string(int request_type) { @@ -268,9 +272,9 @@ void DNS_Request::MakeRequest(ares_channel channel, DNS_Mgr* mgr) std::unique_ptr query_str; int len = 0; - int status = ares_create_query(query_host.c_str(), C_IN, request_type, - DNS_Request::request_id, 1, - out_ptr(query_str), &len, 0); + int status = ares_create_query( + query_host.c_str(), C_IN, request_type, DNS_Request::request_id, 1, + out_ptr(query_str), &len, MAX_UDP_BUFFER_SIZE); if ( status != ARES_SUCCESS ) return; @@ -587,11 +591,18 @@ void DNS_Mgr::InitSource() ares_options options; int optmask = 0; - // Don't close the socket for the server even if we have no active - // requests. - options.flags = ARES_FLAG_STAYOPEN; + // Enable an EDNS option to be sent with the requests. This allows us to set + // a bigger UDP buffer size in the request, which prevents fallback to TCP + // at least up to that size. + options.flags = ARES_FLAG_EDNS; optmask |= ARES_OPT_FLAGS; + options.ednspsz = MAX_UDP_BUFFER_SIZE; + optmask |= ARES_OPT_EDNSPSZ; + + options.socket_receive_buffer_size = MAX_UDP_BUFFER_SIZE; + optmask |= ARES_OPT_SOCK_RCVBUF; + // This option is in milliseconds. options.timeout = DNS_TIMEOUT * 1000; optmask |= ARES_OPT_TIMEOUTMS; From 53579a938302495e8a2df03fc90ce00c95a9e2dd Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 13 Apr 2022 14:42:46 -0700 Subject: [PATCH 183/204] Update NEWS with information about DNS_Mgr changes --- NEWS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS b/NEWS index feebbd0928..f2e5f86a3f 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,11 @@ New Functionality regard. Like binpac and bifcl, it's now also available as a standalone git repository and hooked into the Zeek distribution as a submodule. +- Zeek now uses the c-ares (https://c-ares.org) library for performing DNS + requests, replacing an old custom implementation of a DNS resolver. Switching + to this library simplifies the DNS code, adds support for IPv6 lookups, and + adds the ability to support more DNS request types in the future. + Changed Functionality --------------------- From f601878003255abacd3798fb044fcabc02c2ba3d Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 22 Apr 2022 07:50:46 -0700 Subject: [PATCH 184/204] Add DNS fuzzing corpus from c-ares --- src/fuzzers/dns-corpus.zip | Bin 0 -> 26244 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/fuzzers/dns-corpus.zip diff --git a/src/fuzzers/dns-corpus.zip b/src/fuzzers/dns-corpus.zip new file mode 100644 index 0000000000000000000000000000000000000000..a67cdaff32662f5136e2766fcec29e89df448e9c GIT binary patch literal 26244 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 EAA_8A&Hw-a literal 0 HcmV?d00001 From 521539d4f9f55c7fbaa65b44005932cc5360d8a4 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 25 Apr 2022 10:09:50 +0100 Subject: [PATCH 185/204] Disable OpenSSL initialization starting with 1.1.0 Starting with OpenSSL 1.1.0, library initialization is no longer required - and might even be harmful. See https://wiki.openssl.org/index.php/Library_Initialization for details. --- src/zeek-setup.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 952db62b4f..4ad5f8e3a5 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -5,6 +5,7 @@ #include "zeek/zeek-config.h" #include +#include #include #include #include @@ -544,10 +545,12 @@ SetupResult setup(int argc, char** argv, Options* zopts) // DEBUG_MSG("HMAC key: %s\n", md5_digest_print(shared_hmac_md5_key)); init_hash_function(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L ERR_load_crypto_strings(); OPENSSL_add_all_algorithms_conf(); SSL_library_init(); SSL_load_error_strings(); +#endif // FIXME: On systems that don't provide /dev/urandom, OpenSSL doesn't // seed the PRNG. We should do this here (but at least Linux, FreeBSD From 309c8e2f2231819df243c344c6ed15223bc944b0 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 25 Apr 2022 11:55:23 -0700 Subject: [PATCH 186/204] Forgot to merge cmake changes for c-ares --- cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake b/cmake index 0fa8b3a20c..957419a877 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 0fa8b3a20ca6d4e32b56cdeee693cb46eec41f5e +Subproject commit 957419a87751f365b2326c8dac11e46c87748ce3 From c18d20fda1ec00d8ff49268c2e6111113442316b Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 25 Apr 2022 18:56:28 +0000 Subject: [PATCH 187/204] Rework FindCAres.cmake to not use ExternalProject, fixing OBS builds --- cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake b/cmake index 957419a877..c7e1529a06 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 957419a87751f365b2326c8dac11e46c87748ce3 +Subproject commit c7e1529a061f9169d9bb91b802b0e6b43df6401d From b23d29241086b133e3cba7d96f8fe7584cd6b7ee Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 18 Apr 2022 17:52:56 -0700 Subject: [PATCH 188/204] Management framework: consistency fixes around event() vs Broker::publish() Switch to using Broker::publish() for any event we only send to a peered entity, and not to drive local processing. Also minor indentation cleanup. --- .../frameworks/management/agent/main.zeek | 96 +++++++++---------- .../frameworks/management/controller/api.zeek | 2 +- .../management/controller/main.zeek | 87 +++++++++-------- .../frameworks/management/node/main.zeek | 23 ++--- 4 files changed, 97 insertions(+), 111 deletions(-) diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index f3a8bd2809..45993b29c4 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -57,6 +57,12 @@ global g_nodes: table[string] of Management::Node; global g_cluster: table[string] of Supervisor::ClusterEndpoint; +function agent_topic(): string + { + local epi = Management::Agent::endpoint_info(); + return Management::Agent::topic_prefix + "/" + epi$id; + } + event SupervisorControl::create_response(reqid: string, result: string) { local req = Management::Request::lookup(reqid); @@ -69,7 +75,9 @@ event SupervisorControl::create_response(reqid: string, result: string) { local msg = fmt("failed to create node %s: %s", name, result); Management::Log::error(msg); - event Management::Agent::API::notify_error(Management::Agent::name, msg, name); + Broker::publish(agent_topic(), + Management::Agent::API::notify_error, + Management::Agent::name, msg, name); } Management::Request::finish(reqid); @@ -87,7 +95,9 @@ event SupervisorControl::destroy_response(reqid: string, result: bool) { local msg = fmt("failed to destroy node %s, %s", name, reqid); Management::Log::error(msg); - event Management::Agent::API::notify_error(Management::Agent::name, msg, name); + Broker::publish(agent_topic(), + Management::Agent::API::notify_error, + Management::Agent::name, msg, name); } Management::Request::finish(reqid); @@ -97,7 +107,8 @@ function supervisor_create(nc: Supervisor::NodeConfig) { local req = Management::Request::create(); req$supervisor_state = SupervisorState($node = nc$name); - event SupervisorControl::create_request(req$id, nc); + Broker::publish(SupervisorControl::topic_prefix, + SupervisorControl::create_request, req$id, nc); Management::Log::info(fmt("issued supervisor create for %s, %s", nc$name, req$id)); } @@ -105,7 +116,8 @@ function supervisor_destroy(node: string) { local req = Management::Request::create(); req$supervisor_state = SupervisorState($node = node); - event SupervisorControl::destroy_request(req$id, node); + Broker::publish(SupervisorControl::topic_prefix, + SupervisorControl::destroy_request, req$id, node); Management::Log::info(fmt("issued supervisor destroy for %s, %s", node, req$id)); } @@ -205,8 +217,9 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M $instance = Management::Agent::name); Management::Log::info(fmt("tx Management::Agent::API::set_configuration_response %s", - Management::result_to_string(res))); - event Management::Agent::API::set_configuration_response(reqid, res); + Management::result_to_string(res))); + Broker::publish(agent_topic(), + Management::Agent::API::set_configuration_response, reqid, res); } } @@ -294,8 +307,9 @@ event SupervisorControl::status_response(reqid: string, result: Supervisor::Stat res$data = node_statuses; Management::Log::info(fmt("tx Management::Agent::API::get_nodes_response %s", - Management::result_to_string(res))); - event Management::Agent::API::get_nodes_response(req$parent_id, res); + Management::result_to_string(res))); + Broker::publish(agent_topic(), + Management::Agent::API::get_nodes_response, req$parent_id, res); } event Management::Agent::API::get_nodes_request(reqid: string) @@ -305,7 +319,8 @@ event Management::Agent::API::get_nodes_request(reqid: string) local req = Management::Request::create(); req$parent_id = reqid; - event SupervisorControl::status_request(req$id, ""); + Broker::publish(SupervisorControl::topic_prefix, + SupervisorControl::status_request, req$id, ""); Management::Log::info(fmt("issued supervisor status, %s", req$id)); } @@ -375,7 +390,8 @@ event Management::Node::API::node_dispatch_response(reqid: string, result: Manag # Send response event back to controller and clean up main request state. Management::Log::info(fmt("tx Management::Agent::API::node_dispatch_response %s", Management::Request::to_string(req))); - event Management::Agent::API::node_dispatch_response(req$id, req$results); + Broker::publish(agent_topic(), + Management::Agent::API::node_dispatch_response, req$id, req$results); Management::Request::finish(req$id); } @@ -405,7 +421,8 @@ event Management::Agent::API::node_dispatch_request(reqid: string, action: vecto Management::Log::info(fmt( "tx Management::Agent::API::node_dispatch_response %s, no node overlap", reqid)); - event Management::Agent::API::node_dispatch_response(reqid, vector()); + Broker::publish(agent_topic(), + Management::Agent::API::node_dispatch_response, reqid, vector()); return; } } @@ -417,7 +434,8 @@ event Management::Agent::API::node_dispatch_request(reqid: string, action: vecto Management::Log::info(fmt( "tx Management::Agent::API::node_dispatch_response %s, no nodes registered", reqid)); - event Management::Agent::API::node_dispatch_response(reqid, vector()); + Broker::publish(agent_topic(), + Management::Agent::API::node_dispatch_response, reqid, vector()); return; } else @@ -453,7 +471,8 @@ event Management::Agent::API::node_dispatch_request(reqid: string, action: vecto Management::Log::info(fmt( "tx Management::Agent::API::node_dispatch_response %s, no nodes running", reqid)); - event Management::Agent::API::node_dispatch_response(reqid, req$results); + Broker::publish(agent_topic(), + Management::Agent::API::node_dispatch_response, reqid, req$results); Management::Request::finish(req$id); return; } @@ -478,8 +497,9 @@ event Management::Agent::API::agent_welcome_request(reqid: string) $instance = Management::Agent::name); Management::Log::info(fmt("tx Management::Agent::API::agent_welcome_response %s", - Management::result_to_string(res))); - event Management::Agent::API::agent_welcome_response(reqid, res); + Management::result_to_string(res))); + Broker::publish(agent_topic(), + Management::Agent::API::agent_welcome_response, reqid, res); } event Management::Agent::API::agent_standby_request(reqid: string) @@ -498,8 +518,9 @@ event Management::Agent::API::agent_standby_request(reqid: string) $instance = Management::Agent::name); Management::Log::info(fmt("tx Management::Agent::API::agent_standby_response %s", - Management::result_to_string(res))); - event Management::Agent::API::agent_standby_response(reqid, res); + Management::result_to_string(res))); + Broker::publish(agent_topic(), + Management::Agent::API::agent_standby_response, reqid, res); } event Management::Node::API::notify_node_hello(node: string) @@ -518,8 +539,10 @@ event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) local epi = Management::Agent::endpoint_info(); - event Management::Agent::API::notify_agent_hello(epi$id, - to_addr(epi$network$address), Management::Agent::API::version); + Broker::publish(agent_topic(), + Management::Agent::API::notify_agent_hello, + epi$id, to_addr(epi$network$address), + Management::Agent::API::version); } # XXX We may want a request timeout event handler here. It's arguably cleaner to @@ -529,7 +552,6 @@ event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) event zeek_init() { local epi = Management::Agent::endpoint_info(); - local agent_topic = Management::Agent::topic_prefix + "/" + epi$id; # The agent needs to peer with the supervisor -- this doesn't currently # happen automatically. The address defaults to Broker's default, which @@ -543,45 +565,17 @@ event zeek_init() # Agents need receive communication targeted at it, any responses # from the supervisor, and any responses from cluster nodes. - Broker::subscribe(agent_topic); + Broker::subscribe(agent_topic()); Broker::subscribe(SupervisorControl::topic_prefix); Broker::subscribe(Management::Node::node_topic); - # Auto-publish a bunch of events. Glob patterns or module-level - # auto-publish would be helpful here. - local agent_to_controller_events: vector of any = [ - Management::Agent::API::get_nodes_response, - Management::Agent::API::set_configuration_response, - Management::Agent::API::agent_welcome_response, - Management::Agent::API::agent_standby_response, - Management::Agent::API::node_dispatch_response, - Management::Agent::API::notify_agent_hello, - Management::Agent::API::notify_change, - Management::Agent::API::notify_error, - Management::Agent::API::notify_log - ]; - - for ( i in agent_to_controller_events ) - Broker::auto_publish(agent_topic, agent_to_controller_events[i]); - - local agent_to_sup_events: vector of any = [ - SupervisorControl::create_request, - SupervisorControl::status_request, - SupervisorControl::destroy_request, - SupervisorControl::restart_request, - SupervisorControl::stop_request - ]; - - for ( i in agent_to_sup_events ) - Broker::auto_publish(SupervisorControl::topic_prefix, agent_to_sup_events[i]); - # Establish connectivity with the controller. if ( Management::Agent::controller$address != "0.0.0.0" ) { # We connect to the controller. Broker::peer(Management::Agent::controller$address, - Management::Agent::controller$bound_port, - Management::connect_retry); + Management::Agent::controller$bound_port, + Management::connect_retry); } # The agent always listens, to allow cluster nodes to peer with it. diff --git a/scripts/policy/frameworks/management/controller/api.zeek b/scripts/policy/frameworks/management/controller/api.zeek index 0ce3259a4c..ad9b22cc26 100644 --- a/scripts/policy/frameworks/management/controller/api.zeek +++ b/scripts/policy/frameworks/management/controller/api.zeek @@ -135,7 +135,7 @@ export { result: Management::Result); - # Notification events, agent -> controller + # Notification events ## The controller triggers this event when the operational cluster ## instances align with the ones desired by the cluster diff --git a/scripts/policy/frameworks/management/controller/main.zeek b/scripts/policy/frameworks/management/controller/main.zeek index 441e03517c..72ecf2be30 100644 --- a/scripts/policy/frameworks/management/controller/main.zeek +++ b/scripts/policy/frameworks/management/controller/main.zeek @@ -113,8 +113,7 @@ global g_config_reqid_pending: string = ""; # the one we send whenever the client requests it. global g_config_current: Management::Configuration; -function send_config_to_agents(req: Management::Request::Request, - config: Management::Configuration) +function send_config_to_agents(req: Management::Request::Request, config: Management::Configuration) { for ( name in g_instances ) { @@ -156,7 +155,7 @@ function add_instance(inst: Management::Instance) if ( inst?$listen_port ) Broker::peer(cat(inst$host), inst$listen_port, - Management::connect_retry); + Management::connect_retry); if ( inst$name in g_instances_known ) { @@ -169,7 +168,7 @@ function add_instance(inst: Management::Instance) Management::Log::info(fmt("tx Management::Agent::API::agent_welcome_request to %s", inst$name)); Broker::publish(Management::Agent::topic_prefix + "/" + inst$name, - Management::Agent::API::agent_welcome_request, req$id); + Management::Agent::API::agent_welcome_request, req$id); } } @@ -181,7 +180,7 @@ function drop_instance(inst: Management::Instance) # Send the agent a standby so it shuts down its cluster nodes & state Management::Log::info(fmt("tx Management::Agent::API::agent_standby_request to %s", inst$name)); Broker::publish(Management::Agent::topic_prefix + "/" + inst$name, - Management::Agent::API::agent_standby_request, ""); + Management::Agent::API::agent_standby_request, ""); delete g_instances[inst$name]; @@ -292,7 +291,7 @@ event Management::Agent::API::notify_agent_hello(instance: string, host: addr, a Management::Log::info(fmt("tx Management::Agent::API::agent_welcome_request to %s", instance)); Broker::publish(Management::Agent::topic_prefix + "/" + instance, - Management::Agent::API::agent_welcome_request, req$id); + Management::Agent::API::agent_welcome_request, req$id); } } @@ -315,7 +314,7 @@ event Management::Agent::API::agent_welcome_response(reqid: string, result: Mana Management::Log::info(fmt( "tx Management::Agent::API::agent_standby_request to %s", result$instance)); Broker::publish(Management::Agent::topic_prefix + "/" + result$instance, - Management::Agent::API::agent_standby_request, ""); + Management::Agent::API::agent_standby_request, ""); return; } @@ -326,8 +325,7 @@ event Management::Agent::API::agent_welcome_response(reqid: string, result: Mana } event Management::Agent::API::notify_change(instance: string, n: Management::Node, - old: Management::State, - new: Management::State) + old: Management::State, new: Management::State) { # XXX TODO } @@ -379,8 +377,9 @@ event Management::Agent::API::set_configuration_response(reqid: string, result: g_config_reqid_pending = ""; Management::Log::info(fmt("tx Management::Controller::API::set_configuration_response %s", - Management::Request::to_string(req))); - event Management::Controller::API::set_configuration_response(req$id, req$results); + Management::Request::to_string(req))); + Broker::publish(Management::Controller::topic, + Management::Controller::API::set_configuration_response, req$id, req$results); Management::Request::finish(req$id); } @@ -402,8 +401,9 @@ event Management::Controller::API::set_configuration_request(reqid: string, conf req$results += res; Management::Log::info(fmt("tx Management::Controller::API::set_configuration_response %s", - Management::Request::to_string(req))); - event Management::Controller::API::set_configuration_response(req$id, req$results); + Management::Request::to_string(req))); + Broker::publish(Management::Controller::topic, + Management::Controller::API::set_configuration_response, req$id, req$results); Management::Request::finish(req$id); return; } @@ -508,7 +508,8 @@ event Management::Controller::API::get_instances_request(reqid: string) res$data = insts; Management::Log::info(fmt("tx Management::Controller::API::get_instances_response %s", reqid)); - event Management::Controller::API::get_instances_response(reqid, res); + Broker::publish(Management::Controller::topic, + Management::Controller::API::get_instances_response, reqid, res); } event Management::Agent::API::get_nodes_response(reqid: string, result: Management::Result) @@ -551,8 +552,9 @@ event Management::Agent::API::get_nodes_response(reqid: string, result: Manageme return; Management::Log::info(fmt("tx Management::Controller::API::get_nodes_response %s", - Management::Request::to_string(req))); - event Management::Controller::API::get_nodes_response(req$id, req$results); + Management::Request::to_string(req))); + Broker::publish(Management::Controller::topic, + Management::Controller::API::get_nodes_response, req$id, req$results); Management::Request::finish(req$id); } @@ -564,9 +566,10 @@ event Management::Controller::API::get_nodes_request(reqid: string) if ( |g_instances| == 0 ) { Management::Log::info(fmt("tx Management::Controller::API::get_nodes_response %s", reqid)); - event Management::Controller::API::get_nodes_response(reqid, vector( - Management::Result($reqid=reqid, $success=F, - $error="no instances connected"))); + local res = Management::Result($reqid=reqid, $success=F, + $error="no instances connected"); + Broker::publish(Management::Controller::topic, + Management::Controller::API::get_nodes_response, reqid, vector(res)); return; } @@ -643,7 +646,9 @@ event Management::Agent::API::node_dispatch_response(reqid: string, results: Man Management::Log::info(fmt( "tx Management::Controller::API::get_id_value_response %s", Management::Request::to_string(req))); - event Management::Controller::API::get_id_value_response(req$id, req$results); + Broker::publish(Management::Controller::topic, + Management::Controller::API::get_id_value_response, + req$id, req$results); break; default: Management::Log::error(fmt("unexpected dispatch command %s", @@ -658,12 +663,16 @@ event Management::Controller::API::get_id_value_request(reqid: string, id: strin { Management::Log::info(fmt("rx Management::Controller::API::get_id_value_request %s %s", reqid, id)); + local res: Management::Result; + # Special case: if we have no instances, respond right away. if ( |g_instances| == 0 ) { Management::Log::info(fmt("tx Management::Controller::API::get_id_value_response %s", reqid)); - event Management::Controller::API::get_id_value_response(reqid, vector( - Management::Result($reqid=reqid, $success=F, $error="no instances connected"))); + res = Management::Result($reqid=reqid, $success=F, $error="no instances connected"); + Broker::publish(Management::Controller::topic, + Management::Controller::API::get_id_value_response, + reqid, vector(res)); return; } @@ -673,7 +682,6 @@ event Management::Controller::API::get_id_value_request(reqid: string, id: strin local nodes_final: set[string]; local node: string; - local res: Management::Result; # Input sanitization: check for any requested nodes that aren't part of # the current configuration. We send back error results for those and @@ -700,7 +708,9 @@ event Management::Controller::API::get_id_value_request(reqid: string, id: strin Management::Log::info(fmt( "tx Management::Controller::API::get_id_value_response %s", Management::Request::to_string(req))); - event Management::Controller::API::get_id_value_response(req$id, req$results); + Broker::publish(Management::Controller::topic, + Management::Controller::API::get_id_value_response, + req$id, req$results); Management::Request::finish(req$id); return; } @@ -745,8 +755,9 @@ event Management::Request::request_expired(req: Management::Request::Request) req$results += res; Management::Log::info(fmt("tx Management::Controller::API::set_configuration_response %s", - Management::Request::to_string(req))); - event Management::Controller::API::set_configuration_response(req$id, req$results); + Management::Request::to_string(req))); + Broker::publish(Management::Controller::topic, + Management::Controller::API::set_configuration_response, req$id, req$results); } if ( req?$get_nodes_state ) @@ -754,8 +765,9 @@ event Management::Request::request_expired(req: Management::Request::Request) req$results += res; Management::Log::info(fmt("tx Management::Controller::API::get_nodes_response %s", - Management::Request::to_string(req))); - event Management::Controller::API::get_nodes_response(req$id, req$results); + Management::Request::to_string(req))); + Broker::publish(Management::Controller::topic, + Management::Controller::API::get_nodes_response, req$id, req$results); } if ( req?$node_dispatch_state ) @@ -768,7 +780,9 @@ event Management::Request::request_expired(req: Management::Request::Request) Management::Log::info(fmt( "tx Management::Controller::API::get_id_value_response %s", Management::Request::to_string(req))); - event Management::Controller::API::get_id_value_response(req$id, req$results); + Broker::publish(Management::Controller::topic, + Management::Controller::API::get_id_value_response, + req$id, req$results); break; default: Management::Log::error(fmt("unexpected dispatch command %s", @@ -780,7 +794,8 @@ event Management::Request::request_expired(req: Management::Request::Request) if ( req?$test_state ) { Management::Log::info(fmt("tx Management::Controller::API::test_timeout_response %s", req$id)); - event Management::Controller::API::test_timeout_response(req$id, res); + Broker::publish(Management::Controller::topic, + Management::Controller::API::test_timeout_response, req$id, res); } } @@ -817,17 +832,5 @@ event zeek_init() Broker::subscribe(Management::Agent::topic_prefix); Broker::subscribe(Management::Controller::topic); - # Events sent to the client: - local events: vector of any = [ - Management::Controller::API::get_instances_response, - Management::Controller::API::set_configuration_response, - Management::Controller::API::get_nodes_response, - Management::Controller::API::get_id_value_response, - Management::Controller::API::test_timeout_response - ]; - - for ( i in events ) - Broker::auto_publish(Management::Controller::topic, events[i]); - Management::Log::info("controller is live"); } diff --git a/scripts/policy/frameworks/management/node/main.zeek b/scripts/policy/frameworks/management/node/main.zeek index cd9819ff3d..52aa5f1e96 100644 --- a/scripts/policy/frameworks/management/node/main.zeek +++ b/scripts/policy/frameworks/management/node/main.zeek @@ -51,8 +51,7 @@ global g_dispatch_table: table[string] of DispatchCallback = { ["get_id_value"] = dispatch_get_id_value, }; -event Management::Node::API::node_dispatch_request(reqid: string, action: vector of string, - nodes: set[string]) +event Management::Node::API::node_dispatch_request(reqid: string, action: vector of string, nodes: set[string]) { Management::Log::info(fmt("rx Management::Node::API::node_dispatch_request %s %s %s", reqid, action, nodes)); @@ -64,8 +63,7 @@ event Management::Node::API::node_dispatch_request(reqid: string, action: vector return; } - local res = Management::Result( - $reqid = reqid, $node = Cluster::node); + local res = Management::Result($reqid = reqid, $node = Cluster::node); if ( |action| == 0 ) { @@ -82,15 +80,15 @@ event Management::Node::API::node_dispatch_request(reqid: string, action: vector { Management::Log::info(fmt("tx Management::Node::API::node_dispatch_response %s", Management::result_to_string(res))); - event Management::Node::API::node_dispatch_response(reqid, res); + Broker::publish(node_topic, Management::Node::API::node_dispatch_response, reqid, res); return; } g_dispatch_table[action[0]](action[1:], res); Management::Log::info(fmt("tx Management::Node::API::node_dispatch_response %s", - Management::result_to_string(res))); - event Management::Node::API::node_dispatch_response(reqid, res); + Management::result_to_string(res))); + Broker::publish(node_topic, Management::Node::API::node_dispatch_response, reqid, res); } event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) @@ -100,7 +98,7 @@ event Broker::peer_added(peer: Broker::EndpointInfo, msg: string) # If this is the agent peering, notify it that we're ready if ( peer$network$address == epi$network$address && peer$network$bound_port == epi$network$bound_port ) - event Management::Node::API::notify_node_hello(Cluster::node); + Broker::publish(node_topic, Management::Node::API::notify_node_hello, Cluster::node); } event zeek_init() @@ -109,13 +107,4 @@ event zeek_init() Broker::peer(epi$network$address, epi$network$bound_port, Management::connect_retry); Broker::subscribe(node_topic); - - # Events automatically sent to the Management agent. - local events: vector of any = [ - Management::Node::API::node_dispatch_response, - Management::Node::API::notify_node_hello - ]; - - for ( i in events ) - Broker::auto_publish(node_topic, events[i]); } From 75d07c021e5bc1defa965aaa6284c5dc922a36d8 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sat, 23 Apr 2022 21:24:14 -0700 Subject: [PATCH 189/204] Remove obsolete DNS_Mgr::asyncs_timeouts --- src/DNS_Mgr.cc | 3 +-- src/DNS_Mgr.h | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 02dd4f217f..9b781bde8e 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -1307,7 +1307,6 @@ void DNS_Mgr::IssueAsyncRequests() dns_req->MakeRequest(channel, this); - asyncs_timeouts.push(req); ++asyncs_pending; } } @@ -1401,7 +1400,7 @@ void DNS_Mgr::Flush() double DNS_Mgr::GetNextTimeout() { - if ( asyncs_timeouts.empty() ) + if ( asyncs_pending == 0 ) return -1; return run_state::network_time + DNS_TIMEOUT; diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index 9834f68a09..2f258dfa1d 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -331,10 +331,6 @@ protected: using QueuedList = std::list; QueuedList asyncs_queued; - using TimeoutQueue = - std::priority_queue, AsyncRequestCompare>; - TimeoutQueue asyncs_timeouts; - unsigned long num_requests = 0; unsigned long successful = 0; unsigned long failed = 0; From 6e74ffd9b0c8336ac154181a72a369fe073e93ab Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sat, 23 Apr 2022 21:39:37 -0700 Subject: [PATCH 190/204] Ask c-ares for the next timeout instead of passing a fixed value --- src/DNS_Mgr.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 9b781bde8e..78045042bc 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -1403,7 +1403,21 @@ double DNS_Mgr::GetNextTimeout() if ( asyncs_pending == 0 ) return -1; - return run_state::network_time + DNS_TIMEOUT; + fd_set read_fds, write_fds; + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + int nfds = ares_fds(channel, &read_fds, &write_fds); + if ( nfds == 0 ) + return -1; + + struct timeval tv; + tv.tv_sec = DNS_TIMEOUT; + tv.tv_usec = 0; + + struct timeval* tvp = ares_timeout(channel, &tv, &tv); + + return run_state::network_time + static_cast(tvp->tv_sec) + (static_cast(tvp->tv_usec) / 1e6); } void DNS_Mgr::ProcessFd(int fd, int flags) From 6f2bedaa56238ec957353676b5e87e8b7e194ed6 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 25 Apr 2022 15:54:28 -0700 Subject: [PATCH 191/204] Pre-initialize c-ares channel object. Fixes Coverity 1488318 --- src/DNS_Mgr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index 2f258dfa1d..2adfc3ac01 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -297,7 +297,7 @@ protected: RecordTypePtr dm_rec; - ares_channel channel; + ares_channel channel{}; using CallbackList = std::list; From 84ea0861673f99287de7d444a85fd527bebc62da Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 25 Apr 2022 15:59:35 -0700 Subject: [PATCH 192/204] Wrap call to doctest's MESSAGE() method in Reporter in try/catch block Also check whether doctest is even enabled before trying to use it. --- src/Reporter.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Reporter.cc b/src/Reporter.cc index 945041b881..0ed84562e7 100644 --- a/src/Reporter.cc +++ b/src/Reporter.cc @@ -678,13 +678,28 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Conne s += buffer; +#ifdef ENABLE_ZEEK_UNIT_TESTS if ( doctest::is_running_in_test ) - MESSAGE(s); + { + try + { + MESSAGE(s); + } + catch ( const doctest::detail::TestFailureException& e ) + { + // If doctest throws an exception, just write the string out to stdout + // like normal, just so it's captured somewhere. + fprintf(out, "%s\n", s.c_str()); + } + } else { +#endif s += "\n"; fprintf(out, "%s", s.c_str()); +#ifdef ENABLE_ZEEK_UNIT_TESTS } +#endif } if ( alloced ) From cc9a166c8b70f22e0ce093356783a4eb0ce0d500 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 27 Apr 2022 17:44:34 +0000 Subject: [PATCH 193/204] Fix minor formatting bug that pre-commit missed --- src/DNS_Mgr.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 78045042bc..4d09a19945 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -1417,7 +1417,8 @@ double DNS_Mgr::GetNextTimeout() struct timeval* tvp = ares_timeout(channel, &tv, &tv); - return run_state::network_time + static_cast(tvp->tv_sec) + (static_cast(tvp->tv_usec) / 1e6); + return run_state::network_time + static_cast(tvp->tv_sec) + + (static_cast(tvp->tv_usec) / 1e6); } void DNS_Mgr::ProcessFd(int fd, int flags) From 4ea1a593a92a891003fc941bd7f2aab978fb5553 Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Fri, 4 Sep 2020 09:31:58 +0200 Subject: [PATCH 194/204] Port Zeek to latest Broker API --- auxil/broker | 2 +- src/broker/Manager.cc | 17 ++++++---- src/broker/Manager.h | 4 --- src/broker/Store.h | 2 +- src/broker/comm.bif | 6 ++++ src/broker/store.bif | 11 +++++++ testing/benchmark/broker/node.zeek | 33 +++++++++++++++++++ testing/benchmark/broker/sender.zeek | 28 ++++++++++++++++ testing/benchmark/broker/server.zeek | 33 +++++++++++++++++++ .../Baseline/broker.disconnect/recv.recv.out | 1 + .../broker.disconnect/recv2.recv2.out | 1 + .../Baseline/broker.disconnect/send.send.out | 4 +++ testing/btest/Baseline/broker.error/send.out | 2 +- .../broker.ssl_auth_failure/send.send.out | 2 +- testing/btest/broker/connect-on-retry.zeek | 2 ++ testing/btest/broker/disconnect.zeek | 32 +++++++++++++++--- testing/btest/broker/error.zeek | 4 ++- testing/btest/broker/opaque.zeek | 2 ++ testing/btest/broker/remote_event.zeek | 2 ++ testing/btest/broker/remote_event_any.zeek | 2 ++ testing/btest/broker/remote_event_auto.zeek | 2 ++ .../btest/broker/remote_event_ssl_auth.zeek | 2 ++ .../btest/broker/remote_event_vector_any.zeek | 2 ++ testing/btest/broker/remote_id.zeek | 2 ++ testing/btest/broker/remote_log.zeek | 2 ++ testing/btest/broker/remote_log_batch.zeek | 2 ++ .../btest/broker/remote_log_late_join.zeek | 2 ++ testing/btest/broker/remote_log_types.zeek | 2 ++ testing/btest/broker/ssl-mismatch.zeek | 2 ++ testing/btest/broker/ssl_auth_failure.zeek | 2 ++ .../brokerstore-backend-simple-reverse.zeek | 10 +++++- .../store/brokerstore-backend-sqlite.zeek | 7 +++- testing/btest/broker/unpeer.zeek | 4 ++- 33 files changed, 208 insertions(+), 23 deletions(-) create mode 100644 testing/benchmark/broker/node.zeek create mode 100644 testing/benchmark/broker/sender.zeek create mode 100644 testing/benchmark/broker/server.zeek diff --git a/auxil/broker b/auxil/broker index 8493e1734c..cfb97d3388 160000 --- a/auxil/broker +++ b/auxil/broker @@ -1 +1 @@ -Subproject commit 8493e1734c639ea9b3c66547ba26ebea972e102b +Subproject commit cfb97d338834af1f5c6f9e13ade8a1c5141ae062 diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index 20ba72f28e..d9e00b2291 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -275,7 +275,7 @@ void Manager::InitPostScript() broker::broker_options options; options.disable_ssl = get_option("Broker::disable_ssl")->AsBool(); - options.forward = get_option("Broker::forward_messages")->AsBool(); + options.disable_forwarding = !get_option("Broker::forward_messages")->AsBool(); options.use_real_time = use_real_time; broker::configuration config{std::move(options)}; @@ -474,10 +474,6 @@ void Manager::Terminate() CloseStore(x); FlushLogBuffers(); - - for ( auto& p : bstate->endpoint.peers() ) - if ( p.peer.network ) - bstate->endpoint.unpeer(p.peer.network->address, p.peer.network->port); } bool Manager::Active() @@ -554,7 +550,8 @@ void Manager::Peer(const string& addr, uint16_t port, double retry) if ( bstate->endpoint.is_shutdown() ) return; - DBG_LOG(DBG_BROKER, "Starting to peer with %s:%" PRIu16, addr.c_str(), port); + DBG_LOG(DBG_BROKER, "Starting to peer with %s:%" PRIu16 " (retry: %fs)", + addr.c_str(), port, retry); auto e = getenv("ZEEK_DEFAULT_CONNECT_RETRY"); @@ -1657,6 +1654,14 @@ void Manager::ProcessStatus(broker::status_view stat) event = ::Broker::peer_lost; break; + case broker::sc::endpoint_discovered: + event = ::Broker::endpoint_discovered; + break; + + case broker::sc::endpoint_unreachable: + event = ::Broker::endpoint_unreachable; + break; + default: reporter->Warning("Unhandled Broker status: %s", to_string(stat).data()); break; diff --git a/src/broker/Manager.h b/src/broker/Manager.h index 4649a668ef..8e03474c41 100644 --- a/src/broker/Manager.h +++ b/src/broker/Manager.h @@ -8,10 +8,6 @@ #include #include #include -#include -#include -#include -#include #include #include #include diff --git a/src/broker/Store.h b/src/broker/Store.h index 70cba682b6..10ebad95e5 100644 --- a/src/broker/Store.h +++ b/src/broker/Store.h @@ -122,7 +122,7 @@ public: broker::store store; broker::store::proxy proxy; - broker::publisher_id store_pid; + broker::entity_id store_pid; // Zeek table that events are forwarded to. TableValPtr forward_to; bool have_store = false; diff --git a/src/broker/comm.bif b/src/broker/comm.bif index 2b6d4be802..e4552d84f5 100644 --- a/src/broker/comm.bif +++ b/src/broker/comm.bif @@ -19,6 +19,12 @@ event Broker::peer_removed%(endpoint: EndpointInfo, msg: string%); ## Generated when an existing peering has been lost. event Broker::peer_lost%(endpoint: EndpointInfo, msg: string%); +## Generated when a new Broker endpoint appeared. +event Broker::endpoint_discovered%(endpoint: EndpointInfo, msg: string%); + +## Generated when the last path to a Broker endpoint has been lost. +event Broker::endpoint_unreachable%(endpoint: EndpointInfo, msg: string%); + ## Generated when an error occurs in the Broker sub-system. event Broker::error%(code: ErrorCode, msg: string%); diff --git a/src/broker/store.bif b/src/broker/store.bif index 87f614f373..d29a44191d 100644 --- a/src/broker/store.bif +++ b/src/broker/store.bif @@ -100,6 +100,11 @@ function Broker::__close%(h: opaque of Broker::Store%): bool return val_mgr->False(); } + if ( ! handle->have_store ) + { + return val_mgr->False(); + } + return zeek::val_mgr->Bool(broker_mgr->CloseStore(handle->store.name())); %} @@ -325,6 +330,12 @@ function Broker::__keys%(h: opaque of Broker::Store%): Broker::QueryResult return zeek::Broker::detail::query_result(); } + if ( ! handle->have_store ) + { + zeek::emit_builtin_error("cannot retrieve keys from a closed store", h); + return zeek::Broker::detail::query_result(); + } + auto trigger = frame->GetTrigger(); if ( ! trigger ) diff --git a/testing/benchmark/broker/node.zeek b/testing/benchmark/broker/node.zeek new file mode 100644 index 0000000000..14c7afd34a --- /dev/null +++ b/testing/benchmark/broker/node.zeek @@ -0,0 +1,33 @@ +redef exit_only_after_terminate = T; + +global event_count = 0; + +global event_1: event(val: count); + +event event_1(value: count) + { + ++event_count; + } + +event bye_bye() + { + print "received bye-bye event"; + terminate(); + } + +event print_stats() + { + print "received ", event_count, " events/s"; + event_count = 0; + schedule 1sec { print_stats() }; + } + +event zeek_init() + { + local broker_port = to_port(getenv("BROKER_PORT")); + print "trying to connect to port ", broker_port; + Broker::subscribe("benchmark/terminate"); + Broker::subscribe("benchmark/events"); + Broker::peer("127.0.0.1", broker_port); + schedule 1sec { print_stats() }; + } diff --git a/testing/benchmark/broker/sender.zeek b/testing/benchmark/broker/sender.zeek new file mode 100644 index 0000000000..da020e69e6 --- /dev/null +++ b/testing/benchmark/broker/sender.zeek @@ -0,0 +1,28 @@ +redef exit_only_after_terminate = T; + +global value = 0; + +global event_1: event(val: count); + +event bye_bye() + { + print "received bye-bye event"; + terminate(); + } + +event publish_next() + { + Broker::publish("benchmark/events", event_1, value); + ++value; + schedule 1msec { publish_next() }; + } + +event zeek_init() + { + local broker_port = to_port(getenv("BROKER_PORT")); + print fmt("trying to connect to port %s", broker_port); + Broker::subscribe("benchmark/terminate"); + Broker::peer("127.0.0.1", broker_port); + schedule 250usec { publish_next() }; + } + diff --git a/testing/benchmark/broker/server.zeek b/testing/benchmark/broker/server.zeek new file mode 100644 index 0000000000..d85e7e754f --- /dev/null +++ b/testing/benchmark/broker/server.zeek @@ -0,0 +1,33 @@ +redef exit_only_after_terminate = T; + +global event_count = 0; + +global event_1: event(val: count); + +event event_1(value: count) + { + ++event_count; + } + +event bye_bye() + { + print "received bye-bye event"; + terminate(); + } + +event print_stats() + { + print "received ", event_count, " events/s"; + event_count = 0; + schedule 1sec { print_stats() }; + } + +event zeek_init() + { + local broker_port = to_port(getenv("BROKER_PORT")); + Broker::subscribe("benchmark/terminate"); + Broker::subscribe("benchmark/events"); + Broker::listen("127.0.0.1", broker_port); + print fmt("listening on port %d", broker_port); + schedule 1sec { print_stats() }; + } diff --git a/testing/btest/Baseline/broker.disconnect/recv.recv.out b/testing/btest/Baseline/broker.disconnect/recv.recv.out index c512d83470..73c3301683 100644 --- a/testing/btest/Baseline/broker.disconnect/recv.recv.out +++ b/testing/btest/Baseline/broker.disconnect/recv.recv.out @@ -1,3 +1,4 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +endpoint discovered, found a new peer in the network peer added, handshake successful receiver got event, 1 diff --git a/testing/btest/Baseline/broker.disconnect/recv2.recv2.out b/testing/btest/Baseline/broker.disconnect/recv2.recv2.out index 335187e4b6..6091d6a0e4 100644 --- a/testing/btest/Baseline/broker.disconnect/recv2.recv2.out +++ b/testing/btest/Baseline/broker.disconnect/recv2.recv2.out @@ -1,3 +1,4 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +endpoint discovered, found a new peer in the network peer added, handshake successful receiver got event, 2 diff --git a/testing/btest/Baseline/broker.disconnect/send.send.out b/testing/btest/Baseline/broker.disconnect/send.send.out index 95f77841f4..ce37aaa5a1 100644 --- a/testing/btest/Baseline/broker.disconnect/send.send.out +++ b/testing/btest/Baseline/broker.disconnect/send.send.out @@ -1,5 +1,9 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +endpoint discovered, found a new peer in the network peer added, handshake successful peer lost, lost connection to remote peer +endpoint unreachable, lost the last path +endpoint discovered, found a new peer in the network peer added, handshake successful peer lost, lost connection to remote peer +endpoint unreachable, lost the last path diff --git a/testing/btest/Baseline/broker.error/send.out b/testing/btest/Baseline/broker.error/send.out index da3c12e129..33955b2d4a 100644 --- a/testing/btest/Baseline/broker.error/send.out +++ b/testing/btest/Baseline/broker.error/send.out @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error, Broker::PEER_INVALID, (invalid-node, *1.2.3.4:1947, "cannot unpeer from unknown peer") +error, Broker::PEER_INVALID, (00000000-0000-0000-0000-000000000000, *1.2.3.4:1947, "cannot unpeer from unknown peer") diff --git a/testing/btest/Baseline/broker.ssl_auth_failure/send.send.out b/testing/btest/Baseline/broker.ssl_auth_failure/send.send.out index 861f3823e9..0085e61336 100644 --- a/testing/btest/Baseline/broker.ssl_auth_failure/send.send.out +++ b/testing/btest/Baseline/broker.ssl_auth_failure/send.send.out @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -sender error: code=Broker::PEER_UNAVAILABLE msg=(invalid-node, *, "unable to connect to remote peer") +sender error: code=Broker::PEER_UNAVAILABLE msg=(00000000-0000-0000-0000-000000000000, *, "unable to connect to remote peer") diff --git a/testing/btest/broker/connect-on-retry.zeek b/testing/btest/broker/connect-on-retry.zeek index 42ecd21c4d..7fe700a2cb 100644 --- a/testing/btest/broker/connect-on-retry.zeek +++ b/testing/btest/broker/connect-on-retry.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/disconnect.zeek b/testing/btest/broker/disconnect.zeek index f44fad143b..701172eeb6 100644 --- a/testing/btest/broker/disconnect.zeek +++ b/testing/btest/broker/disconnect.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" @@ -7,7 +9,7 @@ # @TEST-EXEC: btest-bg-run recv2 "zeek -b ../recv.zeek >recv2.out" # @TEST-EXEC: btest-bg-wait 45 - +# # @TEST-EXEC: btest-diff send/send.out # @TEST-EXEC: btest-diff recv/recv.out # @TEST-EXEC: btest-diff recv2/recv2.out @@ -33,10 +35,6 @@ event zeek_init() event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string) { print "peer lost", msg; - system("touch lost"); - - if ( peers == 2 ) - terminate(); } event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string) @@ -46,6 +44,20 @@ event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string) Broker::publish(test_topic, my_event, peers); } +event Broker::endpoint_discovered(endpoint: Broker::EndpointInfo, msg: string) + { + print "endpoint discovered", msg; + } + +event Broker::endpoint_unreachable(endpoint: Broker::EndpointInfo, msg: string) + { + print "endpoint unreachable", msg; + system("touch lost"); + + if ( peers == 2 ) + terminate(); + } + @TEST-END-FILE @@ -77,4 +89,14 @@ event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string) print "peer added", msg; } +event Broker::endpoint_discovered(endpoint: Broker::EndpointInfo, msg: string) + { + print "endpoint discovered", msg; + } + +event Broker::endpoint_unreachable(endpoint: Broker::EndpointInfo, msg: string) + { + print "endpoint unreachable", msg; + } + @TEST-END-FILE diff --git a/testing/btest/broker/error.zeek b/testing/btest/broker/error.zeek index 4a7887707e..c2686274b7 100644 --- a/testing/btest/broker/error.zeek +++ b/testing/btest/broker/error.zeek @@ -1,6 +1,8 @@ +# @TEST-GROUP: broker +# # @TEST-EXEC: zeek -b send.zeek >send.out # @TEST-EXEC: btest-diff send.out -# +# @TEST-START-FILE send.zeek diff --git a/testing/btest/broker/opaque.zeek b/testing/btest/broker/opaque.zeek index 41823a59ed..374ab7dce5 100644 --- a/testing/btest/broker/opaque.zeek +++ b/testing/btest/broker/opaque.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-EXEC: zeek -b %INPUT >out # @TEST-EXEC: btest-diff out # @TEST-EXEC: btest-diff .stderr diff --git a/testing/btest/broker/remote_event.zeek b/testing/btest/broker/remote_event.zeek index e863af5523..ddc4092841 100644 --- a/testing/btest/broker/remote_event.zeek +++ b/testing/btest/broker/remote_event.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_event_any.zeek b/testing/btest/broker/remote_event_any.zeek index 28a5a1abbe..2a290376ca 100644 --- a/testing/btest/broker/remote_event_any.zeek +++ b/testing/btest/broker/remote_event_any.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_event_auto.zeek b/testing/btest/broker/remote_event_auto.zeek index c5497997ac..264f131708 100644 --- a/testing/btest/broker/remote_event_auto.zeek +++ b/testing/btest/broker/remote_event_auto.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_event_ssl_auth.zeek b/testing/btest/broker/remote_event_ssl_auth.zeek index 95ce393e0a..d3882ab2b1 100644 --- a/testing/btest/broker/remote_event_ssl_auth.zeek +++ b/testing/btest/broker/remote_event_ssl_auth.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_event_vector_any.zeek b/testing/btest/broker/remote_event_vector_any.zeek index 628180331d..36bc896a59 100644 --- a/testing/btest/broker/remote_event_vector_any.zeek +++ b/testing/btest/broker/remote_event_vector_any.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_id.zeek b/testing/btest/broker/remote_id.zeek index 35e2416912..c88fa80ac0 100644 --- a/testing/btest/broker/remote_id.zeek +++ b/testing/btest/broker/remote_id.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_log.zeek b/testing/btest/broker/remote_log.zeek index 2f50b0a766..6158e0572a 100644 --- a/testing/btest/broker/remote_log.zeek +++ b/testing/btest/broker/remote_log.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_log_batch.zeek b/testing/btest/broker/remote_log_batch.zeek index b378deb56b..898968bceb 100644 --- a/testing/btest/broker/remote_log_batch.zeek +++ b/testing/btest/broker/remote_log_batch.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_log_late_join.zeek b/testing/btest/broker/remote_log_late_join.zeek index 7e69bdd496..271c77f71a 100644 --- a/testing/btest/broker/remote_log_late_join.zeek +++ b/testing/btest/broker/remote_log_late_join.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/remote_log_types.zeek b/testing/btest/broker/remote_log_types.zeek index a14a12586d..e1ff5f304c 100644 --- a/testing/btest/broker/remote_log_types.zeek +++ b/testing/btest/broker/remote_log_types.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/ssl-mismatch.zeek b/testing/btest/broker/ssl-mismatch.zeek index 60ab15462a..d013b2b978 100644 --- a/testing/btest/broker/ssl-mismatch.zeek +++ b/testing/btest/broker/ssl-mismatch.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run listen "zeek -b %INPUT connect=F Broker::disable_ssl=T" diff --git a/testing/btest/broker/ssl_auth_failure.zeek b/testing/btest/broker/ssl_auth_failure.zeek index 1dffd27618..86275f0e96 100644 --- a/testing/btest/broker/ssl_auth_failure.zeek +++ b/testing/btest/broker/ssl_auth_failure.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" diff --git a/testing/btest/broker/store/brokerstore-backend-simple-reverse.zeek b/testing/btest/broker/store/brokerstore-backend-simple-reverse.zeek index 611e8f19cd..e435bc6f85 100644 --- a/testing/btest/broker/store/brokerstore-backend-simple-reverse.zeek +++ b/testing/btest/broker/store/brokerstore-backend-simple-reverse.zeek @@ -70,6 +70,9 @@ event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string) @TEST-START-FILE clone.zeek +global has_node_up: bool = F; +global has_announce_masters: bool = F; + event dump_tables() { t["a"] = 5; @@ -95,7 +98,9 @@ event dump_tables() event Cluster::node_up(name: string, id: string) { Reporter::info(fmt("Node Up: %s", name)); - event dump_tables(); + has_node_up = T; + if ( has_announce_masters ) + event dump_tables(); } event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string) @@ -106,6 +111,9 @@ event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string) event Broker::announce_masters(masters: set[string]) { Reporter::info(fmt("Received announce_masters: %s", cat(masters))); + has_announce_masters = T; + if ( has_node_up ) + event dump_tables(); } @TEST-END-FILE diff --git a/testing/btest/broker/store/brokerstore-backend-sqlite.zeek b/testing/btest/broker/store/brokerstore-backend-sqlite.zeek index 39c781a347..042c5bec55 100644 --- a/testing/btest/broker/store/brokerstore-backend-sqlite.zeek +++ b/testing/btest/broker/store/brokerstore-backend-sqlite.zeek @@ -125,7 +125,12 @@ event dump_tables() event check_all_set() { - if ( "whatever" in t && "hi" in s && "b" in r ) + # Note: 'a' gets inserted first into 'r'. However, we may still observe 'r' + # with 'b' but without 'a'. This may happen if the clone completes + # its handshake with the server after 'a' and 'b' are already in 'r'. + # In this case, the master sends a snapshot of its state and the + # insertion events for 'a' and 'b' they may trigger in any order. + if ( "whatever" in t && "hi" in s && "a" in r && "b" in r ) event dump_tables(); else schedule 0.1sec { check_all_set() }; diff --git a/testing/btest/broker/unpeer.zeek b/testing/btest/broker/unpeer.zeek index fd057af241..6cb3cc9a8c 100644 --- a/testing/btest/broker/unpeer.zeek +++ b/testing/btest/broker/unpeer.zeek @@ -1,3 +1,5 @@ +# @TEST-GROUP: broker +# # @TEST-PORT: BROKER_PORT # # @TEST-EXEC: btest-bg-run recv "zeek -b ../recv.zeek >recv.out" @@ -6,7 +8,7 @@ # @TEST-EXEC: btest-bg-wait 45 # @TEST-EXEC: btest-diff recv/recv.out # @TEST-EXEC: btest-diff send/send.out -# +# # @TEST-EXEC: cat recv/broker.log | awk '/Broker::STATUS/ { $5="XXX"; print; }' >recv/broker.filtered.log # @TEST-EXEC: cat send/broker.log | awk '/Broker::STATUS/ { $5="XXX"; print; }' >send/broker.filtered.log # @TEST-EXEC: btest-diff recv/broker.filtered.log From 16b2c9a52a81799a7eb35a69bb3e64dba7c84e27 Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Wed, 20 Apr 2022 20:10:40 +0200 Subject: [PATCH 195/204] Fix formatting --- src/broker/Manager.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index d9e00b2291..b349b55b97 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -275,7 +275,7 @@ void Manager::InitPostScript() broker::broker_options options; options.disable_ssl = get_option("Broker::disable_ssl")->AsBool(); - options.disable_forwarding = !get_option("Broker::forward_messages")->AsBool(); + options.disable_forwarding = ! get_option("Broker::forward_messages")->AsBool(); options.use_real_time = use_real_time; broker::configuration config{std::move(options)}; @@ -550,8 +550,8 @@ void Manager::Peer(const string& addr, uint16_t port, double retry) if ( bstate->endpoint.is_shutdown() ) return; - DBG_LOG(DBG_BROKER, "Starting to peer with %s:%" PRIu16 " (retry: %fs)", - addr.c_str(), port, retry); + DBG_LOG(DBG_BROKER, "Starting to peer with %s:%" PRIu16 " (retry: %fs)", addr.c_str(), port, + retry); auto e = getenv("ZEEK_DEFAULT_CONNECT_RETRY"); From 02608df99cc98fe0a8e72c4477352993e01314f7 Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Thu, 21 Apr 2022 16:39:29 +0200 Subject: [PATCH 196/204] Canonify intel.log in read-file-dist-cluster test --- .../manager-1.intel.log | 9 +++++---- .../base/frameworks/intel/read-file-dist-cluster.zeek | 2 +- testing/scripts/diff-remove-timestamps-and-sort | 5 +++++ 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100755 testing/scripts/diff-remove-timestamps-and-sort diff --git a/testing/btest/Baseline/scripts.base.frameworks.intel.read-file-dist-cluster/manager-1.intel.log b/testing/btest/Baseline/scripts.base.frameworks.intel.read-file-dist-cluster/manager-1.intel.log index 38bd8140a6..2244196074 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.intel.read-file-dist-cluster/manager-1.intel.log +++ b/testing/btest/Baseline/scripts.base.frameworks.intel.read-file-dist-cluster/manager-1.intel.log @@ -1,4 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +### NOTE: This file has been sorted with diff-sort. #separator \x09 #set_separator , #empty_field (empty) @@ -7,8 +8,8 @@ #open XXXX-XX-XX-XX-XX-XX #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p seen.indicator seen.indicator_type seen.where seen.node matched sources fuid file_mime_type file_desc #types time string addr port addr port string enum enum string set[enum] set[string] string string string -XXXXXXXXXX.XXXXXX - - - - - 1.2.3.4 Intel::ADDR Intel::IN_A_TEST worker-1 Intel::ADDR source1 - - - -XXXXXXXXXX.XXXXXX - - - - - e@mail.com Intel::EMAIL Intel::IN_A_TEST worker-1 Intel::EMAIL source1 - - - -XXXXXXXXXX.XXXXXX - - - - - 1.2.3.4 Intel::ADDR Intel::IN_A_TEST worker-2 Intel::ADDR source1 - - - -XXXXXXXXXX.XXXXXX - - - - - e@mail.com Intel::EMAIL Intel::IN_A_TEST worker-2 Intel::EMAIL source1 - - - #close XXXX-XX-XX-XX-XX-XX +XXXXXXXXXX.XXXXXX - - - - - 1.2.3.4 Intel::ADDR Intel::IN_A_TEST worker-1 Intel::ADDR source1 - - - +XXXXXXXXXX.XXXXXX - - - - - 1.2.3.4 Intel::ADDR Intel::IN_A_TEST worker-2 Intel::ADDR source1 - - - +XXXXXXXXXX.XXXXXX - - - - - e@mail.com Intel::EMAIL Intel::IN_A_TEST worker-1 Intel::EMAIL source1 - - - +XXXXXXXXXX.XXXXXX - - - - - e@mail.com Intel::EMAIL Intel::IN_A_TEST worker-2 Intel::EMAIL source1 - - - diff --git a/testing/btest/scripts/base/frameworks/intel/read-file-dist-cluster.zeek b/testing/btest/scripts/base/frameworks/intel/read-file-dist-cluster.zeek index 1346961395..3965214db4 100644 --- a/testing/btest/scripts/base/frameworks/intel/read-file-dist-cluster.zeek +++ b/testing/btest/scripts/base/frameworks/intel/read-file-dist-cluster.zeek @@ -7,7 +7,7 @@ # @TEST-EXEC: btest-bg-run worker-2 ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-2 zeek -b %INPUT # @TEST-EXEC: btest-bg-wait 40 # @TEST-EXEC: btest-diff manager-1/.stdout -# @TEST-EXEC: btest-diff manager-1/intel.log +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-timestamps-and-sort btest-diff manager-1/intel.log # @TEST-EXEC: btest-diff worker-1/.stdout # @TEST-EXEC: btest-diff worker-2/.stdout diff --git a/testing/scripts/diff-remove-timestamps-and-sort b/testing/scripts/diff-remove-timestamps-and-sort new file mode 100755 index 0000000000..f50a63f098 --- /dev/null +++ b/testing/scripts/diff-remove-timestamps-and-sort @@ -0,0 +1,5 @@ +#! /usr/bin/env bash + +scripts=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +$scripts/diff-remove-timestamps | $scripts/diff-sort From bb5d3c682a769b7a9d79798bd426dfc0237d9249 Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Sat, 23 Apr 2022 14:25:18 +0200 Subject: [PATCH 197/204] Avoid double-initialization of OpenSSL --- auxil/broker | 2 +- src/broker/Manager.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/auxil/broker b/auxil/broker index cfb97d3388..59addb4c1f 160000 --- a/auxil/broker +++ b/auxil/broker @@ -1 +1 @@ -Subproject commit cfb97d338834af1f5c6f9e13ade8a1c5141ae062 +Subproject commit 59addb4c1ff916a52dbfd216696ff20c97e1e7e1 diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index b349b55b97..f3c6a64ee3 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -275,6 +275,7 @@ void Manager::InitPostScript() broker::broker_options options; options.disable_ssl = get_option("Broker::disable_ssl")->AsBool(); + options.skip_ssl_init = true; options.disable_forwarding = ! get_option("Broker::forward_messages")->AsBool(); options.use_real_time = use_real_time; From a8196cf4fb4c98654a1866263881f950339bbf07 Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Sun, 24 Apr 2022 11:39:54 +0200 Subject: [PATCH 198/204] Fix formatting --- testing/scripts/diff-remove-timestamps-and-sort | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/scripts/diff-remove-timestamps-and-sort b/testing/scripts/diff-remove-timestamps-and-sort index f50a63f098..9726a8e331 100755 --- a/testing/scripts/diff-remove-timestamps-and-sort +++ b/testing/scripts/diff-remove-timestamps-and-sort @@ -1,5 +1,5 @@ #! /usr/bin/env bash -scripts=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +scripts=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) $scripts/diff-remove-timestamps | $scripts/diff-sort From fa27f896d5addbfab4f6f0688ed87ca072dc8a8f Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Wed, 27 Apr 2022 20:45:07 +0200 Subject: [PATCH 199/204] Increase memory for CI jobs --- .cirrus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index 1d5531501d..bfc053f8db 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -8,7 +8,7 @@ cpus: &CPUS 4 btest_jobs: &BTEST_JOBS 4 btest_retries: &BTEST_RETRIES 2 -memory: &MEMORY 4GB +memory: &MEMORY 8GB config: &CONFIG --build-type=release --disable-broker-tests --prefix=$CIRRUS_WORKING_DIR/install static_config: &STATIC_CONFIG --build-type=release --disable-broker-tests --enable-static-broker --enable-static-binpac --prefix=$CIRRUS_WORKING_DIR/install From 02771168f03fad295621c055b5515ff83c8b0f43 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Thu, 28 Apr 2022 00:44:36 +0000 Subject: [PATCH 200/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 1d16c2a720..3280f9b20f 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 1d16c2a7203306081bd8aa1d31e3bdfaa18d0739 +Subproject commit 3280f9b20f92663ce655c1470976bb997eaf9717 From 8786f5ab1dfcbd8a53f54a817d53d0ef7413abee Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Thu, 28 Apr 2022 08:35:36 +0200 Subject: [PATCH 201/204] Initialize OpenSSL on startup --- src/zeek-setup.cc | 93 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 4ad5f8e3a5..6a5701e20b 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -88,6 +88,88 @@ int perftools_leaks = 0; int perftools_profile = 0; #endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L +namespace + { + +struct CRYPTO_dynlock_value + { + std::mutex mtx; + }; + +std::unique_ptr ssl_mtx_tbl; + +void ssl_lock_fn(int mode, int n, const char*, int) + { + if ( mode & CRYPTO_LOCK ) + ssl_mtx_tbl[static_cast(n)].lock(); + else + ssl_mtx_tbl[static_cast(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); + } + +void do_ssl_deinit() + { + ERR_free_strings(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + } + + } // namespace +#endif + zeek::ValManager* zeek::val_mgr = nullptr; zeek::packet_analysis::Manager* zeek::packet_mgr = nullptr; zeek::analyzer::Manager* zeek::analyzer_mgr = nullptr; @@ -545,12 +627,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) // DEBUG_MSG("HMAC key: %s\n", md5_digest_print(shared_hmac_md5_key)); init_hash_function(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L - ERR_load_crypto_strings(); - OPENSSL_add_all_algorithms_conf(); - SSL_library_init(); - SSL_load_error_strings(); -#endif + do_ssl_init(); // FIXME: On systems that don't provide /dev/urandom, OpenSSL doesn't // seed the PRNG. We should do this here (but at least Linux, FreeBSD @@ -993,9 +1070,7 @@ int cleanup(bool did_run_loop) sqlite3_shutdown(); - ERR_free_strings(); - EVP_cleanup(); - CRYPTO_cleanup_all_ex_data(); + do_ssl_deinit(); // Close files after net_delete(), because net_delete() // might write to connection content files. From 6182acd198f5d8e281ca810b05da15997c3d62fe Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Thu, 28 Apr 2022 19:37:11 +0200 Subject: [PATCH 202/204] Fix build on CentOS 7 --- src/zeek-setup.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 6a5701e20b..7a6b048571 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -89,14 +89,14 @@ int perftools_profile = 0; #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L -namespace - { - struct CRYPTO_dynlock_value { std::mutex mtx; }; +namespace + { + std::unique_ptr ssl_mtx_tbl; void ssl_lock_fn(int mode, int n, const char*, int) @@ -627,7 +627,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) // DEBUG_MSG("HMAC key: %s\n", md5_digest_print(shared_hmac_md5_key)); init_hash_function(); - do_ssl_init(); + do_ssl_init(); // FIXME: On systems that don't provide /dev/urandom, OpenSSL doesn't // seed the PRNG. We should do this here (but at least Linux, FreeBSD @@ -1070,7 +1070,7 @@ int cleanup(bool did_run_loop) sqlite3_shutdown(); - do_ssl_deinit(); + do_ssl_deinit(); // Close files after net_delete(), because net_delete() // might write to connection content files. From 2cde69d9d1ebffb36bb57060035da2b7a056aa6b Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Thu, 28 Apr 2022 14:10:26 -0700 Subject: [PATCH 203/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 3280f9b20f..efaca18171 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 3280f9b20f92663ce655c1470976bb997eaf9717 +Subproject commit efaca18171eb9090e50b32618743139bb26d9908 From aa5a5b2136b3846762359a4a020188c4210aca55 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Fri, 29 Apr 2022 00:39:17 +0000 Subject: [PATCH 204/204] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index efaca18171..a5adc652ed 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit efaca18171eb9090e50b32618743139bb26d9908 +Subproject commit a5adc652ed3c7cf179a19c8b373a9443dd1fc5dc

2^F|Po?KwGIUES}e5E1p+F{c~USV;$}J&h9kfPa%kDS4;yCXHu6Z*_Z=w*d$ZWL~W0O*BEW^Zr<_ppcdP~U0Z09wd~2HWoW?Gns< zDMq{=uW(U$#kh5GLzOS=Pl#Yj_$F+=h?D0c`8k&-$elRDvjRXEV6xWQ3NyBr7@d5m z%zmkRkv#4#&F>EJb=v-7qY~Hp$0PH_M4`uUl42Di84i(Db2q8N+>|bfA90|hRUOIs zjU6l3ZaBNAb8AaOuivh0=U+=N#E_N})4xZ;p<|dw_KIx3wc&n6Pf`OXq9ghb_!S8S z;|%AeqBLp2uxgw5?V{So=yC{>Y^%usDIcfoS$^GTh#$^T13L^E&)Of3m7)p(8aQFp zzt3%Dgx=4>u1a#%(=tmqsLH+#%!BX|+{Tw}4Rid9K19>I>j=G%qoz(zRM3k2qBZfN z^YH|7_l)Vn*25JpsT-20U*9#;d($%!zxlDiZ=`klA!Pn=Txq#altM(o-Qz8ESmi3J zCXgQ+5@s8<&5^&Rer+!QG**-)d$VWn-ftFwti-59asH_^p)4Z(WCw~*C9EwS_Rxz zsgYjq)p^ngzWUm79wMEEh29O7hH|9CFB4dgIHV5VhAt1MRz) zt0DW_yG&9bW8)j`#m$MMFDCtL%etDq&%_){#*b`F5b3!vuLq=5!E2+Qb$9nZjySav zZr&^Ti3%;N#9X1E(cg%4&B@1%FdElFHtr~oL}-UMNFVM}JROXbB--x8X`~*gWetdY zU;(t3A!`az{?@GBYRt~mhiQgqX+^6PfY(THUs$Nb>0}-Q=Byu4cq zP4XW7^26{z_G~6bN5+dODot7xUH?7$m*10PRaCrW(U@}weXDO@Etr`30sY@=k=JP0 zP_@I`YQmerYDJypv4)ys-?v?pc}h5HQgq>c{ZN703IWQo|K#>^QCWMF$67 zM&;U+=&XvMjgS}B)B!wVZQ?8I8wTZ&S$#B{o7nEF!dvtq_Nla3?8(V1pbh*Lkdu8hUgm&9Styyb@4tX@3oXE}OnTf| zQ|H+zvT8#m7SiF1L%RJzEbQBRFKcYL_}vs8<%ojQB79Q|l%hLC;k}78Vl4eCQ! zjJHx=(0fB?zHqV;+e!eMgj0xVu2f;%jA?yZLef34_ox7{o0SQJMys}WK3+1n$-~D=>~4=UhBVKI zDb%t}Nc#h*h9uvoG)5$*G>Xw;fSX8*wg0b>fFJwp6|Jv)eC+YQP@)5pLl0uNehHxI zR!3da)92=`06SXxBy01F&8=6PgC|=i2E}N0>#FVTSCfCw6!_8ibUj|kM9nl$>{}Ku zaU~w#`^%~F*NviTGxkdLO>gw6m2S^}yOaA(?1hSSJ~>h@3Ve&KY{b8{)Ydz^;(HbD zIz|rQLHs2GEG{ij>=U$a`(47)Yg@Wj6jO?1D=`t$%|9l8PD47Z00OCZdvqrxXalIz zVF+&d$*nY@o``?fglf(0CW+YC7V|5H*LRbLPe{Zs+N>ge>W6c&E2JY6)nlI0y4(%O zF4P_|6pa}OyfdF{400|_5G93wV!UVXE0d>P283$8>j<99$?Fxf3QM`&w11-%qqLsT z=`Q+uJ953n3l1%}39ByW{isjHNzgSkRMzEOy1Da*@2gY^uN3+9OXoIhe}aTKS%Ec* zZ$TvDamQtt?Eth4a%ByzwR{&GsTjq*!l^Uz&=0o%*;GuQT&gusr4%?kys(&7Q+>Kz z5P_5M(g16e`xqi{mjgKMqv&xhiO#OGU+6>Cn4C-lIALm~ieDtO{PECwX^cjzbId(S z8jJye_Jyl43n_TaeX+|S^^eB_r>xhmrYs4knXk4xW~X%OK1-Y0y0Y#)KP`gzHjXUW zwa{QZ$v6;({?M;Bs1I)51J4!uNZj%?c!%2=%_@9|4v;7-H)Zn+jUGq)<^n6MsdrbF zM)nV!#0GG(hUI4tK(f8m)RuI)5>JA_qTCW67Y*`j{kbFdm77ZPVzjrhI{+?XB1|L) zOY0F&TW<#21e}JR<`wx>?_putRj*np#*}C1!Z~3zq{-2@pjeApcl-AwgU6$j5kuxz zUZ&opCuEk0p;+;ZAXp}NQjX!$X_1KpD^!vRH6}cim!X44UZ(-<}pFZ@sdEo)#E{0MlM?BGkt7GDvHEiCr=l8rQSc&*BpzueNq> zWCEU4&dt*`@r?gGShp#=3HqCqlnxJpaldM_>p@lfIGF#b8Mc|s0v2Mo)e*DR`=WqxZ)cW*h{3U zUFFTxA(nVF>_AELt5%NC&NaWj8ec%xv*ez>&oja@~-lC z#$OG2L7tuQ?pzV)(R&$zsUsd)RN&CpzE`VB3{YO#&NAnz5z|~!CiGJc+I8S|C%?Ta)GXnzzz!l33%u#nj?#yGDr+e1Vem-{veo-Qi5~wQWy9cy7 zZIp|z9t39nf-%c5agduWRMGSTJWFJ$i_uLog_DX?o}6P+hK;K?f`te8$$sEj(OWDIkLGf5~Q zv9X#5-X9l@PVDW&rl=rIXh?dgA(#IH5X@FwcLxqVL_*8egyZS#bx@vEH#HoPp@W5? z2t^wBtpTM5GM;sf?&94<3bb5EtW-pE@EC)I_U6aV#?S@jPJ;1s)HovXzS4pdPv&{T zbg}lTTXUlZx#P7p+%}VH&Grb#ck~jHB zSy+DK?=g%>1nQ8fFL?bMB$aD^b=VvW+=gq;!>Hk1x~Z<2%}Yo*9=G_Kkv53ffptXi z%VEJ`|KTAkfT8*jY)Fc>yTKsClqM**u>My$%by=dmNgusE~A- z6SVQ6^=&C8SGw8lJc11!Q!qL3+Qp+A;y1ZqhrI{pli4VgfGE353a=bzA5y`3nJKeV z$*vEw;CD@Fp?CgTrRwN0zAt1Jy;f4aB(QbFS7)wd*Ol;$F5;`29+{t_ErHJXevIQr z=X_1Q<$uPT5uAuSKP{Y*C^jFWGATjbj|b$yN!^9qaGoBR#&qqnM##VA3l|C2=^VWd zbe8rqEiVQOOtX#q^u9`|JA(P1E%%ifdVzu*&t&=D&zx-0qv~`%P;yjyzlM4zsRk{x2>zSxy~8D&5uu z#N9&?>scoEF~UG2?fx$;nYLr6$UMtfNwQ~cN|fgHUECoC7w_{zJ z=U3E}`%4-^W9HCR#||H2Fikz33Zng$qdh`p@awi5mszRu9}%td`4W-mUN7RlkJo37 zb!rYy$5bm&+vDoewn_;vAi(@fHtf#pD~t+l09=8PuEzQ@bb%d2SB&YG9$D&9+Ux^~UUXarq@N{Eg%DCQe&(73#`vS2K)<3Sd zIO1_%Jk7wSP78+0rs2o;^&+wd31F7WC7An3Q*}wA^DZ1;0ZHJE6DKpmd3%sG^qpCh zNQ24Pb_k2siSvvj<6M2EHsrY ztgeKxq`^f#wIx~_cPPon@!rJOlbvm$Z|$|rPK0Bz{OdEk5^?Bk~wX03! z{O+&tJ)Jj-H-7OMGi z1BETW{P~DkBRgN-`rkf_*HoBvqp4)Hf3gkgO+Cl)pH2?5zgXTZhd3u<6iBdIf#uT* z?bTO5ef=^umXcHp6C~Cyh+ow-UYLM8NnZ@ZR#qEVMd!XN#k2=JQT`#MK@zM8>TRxh z`SJSQRp^8X>A({zT_YRCu*&eeHc-2spLL$=9EJUQ2I5uSvep$gTwfEZaft@0jQAZ{ z9o`NZ#s~raUHuH!=u_*dH+i@{{^dhP%gcMrt?Y_gU0gl}6HJ2-{oPc6nMwFzr4*Rw z#DnQxLwEi$JxJLL_!DY?#P4_m45VkPPNV;=s%*7KK08;iy(#^4jKx#Vz1_Cd)q`!< zY>~)W(d|AN)PM|*P!u4t_$Q%bxCW#-!bHoHaujHm*a{$SPh0SRkhY-mJ!fP4SB=5h z+Dhf)qy})U1xJ0#77(qY6(Za!Z{~m*wE){TCJ{YBv7nYy3RkRHK_f2ox-0BX^S85~ zmNrVVM``_Cg#7A?&`@*m9dkBj8MJ&u&+^;$69WM~q@SN^yMZ1qG zoHI5Pj@Wqhj`8GY=;v}A|M{4268(xV{+Ul7XTJSjAnNK0wIynty3nRca8ETfhO(X(=|D0@Fbe&` zyW&%69LUa&+KK{-PED%Hi|4*}+O%LtZk_jMiX*tc%!w!Y{PX#`JjY(mOX!TJBad)Z zS0R4_dyzchCR=D=2rO(8j-A!a)qSW9=N1;qloKZRvsuTHv5?Y*zgiv-+uK`B+j`|T zr?SQ!QAJDsSCGx|ztk|OWM>ikZ5$=(xKz` zbn!P+M)Q7;m1Gxl%oR9 zpg4xvT!qyh5DiIFETaw#^{e(aqC{w{uK^d z+QFI4=ncP{nZv03j!JjKW#&~?xH%^LZVz-UeUMhi{@P3G)9axPB2jWwq%{ia_C-F~ z?aPdp@|dDt`YGZ}@#sO2DNSN5ltPxi8beF{kYr-{hrD$9CboW zfBQa*n!5pKmgf4E@D79HS%BD2b-E^>1-7(S)(2NvKfUD^UT;+@Lugc9S^HWYA{lZA zz4^kqvhF`oEQ9P-cX_8Kj?886|K#BdCHrC)w&E{?P1PrY_4s!>h60xSQFta2UomWo zr50NWnU{L1>Mm^E5~PmRrwi-cFU9as{Sf-=bPrGBV)cE+;fKp({9ah~WKwAAoyFoF z2=-IsKb(L3_9I|8cVj^gOAI98!mwq1#!NZuj3FYeLL6Iwmut)U@_qUZ?Jw+X>%S?t zIU{C5RjI}X7}y*#^-*5^M8TGwHST{E$inF zrN9tB$A09l2kpCq>&sL7TqMuan1};xB4TtBC zXXa-$8Hav(f#hqKF}qhPve#KKLQC|ow74KLz@8~Ri*GOBL#20R^f`vlots~jEKL=_ zE1v%zjj0tV`ZpcUMWzsBPI4?-)%z^*M4U%Tijmw!OabTBEV~e`iLH+yamr0yX#&c7 z#r@{if`we?etC_;J@6(x{4>&m0z=4C8k{^H@t;KPrSnLDD5QrLeh-6!@t2sywq)bd zq-U3u7dp_gXjL{{EE7rDaCe-?BQm1jxljC}sP}!z*l5=?rjt+SUFt>sMct4JYwx_K zswQ$(3~wjHFnw0FK$c_nFD=Y3LJK7rf;CG?F7gST7j$gNHEU+3vCD;Ob+}EKjp38Z ziyINzA6DZMzob!QUDHBR3M}PIkGECO7-CrZmc3~@sTS8YCm`*_$N;d4XlP{cBfg3# zYGe2Tn4#u8buJA$JMJkF&&^Mw3e_6C%*wC$;l1DKlIooj-0xcCyhj*lJsSLL4tWmb-=wz9D%)45SS(v~EcEXYXvBa4TN&Ei3jOBF_D>e$NU+rA1J zbwOWqA?7IW9fkXUk%~4bY&gMk!fn-7D+k}&rDC+e<%8C*`Z!M=C0UzziD?2-+`H3- z-h$JGe~4>$w|(x5L@kprSOI-|6q}kivPYrMKlHvbGae$JwZIk{y+_^^AV@N=@F(ww zCBtd?$@sjq-3A}I*|(!?fzcE4p6|}KIew0fdw;i*YmFWT5!cQRYp8o41D031HLO*_ zB*1wq&GO6`oxnyLw_seGQxxR%mfDk>=Jg*Ir_>B7aLv8w$9rsPdC1O09$8bk)G$J_TAFi zyp*VI9Raj8*}L`wj@pI~BBhRWEaDmr*2>AW=E+-;S9 zx#$C}-_)0%NJC>%rDf|5Tb>iHr2**V&wp`->Z%YK1^E1MOd?tCK)z@BKc;|hf3Y7q zPmP{L=iqUO>)#ups-q~ZtbLjbli#n-MYTeD$~--?TVBik>XX89gFOh`O%V{!MR%VV zCT0p|g19xo*jXTOcxW3?AzN%Tom46NW#becutwh<=Ko=Jq&N&xStid8N0>sNJe?z0VXmcKq7mEk{EaE$3(wsXu28DOWIMWoxp|AVZ*T zTjqHjL6K`NN^?=k|HIN*1w{3}UE4$vL>g%rx}~H+fuS3Lp}R}E;fK;aq_l_(Al*`f zA~6gN(j_G!Fw)ZR!~gpZJn;Y=XYXh4d);eYD`}x7ThNy{BUh+BwPybHZ^x(|foJtL zwgMbu)ar4z6Ujy|_;cDUJs55{yKls@NXQpKQW6qI9s0-Yw*eGX@o@LHSja{*#?P{7 z3G5rY3+XaLk{`j=l#gJZg8mK>G!sXUtf_Ha8U-Ebk|ZEZpC2(lAk$xZc&+*Sf`YA^ zq41Ke48v2dpm#(OXumD^-2V-jmA^(8^fGprGY#7{Qa#L-s-qQ5CMw->#gTt>e0aXh zlJq`9Ng<#-Uo63f$21m18}QkjSp!|O&5w5h6Q^6iD|O!jSE6`pqwu{@QCaHQSNt=d zB-!$qKtRm1c{buW@-^b+yyCc21Lav`U$m8@TjpA^%SBRKG3JqT*38JPKlhhkoWfq&(BRmA;dsF@t224=vHT%%Yoi)r4bPF{ee#LE;M*gE7@I(w)UE^ z5eMY(hPH<#heyA6HzXZkDQK?FD@!xax9j%hSA>cKppCMYC~(!cBds!7;!$a}e z%gn3u+=MkGjWQXvfU5ONmXbrbF)a(p@F!x_4-ppn4(8@nY?v8dkL zw@#$yD1qLupRc&npv<1^6hDRnWzyKSiCz}{4f2YgIIXV9LH&Wr?b&cL%vlJw*Jb#; z_v+_foyivIkaddk*`**Ap-hRJK(y{T*MNy+J}zVHJ;(t6tI5Iqkxyl(BqV)Sz%5md z^hmI*T7oXO8(Wxuo6R!uG0wu{W;j?abo2Qv%NZLUhv2Lgib>?oj!ATC01*k+&Y9fl zW}BpM_qJ}~)|!5^zHcI~#*TD1Y-QI11E`p){%|Ou#6K8$S-@X^^>jI;?Fsvpi=c&V zl1~e|)+vO>DKXR6nZJ|>q{_(Mo&y+Lh2Ijg-dZO~N$;y4{)m|m-I!$@_ux9p1;#-) z5$!cC5Fru+wP!|zfuDSn`>PLm^xZDwU%9+ZOX~x$MlQ8kkb%R?bz98%(yw_iyvj?)`h&39WLJAQNr3=G2oq|vl%;5 z=%`4D3!Yh0P6J*!SjUHAwpRPES|T8Pcs_2hRM+jnSjK`TV+n zP4tRuUQIec=*3o>NxLA=K7R0w+j>WC$ab4duJG{q58yTnVOBh#n3`8`A7>b#3&vtJ z^o`}D*Q4)ni#exo#OpDZ$D)RQc9hTfeJ9Lr*Rtu2Y_rrX3Cmx}=Z9DLLUBTANdM!RhdK$+RR1;X)yes^MHyu+mTaztQ(E}sl0f+D;ZY~AY;wC2=yG_P z`4*2P(v|<`Tg|XiU;+GL+}NE^ByuVai7eR9lDyE~E*8AkKKVG!8l!}Q_$CgT!Eb&A zDjpW26SBhE++ImDdsgQOM)wc>$AX4&Lk>4&z2%Al44IpQ@1C+=zhTzm(tanuUvIJ6 z%nRWC*)K=Y1f>-O%1t*&ul-XfQ)umTS_RD!wbRK03C?Pxo@8fggni$mKHrbMG{w2A zI-{nja#u(J6=p-etH1Vm{xfltup(_Ke;8DKXMuybfJz|K8SO745;or_p3Y~m(-h(U zNcqUL@`zeldiYcPPdScJM|MLFNrHwS4QUNOR_>K{iD9+JD_w&Z32QZC)hb0TfuP*# z%}|qJQ)&PEna&i3%Ty(Anm<$vX)IH*GSsLG#J8(I<_~U#F(eOVnON^{#mMhweR^9p zs1-d;MH~M^-wOZ4NvK#uO&d!8x;~653{!(oIz!wGTWZe2Dyjpo!J`bH2VpZpZ}!aK zg;HjZyD8t-RwDBC?em#~A{7M4qzvVyUv{O^B@C(^TcKgPkRl;BnRzQm?-dwata|T7 zpJbnpB5^p8!~;^tXb}K$DL4P^q=CMV9wb`uJ=$k!!6TMqM&7b>2 zHW|@TYdoa(K8kc@?R<;)gMvZ(sQoQV+YQ5Lt`A*qlCp71D%k9g>gsTJaE98=*2L7t z4+DiSnSzkUB_D;yq~$D-lNnICUuze9<9(-5zrpc3cqh$-(Eah7h({hXHLc|Wd7;&1 zBXi{$ab5J5x@#$&?=}gn(P}xsiPh2R!wbG_MD+WE;)k+L}wXf;FP%9SC`OomqEg z7bl&ZcQXw19u^-1RBbcZm)K-xvQs~`t6?m3m&Rf6lp5pO-Nr3=&8?39m98>4`E};o zL~#yx2a+O8MOX#1Yy>;j`Xk*nQ7Xl3dn!d7*UwuLkGg#3XBtC{0e40)dNVvkt%ckv zrK-q#eC&-i@EW+ zPwH1fU&%!6EUkMx5UEkgBGbTVY>AbT>*bePvm>i?15jYkT?dDpbgcxC=?tLM=r3hf z-k2MvYKn;4Z1u*^G8#tI&%n!hkQ4a|Z_`$M%H7UCR9S~6wIuhMP#bp;9sTb9tbWh= zNzNyge=nb~xTpsmPHbNga2(u8fX4B9nc;NM1E$VTd&yyTqUDQW{KoG4={wBRnI;4x zw_K}LI%OFv#=yDAx5z?%j=IC_)Rk1j%r@PnO3r;FF>8045{X$g@mE z+HJmU1sgnIJYZ`wIXRB5Z^&kM1cMsX2i~Kt`B!j%ti!Npi0ig+$}vc<)B;bIBAt<+ zyKNIb=`&92ELiJsB!aD@9XzP^hnvOKK{9+{CI=PCm5QV#B+V_LPKQD9Y@m&u`}rAq zX+CanRIxsz1rJrZK8Vx0tqF*B;ggqa6{2ZNsy~~=sNNGGH1|lrM(a`H2>#PQq4Ex!8x1p(r6KvmO zq6F{OzmK=C0*!nLV+k3>yPRhtyqtE8I$(EK4JO zOUEx;#<~$ru6z0gMX!+0l9Q-k^gsW8o?!YJARM(ssrB@HszEzcOufw9@OICmuUuN= z64_}Yv?ix}@`2l^#JH6Ys_HiIx&5U~&k15Q0vx^aQ$44ks_&o4@OeTr0=J08+z@-o zOAgSOY@vuD?x?h>Y+1QmDf}>*Ez(_%C- zGKT2a^Np3Wgr^EeUb0*Sw4{P~i17k=g8hh}3p9gUXoh$}@{?+-)vrOCw zjIrhyV<}J9k9^QO50bQg*1K}BmtAI{QjM2&Qx6YSc>bCLS!4+F*g7B_!^=7Ltngr3 zl&H2D{P4slRy)e%*h}=~7=&pm_Klhn?WeIqVB<2r-6$ii{cA6V`^BwE-jHOjC$a>ET)YugJKEH^mUM6iFQ*^1B z1Kjn)^|w;sEalSwOg*{tg`DhF#NOnQmZbslH3{VoYm)H-lT}bE%hx(&&^S0&vr_ju zyL~M|33zRn#71gJZka$_&O_enj5Oi!hTJNgy~J$?1Cm)T&XnT^bD&1d$<+)xyPzpI z2Cs%{C~J(d9|&@hN7fCJUGiQ%IzXo+eP%EBY~G5F99o+%Y@9 zJ|PwEwCEd>37!Gprl0V}#V^Vt^p~)wM97Tz+VjQkn4=$~@s>a06?*K>zhQ+-tI@WP zm`0U*%R!iP-ueB2=zS`bhxutEZ_$JNq4OM|H+J~(P?M>45jr!hI~S9(QjWYBUY4Eg zeQ|Tp^KbR&qm*x4p~pt5Pf`wjH02|t1rC;LPao$2Is5EFe2ljtsj5`|iS2t5W31Kb z@vePBK67(7ve@}p9Gf2UsrazPv7;ry!x@T`uVQ3+#KuWUxwDr-?o?Sid;EfB^~bku zVlk|3v`Px5&!zey^2;MitZ=KM<*@0?W)bj~T}T&EDh^n*OzvWZ`Eb%4N&n zR{&TO9}ZGkDNkT9Fa*fR`!vc|pg7*@;Ec+hOjKM&z-2r7?Z;DC2u7!(<3xfviCjn# z<^Jk-&M?i!Wre_=f>K$mMhjC@1fLLx`wwm>=;xPFmoemS`x#{fA4@ zzSC!7%J;MzAmJ9uwCAq(J3tUyf;-CJV(CRkNOS;f4##Z}ExihPX2_$8(PC)nX_E4f zG}HK<5;bThc6IN>@~rTcO^nc0M*s*jXh!93SA-qiubsa)blPdHlqQHRrv1<5N=MG( zIE6$6CnLGi&sIg-UhbDzfG_;Api;QbJ)}+ch$KIW^b6?32Y{FNhX zeq9&kncFYA9tE{Fg!+igJDKgB(x~+QMM8q{h5@(}znBrM?!~^WfwHQ4hMUR5sZm>v z>AHh=vYcT;VLgzt6$eBr4T42Z1a$B)UoReB^feOnd2_l8QuIb-QS{2y|4(=i(o2BD zHD)A|an=)^(ScRWMarXXBfVKUY@EE?t$e8@imcoIChE0>jLq4>n4j2GyuI4u~Wn6qyO#5$m_Lx-YlxSE6O3#DUkmfWrDyGllhkAQH0) z_pOBLXo^oI03s*Ik$Gv*++j&ukO!+p?f#Bw4LtTTDw#wDHqocQHNyCMrB5y>^^V(i zGS@hRWC&v}SX!RJqw%-CCK>xY*2F7tPNhGpi0*JC5y@e?#t=J>DTpSG$iWV&?U}BB z%yPe<_!-yZ@MSP1&eTD7Gav&`_-HNlYnG@Ar%Kb0BKcThE2SK)QU}SWD{ODWpp3b- ziYW6}C#GFz+=n`)W1-c;>H^$Vaa|{;7AL=li|h}z==Nc)JuxbCG!vhL;-proRrAXwIMNw5 zQB3q&94rJx2`>W8;E&!;daKMZdPz)ai|#37EqQ}ihM|^J3A}e9tIgCsssH7rQp#L^ zIk8@Spb{j7Le9Nj&*wZ4OTb)Piy|rg<$=(yb}#d^v7At$xX7tgLszHsl!@Vxm5e9l zdlof|u2sB!NoOg-sY4DDf|g+|c%&hrYh|Er-I9jWrW43>v_+eO*q=Ne(hSx%TxIzZy0>-TbysvO+DdeVUFGlp> z7=6xzXoiRMcX;SIcusggsP{C zyZ#JT;T-;+HvZfMHIR@TCOn1WOMcyAyA_Y}f<&EFru45z748p$3e7&{%9B3gs4>FL z$cowI%4>`*fJ>5(JHwiNRyLigWF4*t7zl_aTR=>ld-E`)fAfMyQ)zs7-c_T}FAbik z@q!`NDQ(0f6N+W}`fL`*`iz2p3e6srl+(a@U;z!?5&I!9po|S@W*p=x9qbWjqCjZ0 zMu;Ik#YH^_{iGX`p#z7oecM3NA53i)Le~B#1Sbs&zEygYVIAhs1nKM(SfQg&mz8SA zV$FF=mWyR|+wXQGh_3o3?jXeR<1_sOJVhnC_pCCoOQUR6(&!yxlb%Tq6CLJx0LU3$ z2{0*hU9xsk_nNmIwW($kNeQ<-K+*tUpzJ?T&6kh`^d0}sPh+Q}W@V_@augqos?S$N zYuK9JIGK5&2n`!?l?*)D&P`>rz1Rp)=bSV7NYw|Rr9j#%*QsnzF1Q)Ke()RsHV;=|J`v+M*W>_H4 zaYQ2<0eZkWo8J+gU6zlXN_5f?Kq6)Jp+km!E|H(^jP1tk(_DPsV!+$oE}z55`6;psU9F&gw7IGJ?-?z7XRq+q_i%o*p={nV;5#cEH?rvJd=|ZQC+&GyNKa3ts;erjB{bz zCpJ%bl8O)qsi=MCe=|1F)Vwr%O`w-ifK`0(1bYUx-T^QBD`A84;);?1cuezE%lXqB z*#U>Zwi;y#D?1W2M$l-g-CC_;GyL9x3%#Oj`r$+n8dk~Z#QSqyt&aKfh4MhKUglq? zHR_EL-LJ6d4cOeo;qr?OzSUu0_3_imCsgi`nT@rQ%S&bg;}?Bjzd`=|a!JZZw7%}# zi!#z4dPKK`jOj>Na5!;Eq6XyS|Eep%8~3&DQl@U*)U3q@+jZ(zv$s0PJ=mpPJ@!79&0h&yFxp1=ddUAid$LfrMvls`P=bYC9p42c}EL zppWhE=(MOCI$v=-zvyj=(8`8@k@=K&29Qvnlz!)|#k!8`Q$4MlOUD6Yig9?vNiwwa zG!V2>-HR!_`H+Xq1e3S{E&F|@HHDJ-?-2*cGN6wrY|(C}@oE4eqleJ6O(&uj%%@>b zO1E@Z^d?V~Qx{q(tWOF42ujShyN>&F`LFsR*$QQUR!gOuKWzog%?*M*=LWK1`I$LZ zYSN0C`0Icx#Z6yknUi4!4>rzR)$Kz?f{vY}SzC?7{6PQ^g*WV_U>uf~|egp8kAOvZJPsLhJ##{{Xw! zD+eRcpElF?N@?lw(r$)+P=;YIlH5)0U~`qx_$*xGS(Fna5xtfzv@%BT{Dh7(fpWmn zo}?L0LLNTJ8mq<1g8ZbjE__BFCe-Bt+ zMVD({_HDPG`g>D8-w3^V3Eoh+M~`Ce4>!4cyJbUUO_XvF350XkzA^(g@Q?!aQ6KI6 zPa{k~%MTPcc27(_D>(w6w79-;XZj$c%slrZ{sZFL3(<*46NwBC1k26c!3abTbEao1m$m zgGipSG+u9iqY%i|4#w*u2IK!afF*UvvsDR_8S;L}>Zr#|>&F8P;7@p&mLxfSCm#)Q z{aB$PG!CzS+XXt$8p^&mSfxd+Q<2UPOwBIxS2o0hEDR7r)OQ=N#4B^kPBf%Rzb(0O z$6n?UP`)=zcEUA55R=IJbN92)UB+JCBpw~SM!TKmX@waqCETxI2)fJRerop`*Uk>V zQ1Hr;y7y<?N_Tk zHvVKup2FaEKb!ac_2z5D`w;>`XeHamKQY~G2w3m}SA0EnT1f9os)v!=#7(2l8i(%Z zMpDOmk@(j$uf{VlQf?&?A<~iEL*|5|g}jRdlp=6yWsY7yii3pK3+BQ4n1MDpmzhiz zdYnu(q{oie-;THl%&mrvDA_nVdD5*Yor3viDt-2JKr1_{{UZ(osVC>jQCC^}r1lf=-kZ0L(YK-(4-g#p$}dQ~ z4H}4ix0Tmtio3C?OF0SUTbAhyq=4rxO;ybF)kW{3rLZH-92mFIH#u#EM|D$j-Il6! znP18_&|$?8Out*K7AUrx<>cj)%go_rJbKu2fT<_!t!^}~p1iuQucaoN8Oqd#;3;mZ z4Kwh*lU!3Di{#`mzqpfWvVTI;nz=yM6|;cr`lG23ag!q6zjvRT!|?IiX_v*==n9Q0 z-Bb+G(4Xom55TZAp_ktB(g|1xV>aIX6%AVJG@XsI$b7Vd(~7foRrL>>V}rtW znQ0qUsq+fck<-I8H@e*e{pjiY*dYUu;X>}F4$Tb8Mfq`wcZp0s&K`H z>1SS^*pXJg>kI7i&C>%7;yhS#xstAlj$;nqsc=@9N-rdT85MJJM+Rg~I!rhw5=x#- zje4y?pMgg%o+^{R6@T235W+b3uOzsc)I(#pFzA`keRod22kY2>BvcuK>Tc2VFghMu zfSy;^0d6avXsVt-F3$=C23h0#YPC1dE@CwoWV58#O&Gv6MY`$tJ1fqV5cr|@h}li8 zZvBy}Fe`oHNb48I(v+HtR@t>kd~)@7vON-wZXtPx%4w^74~rhNpzgUE-iS-URt6kF zQRfS5RwH~v>UzR<{W-CkX7T-)Eoh@I$ajaOb$>6mf+Q1ti{U)hK3mdP7@cR6RqL}P z=_AT-(7E>V)+Xif}E+AuT)Tbk0LvqZFHbJ&6CWiGN`v`a8|; zAD(@-bCJ7y4lP63mZJt(nOKj91knAr@mJHvGbxm8RCyyv7K=)6iHVuJ)#-I$u*Pmo z;WTqI%42W)(N&lpN{cTD*N~vfKNQ93|GZl$ISCv;hJ7N6bqYoNck^7YCIaf75$3Tj)nf_9p)9OAKnHh7UN6p^N(A!Lfn0IoF`D{(DHUu=@zEI(K?iU{>b~O zz!*U-kRo8k;{2$n5JIO{iyEAGz-I>p5=k9!qRl+5ae{ybLkUhk+5{-EK%D&7u z44P_aLPHgugaWZib$I2}evWiv>tpk3D#Ns3kNh!w=8Lo2(Bhd5WY zdr1*n$bejmF4@b>XOZdIN+{71*UWF{Lu3_~8v~zl3z9f2+60$g>aLMGnW*tM&N~%k zUDxW(*H=ZZzF5EcD-CJvsT^Vlh#U%(h`ee6E)mEC4JBF+(8a3QrF}og%PpajPGOay z48yd7I$MzKF+bK|l$!M2`sZ-|^J#n;u>^H|QQSJ%&r1y1wA;Y@G{Uv(O8R_CZe7fR zL$qrf%^{sw!g9rEWnJRboYJob3$o@cOV%nUv@5EZA@7XYc^Ci7uv8VPjSVivAe36VZkYQ^ z4)B8g1g+@*1AnuIaw<$h(bXdL~y*WZ1E^j-=~jvx8+s=l0R z{}nHmsAZfQMR5|!Q;QNTd*JTvGXAlggFUPi9 z&$!jrba-Cx%nZ_D+4&uCH#7zB-AyI81SOt#1UY91v zPUCI;x?{9k9%t>Z6@xH$6*8==d(VU{DZ{lE1=U~;Zv7Qqb>+Jg9}EVsZQ77tsy=z= zg2wU6l=2q$d*mUc-!H@_03!b(<)?O)*nIOAfNkh2&GwbHkNb8H_+igy3$JDgf1JKn z#nf+1Zi%l}S-?AV39vIYJ{bB7k)bDgQ+vi!#xxNr`!EVXhhCN|EZtLDvV9!zyeT}lF-Ckyo^VhofpSntn#Ixo4{>1z^)r_!=TCGZ zBF_85H{StNu&de3f1KjG6*&Ff1v&y5z&?4JX7coH5qdqWJGk$dM|UaqpmbsG4Sl1)umxP@|JO?M<-m2tZ7JVFJ~w)_?FE$7R-G|QcxiM%P| z+qWP4Z^TJRe)H*T)U_)XX%Ch4?DXCwCC$Wobj@*=1tF&c*=B;GUsK>3tg1t;Z{8!% z^9|rH#U1-X7C)#>7zq=qxOE4jz79rc&6Nx6$%DvXLEGOx3iO+cX~Qw}YI=Pp;uQ8D zI5Ys>$v$VkjNbTk;lVn&A1yZ>hMFG21@mBSt`H<9Gsff~jF0Fd% zQ7|B7VBdzrM$IkVTwfSQ73)~04?i8vLB1~)3F;yQoq>yCs5DS@xKRypY|}VLD#Ai? z-Y;5__@$B9M-sdleEzzCLon#%d+^<@D$mZ*_$4n!i${zbc(LWF(sbigFY?+w6xWLS zd2itr-Y56P7_EeMaMH!TA?d5J{`I$E2?Io7tlnzq8OTpN)}VgaZSs!w3iQL+fXyoU z1z@I3-N?Os&GkK?Fr5w(mWMRhczko8d?fb7MHE|~#(I2E--@vj^67%I#`FILo~l6L ziDEIMf|dTlY=3<9j!*>q4BL2J+=_@?TtT^Vg(Yh$iQk>F1xqTG88;FjSXR1nXR9+a zgWf+BUCzWz+s~sV?AxJjh+wJFCjr!zx<85)j~3}jYuHWHO$Zi+so} z-{7ejI-<6Z79BQBUu5^ka3@MIbweNAbslFCZisnr)$xu>$;01Ui!;-UtVVi}#_q^X z23@Pqk?xOYv?D|x!>L%HRk2k+M8+({k$&5H%~?%#73Hs`BBhH<{57dWINL%SHK&G;!R z)wuq$tU?KK)IPUK6DiJ?Zq~S6pugn!)ohUyVg-Ms@kAIAS>wH4wMBbl$5(3Jbp2Jj z9{M@Vv(rg*f!J<%^$&Wf+ynY3gIhw5Cu?LRiqq5kc-;RmXvYtGIt* zmtq$ww#PkEKl~t8xsDfHoabPi532RGs<&f`4Ra+U6~UtpILRE^hztTd^ewCsT%9(C zz-bLpQXPt=SJUGqZ}rWdGO3G?C}v{%)`GByRvM}aDXD)u^`1XjDf!)#^D76DpNO}Z zQ>pcvh?QC~hbWHdp%b=`Q4MP5E3G=gltaryGwzd_1}?!O$c^{F2^@$0Y2 zsucTVBE}0gz|r0EkX>03<)+d69%}O%Q>aC$s$Rfy8`>D;y59;q2E^Zf=vOPx=Sw$K z*ir-#;WTT;tgz~?nYy%swpY?Z^h;M2U2oi+9+3?ogeaP}!vLP|KO&C2fX%DPPYX(d z(Iv}%CW+8RNzNn_#6fyB44joXp*fzKU?U?>+Dyw5(-ZjSB#U`%dWmq1Y<$by&50$2 zOlg%zVM~+%Z75VxVAK`EsY4>s_&)h)T1{12OlBYy2vhMYXSv}K-GF2VU9o}Gnu zIk2N2w7bVv3;(^LOPM(J(Ona9s=;F|nb#sKLq;EOtj5Qi(KO%fh1pKC1%yS#zvm@% zm+kaE)@)q7yB>ajH|3|;Px>Oi0zL)lgh-IN)uN1RhB zykAFyws3(UJ?}(H`;`^U<26(vVQom~-IPM7?jIJ`{s+ltEhWB>(?Cq!J^ibB2cMV- zN({Lrb#55lsy~-7eP=jmK)_U)g)_w~a6ECImB{?!No-)~T%kd}W?mr6=T=U4#w_D2 zx459hf+|ZLk7l$lD$F$f$Mhi)CUc72l%e3|lfs6m+34js{AmNp&n%5x3 zUQ*Xz(=sCEo$_?n-4p`uGssdbAA6o7&$Py#UEzQliPm=fLE-tN#&6*vg4GsalnD)6 zvD#_P(Y5%qx|1i`m>%%lu)h&E>-uy5&v&X0rZVt_GhD(NPA6Jhc(G=Q$k(u~q7=Z? ziER}b-qn>o5c_knEmDM*4uihdUjCuGOfifOC&)6j9AAs(8k;b3PG`Z2-% zIs12;*zbpHR9I#bB+NIlE$2x|Nxy6*Oci?2hKN2VJNC@upzmK6umy>`_nmn}h)x-LeUh2?)TnIO7w;E*#fRQLl_s2G`X><+$X$jl4gQIB1F~8D{>j2O6NU7QucvF zHY%o^rV`hhrgH@^$C;}F(o_e@)tJeZ81mhabvU2v9Q}UP7HsA&Skfp<^hD+^}96o;%q=Hk(pn3|IFAh1Rs9nnH~k@WniTo_HODn3F{3Wr-T^%dK{oY zH@5@_or2*Y7jhUjxsT4Mm>xQSCt+*9n)2mN^~+|Br-c;JLRs~sY9icOIci@}$lNp! z`dW0^osVC+*rPWpqoCh@xDbv~BZKrmFF^;UOqepORGBd)SDuIIKs0qC6)B5E8n{u6Gm_pWMS9bN3IyqY{=DBwd;fm=*&HoZ``NdsSBzZu1}%LOH(%ff%~k8z zB5HL)VySvI8@z1C|G5rsw_|9!OEMn#GEGUV569y})Wa3Keq*aHz^sh_ zUBf$5U3oxey-;eg1yG&-(e#{qOMS#$ztc(DrMIekpZsqXrmq|&^x;5A=(wrj>@m<2 zojv|$B)sY8k$L2!2bhLGTK7~h zUn+I!!hBF65fXLp&=*_?^u^zFAnmm|2mAvNwDORMLuy{-Qg=~vT(op z1$b2Q{)u-Wwldm<+MMc+_+7@1wm1o5{cnWaAG}1Z#67JYIm?n{+g%W0!)uzVUgT4j zChaP87l<7=BI8C2PAG(%5`hOC$3E(BA04RY9kgxM5Dn3y2!X z$cd4o##|mCR1F|9Qq#dlOM@bP2vN*Eqsnt?s#Oa&y9wmv5g)D9kAcQ46hoI-i&BS~ zIi~um@!_bx>1XcW^JJiT)M)%f8HMzPUJgdM%i36XZX}-tLQ-kj4P`P{r~P)$L_LrdG7fM~L*PMPi6`BF5sY{~>7khqfl#$b@yKfr#m&XrW>qpov)-QFR&r&3l4A+$@vr{k@7b|EqDTx~)%ywQP+PI3{L1HI5Ymi!rG^ z(Hj2UD0W^~b0}W-?hearrkn;AI2S<8!Al;%63erK|Ir+vwIDu}|NJTNCQILOv`~%Y zZAe{gn5T4wMog@eSEs!-YZH8obaVCc`?lBw^d$ei`~IG)N=VNeX*%rgePawGlD?Lm z!#yZz%*PpcL3)Coz=5^@y@p>%Pl^3Auy~diQkU#YI-^W~J9!L`;;I=+JtvG*Nw6Uw zLJ-EhU;%F#+H|)(C8xL1S5eO^-<+jZhkWuVubVhk(6zeT=5au7%nHd7Y*$mOs^7(F zDY%kb+$H2){(bn2^MF}R$y?PD-BbrAOB~p zWIOexXlUa%`l6{G{oKd?7DnX@L5s1mes70k#{IFkVlXw!Kmv*wc{PszWC;|hjHz1$ z=T(&ge|D4Ux^#1M!Pq~RPC2?%ZqV9p4L$$Z^4E%NTzD90!l!3{CA0t}qrh?J`>7>b zV~B-wPoG@!JA3W2;E7gh&sSpWRNjo>(yh=^YFAfQQ|DBCKc+-5xMoy&A5G?ygmh4QrD9C&IrCDfTX4F zTuCnLw5=$(?1|z0OYw|eJD_cZ4qWTQp%_YV%#NGbn#TY8*E96NC|WU}~limNp) z*q+=~5fwIDO$A&~E_5D3N-ItRnUcT-^#iz|rd~b$%uOG(Pwem=*qPXf9b2S-rbBNZ z>+bgnn}nE|B&RFuRLx^pbzVZ8RN=XGT#Rdsp4m3gq2Q<#Op_|a@;2XspSfQRLWxG- zAe1@;D0R6r%`SIU9uw=Ce|~r`k0iIp0f{#pBh!XvP0c2G8OZbV=&2Y^%Q3o{M$hj7 zX;PAxTf(t8CHhZqs$~g5<|#?Rj{6t|y0{$lvVE#BZ+XOPackUT`Q}3kd~Wux)x%0o zwRtb{myB7#i8LQCzTXlTh5?@s*Ps`V&!AVX{O8d{)2e!vL9IQ{ONKlJ6rV=s4ORf$ zO~<;ECFv}T`;}jLfu~J$9U1%KuG*p=_Dbf3?#i7>?*U7J_!l9wmBi_NqC+)}&omir z={Wcvc)UBd#GRuQyi$wAjpvIqia*TBOi@N9{Dav*u?p2ZQrr~Sj@~0MUPd#kp4(BG z(pJ+NV2svt>#l|j<7y%VFhcstJ=WWo2y&{|?f++XNMzsw0AAuSnXv~)k@%vO9|kON6LXCvTzQK_?O-!f%j(zWPtxV z)OYleI^b#B6tiUJGfAJ-CJUy9!{8fQ1=CJV_S=R^x5&9;uU0yuJlhYPg z0blKdY3KmdVwU~)MiIIXkWje--QSuwZD3ow*J`;}8U`)dLMOkso`BHC(_-`Mq90iz zB6?@LJ+HrfA{@QX|L##aYNQYSx;d?FHSZwYx*Q@^3kjiH@VZiAV7-;T1xWi8S-`&v zw`m$Z{1Yu@i3>f1K>P;TYtdYd(URNLW7$a0PN^tXfDIth{G9@7x65iFltEf}=$f?! zs4SnlcXwGj(_*jjc3y7^?#EcGAoA;lCvyuhi`;PZU4e{p3_%xmM|qdM6CK$KUqN^e zQ`B+`qE(`Na$m!fKBqP+pN>GnZU2moH1l3lxiICaZy4xY7!Q~_ICkd47p#vrRYvtp zqg#d`_chq+|5URrv;bjBEIP!eO&pW^AWaIkW?zoLQ{#Ma^z(?UFL2{!v}=xO2~~}} zbb9wC&zUo~7|toXaGP* zW&bflD)6TP%}7f6a}^NxTmTxzVXZ&QaZTcO{dSmy*>h)wW9TM*W?xyeN+pjy>^vn4 zxlQ8ids41{%#oMgeYpQtilb(nI$<+<=*MaNUa7f&;;xP9<^DB!p@!(CL!InS*j0v@ zQxLI>ke#J~+GCcL@P9)>ot2B7A9DV%678F|^+T#oWL6oTF(f$(wwvy%?TV-Wu3$+j zl2<}~`cQAx*6*UTx*l}+bt}K_b_pQVO=P)8>&{qE`yv)soI6Pj`2lO);5Kc8E*$f- zvXbWSYIQO{Wwz#YP1afyOUV^nqT$?k2(f1MA~Z0?mnW+yd{oyMY5oX@wzl-|A2hH0A_;C5M*g32xzUGPWLubUW?pMyP=ZC z!>}{d0mS(|ZM3PC!gQ05sBBZt7k=TVapY&R z5E7q6)S%*E9;|bseU^iHZL4mQZLyuFCZx^8r$+<)3*(j?xBW=L8Z+wqf8(v;4Z2U( zFycMJ#TqtQEo-Akc)<$)CbJ1^$K^O5=tV^Bn7s+MfMVf+`aRn4I;=%}8Ae7~(Rt9t(i5;y*~;MgFLi<*VL_?yq43#a>wI_N+t=Axi*jOiom z&vf2qP~D!imD2c@;iy-tJo#ShVYCfcD~&IDj|pqAVyN4INOj11*#54qP_rk4O&6|N zjw0-Pz&l3|(qy-~(p~%+9l)|R*R@*zuC#PFtozFH{)GV)>Gw_7-14mF`#&wbj-svI zFG(?jYsgnKAhCqZhQX|vbkZUZ`a5bjesWnh#n8>$?W;Nl@%QPCoU~OISz*a zWnBd}7;g>|15oh=>^f;%e$xB0I>Y;SCwYm##RS$H;vc_36pwK62HR2P{&>F4OvD>O zT8*l=^U$b?Jc!_s{w=~xPsF_q0thTpged1Gm1m7tkeO7^)TW;tfOOnBT#drO3MvAi ze&$cpWsfL}+a(G6r5++qOKH6o}J}ZpPF; z&y1o!iX#ze$U5k#i|>qfj~sE(g*(&Mz-6EAnr5fWoB4#hC%CVPAMjf~Igp5l&K7hw z`&&5fi)US*>kT_++Ng6fBoVEE$xw3NyBft`B0=$Q@#wif!}a_T%gsBfe{A|p*S~D_ z*Q77Mlg+Z}VawL|Qeul>r#;{So9drc_BzQ%v<*3O%myrhO3rk}PdMe)14z$GU$D~^ zsvM%lK_Gp2H)>suJQ`*bG7w)7+?@8TpNDvu<*WDVyST21IZJQ-#~UTy-OT!=vr5ZH zg!ivfxrqqS7Ud{R2*=H@Qnnn9kq)N1u$&mmQrM>j&h?UcwNXxvsC}{WF8uVbZ#&!{ z_`#2zVYUa=gj02);t7_?$fDFBCbl{1ZG|r04_~Qlp$T(Ufr%BL9*wHd^Gy*tHk#H! zLM+oYIan1Vhh!M*>11_Non@@{S)7!0IaTK3I4YgU1ls?tr(W-!DHmq%_Y{F~>&a|D z4T^e5*i3xpsO#&ks?TLl$%0}J#r5smEZ_h5|JZMITCr_yu

utl(A0MY>Mpxnme1R^FhDEjM>P>19(2~pOM&gI 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ʝSXL)BdI(PNE$VJC7_fsB; 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 au6kY~g3*PnHS{Et;l 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