Skip to content

Commit 9b7021c

Browse files
committed
Unirec output plugin: fixed processing of the IFC timeout parameter
1 parent 7d15dbb commit 9b7021c

File tree

1 file changed

+60
-14
lines changed

1 file changed

+60
-14
lines changed

extra_plugins/output/unirec/configuration.c

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,13 @@
5252
#include <errno.h>
5353
#include <unistd.h>
5454
#include <stdarg.h>
55+
#include <limits.h>
5556

5657
/** Timeout configuration */
5758
enum cfg_timeout_mode {
58-
CFG_TIMEOUT_WAIT, /**< Block indefinitely */
59-
CFG_TIMEOUT_NO_WAIT, /**< Don't block */
60-
CFG_TIMEOUT_HALF_WAIT /**< Block only if some client is connected */
59+
CFG_TIMEOUT_WAIT = -1, /**< Block indefinitely */
60+
CFG_TIMEOUT_NO_WAIT = -2, /**< Don't block */
61+
CFG_TIMEOUT_HALF_WAIT = -3 /**< Block only if some client is connected */
6162
};
6263

6364
/** Default maximum number of connections over TCP/TCP-TLS/Unix */
@@ -76,41 +77,41 @@ struct ifc_common {
7677
/** Data buffering and sending in large bulks */
7778
bool buffer;
7879
/** Timeout mode */
79-
enum cfg_timeout_mode timeout;
80+
long int timeout;
8081
};
8182

8283
/*
8384
* <params>
8485
* <uniRecFormat>DST_IP,SRC_IP,BYTES,DST_PORT,?TCP_FLAGS,SRC_PORT,PROTOCOL</uniRecFormat>
8586
* <trapIfcCommon> <!-- optional -->
8687
* <timeout>NO_WAIT</timeout> <!-- optional -->
87-
* <buffer>on</buffer> <!-- optional -->
88+
* <buffer>true</buffer> <!-- optional -->
8889
* <autoflush>500000</autoflush> <!-- optional -->
8990
* </trapIfcCommon>
9091
*
9192
* <trapIfcSpec>
9293
* <tcp>
9394
* <port>8000</port>
94-
* <maxClients>64<maxClients> <!-- optional -->
95+
* <maxClients>64</maxClients> <!-- optional -->
9596
* </tcp>
9697
* <tcp-tls>
9798
* <port>8000</port>
98-
* <maxClients>64<maxClients> <!-- optional -->
99+
* <maxClients>64</maxClients> <!-- optional -->
99100
* <keyFile>...</keyFile>
100101
* <certFile>...</certFile>
101102
* <caFile>...</caFile>
102103
* </tcp-tls>
103104
* <unix>
104105
* <name>ipfixcol-output</name>
105-
* <maxClients>64<maxClients> <!-- optional -->
106+
* <maxClients>64</maxClients> <!-- optional -->
106107
* </unix>
107108
* <file>
108109
* <name>/tmp/nemea/trapdata</name>
109110
* <mode>write</mode> <!-- optional -->
110111
* <time>0</time> <!-- optional -->
111112
* <size>0</size> <!-- optional -->
112113
* </file>
113-
* <trapIfcSpec>
114+
* </trapIfcSpec>
114115
* </params>
115116
*/
116117

@@ -259,6 +260,40 @@ cfg_str_append(char **str, const char *fmt, ...)
259260
return IPX_OK;
260261
}
261262

263+
/**
264+
* \brief Convert a string to long integer
265+
*
266+
* If the string contains unexpected characters, conversion fails.
267+
* \param[in] str String to convert
268+
* \param[out] res Result
269+
* \return #IPX_OK on success
270+
* \return #IPX_ERR_FORMAT on failure
271+
*/
272+
static int
273+
cfg_str2long(const char *str, long int *res)
274+
{
275+
if (strlen(str) == 0) {
276+
// Empty string
277+
return IPX_ERR_FORMAT;
278+
}
279+
280+
char *end_ptr = NULL;
281+
errno = 0;
282+
long int tmp = strtol(str, &end_ptr, 10);
283+
if ((errno == ERANGE || (tmp == LONG_MAX || tmp == LONG_MIN)) || (errno != 0 && tmp == 0)) {
284+
// Conversion failure
285+
return IPX_ERR_FORMAT;
286+
}
287+
288+
if (*end_ptr != '\0') {
289+
// Unexpected characters after the number
290+
return IPX_ERR_FORMAT;
291+
}
292+
293+
*res = tmp;
294+
return IPX_OK;
295+
}
296+
262297
/**
263298
* \brief Process \<trapIfcCommon\> node
264299
*
@@ -272,6 +307,8 @@ cfg_str_append(char **str, const char *fmt, ...)
272307
static int
273308
cfg_parse_common(ipx_ctx_t *ctx, fds_xml_ctx_t *root, struct ifc_common *common)
274309
{
310+
long int val;
311+
275312
const struct fds_xml_cont *content;
276313
while (fds_xml_next(root, &content) != FDS_EOC) {
277314
switch (content->id) {
@@ -287,10 +324,12 @@ cfg_parse_common(ipx_ctx_t *ctx, fds_xml_ctx_t *root, struct ifc_common *common)
287324
assert(content->type == FDS_OPTS_T_STRING);
288325
if (strcasecmp(content->ptr_string, "wait") == 0) {
289326
common->timeout = CFG_TIMEOUT_WAIT;
290-
} else if (strcasecmp(content->ptr_string, "no-wait") == 0) {
327+
} else if (strcasecmp(content->ptr_string, "no_wait") == 0) {
291328
common->timeout = CFG_TIMEOUT_NO_WAIT;
292-
} else if (strcasecmp(content->ptr_string, "half-wait") == 0) {
329+
} else if (strcasecmp(content->ptr_string, "half_wait") == 0) {
293330
common->timeout = CFG_TIMEOUT_HALF_WAIT;
331+
} else if (cfg_str2long(content->ptr_string, &val) == IPX_OK && val > 0) {
332+
common->timeout = val;
294333
} else {
295334
IPX_CTX_ERROR(ctx, "Invalid interface timeout value '%s'", content->ptr_string);
296335
return IPX_ERR_FORMAT;
@@ -617,6 +656,7 @@ cfg_parse_spec(ipx_ctx_t *ctx, fds_xml_ctx_t *root, struct conf_params *cfg)
617656
static int
618657
cfg_add_ifc_common(ipx_ctx_t *ctx, struct conf_params *cfg, const struct ifc_common *common)
619658
{
659+
int rc;
620660
char **ptr = &cfg->trap_ifc_spec;
621661
assert((*ptr) != NULL);
622662

@@ -627,20 +667,26 @@ cfg_add_ifc_common(ipx_ctx_t *ctx, struct conf_params *cfg, const struct ifc_com
627667
}
628668

629669
// Add timeout parameter
630-
const char *timeout_str = NULL;
670+
const char *timeout_str;
631671
switch (common->timeout) {
632672
case CFG_TIMEOUT_HALF_WAIT: timeout_str = "HALF_WAIT"; break;
633673
case CFG_TIMEOUT_NO_WAIT: timeout_str = "NO_WAIT"; break;
634674
case CFG_TIMEOUT_WAIT: timeout_str = "WAIT"; break;
675+
default: timeout_str = NULL; break;
676+
}
677+
678+
if (timeout_str == NULL) {
679+
rc = cfg_str_append(ptr, ":timeout=%ld", common->timeout);
680+
} else {
681+
rc = cfg_str_append(ptr, ":timeout=%s", timeout_str);
635682
}
636683

637-
if (cfg_str_append(ptr, ":timeout=%s", timeout_str) != IPX_OK) {
684+
if (rc != IPX_OK) {
638685
IPX_CTX_ERROR(ctx, "Unable to allocate memory (%s:%d)", __FILE__, __LINE__);
639686
return IPX_ERR_NOMEM;
640687
}
641688

642689
// Add autoflush parameter
643-
int rc;
644690
if (common->autoflush == 0) {
645691
rc = cfg_str_append(ptr, ":autoflush=off");
646692
} else {

0 commit comments

Comments
 (0)