diff options
-rw-r--r-- | runtime/ratelimit.c | 67 | ||||
-rw-r--r-- | runtime/ratelimit.h | 8 |
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? */ |