Files
fastfetch_server/ratelimit.h
2026-05-27 15:27:37 +03:00

66 lines
1.4 KiB
C

#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;
}