diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2024-10-13 11:54:15 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2024-10-16 13:03:41 +0200 |
commit | 25e6c67af673c9286a4881399db482a5ebc58d46 (patch) | |
tree | 02ee250a7179d54ee01fb81a8d1260f29ec09a23 | |
parent | 3b5aef2104f200fa4d6c793a3558fd195356de61 (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.txt | 4 | ||||
-rw-r--r-- | nDPId-test.c | 2 | ||||
-rw-r--r-- | nDPIsrvd.c | 146 | ||||
-rw-r--r-- | ndpid.conf.example | 6 | ||||
-rw-r--r-- | ndpisrvd.conf.example | 25 | ||||
-rw-r--r-- | packages/systemd/default.cfg | 2 | ||||
-rw-r--r-- | packages/systemd/ndpid@.service.in | 5 | ||||
-rw-r--r-- | packages/systemd/ndpisrvd.service.in | 7 |
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 |