diff --git a/src/Net.cc b/src/Net.cc index 0e2fad67e6..1009f5d3de 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -148,7 +148,8 @@ void net_update_time(double new_network_time) void net_init(const std::vector& interfaces, const std::vector& pcap_input_files, - const std::string& pcap_output_file, bool do_watchdog) + const std::optional& pcap_output_file, + bool do_watchdog) { if ( ! pcap_input_files.empty() ) { @@ -189,9 +190,9 @@ void net_init(const std::vector& interfaces, // a timer. reading_traces = reading_live = 0; - if ( ! pcap_output_file.empty() ) + if ( pcap_output_file ) { - const char* writefile = pcap_output_file.data(); + const char* writefile = pcap_output_file->data(); pkt_dumper = iosource_mgr->OpenPktDumper(writefile, false); assert(pkt_dumper); diff --git a/src/Net.h b/src/Net.h index 0a5c23a46c..dab0014dd5 100644 --- a/src/Net.h +++ b/src/Net.h @@ -4,6 +4,7 @@ #include #include +#include #include "net_util.h" #include "util.h" @@ -14,8 +15,9 @@ #include "iosource/PktDumper.h" extern void net_init(const std::vector& interfaces, - const std::vector& pcap_input_files, - const std::string& pcap_output_file, bool do_watchdog); + const std::vector& pcap_input_files, + const std::optional& pcap_output_file, + bool do_watchdog); extern void net_run(); extern void net_get_final_stats(); extern void net_finish(int drain_events); diff --git a/src/Supervisor.cc b/src/Supervisor.cc index f3b517c7ae..bec830237b 100644 --- a/src/Supervisor.cc +++ b/src/Supervisor.cc @@ -20,39 +20,41 @@ extern "C" { #include "setsignal.h" } +using namespace zeek; + namespace { struct Stem { Stem(std::unique_ptr p); ~Stem(); - zeek::Supervisor::Node* Run(); + Supervisor::Node* Run(); - zeek::Supervisor::Node* Poll(); + Supervisor::Node* Poll(); - zeek::Supervisor::Node* Revive(); + Supervisor::Node* Revive(); void Reap(); - bool Spawn(zeek::Supervisor::Node* node); + bool Spawn(Supervisor::Node* node); int AliveNodeCount() const; void KillNodes(int signal) const; - void KillNode(const zeek::Supervisor::Node& node, int signal) const; + void KillNode(const Supervisor::Node& node, int signal) const; - void Destroy(zeek::Supervisor::Node* node) const; + void Destroy(Supervisor::Node* node) const; - bool Wait(zeek::Supervisor::Node* node, int options) const; + bool Wait(Supervisor::Node* node, int options) const; void Shutdown(int exit_code); - void ReportStatus(const zeek::Supervisor::Node& node) const; + void ReportStatus(const Supervisor::Node& node) const; std::unique_ptr signal_flare; std::unique_ptr pipe; - std::map nodes; + std::map nodes; std::string msg_buffer; bool shutting_down = false; }; @@ -80,7 +82,7 @@ static RETSIGTYPE supervisor_sig_handler(int signo) { // TODO: signal safety DBG_LOG(DBG_SUPERVISOR, "received signal: %d", signo); - zeek::supervisor->ObserveChildSignal(); + supervisor->ObserveChildSignal(); return RETSIGVAL; } @@ -104,13 +106,13 @@ static std::vector extract_messages(std::string* buffer) return rval; } -static std::string make_create_message(const zeek::Supervisor::Node& node) +static std::string make_create_message(const Supervisor::Node& node) { auto json_str = node.ToJSON(); return fmt("create %s %s", node.name.data(), json_str.data()); } -zeek::Supervisor::Supervisor(zeek::Supervisor::Config cfg, +Supervisor::Supervisor(Supervisor::Config cfg, std::unique_ptr pipe, pid_t arg_stem_pid) : config(std::move(cfg)), stem_pid(arg_stem_pid), stem_pipe(std::move(pipe)) @@ -121,7 +123,7 @@ zeek::Supervisor::Supervisor(zeek::Supervisor::Config cfg, SetIdle(true); } -zeek::Supervisor::~Supervisor() +Supervisor::~Supervisor() { setsignal(SIGCHLD, SIG_DFL); @@ -156,12 +158,12 @@ zeek::Supervisor::~Supervisor() } } -void zeek::Supervisor::ObserveChildSignal() +void Supervisor::ObserveChildSignal() { signal_flare.Fire(); } -void zeek::Supervisor::ReapStem() +void Supervisor::ReapStem() { if ( ! stem_pid ) return; @@ -199,7 +201,7 @@ void zeek::Supervisor::ReapStem() " of stem process for unknown reason"); } -void zeek::Supervisor::HandleChildSignal() +void Supervisor::HandleChildSignal() { bool had_child_signal = signal_flare.Extinguish(); @@ -270,19 +272,19 @@ void zeek::Supervisor::HandleChildSignal() } } -void zeek::Supervisor::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, +void Supervisor::GetFds(iosource::FD_Set* read, iosource::FD_Set* write, iosource::FD_Set* except) { read->Insert(signal_flare.FD()); read->Insert(stem_pipe->InFD()); } -double zeek::Supervisor::NextTimestamp(double* local_network_time) +double Supervisor::NextTimestamp(double* local_network_time) { return timer_mgr->Time(); } -void zeek::Supervisor::Process() +void Supervisor::Process() { HandleChildSignal(); @@ -357,7 +359,7 @@ void Stem::Reap() } } -bool Stem::Wait(zeek::Supervisor::Node* node, int options) const +bool Stem::Wait(Supervisor::Node* node, int options) const { int status; auto res = waitpid(node->pid, &status, options); @@ -394,7 +396,7 @@ bool Stem::Wait(zeek::Supervisor::Node* node, int options) const return true; } -void Stem::KillNode(const zeek::Supervisor::Node& node, int signal) const +void Stem::KillNode(const Supervisor::Node& node, int signal) const { auto kill_res = kill(node.pid, signal); @@ -403,7 +405,7 @@ void Stem::KillNode(const zeek::Supervisor::Node& node, int signal) const node.name.data(), strerror(errno)); } -void Stem::Destroy(zeek::Supervisor::Node* node) const +void Stem::Destroy(Supervisor::Node* node) const { constexpr auto max_term_attempts = 13; constexpr auto kill_delay = 2; @@ -424,7 +426,7 @@ void Stem::Destroy(zeek::Supervisor::Node* node) const } } -zeek::Supervisor::Node* Stem::Revive() +Supervisor::Node* Stem::Revive() { constexpr auto attempts_before_delay_increase = 3; constexpr auto delay_increase_factor = 2; @@ -459,7 +461,7 @@ zeek::Supervisor::Node* Stem::Revive() node.revival_delay *= delay_increase_factor; if ( Spawn(&node) ) - return new zeek::Supervisor::Node(node); + return new Supervisor::Node(node); ReportStatus(node); } @@ -467,7 +469,7 @@ zeek::Supervisor::Node* Stem::Revive() return {}; } -bool Stem::Spawn(zeek::Supervisor::Node* node) +bool Stem::Spawn(Supervisor::Node* node) { auto node_pid = fork(); @@ -552,13 +554,13 @@ void Stem::Shutdown(int exit_code) } } -void Stem::ReportStatus(const zeek::Supervisor::Node& node) const +void Stem::ReportStatus(const Supervisor::Node& node) const { std::string msg = fmt("status %s %d", node.name.data(), node.pid); safe_write(pipe->OutFD(), msg.data(), msg.size() + 1); } -zeek::Supervisor::Node* Stem::Run() +Supervisor::Node* Stem::Run() { for ( ; ; ) { @@ -571,7 +573,7 @@ zeek::Supervisor::Node* Stem::Run() return {}; } -zeek::Supervisor::Node* Stem::Poll() +Supervisor::Node* Stem::Poll() { pollfd fds[2] = { { pipe->InFD(), POLLIN, 0 }, { signal_flare->FD(), POLLIN, 0} }; @@ -650,10 +652,10 @@ zeek::Supervisor::Node* Stem::Poll() { const auto& node_json = msg_tokens[2]; assert(nodes.find(node_name) == nodes.end()); - auto node = zeek::Supervisor::Node::FromJSON(node_json); + auto node = Supervisor::Node::FromJSON(node_json); if ( Spawn(&node) ) - return new zeek::Supervisor::Node(node); + return new Supervisor::Node(node); // TODO: get stem printfs going through standard Zeek debug.log printf("Stem created node: %s (%d)\n", node.name.data(), node.pid); @@ -678,7 +680,7 @@ zeek::Supervisor::Node* Stem::Poll() Destroy(&node); if ( Spawn(&node) ) - return new zeek::Supervisor::Node(node); + return new Supervisor::Node(node); ReportStatus(node); } @@ -689,7 +691,7 @@ zeek::Supervisor::Node* Stem::Poll() return {}; } -zeek::Supervisor::Node* zeek::Supervisor::RunStem(std::unique_ptr pipe) +Supervisor::Node* Supervisor::RunStem(std::unique_ptr pipe) { Stem s(std::move(pipe)); return s.Run(); @@ -709,9 +711,9 @@ static BifEnum::Supervisor::ClusterRole role_str_to_enum(const std::string& r) return BifEnum::Supervisor::NONE; } -zeek::Supervisor::Node zeek::Supervisor::Node::FromRecord(const RecordVal* node) +Supervisor::Node Supervisor::Node::FromRecord(const RecordVal* node) { - zeek::Supervisor::Node rval; + Supervisor::Node rval; rval.name = node->Lookup("name")->AsString()->CheckString(); auto iface_val = node->Lookup("interface"); @@ -726,12 +728,11 @@ zeek::Supervisor::Node zeek::Supervisor::Node::FromRecord(const RecordVal* node) while ( (v = cluster_table->NextEntry(k, c)) ) { - auto key = cluster_table_val->RecoverIndex(k); + IntrusivePtr key{cluster_table_val->RecoverIndex(k), false}; auto name = key->Index(0)->AsStringVal()->ToStdString(); - Unref(key); auto rv = v->Value()->AsRecordVal(); - zeek::Supervisor::ClusterEndpoint ep; + Supervisor::ClusterEndpoint ep; ep.role = static_cast(rv->Lookup("role")->AsEnum()); ep.host = rv->Lookup("host")->AsAddr().AsString(); ep.port = rv->Lookup("p")->AsPortVal()->Port(); @@ -747,9 +748,9 @@ zeek::Supervisor::Node zeek::Supervisor::Node::FromRecord(const RecordVal* node) return rval; } -zeek::Supervisor::Node zeek::Supervisor::Node::FromJSON(const std::string& json) +Supervisor::Node Supervisor::Node::FromJSON(const std::string& json) { - zeek::Supervisor::Node rval; + Supervisor::Node rval; auto j = nlohmann::json::parse(json); rval.name = j["name"]; @@ -784,27 +785,23 @@ zeek::Supervisor::Node zeek::Supervisor::Node::FromJSON(const std::string& json) return rval; } -std::string zeek::Supervisor::Node::ToJSON() const +std::string Supervisor::Node::ToJSON() const { - auto re = new RE_Matcher("^_"); + auto re = std::make_unique("^_"); auto node_val = ToRecord(); - auto json_val = node_val->ToJSON(false, re); + IntrusivePtr json_val{node_val->ToJSON(false, re.get()), false}; auto rval = json_val->ToStdString(); - delete re; - Unref(node_val); - Unref(json_val); return rval; } -RecordVal* zeek::Supervisor::Node::ToRecord() const +IntrusivePtr Supervisor::Node::ToRecord() const { auto rt = BifType::Record::Supervisor::Node; - auto rval = new RecordVal(rt); + auto rval = make_intrusive(rt); rval->Assign(rt->FieldOffset("name"), new StringVal(name)); - if ( ! interface.empty() ) - rval->Assign(rt->FieldOffset("interface"), - new StringVal(interface)); + if ( interface ) + rval->Assign(rt->FieldOffset("interface"), new StringVal(*interface)); auto tt = BifType::Record::Supervisor::Node->FieldType("cluster"); auto cluster_val = new TableVal(tt->AsTableType()); @@ -814,19 +811,18 @@ RecordVal* zeek::Supervisor::Node::ToRecord() const { auto& name = e.first; auto& ep = e.second; - auto key = new StringVal(name); + auto key = make_intrusive(name); auto ept = BifType::Record::Supervisor::ClusterEndpoint; - auto val = new RecordVal(ept); + auto val = make_intrusive(ept); val->Assign(ept->FieldOffset("role"), BifType::Enum::Supervisor::ClusterRole->GetVal(ep.role)); val->Assign(ept->FieldOffset("host"), new AddrVal(ep.host)); val->Assign(ept->FieldOffset("p"), val_mgr->GetPort(ep.port, TRANSPORT_TCP)); - if ( ! ep.interface.empty() ) - val->Assign(ept->FieldOffset("interface"), new StringVal(ep.interface)); + if ( ep.interface ) + val->Assign(ept->FieldOffset("interface"), new StringVal(*ep.interface)); - cluster_val->Assign(key, val); - Unref(key); + cluster_val->Assign(key.get(), val.detach()); } if ( pid ) @@ -853,14 +849,14 @@ static Val* supervisor_role_to_cluster_node_type(BifEnum::Supervisor::ClusterRol } } -void zeek::Supervisor::Node::InitCluster() +void Supervisor::Node::InitCluster() { auto cluster_node_type = global_scope()->Lookup("Cluster::Node")->AsType()->AsRecordType(); auto cluster_nodes_id = global_scope()->Lookup("Cluster::nodes"); auto cluster_manager_is_logger_id = global_scope()->Lookup("Cluster::manager_is_logger"); auto cluster_nodes = cluster_nodes_id->ID_Val()->AsTableVal(); auto has_logger = false; - std::string manager_name; + std::optional manager_name; for ( const auto& e : supervised_node->cluster ) { @@ -874,30 +870,29 @@ void zeek::Supervisor::Node::InitCluster() { const auto& node_name = e.first; const auto& ep = e.second; - auto key = new StringVal(node_name); - auto val = new RecordVal(cluster_node_type); + auto key = make_intrusive(node_name); + auto val = make_intrusive(cluster_node_type); auto node_type = supervisor_role_to_cluster_node_type(ep.role); val->Assign(cluster_node_type->FieldOffset("node_type"), node_type); val->Assign(cluster_node_type->FieldOffset("ip"), new AddrVal(ep.host)); val->Assign(cluster_node_type->FieldOffset("p"), val_mgr->GetPort(ep.port, TRANSPORT_TCP)); - if ( ! ep.interface.empty() ) + if ( ep.interface ) val->Assign(cluster_node_type->FieldOffset("interface"), - new StringVal(ep.interface)); + new StringVal(*ep.interface)); - if ( ! manager_name.empty() && ep.role != BifEnum::Supervisor::MANAGER ) + if ( manager_name && ep.role != BifEnum::Supervisor::MANAGER ) val->Assign(cluster_node_type->FieldOffset("manager"), - new StringVal(manager_name)); + new StringVal(*manager_name)); - cluster_nodes->Assign(key, val); - Unref(key); + cluster_nodes->Assign(key.get(), val.detach()); } cluster_manager_is_logger_id->SetVal(val_mgr->GetBool(! has_logger)); } -RecordVal* zeek::Supervisor::Status(const std::string& node_name) +RecordVal* Supervisor::Status(const std::string& node_name) { // TODO: handle node classes auto rval = new RecordVal(BifType::Record::Supervisor::Status); @@ -908,22 +903,21 @@ RecordVal* zeek::Supervisor::Status(const std::string& node_name) for ( const auto& n : nodes ) { const auto& node = n.second; - auto key = new StringVal(node.name); + auto key = make_intrusive(node.name); auto val = node.ToRecord(); - node_table_val->Assign(key, val); - Unref(key); + node_table_val->Assign(key.get(), val.detach()); } return rval; } -std::string zeek::Supervisor::Create(const RecordVal* node_val) +std::string Supervisor::Create(const RecordVal* node_val) { - auto node = zeek::Supervisor::Node::FromRecord(node_val); + auto node = Supervisor::Node::FromRecord(node_val); return Create(node); } -std::string zeek::Supervisor::Create(const zeek::Supervisor::Node& node) +std::string Supervisor::Create(const Supervisor::Node& node) { if ( node.name.find(' ') != std::string::npos ) return fmt("node names must not contain spaces: '%s'", @@ -938,7 +932,7 @@ std::string zeek::Supervisor::Create(const zeek::Supervisor::Node& node) return ""; } -bool zeek::Supervisor::Destroy(const std::string& node_name) +bool Supervisor::Destroy(const std::string& node_name) { // TODO: handle node classes @@ -950,7 +944,7 @@ bool zeek::Supervisor::Destroy(const std::string& node_name) return true; } -bool zeek::Supervisor::Restart(const std::string& node_name) +bool Supervisor::Restart(const std::string& node_name) { // TODO: handle node classes diff --git a/src/Supervisor.h b/src/Supervisor.h index 198a751913..543ff8a89e 100644 --- a/src/Supervisor.h +++ b/src/Supervisor.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -13,6 +14,7 @@ #include "Pipe.h" #include "Flare.h" #include "NetVar.h" +#include "IntrusivePtr.h" namespace zeek { @@ -29,7 +31,7 @@ public: BifEnum::Supervisor::ClusterRole role; std::string host; int port; - std::string interface; + std::optional interface; }; struct Node { @@ -39,10 +41,10 @@ public: static void InitCluster(); std::string ToJSON() const; - RecordVal* ToRecord() const; + IntrusivePtr ToRecord() const; std::string name; - std::string interface; + std::optional interface; std::map cluster; pid_t pid = 0; diff --git a/src/main.cc b/src/main.cc index 764b129344..091a3ac33d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef HAVE_GETOPT_H #include #endif @@ -219,11 +220,11 @@ struct zeek_options { bool print_signature_debug_info = false; int print_plugins = 0; - std::string debug_log_streams; - std::string debug_script_tracing_file; + std::optional debug_log_streams; + std::optional debug_script_tracing_file; - std::string identifier_to_print; - std::string script_code_to_exec; + std::optional identifier_to_print; + std::optional script_code_to_exec; std::vector script_prefixes = { "" }; // "" = "no prefix" int supervised_workers = 0; @@ -239,16 +240,16 @@ struct zeek_options { bool perftools_check_leaks = false; bool perftools_profile = false; - std::string pcap_filter; + std::optional pcap_filter; std::vector interfaces; std::vector pcap_files; std::vector signature_files; - std::string pcap_output_file; - std::string random_seed_input_file; - std::string random_seed_output_file; - std::string process_status_file; - std::string zeekygen_config_file; + std::optional pcap_output_file; + std::optional random_seed_input_file; + std::optional random_seed_output_file; + std::optional process_status_file; + std::optional zeekygen_config_file; std::string libidmef_dtd_file = "idmef-message.dtd"; std::set plugins_to_load; @@ -329,12 +330,7 @@ static zeek_options parse_cmdline(int argc, char** argv) rval.debug_scripts = true; break; case 'e': - if ( optarg[0] == 0 ) - // Cheating a bit, but allows checking for an empty string - // to determine whether -e was used or not. - rval.script_code_to_exec = " "; - else - rval.script_code_to_exec = optarg; + rval.script_code_to_exec = optarg; break; case 'f': rval.pcap_filter = optarg; @@ -681,7 +677,7 @@ static std::vector get_script_signature_files() return rval; } -static std::string get_exe_path(std::string invocation) +static std::string get_exe_path(const std::string& invocation) { if ( invocation.empty() ) return ""; @@ -792,8 +788,8 @@ int main(int argc, char** argv) options = {}; const auto& node_name = zeek::supervised_node->name; - if ( ! zeek::supervised_node->interface.empty() ) - options.interfaces.emplace_back(zeek::supervised_node->interface); + if ( zeek::supervised_node->interface ) + options.interfaces.emplace_back(*zeek::supervised_node->interface); if ( ! zeek::supervised_node->cluster.empty() ) { @@ -838,17 +834,17 @@ int main(int argc, char** argv) fprintf(stderr, "Zeek script debugging ON.\n"); } - if ( ! options.script_code_to_exec.empty() ) - command_line_policy = options.script_code_to_exec.data(); + if ( options.script_code_to_exec ) + command_line_policy = options.script_code_to_exec->data(); - if ( ! options.debug_script_tracing_file.empty() ) + if ( options.debug_script_tracing_file ) { - g_trace_state.SetTraceFile(options.debug_script_tracing_file.data()); + g_trace_state.SetTraceFile(options.debug_script_tracing_file->data()); g_trace_state.TraceOn(); } - if ( ! options.process_status_file.empty() ) - proc_status_file = options.process_status_file.data(); + if ( options.process_status_file ) + proc_status_file = options.process_status_file->data(); atexit(atexit_handler); set_processing_status("INITIALIZING", "main"); @@ -862,9 +858,9 @@ int main(int argc, char** argv) plugin_mgr = new plugin::Manager(); #ifdef DEBUG - if ( ! options.debug_log_streams.empty() ) + if ( options.debug_log_streams ) { - debug_logger.EnableStreams(options.debug_log_streams.data()); + debug_logger.EnableStreams(options.debug_log_streams->data()); const char* debug_log_name = nullptr; if ( ! getenv("ZEEK_DEBUG_LOG_STDERR") ) @@ -896,11 +892,11 @@ int main(int argc, char** argv) const char* seed_load_file = zeekenv("ZEEK_SEED_FILE"); - if ( ! options.random_seed_input_file.empty() ) - seed_load_file = options.random_seed_input_file.data(); + if ( options.random_seed_input_file ) + seed_load_file = options.random_seed_input_file->data(); init_random_seed((seed_load_file && *seed_load_file ? seed_load_file : 0), - options.random_seed_output_file.empty() ? 0 : options.random_seed_output_file.data()); + options.random_seed_output_file ? options.random_seed_output_file->data() : 0); // DEBUG_MSG("HMAC key: %s\n", md5_digest_print(shared_hmac_md5_key)); init_hash_function(); @@ -929,8 +925,8 @@ int main(int argc, char** argv) timer_mgr = new PQ_TimerMgr(""); // timer_mgr = new CQ_TimerMgr(); - zeekygen_mgr = new zeekygen::Manager(options.zeekygen_config_file, - bro_argv[0]); + auto zeekygen_cfg = options.zeekygen_config_file.value_or(""); + zeekygen_mgr = new zeekygen::Manager(zeekygen_cfg, bro_argv[0]); add_essential_input_file("base/init-bare.zeek"); add_essential_input_file("base/init-frameworks-and-bifs.zeek"); @@ -944,7 +940,7 @@ int main(int argc, char** argv) options.script_options_to_set.empty() && options.pcap_files.size() == 0 && options.interfaces.size() == 0 && - options.identifier_to_print.empty() && + ! options.identifier_to_print && ! command_line_policy && ! options.print_plugins && ! use_supervisor() && ! zeek::supervised_node ) add_input_file("-"); @@ -1077,14 +1073,14 @@ int main(int argc, char** argv) reporter->InitOptions(); zeekygen_mgr->GenerateDocs(); - if ( ! options.pcap_filter.empty() ) + if ( options.pcap_filter ) { ID* id = global_scope()->Lookup("cmd_line_bpf_filter"); if ( ! id ) reporter->InternalError("global cmd_line_bpf_filter not defined"); - id->SetVal(new StringVal(options.pcap_filter)); + id->SetVal(new StringVal(*options.pcap_filter)); } auto all_signature_files = options.signature_files; @@ -1164,11 +1160,11 @@ int main(int argc, char** argv) } // Print the ID. - if ( ! options.identifier_to_print.empty() ) + if ( options.identifier_to_print ) { - ID* id = global_scope()->Lookup(options.identifier_to_print); + ID* id = global_scope()->Lookup(*options.identifier_to_print); if ( ! id ) - reporter->FatalError("No such ID: %s\n", options.identifier_to_print.data()); + reporter->FatalError("No such ID: %s\n", options.identifier_to_print->data()); ODesc desc; desc.SetQuotes(true);