From e3a0dbdbc6b6c73a51d3f0ca7ba6e6a061123ea3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= Date: Tue, 19 Mar 2024 12:15:14 +0100 Subject: [PATCH] PoC: rate-limit everything for now :-) --- daemon/lua/kres-gen-30.lua | 1 + daemon/lua/kres-gen-31.lua | 1 + daemon/lua/kres-gen-32.lua | 1 + daemon/lua/kres-gen.sh | 1 + daemon/rrl/api.c | 34 ++++++++++++++++++++++++++++++++++ daemon/rrl/api.h | 8 ++++++++ daemon/rrl/meson.build | 1 + modules/policy/policy.lua | 4 +++- 8 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 daemon/rrl/api.c create mode 100644 daemon/rrl/api.h diff --git a/daemon/lua/kres-gen-30.lua b/daemon/lua/kres-gen-30.lua index ae182a37a..65c6ac5ac 100644 --- a/daemon/lua/kres-gen-30.lua +++ b/daemon/lua/kres-gen-30.lua @@ -579,6 +579,7 @@ 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 *); struct engine { char _stub[]; }; diff --git a/daemon/lua/kres-gen-31.lua b/daemon/lua/kres-gen-31.lua index 1033e104f..cb96adf12 100644 --- a/daemon/lua/kres-gen-31.lua +++ b/daemon/lua/kres-gen-31.lua @@ -579,6 +579,7 @@ 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 *); struct engine { char _stub[]; }; diff --git a/daemon/lua/kres-gen-32.lua b/daemon/lua/kres-gen-32.lua index 23a338f09..7a416079c 100644 --- a/daemon/lua/kres-gen-32.lua +++ b/daemon/lua/kres-gen-32.lua @@ -580,6 +580,7 @@ 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 *); struct engine { char _stub[]; }; diff --git a/daemon/lua/kres-gen.sh b/daemon/lua/kres-gen.sh index 5939dc65a..752944979 100755 --- a/daemon/lua/kres-gen.sh +++ b/daemon/lua/kres-gen.sh @@ -334,6 +334,7 @@ ${CDEFS} ${KRESD} functions <<-EOF worker_resolve_mk_pkt worker_resolve_start zi_zone_import + kr_rrl_request_begin EOF echo "struct engine" | ${CDEFS} ${KRESD} types | sed '/module_array_t/,$ d' diff --git a/daemon/rrl/api.c b/daemon/rrl/api.c new file mode 100644 index 000000000..74b2ef6f3 --- /dev/null +++ b/daemon/rrl/api.c @@ -0,0 +1,34 @@ +#include "daemon/rrl/api.h" +#include "daemon/rrl/kru.h" +#include "lib/resolve.h" + +struct kru *the_rrl_kru = NULL; + +// FIXME: add C API that takes configuration parameters and initializes the KRU; +// it will then get called from the generated Lua config file. + +bool kr_rrl_request_begin(struct kr_request *req) +{ + if (!req->qsource.addr) + return false; // don't consider internal requests + const bool limited = true; + if (!limited && the_rrl_kru) { + // FIXME: process limiting via KRU.limited* + } + if (!limited) return limited; + + knot_pkt_t *answer = kr_request_ensure_answer(req); + if (!answer) { // something bad; TODO: perhaps improve recovery from this + kr_assert(false); + return limited; + } + // at this point the packet should be pretty clear + + // Example limiting: REFUSED. + knot_wire_set_rcode(answer->wire, KNOT_RCODE_REFUSED); + kr_request_set_extended_error(req, KNOT_EDNS_EDE_OTHER, "YRAA: rate-limited"); + + req->state = KR_STATE_DONE; + + return limited; +} diff --git a/daemon/rrl/api.h b/daemon/rrl/api.h new file mode 100644 index 000000000..0d155d099 --- /dev/null +++ b/daemon/rrl/api.h @@ -0,0 +1,8 @@ + +#include +#include +struct kr_request; + +/** Do rate-limiting, during knot_layer_api::begin. */ +KR_EXPORT +bool kr_rrl_request_begin(struct kr_request *req); diff --git a/daemon/rrl/meson.build b/daemon/rrl/meson.build index 959ac7e04..707fa2cc5 100644 --- a/daemon/rrl/meson.build +++ b/daemon/rrl/meson.build @@ -2,6 +2,7 @@ # rate limiting code kresd_src += files([ + 'api.c', 'kru-generic.c', 'kru-avx2.c', '../../contrib/openbsd/siphash.c', diff --git a/modules/policy/policy.lua b/modules/policy/policy.lua index 60b034783..107555560 100644 --- a/modules/policy/policy.lua +++ b/modules/policy/policy.lua @@ -934,9 +934,11 @@ policy.layer = { if ffi.C.kr_view_select_action(req, view_action_buf) == 0 then local act_str = ffi.string(view_action_buf[0].data, view_action_buf[0].len) - return loadstring('return '..act_str)()(state, req) + loadstring('return ' .. act_str)()(state, req) end + if ffi.C.kr_rrl_request_begin(req) then return end + local qry = req:initial() -- same as :current() but more descriptive return policy.evaluate(policy.rules, req, qry, state) or state -- 2.47.2