Skip to content

Commit 8c228a8

Browse files
committed
datamodel: stabilize rate-limiting schema
1 parent 9588fa8 commit 8c228a8

File tree

5 files changed

+56
-31
lines changed

5 files changed

+56
-31
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Incompatible changes
3232
- /dnssec/trust-anchor-sentinel -> /dnssec/sentinel
3333
- /dnssec/trust-anchor-signal-query -> /dnssec/signal-query
3434
- /logging/dnssec-bogus -> /dnssec/logging-bogus
35+
- /rate-limiting/log-period -> /rate-limiting/logging-period
3536

3637

3738
Knot Resolver 6.0.11 (2025-02-26)

doc/_static/config.schema.json

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,36 +1567,42 @@
15671567
},
15681568
"rate-limiting": {
15691569
"description": "Configuration of rate limiting.",
1570-
"type": [
1571-
"object",
1572-
"null"
1573-
],
1570+
"type": "object",
15741571
"properties": {
1575-
"capacity": {
1576-
"type": "integer",
1577-
"minimum": 1,
1578-
"description": "Expected maximal number of blocked networks/hosts at the same time.",
1579-
"default": 524288
1572+
"enabled": {
1573+
"type": "boolean",
1574+
"description": "Enable/disable rate limiting",
1575+
"default": false
15801576
},
15811577
"rate-limit": {
1582-
"type": "integer",
1578+
"type": [
1579+
"integer",
1580+
"null"
1581+
],
15831582
"minimum": 1,
1584-
"description": "Maximal number of allowed queries per second from a single host."
1583+
"description": "Maximal number of allowed queries per second from a single host.",
1584+
"default": null
15851585
},
15861586
"instant-limit": {
15871587
"type": "integer",
15881588
"minimum": 1,
15891589
"description": "Maximal number of allowed queries at a single point in time from a single host.",
15901590
"default": 50
15911591
},
1592+
"capacity": {
1593+
"type": "integer",
1594+
"minimum": 1,
1595+
"description": "Expected maximal number of blocked networks/hosts at the same time.",
1596+
"default": 524288
1597+
},
15921598
"slip": {
15931599
"type": "integer",
15941600
"minimum": 0,
15951601
"maximum": 32,
15961602
"description": "Number of restricted responses out of which one is sent as truncated, the others are dropped.",
15971603
"default": 2
15981604
},
1599-
"log-period": {
1605+
"logging-period": {
16001606
"type": "string",
16011607
"pattern": "^(\\d+)(us|ms|s|m|h|d)$",
16021608
"description": "Minimal time between two log messages, or '0s' to disable.",
@@ -1608,7 +1614,15 @@
16081614
"default": false
16091615
}
16101616
},
1611-
"default": null
1617+
"default": {
1618+
"enabled": false,
1619+
"rate_limit": null,
1620+
"instant_limit": 50,
1621+
"capacity": 524288,
1622+
"slip": 2,
1623+
"logging_period": "0s",
1624+
"dry_run": false
1625+
}
16121626
},
16131627
"prioritization": {
16141628
"description": "Configuration of request prioritization (defer).",

python/knot_resolver/datamodel/config_schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class Raw(ConfigSchema):
125125
dns64: Dns64Schema = Dns64Schema()
126126
logging: LoggingSchema = LoggingSchema()
127127
monitoring: MonitoringSchema = MonitoringSchema()
128-
rate_limiting: Optional[RateLimitingSchema] = None
128+
rate_limiting: RateLimitingSchema = RateLimitingSchema()
129129
prioritization: PrioritizationSchema = PrioritizationSchema()
130130
lua: LuaSchema = LuaSchema()
131131

@@ -146,7 +146,7 @@ class Raw(ConfigSchema):
146146
dns64: Dns64Schema
147147
logging: LoggingSchema
148148
monitoring: MonitoringSchema
149-
rate_limiting: Optional[RateLimitingSchema]
149+
rate_limiting: RateLimitingSchema
150150
prioritization: PrioritizationSchema
151151
lua: LuaSchema
152152

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Optional
2+
13
from knot_resolver.datamodel.types import (
24
Int0_32,
35
IntPositive,
@@ -11,24 +13,29 @@ class RateLimitingSchema(ConfigSchema):
1113
Configuration of rate limiting.
1214
1315
---
14-
capacity: Expected maximal number of blocked networks/hosts at the same time.
16+
enabled: Enable/disable rate limiting
1517
rate_limit: Maximal number of allowed queries per second from a single host.
1618
instant_limit: Maximal number of allowed queries at a single point in time from a single host.
19+
capacity: Expected maximal number of blocked networks/hosts at the same time.
1720
slip: Number of restricted responses out of which one is sent as truncated, the others are dropped.
18-
log_period: Minimal time between two log messages, or '0s' to disable.
21+
logging_period: Minimal time between two log messages, or '0s' to disable.
1922
dry_run: Perform only classification and logging but no restrictions.
2023
"""
2124

22-
capacity: IntPositive = IntPositive(524288)
23-
rate_limit: IntPositive
25+
enabled: bool = False
26+
rate_limit: Optional[IntPositive] = None
2427
instant_limit: IntPositive = IntPositive(50)
28+
capacity: IntPositive = IntPositive(524288)
2529
slip: Int0_32 = Int0_32(2)
26-
log_period: TimeUnit = TimeUnit("0s")
30+
logging_period: TimeUnit = TimeUnit("0s")
2731
dry_run: bool = False
2832

2933
def _validate(self) -> None:
34+
if self.enabled and not self.rate_limit:
35+
raise ValueError("'rate-limit' has to be configured to enable rate limiting")
36+
3037
max_instant_limit = int(2**32 // 768 - 1)
3138
if not int(self.instant_limit) <= max_instant_limit:
3239
raise ValueError(f"'instant-limit' has to be in range 1..{max_instant_limit}")
33-
if not int(self.rate_limit) <= 1000 * int(self.instant_limit):
40+
if self.rate_limit and not int(self.rate_limit) <= 1000 * int(self.instant_limit):
3441
raise ValueError("'rate-limit' has to be in range 1..(1000 * instant-limit)")
Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
{% from 'macros/common_macros.lua.j2' import boolean %}
22

3-
{% if cfg.rate_limiting.rate_limit is defined and cfg.rate_limiting.rate_limit -%}
4-
assert(C.ratelimiting_init(
5-
'{{ cfg.rundir }}/ratelimiting',
6-
{{ cfg.rate_limiting.capacity }},
7-
{{ cfg.rate_limiting.instant_limit }},
8-
{{ cfg.rate_limiting.rate_limit }},
9-
{{ cfg.rate_limiting.slip }},
10-
{{ cfg.rate_limiting.log_period.millis() }},
11-
{{ boolean(cfg.rate_limiting.dry_run) }}) == 0)
12-
{%- endif %}
3+
{% if cfg.rate_limiting.enabled %}
4+
assert(
5+
C.ratelimiting_init(
6+
'{{ cfg.rundir }}/ratelimiting',
7+
{{ cfg.rate_limiting.capacity }},
8+
{{ cfg.rate_limiting.instant_limit }},
9+
{{ cfg.rate_limiting.rate_limit }},
10+
{{ cfg.rate_limiting.slip }},
11+
{{ cfg.rate_limiting.log_period.millis() }},
12+
{{ boolean(cfg.rate_limiting.dry_run) }}
13+
) == 0
14+
)
15+
{% endif %}

0 commit comments

Comments
 (0)