summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/ratelimit.c67
-rw-r--r--runtime/ratelimit.h8
2 files changed, 49 insertions, 26 deletions
diff --git a/runtime/ratelimit.c b/runtime/ratelimit.c
index d3d32b58..e94ad1bc 100644
--- a/runtime/ratelimit.c
+++ b/runtime/ratelimit.c
@@ -32,6 +32,7 @@
#include "parser.h"
#include "unicode-helper.h"
#include "msg.h"
+#include "rsconf.h"
#include "dirty.h"
/* definitions for objects we access */
@@ -68,41 +69,17 @@ ratelimitGenRepMsg(ratelimit_t *ratelimit)
done: return repMsg;
}
-/* ratelimit a message, that means:
- * - handle "last message repeated n times" logic
- * - handle actual (discarding) rate-limiting
- * This function returns RS_RET_OK, if the caller shall process
- * the message regularly and RS_RET_DISCARD if the caller must
- * discard the message. The caller should also discard the message
- * if another return status occurs. This places some burden on the
- * caller logic, but provides best performance. Demanding this
- * cooperative mode can enable a faulty caller to thrash up part
- * of the system, but we accept that risk (a faulty caller can
- * always do all sorts of evil, so...)
- * If *ppRepMsg != NULL on return, the caller must enqueue that
- * message before the original message.
- */
-rsRetVal
-ratelimitMsg(ratelimit_t *ratelimit, msg_t *pMsg, msg_t **ppRepMsg)
+static inline rsRetVal
+doLastMessageRepeatedNTimes(ratelimit_t *ratelimit, msg_t *pMsg, msg_t **ppRepMsg)
{
- rsRetVal localRet;
int bNeedUnlockMutex = 0;
DEFiRet;
- if((pMsg->msgFlags & NEEDS_PARSING) != 0) {
- if((localRet = parser.ParseMsg(pMsg)) != RS_RET_OK) {
- DBGPRINTF("Message discarded, parsing error %d\n", localRet);
- ABORT_FINALIZE(RS_RET_DISCARDMSG);
- }
- }
-
if(ratelimit->bThreadSafe) {
pthread_mutex_lock(&ratelimit->mut);
bNeedUnlockMutex = 1;
}
- *ppRepMsg = NULL;
- /* suppress duplicate messages */
if( ratelimit->pMsg != NULL &&
getMSGLen(pMsg) == getMSGLen(ratelimit->pMsg) &&
!ustrcmp(getMSG(pMsg), getMSG(ratelimit->pMsg)) &&
@@ -133,6 +110,43 @@ finalize_it:
RETiRet;
}
+/* ratelimit a message, that means:
+ * - handle "last message repeated n times" logic
+ * - handle actual (discarding) rate-limiting
+ * This function returns RS_RET_OK, if the caller shall process
+ * the message regularly and RS_RET_DISCARD if the caller must
+ * discard the message. The caller should also discard the message
+ * if another return status occurs. This places some burden on the
+ * caller logic, but provides best performance. Demanding this
+ * cooperative mode can enable a faulty caller to thrash up part
+ * of the system, but we accept that risk (a faulty caller can
+ * always do all sorts of evil, so...)
+ * If *ppRepMsg != NULL on return, the caller must enqueue that
+ * message before the original message.
+ */
+rsRetVal
+ratelimitMsg(ratelimit_t *ratelimit, msg_t *pMsg, msg_t **ppRepMsg)
+{
+ rsRetVal localRet;
+ DEFiRet;
+
+#warning be sure to parse only when actually required!
+ if((pMsg->msgFlags & NEEDS_PARSING) != 0) {
+ if((localRet = parser.ParseMsg(pMsg)) != RS_RET_OK) {
+ DBGPRINTF("Message discarded, parsing error %d\n", localRet);
+ ABORT_FINALIZE(RS_RET_DISCARDMSG);
+ }
+ }
+
+ *ppRepMsg = NULL;
+
+ if(ratelimit->bReduceRepeatMsgs) {
+ CHKiRet(doLastMessageRepeatedNTimes(ratelimit, pMsg, ppRepMsg));
+ }
+finalize_it:
+ RETiRet;
+}
+
/* add a message to a ratelimiter/multisubmit structure.
* ratelimiting is automatically handled according to the ratelimit
@@ -177,6 +191,7 @@ ratelimitNew(ratelimit_t **ppThis)
DEFiRet;
CHKmalloc(pThis = calloc(1, sizeof(ratelimit_t)));
+ pThis->bReduceRepeatMsgs = runConf->globals.bReduceRepeatMsgs;
*ppThis = pThis;
finalize_it:
RETiRet;
diff --git a/runtime/ratelimit.h b/runtime/ratelimit.h
index 37dad900..5fa884a8 100644
--- a/runtime/ratelimit.h
+++ b/runtime/ratelimit.h
@@ -22,6 +22,14 @@
#define INCLUDED_RATELIMIT_H
struct ratelimit_s {
+ /* support for Linux kernel-type ratelimiting */
+ unsigned short interval;
+ unsigned short burst;
+ unsigned done;
+ unsigned missed;
+ time_t begin;
+ /* support for "last message repeated n times */
+ int bReduceRepeatMsgs; /**< shall we do "last message repeated n times" processing? */
unsigned nsupp; /**< nbr of msgs suppressed */
msg_t *pMsg;
sbool bThreadSafe; /**< do we need to operate in Thread-Safe mode? */