diff options
Diffstat (limited to 'ratelimit.c')
| -rw-r--r-- | ratelimit.c | 108 |
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 |
