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);
}
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;
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;
}
/* 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);
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);
subdir('hints')
subdir('http')
subdir('nsid')
+subdir('padding')
subdir('policy')
subdir('stats')
subdir('view')
--- /dev/null
+# 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,
+)
--- /dev/null
+/* 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