fix(relay): bounded resources for traffic spikes
- Reject envelopes for addresses without a device (404) instead of queueing them for 30 days; random addresses were the cheapest way to fill the relay's disk. - Per-sender hourly quota on stored envelopes (count and bytes, 429) and a count cap on each recipient's queue next to the byte cap. - Per-account attachment quota: bytes per day and bytes stored within the TTL, kept in memory only (no account-to-blob link is stored). - Disk watermarks: below a configurable share of free space the relay refuses new attachments, then new offline envelopes (507), before Postgres runs out of space. - WebSocket buffers 4 KiB read / unbuffered write: ~16.6 KiB per connection instead of ~137 KiB (10 500 connections measured at ~180 MiB including the DB pool). - reqwest with HTTP/2: APNs only accepts HTTP/2, so no iOS wake-up could ever be delivered. APNs registration with only a VoIP token is stored instead of deleted. - All limits configurable via environment (limits.rs). Defaults keep previous behaviour except registration per IP (50 + 1/10 s, for carrier-grade NAT) guarded by a global cap (40/s), separate Tor buckets (SEPOT_TOR_PEERS) and a rate limit on opening WebSockets. SEPOT_REGISTRATION_PAUSED=1 pauses new registrations (503). - Envelopes whose encoding exceeds the queue column limit are 400 before they count against the sender quota. Rate limiting moves from tower_governor to governor directly, so Tor and clearnet can use different quotas on the same route.
This commit is contained in:
@@ -42,13 +42,15 @@ tokio-util = { version = "0.7", features = ["io"] }
|
||||
# při AUTH. Relay NIKDY nešifruje/nedešifruje zprávy (hloupý relay).
|
||||
libsignal-protocol = { git = "https://github.com/signalapp/libsignal", tag = "v0.96.4" }
|
||||
libsignal-core = { git = "https://github.com/signalapp/libsignal", tag = "v0.96.4" }
|
||||
tower_governor = "0.8.0"
|
||||
# Rate limity (token bucket per IP / Tor / globálně, limits.rs)
|
||||
governor = "0.10"
|
||||
tower-http = { version = "0.7.0", features = ["timeout"] }
|
||||
|
||||
# Push budíčky (UnifiedPush/WebPush = POST na endpoint). rustls, ať build
|
||||
# zůstane bez OpenSSL (stejně jako sqlx tls-rustls). Bez default featur —
|
||||
# nechceme native-tls ani zbytečné kodeky.
|
||||
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json"] }
|
||||
# nechceme native-tls ani zbytečné kodeky. http2: APNs jiný protokol
|
||||
# nepřijme (HTTP/1.1 spojení odmítne) — bez něj nedorazil žádný iOS budíček.
|
||||
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json", "http2"] }
|
||||
# FCM fast mode: RS256 JWT pro OAuth2 service account flow
|
||||
jsonwebtoken = "9"
|
||||
# setrlimit(RLIMIT_NOFILE) při startu — docker dává soft limit 1024
|
||||
|
||||
Reference in New Issue
Block a user