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§
- Rate
Limit Config - Resolved three-layer rate-limit configuration.
- Three
Layer Rate Limiter - Three-layer rate limiter for inbound authenticated per-request traffic.
Enums§
- Reject
Layer - Layer that triggered a rejection. Used as a log/trace field and to pick
the right per-layer Counter via
RateLimitMetricsSink::rejected.
Traits§
- Rate
Limit Metrics Sink - 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 hotrejectedpath.