summaryrefslogtreecommitdiffstats
path: root/modules/extended_error
diff options
context:
space:
mode:
Diffstat (limited to 'modules/extended_error')
-rw-r--r--modules/extended_error/extended_error.c47
-rw-r--r--modules/extended_error/meson.build20
2 files changed, 67 insertions, 0 deletions
diff --git a/modules/extended_error/extended_error.c b/modules/extended_error/extended_error.c
new file mode 100644
index 0000000..db0ed57
--- /dev/null
+++ b/modules/extended_error/extended_error.c
@@ -0,0 +1,47 @@
+#include <libknot/rrtype/opt.h>
+
+#include "lib/module.h"
+#include "daemon/engine.h"
+
+static int extended_error_finalize(kr_layer_t *ctx) {
+ struct kr_request *req = ctx->req;
+ const knot_rrset_t *src_opt = req->qsource.packet->opt_rr;
+ const struct kr_extended_error *ede = &req->extended_error;
+
+ if (ede->info_code == KNOT_EDNS_EDE_NONE /* no extended error */
+ || src_opt == NULL /* no EDNS in query */
+ || kr_fails_assert(ede->info_code >= 0 && ede->info_code < UINT16_MAX) /* info code out of range */
+ || kr_fails_assert(req->answer->opt_rr) /* sanity check - answer should have EDNS */
+ ) {
+ return ctx->state;
+ }
+
+ const uint16_t info_code = (uint16_t)ede->info_code;
+ const size_t extra_len = ede->extra_text ? strlen(ede->extra_text) : 0;
+ uint8_t buf[sizeof(info_code) + extra_len];
+ knot_wire_write_u16(buf, info_code);
+ if (extra_len)
+ memcpy(buf + sizeof(info_code), ede->extra_text, extra_len);
+
+ if (knot_edns_add_option(req->answer->opt_rr, KNOT_EDNS_OPTION_EDE,
+ sizeof(buf), buf, &req->pool) != KNOT_EOK) {
+ /* something went wrong and there is no way to salvage content of OPT RRset */
+ kr_log_req(req, 0, 0, EDE, "unable to add Extended Error option\n");
+ knot_rrset_clear(req->answer->opt_rr, &req->pool);
+ }
+
+ return ctx->state;
+}
+
+KR_EXPORT
+int extended_error_init(struct kr_module *module) {
+ static kr_layer_api_t layer = {
+ .answer_finalize = &extended_error_finalize,
+ };
+ layer.data = module;
+ module->layer = &layer;
+
+ return kr_ok();
+}
+
+KR_MODULE_EXPORT(extended_error)
diff --git a/modules/extended_error/meson.build b/modules/extended_error/meson.build
new file mode 100644
index 0000000..15a1772
--- /dev/null
+++ b/modules/extended_error/meson.build
@@ -0,0 +1,20 @@
+# C module: extended_error
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+extended_error_src = files([
+ 'extended_error.c',
+])
+c_src_lint += extended_error_src
+
+extended_error_mod = shared_module(
+ 'extended_error',
+ extended_error_src,
+ dependencies: [
+ libknot,
+ ],
+ include_directories: mod_inc_dir,
+ name_prefix: '',
+ install: true,
+ install_dir: modules_dir,
+ link_with: kresd,
+)