Guest User

Untitled

a guest
Nov 17th, 2019
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.47 KB | None | 0 0
  1. #ifndef RATELIMIT_H /* nobys experimental rate limiting framework */
  2. #define RATELIMIT_H
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <time.h>
  6. class ratelimit {
  7. private:
  8.     struct node {
  9.         void *data;
  10.         struct node *next;
  11.     };
  12.     struct queue {
  13.         struct node *head, *tail;
  14.     } r;
  15.     struct entry {
  16.         char name[512];
  17.         struct queue times;
  18.     };
  19. public:
  20.     ratelimit()
  21.     {
  22.         memset(&r, 0, sizeof(r));
  23.     }
  24.     void ratelimit_tick (int cutoff)
  25.     {
  26.         time_t n = time(NULL);
  27.         int pc1 = 0;
  28.         for (struct node *ptr = r.head; ptr; ptr = ptr->next) {
  29.             struct entry *ent = (struct entry *)ptr->data;
  30.             int count = 0, pc = 0;
  31.             if (!ent)
  32.                 continue;
  33.             for (struct node *ptr1 = ent->times.head; ptr1; ptr1 = ptr1->next) {
  34.                 time_t t = (time_t)ptr1->data;
  35.                 int dif = (int)(n - t);
  36.                 if (dif > cutoff)
  37.                     ++pc;
  38.                 else
  39.                     ++count;
  40.             }
  41.             while (pc--)
  42.                 qpop(&ent->times);
  43.             if (!count)
  44.                 ++pc1;
  45.         }
  46.         while (pc1--)
  47.             free(qpop(&r));
  48.     }
  49.     int ratelimit_add (const char *name)
  50.     {
  51.         if (!name || !name[0])
  52.             return 1;
  53.         int nlen = (int)strlen(name);
  54.         if (nlen > 250)
  55.             return 2;
  56.         time_t n = time(NULL);
  57.         if (!r.head)
  58.             return _ratelimit_new(name);
  59.         for (struct node *ptr = r.head; ptr; ptr = ptr->next) {
  60.             struct entry *ent = (struct entry *)ptr->data;
  61.             if (ent && (int)strlen(ent->name) == nlen && !strcmp(ent->name, name)) {
  62.                 qpush(&ent->times, (void *)n);
  63.                 return qcount(&ent->times);
  64.             }
  65.         }
  66.         return _ratelimit_new(name);
  67.     }
  68. private:
  69.     int _ratelimit_new (const char *name)
  70.     {
  71.         struct entry *nw = (struct entry *)calloc(1, sizeof(struct entry));
  72.         time_t n = time(NULL);
  73.         qpush(&nw->times, (void *)n);
  74.         strcpy(nw->name, name);
  75.         qpush(&r, nw);
  76.         return 1;
  77.     }
  78.     void *qpop (struct queue *q)
  79.     {
  80.         struct node *tmp = NULL;
  81.         void *retn = 0;
  82.         if (q->head == NULL)
  83.             return NULL;
  84.         tmp = q->head;
  85.         retn = q->head->data;
  86.         if (q->head == q->tail)
  87.             q->head = q->tail = NULL;
  88.         else
  89.             q->head = q->head->next;
  90.         free(tmp);
  91.         return retn;
  92.     }
  93.     void qpush (struct queue *q, void *data)
  94.     {
  95.         struct node *nw;
  96.         if (!(nw = (struct node *)calloc(sizeof(struct node), 1)))
  97.             return;
  98.         nw->data = data;
  99.         nw->next = NULL;
  100.         if (!q->tail && !q->head) {
  101.             q->tail = q->head = nw;
  102.             return;
  103.         }
  104.         q->tail->next = nw;
  105.         q->tail = nw;
  106.     }
  107.     int qcount (struct queue *q)
  108.     {
  109.         int c = 0;
  110.         if (!q || !q->head)
  111.             return -1;
  112.         for (struct node *ptr = q->head; ptr; ptr = ptr->next)
  113.             ++c;
  114.         return c;
  115.     }
  116. };
  117. #endif
Advertisement
Add Comment
Please, Sign In to add comment