]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
rrl: renaming, movements, create defer protolayer docs-develop-rrl-8r8r8r/deployments/4197
authorLukáš Ondráček <lukas.ondracek@nic.cz>
Tue, 28 May 2024 14:47:17 +0000 (16:47 +0200)
committerLukáš Ondráček <lukas.ondracek@nic.cz>
Tue, 28 May 2024 14:47:17 +0000 (16:47 +0200)
27 files changed:
daemon/defer.c [new file with mode: 0644]
daemon/defer.h [new file with mode: 0644]
daemon/lua/kres-gen-30.lua
daemon/lua/kres-gen-31.lua
daemon/lua/kres-gen-32.lua
daemon/lua/kres-gen.sh
daemon/main.c
daemon/meson.build
daemon/ratelimiting.c [moved from daemon/rrl/api.c with 94% similarity]
daemon/ratelimiting.h [new file with mode: 0644]
daemon/ratelimiting.test/tests-parallel.c [moved from daemon/rrl/tests-parallel.c with 98% similarity]
daemon/ratelimiting.test/tests.c [moved from daemon/rrl/tests.c with 98% similarity]
daemon/ratelimiting.test/tests.inc.c [moved from daemon/rrl/tests.inc.c with 96% similarity]
daemon/rrl/api.h [deleted file]
daemon/rrl/meson.build [deleted file]
daemon/session2.c
daemon/session2.h
daemon/worker.c
lib/kru-avx2.c [moved from daemon/rrl/kru-avx2.c with 100% similarity]
lib/kru-decay.inc.c [moved from daemon/rrl/kru-decay.inc.c with 100% similarity]
lib/kru-generic.c [moved from daemon/rrl/kru-generic.c with 100% similarity]
lib/kru.h [moved from daemon/rrl/kru.h with 100% similarity]
lib/kru.inc.c [moved from daemon/rrl/kru.inc.c with 100% similarity]
lib/meson.build
manager/knot_resolver_manager/datamodel/templates/rate_limiting.lua.j2
meson.build
modules/policy/policy.lua

diff --git a/daemon/defer.c b/daemon/defer.c
new file mode 100644 (file)
index 0000000..66b2667
--- /dev/null
@@ -0,0 +1,28 @@
+#include "daemon/defer.h"
+#include "lib/kru.h"
+
+// TODO: move kru_defer to another file
+
+#include "daemon/session2.h"
+
+defer_sample_state_t defer_sample_state = {
+       .do_sample = true, // FIXME: start with false, set to true based on config when opening KRU
+       .is_accounting = 0,
+};
+
+
+static enum protolayer_iter_cb_result pl_defer_unwrap(
+               void *sess_data, void *iter_data,
+               struct protolayer_iter_ctx *ctx)
+{
+
+       kr_log_notice(DEVEL, "DEFER: %s\n",
+                       kr_straddr(&defer_sample_state.addr.ip));
+
+       return protolayer_continue(ctx);
+       //return protolayer_async();
+}
+
+void defer_init(void) {
+       protolayer_globals[PROTOLAYER_TYPE_DEFER].unwrap = pl_defer_unwrap;
+}
diff --git a/daemon/defer.h b/daemon/defer.h
new file mode 100644 (file)
index 0000000..32f7da7
--- /dev/null
@@ -0,0 +1,78 @@
+#include <stdbool.h>
+#include "lib/defines.h"
+#include "lib/utils.h"
+
+// TODO: reconsider `static inline` cases below
+
+
+typedef struct {
+       bool do_sample; /// whether to sample; could be important if _COARSE isn't available
+       int8_t is_accounting; /// whether currently accounting the time to someone; should be 0/1
+       union kr_sockaddr addr; /// request source (to which we account) or AF_UNSPEC if unknown yet
+       uint64_t stamp; /// monotonic nanoseconds, probably won't wrap
+} defer_sample_state_t;
+extern defer_sample_state_t defer_sample_state;
+
+#include <time.h>
+static inline uint64_t get_stamp(void)
+{
+       struct timespec now_ts = {0};
+       clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now_ts);
+       return now_ts.tv_nsec + 1000*1000*1000 * (uint64_t)now_ts.tv_sec;
+}
+
+/// Start accounting work, if not doing it already.
+static inline void defer_sample_start(void)
+{
+       if (!defer_sample_state.do_sample) return;
+       kr_assert(!defer_sample_state.is_accounting);
+       ++defer_sample_state.is_accounting;
+       defer_sample_state.stamp = get_stamp();
+       defer_sample_state.addr.ip.sa_family = AF_UNSPEC;
+}
+
+/// Annotate the work currently being accounted by an IP address.
+static inline void defer_sample_addr(const union kr_sockaddr *addr)
+{
+       if (!defer_sample_state.do_sample || kr_fails_assert(addr)) return;
+       if (!defer_sample_state.is_accounting) return;
+
+       if (defer_sample_state.addr.ip.sa_family != AF_UNSPEC) {
+               // TODO: this costs performance, so only in some debug mode?
+               kr_assert(kr_sockaddr_cmp(&addr->ip, &defer_sample_state.addr.ip) == kr_ok());
+               return;
+       }
+
+       switch (addr->ip.sa_family) {
+       case AF_INET:
+               defer_sample_state.addr.ip4 = addr->ip4;
+               break;
+       case AF_INET6:
+               defer_sample_state.addr.ip6 = addr->ip6;
+               break;
+       default:
+               defer_sample_state.addr.ip.sa_family = AF_UNSPEC;
+               break;
+       }
+}
+
+/// Stop accounting work - and change the source if applicable.
+static inline void defer_sample_stop(void)
+{
+       if (!defer_sample_state.do_sample) return;
+
+       if (kr_fails_assert(defer_sample_state.is_accounting > 0)) return; // weird
+       if (--defer_sample_state.is_accounting) return;
+
+       const uint64_t elapsed = get_stamp() - defer_sample_state.stamp;
+
+       // we accounted something
+       // FIXME: drop the log, add KRU, etc.
+       kr_log_notice(DEVEL, "%8.3f ms for %s\n", elapsed / 1000000.0,
+                       kr_straddr(&defer_sample_state.addr.ip));
+       // TODO: some queries of internal origin have suspicioiusly high numbers.
+       // We won't be really accounting those, but it might suggest some other issue.
+}
+
+
+void defer_init(void);
index c09da7546f67231866c37021cd1c87f301d425d0..c7df184c6ce5254a2e3bea27cc3b92e174111dc9 100644 (file)
@@ -580,8 +580,8 @@ int worker_resolve_exec(struct qr_task *, knot_pkt_t *);
 knot_pkt_t *worker_resolve_mk_pkt(const char *, uint16_t, uint16_t, const struct kr_qflags *);
 struct qr_task *worker_resolve_start(knot_pkt_t *, struct kr_qflags);
 int zi_zone_import(const zi_config_t);
-_Bool kr_rrl_request_begin(struct kr_request *);
-void kr_rrl_init(const char *, size_t, uint32_t, uint32_t, int);
+_Bool ratelimiting_request_begin(struct kr_request *);
+void ratelimiting_init(const char *, size_t, uint32_t, uint32_t, int);
 struct engine {
        char _stub[];
 };
index 51587b7ccac11bb567eb6ed9e37043a3b895bc4f..28c9c5a62d1f875485b3cf067d1f21be92a2c47d 100644 (file)
@@ -580,8 +580,8 @@ int worker_resolve_exec(struct qr_task *, knot_pkt_t *);
 knot_pkt_t *worker_resolve_mk_pkt(const char *, uint16_t, uint16_t, const struct kr_qflags *);
 struct qr_task *worker_resolve_start(knot_pkt_t *, struct kr_qflags);
 int zi_zone_import(const zi_config_t);
-_Bool kr_rrl_request_begin(struct kr_request *);
-void kr_rrl_init(const char *, size_t, uint32_t, uint32_t, int);
+_Bool ratelimiting_request_begin(struct kr_request *);
+void ratelimiting_init(const char *, size_t, uint32_t, uint32_t, int);
 struct engine {
        char _stub[];
 };
index 0c91909a71f783ac9bd17a263b5d53da86a28f7b..cbf4b3042d154f0da4a85d554680fe65ff68783a 100644 (file)
@@ -581,8 +581,8 @@ int worker_resolve_exec(struct qr_task *, knot_pkt_t *);
 knot_pkt_t *worker_resolve_mk_pkt(const char *, uint16_t, uint16_t, const struct kr_qflags *);
 struct qr_task *worker_resolve_start(knot_pkt_t *, struct kr_qflags);
 int zi_zone_import(const zi_config_t);
-_Bool kr_rrl_request_begin(struct kr_request *);
-void kr_rrl_init(const char *, size_t, uint32_t, uint32_t, int);
+_Bool ratelimiting_request_begin(struct kr_request *);
+void ratelimiting_init(const char *, size_t, uint32_t, uint32_t, int);
 struct engine {
        char _stub[];
 };
index c14df875b5022b622f99393b447e719bea47dee4..beb4b7e870b207290b661facf65eb6950171133a 100755 (executable)
@@ -337,8 +337,8 @@ ${CDEFS} ${KRESD} functions <<-EOF
        worker_resolve_mk_pkt
        worker_resolve_start
        zi_zone_import
-       kr_rrl_request_begin
-       kr_rrl_init
+       ratelimiting_request_begin
+       ratelimiting_init
 EOF
 
 echo "struct engine" | ${CDEFS} ${KRESD} types | sed '/module_array_t/,$ d'
index 6ea94310eb0fb3bee9726c66495f3f01427d9ce7..c21c2f4b9bc45cb8299f59c26250536a98113bf3 100644 (file)
@@ -11,7 +11,8 @@
 #include "daemon/network.h"
 #include "daemon/udp_queue.h"
 #include "daemon/worker.h"
-#include "daemon/rrl/api.h"
+#include "daemon/ratelimiting.h"
+#include "daemon/defer.h"
 
 #ifdef ENABLE_DOH2
 #include "daemon/http.h"
@@ -588,6 +589,7 @@ int main(int argc, char **argv)
        io_protolayers_init();
        tls_protolayers_init();
        proxy_protolayers_init();
+       defer_init();
 #ifdef ENABLE_DOH2
        http_protolayers_init();
 #endif
@@ -650,7 +652,7 @@ int main(int argc, char **argv)
 cleanup:/* Cleanup. */
        network_unregister();
 
-       kr_rrl_deinit();
+       ratelimiting_deinit();
        kr_resolver_deinit();
        worker_deinit();
        engine_deinit();
index f8f914ca061989110ee598a7a29517e2b8c3c33b..87475ea3d9167401b540596dfead65ab92ca2ce9 100644 (file)
@@ -8,12 +8,14 @@ kresd_src = files([
   'bindings/modules.c',
   'bindings/net.c',
   'bindings/worker.c',
+  'defer.c',
   'engine.c',
   'ffimodule.c',
   'io.c',
   'main.c',
   'network.c',
   'proxyv2.c',
+  'ratelimiting.c',
   'session2.c',
   'tls.c',
   'tls_ephemeral_credentials.c',
@@ -29,6 +31,13 @@ endif
 
 c_src_lint += kresd_src
 
+unit_tests += [
+  ['ratelimiting', files('ratelimiting.test/tests.c') + libkres_src ],
+
+  # parallel tests timeouts under valgrind; they checks mainly for race conditions, which is not needed there
+  ['ratelimiting-parallel', files('ratelimiting.test/tests-parallel.c') + libkres_src, ['skip_valgrind']]
+]
+
 config_tests += [
   ['cache.clear', files('cache.test/clear.test.lua')],
   ['zimport', files('zimport.test/zimport.test.lua')],
@@ -57,8 +66,6 @@ kresd_deps = [
 
 
 subdir('lua')
-subdir('rrl')
-
 
 kresd = executable(
   'kresd',
similarity index 94%
rename from daemon/rrl/api.c
rename to daemon/ratelimiting.c
index 2ce12da43744a18593d251495518ab0aad87b744..fc89497fc514bb550b3ac4bacac6948e56214117 100644 (file)
@@ -1,8 +1,8 @@
 #include <fcntl.h>
 #include <sys/mman.h>
 
-#include "daemon/rrl/api.h"
-#include "daemon/rrl/kru.h"
+#include "daemon/ratelimiting.h"
+#include "lib/kru.h"
 #include "lib/utils.h"
 #include "lib/resolve.h"
 
@@ -17,7 +17,7 @@
 #define RRL_V6_PREFIXES_CNT (sizeof(RRL_V6_PREFIXES) / sizeof(*RRL_V6_PREFIXES))
 #define RRL_MAX_PREFIXES_CNT ((RRL_V4_PREFIXES_CNT > RRL_V6_PREFIXES_CNT) ? RRL_V4_PREFIXES_CNT : RRL_V6_PREFIXES_CNT)
 
-struct rrl {
+struct rrl {  // TODO rename?
        size_t capacity;
        uint32_t instant_limit;
        uint32_t rate_limit;
@@ -31,11 +31,6 @@ struct rrl *the_rrl = NULL;
 int the_rrl_fd = -1;
 char *the_rrl_mmap_file = NULL;
 
-kr_rrl_sample_state_t kr_rrl_sample_state = {
-       .do_sample = true, // FIXME: start with false, set to true based on config when opening KRU
-       .is_accounting = 0,
-};
-
 /// return whether we're using optimized variant right now
 static bool using_avx2(void)
 {
@@ -44,7 +39,7 @@ static bool using_avx2(void)
        return result;
 }
 
-void kr_rrl_init(const char *mmap_file, size_t capacity, uint32_t instant_limit, uint32_t rate_limit, int tc_limit_perc)
+void ratelimiting_init(const char *mmap_file, size_t capacity, uint32_t instant_limit, uint32_t rate_limit, int tc_limit_perc)
 {
        int fd = the_rrl_fd = open(mmap_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
        if (fd == -1) {
@@ -133,7 +128,7 @@ check_fail:
        abort();
 }
 
-void kr_rrl_deinit(void)
+void ratelimiting_deinit(void)
 {
        if (the_rrl == NULL) return;
        int fd = the_rrl_fd;
@@ -162,7 +157,7 @@ void kr_rrl_deinit(void)
        the_rrl = NULL;
 }
 
-bool kr_rrl_request_begin(struct kr_request *req)
+bool ratelimiting_request_begin(struct kr_request *req)
 {
        if (!req->qsource.addr)
                return false;  // don't consider internal requests
diff --git a/daemon/ratelimiting.h b/daemon/ratelimiting.h
new file mode 100644 (file)
index 0000000..406431b
--- /dev/null
@@ -0,0 +1,18 @@
+#include <stdbool.h>
+#include "lib/defines.h"
+#include "lib/utils.h"
+struct kr_request;
+
+/** Initialize rate-limiting with shared mmapped memory.
+ * The existing data are used if another instance is already using the file
+ * and it was initialized with the same parameters; it fails on mismatch. */
+KR_EXPORT
+void ratelimiting_init(const char *mmap_file, size_t capacity, uint32_t instant_limit, uint32_t rate_limit, int tc_limit_perc);
+
+/** Do rate-limiting, during knot_layer_api::begin. */
+KR_EXPORT
+bool ratelimiting_request_begin(struct kr_request *req);
+
+/** Remove mmapped file data if not used by other processes. */
+KR_EXPORT
+void ratelimiting_deinit(void);
similarity index 98%
rename from daemon/rrl/tests-parallel.c
rename to daemon/ratelimiting.test/tests-parallel.c
index 934ef5f949abe111d512df36f6d46fb4d911785c..8efeb2fa7951d0f957f2631b757904e52fcb69f9 100644 (file)
@@ -16,7 +16,7 @@
 
 static void the_tests(void **state);
 
-#include "daemon/rrl/tests.inc.c"
+#include "./tests.inc.c"
 
 #define THREADS 4
 
@@ -98,7 +98,7 @@ static void *runnable(void *arg)
                                         hqi % 0xff, (hqi >> 8) % 0xff, (hqi >> 16) % 0xff);
                                kr_straddr_socket_set((struct sockaddr *)&addr, addr_str, 0);
 
-                               if (!kr_rrl_request_begin(&req)) {
+                               if (!ratelimiting_request_begin(&req)) {
                                        atomic_fetch_add(&d->stages[si].hosts[hi].passed, 1);
                                }
 
similarity index 98%
rename from daemon/rrl/tests.c
rename to daemon/ratelimiting.test/tests.c
index abccaafa78efe4d3bd3556c242a2a9c3a04ce1f2..ad111dd5e8f86ea49d8761771f9609d185338a6d 100644 (file)
@@ -16,7 +16,7 @@
 
 static void the_tests(void **state);
 
-#include "daemon/rrl/tests.inc.c"
+#include "./tests.inc.c"
 
 // defining count_test as macro to let it print usable line number on failure
 #define count_test(DESC, EXPECTED_PASSING, MARGIN_FRACT, ...) { \
@@ -42,7 +42,7 @@ uint32_t _count_test(int expected_passing, int addr_family, char *addr_format, u
                                i % (max_value - min_value + 1) + min_value,
                                i / (max_value - min_value + 1) % 256);
                kr_straddr_socket_set((struct sockaddr *) &addr, addr_str, 0);
-               if (kr_rrl_request_begin(&req)) {
+               if (ratelimiting_request_begin(&req)) {
                        cnt = i;
                        break;
                }
similarity index 96%
rename from daemon/rrl/tests.inc.c
rename to daemon/ratelimiting.test/tests.inc.c
index a352d94c04b93a933aee9432206ddf306e3fc08e..14a5a9c0833b7210af2b5af3b075feb0223d720a 100644 (file)
@@ -29,7 +29,7 @@
 #include "lib/utils.h"
 uint64_t fakeclock_now(void);
 #define kr_now fakeclock_now
-#include "daemon/rrl/api.c"
+#include "daemon/ratelimiting.c"
 #undef kr_now
 
 #define RRL_TABLE_SIZE     (1 << 20)
@@ -95,7 +95,7 @@ static void test_rrl(void **state) {
        const char *tmpdir = test_tmpdir_create();
        char mmap_file[64];
        stpcpy(stpcpy(mmap_file, tmpdir), "/rrl");
-       kr_rrl_init(mmap_file, RRL_TABLE_SIZE, RRL_INSTANT_LIMIT, RRL_RATE_LIMIT, 100);
+       ratelimiting_init(mmap_file, RRL_TABLE_SIZE, RRL_INSTANT_LIMIT, RRL_RATE_LIMIT, 100);
 
        if (KRU.initialize == KRU_GENERIC.initialize) {
                struct kru_generic *kru = (struct kru_generic *) the_rrl->kru;
@@ -109,7 +109,7 @@ static void test_rrl(void **state) {
 
        the_tests(state);
 
-       kr_rrl_deinit();
+       ratelimiting_deinit();
        test_tmpdir_remove(tmpdir);
        dnssec_crypto_cleanup();
 }
diff --git a/daemon/rrl/api.h b/daemon/rrl/api.h
deleted file mode 100644 (file)
index 685b80a..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-
-#include <stdbool.h>
-#include "lib/defines.h"
-#include "lib/utils.h"
-struct kr_request;
-
-/** Initialize rate-limiting with shared mmapped memory.
- * The existing data are used if another instance is already using the file
- * and it was initialized with the same parameters; it fails on mismatch. */
-KR_EXPORT
-void kr_rrl_init(const char *mmap_file, size_t capacity, uint32_t instant_limit, uint32_t rate_limit, int tc_limit_perc);
-
-/** Do rate-limiting, during knot_layer_api::begin. */
-KR_EXPORT
-bool kr_rrl_request_begin(struct kr_request *req);
-
-/** Remove mmapped file data if not used by other processes. */
-KR_EXPORT
-void kr_rrl_deinit(void);
-
-
-// TODO: reconsider `static inline` cases below
-
-
-typedef struct {
-       bool do_sample; /// whether to sample; could be important if _COARSE isn't available
-       int8_t is_accounting; /// whether currently accounting the time to someone; should be 0/1
-       union kr_sockaddr addr; /// request source (to which we account) or AF_UNSPEC if unknown yet
-       uint64_t stamp; /// monotonic nanoseconds, probably won't wrap
-} kr_rrl_sample_state_t;
-extern kr_rrl_sample_state_t kr_rrl_sample_state;
-
-#include <time.h>
-static inline uint64_t get_stamp(void)
-{
-       struct timespec now_ts = {0};
-       clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now_ts);
-       return now_ts.tv_nsec + 1000*1000*1000 * (uint64_t)now_ts.tv_sec;
-}
-
-/// Start accounting work, if not doing it already.
-static inline void kr_rrl_sample_start(void)
-{
-       if (!kr_rrl_sample_state.do_sample) return;
-       kr_assert(!kr_rrl_sample_state.is_accounting);
-       ++kr_rrl_sample_state.is_accounting;
-       kr_rrl_sample_state.stamp = get_stamp();
-       kr_rrl_sample_state.addr.ip.sa_family = AF_UNSPEC;
-}
-
-/// Annotate the work currently being accounted by an IP address.
-static inline void kr_rrl_sample_addr(const union kr_sockaddr *addr)
-{
-       if (!kr_rrl_sample_state.do_sample || kr_fails_assert(addr)) return;
-       if (!kr_rrl_sample_state.is_accounting) return;
-
-       if (kr_rrl_sample_state.addr.ip.sa_family != AF_UNSPEC) {
-               // TODO: this costs performance, so only in some debug mode?
-               kr_assert(kr_sockaddr_cmp(&addr->ip, &kr_rrl_sample_state.addr.ip) == kr_ok());
-               return;
-       }
-
-       switch (addr->ip.sa_family) {
-       case AF_INET:
-               kr_rrl_sample_state.addr.ip4 = addr->ip4;
-               break;
-       case AF_INET6:
-               kr_rrl_sample_state.addr.ip6 = addr->ip6;
-               break;
-       default:
-               kr_rrl_sample_state.addr.ip.sa_family = AF_UNSPEC;
-               break;
-       }
-}
-
-/// Stop accounting work - and change the source if applicable.
-static inline void kr_rrl_sample_stop(void)
-{
-       if (!kr_rrl_sample_state.do_sample) return;
-
-       if (kr_fails_assert(kr_rrl_sample_state.is_accounting > 0)) return; // weird
-       if (--kr_rrl_sample_state.is_accounting) return;
-
-       const uint64_t elapsed = get_stamp() - kr_rrl_sample_state.stamp;
-
-       // we accounted something
-       // FIXME: drop the log, add KRU, etc.
-       kr_log_notice(DEVEL, "%8.3f ms for %s\n", elapsed / 1000000.0,
-                       kr_straddr(&kr_rrl_sample_state.addr.ip));
-       // TODO: some queries of internal origin have suspicioiusly high numbers.
-       // We won't be really accounting those, but it might suggest some other issue.
-}
diff --git a/daemon/rrl/meson.build b/daemon/rrl/meson.build
deleted file mode 100644 (file)
index 8a815d7..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-# rate limiting code
-
-kresd_src += files([
-  'api.c',
-  'kru-generic.c',
-  'kru-avx2.c',
-  '../../contrib/openbsd/siphash.c',
-])
-
-kresd_deps += [
-  # https://mesonbuild.com/howtox.html#add-math-library-lm-portably
-  (meson.get_compiler('c').find_library('m', required : false))
-]
-
-unit_tests += [
-  ['rrl', files('tests.c', 'kru-generic.c', 'kru-avx2.c', '../../contrib/openbsd/siphash.c') + libkres_src ],
-
-  # parallel tests timeouts under valgrind; they checks mainly for race conditions, which is not needed there
-  ['rrl-parallel', files('tests-parallel.c', 'kru-generic.c', 'kru-avx2.c', '../../contrib/openbsd/siphash.c') + libkres_src, ['skip_valgrind']]
-]
index 682815ad3b5b3eb7eb0bb32cbbe5676d99fe3902..121ecddbe82006c281f430a864504ec313cee209 100644 (file)
@@ -16,7 +16,7 @@
 #include "daemon/io.h"
 #include "daemon/udp_queue.h"
 #include "daemon/worker.h"
-#include "daemon/rrl/api.h"
+#include "daemon/defer.h"
 #include "daemon/proxyv2.h"
 
 #include "daemon/session2.h"
@@ -38,18 +38,21 @@ struct protolayer_globals protolayer_globals[PROTOLAYER_TYPE_COUNT] = {{0}};
 static const enum protolayer_type protolayer_grp_udp53[] = {
        PROTOLAYER_TYPE_UDP,
        PROTOLAYER_TYPE_PROXYV2_DGRAM,
+       PROTOLAYER_TYPE_DEFER,
        PROTOLAYER_TYPE_DNS_DGRAM,
 };
 
 static const enum protolayer_type protolayer_grp_tcp53[] = {
        PROTOLAYER_TYPE_TCP,
        PROTOLAYER_TYPE_PROXYV2_STREAM,
+       PROTOLAYER_TYPE_DEFER,
        PROTOLAYER_TYPE_DNS_MULTI_STREAM,
 };
 
 static const enum protolayer_type protolayer_grp_dot[] = {
        PROTOLAYER_TYPE_TCP,
        PROTOLAYER_TYPE_PROXYV2_STREAM,
+       PROTOLAYER_TYPE_DEFER,
        PROTOLAYER_TYPE_TLS,
        PROTOLAYER_TYPE_DNS_MULTI_STREAM,
 };
@@ -57,6 +60,7 @@ static const enum protolayer_type protolayer_grp_dot[] = {
 static const enum protolayer_type protolayer_grp_doh[] = {
        PROTOLAYER_TYPE_TCP,
        PROTOLAYER_TYPE_PROXYV2_STREAM,
+       PROTOLAYER_TYPE_DEFER,
        PROTOLAYER_TYPE_TLS,
        PROTOLAYER_TYPE_HTTP,
        PROTOLAYER_TYPE_DNS_UNSIZED_STREAM,
@@ -615,11 +619,11 @@ static int session2_submit(
        // Note two cases: incoming session (new request)
        // vs. outgoing session (resuming work on some request)
        if (direction == PROTOLAYER_UNWRAP) {
-               kr_rrl_sample_start();
+               defer_sample_start();
                // In particular we don't want to miss en/decryption work
                // for regular connections from clients.
                if (!session->outgoing && session->secure && !proxy_allowed(comm->comm_addr))
-                       kr_rrl_sample_addr((const union kr_sockaddr *)comm->comm_addr);
+                       defer_sample_addr((const union kr_sockaddr *)comm->comm_addr);
        }
        int ret;
 
@@ -658,7 +662,7 @@ static int session2_submit(
 
        ret = protolayer_step(ctx);
        if (direction == PROTOLAYER_UNWRAP)
-               kr_rrl_sample_stop();
+               defer_sample_stop();
        return ret;
 }
 
@@ -946,10 +950,10 @@ uv_handle_t *session2_get_handle(struct session2 *s)
 
 static void session2_on_timeout(uv_timer_t *timer)
 {
-       kr_rrl_sample_start();
+       defer_sample_start();
        struct session2 *s = timer->data;
        session2_event(s, s->timer_event, NULL);
-       kr_rrl_sample_stop();
+       defer_sample_stop();
 }
 
 int session2_timer_start(struct session2 *s, enum protolayer_event_type event, uint64_t timeout, uint64_t repeat)
index eac8da3d6368f3060ce7a451137d90014d9abd1e..0e824a456a9eea2593a06564476e4c9f07612aed 100644 (file)
@@ -225,7 +225,9 @@ static inline size_t wire_buf_free_space_length(const struct wire_buf *wb)
        XX(DNS_MULTI_STREAM) /**< Multiple packets WITH prepended sizes in a
                              * stream (may span multiple (un)wraps). */\
        XX(DNS_SINGLE_STREAM) /**< Singular packet WITH prepended size in a
-                              * stream (may span multiple (un)wraps). */
+                              * stream (may span multiple (un)wraps). */\
+       /* Requests prioritization */\
+       XX(DEFER)
 
 /** The identifiers of protocol layer types. */
 enum protolayer_type {
@@ -627,7 +629,7 @@ struct protolayer_data_param {
 /** Global data for a specific layered protocol. This is to be initialized in
  * the `protolayer_globals` global array (below) during the the resolver's
  * startup. It contains pointers to functions implementing a particular
- * protocol, as well as other importand data.
+ * protocol, as well as other important data.
  *
  * Every member of this struct is allowed to be zero/NULL if a particular
  * protocol has no use for it. */
index d3d68f1022af9ef3636e62a536634fdf7658518e..8dfeb0749f8ec7bd897623096a608ca8901142f8 100644 (file)
@@ -34,7 +34,7 @@
 #include "lib/layer.h"
 #include "lib/layer/iterate.h" /* kr_response_classify */
 #include "lib/utils.h"
-#include "daemon/rrl/api.h"
+#include "daemon/defer.h"
 
 
 /* Magic defaults for the worker. */
@@ -72,6 +72,7 @@ struct request_ctx
        } source;
 };
 
+
 /** Query resolution task. */
 struct qr_task
 {
@@ -363,7 +364,7 @@ static struct request_ctx *request_create(struct session2 *session,
                /* We need to store a copy of peer address. */
                memcpy(&ctx->source.addr.ip, src_addr, kr_sockaddr_len(src_addr));
                req->qsource.addr = &ctx->source.addr.ip;
-               kr_rrl_sample_addr(&ctx->source.addr);
+               defer_sample_addr(&ctx->source.addr);
 
                if (!comm_addr)
                        comm_addr = src_addr;
@@ -1217,7 +1218,7 @@ static int qr_task_step(struct qr_task *task,
                        const struct sockaddr *packet_source, knot_pkt_t *packet)
 {
        if (task && task->ctx->source.session)
-               kr_rrl_sample_addr(&task->ctx->source.addr);
+               defer_sample_addr(&task->ctx->source.addr);
 
        /* No more steps after we're finished. */
        if (!task || task->finished) {
similarity index 100%
rename from daemon/rrl/kru-avx2.c
rename to lib/kru-avx2.c
similarity index 100%
rename from daemon/rrl/kru-generic.c
rename to lib/kru-generic.c
similarity index 100%
rename from daemon/rrl/kru.h
rename to lib/kru.h
similarity index 100%
rename from daemon/rrl/kru.inc.c
rename to lib/kru.inc.c
index 60988f02e6c1910d95110e0184851b32f50f90ea..9f611e3a95c8784bcd4e9ba5bef0713757f69d28 100644 (file)
@@ -19,6 +19,8 @@ libkres_src = files([
   'generic/lru.c',
   'generic/queue.c',
   'generic/trie.c',
+  'kru-avx2.c',
+  'kru-generic.c',
   'layer/cache.c',
   'layer/iterate.c',
   'layer/validate.c',
@@ -38,6 +40,7 @@ libkres_src = files([
   'selection_iter.c',
   'utils.c',
   'zonecut.c',
+  '../contrib/openbsd/siphash.c', # needed for kru
 ])
 c_src_lint += libkres_src
 
@@ -57,6 +60,7 @@ libkres_headers = files([
   'generic/pack.h',
   'generic/queue.h',
   'generic/trie.h',
+  'kru.h',
   'layer.h',
   'layer/iterate.h',
   'log.h',
@@ -110,6 +114,7 @@ libkres_lib = library('kres',
     gnutls,
     luajit,
     libsystemd,
+    libm
   ],
   install: true,
 )
index 552a9dcb2d1ac6886efbfca6b3266f233af2fc53..dfd6b770582ce53fde8b4d461463a1d6d5620e9f 100644 (file)
@@ -1,8 +1,8 @@
 {% from 'macros/common_macros.lua.j2' import boolean %}
 
 {% if cfg.rate_limiting.rate_limit -%}
-C.kr_rrl_init(
-       '{{ cfg.rundir }}/rrl',
+C.ratelimiting_init(
+       '{{ cfg.rundir }}/ratelimiting',
        {{ cfg.rate_limiting.capacity }},
        {{ cfg.rate_limiting.instant_limit }},
        {{ cfg.rate_limiting.rate_limit }},
index 77ca8138cd496af2e6b26950d9d075eccf60d432..70c5568510dcb18d82b998e563e26c47e4af3b79 100644 (file)
@@ -29,6 +29,8 @@ if not lmdb.found()  # darwin workaround: missing pkgconfig
 endif
 gnutls = dependency('gnutls')
 luajit = dependency('luajit')
+# https://mesonbuild.com/howtox.html#add-math-library-lm-portably
+libm = meson.get_compiler('c').find_library('m', required : false)
 message('------------------------------')
 
 
index 107555560d446745ad54d00de3fd39004f116ee6..bf796a6dd4f47ddb2d6c73f130e0a81ca7e96d00 100644 (file)
@@ -937,7 +937,7 @@ policy.layer = {
                        loadstring('return ' .. act_str)()(state, req)
                end
 
-               if ffi.C.kr_rrl_request_begin(req) then return end
+               if ffi.C.ratelimiting_request_begin(req) then return end
 
                local qry = req:initial() -- same as :current() but more descriptive
                return policy.evaluate(policy.rules, req, qry, state)