Merge pull request #6595 from rgerhards/feat/ratelimit-name-remaining

ratelimit: wire ratelimit.name into remaining modules
This commit is contained in:
Rainer Gerhards 2026-02-27 11:50:57 +01:00 committed by GitHub
commit 5e3f81656d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 746 additions and 84 deletions

View File

@ -0,0 +1,17 @@
You are a senior C security and performance auditor. Analyze the following rsyslog module code specifically for memory leaks on error paths.
**Audit Focus: Error Path Leaks & Ownership**
1. **Error Path Leaks**:
- Trace every `RS_RET` return path.
- Ensure that any memory allocated via `malloc`, `calloc`, or `strdup` (common in `setInstParam`) is freed before an error return.
- Check if `pData` or `WID` sub-elements are leaked during partial initialization failure.
2. **Ownership Ambiguity**:
- Determine if memory passed to a function is "owned" (caller must free) or "transferred" (callee must free).
- In rsyslog, `pData` is typically freed in `freeInstance`, and `WID` in `freeWrkrInstance`. Ensure no double-frees occur during HUP or teardown.
**Output**:
- List any identified leaks (e.g., "Line 45: ptr is not freed on RS_RET_PARAM_ERROR").
- Provide a summary of "Clean" vs "At Risk" allocations.
- Suggest specific `free()` placements for identified leaks.

View File

@ -0,0 +1,15 @@
You are a senior C security and performance auditor. Analyze the following rsyslog module code specifically for global and instance lifecycle symmetry.
**Audit Focus: Lifecycle Symmetry**
1. **Module Lifecycle**:
- Verify `modInit` and `modExit` balance global resource allocations (mutexes, global hashes, etc.).
- Ensure `createInstance` results in a fully initialized `pData` that `freeInstance` can safely clean up (even if only partially initialized).
2. **Worker Symmetry**:
- Check that `createWrkrInstance` and `freeWrkrInstance` are balanced.
- Look for thread-local storage or resources that might not be cleaned up if a thread terminates unexpectedly.
**Output**:
- List any identified symmetry issues (e.g., "Mutex initialized in modInit but not destroyed in modExit").
- Verify if `freeInstance` handles NULL pointers safely.

View File

@ -0,0 +1,18 @@
You are a senior C security and performance auditor. Analyze the following rsyslog module code specifically for NULL check compliance and macro usage.
**Audit Focus: NULL Checks & Memory Macros**
1. **Memory Macros**:
- Prefer `CHKmalloc()` for allocations. It handles the `NULL` check and jumps to `finalize_it` (or the local error label) automatically.
- If `malloc` or `strdup` is used directly, verify there is an immediate `NULL` check.
2. **Function-Specific Checks**:
- `es_str2cstr()` can fail and return `NULL`. Every call MUST be followed by a `NULL` check (or wrapped in `CHKmalloc` logic if applicable).
3. **String Handling**:
- Look for `strdup()` calls. Are they matched by a `free()`?
- Check for buffer overflows in `snprintf` or `strcpy` (though `format-code.sh` helps, logic errors remain).
**Output**:
- List any identified risks (e.g., "Line 123: es_str2cstr return is not checked").
- Suggest macro replacements (like `CHKmalloc`) where appropriate.

View File

@ -110,8 +110,9 @@ struct instanceConf_s {
uchar *pszBasicAuthFile; /* file containing basic auth users/pass */
ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */
ratelimit_t *ratelimiter;
unsigned int ratelimitInterval;
unsigned int ratelimitBurst;
int ratelimitInterval;
int ratelimitBurst;
uchar *pszRatelimitName;
uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */
prop_t *pInputName;
sbool flowControl;
@ -162,6 +163,7 @@ static struct cnfparamdescr inppdescr[] = {{"endpoint", eCmdHdlrString, 0},
{"name", eCmdHdlrString, 0},
{"ratelimit.interval", eCmdHdlrInt, 0},
{"ratelimit.burst", eCmdHdlrInt, 0},
{"ratelimit.name", eCmdHdlrString, 0},
{"addmetadata", eCmdHdlrBinary, 0}};
#include "im-helper.h" /* must be included AFTER the type definitions! */
@ -218,8 +220,9 @@ static rsRetVal createInstance(instanceConf_t **pinst) {
inst->ratelimiter = NULL;
inst->pszInputName = NULL;
inst->pInputName = NULL;
inst->ratelimitBurst = 10000; /* arbitrary high limit */
inst->ratelimitInterval = 0; /* off */
inst->ratelimitBurst = -1;
inst->ratelimitInterval = -1;
inst->pszRatelimitName = NULL;
inst->flowControl = 1;
inst->bDisableLFDelim = 0;
inst->bSuppOctetFram = 0;
@ -1069,9 +1072,11 @@ BEGINnewInpInst
} else if (!strcmp(inppblk.descr[i].name, "name")) {
inst->pszInputName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(inppblk.descr[i].name, "ratelimit.burst")) {
inst->ratelimitBurst = (unsigned int)pvals[i].val.d.n;
inst->ratelimitBurst = (int)pvals[i].val.d.n;
} else if (!strcmp(inppblk.descr[i].name, "ratelimit.interval")) {
inst->ratelimitInterval = (unsigned int)pvals[i].val.d.n;
inst->ratelimitInterval = (int)pvals[i].val.d.n;
} else if (!strcmp(inppblk.descr[i].name, "ratelimit.name")) {
inst->pszRatelimitName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(inppblk.descr[i].name, "flowcontrol")) {
inst->flowControl = (int)pvals[i].val.d.n;
} else if (!strcmp(inppblk.descr[i].name, "disablelfdelimiter")) {
@ -1088,13 +1093,31 @@ BEGINnewInpInst
}
}
if (inst->pszRatelimitName != NULL) {
if (inst->ratelimitInterval != -1 || inst->ratelimitBurst != -1) {
LogError(0, RS_RET_INVALID_PARAMS,
"imhttp: ratelimit.name is mutually exclusive with "
"ratelimit.interval and ratelimit.burst - using ratelimit.name");
}
inst->ratelimitInterval = 0;
inst->ratelimitBurst = 0;
} else {
if (inst->ratelimitInterval == -1) inst->ratelimitInterval = 0;
if (inst->ratelimitBurst == -1) inst->ratelimitBurst = 10000;
}
if (inst->pszInputName) {
CHKiRet(prop.Construct(&inst->pInputName));
CHKiRet(prop.SetString(inst->pInputName, inst->pszInputName, ustrlen(inst->pszInputName)));
CHKiRet(prop.ConstructFinalize(inst->pInputName));
}
CHKiRet(ratelimitNew(&inst->ratelimiter, "imphttp", NULL));
ratelimitSetLinuxLike(inst->ratelimiter, inst->ratelimitInterval, inst->ratelimitBurst);
if (inst->pszRatelimitName != NULL) {
CHKiRet(ratelimitNewFromConfig(&inst->ratelimiter, loadModConf->pConf, (char *)inst->pszRatelimitName, "imhttp",
NULL));
} else {
CHKiRet(ratelimitNew(&inst->ratelimiter, "imhttp", NULL));
ratelimitSetLinuxLike(inst->ratelimiter, (unsigned)inst->ratelimitInterval, (unsigned)inst->ratelimitBurst);
}
finalize_it:
CODE_STD_FINALIZERnewInpInst cnfparamvalsDestruct(pvals, &inppblk);
@ -1336,6 +1359,7 @@ BEGINfreeCnf
free(inst->pszBasicAuthFile);
free(inst->pszBindRuleset);
free(inst->pszInputName);
free(inst->pszRatelimitName);
del = inst;
inst = inst->next;

View File

@ -190,8 +190,9 @@ typedef struct instanceConf_s {
unsigned int *httpRetryCodes;
int nIgnorableCodes;
unsigned int *ignorableCodes;
unsigned int ratelimitInterval;
unsigned int ratelimitBurst;
int ratelimitInterval;
int ratelimitBurst;
uchar *pszRatelimitName;
/* for retries */
ratelimit_t *ratelimiter;
uchar *retryRulesetName;
@ -283,6 +284,7 @@ static struct cnfparamdescr actpdescr[] = {
{"retry.ruleset", eCmdHdlrString, 0},
{"ratelimit.interval", eCmdHdlrInt, 0},
{"ratelimit.burst", eCmdHdlrInt, 0},
{"ratelimit.name", eCmdHdlrString, 0},
{"name", eCmdHdlrGetWord, 0},
{"httpignorablecodes", eCmdHdlrArray, 0},
{"profile", eCmdHdlrGetWord, 0},
@ -387,6 +389,7 @@ BEGINfreeInstance
free(pData->retryRulesetName);
free(pData->ignorableCodes);
if (pData->ratelimiter != NULL) ratelimitDestruct(pData->ratelimiter);
free(pData->pszRatelimitName);
if (pData->bFreeBatchFormatName) free(pData->batchFormatName);
if (pData->listObjStats != NULL) {
const int numStats = pData->statsBySenders ? pData->numServers : 1;
@ -473,8 +476,8 @@ BEGINdbgPrintInstInfo
dbgprintf("\tretry='%d'\n", pData->retryFailures);
dbgprintf("\tretry.addmetadata='%d'\n", pData->retryAddMetadata);
dbgprintf("\tretry.ruleset='%s'\n", pData->retryRulesetName);
dbgprintf("\tratelimit.interval='%u'\n", pData->ratelimitInterval);
dbgprintf("\tratelimit.burst='%u'\n", pData->ratelimitBurst);
dbgprintf("\tratelimit.interval='%d'\n", pData->ratelimitInterval);
dbgprintf("\tratelimit.burst='%d'\n", pData->ratelimitBurst);
for (i = 0; i < pData->nIgnorableCodes; ++i) dbgprintf("%c'%d'", i == 0 ? '[' : ' ', pData->ignorableCodes[i]);
dbgprintf("]\n");
dbgprintf("\tratelimit.interval='%d'\n", pData->ratelimitInterval);
@ -1981,9 +1984,10 @@ static void ATTR_NONNULL() setInstParamDefaults(instanceData *const pData) {
pData->retryAddMetadata = 0;
pData->nhttpRetryCodes = 0;
pData->httpRetryCodes = NULL;
pData->ratelimitBurst = 20000;
pData->ratelimitInterval = 600;
pData->ratelimitBurst = -1;
pData->ratelimitInterval = -1;
pData->ratelimiter = NULL;
pData->pszRatelimitName = NULL;
pData->retryRulesetName = NULL;
pData->retryRuleset = NULL;
pData->nIgnorableCodes = 0;
@ -2433,9 +2437,11 @@ BEGINnewActInst
} else if (!strcmp(actpblk.descr[i].name, "retry.addmetadata")) {
pData->retryAddMetadata = pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.burst")) {
pData->ratelimitBurst = (unsigned int)pvals[i].val.d.n;
pData->ratelimitBurst = (int)pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.interval")) {
pData->ratelimitInterval = (unsigned int)pvals[i].val.d.n;
pData->ratelimitInterval = (int)pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.name")) {
pData->pszRatelimitName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(actpblk.descr[i].name, "name")) {
pData->statsName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(actpblk.descr[i].name, "httpignorablecodes")) {
@ -2467,6 +2473,19 @@ BEGINnewActInst
}
}
if (pData->pszRatelimitName != NULL) {
if (pData->ratelimitInterval != -1 || pData->ratelimitBurst != -1) {
LogError(0, RS_RET_INVALID_PARAMS,
"omhttp: ratelimit.name is mutually exclusive with "
"ratelimit.interval and ratelimit.burst - using ratelimit.name");
}
pData->ratelimitInterval = 0;
pData->ratelimitBurst = 0;
} else {
if (pData->ratelimitInterval == -1) pData->ratelimitInterval = 600;
if (pData->ratelimitBurst == -1) pData->ratelimitBurst = 20000;
}
if (pData->pwd != NULL && pData->uid == NULL) {
LogError(0, RS_RET_UID_MISSING,
"omhttp: password is provided, but no uid "
@ -2611,8 +2630,14 @@ BEGINnewActInst
}
if (pData->retryFailures) {
CHKiRet(ratelimitNew(&pData->ratelimiter, "omhttp", NULL));
ratelimitSetLinuxLike(pData->ratelimiter, pData->ratelimitInterval, pData->ratelimitBurst);
if (pData->pszRatelimitName != NULL) {
CHKiRet(ratelimitNewFromConfig(&pData->ratelimiter, loadModConf->pConf, (char *)pData->pszRatelimitName,
"omhttp", NULL));
} else {
CHKiRet(ratelimitNew(&pData->ratelimiter, "omhttp", NULL));
ratelimitSetLinuxLike(pData->ratelimiter, (unsigned)pData->ratelimitInterval,
(unsigned)pData->ratelimitBurst);
}
ratelimitSetNoTimeCache(pData->ratelimiter);
}

View File

@ -520,6 +520,7 @@ EXTRA_DIST = \
source/reference/parameters/imgssapi-inputgssserverpermitplaintcp.rst \
source/reference/parameters/imgssapi-inputgssserverrun.rst \
source/reference/parameters/imgssapi-inputgssserverservicename.rst \
source/reference/parameters/imhttp-ratelimit-name.rst \
source/reference/parameters/imjournal-defaultfacility.rst \
source/reference/parameters/imjournal-defaultseverity.rst \
source/reference/parameters/imjournal-defaulttag.rst \
@ -531,6 +532,7 @@ EXTRA_DIST = \
source/reference/parameters/imjournal-persiststateinterval.rst \
source/reference/parameters/imjournal-ratelimit-burst.rst \
source/reference/parameters/imjournal-ratelimit-interval.rst \
source/reference/parameters/imjournal-ratelimit-name.rst \
source/reference/parameters/imjournal-remote.rst \
source/reference/parameters/imjournal-statefile.rst \
source/reference/parameters/imjournal-usepid.rst \
@ -551,6 +553,7 @@ EXTRA_DIST = \
source/reference/parameters/imklog-permitnonkernelfacility.rst \
source/reference/parameters/imklog-ratelimitburst.rst \
source/reference/parameters/imklog-ratelimitinterval.rst \
source/reference/parameters/imklog-ratelimit-name.rst \
source/reference/parameters/immark-interval.rst \
source/reference/parameters/immark-markmessagetext.rst \
source/reference/parameters/immark-ruleset.rst \
@ -709,6 +712,7 @@ EXTRA_DIST = \
source/reference/parameters/imuxsock-parsetrusted.rst \
source/reference/parameters/imuxsock-ratelimit-burst.rst \
source/reference/parameters/imuxsock-ratelimit-interval.rst \
source/reference/parameters/imuxsock-ratelimit-name.rst \
source/reference/parameters/imuxsock-ratelimit-severity.rst \
source/reference/parameters/imuxsock-ruleset.rst \
source/reference/parameters/imuxsock-socket.rst \
@ -721,6 +725,7 @@ EXTRA_DIST = \
source/reference/parameters/imuxsock-syssock-parsetrusted.rst \
source/reference/parameters/imuxsock-syssock-ratelimit-burst.rst \
source/reference/parameters/imuxsock-syssock-ratelimit-interval.rst \
source/reference/parameters/imuxsock-syssock-ratelimit-name.rst \
source/reference/parameters/imuxsock-syssock-ratelimit-severity.rst \
source/reference/parameters/imuxsock-syssock-unlink.rst \
source/reference/parameters/imuxsock-syssock-use.rst \
@ -878,6 +883,7 @@ EXTRA_DIST = \
source/reference/parameters/omelasticsearch-pwd.rst \
source/reference/parameters/omelasticsearch-ratelimit-burst.rst \
source/reference/parameters/omelasticsearch-ratelimit-interval.rst \
source/reference/parameters/omelasticsearch-ratelimit-name.rst \
source/reference/parameters/omelasticsearch-rebindinterval.rst \
source/reference/parameters/omelasticsearch-retryfailures.rst \
source/reference/parameters/omelasticsearch-retryruleset.rst \
@ -895,6 +901,7 @@ EXTRA_DIST = \
source/reference/parameters/omelasticsearch-uid.rst \
source/reference/parameters/omelasticsearch-usehttps.rst \
source/reference/parameters/omelasticsearch-writeoperation.rst \
source/reference/parameters/omfwd-ratelimit-name.rst \
source/reference/parameters/omfile-addlf.rst \
source/reference/parameters/omfile-asyncwriting.rst \
source/reference/parameters/omfile-closetimeout.rst \
@ -959,6 +966,7 @@ EXTRA_DIST = \
source/reference/parameters/omhttp-pwd.rst \
source/reference/parameters/omhttp-ratelimit-burst.rst \
source/reference/parameters/omhttp-ratelimit-interval.rst \
source/reference/parameters/omhttp-ratelimit-name.rst \
source/reference/parameters/omhttp-reloadonhup.rst \
source/reference/parameters/omhttp-restpath.rst \
source/reference/parameters/omhttp-restpathtimeout.rst \

View File

@ -264,6 +264,13 @@ RateLimit.Burst
Specifies the rate-limiting burst in number of messages.
RateLimit.Name
^^^^^^^^^^^^^^
.. include:: ../../reference/parameters/imhttp-ratelimit-name.rst
:start-after: .. summary-start
:end-before: .. summary-end
flowControl
^^^^^^^^^^^

View File

@ -77,6 +77,10 @@ Module Parameters
- .. include:: ../../reference/parameters/imjournal-ratelimit-burst.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-imjournal-ratelimit-name`
- .. include:: ../../reference/parameters/imjournal-ratelimit-name.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-imjournal-ignorepreviousmessages`
- .. include:: ../../reference/parameters/imjournal-ignorepreviousmessages.rst
:start-after: .. summary-start
@ -143,6 +147,7 @@ Parameters specific to the input module.
../../reference/parameters/imjournal-statefile
../../reference/parameters/imjournal-ratelimit-interval
../../reference/parameters/imjournal-ratelimit-burst
../../reference/parameters/imjournal-ratelimit-name
../../reference/parameters/imjournal-ignorepreviousmessages
../../reference/parameters/imjournal-defaultseverity
../../reference/parameters/imjournal-defaultfacility

View File

@ -64,6 +64,10 @@ Module Parameters
- .. include:: ../../reference/parameters/imklog-ratelimitburst.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-imklog-ratelimit-name`
- .. include:: ../../reference/parameters/imklog-ratelimit-name.rst
:start-after: .. summary-start
:end-before: .. summary-end
Caveats/Known Bugs
@ -136,5 +140,6 @@ Unsupported |FmtObsoleteName| directives
../../reference/parameters/imklog-logpath
../../reference/parameters/imklog-ratelimitinterval
../../reference/parameters/imklog-ratelimitburst
../../reference/parameters/imklog-ratelimit-name

View File

@ -90,6 +90,10 @@ Module Parameters
- .. include:: ../../reference/parameters/imuxsock-syssock-ratelimit-severity.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-imuxsock-syssock-ratelimit-name`
- .. include:: ../../reference/parameters/imuxsock-syssock-ratelimit-name.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-imuxsock-syssock-usesystimestamp`
- .. include:: ../../reference/parameters/imuxsock-syssock-usesystimestamp.rst
:start-after: .. summary-start
@ -152,6 +156,10 @@ Input Parameters
- .. include:: ../../reference/parameters/imuxsock-ratelimit-severity.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-imuxsock-ratelimit-name`
- .. include:: ../../reference/parameters/imuxsock-ratelimit-name.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-imuxsock-usepidfromsystem`
- .. include:: ../../reference/parameters/imuxsock-usepidfromsystem.rst
:start-after: .. summary-start
@ -539,6 +547,7 @@ system log socket.
../../reference/parameters/imuxsock-syssock-ratelimit-interval
../../reference/parameters/imuxsock-syssock-ratelimit-burst
../../reference/parameters/imuxsock-syssock-ratelimit-severity
../../reference/parameters/imuxsock-syssock-ratelimit-name
../../reference/parameters/imuxsock-syssock-usesystimestamp
../../reference/parameters/imuxsock-syssock-annotate
../../reference/parameters/imuxsock-syssock-parsetrusted
@ -552,6 +561,7 @@ system log socket.
../../reference/parameters/imuxsock-ratelimit-interval
../../reference/parameters/imuxsock-ratelimit-burst
../../reference/parameters/imuxsock-ratelimit-severity
../../reference/parameters/imuxsock-ratelimit-name
../../reference/parameters/imuxsock-usepidfromsystem
../../reference/parameters/imuxsock-usesystimestamp
../../reference/parameters/imuxsock-createpath

View File

@ -201,6 +201,10 @@ Action Parameters
- .. include:: ../../reference/parameters/omelasticsearch-ratelimit-burst.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-omelasticsearch-ratelimit-name`
- .. include:: ../../reference/parameters/omelasticsearch-ratelimit-name.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-omelasticsearch-rebindinterval`
- .. include:: ../../reference/parameters/omelasticsearch-rebindinterval.rst
:start-after: .. summary-start
@ -246,6 +250,7 @@ Action Parameters
../../reference/parameters/omelasticsearch-retryruleset
../../reference/parameters/omelasticsearch-ratelimit-interval
../../reference/parameters/omelasticsearch-ratelimit-burst
../../reference/parameters/omelasticsearch-ratelimit-name
../../reference/parameters/omelasticsearch-rebindinterval
.. _omelasticsearch-statistic-counter:

View File

@ -577,6 +577,14 @@ RateLimit.Burst
Specifies the rate-limiting burst in number of messages.
RateLimit.Name
^^^^^^^^^^^^^^
.. include:: ../../reference/parameters/omfwd-ratelimit-name.rst
:start-after: .. summary-start
:end-before: .. summary-end
StreamDriver
^^^^^^^^^^^^

View File

@ -164,6 +164,10 @@ Input Parameters
- .. include:: ../../reference/parameters/omhttp-ratelimit-burst.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-omhttp-ratelimit-name`
- .. include:: ../../reference/parameters/omhttp-ratelimit-name.rst
:start-after: .. summary-start
:end-before: .. summary-end
* - :ref:`param-omhttp-errorfile`
- .. include:: ../../reference/parameters/omhttp-errorfile.rst
:start-after: .. summary-start
@ -241,6 +245,7 @@ Input Parameters
../../reference/parameters/omhttp-retry-addmetadata
../../reference/parameters/omhttp-ratelimit-interval
../../reference/parameters/omhttp-ratelimit-burst
../../reference/parameters/omhttp-ratelimit-name
../../reference/parameters/omhttp-errorfile
../../reference/parameters/omhttp-compress
../../reference/parameters/omhttp-compress-level

View File

@ -0,0 +1,26 @@
.. index:: ! imhttp; RateLimit.Name
.. _param-imhttp-ratelimit-name:
RateLimit.Name
==============
.. summary-start
**Default:** none
**Type:** string
**Description:**
Sets the name of the rate limit to use. This allows multiple listeners to share the same rate
limiting configuration (and state). The name refers to a :doc:`global rate limit object
<../../rainerscript/configuration_objects/ratelimit>` defined in the configuration.
**Note:** This parameter is mutually exclusive with ``ratelimit.interval`` and
``ratelimit.burst``. If ``ratelimit.name`` is specified, local per-listener limits cannot be
defined and any attempt to do so will result in an error (and the named rate limit will be used).
.. versionadded:: 8.2602.0
.. summary-end

View File

@ -0,0 +1,25 @@
.. index:: ! imjournal; RateLimit.Name
.. _param-imjournal-ratelimit-name:
RateLimit.Name
==============
.. summary-start
**Default:** none
**Type:** string
**Description:**
Sets the name of the rate limit to use. The name refers to a :doc:`global rate limit object
<../../rainerscript/configuration_objects/ratelimit>` defined in the configuration.
**Note:** This parameter is mutually exclusive with ``ratelimit.interval`` and
``ratelimit.burst``. If ``ratelimit.name`` is specified, inline rate limit parameters cannot be
defined and any attempt to do so will result in an error (and the named rate limit will be used).
.. versionadded:: 8.2602.0
.. summary-end

View File

@ -0,0 +1,25 @@
.. index:: ! imklog; RateLimit.Name
.. _param-imklog-ratelimit-name:
RateLimit.Name
==============
.. summary-start
**Default:** none
**Type:** string
**Description:**
Sets the name of the rate limit to use. The name refers to a :doc:`global rate limit object
<../../rainerscript/configuration_objects/ratelimit>` defined in the configuration.
**Note:** This parameter is mutually exclusive with ``ratelimitinterval`` and
``ratelimitburst``. If ``ratelimit.name`` is specified, inline rate limit parameters cannot be
defined and any attempt to do so will result in an error (and the named rate limit will be used).
.. versionadded:: 8.2602.0
.. summary-end

View File

@ -0,0 +1,26 @@
.. index:: ! imuxsock; RateLimit.Name
.. _param-imuxsock-ratelimit-name:
RateLimit.Name
==============
.. summary-start
**Default:** none
**Type:** string
**Description:**
Sets the name of the rate limit to use for this socket. This allows multiple sockets to share
the same rate limiting configuration (and state). The name refers to a :doc:`global rate limit
object <../../rainerscript/configuration_objects/ratelimit>` defined in the configuration.
**Note:** This parameter is mutually exclusive with ``ratelimit.interval`` and
``ratelimit.burst``. If ``ratelimit.name`` is specified, local per-socket limits cannot be
defined and any attempt to do so will result in an error (and the named rate limit will be used).
.. versionadded:: 8.2602.0
.. summary-end

View File

@ -0,0 +1,26 @@
.. index:: ! imuxsock; SysSock.RateLimit.Name
.. _param-imuxsock-syssock-ratelimit-name:
SysSock.RateLimit.Name
======================
.. summary-start
**Default:** none
**Type:** string
**Description:**
Sets the name of the rate limit to use for the system log socket. The name refers to a
:doc:`global rate limit object <../../rainerscript/configuration_objects/ratelimit>` defined in
the configuration.
**Note:** This parameter is mutually exclusive with ``syssock.ratelimit.interval`` and
``syssock.ratelimit.burst``. If ``syssock.ratelimit.name`` is specified, local limits cannot be
defined and any attempt to do so will result in an error (and the named rate limit will be used).
.. versionadded:: 8.2602.0
.. summary-end

View File

@ -0,0 +1,26 @@
.. index:: ! omelasticsearch; RateLimit.Name
.. _param-omelasticsearch-ratelimit-name:
RateLimit.Name
==============
.. summary-start
**Default:** none
**Type:** string
**Description:**
Sets the name of the rate limit to use. This allows multiple actions to share the same rate
limiting configuration (and state). The name refers to a :doc:`global rate limit object
<../../rainerscript/configuration_objects/ratelimit>` defined in the configuration.
**Note:** This parameter is mutually exclusive with ``ratelimit.interval`` and
``ratelimit.burst``. If ``ratelimit.name`` is specified, local per-action limits cannot be
defined and any attempt to do so will result in an error (and the named rate limit will be used).
.. versionadded:: 8.2602.0
.. summary-end

View File

@ -0,0 +1,26 @@
.. index:: ! omfwd; RateLimit.Name
.. _param-omfwd-ratelimit-name:
RateLimit.Name
==============
.. summary-start
**Default:** none
**Type:** string
**Description:**
Sets the name of the rate limit to use. This allows multiple actions to share the same rate
limiting configuration (and state). The name refers to a :doc:`global rate limit object
<../../rainerscript/configuration_objects/ratelimit>` defined in the configuration.
**Note:** This parameter is mutually exclusive with ``ratelimit.interval`` and
``ratelimit.burst``. If ``ratelimit.name`` is specified, local per-action limits cannot be
defined and any attempt to do so will result in an error (and the named rate limit will be used).
.. versionadded:: 8.2602.0
.. summary-end

View File

@ -0,0 +1,26 @@
.. index:: ! omhttp; RateLimit.Name
.. _param-omhttp-ratelimit-name:
RateLimit.Name
==============
.. summary-start
**Default:** none
**Type:** string
**Description:**
Sets the name of the rate limit to use. This allows multiple actions to share the same rate
limiting configuration (and state). The name refers to a :doc:`global rate limit object
<../../rainerscript/configuration_objects/ratelimit>` defined in the configuration.
**Note:** This parameter is mutually exclusive with ``ratelimit.interval`` and
``ratelimit.burst``. If ``ratelimit.name`` is specified, local per-action limits cannot be
defined and any attempt to do so will result in an error (and the named rate limit will be used).
.. versionadded:: 8.2602.0
.. summary-end

View File

@ -87,8 +87,9 @@ static struct configSettings_s {
char *stateFile;
int fCreateMode; /* default mode to use when creating new files, e.g. stateFile */
int iPersistStateInterval;
unsigned int ratelimitInterval;
unsigned int ratelimitBurst;
int ratelimitInterval;
int ratelimitBurst;
char *pszRatelimitName;
int bIgnorePrevious;
int bIgnoreNonValidStatefile;
int iDfltSeverity;
@ -108,6 +109,7 @@ static struct cnfparamdescr modpdescr[] = {{"statefile", eCmdHdlrGetWord, 0},
{"filecreatemode", eCmdHdlrFileCreateMode, 0},
{"ratelimit.interval", eCmdHdlrInt, 0},
{"ratelimit.burst", eCmdHdlrInt, 0},
{"ratelimit.name", eCmdHdlrString, 0},
{"persiststateinterval", eCmdHdlrInt, 0},
{"ignorepreviousmessages", eCmdHdlrBinary, 0},
{"ignorenonvalidstatefile", eCmdHdlrBinary, 0},
@ -1036,9 +1038,14 @@ static void stopSrvWrkr(journal_etry_t *const etry) {
BEGINrunInput
CODESTARTrunInput;
CHKiRet(ratelimitNew(&ratelimiter, "imjournal", NULL));
dbgprintf("imjournal: ratelimiting burst %u, interval %u\n", cs.ratelimitBurst, cs.ratelimitInterval);
ratelimitSetLinuxLike(ratelimiter, cs.ratelimitInterval, cs.ratelimitBurst);
if (cs.pszRatelimitName != NULL) {
CHKiRet(ratelimitNewFromConfig(&ratelimiter, runModConf->pConf, cs.pszRatelimitName, "imjournal", NULL));
} else {
CHKiRet(ratelimitNew(&ratelimiter, "imjournal", NULL));
dbgprintf("imjournal: ratelimiting burst %u, interval %u\n", (unsigned)cs.ratelimitBurst,
(unsigned)cs.ratelimitInterval);
ratelimitSetLinuxLike(ratelimiter, (unsigned)cs.ratelimitInterval, (unsigned)cs.ratelimitBurst);
}
ratelimitSetNoTimeCache(ratelimiter);
/* handling old "usepidfromsystem" option */
@ -1076,8 +1083,9 @@ BEGINbeginCnfLoad
cs.iPersistStateInterval = DFLT_persiststateinterval;
cs.stateFile = NULL;
cs.fCreateMode = 0644;
cs.ratelimitBurst = 20000;
cs.ratelimitInterval = 600;
cs.ratelimitBurst = -1;
cs.ratelimitInterval = -1;
cs.pszRatelimitName = NULL;
cs.iDfltSeverity = DFLT_SEVERITY;
cs.iDfltFacility = DFLT_FACILITY;
cs.bUseJnlPID = -1;
@ -1228,6 +1236,8 @@ BEGINfreeCnf
free(cs.stateFile);
free(cs.usePid);
free(cs.dfltTag);
free(cs.pszRatelimitName);
cs.pszRatelimitName = NULL;
statsobj.Destruct(&(statsCounter.stats));
ENDfreeCnf
@ -1266,6 +1276,8 @@ BEGINafterRun
if (ratelimiter) {
ratelimitDestruct(ratelimiter);
}
free(cs.pszRatelimitName);
cs.pszRatelimitName = NULL;
ENDafterRun
@ -1311,9 +1323,12 @@ BEGINsetModCnf
} else if (!strcmp(modpblk.descr[i].name, "filecreatemode")) {
cs.fCreateMode = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "ratelimit.burst")) {
cs.ratelimitBurst = (unsigned int)pvals[i].val.d.n;
cs.ratelimitBurst = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "ratelimit.interval")) {
cs.ratelimitInterval = (unsigned int)pvals[i].val.d.n;
cs.ratelimitInterval = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "ratelimit.name")) {
free(cs.pszRatelimitName);
cs.pszRatelimitName = (char *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(modpblk.descr[i].name, "ignorepreviousmessages")) {
cs.bIgnorePrevious = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "ignorenonvalidstatefile")) {
@ -1349,6 +1364,17 @@ BEGINsetModCnf
}
}
if (cs.pszRatelimitName != NULL) {
if (cs.ratelimitInterval != -1 || cs.ratelimitBurst != -1) {
LogError(0, RS_RET_INVALID_PARAMS,
"imjournal: ratelimit.name is mutually exclusive with "
"ratelimit.interval and ratelimit.burst - using ratelimit.name");
}
} else {
if (cs.ratelimitInterval == -1) cs.ratelimitInterval = 600;
if (cs.ratelimitBurst == -1) cs.ratelimitBurst = 20000;
}
finalize_it:
if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk);
ENDsetModCnf

View File

@ -99,7 +99,8 @@ static struct cnfparamdescr modpdescr[] = {{"ruleset", eCmdHdlrString, 0},
{"keepkerneltimestamp", eCmdHdlrBinary, 0},
{"internalmsgfacility", eCmdHdlrFacility, 0},
{"ratelimitinterval", eCmdHdlrInt, 0},
{"ratelimitburst", eCmdHdlrInt, 0}};
{"ratelimitburst", eCmdHdlrInt, 0},
{"ratelimit.name", eCmdHdlrString, 0}};
static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr};
static prop_t *pInputName = NULL;
@ -316,8 +317,9 @@ BEGINbeginCnfLoad
pModConf->iFacilIntMsg = klogFacilIntMsg();
loadModConf->configSetViaV2Method = 0;
pModConf->ratelimiter = NULL;
pModConf->ratelimitBurst = 10000; /* arbitrary high limit */
pModConf->ratelimitInterval = 0; /* off */
pModConf->ratelimitBurst = -1;
pModConf->ratelimitInterval = -1;
pModConf->pszRatelimitName = NULL;
bLegacyCnfModGlobalsPermitted = 1;
/* init legacy config vars */
initConfigSettings();
@ -356,9 +358,11 @@ BEGINsetModCnf
} else if (!strcmp(modpblk.descr[i].name, "internalmsgfacility")) {
loadModConf->iFacilIntMsg = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "ratelimitburst")) {
loadModConf->ratelimitBurst = (unsigned int)pvals[i].val.d.n;
loadModConf->ratelimitBurst = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "ratelimitinterval")) {
loadModConf->ratelimitInterval = (unsigned int)pvals[i].val.d.n;
loadModConf->ratelimitInterval = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "ratelimit.name")) {
loadModConf->pszRatelimitName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(modpblk.descr[i].name, "ruleset")) {
loadModConf->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else {
@ -369,6 +373,17 @@ BEGINsetModCnf
}
}
if (loadModConf->pszRatelimitName != NULL) {
if (loadModConf->ratelimitInterval != -1 || loadModConf->ratelimitBurst != -1) {
LogError(0, RS_RET_INVALID_PARAMS,
"imklog: ratelimit.name is mutually exclusive with "
"ratelimitinterval and ratelimitburst - using ratelimit.name");
}
} else {
if (loadModConf->ratelimitInterval == -1) loadModConf->ratelimitInterval = 0;
if (loadModConf->ratelimitBurst == -1) loadModConf->ratelimitBurst = 10000;
}
/* disable legacy module-global config directives */
bLegacyCnfModGlobalsPermitted = 0;
loadModConf->configSetViaV2Method = 1;
@ -415,8 +430,14 @@ ENDactivateCnfPrePrivDrop
BEGINactivateCnf
CODESTARTactivateCnf;
CHKiRet(ratelimitNew(&runModConf->ratelimiter, "imklog", NULL));
ratelimitSetLinuxLike(runModConf->ratelimiter, runModConf->ratelimitInterval, runModConf->ratelimitBurst);
if (runModConf->pszRatelimitName != NULL) {
CHKiRet(ratelimitNewFromConfig(&runModConf->ratelimiter, runModConf->pConf,
(char *)runModConf->pszRatelimitName, "imklog", NULL));
} else {
CHKiRet(ratelimitNew(&runModConf->ratelimiter, "imklog", NULL));
ratelimitSetLinuxLike(runModConf->ratelimiter, (unsigned)runModConf->ratelimitInterval,
(unsigned)runModConf->ratelimitBurst);
}
finalize_it:
ENDactivateCnf
@ -424,6 +445,7 @@ ENDactivateCnf
BEGINfreeCnf
CODESTARTfreeCnf;
free(pModConf->pszBindRuleset);
free(pModConf->pszRatelimitName);
ENDfreeCnf
@ -436,7 +458,7 @@ ENDwillRun
BEGINafterRun
CODESTARTafterRun;
ratelimitDestruct(runModConf->ratelimiter);
if (runModConf->ratelimiter != NULL) ratelimitDestruct(runModConf->ratelimiter);
iRet = klogAfterRun(runModConf);
ENDafterRun

View File

@ -43,6 +43,7 @@ struct modConfData_s {
ratelimit_t *ratelimiter;
int ratelimitInterval;
int ratelimitBurst;
uchar *pszRatelimitName;
ruleset_t *pBindRuleset; /* ruleset to bind (use system default if unspecified) */
uchar *pszBindRuleset;
};

View File

@ -213,9 +213,10 @@ struct instanceConf_s {
sbool bWritePid; /* use credentials from recvmsg() and fixup PID in TAG */
sbool bUseSysTimeStamp; /* use timestamp from system (instead of from message) */
int bCreatePath; /* auto-create socket path? */
unsigned int ratelimitInterval; /* interval in seconds, 0 = off */
unsigned int ratelimitBurst; /* max nbr of messages in interval */
int ratelimitInterval; /* interval in seconds, 0 = off */
int ratelimitBurst; /* max nbr of messages in interval */
int ratelimitSeverity;
uchar *pszRatelimitName;
int bAnnotate; /* annotate trusted properties */
int bParseTrusted; /* parse trusted properties */
sbool bDiscardOwnMsgs; /* discard messages that originated from our own pid? */
@ -231,9 +232,10 @@ struct modConfData_s {
rsconf_t *pConf; /* our overall config object */
instanceConf_t *root, *tail;
uchar *pLogSockName;
unsigned int ratelimitIntervalSysSock;
unsigned int ratelimitBurstSysSock;
int ratelimitIntervalSysSock;
int ratelimitBurstSysSock;
int ratelimitSeveritySysSock;
uchar *pszRatelimitNameSysSock;
int bAnnotateSysSock;
int bParseTrusted;
int bUseSpecialParser;
@ -265,7 +267,8 @@ static struct cnfparamdescr modpdescr[] = {{"syssock.use", eCmdHdlrBinary, 0},
{"syssock.usepidfromsystem", eCmdHdlrBinary, 0},
{"syssock.ratelimit.interval", eCmdHdlrInt, 0},
{"syssock.ratelimit.burst", eCmdHdlrInt, 0},
{"syssock.ratelimit.severity", eCmdHdlrInt, 0}};
{"syssock.ratelimit.severity", eCmdHdlrInt, 0},
{"syssock.ratelimit.name", eCmdHdlrString, 0}};
static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr};
/* input instance parameters */
@ -286,7 +289,8 @@ static struct cnfparamdescr inppdescr[] = {
{"ruleset", eCmdHdlrString, 0},
{"ratelimit.interval", eCmdHdlrInt, 0},
{"ratelimit.burst", eCmdHdlrInt, 0},
{"ratelimit.severity", eCmdHdlrInt, 0}};
{"ratelimit.severity", eCmdHdlrInt, 0},
{"ratelimit.name", eCmdHdlrString, 0}};
static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr};
#include "im-helper.h" /* must be included AFTER the type definitions! */
@ -305,9 +309,10 @@ static rsRetVal createInstance(instanceConf_t **pinst) {
inst->pLogHostName = NULL;
inst->pszBindRuleset = NULL;
inst->pBindRuleset = NULL;
inst->ratelimitInterval = DFLT_ratelimitInterval;
inst->ratelimitBurst = DFLT_ratelimitBurst;
inst->ratelimitInterval = -1;
inst->ratelimitBurst = -1;
inst->ratelimitSeverity = DFLT_ratelimitSeverity;
inst->pszRatelimitName = NULL;
inst->bUseFlowCtl = 0;
inst->bUseSpecialParser = DFLT_bUseSpecialParser;
inst->bParseHost = UNSET;
@ -398,7 +403,7 @@ static rsRetVal addListner(instanceConf_t *inst) {
CHKiRet(prop.SetString(listeners[nfd].hostName, inst->pLogHostName, ustrlen(inst->pLogHostName)));
CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName));
}
if (inst->ratelimitInterval > 0) {
if (inst->pszRatelimitName != NULL || inst->ratelimitInterval > 0) {
if ((listeners[nfd].ht =
create_hashtable(100, hash_from_key_fn, key_equals_fn, (void (*)(void *))ratelimitDestruct)) == NULL) {
/* in this case, we simply turn off rate-limiting */
@ -406,6 +411,8 @@ static rsRetVal addListner(instanceConf_t *inst) {
"imuxsock: turning off rate limiting because we could not "
"create hash table\n");
inst->ratelimitInterval = 0;
free(inst->pszRatelimitName);
inst->pszRatelimitName = NULL;
}
} else {
listeners[nfd].ht = NULL;
@ -418,7 +425,7 @@ static rsRetVal addListner(instanceConf_t *inst) {
listeners[nfd].bCreatePath = inst->bCreatePath;
listeners[nfd].sockName = ustrdup(inst->sockName);
listeners[nfd].bUseCreds = (inst->bDiscardOwnMsgs || inst->bWritePid || inst->ratelimitInterval ||
inst->bAnnotate || inst->bUseSysTimeStamp)
inst->pszRatelimitName || inst->bAnnotate || inst->bUseSysTimeStamp)
? 1
: 0;
listeners[nfd].bAnnotate = inst->bAnnotate;
@ -429,9 +436,14 @@ static rsRetVal addListner(instanceConf_t *inst) {
listeners[nfd].bUseSysTimeStamp = inst->bUseSysTimeStamp;
listeners[nfd].bUseSpecialParser = inst->bUseSpecialParser;
listeners[nfd].pRuleset = inst->pBindRuleset;
CHKiRet(ratelimitNew(&listeners[nfd].dflt_ratelimiter, "imuxsock", NULL));
ratelimitSetLinuxLike(listeners[nfd].dflt_ratelimiter, listeners[nfd].ratelimitInterval,
listeners[nfd].ratelimitBurst);
if (inst->pszRatelimitName != NULL) {
CHKiRet(ratelimitNewFromConfig(&listeners[nfd].dflt_ratelimiter, runModConf->pConf,
(char *)inst->pszRatelimitName, "imuxsock", NULL));
} else {
CHKiRet(ratelimitNew(&listeners[nfd].dflt_ratelimiter, "imuxsock", NULL));
ratelimitSetLinuxLike(listeners[nfd].dflt_ratelimiter, listeners[nfd].ratelimitInterval,
listeners[nfd].ratelimitBurst);
}
ratelimitSetSeverity(listeners[nfd].dflt_ratelimiter, listeners[nfd].ratelimitSev);
nfd++;
@ -1107,7 +1119,7 @@ static rsRetVal activateListeners(void) {
}
}
#endif
if (runModConf->ratelimitIntervalSysSock > 0) {
if (runModConf->pszRatelimitNameSysSock != NULL || runModConf->ratelimitIntervalSysSock > 0) {
if ((listeners[0].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) {
/* in this case, we simply turn of rate-limiting */
LogError(0, NO_ERRCODE,
@ -1126,11 +1138,11 @@ static rsRetVal activateListeners(void) {
listeners[0].ratelimitInterval = runModConf->ratelimitIntervalSysSock;
listeners[0].ratelimitBurst = runModConf->ratelimitBurstSysSock;
listeners[0].ratelimitSev = runModConf->ratelimitSeveritySysSock;
listeners[0].bUseCreds =
(runModConf->bWritePidSysSock || runModConf->ratelimitIntervalSysSock || runModConf->bAnnotateSysSock ||
runModConf->bDiscardOwnMsgs || runModConf->bUseSysTimeStamp)
? 1
: 0;
listeners[0].bUseCreds = (runModConf->bWritePidSysSock || runModConf->ratelimitIntervalSysSock ||
runModConf->pszRatelimitNameSysSock || runModConf->bAnnotateSysSock ||
runModConf->bDiscardOwnMsgs || runModConf->bUseSysTimeStamp)
? 1
: 0;
listeners[0].bWritePid = runModConf->bWritePidSysSock;
listeners[0].bAnnotate = runModConf->bAnnotateSysSock;
listeners[0].bParseTrusted = runModConf->bParseTrusted;
@ -1141,9 +1153,14 @@ static rsRetVal activateListeners(void) {
listeners[0].bUseSysTimeStamp = runModConf->bUseSysTimeStamp;
listeners[0].flags = runModConf->bIgnoreTimestamp ? IGNDATE : NOFLAG;
listeners[0].flowCtl = runModConf->bUseFlowCtl ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY;
CHKiRet(ratelimitNew(&listeners[0].dflt_ratelimiter, "imuxsock", NULL));
ratelimitSetLinuxLike(listeners[0].dflt_ratelimiter, listeners[0].ratelimitInterval,
listeners[0].ratelimitBurst);
if (runModConf->pszRatelimitNameSysSock != NULL) {
CHKiRet(ratelimitNewFromConfig(&listeners[0].dflt_ratelimiter, runModConf->pConf,
(char *)runModConf->pszRatelimitNameSysSock, "imuxsock", NULL));
} else {
CHKiRet(ratelimitNew(&listeners[0].dflt_ratelimiter, "imuxsock", NULL));
ratelimitSetLinuxLike(listeners[0].dflt_ratelimiter, listeners[0].ratelimitInterval,
listeners[0].ratelimitBurst);
}
ratelimitSetSeverity(listeners[0].dflt_ratelimiter, listeners[0].ratelimitSev);
}
@ -1196,9 +1213,10 @@ BEGINbeginCnfLoad
*/
pModConf->bDiscardOwnMsgs = pConf->globals.bProcessInternalMessages;
pModConf->bUnlink = 1;
pModConf->ratelimitIntervalSysSock = DFLT_ratelimitInterval;
pModConf->ratelimitBurstSysSock = DFLT_ratelimitBurst;
pModConf->ratelimitIntervalSysSock = -1;
pModConf->ratelimitBurstSysSock = -1;
pModConf->ratelimitSeveritySysSock = DFLT_ratelimitSeverity;
pModConf->pszRatelimitNameSysSock = NULL;
bLegacyCnfModGlobalsPermitted = 1;
/* reset legacy config vars */
resetConfigVariables(NULL, NULL);
@ -1249,11 +1267,13 @@ BEGINsetModCnf
} else if (!strcmp(modpblk.descr[i].name, "syssock.usepidfromsystem")) {
loadModConf->bWritePidSysSock = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "syssock.ratelimit.interval")) {
loadModConf->ratelimitIntervalSysSock = (unsigned int)pvals[i].val.d.n;
loadModConf->ratelimitIntervalSysSock = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "syssock.ratelimit.burst")) {
loadModConf->ratelimitBurstSysSock = (unsigned int)pvals[i].val.d.n;
loadModConf->ratelimitBurstSysSock = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "syssock.ratelimit.severity")) {
loadModConf->ratelimitSeveritySysSock = (int)pvals[i].val.d.n;
} else if (!strcmp(modpblk.descr[i].name, "syssock.ratelimit.name")) {
loadModConf->pszRatelimitNameSysSock = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else {
dbgprintf(
"imuxsock: program error, non-handled "
@ -1262,6 +1282,17 @@ BEGINsetModCnf
}
}
if (loadModConf->pszRatelimitNameSysSock != NULL) {
if (loadModConf->ratelimitIntervalSysSock != -1 || loadModConf->ratelimitBurstSysSock != -1) {
LogError(0, RS_RET_INVALID_PARAMS,
"imuxsock: syssock.ratelimit.name is mutually exclusive with "
"syssock.ratelimit.interval and syssock.ratelimit.burst - using syssock.ratelimit.name");
}
} else {
if (loadModConf->ratelimitIntervalSysSock == -1) loadModConf->ratelimitIntervalSysSock = DFLT_ratelimitInterval;
if (loadModConf->ratelimitBurstSysSock == -1) loadModConf->ratelimitBurstSysSock = DFLT_ratelimitBurst;
}
/* disable legacy module-global config directives */
bLegacyCnfModGlobalsPermitted = 0;
loadModConf->configSetViaV2Method = 1;
@ -1322,11 +1353,13 @@ BEGINnewInpInst
} else if (!strcmp(inppblk.descr[i].name, "ruleset")) {
inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(inppblk.descr[i].name, "ratelimit.interval")) {
inst->ratelimitInterval = (unsigned int)pvals[i].val.d.n;
inst->ratelimitInterval = (int)pvals[i].val.d.n;
} else if (!strcmp(inppblk.descr[i].name, "ratelimit.burst")) {
inst->ratelimitBurst = (unsigned int)pvals[i].val.d.n;
inst->ratelimitBurst = (int)pvals[i].val.d.n;
} else if (!strcmp(inppblk.descr[i].name, "ratelimit.severity")) {
inst->ratelimitSeverity = (int)pvals[i].val.d.n;
} else if (!strcmp(inppblk.descr[i].name, "ratelimit.name")) {
inst->pszRatelimitName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else {
dbgprintf(
"imuxsock: program error, non-handled "
@ -1334,6 +1367,18 @@ BEGINnewInpInst
inppblk.descr[i].name);
}
}
if (inst->pszRatelimitName != NULL) {
if (inst->ratelimitInterval != -1 || inst->ratelimitBurst != -1) {
LogError(0, RS_RET_INVALID_PARAMS,
"imuxsock: ratelimit.name is mutually exclusive with "
"ratelimit.interval and ratelimit.burst - using ratelimit.name");
}
} else {
if (inst->ratelimitInterval == -1) inst->ratelimitInterval = DFLT_ratelimitInterval;
if (inst->ratelimitBurst == -1) inst->ratelimitBurst = DFLT_ratelimitBurst;
}
finalize_it:
CODE_STD_FINALIZERnewInpInst cnfparamvalsDestruct(pvals, &inppblk);
ENDnewInpInst
@ -1432,10 +1477,12 @@ BEGINfreeCnf
instanceConf_t *inst, *del;
CODESTARTfreeCnf;
free(pModConf->pLogSockName);
free(pModConf->pszRatelimitNameSysSock);
for (inst = pModConf->root; inst != NULL;) {
free(inst->sockName);
free(inst->pszBindRuleset);
free(inst->pLogHostName);
free(inst->pszRatelimitName);
del = inst;
inst = inst->next;
free(del);

View File

@ -165,8 +165,9 @@ typedef struct instanceConf_s {
uchar *myPrivKeyFile;
es_write_ops_t writeOperation;
sbool retryFailures;
unsigned int ratelimitInterval;
unsigned int ratelimitBurst;
int ratelimitInterval;
int ratelimitBurst;
uchar *pszRatelimitName;
/* for retries */
ratelimit_t *ratelimiter;
uchar *retryRulesetName;
@ -240,6 +241,7 @@ static struct cnfparamdescr actpdescr[] = {{"server", eCmdHdlrArray, 0},
{"retryfailures", eCmdHdlrBinary, 0},
{"ratelimit.interval", eCmdHdlrInt, 0},
{"ratelimit.burst", eCmdHdlrInt, 0},
{"ratelimit.name", eCmdHdlrString, 0},
{"retryruleset", eCmdHdlrString, 0},
{"rebindinterval", eCmdHdlrInt, 0},
{"esversion.major", eCmdHdlrPositiveInt, 0}};
@ -351,6 +353,7 @@ BEGINfreeInstance
free(pData->retryRulesetName);
free(pData->detectedVersionString);
if (pData->ratelimiter != NULL) ratelimitDestruct(pData->ratelimiter);
free(pData->pszRatelimitName);
ENDfreeInstance
BEGINfreeWrkrInstance
@ -2178,9 +2181,10 @@ static void ATTR_NONNULL() setInstParamDefaults(instanceData *const pData) {
pData->myPrivKeyFile = NULL;
pData->writeOperation = ES_WRITE_INDEX;
pData->retryFailures = 0;
pData->ratelimitBurst = 20000;
pData->ratelimitInterval = 600;
pData->ratelimitBurst = -1;
pData->ratelimitInterval = -1;
pData->ratelimiter = NULL;
pData->pszRatelimitName = NULL;
pData->retryRulesetName = NULL;
pData->retryRuleset = NULL;
pData->rebindInterval = DEFAULT_REBIND_INTERVAL;
@ -2309,9 +2313,11 @@ BEGINnewActInst
} else if (!strcmp(actpblk.descr[i].name, "retryfailures")) {
pData->retryFailures = pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.burst")) {
pData->ratelimitBurst = (unsigned int)pvals[i].val.d.n;
pData->ratelimitBurst = (int)pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.interval")) {
pData->ratelimitInterval = (unsigned int)pvals[i].val.d.n;
pData->ratelimitInterval = (int)pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.name")) {
pData->pszRatelimitName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(actpblk.descr[i].name, "retryruleset")) {
pData->retryRulesetName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if (!strcmp(actpblk.descr[i].name, "rebindinterval")) {
@ -2326,6 +2332,19 @@ BEGINnewActInst
}
}
if (pData->pszRatelimitName != NULL) {
if (pData->ratelimitInterval != -1 || pData->ratelimitBurst != -1) {
LogError(0, RS_RET_INVALID_PARAMS,
"omelasticsearch: ratelimit.name is mutually exclusive with "
"ratelimit.interval and ratelimit.burst - using ratelimit.name");
}
pData->ratelimitInterval = 0;
pData->ratelimitBurst = 0;
} else {
if (pData->ratelimitInterval == -1) pData->ratelimitInterval = 600;
if (pData->ratelimitBurst == -1) pData->ratelimitBurst = 20000;
}
if (pData->apiKey != NULL && (pData->uid != NULL || pData->pwd != NULL)) {
LogError(0, RS_RET_CONFIG_ERROR,
"omelasticsearch: apikey cannot be combined with uid/pwd "
@ -2474,8 +2493,14 @@ BEGINnewActInst
}
if (pData->retryFailures) {
CHKiRet(ratelimitNew(&pData->ratelimiter, "omelasticsearch", NULL));
ratelimitSetLinuxLike(pData->ratelimiter, pData->ratelimitInterval, pData->ratelimitBurst);
if (pData->pszRatelimitName != NULL) {
CHKiRet(ratelimitNewFromConfig(&pData->ratelimiter, loadModConf->pConf, (char *)pData->pszRatelimitName,
"omelasticsearch", NULL));
} else {
CHKiRet(ratelimitNew(&pData->ratelimiter, "omelasticsearch", NULL));
ratelimitSetLinuxLike(pData->ratelimiter, (unsigned)pData->ratelimitInterval,
(unsigned)pData->ratelimitBurst);
}
ratelimitSetNoTimeCache(pData->ratelimiter);
}

View File

@ -239,6 +239,13 @@ TESTS_DEFAULT = \
sndrcv_udp_nonstdpt_v6.sh \
imudp_thread_hang.sh \
imudp_ratelimit_name.sh \
omfwd_ratelimit_name.sh \
omelasticsearch_ratelimit_name.sh \
omhttp_ratelimit_name.sh \
imhttp_ratelimit_name.sh \
imjournal_ratelimit_name.sh \
imklog_ratelimit_name.sh \
imuxsock_ratelimit_name.sh \
asynwr_simple.sh \
asynwr_simple_2.sh \
asynwr_timeout.sh \
@ -598,7 +605,11 @@ TESTS_IMTCP_VALGRIND = \
TESTS_RATELIMIT = \
ratelimit_exclusivity.sh \
ratelimit_name.sh \
ratelimit_duplicate.sh
ratelimit_duplicate.sh \
omfwd_ratelimit_name.sh \
omelasticsearch_ratelimit_name.sh \
imklog_ratelimit_name.sh \
imuxsock_ratelimit_name.sh
TESTS_IMTCP_IMPSTATS = \
imtcp-impstats.sh
@ -757,7 +768,8 @@ TESTS_OMHTTP_FLAKY_VALGRIND = \
TESTS_IMJOURNAL = \
imjournal-basic.sh \
imjournal-statefile.sh
imjournal-statefile.sh \
imjournal_ratelimit_name.sh
TESTS_IMJOURNAL_VALGRIND = \
imjournal-basic-vg.sh \
@ -834,7 +846,8 @@ TESTS_OMHTTP = \
omhttp-httpheaderkey.sh \
omhttp-multiplehttpheaders.sh \
omhttp-dynrestpath.sh \
omhttp-batch-dynrestpath.sh
omhttp-batch-dynrestpath.sh \
omhttp_ratelimit_name.sh
TESTS_OMHTTP_VALGRIND = \
omhttp-auth-vg.sh \
@ -917,7 +930,8 @@ TESTS_IMHTTP = \
imhttp-post-payload-compress.sh \
imhttp-getrequest-file.sh \
imhttp-healthcheck.sh \
imhttp-metrics.sh
imhttp-metrics.sh \
imhttp_ratelimit_name.sh
TESTS_IMHTTP_VALGRIND = \
imhttp-post-payload-vg.sh \

22
tests/imhttp_ratelimit_name.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
# Test named rate limits for imhttp (config-validation)
# Verifies that imhttp accepts ratelimit.name without error.
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
ratelimit(name="imhttp_test_limit" interval="2" burst="5")
module(load="../contrib/imhttp/.libs/imhttp"
ports="0"
listenportfilename="'$RSYSLOG_DYNNAME'.imhttp.port")
input(type="imhttp" endpoint="/test" ratelimit.name="imhttp_test_limit" ruleset="imhttp")
template(name="outfmt" type="string" string="%msg%\n")
ruleset(name="imhttp") {
action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
}
'
startup
shutdown_when_empty
wait_shutdown
exit_test

View File

@ -0,0 +1,20 @@
#!/bin/bash
# Test named rate limits for imjournal (config-validation)
# Verifies that imjournal accepts ratelimit.name without error.
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
ratelimit(name="imjournal_test_limit" interval="2" burst="5")
module(load="../plugins/imjournal/.libs/imjournal"
ratelimit.name="imjournal_test_limit"
StateFile="'$RSYSLOG_DYNNAME'.imjournal.state"
IgnorePreviousMessages="on")
template(name="outfmt" type="string" string="%msg%\n")
action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
'
startup
shutdown_when_empty
wait_shutdown
exit_test

21
tests/imklog_ratelimit_name.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
# Test named rate limits for imklog (config-validation)
# Verifies that imklog accepts ratelimit.name without error.
. ${srcdir:=.}/diag.sh init
if [ "$EUID" -ne 0 ]; then
exit 77 # Not root, skip this test
fi
generate_conf
add_conf '
ratelimit(name="imklog_test_limit" interval="2" burst="5")
module(load="../plugins/imklog/.libs/imklog"
ratelimit.name="imklog_test_limit")
template(name="outfmt" type="string" string="%msg%\n")
action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
'
startup
shutdown_when_empty
wait_shutdown
exit_test

View File

@ -0,0 +1,22 @@
#!/bin/bash
# Test named rate limits for imuxsock
# Verifies that imuxsock accepts ratelimit.name and
# syssock.ratelimit.name without error.
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
ratelimit(name="imuxsock_test_limit" interval="2" burst="5")
ratelimit(name="imuxsock_syssock_limit" interval="3" burst="10")
module(load="../plugins/imuxsock/.libs/imuxsock"
SysSock.Use="off")
input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-imuxsock.sock"
ratelimit.name="imuxsock_test_limit")
template(name="outfmt" type="string" string="%msg%\n")
action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
'
startup
shutdown_when_empty
wait_shutdown
exit_test

View File

@ -0,0 +1,20 @@
#!/bin/bash
# Test named rate limits for omelasticsearch (config-validation)
# Verifies that omelasticsearch accepts ratelimit.name without error.
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
ratelimit(name="omelasticsearch_test_limit" interval="2" burst="5")
module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
template(name="outfmt" type="string" string="%msg%\n")
action(type="omelasticsearch" server="localhost" serverport="19200"
ratelimit.name="omelasticsearch_test_limit"
retryfailures="on" template="outfmt")
action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
'
startup
shutdown_when_empty
wait_shutdown
exit_test

21
tests/omfwd_ratelimit_name.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
# Test named rate limits for omfwd (config-validation)
# Verifies that omfwd accepts ratelimit.name without error.
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
ratelimit(name="omfwd_test_limit" interval="2" burst="5")
module(load="../plugins/imudp/.libs/imudp")
input(type="imudp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.rcvr.port")
template(name="outfmt" type="string" string="%msg%\n")
if $msg contains "msgnum:" then
action(type="omfwd" target="127.0.0.1" port="514" protocol="udp"
ratelimit.name="omfwd_test_limit" template="outfmt")
'
startup
shutdown_when_empty
wait_shutdown
exit_test

20
tests/omhttp_ratelimit_name.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
# Test named rate limits for omhttp (config-validation)
# Verifies that omhttp accepts ratelimit.name without error.
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
ratelimit(name="omhttp_test_limit" interval="2" burst="5")
module(load="../contrib/omhttp/.libs/omhttp")
template(name="outfmt" type="string" string="%msg%\n")
action(type="omhttp" server="localhost" serverport="19280"
ratelimit.name="omhttp_test_limit"
retryfailures="on" template="outfmt")
action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
'
startup
shutdown_when_empty
wait_shutdown
exit_test

View File

@ -145,8 +145,9 @@ typedef struct _instanceData {
uint8_t compressionMode;
sbool strmCompFlushOnTxEnd; /* flush stream compression on transaction end? */
unsigned poolResumeInterval;
unsigned int ratelimitInterval;
unsigned int ratelimitBurst;
int ratelimitInterval;
int ratelimitBurst;
uchar *pszRatelimitName;
ratelimit_t *ratelimiter;
targetStats_t *target_stats;
} instanceData;
@ -259,7 +260,8 @@ static struct cnfparamdescr actpdescr[] = {
{"template", eCmdHdlrGetWord, 0},
{"pool.resumeinterval", eCmdHdlrPositiveInt, 0},
{"ratelimit.interval", eCmdHdlrInt, 0},
{"ratelimit.burst", eCmdHdlrInt, 0}};
{"ratelimit.burst", eCmdHdlrInt, 0},
{"ratelimit.name", eCmdHdlrString, 0}};
static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr};
struct modConfData_s {
@ -862,6 +864,7 @@ BEGINfreeInstance
free((void *)pData->pszStrmDrvrCRLFile);
free((void *)pData->pszStrmDrvrKeyFile);
free((void *)pData->pszStrmDrvrCertFile);
free(pData->pszRatelimitName);
net.DestructPermittedPeers(&pData->pPermPeers);
if (pData->ratelimiter != NULL) {
ratelimitDestruct(pData->ratelimiter);
@ -1848,8 +1851,9 @@ static void setInstParamDefaults(instanceData *pData) {
pData->ipfreebind = IPFREEBIND_ENABLED_WITH_LOG;
pData->poolResumeInterval = 30;
pData->ratelimiter = NULL;
pData->ratelimitInterval = 0;
pData->ratelimitBurst = 200;
pData->ratelimitInterval = -1;
pData->ratelimitBurst = -1;
pData->pszRatelimitName = NULL;
}
@ -2113,15 +2117,30 @@ BEGINnewActInst
} else if (!strcmp(actpblk.descr[i].name, "pool.resumeinterval")) {
pData->poolResumeInterval = (unsigned int)pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.burst")) {
pData->ratelimitBurst = (unsigned int)pvals[i].val.d.n;
pData->ratelimitBurst = (int)pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.interval")) {
pData->ratelimitInterval = (unsigned int)pvals[i].val.d.n;
pData->ratelimitInterval = (int)pvals[i].val.d.n;
} else if (!strcmp(actpblk.descr[i].name, "ratelimit.name")) {
pData->pszRatelimitName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
} else {
LogError(0, RS_RET_INTERNAL_ERROR, "omfwd: program error, non-handled parameter '%s'",
actpblk.descr[i].name);
}
}
if (pData->pszRatelimitName != NULL) {
if (pData->ratelimitInterval != -1 || pData->ratelimitBurst != -1) {
LogError(0, RS_RET_INVALID_PARAMS,
"omfwd: ratelimit.name is mutually exclusive with "
"ratelimit.interval and ratelimit.burst - using ratelimit.name");
}
pData->ratelimitInterval = 0;
pData->ratelimitBurst = 0;
} else {
if (pData->ratelimitInterval == -1) pData->ratelimitInterval = 0;
if (pData->ratelimitBurst == -1) pData->ratelimitBurst = 200;
}
if (pData->targetSrv != NULL && pData->target_name != NULL) {
LogError(0, RS_RET_PARAM_ERROR, "omfwd: target and targetSrv are mutually exclusive");
ABORT_FINALIZE(RS_RET_PARAM_ERROR);
@ -2197,9 +2216,13 @@ BEGINnewActInst
LogError(0, RS_RET_PARAM_ERROR, "omfwd: parameter \"address\" not supported for tcp -- ignored");
}
if (pData->ratelimitInterval > 0) {
if (pData->pszRatelimitName != NULL) {
CHKiRet(ratelimitNewFromConfig(&pData->ratelimiter, loadModConf->pConf, (char *)pData->pszRatelimitName,
"omfwd", NULL));
ratelimitSetNoTimeCache(pData->ratelimiter);
} else if (pData->ratelimitInterval > 0) {
CHKiRet(ratelimitNew(&pData->ratelimiter, "omfwd", NULL));
ratelimitSetLinuxLike(pData->ratelimiter, pData->ratelimitInterval, pData->ratelimitBurst);
ratelimitSetLinuxLike(pData->ratelimiter, (unsigned)pData->ratelimitInterval, (unsigned)pData->ratelimitBurst);
ratelimitSetNoTimeCache(pData->ratelimiter);
}