]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/ratelimiting: polish
authorLukáš Ondráček <lukas.ondracek@nic.cz>
Wed, 30 Oct 2024 18:09:41 +0000 (19:09 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 4 Nov 2024 13:39:13 +0000 (14:39 +0100)
15 files changed:
daemon/defer.c
daemon/defer.h
daemon/meson.build
daemon/mmapped.c
daemon/mmapped.h
daemon/ratelimiting.c
daemon/ratelimiting.h
daemon/ratelimiting.test/tests.inc.c
daemon/session2.c
daemon/session2.h
daemon/worker.c
doc/_static/config.schema.json
lib/kru.h
python/knot_resolver/datamodel/rate_limiting_schema.py
tests/unit/meson.build

index 14d79f30b014621084bfcd2aa318f2c8e4d74e86..ef24727df212056b8f9b5ee37b387904b668272a 100644 (file)
@@ -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.
index ab7a6a8f67efc0564f9e0201ab66098def28c865..db1b083b3700740def5276cbcf31718d9447e0b2 100644 (file)
@@ -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"
index 332890b463d2b1a6319d9c98464c02befd3fea4c..a3f95480b2bb7a535564e0aa1abb6ab9fd4d9210 100644 (file)
@@ -68,6 +68,7 @@ kresd_deps = [
 
 subdir('lua')
 
+
 kresd = executable(
   'kresd',
   kresd_src,
index 8649833f1ae8379e5f048ab244b99b434a7b56a7..7c6ba099f5c3e2fcfbea87d02e12b5e9872758b5 100644 (file)
@@ -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>
index 912a46c1f9fb23648d78a475d1dff0123581adea..2f810376ea12acd44f3095e06417bdf0d160913a 100644 (file)
@@ -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
index 8d34efbca92b5ffacf5dd6aacb5ef1e99fb1a658..8f079004a952379dc2ba44b7ce5a2b7ba0cd84ff 100644 (file)
@@ -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"
index def9d2f3f482e3350db404cbd85968f76a3c1f4e..1e609735f0ca08fd062d99ba5fb89313fabe8a09 100644 (file)
@@ -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"
index e2427b5f2ea9ee7f94ad4b3722d7c6b3cc88f164..27e935438ebca7dabdcf034f1a2067caa63976f9 100644 (file)
@@ -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) {
index 780a2fec0e6ad0400b49b98ee9dc40962c6126ab..40328e13225fe1eb57bb0fe254f89b686a4028da 100644 (file)
@@ -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;
index a95a54c1d0299ed21fb45036839071d4a57e7148..957df6d9c7f7cd99b70c3cc9fd50ec93f68d4d7b 100644 (file)
@@ -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. */
index fe3038028d8e0e460a5e2ac6ac087902c24e1864..c14f927f8a934d30c4ddf10d1a00a82bba87142a 100644 (file)
@@ -72,7 +72,6 @@ struct request_ctx
        } source;
 };
 
-
 /** Query resolution task. */
 struct qr_task
 {
index 8ecbbbd4399bbf38ad7892bd3ca604d8acdf7ee0..bc24cdd0be62f03338d4de48319b914a0ac89300 100644 (file)
                 },
                 "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": {
index b36feeb59786dc6650859b9c67b9acaf58200acb..ef177ef8d8bf60e2d1d763c9c1d4476d8331cc8f 100644 (file)
--- 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);
 };
index 3030312de3a08f08b886ba5363df1d0304a33d17..1b6b46f269d68a9701f7257c10fe866c29f905ea 100644 (file)
@@ -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.
     """
 
index 04d8d4a9521778babb72ff48c5eda7874f78ce5a..7e0be7b071070624aab278e95f89fdcfa9222d68 100644 (file)
@@ -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,
     ],
   )