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
9830739b64
commit
91974ce10b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=108142
@ -663,3 +663,91 @@ timevalfix(struct timeval *t1)
|
|||||||
t1->tv_usec -= 1000000;
|
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 */
|
/* Other functions */
|
||||||
int itimerdecr(struct itimerval *itp, int usec);
|
int itimerdecr(struct itimerval *itp, int usec);
|
||||||
int itimerfix(struct timeval *tv);
|
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 timevaladd(struct timeval *t1, struct timeval *t2);
|
||||||
void timevalsub(struct timeval *t1, struct timeval *t2);
|
void timevalsub(struct timeval *t1, struct timeval *t2);
|
||||||
int tvtohz(struct timeval *tv);
|
int tvtohz(struct timeval *tv);
|
||||||
|
Loading…
Reference in New Issue
Block a user