eh
This commit is contained in:
65
ratelimit.h
Normal file
65
ratelimit.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef RATELIMIT_THREADSAFE
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
ratelimit_table_type value;
|
||||
int count;
|
||||
double window_start;
|
||||
} ratelimit_t;
|
||||
|
||||
static struct {
|
||||
ratelimit_t data[256];
|
||||
size_t next;
|
||||
#ifdef RATELIMIT_THREADSAFE
|
||||
pthread_mutex_t lock;
|
||||
#endif
|
||||
} ratelimit_table = { {0}, 0
|
||||
#ifdef RATELIMIT_THREADSAFE
|
||||
, PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
};
|
||||
|
||||
static int rate_limited(ratelimit_table_type value, float window, int rate_limit) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
double now = ts.tv_sec + ts.tv_nsec * 1e-9;
|
||||
|
||||
#ifdef RATELIMIT_THREADSAFE
|
||||
pthread_mutex_lock(&ratelimit_table.lock);
|
||||
#endif
|
||||
|
||||
ratelimit_t* e = (void*)0;
|
||||
for (size_t i = 0; i < 256; i++) {
|
||||
if (memcmp(ratelimit_table.data[i].value, value, sizeof(ratelimit_table_type)) == 0) {
|
||||
e = &ratelimit_table.data[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!e) {
|
||||
e = &ratelimit_table.data[ratelimit_table.next++];
|
||||
memcpy(e->value, value, sizeof(ratelimit_table_type));
|
||||
e->window_start = now;
|
||||
e->count = 0;
|
||||
}
|
||||
|
||||
if (now - e->window_start >= window) {
|
||||
e->window_start = now;
|
||||
e->count = 0;
|
||||
}
|
||||
|
||||
const int allowed = e->count < rate_limit;
|
||||
if (allowed) e->count++;
|
||||
|
||||
#ifdef RATELIMIT_THREADSAFE
|
||||
pthread_mutex_unlock(&ratelimit_table.lock);
|
||||
#endif
|
||||
|
||||
return allowed ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user