]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #5218: File names
authorRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 17 Mar 2026 17:31:58 +0000 (17:31 +0000)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 17 Mar 2026 17:31:58 +0000 (17:31 +0000)
Merge in SNORT/snort3 from ~RUCOMBS/snort3:file_names to master

Squashed commit of the following:

commit 3be526f4dbeb5c81b852143c0536adcdc9990ca3
Author: Russ Combs <rucombs@cisco.com>
Date:   Thu Mar 12 12:49:03 2026 -0400

    file names: add unit tests for get_main_file and get_instance_file

commit b2c17a8fe4a4ba44f51d2b3d03a46fcb6ec0307c
Author: Russ Combs <rucombs@cisco.com>
Date:   Thu Mar 12 08:01:51 2026 -0400

    logs: do not add / to run prefix for main thread logs

    Also, do not fatal error when trace.set fails.

src/framework/pig_pen.cc
src/framework/pig_pen.h
src/main.cc
src/main.h
src/main/test/CMakeLists.txt
src/main/test/thread_test.cc [new file with mode: 0644]
src/main/thread.cc
src/tracer/file_trace_logger.cc

index 7f2988f4df2a89563a10e6afaf162bf5c15bc32d..95ac414ff9029465c45aff3eb14fb42cb6fa1d39 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "detection/detection_engine.h"
 #include "log/log.h"
+#include "main.h"
 #include "main/process.h"
 #include "main/snort.h"
 #include "main/snort_config.h"
@@ -80,6 +81,9 @@ void PigPen::release(Inspector* pi)
 // process foo
 //--------------------------------------------------------------------------
 
+bool PigPen::snort_started()
+{ return main_snort_started(); }
+
 bool PigPen::snort_is_reloading()
 { return Snort::is_reloading(); }
 
index 8b0b7d647ba767f597e515f978fd809dcfd04796..3c5f27acdab5cfa91f043737eee9b5a4654caf0c 100644 (file)
@@ -57,6 +57,7 @@ struct SO_PUBLIC PigPen
     static void release(Inspector*);
 
     // process foo
+    static bool snort_started();
     static bool snort_is_reloading();
     static void open_syslog();
     static void close_syslog();
index 5ed6f77445d71cbb16ba951007e860c264b8ae32..de26f1599ee0bb0f008d12ed645a6315c94af8ab 100644 (file)
@@ -112,6 +112,9 @@ static bool use_shell(const SnortConfig* sc)
 #endif
 }
 
+bool main_snort_started()
+{ return pthreads_started; }
+
 // FIXIT-L X Replace main_poke()/main_read() usage with command objects
 void main_poke(unsigned id)
 {
index 834c7baa83d7dc9ab0b9301701386ff9a63188ed..77e73fd127748674b713a27c8f432e83f22ea4ab 100644 (file)
@@ -24,6 +24,7 @@
 struct lua_State;
 extern bool exit_requested;
 const char* get_prompt();
+bool main_snort_started();
 
 // commands provided by the snort module
 int main_delete_inspector(lua_State* = nullptr);
index 7338bc281948fcb8b355723d0d8f9c073c2f4533..38bafedbc86ae662663e0581760eabe2c4b22f36 100644 (file)
@@ -1,3 +1,8 @@
+add_cpputest(thread_test
+    SOURCES
+        ../thread.cc
+)
+
 if ( ENABLE_SHELL )
     add_cpputest(distill_verdict_test
         SOURCES
diff --git a/src/main/test/thread_test.cc b/src/main/test/thread_test.cc
new file mode 100644 (file)
index 0000000..77b5822
--- /dev/null
@@ -0,0 +1,442 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2026 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "main/snort.h"
+#include "main/snort_config.h"
+#include "main/thread.h"
+#include "main/thread_config.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+
+//-------------------------------------------------------------------------
+// stubs
+//-------------------------------------------------------------------------
+
+static unsigned s_instance_max = 1;
+
+namespace snort
+{
+static SnortConfig snort_conf;
+
+SnortConfig::SnortConfig(const char*)
+{
+    daq_config = nullptr;
+    thread_config = nullptr;
+}
+
+SnortConfig::~SnortConfig() = default;
+
+const SnortConfig* SnortConfig::get_conf()
+{ return &snort_conf; }
+
+void ParseError(const char*, ...) { }
+
+const char* get_error(int)
+{ return ""; }
+
+unsigned ThreadConfig::get_instance_max()
+{ return s_instance_max; }
+
+int ThreadConfig::get_instance_tid(int)
+{ return 0; }
+
+unsigned Snort::get_process_id()
+{ return 0; }
+} // namespace snort
+
+using namespace snort;
+
+//-------------------------------------------------------------------------
+// helpers
+//-------------------------------------------------------------------------
+
+static void reset_conf()
+{
+    snort_conf.log_dir.clear();
+    snort_conf.run_prefix.clear();
+    snort_conf.id_offset = 0;
+    snort_conf.id_subdir = false;
+    snort_conf.id_zero = false;
+    s_instance_max = 1;
+    set_instance_id(0);
+}
+
+//-------------------------------------------------------------------------
+// get_instance_file tests
+//-------------------------------------------------------------------------
+
+TEST_GROUP(get_instance_file_tests)
+{
+    void setup() override { reset_conf(); }
+};
+
+TEST(get_instance_file_tests, default_path)
+{
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./name", file.c_str());
+}
+
+TEST(get_instance_file_tests, log_dir)
+{
+    snort_conf.log_dir = "/tmp/logs/";
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/logs/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, log_dir_no_trailing_slash)
+{
+    snort_conf.log_dir = "/tmp/logs";
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/logs/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix)
+{
+    snort_conf.run_prefix = "snort";
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./snort_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, multi_thread)
+{
+    s_instance_max = 4;
+    set_instance_id(2);
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./2_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, id_zero)
+{
+    snort_conf.id_zero = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./0_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, id_offset)
+{
+    s_instance_max = 2;
+    snort_conf.id_offset = 10;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./10_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix_multi_thread)
+{
+    snort_conf.run_prefix = "p";
+    s_instance_max = 2;
+    set_instance_id(1);
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./p1_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, id_subdir)
+{
+    snort_conf.log_dir = "/tmp";
+    s_instance_max = 2;
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/0/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, log_dir_run_prefix)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.run_prefix = "p";
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/p_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, log_dir_id_zero)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.id_zero = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/0_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, log_dir_run_prefix_multi_thread)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.run_prefix = "p";
+    s_instance_max = 2;
+    set_instance_id(1);
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/p1_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix_id_zero)
+{
+    snort_conf.run_prefix = "p";
+    snort_conf.id_zero = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./p0_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix_id_offset)
+{
+    snort_conf.run_prefix = "p";
+    s_instance_max = 2;
+    snort_conf.id_offset = 10;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./p10_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix_id_subdir)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.run_prefix = "p";
+    s_instance_max = 2;
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/p0/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, id_zero_id_offset)
+{
+    snort_conf.id_zero = true;
+    snort_conf.id_offset = 10;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./10_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, id_subdir_id_zero)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.id_zero = true;
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/0/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, multi_thread_id_offset_nonzero_id)
+{
+    s_instance_max = 4;
+    set_instance_id(2);
+    snort_conf.id_offset = 10;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./12_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, id_offset_id_subdir)
+{
+    snort_conf.log_dir = "/tmp";
+    s_instance_max = 2;
+    snort_conf.id_offset = 10;
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/10/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix_id_zero_id_offset)
+{
+    snort_conf.run_prefix = "p";
+    snort_conf.id_zero = true;
+    snort_conf.id_offset = 10;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("./p10_name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix_id_zero_id_subdir)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.run_prefix = "p";
+    snort_conf.id_zero = true;
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/p0/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix_id_offset_id_subdir)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.run_prefix = "p";
+    s_instance_max = 2;
+    snort_conf.id_offset = 10;
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/p10/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, id_zero_id_offset_id_subdir)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.id_zero = true;
+    snort_conf.id_offset = 10;
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/10/name", file.c_str());
+}
+
+TEST(get_instance_file_tests, run_prefix_id_zero_id_offset_id_subdir)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.run_prefix = "p";
+    snort_conf.id_zero = true;
+    snort_conf.id_offset = 10;
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_instance_file(file, "name");
+    STRCMP_EQUAL("/tmp/p10/name", file.c_str());
+}
+
+//-------------------------------------------------------------------------
+// get_main_file tests
+//-------------------------------------------------------------------------
+
+TEST_GROUP(get_main_file_tests)
+{
+    void setup() override { reset_conf(); }
+};
+
+TEST(get_main_file_tests, default_path)
+{
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("./main_name", file.c_str());
+}
+
+TEST(get_main_file_tests, log_dir)
+{
+    snort_conf.log_dir = "/tmp/logs/";
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("/tmp/logs/main_name", file.c_str());
+}
+
+TEST(get_main_file_tests, log_dir_no_trailing_slash)
+{
+    snort_conf.log_dir = "/tmp/logs";
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("/tmp/logs/main_name", file.c_str());
+}
+
+TEST(get_main_file_tests, run_prefix)
+{
+    snort_conf.run_prefix = "snort";
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("./snortmain_name", file.c_str());
+}
+
+TEST(get_main_file_tests, id_zero)
+{
+    snort_conf.id_zero = true;
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("./name", file.c_str());
+}
+
+TEST(get_main_file_tests, run_prefix_id_zero)
+{
+    snort_conf.run_prefix = "snort";
+    snort_conf.id_zero = true;
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("./snortname", file.c_str());
+}
+
+TEST(get_main_file_tests, log_dir_run_prefix)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.run_prefix = "p";
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("/tmp/pmain_name", file.c_str());
+}
+
+TEST(get_main_file_tests, log_dir_id_zero)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.id_zero = true;
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("/tmp/name", file.c_str());
+}
+
+TEST(get_main_file_tests, log_dir_run_prefix_id_zero)
+{
+    snort_conf.log_dir = "/tmp";
+    snort_conf.run_prefix = "p";
+    snort_conf.id_zero = true;
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("/tmp/pname", file.c_str());
+}
+
+TEST(get_main_file_tests, id_offset_ignored)
+{
+    snort_conf.id_offset = 10;
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("./main_name", file.c_str());
+}
+
+TEST(get_main_file_tests, id_subdir_ignored)
+{
+    snort_conf.id_subdir = true;
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("./main_name", file.c_str());
+}
+
+TEST(get_main_file_tests, multi_thread_ignored)
+{
+    s_instance_max = 4;
+    set_instance_id(2);
+    std::string file;
+    get_main_file(file, "name");
+    STRCMP_EQUAL("./main_name", file.c_str());
+}
+
+//-------------------------------------------------------------------------
+// main
+//-------------------------------------------------------------------------
+
+int main(int argc, char** argv)
+{
+    return CommandLineTestRunner::RunAllTests(argc, argv);
+}
index 8819abcbf0bc9e94922a55ac603c2ebdf4a941ef..9684ff75f190e604e1288054b34be453da94c99c 100644 (file)
@@ -179,10 +179,7 @@ const char* get_main_file(std::string& file, const char* name)
         file += '/';
 
     if ( !sc->run_prefix.empty() )
-    {
         file += sc->run_prefix;
-        file += '/';
-    }
 
     if ( !sc->id_zero )
         file += "main_";
index 092de87808442796e99afd01f56e5fa3e78cd5d8..5773eb2798ee76511014be8c7b623775f5dcd4f8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "file_trace_logger.h"
 
+#include "framework/pig_pen.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "main/thread.h"
@@ -65,7 +66,8 @@ FileTrace::FileTrace(const FileTraceConfig& cfg) :
     TraceLoggerPlug("file_trace"),
     config(cfg)
 {
-    text_log = TextLog_Init(TRACE_FILE_NAME, BUFFER_SIZE, config.max_file_size);
+    bool crit = !PigPen::snort_started();
+    text_log = TextLog_Init(TRACE_FILE_NAME, BUFFER_SIZE, config.max_file_size, crit);
 }
 
 FileTrace::~FileTrace()