]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
WIP padding module padding-flag 818/head
authorIvana Krumlová <ivana.krumlova@nic.cz>
Fri, 12 Jul 2019 13:16:52 +0000 (15:16 +0200)
committerIvana Krumlová <ivana.krumlova@nic.cz>
Fri, 12 Jul 2019 13:25:04 +0000 (15:25 +0200)
- in .begin sets PADDING_REQUIRED flag for tls requests
- function add_padding is moved from resolve.c but .answer_finalize is
too early and .finish too late to aply it

lib/resolve.c
modules/meson.build
modules/padding/meson.build [new file with mode: 0644]
modules/padding/padding.c [new file with mode: 0644]

index 3dbb2d2debf96196e27b2bb3d70da7b3b0eee355..2d87dbc19aec69059bca6542c2e0ffc93edde281 100644 (file)
@@ -427,15 +427,6 @@ static int edns_create(knot_pkt_t *pkt, knot_pkt_t *template, struct kr_request
                wire_size += KR_COOKIE_OPT_MAX_LEN;
        }
 #endif /* defined(ENABLE_COOKIES) */
-       if (req->options.PADDING_REQUIRED) {
-               if (req->ctx->tls_padding == -1)
-                       /* FIXME: we do not know how to reserve space for the
-                        * default padding policy, since we can't predict what
-                        * it will select. So i'm just guessing :/ */
-                       wire_size += KNOT_EDNS_OPTION_HDRLEN + 512;
-               if (req->ctx->tls_padding >= 2)
-                       wire_size += KNOT_EDNS_OPTION_HDRLEN + req->ctx->tls_padding;
-       }
        return knot_pkt_reserve(pkt, wire_size);
 }
 
@@ -519,42 +510,6 @@ static int write_extra_ranked_records(const ranked_rr_array_t *arr, uint16_t reo
        return err;
 }
 
-/** @internal Add an EDNS padding RR into the answer if requested and required. */
-static int answer_padding_maybe(struct kr_request *request)
-{
-       if (!request || !request->answer || !request->ctx) {
-               assert(false);
-               return kr_error(EINVAL);
-       }
-       if (!request->options.PADDING_REQUIRED) return kr_ok();
-
-       int32_t padding = request->ctx->tls_padding;
-       knot_pkt_t *answer = request->answer;
-       knot_rrset_t *opt_rr = answer->opt_rr;
-       int32_t pad_bytes = -1;
-
-       if (padding == -1) { /* use the default padding policy from libknot */
-               pad_bytes =  knot_pkt_default_padding_size(answer, opt_rr);
-       }
-       if (padding >= 2) {
-               int32_t max_pad_bytes = knot_edns_get_payload(opt_rr) - (answer->size + knot_rrset_size(opt_rr));
-               pad_bytes = MIN(knot_edns_alignment_size(answer->size, knot_rrset_size(opt_rr), padding),
-                               max_pad_bytes);
-       }
-
-       if (pad_bytes >= 0) {
-               uint8_t zeros[MAX(1, pad_bytes)];
-               memset(zeros, 0, sizeof(zeros));
-               int r = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_PADDING,
-                                            pad_bytes, zeros, &answer->mm);
-               if (r != KNOT_EOK) {
-                       knot_rrset_clear(opt_rr, &answer->mm);
-                       return kr_error(r);
-               }
-       }
-       return kr_ok();
-}
-
 static int answer_fail(struct kr_request *request)
 {
        knot_pkt_t *answer = request->answer;
@@ -565,7 +520,6 @@ static int answer_fail(struct kr_request *request)
        if (ret == 0 && answer->opt_rr) {
                /* OPT in SERVFAIL response is still useful for cookies/additional info. */
                knot_pkt_begin(answer, KNOT_ADDITIONAL);
-               answer_padding_maybe(request); /* Ignore failed padding in SERVFAIL answer. */
                ret = edns_put(answer, false);
        }
        return ret;
@@ -630,9 +584,6 @@ static int answer_finalize(struct kr_request *request, int state)
        }
        /* Write EDNS information */
        if (answer->opt_rr) {
-               if (answer_padding_maybe(request) != kr_ok()) {
-                       return answer_fail(request);
-               }
                knot_pkt_begin(answer, KNOT_ADDITIONAL);
                int ret = knot_pkt_put(answer, KNOT_COMPR_HINT_NONE,
                                       answer->opt_rr, KNOT_PF_FREE);
@@ -712,7 +663,6 @@ int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pk
        request->ctx = ctx;
        request->answer = answer;
        request->options = ctx->options;
-       request->options.PADDING_REQUIRED = true; //WIP: this sets the flag for every request
        request->state = KR_STATE_CONSUME;
        request->current_query = NULL;
        array_init(request->additional);
index 3ae4b56de92e1373cc42ce2a9907a05a729c3bde..1c509b246f65532bb5d656b8637ebea42ee80b73 100644 (file)
@@ -46,6 +46,7 @@ subdir('experimental_dot_auth')
 subdir('hints')
 subdir('http')
 subdir('nsid')
+subdir('padding')
 subdir('policy')
 subdir('stats')
 subdir('view')
diff --git a/modules/padding/meson.build b/modules/padding/meson.build
new file mode 100644 (file)
index 0000000..55f1191
--- /dev/null
@@ -0,0 +1,23 @@
+# C module: padding
+
+padding_src = files([
+  'padding.c',
+])
+c_src_lint += padding_src
+
+integr_tests += [
+  ['padding', join_paths(meson.current_source_dir(), 'test.integr')],
+]
+
+
+padding_mod = shared_module(
+  'padding',
+  padding_src,
+  dependencies: [
+    luajit_inc,
+  ],
+  include_directories: mod_inc_dir,
+  name_prefix: '',
+  install: true,
+  install_dir: modules_dir,
+)
diff --git a/modules/padding/padding.c b/modules/padding/padding.c
new file mode 100644 (file)
index 0000000..c4fecaa
--- /dev/null
@@ -0,0 +1,113 @@
+/*  Copyright (C) 2014-2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file padding.c
+ * @brief TODO
+ */
+
+#include <libknot/packet/pkt.h>
+#include <libknot/packet/wire.h>
+#include <libknot/descriptor.h>
+#include <ccan/json/json.h>
+#include <contrib/cleanup.h>
+#include <arpa/inet.h>
+#include <lua.h>
+
+#include "lib/layer/iterate.h"
+#include "lib/rplan.h"
+#include "lib/module.h"
+#include "lib/layer.h"
+#include "lib/resolve.h"
+
+/** @internal Compatibility wrapper for Lua < 5.2 */
+#if LUA_VERSION_NUM < 502
+#define lua_rawlen(L, obj) lua_objlen((L), (obj))
+#endif
+
+static int set_for_tls(kr_layer_t *ctx)
+{
+       struct kr_request *req = ctx->req;
+       if (req->qsource.flags.tls) {
+            req->options.PADDING_REQUIRED = true;
+        }
+       return ctx->state;
+}
+
+static int add_padding(kr_layer_t *ctx) {
+        struct kr_request *request = ctx->req;
+        
+        if (!request || !request->answer || !request->ctx) {
+                assert(false);
+                return kr_error(EINVAL);
+        }
+        if (!request->options.PADDING_REQUIRED) return kr_ok();
+
+        int32_t padding = request->ctx->tls_padding;
+        knot_pkt_t *answer = request->answer;
+        knot_rrset_t *opt_rr = answer->opt_rr;
+        int32_t pad_bytes = -1;
+
+        if (padding == -1) { /* use the default padding policy from libknot */
+                pad_bytes =  knot_pkt_default_padding_size(answer, opt_rr);
+        }
+        if (padding >= 2) {
+                int32_t max_pad_bytes = knot_edns_get_payload(opt_rr) - (answer->size + knot_rrset_size(opt_rr));
+                pad_bytes = MIN(knot_edns_alignment_size(answer->size, knot_rrset_size(opt_rr), padding),
+                                max_pad_bytes);
+        }
+
+        if (pad_bytes >= 0) {
+                uint8_t zeros[MAX(1, pad_bytes)];
+                memset(zeros, 0, sizeof(zeros));
+                int r = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_PADDING,
+                                             pad_bytes, zeros, &answer->mm);
+                if (r != KNOT_EOK) {
+                        knot_rrset_clear(opt_rr, &answer->mm);
+                        return kr_error(r);
+                }
+        }
+        return kr_ok();
+}
+
+KR_EXPORT
+int padding_init(struct kr_module *module)
+{
+       static kr_layer_api_t layer = {
+               .begin = &set_for_tls,
+                .answer_finalize = &add_padding,
+                //.finish = &add_padding,
+       };
+       /* Store module reference */
+       layer.data = module;
+       module->layer = &layer;
+
+       static const struct kr_prop props[] = {
+           { NULL, NULL, NULL }
+       };
+       module->props = props;
+       return kr_ok();
+}
+
+KR_EXPORT
+int padding_deinit(struct kr_module *module)
+{
+       return kr_ok();
+}
+
+KR_MODULE_EXPORT(padding)
+
+#undef VERBOSE_MSG