networking · intermediate · ~15 min
Token-bucket rate limiting, a defensive shield against brute force.
Implement a single-slot token-bucket rate limiter — the smoothing technique behind rate-limited APIs and brute-force defenses.
Given the bucket struct (defined by the harness):
typedef struct { double tokens; double rate; double max; double last_refill; } bucket_t;
implement int rl_allow(bucket_t *b, double now) that decides whether one request is allowed at time now. It must:
rate * (now - last_refill) tokens, capped at max.last_refill = now.tokens >= 1.0, consume one token and return 1; otherwise return 0.b: the bucket (carries current tokens, refill rate per unit time, max capacity, and last_refill timestamp).now: the current time, in the same units as rate and last_refill.Return 1 if a token was available and consumed (request allowed), else 0 (request denied). The bucket is updated in place.
b = {tokens:0, rate:1, max:3, last_refill:0}
rl_allow(&b, 0.0) -> 0 (no tokens yet)
rl_allow(&b, 1.0) -> 1 (1s elapsed -> 1 token, consumed)
rl_allow(&b, 1.0) -> 0 (no time passed, bucket empty)
rl_allow(&b, 5.0) -> 1 (refill capped at max=3, one consumed)
max.now adds no tokens the second time.b: the bucket struct (tokens, rate, max, last_refill); now: current time.
1 if a token was available and consumed (allowed), else 0; b is updated in place.
Refill by rate*(now-last_refill), cap at max, set last_refill=now, then consume one token if >= 1.
#include <stdio.h>
int rl_allow(bucket_t *b, double now) { /* TODO */ return 0; }
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.