on master help sign in
Remove unused gateClientWrite rate limiter
commitabe00eedec183acf0a720ee51392294f6e87b720 authoriko <mail@iko.soy> dateThu 7 May 2026, 20:53 (5 months ago) parentc53339b
1 file changed+14−35
server.knot+14−35
server.knot+14−35
@@ -131,12 +131,6 @@ maxLookupRatePerKey = 5
131131-- Window for the per-key lookup rate limit (1 s).
132132lookupRateWindowMs : Int<Ms>
133133lookupRateWindowMs = 1000
134−-- Other client write requests permitted per key per window.
135−maxClientWriteRatePerKey : Int
136−maxClientWriteRatePerKey = 10
137−-- Window for the per-key client-write rate limit (1 s).
138−clientWriteRateWindowMs : Int<Ms>
139−clientWriteRateWindowMs = 1000
140134-- Requests permitted per source IP per window (covers unauthenticated traffic).
141135maxIpRatePerIp : Int
142136maxIpRatePerIp = 10
@@ -336,8 +330,6 @@ type ActivePoll = {pubkey: PubkeyHex, startedAt: Timestamp}
336330*challengeRates : [RateEntry]
337331-- Per-key counters for read-only lookups (presence, /messages/list).
338332*lookupRates : [RateEntry]
339−-- Per-key counters for misc client writes (/messages/status).
340−*clientWriteRates : [RateEntry]
341333-- Per-peer counters for inbound federation calls.
342334*federationRates : [RateEntry]
343335-- Per-source-IP counters; gate for unauthenticated traffic.
@@ -427,8 +419,8 @@ route MaintenanceApi where
427419 POST {pubkey: PubkeyHex} /maintenance/messages/purge headers {authorization: Text} -> {ok: Bool, purgedCount: Int} = AdminPurgeMessages
428420 POST {ip: Text} /maintenance/sessions/revoke-ip headers {authorization: Text} -> {ok: Bool, revokedCount: Int, affectedKeys: Int} = AdminRevokeIp
429421 POST {limit: Int} /maintenance/sessions/list headers {authorization: Text} -> {sessions: [{pubkey: PubkeyHex, count: Int, ips: [Text], latestExpiry: Timestamp}], ok: Bool, total: Int} = AdminListAllSessions
430− GET /maintenance/rate-limits headers {authorization: Text} -> {ok: Bool, globalRequest: Int, ipRate: Int, sendRate: Int, federationRate: Int, authGlobal: Int, recvRate: Int, challengeRate: Int, pairRate: Int, lookupRate: Int, clientWriteRate: Int} = GetRateLimits
431− POST {globalRequest: Int, ipRate: Int, sendRate: Int, federationRate: Int, authGlobal: Int, recvRate: Int, challengeRate: Int, pairRate: Int, lookupRate: Int, clientWriteRate: Int} /maintenance/rate-limits headers {authorization: Text} -> {ok: Bool} = SetRateLimits
422+ GET /maintenance/rate-limits headers {authorization: Text} -> {ok: Bool, globalRequest: Int, ipRate: Int, sendRate: Int, federationRate: Int, authGlobal: Int, recvRate: Int, challengeRate: Int, pairRate: Int, lookupRate: Int} = GetRateLimits
423+ POST {globalRequest: Int, ipRate: Int, sendRate: Int, federationRate: Int, authGlobal: Int, recvRate: Int, challengeRate: Int, pairRate: Int, lookupRate: Int} /maintenance/rate-limits headers {authorization: Text} -> {ok: Bool} = SetRateLimits
432424 POST /maintenance/nonces/flush headers {authorization: Text} -> {ok: Bool, flushedCount: Int} = FlushNonces
433425 POST {server: ServerName} /maintenance/allow headers {authorization: Text} -> {ok: Bool, allowed: Int} = AllowPeer
434426 POST {server: ServerName} /maintenance/unallow headers {authorization: Text} -> {ok: Bool, removed: Bool} = UnallowPeer
@@ -466,7 +458,7 @@ route StatsApi where
466458 GET /stats/key/{pubkey: PubkeyHex} headers {authorization: Text} -> {messages: Int, presence: [KeyPresenceEntry], sessions: Int, forwards: Int, forwardDetails: [{server: Text, retries: Int}], activePolls: Int, ok: Bool} = StatsKey
467459 POST {limit: Int} /stats/top-recipients headers {authorization: Text} -> {recipients: [RecipientCount], ok: Bool, total: Int} = TopRecipients
468460 GET /stats/forwards headers {authorization: Text} -> {servers: [{server: Text, count: Int, totalRetries: Int}], ok: Bool, total: Int} = StatsForwards
469− GET /stats/rates headers {authorization: Text} -> {ok: Bool, scalePct: Int, globalRequest: Int, ipRate: Int, sendRate: Int, federationRate: Int, authGlobal: Int, recvRate: Int, challengeRate: Int, pairRate: Int, lookupRate: Int, clientWriteRate: Int} = StatsRates
461+ GET /stats/rates headers {authorization: Text} -> {ok: Bool, scalePct: Int, globalRequest: Int, ipRate: Int, sendRate: Int, federationRate: Int, authGlobal: Int, recvRate: Int, challengeRate: Int, pairRate: Int, lookupRate: Int} = StatsRates
470462
471463route MetricsApi where
472464 GET /metrics headers {authorization: Text} -> {metrics: Text, ok: Bool} = Metrics
@@ -667,8 +659,8 @@ isBadServerName = \sn -> sn == "" || sn == "localhost" || not all (chars sn) (\c
667659-- Auth helpers
668660-- ============================================
669661-- Bearer token extraction, session lookup, maintenance secret check, and the
670−-- `gateAuth`/`gateClientWrite`/`gateLookup` combinators that every client
671−-- handler funnels through (global rate → per-key rate → session).
662+-- `gateAuth`/`gateLookup` combinators that every client handler funnels
663+-- through (global rate → per-key rate → session).
672664-- Federation requests use a separate path (`withFederationAuth`) using
673665-- Ed25519-signed auth verified via the peer's published public key.
674666
@@ -705,19 +697,8 @@ gateAuth = \auth ip t mkErr onAuth -> do
705697 let err = \e -> yield (mkErr e)
706698 if g then err "rate_limited" else withSessionAuth auth t ip (err "unauthorized") onAuth
707699
708−-- gateAuth + per-key rate gate. `rateResp` is the response value when the per-key gate trips.
709−gateClientWrite : Text -> Text -> Int<Ms> -> (Text -> a) -> a -> (Text -> IO {} a) -> IO {rw *globalRateCount, rw *globalRateWindowStart, r *sessions} a
710−gateClientWrite = \auth ip t mkErr rateResp onAuth ->
711− gateAuth auth ip t mkErr (\pk -> do
712− lim <- atomic do
713− rates <- *clientWriteRates
714− let r = checkRate rates pk maxClientWriteRatePerKey clientWriteRateWindowMs t
715− -- TODO: make this no be a `replace`
716− *clientWriteRates = r.entries
717− yield r.limited
718− if lim then yield rateResp else onAuth pk)
719−
720−-- Variant of `gateClientWrite` that uses the per-key lookup-rate window instead.
700+-- gateAuth + per-key lookup-rate gate. `rateResp` is the response value when
701+-- the per-key gate trips.
721702gateLookup : Text -> Text -> Int<Ms> -> (Text -> a) -> a -> (Text -> IO {} a) -> IO {rw *globalRateCount, rw *globalRateWindowStart, r *sessions} a
722703gateLookup = \auth ip t mkErr rateResp onAuth ->
723704 gateAuth auth ip t mkErr (\pk -> do
@@ -1864,7 +1845,7 @@ handleAdminListAllSessions = \limit authorization -> withMaintAuth authorization
18641845
18651846-- GET /maintenance/rate-limits: expose the configured rate ceilings. Returns
18661847-- zeros for unauthenticated callers (response shape stays stable).
1867−handleGetRateLimits : Text -> IO {r *runtimeMaintenanceSecret} {authGlobal: Int, challengeRate: Int, clientWriteRate: Int, federationRate: Int, globalRequest: Int, ipRate: Int, lookupRate: Int, ok: Bool, pairRate: Int, recvRate: Int, sendRate: Int}
1848+handleGetRateLimits : Text -> IO {r *runtimeMaintenanceSecret} {authGlobal: Int, challengeRate: Int, federationRate: Int, globalRequest: Int, ipRate: Int, lookupRate: Int, ok: Bool, pairRate: Int, recvRate: Int, sendRate: Int}
18681849handleGetRateLimits = \authorization -> do
18691850 ok <- verifyMaintenanceAuth authorization
18701851 let v = \x -> if ok then x else 0
@@ -1878,14 +1859,13 @@ handleGetRateLimits = \authorization -> do
18781859 recvRate: v maxRecvRatePerKey,
18791860 challengeRate: v maxChallengeRatePerKey,
18801861 pairRate: v maxPairRatePerPair,
1881− lookupRate: v maxLookupRatePerKey,
1882− clientWriteRate: v maxClientWriteRatePerKey
1862+ lookupRate: v maxLookupRatePerKey
18831863 }
18841864
18851865-- POST /maintenance/rate-limits: stub. Rate ceilings are compile-time constants
18861866-- in this simplified server, so this just authorizes and returns ok=true.
1887−handleSetRateLimits : a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> Text -> IO {r *runtimeMaintenanceSecret} {ok: Bool}
1888−handleSetRateLimits = \globalRequest ipRate sendRate federationRate authGlobal recvRate challengeRate pairRate lookupRate clientWriteRate authorization -> do
1867+handleSetRateLimits : a -> b -> c -> d -> e -> f -> g -> h -> i -> Text -> IO {r *runtimeMaintenanceSecret} {ok: Bool}
1868+handleSetRateLimits = \globalRequest ipRate sendRate federationRate authGlobal recvRate challengeRate pairRate lookupRate authorization -> do
18891869 authorized <- verifyMaintenanceAuth authorization
18901870 yield {ok: authorized}
18911871
@@ -2203,7 +2183,7 @@ handleStatsForwards = \authorization -> withMaintAuth authorization (yield {
22032183
22042184-- GET /stats/rates: same shape as /maintenance/rate-limits with an extra
22052185-- scalePct field. Kept separate for backwards compatibility with older clients.
2206−handleStatsRates : Text -> IO {r *runtimeMaintenanceSecret} {authGlobal: Int, challengeRate: Int, clientWriteRate: Int, federationRate: Int, globalRequest: Int, ipRate: Int, lookupRate: Int, ok: Bool, pairRate: Int, recvRate: Int, scalePct: Int, sendRate: Int}
2186+handleStatsRates : Text -> IO {r *runtimeMaintenanceSecret} {authGlobal: Int, challengeRate: Int, federationRate: Int, globalRequest: Int, ipRate: Int, lookupRate: Int, ok: Bool, pairRate: Int, recvRate: Int, scalePct: Int, sendRate: Int}
22072187handleStatsRates = \authorization -> do
22082188 ok <- verifyMaintenanceAuth authorization
22092189 let v = \x -> if ok then x else 0
@@ -2218,8 +2198,7 @@ handleStatsRates = \authorization -> do
22182198 recvRate: v maxRecvRatePerKey,
22192199 challengeRate: v maxChallengeRatePerKey,
22202200 pairRate: v maxPairRatePerPair,
2221− lookupRate: v maxLookupRatePerKey,
2222− clientWriteRate: v maxClientWriteRatePerKey
2201+ lookupRate: v maxLookupRatePerKey
22232202 }
22242203
22252204-- GET /metrics: Prometheus-style text exposition of the most useful gauges.
@@ -2280,7 +2259,7 @@ api = serve Api where
22802259 AdminPurgeMessages = \{pubkey, authorization} -> handleAdminPurgeMessages pubkey authorization
22812260 AdminRevokeIp = \{ip, authorization} -> handleAdminRevokeIp ip authorization
22822261 GetRateLimits = \{authorization} -> handleGetRateLimits authorization
2283− SetRateLimits = \{globalRequest, ipRate, sendRate, federationRate, authGlobal, recvRate, challengeRate, pairRate, lookupRate, clientWriteRate, authorization} -> handleSetRateLimits globalRequest ipRate sendRate federationRate authGlobal recvRate challengeRate pairRate lookupRate clientWriteRate authorization
2262+ SetRateLimits = \{globalRequest, ipRate, sendRate, federationRate, authGlobal, recvRate, challengeRate, pairRate, lookupRate, authorization} -> handleSetRateLimits globalRequest ipRate sendRate federationRate authGlobal recvRate challengeRate pairRate lookupRate authorization
22842263 FlushNonces = \{authorization} -> handleFlushNonces authorization
22852264 AllowPeer = \{server, authorization} -> handleAllowPeer server authorization
22862265 UnallowPeer = \{server, authorization} -> handleUnallowPeer server authorization