Skip to main content

Module rate_limit

Module rate_limit 

Source
Expand description

Shared three-layer token-bucket rate limiter for per-request inbound traffic on authenticated QUIC handlers.

This is the engine behind both the cdn/dht/v1 limiter (ADR 022 §DHT Rate Limiting, via crate::dht::rate_limit::DhtRateLimiter) and the cdn/probe/v1 limiter (ADR 005 §Probe rate limiting, via crate::handlers::probe_rate_limit::ProbeRateLimiter). The two ADRs specify the identical three-layer shape — the differences are the default parameters, the operator-visible metric names, and that the DHT path additionally drives the engine’s batch-token accounting (ThreeLayerRateLimiter::admit_batch_extra) while the probe path issues exactly one ThreeLayerRateLimiter::check per connection. So the mechanism lives here once and each path supplies its own RateLimitMetricsSink.

Distinct from the connection-level crate::dispatch::ConnectionLimiter: that limiter caps how many connections we accept; this one caps the per-request work done on each accepted connection (for DHT, many requests per connection; the probe path is one probe per connection). Both run — the connection limiter rejects floods at handshake, this layer rejects per-request floods on a successfully accepted connection.

§Layered checks

Layers fire global → per-IP → per-peer (cheapest-first ordering). A request rejected by the global cap never pays the per-IP map lookup; a per-IP rejection never pays the per-peer map lookup. The first rejection short-circuits and is the only one reported to the sink’s RateLimitMetricsSink::rejected — one unlabeled Counter per layer, per the sibling-counter convention settled in #1475 (see RejectLayer below and adr/appendix-observability.md § Reason splits). Not a backend limitation: iroh_metrics supports labels via Family<L, M>, which DecdnMetrics::probe_hold_unavailable and DecdnMetrics::streams_active both use. Each layer has an unrelated remedy, so no alert spans the family. Operators recover the rolled-up rate with sum(rate({__name__=~"decdn_(probe|dht)_rate_limit_rejected_(per_peer|per_ip|global)_total"}[1m])).

Structs§

RateLimitConfig
Resolved three-layer rate-limit configuration.
ThreeLayerRateLimiter
Three-layer rate limiter for inbound authenticated per-request traffic.

Enums§

RejectLayer
Layer that triggered a rejection. Used as a log/trace field and to pick the right per-layer Counter via RateLimitMetricsSink::rejected.

Traits§

RateLimitMetricsSink
Metrics fan-out for a ThreeLayerRateLimiter. Each protocol path (cdn/dht/v1, cdn/probe/v1) supplies an implementation that routes to its own operator-visible counters/gauges, so the limiter core stays backend-agnostic. Implementations must be cheap and lock-free on the hot rejected path.