aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2024-10-13 11:54:15 +0200
committerToni Uhlig <matzeton@googlemail.com>2024-10-16 13:03:41 +0200
commit25e6c67af673c9286a4881399db482a5ebc58d46 (patch)
tree02ee250a7179d54ee01fb81a8d1260f29ec09a23
parent3b5aef2104f200fa4d6c793a3558fd195356de61 (diff)
Added config file support for nDPIsrvd
* adjusted systemd to make use of those Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r--CMakeLists.txt4
-rw-r--r--nDPId-test.c2
-rw-r--r--nDPIsrvd.c146
-rw-r--r--ndpid.conf.example6
-rw-r--r--ndpisrvd.conf.example25
-rw-r--r--packages/systemd/default.cfg2
-rw-r--r--packages/systemd/ndpid@.service.in5
-rw-r--r--packages/systemd/ndpisrvd.service.in7
8 files changed, 164 insertions, 33 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 90ab44042..b8a4d8d67 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -516,7 +516,9 @@ if(ENABLE_SYSTEMD)
configure_file(packages/systemd/ndpisrvd.service.in ndpisrvd.service @ONLY)
configure_file(packages/systemd/ndpid@.service.in ndpid@.service @ONLY)
- install(FILES packages/systemd/default.cfg DESTINATION etc/default RENAME ndpid)
+ install(DIRECTORY DESTINATION etc/nDPId)
+ install(FILES "ndpid.conf.example" DESTINATION share/nDPId)
+ install(FILES "ndpisrvd.conf.example" DESTINATION share/nDPId)
install(FILES "${CMAKE_BINARY_DIR}/ndpisrvd.service" DESTINATION lib/systemd/system)
install(FILES "${CMAKE_BINARY_DIR}/ndpid@.service" DESTINATION lib/systemd/system)
endif()
diff --git a/nDPId-test.c b/nDPId-test.c
index fa39139c0..5aa30305b 100644
--- a/nDPId-test.c
+++ b/nDPId-test.c
@@ -1667,7 +1667,7 @@ int main(int argc, char ** argv)
return retval;
}
- nDPIsrvd_options.max_write_buffers = 32;
+ set_cmdarg_ull(&nDPIsrvd_options.max_write_buffers, 32);
set_cmdarg_boolean(&nDPId_options.enable_data_analysis, 1);
set_cmdarg_ull(&nDPId_options.max_packets_per_flow_to_send, 5);
#ifdef ENABLE_ZLIB
diff --git a/nDPIsrvd.c b/nDPIsrvd.c
index 430e89f92..787feb741 100644
--- a/nDPIsrvd.c
+++ b/nDPIsrvd.c
@@ -90,27 +90,48 @@ static struct nDPIsrvd_address distributor_in_address = {
static struct
{
+ struct cmdarg config_file;
struct cmdarg pidfile;
struct cmdarg collector_un_sockpath;
struct cmdarg distributor_un_sockpath;
struct cmdarg distributor_in_address;
struct cmdarg user;
struct cmdarg group;
- nDPIsrvd_ull max_remote_descriptors;
- nDPIsrvd_ull max_write_buffers;
- uint8_t bufferbloat_fallback_to_blocking;
+ struct cmdarg max_remote_descriptors;
+ struct cmdarg max_write_buffers;
+ struct cmdarg bufferbloat_fallback_to_blocking;
#ifdef ENABLE_EPOLL
- uint8_t use_poll;
+ struct cmdarg use_poll;
#endif
-} nDPIsrvd_options = {.pidfile = CMDARG_STR(nDPIsrvd_PIDFILE),
+} nDPIsrvd_options = {.config_file = CMDARG_STR(NULL),
+ .pidfile = CMDARG_STR(nDPIsrvd_PIDFILE),
.collector_un_sockpath = CMDARG_STR(COLLECTOR_UNIX_SOCKET),
.distributor_un_sockpath = CMDARG_STR(DISTRIBUTOR_UNIX_SOCKET),
.distributor_in_address = CMDARG_STR(NULL),
.user = CMDARG_STR(DEFAULT_CHUSER),
.group = CMDARG_STR(NULL),
- .max_remote_descriptors = nDPIsrvd_MAX_REMOTE_DESCRIPTORS,
- .max_write_buffers = nDPIsrvd_MAX_WRITE_BUFFERS,
- .bufferbloat_fallback_to_blocking = 1};
+ .max_remote_descriptors = CMDARG_ULL(nDPIsrvd_MAX_REMOTE_DESCRIPTORS),
+ .max_write_buffers = CMDARG_ULL(nDPIsrvd_MAX_WRITE_BUFFERS),
+ .bufferbloat_fallback_to_blocking = CMDARG_BOOL(1)
+#ifdef ENABLE_EPOLL
+ ,
+ .use_poll = CMDARG_BOOL(0)
+#endif
+};
+struct confopt config_map[] = {CONFOPT("pidfile", &nDPIsrvd_options.pidfile),
+ CONFOPT("collector", &nDPIsrvd_options.collector_un_sockpath),
+ CONFOPT("distributor-unix", &nDPIsrvd_options.distributor_un_sockpath),
+ CONFOPT("distributor-in", &nDPIsrvd_options.distributor_in_address),
+ CONFOPT("user", &nDPIsrvd_options.user),
+ CONFOPT("group", &nDPIsrvd_options.group),
+ CONFOPT("max-remote-descriptors", &nDPIsrvd_options.max_remote_descriptors),
+ CONFOPT("max-write-buffers", &nDPIsrvd_options.max_write_buffers),
+ CONFOPT("blocking-io-fallback", &nDPIsrvd_options.bufferbloat_fallback_to_blocking)
+#ifdef ENABLE_EPOLL
+ ,
+ CONFOPT("poll", &nDPIsrvd_options.use_poll)
+#endif
+};
static void logger_nDPIsrvd(struct remote_desc const * const remote,
char const * const prefix,
@@ -239,9 +260,9 @@ static int add_to_additional_write_buffers(struct remote_desc * const remote,
return -1;
}
- if (utarray_len(additional_write_buffers) >= nDPIsrvd_options.max_write_buffers)
+ if (utarray_len(additional_write_buffers) >= GET_CMDARG_ULL(nDPIsrvd_options.max_write_buffers))
{
- if (nDPIsrvd_options.bufferbloat_fallback_to_blocking == 0)
+ if (GET_CMDARG_BOOL(nDPIsrvd_options.bufferbloat_fallback_to_blocking) == 0)
{
logger_nDPIsrvd(remote,
"Buffer limit for",
@@ -804,10 +825,13 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
{
int opt;
- while ((opt = getopt(argc, argv, "lL:c:dp:s:S:m:u:g:C:Dvh")) != -1)
+ while ((opt = getopt(argc, argv, "f:lL:c:dp:s:S:m:u:g:C:Dvh")) != -1)
{
switch (opt)
{
+ case 'f':
+ set_cmdarg_string(&nDPIsrvd_options.config_file, optarg);
+ break;
case 'l':
enable_console_logger();
break;
@@ -822,7 +846,7 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
break;
case 'e':
#ifdef ENABLE_EPOLL
- nDPIsrvd_options.use_poll = 1;
+ set_cmdarg_boolean(&nDPIsrvd_options.use_poll, 1);
#else
logger_early(1, "%s", "nDPIsrvd was built w/o epoll() support, poll() is already the default");
#endif
@@ -840,12 +864,17 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
set_cmdarg_string(&nDPIsrvd_options.distributor_in_address, optarg);
break;
case 'm':
- if (str_value_to_ull(optarg, &nDPIsrvd_options.max_remote_descriptors) != CONVERSION_OK)
+ {
+ nDPIsrvd_ull tmp;
+
+ if (str_value_to_ull(optarg, &tmp) != CONVERSION_OK)
{
fprintf(stderr, "%s: Argument for `-C' is not a number: %s\n", argv[0], optarg);
return 1;
}
+ set_cmdarg_ull(&nDPIsrvd_options.max_remote_descriptors, tmp);
break;
+ }
case 'u':
set_cmdarg_string(&nDPIsrvd_options.user, optarg);
break;
@@ -853,14 +882,19 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
set_cmdarg_string(&nDPIsrvd_options.group, optarg);
break;
case 'C':
- if (str_value_to_ull(optarg, &nDPIsrvd_options.max_write_buffers) != CONVERSION_OK)
+ {
+ nDPIsrvd_ull tmp;
+
+ if (str_value_to_ull(optarg, &tmp) != CONVERSION_OK)
{
fprintf(stderr, "%s: Argument for `-C' is not a number: %s\n", argv[0], optarg);
return 1;
}
+ set_cmdarg_ull(&nDPIsrvd_options.max_write_buffers, tmp);
break;
+ }
case 'D':
- nDPIsrvd_options.bufferbloat_fallback_to_blocking = 0;
+ set_cmdarg_boolean(&nDPIsrvd_options.bufferbloat_fallback_to_blocking, 0);
break;
case 'v':
fprintf(stderr, "%s", get_nDPId_version());
@@ -869,11 +903,13 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
default:
fprintf(stderr, "%s\n", get_nDPId_version());
fprintf(stderr,
- "Usage: %s [-l] [-L logfile] [-c path-to-unix-sock] [-e] [-d] [-p pidfile]\n"
+ "Usage: %s [-f config-file] [-l] [-L logfile]\n"
+ "\t[-c path-to-unix-sock] [-e] [-d] [-p pidfile]\n"
"\t[-s path-to-distributor-unix-socket] [-S distributor-host:port]\n"
"\t[-m max-remote-descriptors] [-u user] [-g group]\n"
"\t[-C max-buffered-json-lines] [-D]\n"
"\t[-v] [-h]\n\n"
+ "\t-f\tLoad nDPIsrvd options from a configuration file.\n"
"\t-l\tLog all messages to stderr.\n"
"\t-L\tLog all messages to a log file.\n"
"\t-c\tPath to a listening UNIX socket (nDPIsrvd Collector).\n"
@@ -903,6 +939,8 @@ static int nDPIsrvd_parse_options(int argc, char ** argv)
}
}
+ set_config_defaults(&config_map[0], nDPIsrvd_ARRAY_LENGTH(config_map));
+
if (is_path_absolute("Pidfile", GET_CMDARG_STR(nDPIsrvd_options.pidfile)) != 0)
{
return 1;
@@ -1517,8 +1555,9 @@ static int mainloop(struct nio * const io)
static int setup_event_queue(struct nio * const io)
{
#ifdef ENABLE_EPOLL
- if ((nDPIsrvd_options.use_poll == 0 && nio_use_epoll(io, 32) != NIO_SUCCESS) ||
- (nDPIsrvd_options.use_poll != 0 && nio_use_poll(io, nDPIsrvd_MAX_REMOTE_DESCRIPTORS) != NIO_SUCCESS))
+ if ((GET_CMDARG_BOOL(nDPIsrvd_options.use_poll) == 0 && nio_use_epoll(io, 32) != NIO_SUCCESS) ||
+ (GET_CMDARG_BOOL(nDPIsrvd_options.use_poll) != 0 &&
+ nio_use_poll(io, nDPIsrvd_MAX_REMOTE_DESCRIPTORS) != NIO_SUCCESS))
#else
if (nio_use_poll(io, nDPIsrvd_MAX_REMOTE_DESCRIPTORS) != NIO_SUCCESS)
#endif
@@ -1577,6 +1616,49 @@ static int setup_remote_descriptors(nDPIsrvd_ull max_remote_descriptors)
return 0;
}
+static int nDPIsrvd_parsed_config_line(
+ int lineno, char const * const section, char const * const name, char const * const value, void * const user_data)
+{
+ (void)user_data;
+
+ if (strnlen(section, INI_MAX_SECTION) == nDPIsrvd_STRLEN_SZ("general") &&
+ strncmp(section, "general", INI_MAX_SECTION) == 0)
+ {
+ size_t i;
+
+ for (i = 0; i < nDPIsrvd_ARRAY_LENGTH(config_map); ++i)
+ {
+ if (strnlen(name, INI_MAX_NAME) == strnlen(config_map[i].key, INI_MAX_NAME) &&
+ strncmp(name, config_map[i].key, INI_MAX_NAME) == 0)
+ {
+ if (IS_CMDARG_SET(*config_map[i].opt) != 0)
+ {
+ logger_early(1, "General config key `%s' already set, ignoring value `%s'", name, value);
+ }
+ else
+ {
+ if (set_config_from(&config_map[i], value) != 0)
+ {
+ return 0;
+ }
+ }
+ break;
+ }
+ }
+ if (i == nDPIsrvd_ARRAY_LENGTH(config_map))
+ {
+ logger_early(1, "Invalid general config key `%s' at line %d", name, lineno);
+ }
+ }
+ else
+ {
+ logger_early(
+ 1, "Invalid config section `%s' at line %d with key `%s' and value `%s'", section, lineno, name, value);
+ }
+
+ return 1;
+}
+
#ifndef NO_MAIN
int main(int argc, char ** argv)
{
@@ -1595,6 +1677,32 @@ int main(int argc, char ** argv)
{
return 1;
}
+ {
+ int ret;
+
+ if (IS_CMDARG_SET(nDPIsrvd_options.config_file) != 0 &&
+ (ret =
+ parse_config_file(GET_CMDARG_STR(nDPIsrvd_options.config_file), nDPIsrvd_parsed_config_line, NULL)) !=
+ 0)
+ {
+ if (ret > 0)
+ {
+ logger_early(1, "Config file `%s' is malformed", GET_CMDARG_STR(nDPIsrvd_options.config_file));
+ }
+ else if (ret == -ENOENT)
+ {
+ logger_early(1, "Path `%s' is not a regular file", GET_CMDARG_STR(nDPIsrvd_options.config_file));
+ }
+ else
+ {
+ logger_early(1,
+ "Could not open file `%s' for reading: %s",
+ GET_CMDARG_STR(nDPIsrvd_options.config_file),
+ strerror(errno));
+ }
+ return 1;
+ }
+ }
if (is_daemonize_enabled() != 0 && is_console_logger_enabled() != 0)
{
@@ -1630,7 +1738,7 @@ int main(int argc, char ** argv)
goto error;
}
- if (setup_remote_descriptors(nDPIsrvd_options.max_remote_descriptors) != 0)
+ if (setup_remote_descriptors(GET_CMDARG_ULL(nDPIsrvd_options.max_remote_descriptors)) != 0)
{
goto error;
}
diff --git a/ndpid.conf.example b/ndpid.conf.example
index 0d980d4b7..bb7c34978 100644
--- a/ndpid.conf.example
+++ b/ndpid.conf.example
@@ -7,8 +7,8 @@
# This will work for libpcap as well as with PF_RING.
#bpf = udp or tcp
-pidfile = /tmp/ndpid.pid
-user = nobody
+#pidfile = /tmp/ndpid.pid
+#user = nobody
#group = nogroup
#protocols = /path/to/libnDPI/example/protos.txt
#categories = /path/to/libnDPI/example/categories.txt
@@ -16,7 +16,7 @@ user = nobody
#sha1 = /path/to/libnDPI/example/sha1_fingerprints.csv
# Collector endpoint as UNIX socket (usually nDPIsrvd)
-collector = /var/run/ndpisrvd-collector
+collector = /run/nDPIsrvd/collector
# Collector endpoint as UDP socket (usually a custom application)
#collector = 127.0.0.1:7777
diff --git a/ndpisrvd.conf.example b/ndpisrvd.conf.example
new file mode 100644
index 000000000..b1acebc17
--- /dev/null
+++ b/ndpisrvd.conf.example
@@ -0,0 +1,25 @@
+[general]
+#pidfile = /tmp/ndpisrvd.pid
+#user = nobody
+#group = nogroup
+
+# Collector listener as UNIX socket
+collector = /run/nDPIsrvd/collector
+
+# Distributor listener as UNIX socket
+distributor-unix = /run/nDPIsrvd/distributor
+
+# Distributor listener as IP socket
+#distributor-in = 127.0.0.1:7000
+
+# Max (distributor) clients allowed to connect to nDPIsrvd
+max-remote-descriptors = 128
+
+# Additional output buffers useful if a distributor sink speed unstable
+max-write-buffers = 1024
+
+# Fallback to blocking I/O if output buffers full
+blocking-io-fallback = true
+
+# Force poll() on systems that support epoll() as well
+#poll = false
diff --git a/packages/systemd/default.cfg b/packages/systemd/default.cfg
deleted file mode 100644
index 8598da168..000000000
--- a/packages/systemd/default.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-COLLECTOR_PATH=/var/run/ndpisrvd-collector
-NDPID_ARGS="-A -z"
diff --git a/packages/systemd/ndpid@.service.in b/packages/systemd/ndpid@.service.in
index cfbb4110f..26ad27ac1 100644
--- a/packages/systemd/ndpid@.service.in
+++ b/packages/systemd/ndpid@.service.in
@@ -5,10 +5,9 @@ Requires=ndpisrvd.service
[Service]
Type=simple
-ExecStart=@CMAKE_INSTALL_PREFIX@/sbin/nDPId $NDPID_ARGS -i %i -c ${COLLECTOR_PATH}
+ExecStartPre=/bin/sh -c 'test -r "@CMAKE_INSTALL_PREFIX@/etc/nDPId/%i.conf" || cp -v "@CMAKE_INSTALL_PREFIX@/share/nDPId/ndpid.conf.example" "@CMAKE_INSTALL_PREFIX@/etc/nDPId/%i.conf"'
+ExecStart=@CMAKE_INSTALL_PREFIX@/sbin/nDPId -f @CMAKE_INSTALL_PREFIX@/etc/nDPId/%i.conf -i %i -u nobody
Restart=on-failure
-Environment=COLLECTOR_PATH=/var/run/ndpisrvd-collector NDPID_ARGS="-A -z"
-EnvironmentFile=@CMAKE_INSTALL_PREFIX@/etc/default/ndpid
[Install]
WantedBy=multi-user.target
diff --git a/packages/systemd/ndpisrvd.service.in b/packages/systemd/ndpisrvd.service.in
index 0fd3ba8e7..97ab3b398 100644
--- a/packages/systemd/ndpisrvd.service.in
+++ b/packages/systemd/ndpisrvd.service.in
@@ -4,11 +4,10 @@ After=network.target
[Service]
Type=simple
-ExecStart=@CMAKE_INSTALL_PREFIX@/bin/nDPIsrvd -c ${COLLECTOR_PATH}
-ExecStopPost=/bin/rm -f /var/run/ndpisrvd-collector
+ExecStartPre=/bin/sh -c 'test -r "@CMAKE_INSTALL_PREFIX@/etc/nDPId/nDPIsrvd.conf" || cp -v "@CMAKE_INSTALL_PREFIX@/share/nDPId/ndpisrvd.conf.example" "@CMAKE_INSTALL_PREFIX@/etc/nDPId/nDPIsrvd.conf"'
+ExecStartPre=/bin/sh -c 'mkdir -p /run/nDPIsrvd && chown nobody /run/nDPIsrvd'
+ExecStart=@CMAKE_INSTALL_PREFIX@/bin/nDPIsrvd -f @CMAKE_INSTALL_PREFIX@/etc/nDPId/nDPIsrvd.conf -u nobody
Restart=on-failure
-Environment=COLLECTOR_PATH=/var/run/ndpisrvd-collector
-EnvironmentFile=@CMAKE_INSTALL_PREFIX@/etc/default/ndpid
[Install]
WantedBy=multi-user.target