From 9ac9b91ad4c5a0e36d3d0742770270e14269081c Mon Sep 17 00:00:00 2001 From: Ramon Novoa Date: Mon, 26 Apr 2021 18:49:16 +0200 Subject: [PATCH] Add support for module_wait_timeout. module_wait_timeout lets the user specify the timeout passed to WaitForSingleObject (in milliseconds). Lowering it can greatly improve performance when the executed command generates a lot of output. Ref. pandora_enterprise#7248. --- pandora_agents/win32/modules/pandora_module.cc | 16 ++++++++++++++++ pandora_agents/win32/modules/pandora_module.h | 2 ++ .../win32/modules/pandora_module_exec.cc | 12 +++++------- .../win32/modules/pandora_module_factory.cc | 13 ++++++++++++- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/pandora_agents/win32/modules/pandora_module.cc b/pandora_agents/win32/modules/pandora_module.cc index 549b7d05e1..d5bd1fc21d 100644 --- a/pandora_agents/win32/modules/pandora_module.cc +++ b/pandora_agents/win32/modules/pandora_module.cc @@ -81,6 +81,7 @@ Pandora_Module::Pandora_Module (string name) { this->module_ff_type = ""; this->module_alert_template = ""; this->module_crontab = ""; + this->module_wait_timeout = 500; } /** @@ -1722,3 +1723,18 @@ Pandora_Module::isIntensive () { return true; } + +/** + * Set the WaitForSingleObject timeout. + * + * @param timeout Timeout in milliseconds. + */ +void +Pandora_Module::setWaitTimeout (int timeout) { + + if (timeout < 0) { + return; + } + + this->module_wait_timeout = timeout; +} diff --git a/pandora_agents/win32/modules/pandora_module.h b/pandora_agents/win32/modules/pandora_module.h index 981266ff88..026e539ff1 100644 --- a/pandora_agents/win32/modules/pandora_module.h +++ b/pandora_agents/win32/modules/pandora_module.h @@ -216,6 +216,7 @@ namespace Pandora_Modules { string getDataOutput (Pandora_Data *data); void cleanDataList (); + int module_wait_timeout; public: Pandora_Module (string name); virtual ~Pandora_Module (); @@ -231,6 +232,7 @@ namespace Pandora_Modules { int getInterval (); int getIntensiveInterval (); void setTimeout (int timeout); + void setWaitTimeout (int timeout); int getTimeout (); string getSave (); bool getAsync (); diff --git a/pandora_agents/win32/modules/pandora_module_exec.cc b/pandora_agents/win32/modules/pandora_module_exec.cc index 2ff6b4fe2b..b85ef89d52 100644 --- a/pandora_agents/win32/modules/pandora_module_exec.cc +++ b/pandora_agents/win32/modules/pandora_module_exec.cc @@ -172,7 +172,7 @@ Pandora_Module_Exec::run () { string output; int tickbase = GetTickCount(); - while ( (dwRet = WaitForSingleObject (pi.hProcess, 500)) != WAIT_ABANDONED ) { + while ( (dwRet = WaitForSingleObject (pi.hProcess, this->module_wait_timeout)) != WAIT_ABANDONED ) { PeekNamedPipe (out_read, buffer, BUFSIZE, &read, &avail, NULL); if (avail > 0) { ReadFile (out_read, buffer, BUFSIZE, &read, NULL); @@ -180,11 +180,6 @@ Pandora_Module_Exec::run () { output += (char *) buffer; } - /* Change the output encoding */ - if (this->native_encoding != -1){ - changeOutputEncoding(&output); - } - if (dwRet == WAIT_OBJECT_0) { break; } else if(this->getTimeout() < GetTickCount() - tickbase) { @@ -220,6 +215,10 @@ Pandora_Module_Exec::run () { } // Command output mode else if (!output.empty()) { + /* Change the output encoding */ + if (this->native_encoding != -1){ + changeOutputEncoding(&output); + } this->setOutput (output); } else { this->setOutput (""); @@ -471,4 +470,3 @@ void Pandora_Module_Exec::changeOutputEncoding(string * string_change){ } } - diff --git a/pandora_agents/win32/modules/pandora_module_factory.cc b/pandora_agents/win32/modules/pandora_module_factory.cc index 1cc3938634..022f971388 100644 --- a/pandora_agents/win32/modules/pandora_module_factory.cc +++ b/pandora_agents/win32/modules/pandora_module_factory.cc @@ -124,6 +124,7 @@ using namespace Pandora_Strutils; #define TOKEN_NATIVE_ENCODING ("module_native_encoding") #define TOKEN_ALERT_TEMPLATE ("module_alert_template") #define TOKEN_USER_SESSION ("module_user_session ") +#define TOKEN_WAIT_TIMEOUT ("module_wait_timeout ") string parseLine (string line, string token) { @@ -178,7 +179,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { string module_critical_instructions, module_warning_instructions, module_unknown_instructions, module_tags; string module_critical_inverse, module_warning_inverse, module_quiet, module_ff_interval; string module_native_encoding, module_alert_template, module_ff_type; - string macro; + string macro, module_wait_timeout; Pandora_Module *module; bool numeric; Module_Type type; @@ -260,6 +261,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { module_alert_template = ""; module_user_session = ""; macro = ""; + module_wait_timeout = ""; stringtok (tokens, definition, "\n"); @@ -291,6 +293,9 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { if (module_exec == "") { module_exec = parseLine (line, TOKEN_EXEC); } + if (module_wait_timeout == "") { + module_wait_timeout = parseLine (line, TOKEN_WAIT_TIMEOUT); + } if (module_proc == "") { module_proc = parseLine (line, TOKEN_PROC); } @@ -1130,6 +1135,9 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { if (module_timeout != "") { module->setTimeout (atoi (module_timeout.c_str ())); } + if (module_wait_timeout != "") { + module->setWaitTimeout (atoi (module_wait_timeout.c_str ())); + } } else if (module_proc != "") { module = new Pandora_Module_Proc (module_name, @@ -1230,6 +1238,9 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { if (module_timeout != ""){ module->setTimeout(atoi(module_timeout.c_str())); } + if (module_wait_timeout != "") { + module->setWaitTimeout (atoi (module_wait_timeout.c_str ())); + } } else if (module_ping != "") { if (module_ping_count == "") { module_ping_count = "1";