Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef RATELIMIT_H /* nobys experimental rate limiting framework */
- #define RATELIMIT_H
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- class ratelimit {
- private:
- struct node {
- void *data;
- struct node *next;
- };
- struct queue {
- struct node *head, *tail;
- } r;
- struct entry {
- char name[512];
- struct queue times;
- };
- public:
- ratelimit()
- {
- memset(&r, 0, sizeof(r));
- }
- void ratelimit_tick (int cutoff)
- {
- time_t n = time(NULL);
- int pc1 = 0;
- for (struct node *ptr = r.head; ptr; ptr = ptr->next) {
- struct entry *ent = (struct entry *)ptr->data;
- int count = 0, pc = 0;
- if (!ent)
- continue;
- for (struct node *ptr1 = ent->times.head; ptr1; ptr1 = ptr1->next) {
- time_t t = (time_t)ptr1->data;
- int dif = (int)(n - t);
- if (dif > cutoff)
- ++pc;
- else
- ++count;
- }
- while (pc--)
- qpop(&ent->times);
- if (!count)
- ++pc1;
- }
- while (pc1--)
- free(qpop(&r));
- }
- int ratelimit_add (const char *name)
- {
- if (!name || !name[0])
- return 1;
- int nlen = (int)strlen(name);
- if (nlen > 250)
- return 2;
- time_t n = time(NULL);
- if (!r.head)
- return _ratelimit_new(name);
- for (struct node *ptr = r.head; ptr; ptr = ptr->next) {
- struct entry *ent = (struct entry *)ptr->data;
- if (ent && (int)strlen(ent->name) == nlen && !strcmp(ent->name, name)) {
- qpush(&ent->times, (void *)n);
- return qcount(&ent->times);
- }
- }
- return _ratelimit_new(name);
- }
- private:
- int _ratelimit_new (const char *name)
- {
- struct entry *nw = (struct entry *)calloc(1, sizeof(struct entry));
- time_t n = time(NULL);
- qpush(&nw->times, (void *)n);
- strcpy(nw->name, name);
- qpush(&r, nw);
- return 1;
- }
- void *qpop (struct queue *q)
- {
- struct node *tmp = NULL;
- void *retn = 0;
- if (q->head == NULL)
- return NULL;
- tmp = q->head;
- retn = q->head->data;
- if (q->head == q->tail)
- q->head = q->tail = NULL;
- else
- q->head = q->head->next;
- free(tmp);
- return retn;
- }
- void qpush (struct queue *q, void *data)
- {
- struct node *nw;
- if (!(nw = (struct node *)calloc(sizeof(struct node), 1)))
- return;
- nw->data = data;
- nw->next = NULL;
- if (!q->tail && !q->head) {
- q->tail = q->head = nw;
- return;
- }
- q->tail->next = nw;
- q->tail = nw;
- }
- int qcount (struct queue *q)
- {
- int c = 0;
- if (!q || !q->head)
- return -1;
- for (struct node *ptr = q->head; ptr; ptr = ptr->next)
- ++c;
- return c;
- }
- };
- #endif
Advertisement
Add Comment
Please, Sign In to add comment