summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukáš Ondráček <lukas.ondracek@nic.cz>2024-10-30 19:09:41 +0100
committerVladimír Čunát <vladimir.cunat@nic.cz>2024-11-04 14:39:13 +0100
commit388ff000b4350ab7a221db1af646d565dddf7758 (patch)
treef8b4ac5884722c8e99a157bfaf53257811e15505
parentdaemon/ratelimiting: fix runtime configuration reload (diff)
downloadknot-resolver-388ff000b4350ab7a221db1af646d565dddf7758.tar.xz
knot-resolver-388ff000b4350ab7a221db1af646d565dddf7758.zip
daemon/ratelimiting: polish
-rw-r--r--daemon/defer.c5
-rw-r--r--daemon/defer.h4
-rw-r--r--daemon/meson.build1
-rw-r--r--daemon/mmapped.c4
-rw-r--r--daemon/mmapped.h4
-rw-r--r--daemon/ratelimiting.c4
-rw-r--r--daemon/ratelimiting.h4
-rw-r--r--daemon/ratelimiting.test/tests.inc.c2
-rw-r--r--daemon/session2.c14
-rw-r--r--daemon/session2.h7
-rw-r--r--daemon/worker.c1
-rw-r--r--doc/_static/config.schema.json4
-rw-r--r--lib/kru.h16
-rw-r--r--python/knot_resolver/datamodel/rate_limiting_schema.py4
-rw-r--r--tests/unit/meson.build3
15 files changed, 52 insertions, 25 deletions
diff --git a/daemon/defer.c b/daemon/defer.c
index 14d79f30..ef24727d 100644
--- a/daemon/defer.c
+++ b/daemon/defer.c
@@ -1,3 +1,7 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
#include "daemon/defer.h"
#include "daemon/mmapped.h"
#include "daemon/session2.h"
@@ -113,7 +117,6 @@ struct pl_defer_sess_data {
struct pl_defer_iter_data {
struct protolayer_data h;
uint64_t req_stamp; // time when request was received, uses get_stamp()
- // TODO use different clock than CLOCK_THREAD_CPUTIME_ID?
};
/// Return whether we're using optimized variant right now.
diff --git a/daemon/defer.h b/daemon/defer.h
index ab7a6a8f..db1b083b 100644
--- a/daemon/defer.h
+++ b/daemon/defer.h
@@ -1,3 +1,7 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
#include <stdbool.h>
#include "lib/defines.h"
#include "lib/utils.h"
diff --git a/daemon/meson.build b/daemon/meson.build
index 332890b4..a3f95480 100644
--- a/daemon/meson.build
+++ b/daemon/meson.build
@@ -68,6 +68,7 @@ kresd_deps = [
subdir('lua')
+
kresd = executable(
'kresd',
kresd_src,
diff --git a/daemon/mmapped.c b/daemon/mmapped.c
index 8649833f..7c6ba099 100644
--- a/daemon/mmapped.c
+++ b/daemon/mmapped.c
@@ -1,3 +1,7 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
diff --git a/daemon/mmapped.h b/daemon/mmapped.h
index 912a46c1..2f810376 100644
--- a/daemon/mmapped.h
+++ b/daemon/mmapped.h
@@ -1,3 +1,7 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
#include <stdbool.h>
#define MMAPPED_WAS_FIRST 1
diff --git a/daemon/ratelimiting.c b/daemon/ratelimiting.c
index 8d34efbc..8f079004 100644
--- a/daemon/ratelimiting.c
+++ b/daemon/ratelimiting.c
@@ -1,3 +1,7 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
#include "daemon/ratelimiting.h"
#include "daemon/mmapped.h"
#include "lib/kru.h"
diff --git a/daemon/ratelimiting.h b/daemon/ratelimiting.h
index def9d2f3..1e609735 100644
--- a/daemon/ratelimiting.h
+++ b/daemon/ratelimiting.h
@@ -1,3 +1,7 @@
+/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
#include <stdbool.h>
#include "lib/defines.h"
#include "lib/utils.h"
diff --git a/daemon/ratelimiting.test/tests.inc.c b/daemon/ratelimiting.test/tests.inc.c
index e2427b5f..27e93543 100644
--- a/daemon/ratelimiting.test/tests.inc.c
+++ b/daemon/ratelimiting.test/tests.inc.c
@@ -94,7 +94,7 @@ static void test_rrl(void **state) {
/* create rrl table */
const char *tmpdir = test_tmpdir_create();
char mmap_file[64];
- stpcpy(stpcpy(mmap_file, tmpdir), "/rrl");
+ stpcpy(stpcpy(mmap_file, tmpdir), "/ratelimiting");
ratelimiting_init(mmap_file, RRL_TABLE_SIZE, RRL_INSTANT_LIMIT, RRL_RATE_LIMIT, 0);
if (KRU.initialize == KRU_GENERIC.initialize) {
diff --git a/daemon/session2.c b/daemon/session2.c
index 780a2fec..40328e13 100644
--- a/daemon/session2.c
+++ b/daemon/session2.c
@@ -328,6 +328,11 @@ static inline struct protolayer_data *protolayer_sess_data_get(
return (struct protolayer_data *)(pl_data_beg + offset);
}
+void *protolayer_sess_data_get_current(struct protolayer_iter_ctx *ctx)
+{
+ return protolayer_sess_data_get(ctx->session, ctx->layer_ix);
+}
+
/** Gets layer-specific iteration data for the layer with the specified index
* from the context. */
static inline struct protolayer_data *protolayer_iter_data_get(
@@ -353,11 +358,6 @@ void *protolayer_iter_data_get_current(struct protolayer_iter_ctx *ctx)
return protolayer_iter_data_get(ctx, ctx->layer_ix);
}
-void *protolayer_sess_data_get_current(struct protolayer_iter_ctx *ctx)
-{
- return protolayer_sess_data_get(ctx->session, ctx->layer_ix);
-}
-
static inline ssize_t session2_get_protocol(
struct session2 *s, enum protolayer_type protocol)
{
@@ -612,8 +612,6 @@ static int session2_submit(
if ((direction == PROTOLAYER_UNWRAP) && (layer_ix == 0))
defer_sample_start();
- int ret;
-
struct protolayer_iter_ctx *ctx = malloc(session->iter_ctx_size);
kr_require(ctx);
@@ -672,7 +670,7 @@ static int session2_submit(
globals->iter_init(ctx, iter_data);
}
- ret = protolayer_step(ctx);
+ int ret = protolayer_step(ctx);
if ((direction == PROTOLAYER_UNWRAP) && (layer_ix == 0))
defer_sample_stop();
return ret;
diff --git a/daemon/session2.h b/daemon/session2.h
index a95a54c1..957df6d9 100644
--- a/daemon/session2.h
+++ b/daemon/session2.h
@@ -535,14 +535,13 @@ size_t protolayer_queue_count_payload(const protolayer_iter_ctx_queue_t *queue);
* queue iterators, as it does not need to iterate through the whole queue. */
bool protolayer_queue_has_payload(const protolayer_iter_ctx_queue_t *queue);
-/** Gets layer-specific iteration data for the last processed layer.
- * To be used after returning from its callback for async continuation but before calling protolayer_continue. */
-void *protolayer_iter_data_get_current(struct protolayer_iter_ctx *ctx);
-
/** Gets layer-specific session data for the last processed layer.
* To be used after returning from its callback for async continuation but before calling protolayer_continue. */
void *protolayer_sess_data_get_current(struct protolayer_iter_ctx *ctx);
+/** Gets layer-specific iteration data for the last processed layer.
+ * To be used after returning from its callback for async continuation but before calling protolayer_continue. */
+void *protolayer_iter_data_get_current(struct protolayer_iter_ctx *ctx);
/** Layer-specific data - the generic struct. To be added as the first member of
* each specific struct. */
diff --git a/daemon/worker.c b/daemon/worker.c
index fe303802..c14f927f 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -72,7 +72,6 @@ struct request_ctx
} source;
};
-
/** Query resolution task. */
struct qr_task
{
diff --git a/doc/_static/config.schema.json b/doc/_static/config.schema.json
index 8ecbbbd4..bc24cdd0 100644
--- a/doc/_static/config.schema.json
+++ b/doc/_static/config.schema.json
@@ -1682,11 +1682,11 @@
},
"rate-limit": {
"type": "integer",
- "description": "Number of allowed queries per second from a single host."
+ "description": "Maximal number of allowed queries per second from a single host."
},
"instant-limit": {
"type": "integer",
- "description": "Number of allowed queries at a single point in time from a single host.",
+ "description": "Maximal number of allowed queries at a single point in time from a single host.",
"default": 50
},
"slip": {
diff --git a/lib/kru.h b/lib/kru.h
index b36feeb5..ef177ef8 100644
--- a/lib/kru.h
+++ b/lib/kru.h
@@ -22,7 +22,7 @@
#define ALIGNED_CPU_CACHE _Alignas(64)
-// An unsigned integral type used for prices, blocking occurs when sum of prices overflows.
+// An unsigned integral type used for prices, limiting occurs when sum of prices overflows.
// Greater than 16-bit type enables randomized fractional incrementing as the internal counters are still 16-bit.
// Exponential decay always uses randomized rounding on 32 bits.
typedef uint32_t kru_price_t;
@@ -49,8 +49,14 @@ struct kru_api {
/// Note that the _multi variants increase these totals
/// by tracking multiple keys in a single query.
///
+ /// The max_decay parameter sets maximal decrease of a counter per a time_now tick,
+ /// which occurs when the original value was just under the limit.
+ /// I.e. the value KRU_LIMIT will be lowered to (KRU_LIMIT - max_decay);
+ /// in general, the value is multiplied by (KRU_LIMIT - max_decay)/KRU_LIMIT each time_now tick
+ /// (typically time_now counts milliseconds).
+ ///
/// Returns false if kru is NULL or other failure occurs.
- bool (*initialize)(struct kru *kru, int capacity_log, kru_price_t max_decay); // TODO describe max_decay and some other args below
+ bool (*initialize)(struct kru *kru, int capacity_log, kru_price_t max_decay);
/// Calculate size of the KRU structure.
size_t (*get_size)(int capacity_log);
@@ -69,7 +75,9 @@ struct kru_api {
/// Returns a prefix (value in prefixes) on which the key is blocked, or zero if all queries passed.
/// Updates KRU only if no query is blocked, unless a race condition occurs --
/// in such a case all longer prefixes might have been updated.
- /// The key of i-th query consists of prefixes[i] bits of key, prefixes[i], and namespace.
+ /// The key of i-th query consists of prefixes[i] bits of key, prefixes[i], and namespace;
+ /// the specific namespace values may be arbitrary,
+ /// they just extend the keys to allow storing different noncolliding sets of them in the same table (such as IPv4 and IPv6).
/// If zero is returned, *max_load_out (unless NULL) is set to
/// the maximum of final values of the involved counters normalized to the limit 2^16.
uint8_t (*limited_multi_prefix_or)(struct kru *kru, uint32_t time_now,
@@ -79,7 +87,7 @@ struct kru_api {
/// Returns the maximum of final values of the involved counters normalized to the limit 2^16
/// and stores the corresponding prefix (value in prefixes) to *prefix_out (unless NULL).
/// Set prices to NULL to skip updating; otherwise, KRU is always updated, using maximal allowed value on overflow.
- /// The key of i-th query consists of prefixes[i] bits of key, prefixes[i], and namespace.
+ /// The key of i-th query consists of prefixes[i] bits of key, prefixes[i], and namespace; as above.
uint16_t (*load_multi_prefix_max)(struct kru *kru, uint32_t time_now,
uint8_t namespace, uint8_t key[static 16], uint8_t *prefixes, kru_price_t *prices, size_t queries_cnt, uint8_t *prefix_out);
};
diff --git a/python/knot_resolver/datamodel/rate_limiting_schema.py b/python/knot_resolver/datamodel/rate_limiting_schema.py
index 3030312d..1b6b46f2 100644
--- a/python/knot_resolver/datamodel/rate_limiting_schema.py
+++ b/python/knot_resolver/datamodel/rate_limiting_schema.py
@@ -7,8 +7,8 @@ class RateLimitingSchema(ConfigSchema):
---
capacity: Expected maximal number of blocked networks/hosts at the same time.
- rate_limit: Number of allowed queries per second from a single host.
- instant_limit: Number of allowed queries at a single point in time from a single host.
+ rate_limit: Maximal number of allowed queries per second from a single host.
+ instant_limit: Maximal number of allowed queries at a single point in time from a single host.
slip: Number of restricted responses out of which one is sent as truncated, the others are dropped.
"""
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 04d8d4a9..7e0be7b0 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -28,8 +28,7 @@ foreach unit_test : unit_tests
libuv,
lmdb,
libdnssec,
- # https://mesonbuild.com/howtox.html#add-math-library-lm-portably
- (meson.get_compiler('c').find_library('m', required : false)),
+ libm,
],
)