Implement token bucket rate limiting with IPv6 /64 normalization

- Add TokenBucket with nodelay semantics (nginx limit_req burst nodelay)
- Per-IP rate limiting: IPv4 /32, IPv6 /64 prefix normalization
- DashMap for concurrent access, ArcSwap for lock-free config reads
- Background eviction task for stale entry cleanup
- 429 response with plain text body, RATE_LIMIT log prefix
- Config reload adopts new rate/burst on next request without clearing state
- Unit tests for bucket algorithm and IPv6 normalization
- Integration tests for 429 responses and per-IP independence
This commit is contained in:
2026-06-11 13:01:25 +00:00
parent f1cada010f
commit 2791070971
5 changed files with 592 additions and 3 deletions

23
Cargo.lock generated
View File

@@ -489,6 +489,20 @@ version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "dashmap"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
dependencies = [
"cfg-if",
"crossbeam-utils",
"hashbrown 0.14.5",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]]
name = "data-encoding"
version = "2.11.0"
@@ -789,6 +803,12 @@ dependencies = [
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.17.1"
@@ -1064,7 +1084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
"hashbrown",
"hashbrown 0.17.1",
]
[[package]]
@@ -1584,6 +1604,7 @@ dependencies = [
"arc-swap",
"axum",
"clap",
"dashmap",
"futures",
"hyper",
"rcgen",