to_server = telnet_commands, to_client = telnet_commands },
}
}
-
return m;
}
-const std::string& Markup::sanitize(const char* const c)
-{ return sanitize(std::string(c)); }
+const string& Markup::sanitize(const char* const c)
+{ return sanitize(string(c)); }
-const std::string& Markup::sanitize(const std::string& s)
+const string& Markup::sanitize(const string& s)
{
const char* const asciidoc_chars = "~*<>^'";
- static std::string m;
+ static string m;
m.clear();
m += s;
if (enabled)
{
- for (std::size_t found = m.find_first_of(asciidoc_chars, 0);
- found != std::string::npos;
+ for (size_t found = m.find_first_of(asciidoc_chars, 0);
+ found != string::npos;
found = m.find_first_of(asciidoc_chars, found))
{
m.insert(found, "\\");
set_instance_id(id);
ps->apply();
+ pin_thread_to_cpu(source);
snort_thread_init(source);
analyze();
#include "filters/detection_filter.h"
#include "filters/sfthreshold.h"
#include "sfip/sf_ip.h"
+#include "main/thread.h"
#if defined(DEBUG_MSGS) || defined (REG_TEST)
#include "file_api/file_api.h"
// process module
//-------------------------------------------------------------------------
+static const Parameter thread_pinning_params[] =
+{
+ { "cpu", Parameter::PT_INT, "0:127", nullptr,
+ "pin the associated source/thread to this cpu"},
+
+ { "source", Parameter::PT_STRING, nullptr, nullptr,
+ "set cpu affinity for this source (either pcap or <iface>"},
+
+ { "thread", Parameter::PT_INT, "0:", nullptr,
+ "set cpu affinity for the <cur_thread_num> thread that runs"},
+};
+
static const Parameter process_params[] =
{
{ "chroot", Parameter::PT_STRING, nullptr, nullptr,
"set chroot directory (same as -t)" },
+ { "threads", Parameter::PT_LIST, thread_pinning_params, nullptr,
+ "thread pinning parameters"},
+
{ "daemon", Parameter::PT_BOOL, nullptr, "false",
"fork as a daemon (same as -D)" },
public:
ProcessModule() : Module("process", process_help, process_params) { };
bool set(const char*, Value&, SnortConfig*);
+ bool begin(const char*, int, SnortConfig*);
+ bool end(const char*, int, SnortConfig*);
+
+private:
+ std::string source;
+ int thread;
+ int cpu;
};
bool ProcessModule::set(const char*, Value& v, SnortConfig* sc)
if ( v.get_bool() )
ConfigUtc(sc, "");
}
+
+ else if (v.is("cpu"))
+ cpu = v.get_long();
+
+ else if (v.is("source"))
+ source = v.get_string();
+
+ else if (v.is("thread"))
+ thread = v.get_long();
+
else
return false;
return true;
}
+bool ProcessModule::begin(const char*, int, SnortConfig*)
+{
+ source.clear();
+ thread = -1;
+ cpu = -1;
+ return true;
+}
+
+bool ProcessModule::end(const char* fqn, int idx, SnortConfig* sc)
+{
+ if ( !idx )
+ return true;
+
+ if (!strcmp(fqn, "process.threads"))
+ {
+ if (cpu == -1)
+ ParseError("%s - cpu must be an integer in the range"
+ " of 0 < cpu < max_cpus", fqn, cpu);
+
+ else if (cpu >= CPU_SETSIZE)
+ ParseError("cpu must be between 0 and %d", INT8_MAX);
+
+ else if ((source.empty()) && (thread == -1))
+ ParseError("%s - must have either a source or a thread!", fqn);
+
+ else if ((!source.empty()) && (thread >= 0))
+ ParseError("%s - must have either a source or a thread!"
+ " Both thread(%d) and source(%s) are set", fqn, thread, source.c_str());
+
+ else if (!source.empty())
+ set_cpu_affinity(sc, source, cpu);
+
+ else
+ set_cpu_affinity(sc, thread, cpu);
+ }
+
+ return true;
+}
+
//-------------------------------------------------------------------------
// file_id module
//-------------------------------------------------------------------------
/* D A T A S T R U C T U R E S *********************************************/
-typedef enum _RunFlag
+enum RunFlag
{
RUN_FLAG__READ = 0x00000001, /* -r --pcap-dir, etc. */
RUN_FLAG__DAEMON = 0x00000002, /* -D */
RUN_FLAG__SHELL = 0x40000000, /* --shell */
RUN_FLAG__TEST = 0x80000000 /* -T */
-} RunFlag;
+};
-typedef enum _OutputFlag
+enum OutputFlag
{
OUTPUT_FLAG__LINE_BUFFER = 0x00000001, /* -f */
OUTPUT_FLAG__VERBOSE_DUMP = 0x00000002, /* -X */
OUTPUT_FLAG__NO_ALERT = 0x00001000, /* -A none */
OUTPUT_FLAG__NO_LOG = 0x00002000, /* -K none */
-} OutputFlag;
+};
-typedef enum _LoggingFlag
+enum LoggingFlag
{
LOGGING_FLAG__VERBOSE = 0x00000001, /* -v */
LOGGING_FLAG__QUIET = 0x00000002, /* -q */
LOGGING_FLAG__SYSLOG = 0x00000004 /* -M */
-} LoggingFlag;
+};
-typedef enum {
+enum TunnelFlags{
TUNNEL_GTP = 0x01,
TUNNEL_TEREDO = 0x02,
TUNNEL_6IN4 = 0x04,
TUNNEL_4IN6 = 0x08
-} TunnelFlags;
+};
/* E X T E R N S ************************************************************/
SO_PUBLIC extern THREAD_LOCAL SnortConfig* snort_conf;
set_inspection_policy(sc->get_inspection_policy());
set_ips_policy(sc->get_ips_policy());
set_network_policy(sc->get_network_policy());
+
+
+ sc->source_affinity = new std::map<const std::string, int>;
+ sc->thread_affinity = new std::vector<int>(32, -1);
+
return sc;
}
delete sc->policy_map;
free(sc->state);
+
+ if (sc->source_affinity)
+ delete sc->source_affinity;
+
+ if (sc->thread_affinity)
+ delete sc->thread_affinity;
+
free(sc);
}
#include "config.h"
#endif
+#include <vector>
+#include <map>
#include <sys/stat.h>
#include "detection/rules.h"
#include "sfip/sfip_t.h"
bool unit_test;
#endif
+
+ std::map<const std::string, int>* source_affinity;
+ std::vector<int>* thread_affinity;
+
InspectionPolicy* get_inspection_policy()
{ return policy_map->inspection_policy[0]; };
*/
// thread.cc author Russ Combs <rucombs@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include "thread.h"
+#ifdef LINUX
+# include <sched.h>
+#endif
+
#include <sys/stat.h>
#include <thread>
-#include "snort.h"
+#include <vector>
+
+#include "main/snort.h"
+#include "parser/parser.h"
+
+
//-------------------------------------------------------------------------
// FIXIT-L instance_id zero indicates main thread during parse time and the
static unsigned instance_max = 1;
static THREAD_LOCAL unsigned instance_id = 0;
+static THREAD_LOCAL cpu_set_t cpu_set;
+
+
void set_instance_id(unsigned id)
{
instance_id = id;
return instance_max;
}
+
+
+
+bool set_cpu_affinity(SnortConfig* sc, const std::string& str, int cpu)
+{
+ std::map<const std::string, int>& sa = *(sc->source_affinity);
+
+ auto search = sa.find(str);
+ if(search != sa.end())
+ ParseError("Multiple CPU's set for interface %s", str.c_str());
+
+ sa[std::string(str)] = cpu;
+ return false;
+}
+
+bool set_cpu_affinity(SnortConfig* sc, int thread, int cpu)
+{
+ std::vector<int>& ta = *(sc->thread_affinity);
+
+ if (ta.size() <= (unsigned)thread)
+ {
+ const std::size_t curr_size = ta.size();
+ const std::size_t new_size = curr_size * 2;
+ ta.resize(new_size);
+
+ for (std::size_t i = curr_size; i < new_size; ++i)
+ ta[i] = -1;
+ }
+
+ if (ta[thread] >= 0)
+ ParseError("Multiple CPU's set for thread %d", thread);
+
+ ta[thread] = cpu;
+ return true;
+}
+
+void pin_thread_to_cpu(const char* source)
+{
+ std::vector<int>& ta = *(snort_conf->thread_affinity);
+ std::map<const std::string, int>& sa = *(snort_conf->source_affinity);
+ const std::string src = source;
+ int cpu = -1;
+
+ ta.shrink_to_fit();
+ auto search = sa.find(src);
+
+ if(search != sa.end())
+ {
+ cpu = sa[src];
+ }
+ else if (ta[instance_id] != -1)
+ {
+ cpu = ta[instance_id];
+ }
+
+
+ if (cpu != -1)
+ {
+// PREPROCESSOR MACROS -- these are not actually if statements!
+# if LINUX
+ {
+ CPU_ZERO(&cpu_set);
+ if (cpu >= CPU_SETSIZE)
+ {
+ FatalError("Maximum CPU value for this Operating System is %d",
+ CPU_SETSIZE);
+ }
+
+ CPU_SET(cpu, &cpu_set);
+ sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
+
+ }
+# else
+ {
+ static bool warning_printed = false;
+ if (!warning_printed)
+ {
+ LogWarning("Thread Pinning / CPU affinity support is currently"
+ " unsupported for this Operating System");
+ warning_printed = true;
+ }
+ }
+# endif
+ }
+}
+
//-------------------------------------------------------------------------
// union rules - breaks are mandatory and must be taken in daq thread
//-------------------------------------------------------------------------
void set_instance_id(unsigned);
void set_instance_max(unsigned);
+
+struct SnortConfig;
+bool set_cpu_affinity(SnortConfig*, const std::string&, int cpu);
+bool set_cpu_affinity(SnortConfig*, int thread, int cpu);
+void pin_thread_to_cpu(const char* source);
+
SO_PUBLIC unsigned get_instance_id();
SO_PUBLIC unsigned get_instance_max();
#include "sfdaq.h"
#include "utils/util.h"
-typedef struct _PcapReadObject
+struct PcapReadObject
{
SourceType type;
char *arg;
char *filter;
-} PcapReadObject;
+};
static SF_LIST *pcap_object_list = NULL;
static SF_QUEUE *pcap_queue = NULL;