Csilk 0.2.1
A lightweight, high-performance C HTTP web framework
Loading...
Searching...
No Matches
ratelimit.c File Reference

Simple IP-based rate limiting middleware implementation. More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <uv.h>
#include "csilk/core/internal.h"
#include "csilk/csilk.h"
Include dependency graph for ratelimit.c:

Data Structures

struct  ip_entry_t
 Rate-limit tracking entry for a single IP address. More...
 

Macros

#define MAX_IP_ENTRIES   1024
 Maximum number of distinct IP addresses tracked concurrently.
 
#define WINDOW_SIZE   60
 Rate limiting sliding window size in seconds.
 
#define EVICT_INTERVAL   300
 Interval (in seconds) at which stale entries are garbage-collected.
 

Functions

static void init_ratelimit_mutex ()
 Initialize the rate-limiting mutex (called once via uv_once).
 
static void evict_stale_entries (time_t now)
 Compact the IP table by removing entries whose last_seen timestamp is older than WINDOW_SIZE seconds.
 
static void evict_oldest_entry (void)
 Evict the single oldest entry from the IP table (LRU policy).
 
void csilk_rate_limit_middleware (csilk_ctx_t *c, int limit)
 IP-based rate limiting middleware with sliding window.
 

Variables

static ip_entry_t ip_table [MAX_IP_ENTRIES]
 
static int ip_count = 0
 
static time_t last_evict = 0
 
static uv_mutex_t ratelimit_mutex
 
static uv_once_t ratelimit_once = UV_ONCE_INIT
 

Detailed Description

Simple IP-based rate limiting middleware implementation.


Data Structure Documentation

◆ ip_entry_t

struct ip_entry_t

Rate-limit tracking entry for a single IP address.

Each entry stores the IP string, the request count within the current window, the timestamp when the counting window started, and the timestamp of the most recent request (used for LRU eviction when the table is full).

Data Fields
int count

Request count in current window.

char ip[46]

Client IP address string.

time_t last_reset

Timestamp when the window started.

time_t last_seen

Timestamp of last request (for LRU eviction).

Macro Definition Documentation

◆ EVICT_INTERVAL

#define EVICT_INTERVAL   300

Interval (in seconds) at which stale entries are garbage-collected.

A periodic eviction pass removes entries whose last_seen timestamp is older than WINDOW_SIZE seconds, preventing the table from filling with dead entries.

◆ MAX_IP_ENTRIES

#define MAX_IP_ENTRIES   1024

Maximum number of distinct IP addresses tracked concurrently.

When the table is full, the least recently seen entry is evicted to make room for new clients.

◆ WINDOW_SIZE

#define WINDOW_SIZE   60

Rate limiting sliding window size in seconds.

The request counter for each IP is reset if the last reset timestamp is older than this many seconds.

Function Documentation

◆ csilk_rate_limit_middleware()

void csilk_rate_limit_middleware ( csilk_ctx_t *  c,
int  limit 
)

IP-based rate limiting middleware with sliding window.

Simple per-IP rate-limiting middleware.

Tracks request counts per client IP address within a configurable window. If the number of requests from a given IP exceeds the limit, a 429 Too Many Requests response is sent (with a Retry-After header) and the pipeline is aborted.

The IP table is protected by a libuv mutex for thread safety. Stale entries are periodically evicted to prevent unbounded memory growth.

Parameters
cThe request context.
limitMaximum number of requests allowed per IP within the WINDOW_SIZE (60-second) sliding window.
Note
The mutex is initialized once via uv_once on the first call.
Warning
Rate limiting is per-worker-process. In multi-process deployments, each process maintains its own independent table unless an external store (Redis, etc.) is used instead.
If csilk_get_client_ip() returns NULL (e.g. in tests or certain proxy setups), the request is passed through without rate limiting.

◆ evict_oldest_entry()

static void evict_oldest_entry ( void  )
static

Evict the single oldest entry from the IP table (LRU policy).

Scans the ip_table for the entry with the smallest last_seen value and replaces it with the last entry in the table, decrementing ip_count. Called when the table is full and a new IP needs to be tracked.

◆ evict_stale_entries()

static void evict_stale_entries ( time_t  now)
static

Compact the IP table by removing entries whose last_seen timestamp is older than WINDOW_SIZE seconds.

Iterates over the table and compacts it in-place, updating ip_count to reflect the number of remaining active entries.

Parameters
nowThe current time to compare against last_seen.

◆ init_ratelimit_mutex()

static void init_ratelimit_mutex ( )
static

Initialize the rate-limiting mutex (called once via uv_once).

Creates the libuv mutex that protects the shared ip_table and ip_count from concurrent access across worker threads.

Variable Documentation

◆ ip_count

int ip_count = 0
static

◆ ip_table

ip_entry_t ip_table[MAX_IP_ENTRIES]
static

◆ last_evict

time_t last_evict = 0
static

◆ ratelimit_mutex

uv_mutex_t ratelimit_mutex
static

◆ ratelimit_once

uv_once_t ratelimit_once = UV_ONCE_INIT
static