add generic rate limiting support from netbsd; ratelimit is purely time based,
ppsratecheck is for controlling packets/second Obtained from: netbsd
This commit is contained in:
parent
d522abfb6d
commit
78550cc698
@ -663,3 +663,91 @@ timevalfix(struct timeval *t1)
|
||||
t1->tv_usec -= 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef timersub
|
||||
#define timersub(tvp, uvp, vvp) \
|
||||
do { \
|
||||
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
|
||||
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
|
||||
if ((vvp)->tv_usec < 0) { \
|
||||
(vvp)->tv_sec--; \
|
||||
(vvp)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ratecheck(): simple time-based rate-limit checking. see ratecheck(9)
|
||||
* for usage and rationale.
|
||||
*/
|
||||
int
|
||||
ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
|
||||
{
|
||||
struct timeval tv, delta;
|
||||
int rv = 0;
|
||||
|
||||
getmicrouptime(&tv);
|
||||
timersub(&tv, lasttime, &delta);
|
||||
|
||||
/*
|
||||
* check for 0,0 is so that the message will be seen at least once,
|
||||
* even if interval is huge.
|
||||
*/
|
||||
if (timevalcmp(&delta, mininterval, >=) ||
|
||||
(lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) {
|
||||
*lasttime = tv;
|
||||
rv = 1;
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* ppsratecheck(): packets (or events) per second limitation.
|
||||
*/
|
||||
int
|
||||
ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
|
||||
{
|
||||
struct timeval tv, delta;
|
||||
int rv;
|
||||
|
||||
getmicrouptime(&tv);
|
||||
timersub(&tv, lasttime, &delta);
|
||||
|
||||
/*
|
||||
* check for 0,0 is so that the message will be seen at least once.
|
||||
* if more than one second have passed since the last update of
|
||||
* lasttime, reset the counter.
|
||||
*
|
||||
* we do increment *curpps even in *curpps < maxpps case, as some may
|
||||
* try to use *curpps for stat purposes as well.
|
||||
*/
|
||||
if ((lasttime->tv_sec == 0 && lasttime->tv_usec == 0) ||
|
||||
delta.tv_sec >= 1) {
|
||||
*lasttime = tv;
|
||||
*curpps = 0;
|
||||
rv = 1;
|
||||
} else if (maxpps < 0)
|
||||
rv = 1;
|
||||
else if (*curpps < maxpps)
|
||||
rv = 1;
|
||||
else
|
||||
rv = 0;
|
||||
|
||||
#if 1 /*DIAGNOSTIC?*/
|
||||
/* be careful about wrap-around */
|
||||
if (*curpps + 1 > *curpps)
|
||||
*curpps = *curpps + 1;
|
||||
#else
|
||||
/*
|
||||
* assume that there's not too many calls to this function.
|
||||
* not sure if the assumption holds, as it depends on *caller's*
|
||||
* behavior, not the behavior of this function.
|
||||
* IMHO it is wrong to make assumption on the caller's behavior,
|
||||
* so the above #if is #if 1, not #ifdef DIAGNOSTIC.
|
||||
*/
|
||||
*curpps = *curpps + 1;
|
||||
#endif
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
@ -302,6 +302,8 @@ void getmicrotime(struct timeval *tvp);
|
||||
/* Other functions */
|
||||
int itimerdecr(struct itimerval *itp, int usec);
|
||||
int itimerfix(struct timeval *tv);
|
||||
int ppsratecheck(struct timeval *, int *, int);
|
||||
int ratecheck(struct timeval *, const struct timeval *);
|
||||
void timevaladd(struct timeval *t1, struct timeval *t2);
|
||||
void timevalsub(struct timeval *t1, struct timeval *t2);
|
||||
int tvtohz(struct timeval *tv);
|
||||
|
Loading…
Reference in New Issue
Block a user