summaryrefslogtreecommitdiff
path: root/ratelimit.c
diff options
context:
space:
mode:
Diffstat (limited to 'ratelimit.c')
-rw-r--r--ratelimit.c108
1 files changed, 0 insertions, 108 deletions
diff --git a/ratelimit.c b/ratelimit.c
deleted file mode 100644
index 38f756e..0000000
--- a/ratelimit.c
+++ /dev/null
@@ -1,108 +0,0 @@
-#include <pthread.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#define TABLE_SIZE 2048
-#define MAX_KEY_LEN 46
-#define STALE_SECONDS 30
-
-struct rl_entry {
- char ip[ MAX_KEY_LEN ];
- time_t last_request;
- int count;
- int in_use;
-};
-
-struct rl_table {
- struct rl_entry entries[ TABLE_SIZE ];
- pthread_mutex_t mutex;
-};
-
-struct rl_table* global_ratelimit = NULL;
-
-void ratelimit_init() {
- if (global_ratelimit != NULL) return;
-
- struct rl_table* table = malloc(sizeof(struct rl_table));
- if (!table) {
- perror("failed to alloc ratelimit table");
- exit(1);
- }
- memset(table->entries, 0, sizeof(table->entries));
- pthread_mutex_init(&table->mutex, NULL);
-
- global_ratelimit = table;
-}
-
-static uint32_t hash_ip(const char* ip) {
- uint32_t hash = 5381;
- while (*ip) hash = (hash << 5) + hash + *ip++;
- return hash % TABLE_SIZE;
-}
-
-int ratelimit_check(const char* ip) {
- ratelimit_init();
- pthread_mutex_lock(&global_ratelimit->mutex);
-
- time_t now = time(NULL);
- uint32_t index = hash_ip(ip);
- uint32_t probes = 0;
-
- while (probes < TABLE_SIZE) {
- struct rl_entry* entry = &global_ratelimit->entries[ index ];
-
- if (!entry->in_use) {
- strncpy(entry->ip, ip, MAX_KEY_LEN - 1);
- entry->ip[ MAX_KEY_LEN - 1 ] = '\0';
- entry->last_request = now;
- entry->count = 1;
- entry->in_use = 1;
- pthread_mutex_unlock(&global_ratelimit->mutex);
- return 1;
- }
-
- if (strcmp(entry->ip, ip) == 0) {
- if (now > entry->last_request) {
- entry->last_request = now;
- entry->count = 1;
- } else if (entry->count >= 4) {
- pthread_mutex_unlock(&global_ratelimit->mutex);
- return 0;
- } else {
- entry->count++;
- }
- pthread_mutex_unlock(&global_ratelimit->mutex);
- return 1;
- }
-
- if (entry->in_use && (now - entry->last_request) > STALE_SECONDS) {
- entry->in_use = 0;
- entry->count = 0;
- entry->last_request = 0;
- entry->ip[ 0 ] = '\0';
- strncpy(entry->ip, ip, MAX_KEY_LEN - 1);
- entry->ip[ MAX_KEY_LEN - 1 ] = '\0';
- entry->last_request = now;
- entry->count = 1;
- entry->in_use = 1;
- pthread_mutex_unlock(&global_ratelimit->mutex);
- return 1;
- }
-
- index = (index + 1) % TABLE_SIZE;
- probes++;
- }
-
- pthread_mutex_unlock(&global_ratelimit->mutex);
- return 0;
-}
-
-void ratelimit_free(struct rl_table* table) {
- if (table) {
- pthread_mutex_destroy(&table->mutex);
- free(table);
- }
-} \ No newline at end of file