Skip to content

Feat/rate limit#11

Merged
Ataba29 merged 5 commits into
mainfrom
feat/rateLimit
Jul 2, 2026
Merged

Feat/rate limit#11
Ataba29 merged 5 commits into
mainfrom
feat/rateLimit

Conversation

@Ataba29

@Ataba29 Ataba29 commented Jul 1, 2026

Copy link
Copy Markdown
Owner

feat/rateLimit

What's in this PR

This PR introduces a full rate limiting layer to protect the server from abusive traffic using the Token Bucket algorithm — the same approach used by Stripe, GitHub, and AWS.

RateLimiter (src/Limit/Limiter.h/.cpp)

  • Per-IP token bucket: each IP starts with a configurable number of tokens, each request costs one token, tokens refill at a fixed rate per second
  • Global request cap: limits total requests per second across all IPs regardless of source
  • Lazy token refill: no background thread needed, tokens are calculated on demand based on elapsed time
  • Thread safe: separate mutexes for per-IP map and global window to minimize contention

Server integration (src/Server/Server.cpp)

  • Rate check happens in acceptClients before any job is handed to the thread pool
  • Blocked clients are dropped immediately with CloseSocket and continue — no worker thread is consumed
  • Client IP extracted using getpeername + inet_ntop (cross-platform, works on both Windows and Linux)

Unit tests (src/Tests/test_ratelimiter.cpp)

  • Normal traffic from multiple IPs is allowed
  • Single IP gets blocked after exhausting token bucket
  • Blocked IP does not affect other IPs
  • Global limit blocks all IPs once reached
  • Tokens refill correctly over time
  • Concurrent requests from same IP are handled safely without race conditions

Verified on both Windows (local) and Linux (Docker container)

@razimograbi razimograbi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall good job !
Very clean code

Comment thread src/Limit/Limiter.cpp
Comment on lines +31 to +35
if (elapsed >= 1)
{
globalCount = 0;
globalWindowStart = now;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We reset the global bucket count each second? Why?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the actual hardware is fast enough to handle a 1-second reset time, with the correct max global traffic per second adjusted, it won't harm the server

Comment thread src/Limit/Limiter.cpp Outdated
@razimograbi

Copy link
Copy Markdown
Collaborator

Approved

@Ataba29 Ataba29 merged commit d282499 into main Jul 2, 2026
@Ataba29 Ataba29 deleted the feat/rateLimit branch July 2, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants