this is not going to be backwards compatible change, but it will be the first tagged libknot release sufficient for resolver
--- /dev/null
+/* Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "contrib/base32hex.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+/*! \brief Maximal length of binary input to Base32hex encoding. */
+#define MAX_BIN_DATA_LEN ((INT32_MAX / 8) * 5)
+
+/*! \brief Base32hex padding character. */
+const uint8_t base32hex_pad = '=';
+/*! \brief Base32hex alphabet. */
+const uint8_t base32hex_enc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+
+/*! \brief Indicates bad Base32hex character. */
+#define KO 255
+/*! \brief Indicates Base32hex padding character. */
+#define PD 32
+
+/*! \brief Transformation and validation table for decoding Base32hex. */
+const uint8_t base32hex_dec[256] = {
+ [ 0] = KO, [ 43] = KO, ['V'] = 31, [129] = KO, [172] = KO, [215] = KO,
+ [ 1] = KO, [ 44] = KO, ['W'] = KO, [130] = KO, [173] = KO, [216] = KO,
+ [ 2] = KO, [ 45] = KO, ['X'] = KO, [131] = KO, [174] = KO, [217] = KO,
+ [ 3] = KO, [ 46] = KO, ['Y'] = KO, [132] = KO, [175] = KO, [218] = KO,
+ [ 4] = KO, [ 47] = KO, ['Z'] = KO, [133] = KO, [176] = KO, [219] = KO,
+ [ 5] = KO, ['0'] = 0, [ 91] = KO, [134] = KO, [177] = KO, [220] = KO,
+ [ 6] = KO, ['1'] = 1, [ 92] = KO, [135] = KO, [178] = KO, [221] = KO,
+ [ 7] = KO, ['2'] = 2, [ 93] = KO, [136] = KO, [179] = KO, [222] = KO,
+ [ 8] = KO, ['3'] = 3, [ 94] = KO, [137] = KO, [180] = KO, [223] = KO,
+ [ 9] = KO, ['4'] = 4, [ 95] = KO, [138] = KO, [181] = KO, [224] = KO,
+ [ 10] = KO, ['5'] = 5, [ 96] = KO, [139] = KO, [182] = KO, [225] = KO,
+ [ 11] = KO, ['6'] = 6, ['a'] = 10, [140] = KO, [183] = KO, [226] = KO,
+ [ 12] = KO, ['7'] = 7, ['b'] = 11, [141] = KO, [184] = KO, [227] = KO,
+ [ 13] = KO, ['8'] = 8, ['c'] = 12, [142] = KO, [185] = KO, [228] = KO,
+ [ 14] = KO, ['9'] = 9, ['d'] = 13, [143] = KO, [186] = KO, [229] = KO,
+ [ 15] = KO, [ 58] = KO, ['e'] = 14, [144] = KO, [187] = KO, [230] = KO,
+ [ 16] = KO, [ 59] = KO, ['f'] = 15, [145] = KO, [188] = KO, [231] = KO,
+ [ 17] = KO, [ 60] = KO, ['g'] = 16, [146] = KO, [189] = KO, [232] = KO,
+ [ 18] = KO, ['='] = PD, ['h'] = 17, [147] = KO, [190] = KO, [233] = KO,
+ [ 19] = KO, [ 62] = KO, ['i'] = 18, [148] = KO, [191] = KO, [234] = KO,
+ [ 20] = KO, [ 63] = KO, ['j'] = 19, [149] = KO, [192] = KO, [235] = KO,
+ [ 21] = KO, [ 64] = KO, ['k'] = 20, [150] = KO, [193] = KO, [236] = KO,
+ [ 22] = KO, ['A'] = 10, ['l'] = 21, [151] = KO, [194] = KO, [237] = KO,
+ [ 23] = KO, ['B'] = 11, ['m'] = 22, [152] = KO, [195] = KO, [238] = KO,
+ [ 24] = KO, ['C'] = 12, ['n'] = 23, [153] = KO, [196] = KO, [239] = KO,
+ [ 25] = KO, ['D'] = 13, ['o'] = 24, [154] = KO, [197] = KO, [240] = KO,
+ [ 26] = KO, ['E'] = 14, ['p'] = 25, [155] = KO, [198] = KO, [241] = KO,
+ [ 27] = KO, ['F'] = 15, ['q'] = 26, [156] = KO, [199] = KO, [242] = KO,
+ [ 28] = KO, ['G'] = 16, ['r'] = 27, [157] = KO, [200] = KO, [243] = KO,
+ [ 29] = KO, ['H'] = 17, ['s'] = 28, [158] = KO, [201] = KO, [244] = KO,
+ [ 30] = KO, ['I'] = 18, ['t'] = 29, [159] = KO, [202] = KO, [245] = KO,
+ [ 31] = KO, ['J'] = 19, ['u'] = 30, [160] = KO, [203] = KO, [246] = KO,
+ [ 32] = KO, ['K'] = 20, ['v'] = 31, [161] = KO, [204] = KO, [247] = KO,
+ [ 33] = KO, ['L'] = 21, ['w'] = KO, [162] = KO, [205] = KO, [248] = KO,
+ [ 34] = KO, ['M'] = 22, ['x'] = KO, [163] = KO, [206] = KO, [249] = KO,
+ [ 35] = KO, ['N'] = 23, ['y'] = KO, [164] = KO, [207] = KO, [250] = KO,
+ [ 36] = KO, ['O'] = 24, ['z'] = KO, [165] = KO, [208] = KO, [251] = KO,
+ [ 37] = KO, ['P'] = 25, [123] = KO, [166] = KO, [209] = KO, [252] = KO,
+ [ 38] = KO, ['Q'] = 26, [124] = KO, [167] = KO, [210] = KO, [253] = KO,
+ [ 39] = KO, ['R'] = 27, [125] = KO, [168] = KO, [211] = KO, [254] = KO,
+ [ 40] = KO, ['S'] = 28, [126] = KO, [169] = KO, [212] = KO, [255] = KO,
+ [ 41] = KO, ['T'] = 29, [127] = KO, [170] = KO, [213] = KO,
+ [ 42] = KO, ['U'] = 30, [128] = KO, [171] = KO, [214] = KO,
+};
+
+int32_t base32hex_decode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
+{
+ // Checking inputs.
+ if (in == NULL || out == NULL) {
+ return -1;
+ }
+ if (in_len > INT32_MAX || out_len < ((in_len + 7) / 8) * 5) {
+ return -1;
+ }
+ if ((in_len % 8) != 0) {
+ return -1;
+ }
+
+ const uint8_t *stop = in + in_len;
+ uint8_t *bin = out;
+ uint8_t pad_len = 0;
+ uint8_t c1, c2, c3, c4, c5, c6, c7, c8;
+
+ // Decoding loop takes 8 characters and creates 5 bytes.
+ while (in < stop) {
+ // Filling and transforming 8 Base32hex chars.
+ c1 = base32hex_dec[in[0]];
+ c2 = base32hex_dec[in[1]];
+ c3 = base32hex_dec[in[2]];
+ c4 = base32hex_dec[in[3]];
+ c5 = base32hex_dec[in[4]];
+ c6 = base32hex_dec[in[5]];
+ c7 = base32hex_dec[in[6]];
+ c8 = base32hex_dec[in[7]];
+
+ // Check 8. char if is bad or padding.
+ if (c8 >= PD) {
+ if (c8 == PD && pad_len == 0) {
+ pad_len = 1;
+ } else {
+ return -1;
+ }
+ }
+
+ // Check 7. char if is bad or padding (if so, 6. must be too).
+ if (c7 >= PD) {
+ if (c7 == PD && c6 == PD && pad_len == 1) {
+ pad_len = 3;
+ } else {
+ return -1;
+ }
+ }
+
+ // Check 6. char if is bad or padding.
+ if (c6 >= PD) {
+ if (!(c6 == PD && pad_len == 3)) {
+ return -1;
+ }
+ }
+
+ // Check 5. char if is bad or padding.
+ if (c5 >= PD) {
+ if (c5 == PD && pad_len == 3) {
+ pad_len = 4;
+ } else {
+ return -1;
+ }
+ }
+
+ // Check 4. char if is bad or padding (if so, 3. must be too).
+ if (c4 >= PD) {
+ if (c4 == PD && c3 == PD && pad_len == 4) {
+ pad_len = 6;
+ } else {
+ return -1;
+ }
+ }
+
+ // Check 3. char if is bad or padding.
+ if (c3 >= PD) {
+ if (!(c3 == PD && pad_len == 6)) {
+ return -1;
+ }
+ }
+
+ // 1. and 2. chars must not be padding.
+ if (c2 >= PD || c1 >= PD) {
+ return -1;
+ }
+
+ // Computing of output data based on padding length.
+ switch (pad_len) {
+ case 0:
+ bin[4] = (c7 << 5) + c8;
+ case 1:
+ bin[3] = (c5 << 7) + (c6 << 2) + (c7 >> 3);
+ case 3:
+ bin[2] = (c4 << 4) + (c5 >> 1);
+ case 4:
+ bin[1] = (c2 << 6) + (c3 << 1) + (c4 >> 4);
+ case 6:
+ bin[0] = (c1 << 3) + (c2 >> 2);
+ }
+
+ // Update output end.
+ switch (pad_len) {
+ case 0:
+ bin += 5;
+ break;
+ case 1:
+ bin += 4;
+ break;
+ case 3:
+ bin += 3;
+ break;
+ case 4:
+ bin += 2;
+ break;
+ case 6:
+ bin += 1;
+ break;
+ }
+
+ in += 8;
+ }
+
+ return (bin - out);
+}
--- /dev/null
+/* Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
+ */
+/*!
+ * \file
+ *
+ * \brief Base32hex implementation (RFC 4648).
+ *
+ * \note Input Base32hex string can contain a-v characters. These characters
+ * are considered as A-V equivalent.
+ *
+ * \addtogroup contrib
+ * @{
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+/*!
+ * \brief Decodes text data using Base32hex.
+ *
+ * \note Input data needn't be terminated with '\0'.
+ *
+ * \note Input data must be continuous Base32hex string!
+ *
+ * \param in Input text data.
+ * \param in_len Length of input string.
+ * \param out Output data buffer.
+ * \param out_len Size of output buffer.
+ *
+ * \retval >=0 length of output data.
+ * \retval KNOT_E* if error.
+ */
+int32_t base32hex_decode(const uint8_t *in,
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len);
+
+/*! @} */
contrib/ccan/isaac/isaac.c \
contrib/ccan/json/json.c \
contrib/ucw/mempool.c \
- contrib/murmurhash3/murmurhash3.c
+ contrib/murmurhash3/murmurhash3.c \
+ contrib/base32hex.c
contrib_CFLAGS := -fPIC
contrib_TARGET := $(abspath contrib)/contrib$(AREXT)
$(eval $(call make_static,contrib,contrib))
--- /dev/null
+/* Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
+ */
+/*!
+ * \file
+ *
+ * \brief Wire integer operations.
+ *
+ * \addtogroup contrib
+ * @{
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string.h>
+
+#if defined(__linux__)
+# include <endian.h>
+# ifndef be64toh
+# include <arpa/inet.h>
+# include <byteswap.h>
+# if BYTE_ORDER == LITTLE_ENDIAN
+# define be16toh(x) ntohs(x)
+# define be32toh(x) ntohl(x)
+# define be64toh(x) bswap_64 (x)
+# define le16toh(x) (x)
+# define le32toh(x) (x)
+# define le64toh(x) (x)
+# else
+# define be16toh(x) (x)
+# define be32toh(x) (x)
+# define be64toh(x) (x)
+# define le16toh(x) ntohs(x)
+# define le32toh(x) ntohl(x)
+# define le64toh(x) bswap_64 (x)
+# endif
+# endif
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+# include <sys/endian.h>
+#elif defined(__OpenBSD__)
+# include <endian.h>
+#elif defined(__APPLE__)
+# include <libkern/OSByteOrder.h>
+# define be16toh(x) OSSwapBigToHostInt16(x)
+# define be32toh(x) OSSwapBigToHostInt32(x)
+# define be64toh(x) OSSwapBigToHostInt64(x)
+# define htobe16(x) OSSwapHostToBigInt16(x)
+# define htobe32(x) OSSwapHostToBigInt32(x)
+# define htobe64(x) OSSwapHostToBigInt64(x)
+# define le16toh(x) OSSwapLittleToHostInt16(x)
+# define le32toh(x) OSSwapLittleToHostInt32(x)
+# define le64toh(x) OSSwapLittleToHostInt64(x)
+# define htole16(x) OSSwapHostToLittleInt16(x)
+# define htole32(x) OSSwapHostToLittleInt32(x)
+# define htole64(x) OSSwapHostToLittleInt64(x)
+#endif
+
+/*!
+ * \brief Reads 2 bytes from the wireformat data.
+ *
+ * \param pos Data to read the 2 bytes from.
+ *
+ * \return The 2 bytes read, in host byte order.
+ */
+inline static uint16_t wire_read_u16(const uint8_t *pos)
+{
+ return be16toh(*(uint16_t *)pos);
+}
+
+/*!
+ * \brief Reads 4 bytes from the wireformat data.
+ *
+ * \param pos Data to read the 4 bytes from.
+ *
+ * \return The 4 bytes read, in host byte order.
+ */
+inline static uint32_t wire_read_u32(const uint8_t *pos)
+{
+ return be32toh(*(uint32_t *)pos);
+}
+
+/*!
+ * \brief Reads 6 bytes from the wireformat data.
+ *
+ * \param pos Data to read the 6 bytes from.
+ *
+ * \return The 6 bytes read, in host byte order.
+ */
+inline static uint64_t wire_read_u48(const uint8_t *pos)
+{
+ uint64_t input = 0;
+ memcpy((uint8_t *)&input + 1, pos, 6);
+ return be64toh(input) >> 8;
+}
+
+/*!
+ * \brief Read 8 bytes from the wireformat data.
+ *
+ * \param pos Data to read the 8 bytes from.
+ *
+ * \return The 8 bytes read, in host byte order.
+ */
+inline static uint64_t wire_read_u64(const uint8_t *pos)
+{
+ return be64toh(*(uint64_t *)pos);
+}
+
+/*!
+ * \brief Writes 2 bytes in wireformat.
+ *
+ * The data are stored in network byte order (big endian).
+ *
+ * \param pos Position where to put the 2 bytes.
+ * \param data Data to put.
+ */
+inline static void wire_write_u16(uint8_t *pos, uint16_t data)
+{
+ *(uint16_t *)pos = htobe16(data);
+}
+
+/*!
+ * \brief Writes 4 bytes in wireformat.
+ *
+ * The data are stored in network byte order (big endian).
+ *
+ * \param pos Position where to put the 4 bytes.
+ * \param data Data to put.
+ */
+inline static void wire_write_u32(uint8_t *pos, uint32_t data)
+{
+ *(uint32_t *)pos = htobe32(data);
+}
+
+/*!
+ * \brief Writes 6 bytes in wireformat.
+ *
+ * The data are stored in network byte order (big endian).
+ *
+ * \param pos Position where to put the 4 bytes.
+ * \param data Data to put.
+ */
+inline static void wire_write_u48(uint8_t *pos, uint64_t data)
+{
+ uint64_t swapped = htobe64(data << 8);
+ memcpy(pos, (uint8_t *)&swapped + 1, 6);
+}
+
+/*!
+ * \brief Writes 8 bytes in wireformat.
+ *
+ * The data are stored in network byte order (big endian).
+ *
+ * \param pos Position where to put the 8 bytes.
+ * \param data Data to put.
+ */
+inline static void wire_write_u64(uint8_t *pos, uint64_t data)
+{
+ *(uint64_t *)pos = htobe64(data);
+}
+
+/*! @} */
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <assert.h>
#include <uv.h>
#include <contrib/cleanup.h>
#include <libknot/descriptor.h>
static int cache_count(lua_State *L)
{
struct engine *engine = engine_luaget(L);
- const namedb_api_t *storage = engine->resolver.cache.api;
+ const knot_db_api_t *storage = engine->resolver.cache.api;
/* Fetch item count */
struct kr_cache_txn txn;
- int ret = kr_cache_txn_begin(&engine->resolver.cache, &txn, NAMEDB_RDONLY);
+ int ret = kr_cache_txn_begin(&engine->resolver.cache, &txn, KNOT_DB_RDONLY);
if (ret != 0) {
format_error(L, kr_strerror(ret));
lua_error(L);
#include <unistd.h>
#include <grp.h>
#include <pwd.h>
-#include <libknot/internal/mempattern.h>
-/* #include <libknot/internal/namedb/namedb_trie.h> @todo Not supported (doesn't keep value copy) */
-#include <libknot/internal/namedb/namedb_lmdb.h>
+/* #include <libknot/internal/namedb/knot_db_trie.h> @todo Not supported (doesn't keep value copy) */
+#include <libknot/db/db_lmdb.h>
#include "daemon/engine.h"
#include "daemon/bindings.h"
unsigned opt_code = 0;
if (lua_isstring(L, 1)) {
const char *opt = lua_tostring(L, 1);
- for (const lookup_table_t *it = kr_query_flag_names(); it->name; ++it) {
+ for (const knot_lookup_t *it = kr_query_flag_names(); it->name; ++it) {
if (strcmp(it->name, opt) == 0) {
opt_code = it->id;
break;
*/
/** @internal Make lmdb options. */
-void *namedb_lmdb_mkopts(const char *conf, size_t maxsize)
+void *knot_db_lmdb_mkopts(const char *conf, size_t maxsize)
{
- struct namedb_lmdb_opts *opts = malloc(sizeof(*opts));
+ struct knot_db_lmdb_opts *opts = malloc(sizeof(*opts));
if (opts) {
memset(opts, 0, sizeof(*opts));
opts->path = (conf && strlen(conf)) ? conf : ".";
/* Initialize storage backends */
struct storage_api lmdb = {
- "lmdb://", namedb_lmdb_api, namedb_lmdb_mkopts
+ "lmdb://", knot_db_lmdb_api, knot_db_lmdb_mkopts
};
return array_push(engine->storage_registry, lmdb);
return kr_ok();
}
-int engine_init(struct engine *engine, mm_ctx_t *pool)
+int engine_init(struct engine *engine, knot_mm_t *pool)
{
if (engine == NULL) {
return kr_error(EINVAL);
*/
struct lua_State;
+#include "lib/utils.h"
#include "lib/resolve.h"
#include "daemon/network.h"
/** Cache storage backend. */
struct storage_api {
const char *prefix; /**< Storage prefix, e.g. 'lmdb://' */
- const namedb_api_t *(*api)(void); /**< Storage API implementation */
+ const knot_db_api_t *(*api)(void); /**< Storage API implementation */
void *(*opts_create)(const char *, size_t); /**< Storage options factory */
};
struct network net;
module_array_t modules;
storage_registry_t storage_registry;
- mm_ctx_t *pool;
+ knot_mm_t *pool;
struct lua_State *L;
};
-int engine_init(struct engine *engine, mm_ctx_t *pool);
+int engine_init(struct engine *engine, knot_mm_t *pool);
void engine_deinit(struct engine *engine);
/** @warning This function leaves 1 string result on stack. */
int engine_cmd(struct engine *engine, const char *str);
/* libknot */
typedef int knot_section_t; /* Do not touch */
typedef void knot_rrinfo_t; /* Do not touch */
-typedef struct node {
- struct node *next, *prev;
-} node_t;
typedef uint8_t knot_dname_t;
typedef uint8_t knot_rdata_t;
typedef struct knot_rdataset {
size_t cap;
} rr_array_t;
struct kr_query {
- node_t _node;
struct kr_query *parent;
knot_dname_t *sname;
uint16_t type;
ffi.metatype( kr_query_t, {
__index = {
name = function(qry, new_name) return ffi.string(qry.sname, knot.knot_dname_size(qry.sname)) end,
- next = function(qry)
- assert(qry)
- return C.kr_rplan_next(qry)
- end,
resolved = function(qry)
return band(qry.flags, kres.query.RESOLVED) ~= 0
end,
#include <string.h>
#include <getopt.h>
#include <uv.h>
+#include <assert.h>
#include <contrib/cleanup.h>
#include <contrib/ucw/mempool.h>
#include <contrib/ccan/asprintf/asprintf.h>
+#include <libknot/error.h>
#include "lib/defines.h"
#include "lib/resolve.h"
" [rundir] Path to the working directory (default: .)\n");
}
-static struct worker_ctx *init_worker(uv_loop_t *loop, struct engine *engine, mm_ctx_t *pool, int worker_id, int worker_count)
+static struct worker_ctx *init_worker(uv_loop_t *loop, struct engine *engine, knot_mm_t *pool, int worker_id, int worker_count)
{
/* Load bindings */
engine_lualib(engine, "modules", lib_modules);
uv_signal_start(&sigint, signal_handler, SIGINT);
uv_signal_start(&sigterm, signal_handler, SIGTERM);
/* Create a server engine. */
- mm_ctx_t pool = {
+ knot_mm_t pool = {
.ctx = mp_new (4096),
- .alloc = (mm_alloc_t) mp_alloc
+ .alloc = (knot_mm_alloc_t) mp_alloc
};
struct engine engine;
ret = engine_init(&engine, &pool);
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <unistd.h>
#include "daemon/network.h"
#include "daemon/worker.h"
#include "daemon/io.h"
#include <libknot/descriptor.h>
#include <contrib/ucw/lib.h>
#include <contrib/ucw/mempool.h>
+#include <contrib/wire.h>
#if defined(__GLIBC__) && defined(_GNU_SOURCE)
#include <malloc.h>
#endif
-
+#include <assert.h>
+#include "lib/utils.h"
#include "daemon/worker.h"
#include "daemon/engine.h"
#include "daemon/io.h"
}
/* Recycle available mempool if possible */
- mm_ctx_t pool = {
+ knot_mm_t pool = {
.ctx = pool_take(worker),
- .alloc = (mm_alloc_t) mp_alloc
+ .alloc = (knot_mm_alloc_t) mp_alloc
};
/* Create resolution task */
task->on_complete = NULL;
/* Remember query source addr */
if (addr) {
- memcpy(&task->source.addr, addr, sockaddr_len(addr));
+ size_t addr_len = sizeof(struct sockaddr_in);
+ if (addr->sa_family == AF_INET6)
+ addr_len = sizeof(struct sockaddr_in6);
+ memcpy(&task->source.addr, addr, addr_len);
task->req.qsource.addr = (const struct sockaddr *)&task->source.addr;
} else {
task->source.addr.ip4.sin_family = AF_UNSPEC;
map_del(&task->worker->outstanding, key);
}
/* Notify waiting tasks. */
- struct kr_query *leader_qry = TAIL(task->req.rplan.pending);
+ struct kr_query *leader_qry = array_tail(task->req.rplan.pending);
for (size_t i = task->waiting.len; i --> 0;) {
struct qr_task *follower = task->waiting.at[i];
- struct kr_query *qry = TAIL(follower->req.rplan.pending);
+ struct kr_query *qry = array_tail(follower->req.rplan.pending);
/* Reuse MSGID and 0x20 secret */
if (qry) {
qry->id = leader_qry->id;
return kr_error(ENOMEM);
memset(&worker->pkt_pool, 0, sizeof(worker->pkt_pool));
worker->pkt_pool.ctx = mp_new (4 * sizeof(knot_pkt_t));
- worker->pkt_pool.alloc = (mm_alloc_t) mp_alloc;
+ worker->pkt_pool.alloc = (knot_mm_alloc_t) mp_alloc;
worker->outstanding = map_make();
return kr_ok();
}
#pragma once
-#include <libknot/internal/mempattern.h>
-
#include "daemon/engine.h"
#include "lib/generic/array.h"
#include "lib/generic/map.h"
map_t outstanding;
mp_freelist_t pools;
mp_freelist_t ioreqs;
- mm_ctx_t pkt_pool;
+ knot_mm_t pkt_pool;
};
/* Worker callback */
local last = req:resolved()
print(last.type)
- last = last:next()
- if last ~= nil then
- print(last.type)
- end
As described in the layers, you can not only retrieve information about current query, but also push new ones or pop old ones.
#include <unistd.h>
#include <errno.h>
-#include <libknot/internal/mempattern.h>
-#include <libknot/internal/namedb/namedb_lmdb.h>
+#include <libknot/db/db_lmdb.h>
#include <libknot/errcode.h>
#include <libknot/descriptor.h>
#include <libknot/dname.h>
if (ret != 0) {
return; /* N/A, doesn't work. */
}
- namedb_val_t key = { KEY_VERSION, 2 };
- namedb_val_t val = { NULL, 0 };
+ knot_db_val_t key = { KEY_VERSION, 2 };
+ knot_db_val_t val = { NULL, 0 };
ret = txn_api(&txn)->find(&txn.t, &key, &val, 0);
if (ret == 0) { /* Version is OK */
kr_cache_txn_abort(&txn);
}
}
-int kr_cache_open(struct kr_cache *cache, const namedb_api_t *api, void *opts, mm_ctx_t *mm)
+int kr_cache_open(struct kr_cache *cache, const knot_db_api_t *api, void *opts, knot_mm_t *mm)
{
if (!cache) {
return kr_error(EINVAL);
}
/* Open cache */
- cache->api = (api == NULL) ? namedb_lmdb_api() : api;
+ cache->api = (api == NULL) ? knot_db_lmdb_api() : api;
int ret = cache->api->init(&cache->db, mm, opts);
if (ret != 0) {
return ret;
} else {
/* Count statistics */
txn->owner = cache;
- if (flags & NAMEDB_RDONLY) {
+ if (flags & KNOT_DB_RDONLY) {
cache->stats.txn_read += 1;
} else {
cache->stats.txn_write += 1;
}
/* Look up and return value */
- namedb_val_t key = { keybuf, key_len };
- namedb_val_t val = { NULL, 0 };
+ knot_db_val_t key = { keybuf, key_len };
+ knot_db_val_t val = { NULL, 0 };
int ret = txn_api(txn)->find(&txn->t, &key, &val, 0);
if (ret != KNOT_EOK) {
return NULL;
return ret;
}
-static void entry_write(struct kr_cache_entry *dst, struct kr_cache_entry *header, namedb_val_t data)
+static void entry_write(struct kr_cache_entry *dst, struct kr_cache_entry *header, knot_db_val_t data)
{
assert(dst && header);
memcpy(dst, header, sizeof(*header));
}
int kr_cache_insert(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type,
- struct kr_cache_entry *header, namedb_val_t data)
+ struct kr_cache_entry *header, knot_db_val_t data)
{
if (!txn_is_valid(txn) || !name || !header) {
return kr_error(EINVAL);
if (key_len == 0) {
return kr_error(EILSEQ);
}
- namedb_val_t key = { keybuf, key_len };
- namedb_val_t entry = { NULL, sizeof(*header) + data.len };
- const namedb_api_t *db_api = txn_api(txn);
+ knot_db_val_t key = { keybuf, key_len };
+ knot_db_val_t entry = { NULL, sizeof(*header) + data.len };
+ const knot_db_api_t *db_api = txn_api(txn);
/* LMDB can do late write and avoid copy */
txn->owner->stats.insert += 1;
- if (db_api == namedb_lmdb_api()) {
+ if (db_api == knot_db_lmdb_api()) {
int ret = db_api->insert(&txn->t, &key, &entry, 0);
if (ret != 0) {
return ret;
if (key_len == 0) {
return kr_error(EILSEQ);
}
- namedb_val_t key = { keybuf, key_len };
+ knot_db_val_t key = { keybuf, key_len };
txn->owner->stats.delete += 1;
return txn_api(txn)->del(&txn->t, &key);
}
return found->rank;
}
-int kr_cache_materialize(knot_rrset_t *dst, const knot_rrset_t *src, uint32_t drift, mm_ctx_t *mm)
+int kr_cache_materialize(knot_rrset_t *dst, const knot_rrset_t *src, uint32_t drift, knot_mm_t *mm)
{
if (!dst || !src) {
return kr_error(EINVAL);
rd = kr_rdataset_next(rd);
}
- namedb_val_t data = { rr->rrs.data, knot_rdataset_size(&rr->rrs) };
+ knot_db_val_t data = { rr->rrs.data, knot_rdataset_size(&rr->rrs) };
return kr_cache_insert(txn, KR_CACHE_RR, rr->owner, rr->type, &header, data);
}
}
uint16_t covered = knot_rrsig_type_covered(&rr->rrs, 0);
- namedb_val_t data = { rr->rrs.data, knot_rdataset_size(&rr->rrs) };
+ knot_db_val_t data = { rr->rrs.data, knot_rdataset_size(&rr->rrs) };
return kr_cache_insert(txn, KR_CACHE_SIG, rr->owner, covered, &header, data);
}
#pragma once
#include <libknot/rrset.h>
-#include <libknot/internal/namedb/namedb.h>
+#include <libknot/db/db.h>
#include "lib/defines.h"
/** Cache entry tag */
*/
struct kr_cache
{
- namedb_t *db; /**< Storage instance */
- const namedb_api_t *api; /**< Storage engine */
+ knot_db_t *db; /**< Storage instance */
+ const knot_db_api_t *api; /**< Storage engine */
struct {
uint32_t hit; /**< Number of cache hits */
uint32_t miss; /**< Number of cache misses */
/** Cache transaction */
struct kr_cache_txn {
- namedb_txn_t t; /**< Storage transaction */
+ knot_db_txn_t t; /**< Storage transaction */
struct kr_cache *owner; /**< Transaction owner */
};
* @return 0 or an error code
*/
KR_EXPORT
-int kr_cache_open(struct kr_cache *cache, const namedb_api_t *api, void *opts, mm_ctx_t *mm);
+int kr_cache_open(struct kr_cache *cache, const knot_db_api_t *api, void *opts, knot_mm_t *mm);
/**
* Close persistent cache.
*/
KR_EXPORT
int kr_cache_insert(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type,
- struct kr_cache_entry *header, namedb_val_t data);
+ struct kr_cache_entry *header, knot_db_val_t data);
/**
* Remove asset from cache.
* @return 0 or an errcode
*/
KR_EXPORT
-int kr_cache_materialize(knot_rrset_t *dst, const knot_rrset_t *src, uint32_t drift, mm_ctx_t *mm);
+int kr_cache_materialize(knot_rrset_t *dst, const knot_rrset_t *src, uint32_t drift, knot_mm_t *mm);
/**
* Insert RRSet into cache, replacing any existing data.
#include <libknot/rrtype/dnskey.h>
#include <libknot/rrtype/nsec.h>
#include <libknot/rrtype/rrsig.h>
-
+#include <contrib/wire.h>
#include "lib/defines.h"
#include "lib/dnssec/nsec.h"
#pragma once
#include "lib/defines.h"
-#include <libknot/internal/consts.h>
#include <libknot/packet/pkt.h>
/**
}
int kr_nsec_name_error_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
- const knot_dname_t *sname, mm_ctx_t *pool)
+ const knot_dname_t *sname)
{
const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
if (!sec || !sname) {
#pragma once
-#include <libknot/internal/consts.h>
-#include <libknot/internal/mempattern.h>
#include <libknot/packet/pkt.h>
/**
* @param pkt Packet structure to be processed.
* @param section_id Packet section to be processed.
* @param sname Name to be checked.
- * @param pool
* @return 0 or error code.
*/
int kr_nsec_name_error_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
- const knot_dname_t *sname, mm_ctx_t *pool);
+ const knot_dname_t *sname);
/**
* No data response check (RFC4035 3.1.3.1; RFC4035 5.4, bullet 1).
#include <dnssec/error.h>
#include <dnssec/nsec.h>
#include <libknot/descriptor.h>
-#include <libknot/internal/base32hex.h>
+#include <contrib/base32hex.h>
#include <libknot/rrset.h>
#include <libknot/rrtype/nsec3.h>
int32_t ret = base32hex_decode(nsec3->owner + 1, nsec3->owner[0], hash->data, max_hash_size);
if (ret < 0) {
- return ret;
+ return kr_error(EILSEQ);
}
hash->size = ret;
#pragma once
-#include <libknot/internal/consts.h>
-#include <libknot/internal/mempattern.h>
#include <libknot/packet/pkt.h>
/**
+++ /dev/null
-/* Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <libknot/internal/consts.h>
-
-#include "lib/dnssec/packet/pkt.h"
-
-/**
- * Search in section for given type.
- * @param sec Packet section.
- * @param type Type to search for.
- * @return True if found.
- */
-static bool section_has_type(const knot_pktsection_t *sec, uint16_t type)
-{
- if (!sec) {
- return false;
- }
-
- for (unsigned i = 0; i < sec->count; ++i) {
- const knot_rrset_t *rr = knot_pkt_rr(sec, i);
- if (rr->type == type) {
- return true;
- }
- }
-
- return false;
-}
-
-bool _knot_pkt_has_type(const knot_pkt_t *pkt, uint16_t type)
-{
- if (!pkt) {
- return false;
- }
-
- if (section_has_type(knot_pkt_section(pkt, KNOT_ANSWER), type)) {
- return true;
- }
- if (section_has_type(knot_pkt_section(pkt, KNOT_AUTHORITY), type)) {
- return true;
- }
- return section_has_type(knot_pkt_section(pkt, KNOT_ADDITIONAL), type);
-}
+++ /dev/null
-/* Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include <libknot/packet/pkt.h>
-
-/**
- * Check whether packet contains given type.
- * @param pkt Packet to seek through.
- * @param type RR type to search for.
- * @return True if found.
- */
-bool _knot_pkt_has_type(const knot_pkt_t *pkt, uint16_t type);
+++ /dev/null
-/* Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include <libknot/rdataset.h>
-
-static inline
-uint16_t _knot_ds_ktag(const knot_rdataset_t *rrs, size_t pos)
-{
- KNOT_RDATASET_CHECK(rrs, pos, return 0);
- return wire_read_u16(knot_rdata_offset(rrs, pos, 0));
-}
-
-static inline
-uint8_t _knot_ds_alg(const knot_rdataset_t *rrs, size_t pos)
-{
- KNOT_RDATASET_CHECK(rrs, pos, return 0);
- return *knot_rdata_offset(rrs, pos, 2);
-}
-
-static inline
-uint8_t _knot_ds_dtype(const knot_rdataset_t *rrs, size_t pos)
-{
- KNOT_RDATASET_CHECK(rrs, pos, return 0);
- return *knot_rdata_offset(rrs, pos, 3);
-}
-
-static inline
-void _knot_ds_digest(const knot_rdataset_t *rrs, size_t pos,
- uint8_t **digest, uint16_t *digest_size)
-{
- KNOT_RDATASET_CHECK(rrs, pos, return);
- *digest = knot_rdata_offset(rrs, pos, 4);
- const knot_rdata_t *rr = knot_rdataset_at(rrs, pos);
- *digest_size = knot_rdata_rdlen(rr) - 4;
-}
#include <libknot/packet/wire.h>
#include <libknot/rrset.h>
#include <libknot/rrtype/rrsig.h>
+#include <libknot/rrtype/ds.h>
#include "lib/defines.h"
#include "lib/utils.h"
-#include "lib/dnssec/rrtype/ds.h"
#include "lib/dnssec/signature.h"
static int authenticate_ds(const dnssec_key_t *key, dnssec_binary_t *ds_rdata, uint8_t digest_type)
.size = knot_rdata_rdlen(rd),
.data = knot_rdata_data(rd)
};
- ret = authenticate_ds(key, &ds_rdata, _knot_ds_dtype(&ref->rrs, i));
+ ret = authenticate_ds(key, &ds_rdata, knot_ds_dtype(&ref->rrs, i));
if (ret == 0) { /* Found a good DS */
break;
}
*/
#include <sys/time.h>
+#include <assert.h>
#include <libknot/descriptor.h>
#include <libknot/rrtype/rdname.h>
}
#ifndef NDEBUG
- lookup_table_t *rcode = lookup_by_id(knot_rcode_names, knot_wire_get_rcode(pkt->wire));
+ const knot_lookup_t *rcode = knot_lookup_by_id(knot_rcode_names, knot_wire_get_rcode(pkt->wire));
#endif
/* Check response code. */
/* Prepare read transaction */
struct kr_cache_txn txn;
struct kr_cache *cache = &req->ctx->cache;
- if (kr_cache_txn_begin(cache, &txn, NAMEDB_RDONLY) != 0) {
+ if (kr_cache_txn_begin(cache, &txn, KNOT_DB_RDONLY) != 0) {
return ctx->state;
}
if (kr_cache_txn_begin(&req->ctx->cache, &txn, 0) != 0) {
return ctx->state; /* Couldn't acquire cache, ignore. */
}
- namedb_val_t data = { pkt->wire, pkt->size };
+ knot_db_val_t data = { pkt->wire, pkt->size };
struct kr_cache_entry header = {
.timestamp = qry->timestamp.tv_sec,
.ttl = ttl,
static int loot_rrcache(struct kr_cache *cache, knot_pkt_t *pkt, struct kr_query *qry, uint16_t rrtype, bool dobit)
{
struct kr_cache_txn txn;
- int ret = kr_cache_txn_begin(cache, &txn, NAMEDB_RDONLY);
+ int ret = kr_cache_txn_begin(cache, &txn, KNOT_DB_RDONLY);
if (ret != 0) {
return ret;
}
return map_walk(stash, &commit_rr, &baton);
}
-static void stash_glue(map_t *stash, knot_pkt_t *pkt, const knot_dname_t *ns_name, mm_ctx_t *pool)
+static void stash_glue(map_t *stash, knot_pkt_t *pkt, const knot_dname_t *ns_name, knot_mm_t *pool)
{
const knot_pktsection_t *additional = knot_pkt_section(pkt, KNOT_ADDITIONAL);
for (unsigned i = 0; i < additional->count; ++i) {
}
/* @internal DS is special and is present only parent-side */
-static void stash_ds(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, mm_ctx_t *pool)
+static void stash_ds(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, knot_mm_t *pool)
{
const knot_pktsection_t *authority = knot_pkt_section(pkt, KNOT_AUTHORITY);
for (unsigned i = 0; i < authority->count; ++i) {
}
}
-static int stash_authority(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, mm_ctx_t *pool)
+static int stash_authority(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, knot_mm_t *pool)
{
const knot_pktsection_t *authority = knot_pkt_section(pkt, KNOT_AUTHORITY);
for (unsigned i = 0; i < authority->count; ++i) {
return kr_ok();
}
-static int stash_answer(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, mm_ctx_t *pool)
+static int stash_answer(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, knot_mm_t *pool)
{
/* Work with QNAME, as minimised name data is cacheable. */
const knot_dname_t *cname_begin = knot_pkt_qname(pkt);
ret = stash_answer(qry, pkt, &stash, &req->pool);
}
/* Cache authority only if chasing referral/cname chain */
- if (!is_auth || qry != TAIL(req->rplan.pending)) {
+ if (!is_auth || qry != array_tail(req->rplan.pending)) {
ret = stash_authority(qry, pkt, &stash, &req->pool);
}
/* Cache DS records in referrals */
#include "lib/dnssec/nsec.h"
#include "lib/dnssec/nsec3.h"
-#include "lib/dnssec/packet/pkt.h"
#include "lib/dnssec.h"
#include "lib/layer.h"
#include "lib/resolve.h"
#define DEBUG_MSG(qry, fmt...) QRDEBUG(qry, "vldr", fmt)
+/**
+ * Search in section for given type.
+ * @param sec Packet section.
+ * @param type Type to search for.
+ * @return True if found.
+ */
+static bool section_has_type(const knot_pktsection_t *sec, uint16_t type)
+{
+ if (!sec) {
+ return false;
+ }
+
+ for (unsigned i = 0; i < sec->count; ++i) {
+ const knot_rrset_t *rr = knot_pkt_rr(sec, i);
+ if (rr->type == type) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool pkt_has_type(const knot_pkt_t *pkt, uint16_t type)
+{
+ if (!pkt) {
+ return false;
+ }
+
+ if (section_has_type(knot_pkt_section(pkt, KNOT_ANSWER), type)) {
+ return true;
+ }
+ if (section_has_type(knot_pkt_section(pkt, KNOT_AUTHORITY), type)) {
+ return true;
+ }
+ return section_has_type(knot_pkt_section(pkt, KNOT_ADDITIONAL), type);
+}
+
+
/** @internal Baton for validate_section */
struct validate_baton {
const knot_pkt_t *pkt;
}
static int validate_section(struct kr_query *qry, knot_pkt_t *answer,
- knot_section_t section_id, mm_ctx_t *pool,
+ knot_section_t section_id, knot_mm_t *pool,
bool has_nsec3)
{
const knot_pktsection_t *sec = knot_pkt_section(answer, section_id);
return ret;
}
-static int validate_records(struct kr_query *qry, knot_pkt_t *answer, mm_ctx_t *pool, bool has_nsec3)
+static int validate_records(struct kr_query *qry, knot_pkt_t *answer, knot_mm_t *pool, bool has_nsec3)
{
if (!qry->zone_cut.key) {
DEBUG_MSG(qry, "<= no DNSKEY, can't validate\n");
/* Check if this is a DNSKEY answer, check trust chain and store. */
uint8_t pkt_rcode = knot_wire_get_rcode(pkt->wire);
uint16_t qtype = knot_pkt_qtype(pkt);
- bool has_nsec3 = _knot_pkt_has_type(pkt, KNOT_RRTYPE_NSEC3);
+ bool has_nsec3 = pkt_has_type(pkt, KNOT_RRTYPE_NSEC3);
if (knot_wire_get_aa(pkt->wire) && qtype == KNOT_RRTYPE_DNSKEY) {
ret = validate_keyset(qry, pkt, has_nsec3);
if (ret != 0) {
if (!(qry->flags & QUERY_CACHED) && pkt_rcode == KNOT_RCODE_NXDOMAIN) {
/* @todo If knot_pkt_qname(pkt) is used instead of qry->sname then the tests crash. */
if (!has_nsec3) {
- ret = kr_nsec_name_error_response_check(pkt, KNOT_AUTHORITY, qry->sname, &req->pool);
+ ret = kr_nsec_name_error_response_check(pkt, KNOT_AUTHORITY, qry->sname);
} else {
ret = kr_nsec3_name_error_response_check(pkt, KNOT_AUTHORITY, qry->sname);
}
lib/layer/pktcache.c \
lib/dnssec/nsec.c \
lib/dnssec/nsec3.c \
- lib/dnssec/packet/pkt.c \
lib/dnssec/signature.c \
lib/dnssec/ta.c \
lib/dnssec.c \
lib/layer.h \
lib/dnssec/nsec.h \
lib/dnssec/nsec3.h \
- lib/dnssec/packet/pkt.h \
- lib/dnssec/rrtype/ds.h \
lib/dnssec/signature.h \
lib/dnssec/ta.h \
lib/dnssec.h \
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
-#include <libknot/internal/sockaddr.h>
#include "lib/nsrep.h"
#include "lib/rplan.h"
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
+#include <assert.h>
+#include <arpa/inet.h>
#include <libknot/rrtype/rdname.h>
#include <libknot/descriptor.h>
#include <ucw/mempool.h>
/* Find closest zone cut from cache */
struct kr_cache_txn txn;
- if (kr_cache_txn_begin(&req->ctx->cache, &txn, NAMEDB_RDONLY) == 0) {
+ if (kr_cache_txn_begin(&req->ctx->cache, &txn, KNOT_DB_RDONLY) == 0) {
/* If at/subdomain of parent zone cut, start from its encloser.
* This is for case when we get to a dead end (and need glue from parent), or DS refetch. */
struct kr_query *parent = qry->parent;
}
/* Set AD=1 if succeeded and requested secured answer. */
struct kr_rplan *rplan = &request->rplan;
- if (state == KNOT_STATE_DONE && !EMPTY_LIST(rplan->resolved)) {
- struct kr_query *last = TAIL(rplan->resolved);
+ if (state == KNOT_STATE_DONE && rplan->resolved.len > 0) {
+ struct kr_query *last = array_tail(rplan->resolved);
/* Do not set AD for RRSIG query, as we can't validate it. */
if ((last->flags & QUERY_DNSSEC_WANT) && knot_pkt_has_dnssec(answer) &&
knot_pkt_qtype(answer) != KNOT_RRTYPE_RRSIG) {
}
/* Different processing for network error */
- struct kr_query *qry = TAIL(rplan->pending);
+ struct kr_query *qry = array_tail(rplan->pending);
bool tried_tcp = (qry->flags & QUERY_TCP);
if (!packet || packet->size == 0) {
if (tried_tcp)
gettimeofday(&now, NULL);
kr_nsrep_update_rtt(&qry->ns, src, time_diff(&qry->timestamp, &now), ctx->cache_rtt);
WITH_DEBUG {
- char addr_str[SOCKADDR_STRLEN];
+ char addr_str[INET6_ADDRSTRLEN];
inet_ntop(src->sa_family, kr_inaddr(src), addr_str, sizeof(addr_str));
DEBUG_MSG(qry, "<= server: '%s' rtt: %ld ms\n", addr_str, time_diff(&qry->timestamp, &now));
}
} else if (!(qry->flags & QUERY_DNSSEC_BOGUS)) {
kr_nsrep_update_rtt(&qry->ns, src, KR_NS_TIMEOUT, ctx->cache_rtt);
WITH_DEBUG {
- char addr_str[SOCKADDR_STRLEN];
+ char addr_str[INET6_ADDRSTRLEN];
inet_ntop(src->sa_family, kr_inaddr(src), addr_str, sizeof(addr_str));
DEBUG_MSG(qry, "=> server: '%s' flagged as 'bad'\n", addr_str);
}
return KNOT_STATE_FAIL;
}
/* If we have deferred answers, resume them. */
- struct kr_query *qry = TAIL(rplan->pending);
+ struct kr_query *qry = array_tail(rplan->pending);
if (qry->deferred != NULL) {
/* @todo: Refactoring validator, check trust chain before resuming. */
switch(trust_chain_check(request, qry)) {
}
WITH_DEBUG {
- char qname_str[KNOT_DNAME_MAXLEN], zonecut_str[KNOT_DNAME_MAXLEN], ns_str[SOCKADDR_STRLEN], type_str[16];
+ char qname_str[KNOT_DNAME_MAXLEN], zonecut_str[KNOT_DNAME_MAXLEN], ns_str[INET6_ADDRSTRLEN], type_str[16];
knot_dname_to_str(qname_str, knot_pkt_qname(packet), sizeof(qname_str));
knot_dname_to_str(zonecut_str, qry->zone_cut.name, sizeof(zonecut_str));
knot_rrtype_to_string(knot_pkt_qtype(packet), type_str, sizeof(type_str));
request->state = state;
ITERATE_LAYERS(request, NULL, finish);
DEBUG_MSG(NULL, "finished: %d, queries: %zu, mempool: %zu B\n",
- request->state, list_size(&rplan->resolved), (size_t) mp_total_size(request->pool.ctx));
+ request->state, rplan->resolved.len, (size_t) mp_total_size(request->pool.ctx));
return KNOT_STATE_DONE;
}
return NULL;
}
-mm_ctx_t *kr_resolve_pool(struct kr_request *request)
+knot_mm_t *kr_resolve_pool(struct kr_request *request)
{
if (request) {
return &request->pool;
kr_nsrep_lru_t *cache_rtt;
kr_nsrep_lru_t *cache_rep;
module_array_t *modules;
- mm_ctx_t *pool;
+ knot_mm_t *pool;
};
/**
rr_array_t authority;
rr_array_t additional;
struct kr_rplan rplan;
- mm_ctx_t pool;
+ knot_mm_t pool;
};
/**
* @return mempool
*/
KR_EXPORT KR_PURE
-mm_ctx_t *kr_resolve_pool(struct kr_request *request);
+knot_mm_t *kr_resolve_pool(struct kr_request *request);
((q)->sclass == (cls) && (q)->stype == type && knot_dname_is_equal((q)->sname, name))
/** @internal LUT of query flag names. */
-const lookup_table_t query_flag_names[] = {
+const knot_lookup_t query_flag_names[] = {
#define X(flag, _) { QUERY_ ## flag, #flag },
QUERY_FLAGS(X)
#undef X
{ 0, NULL }
};
-const lookup_table_t *kr_query_flag_names(void)
+const knot_lookup_t *kr_query_flag_names(void)
{
return query_flag_names;
}
-static struct kr_query *query_create(mm_ctx_t *pool, const knot_dname_t *name)
+static struct kr_query *query_create(knot_mm_t *pool, const knot_dname_t *name)
{
if (name == NULL) {
return NULL;
return qry;
}
-static void query_free(mm_ctx_t *pool, struct kr_query *qry)
+static void query_free(knot_mm_t *pool, struct kr_query *qry)
{
kr_zonecut_deinit(&qry->zone_cut);
mm_free(pool, qry->sname);
mm_free(pool, qry);
}
-int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, mm_ctx_t *pool)
+int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, knot_mm_t *pool)
{
if (rplan == NULL) {
return KNOT_EINVAL;
rplan->pool = pool;
rplan->request = request;
- init_list(&rplan->pending);
- init_list(&rplan->resolved);
+ array_init(rplan->pending);
+ array_init(rplan->resolved);
return KNOT_EOK;
}
return;
}
- struct kr_query *qry = NULL, *next = NULL;
- WALK_LIST_DELSAFE(qry, next, rplan->pending) {
- query_free(rplan->pool, qry);
+ for (size_t i = 0; i < rplan->pending.len; ++i) {
+ query_free(rplan->pool, rplan->pending.at[i]);
}
- WALK_LIST_DELSAFE(qry, next, rplan->resolved) {
- query_free(rplan->pool, qry);
+ for (size_t i = 0; i < rplan->resolved.len; ++i) {
+ query_free(rplan->pool, rplan->resolved.at[i]);
}
+ array_clear_mm(rplan->pending, mm_free, rplan->pool);
+ array_clear_mm(rplan->resolved, mm_free, rplan->pool);
}
bool kr_rplan_empty(struct kr_rplan *rplan)
return true;
}
- return EMPTY_LIST(rplan->pending);
+ return rplan->pending.len == 0;
}
struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
return NULL;
}
+ /* Make sure there's enough space */
+ int ret = array_reserve_mm(rplan->pending, rplan->pending.len + 1, kr_memreserve, rplan->pool);
+ if (ret != 0) {
+ return NULL;
+ }
+
struct kr_query *qry = query_create(rplan->pool, name);
if (qry == NULL) {
return NULL;
qry->parent = parent;
qry->ns.addr[0].ip.sa_family = AF_UNSPEC;
gettimeofday(&qry->timestamp, NULL);
- add_tail(&rplan->pending, &qry->node);
kr_zonecut_init(&qry->zone_cut, (const uint8_t *)"", rplan->pool);
+ array_push(rplan->pending, qry);
WITH_DEBUG {
char name_str[KNOT_DNAME_MAXLEN], type_str[16];
return KNOT_EINVAL;
}
- rem_node(&qry->node);
- add_tail(&rplan->resolved, &qry->node);
+ /* Make sure there's enough space */
+ int ret = array_reserve_mm(rplan->resolved, rplan->resolved.len + 1, kr_memreserve, rplan->pool);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Find the query, it will likely be on top */
+ for (size_t i = rplan->pending.len; i --> 0;) {
+ if (rplan->pending.at[i] == qry) {
+ array_del(rplan->pending, i);
+ array_push(rplan->resolved, qry);
+ break;
+ }
+ }
return KNOT_EOK;
}
bool kr_rplan_satisfies(struct kr_query *closure, const knot_dname_t *name, uint16_t cls, uint16_t type)
{
- if (!name)
- return false;
- while (closure != NULL) {
+ while (name && closure) {
if (QUERY_PROVIDES(closure, name, cls, type)) {
return true;
}
struct kr_query *kr_rplan_resolved(struct kr_rplan *rplan)
{
- if (EMPTY_LIST(rplan->resolved)) {
- return NULL;
- }
- return TAIL(rplan->resolved);
-}
-
-struct kr_query *kr_rplan_next(struct kr_query *qry)
-{
- if (!qry) {
+ if (rplan->resolved.len == 0) {
return NULL;
}
- return (struct kr_query *)qry->node.prev; /* The lists are used as stack, TOP is the TAIL. */
+ return array_tail(rplan->resolved);
}
#undef DEBUG_MSG
#include <sys/time.h>
#include <libknot/dname.h>
-#include <libknot/internal/lists.h>
-#include <libknot/internal/namedb/namedb.h>
-#include <libknot/internal/sockaddr.h>
+#include <libknot/codes.h>
#include "lib/cache.h"
#include "lib/zonecut.h"
/** Query flag names table */
KR_EXPORT KR_CONST
-const lookup_table_t *kr_query_flag_names(void);
+const knot_lookup_t *kr_query_flag_names(void);
/**
* Single query representation.
*/
struct kr_query {
- node_t node;
struct kr_query *parent;
knot_dname_t *sname;
uint16_t stype;
struct kr_layer_pickle *deferred;
};
+/** @internal Array of queries. */
+typedef array_t(struct kr_query *) kr_qarray_t;
+
/**
* Query resolution plan structure.
*
* It also keeps a notion of current zone cut.
*/
struct kr_rplan {
- list_t pending; /**< List of pending queries. */
- list_t resolved; /**< List of resolved queries. */
- struct kr_request *request; /**< Parent resolution request. */
- mm_ctx_t *pool; /**< Temporary memory pool. */
+ kr_qarray_t pending; /**< List of pending queries. */
+ kr_qarray_t resolved; /**< List of resolved queries. */
+ struct kr_request *request; /**< Parent resolution request. */
+ knot_mm_t *pool; /**< Temporary memory pool. */
};
/**
* @param pool ephemeral memory pool for whole resolution
*/
KR_EXPORT
-int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, mm_ctx_t *pool);
+int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, knot_mm_t *pool);
/**
* Deinitialize resolution plan, aborting any uncommited transactions.
if (*have >= want) {
return 0;
} else {
- mm_ctx_t *pool = baton;
+ knot_mm_t *pool = baton;
size_t next_size = array_next_count(want);
void *mem_new = mm_alloc(pool, next_size * elm_size);
if (mem_new != NULL) {
return (char *)&key_buf[ret] - key;
}
-int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, mm_ctx_t *pool)
+int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, knot_mm_t *pool)
{
if (!stash || !rr) {
return kr_error(EINVAL);
return knot_rdataset_merge(&stashed->rrs, &rr->rrs, pool);
}
-int kr_rrarray_add(rr_array_t *array, const knot_rrset_t *rr, mm_ctx_t *pool)
+int kr_rrarray_add(rr_array_t *array, const knot_rrset_t *rr, knot_mm_t *pool)
{
int ret = array_reserve_mm(*array, array->len + 1, kr_memreserve, pool);
if (ret != 0) {
#pragma once
#include <stdio.h>
+#include <stdbool.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <libknot/packet/pkt.h>
#include "lib/generic/map.h"
#include "lib/generic/array.h"
+#include "lib/defines.h"
/*
* Logging and debugging.
#define WITH_DEBUG if(0)
#endif
+/** @cond Memory alloc routines */
+static inline void *mm_alloc(knot_mm_t *mm, size_t size)
+{
+ if (mm) return mm->alloc(mm->ctx, size);
+ else return malloc(size);
+}
+static inline void mm_free(knot_mm_t *mm, void *what)
+{
+ if (mm) {
+ if (mm->free)
+ mm->free(what);
+ }
+ else free(what);
+}
+/* @endcond */
+
/** Return time difference in miliseconds.
* @note based on the _BSD_SOURCE timersub() macro */
static inline long time_diff(struct timeval *begin, struct timeval *end) {
KR_EXPORT
unsigned kr_rand_uint(unsigned max);
-/** Memory reservation routine for mm_ctx_t */
+/** Memory reservation routine for knot_mm_t */
KR_EXPORT
int kr_memreserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have);
* @note RRSIG RRSets are merged according the type covered fields.
* @return 0 or an error
*/
-int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, mm_ctx_t *pool);
+int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, knot_mm_t *pool);
/** @internal Add RRSet copy to RR array. */
-int kr_rrarray_add(rr_array_t *array, const knot_rrset_t *rr, mm_ctx_t *pool);
+int kr_rrarray_add(rr_array_t *array, const knot_rrset_t *rr, knot_mm_t *pool);
/**
* Call module property.
cut->name = next_name;
}
-int kr_zonecut_init(struct kr_zonecut *cut, const knot_dname_t *name, mm_ctx_t *pool)
+int kr_zonecut_init(struct kr_zonecut *cut, const knot_dname_t *name, knot_mm_t *pool)
{
if (!cut || !name) {
return kr_error(EINVAL);
* Fetch RRSet of given type.
*/
static int fetch_rrset(knot_rrset_t **rr, const knot_dname_t *owner, uint16_t type,
- struct kr_cache_txn *txn, mm_ctx_t *pool, uint32_t timestamp)
+ struct kr_cache_txn *txn, knot_mm_t *pool, uint32_t timestamp)
{
if (!rr) {
return kr_error(ENOENT);
knot_rrset_t* key; /**< Zone cut DNSKEY. */
knot_rrset_t* trust_anchor; /**< Current trust anchor. */
struct kr_zonecut *parent; /**< Parent zone cut. */
- mm_ctx_t *pool; /**< Memory pool. */
+ knot_mm_t *pool; /**< Memory pool. */
};
/**
* @return 0 or error code
*/
KR_EXPORT
-int kr_zonecut_init(struct kr_zonecut *cut, const knot_dname_t *name, mm_ctx_t *pool);
+int kr_zonecut_init(struct kr_zonecut *cut, const knot_dname_t *name, knot_mm_t *pool);
/**
* Clear the structure and free the address set.
#include <time.h>
#include <libknot/descriptor.h>
+#include <libknot/error.h>
#include <ccan/json/json.h>
#include "daemon/engine.h"
* Properties.
*/
-typedef int (*cache_cb_t)(struct kr_cache_txn *txn, namedb_iter_t *it, namedb_val_t *key, void *baton);
+typedef int (*cache_cb_t)(struct kr_cache_txn *txn, knot_db_iter_t *it, knot_db_val_t *key, void *baton);
/** @internal Prefix walk. */
static int cache_prefixed(struct engine *engine, const char *args, unsigned txn_flags, cache_cb_t cb, void *baton)
/* Start search transaction */
struct kr_cache *cache = &engine->resolver.cache;
- const namedb_api_t *api = cache->api;
+ const knot_db_api_t *api = cache->api;
struct kr_cache_txn txn;
ret = kr_cache_txn_begin(cache, &txn, txn_flags);
if (ret != 0) {
/* Walk through cache records matching given prefix.
* Note that since the backend of the cache is opaque, there's no exactly efficient
* way to do prefix search (i.e. Redis uses hashtable but offers SCAN, LMDB can do lexical closest match, ...). */
- namedb_val_t key = { prefix, prefix_len };
- namedb_iter_t *it = api->iter_begin(&txn.t, 0);
+ knot_db_val_t key = { prefix, prefix_len };
+ knot_db_iter_t *it = api->iter_begin(&txn.t, 0);
if (it) { /* Seek first key matching the prefix. */
- it = api->iter_seek(it, &key, NAMEDB_GEQ);
+ it = api->iter_seek(it, &key, KNOT_DB_GEQ);
}
while (it != NULL) {
if (api->iter_key(it, &key) != 0) {
}
/** @internal Delete iterated key. */
-static int cache_delete_cb(struct kr_cache_txn *txn, namedb_iter_t *it, namedb_val_t *key, void *baton)
+static int cache_delete_cb(struct kr_cache_txn *txn, knot_db_iter_t *it, knot_db_val_t *key, void *baton)
{
struct kr_cache *cache = txn->owner;
return cache->api->del(&txn->t, key);
{
struct engine *engine = env;
struct kr_cache *cache = &engine->resolver.cache;
- const namedb_api_t *storage = cache->api;
+ const knot_db_api_t *storage = cache->api;
struct kr_cache_txn txn;
int ret = kr_cache_txn_begin(cache, &txn, 0);
/* Fetch current time and start iterating */
struct timeval now;
gettimeofday(&now, NULL);
- namedb_iter_t *it = storage->iter_begin(&txn.t, 0);
+ knot_db_iter_t *it = storage->iter_begin(&txn.t, 0);
while (it && pruned < prune_max) {
/* Fetch RR from cache */
- namedb_val_t key, val;
+ knot_db_val_t key, val;
if (storage->iter_key(it, &key) != 0 ||
storage->iter_val(it, &val) != 0) {
break;
}
/** @internal Serialize cached record name into JSON. */
-static int cache_dump_cb(struct kr_cache_txn *txn, namedb_iter_t *it, namedb_val_t *key, void *baton)
+static int cache_dump_cb(struct kr_cache_txn *txn, knot_db_iter_t *it, knot_db_val_t *key, void *baton)
{
JsonNode* json_records = baton;
char buf[KNOT_DNAME_MAXLEN];
char *result = NULL;
JsonNode *json_records = json_mkobject();
if (json_records) {
- int ret = cache_prefixed(env, args, NAMEDB_RDONLY, &cache_dump_cb, json_records);
+ int ret = cache_prefixed(env, args, KNOT_DB_RDONLY, &cache_dump_cb, json_records);
if (ret == 0) {
result = json_encode(json_records);
}
static int parse_addr_str(struct sockaddr_storage *sa, const char *addr)
{
int family = strchr(addr, ':') ? AF_INET6 : AF_INET;
- return sockaddr_set(sa, family, addr, 0);
+ memset(sa, 0, sizeof(struct sockaddr_storage));
+ sa->ss_family = family;
+ char *addr_bytes = (char *)kr_inaddr((struct sockaddr *)sa);
+ if (inet_pton(family, addr, addr_bytes) < 1) {
+ return kr_error(EILSEQ);
+ }
+ return 0;
}
static int add_pair(struct kr_zonecut *hints, const char *name, const char *addr)
}
/* Create pool and copy itself */
- mm_ctx_t _pool = {
+ knot_mm_t _pool = {
.ctx = mp_new(4096),
- .alloc = (mm_alloc_t) mp_alloc
+ .alloc = (knot_mm_alloc_t) mp_alloc
};
- mm_ctx_t *pool = mm_alloc(&_pool, sizeof(*pool));
+ knot_mm_t *pool = mm_alloc(&_pool, sizeof(*pool));
if (!pool) {
return kr_error(ENOMEM);
}
/** @internal Pack address list into JSON array. */
static JsonNode *pack_addrs(pack_t *pack)
{
- char buf[SOCKADDR_STRLEN];
+ char buf[INET6_ADDRSTRLEN];
JsonNode *root = json_mkarray();
uint8_t *addr = pack_head(*pack);
while (addr != pack_tail(*pack)) {
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libknot/internal/namedb/namedb.h>
+#include <libknot/db/db.h>
#include <contrib/cleanup.h>
#include "daemon/engine.h"
#include "lib/cache.h"
/** @internal Memcached API */
-extern const namedb_api_t *namedb_memcached_api(void);
+extern const knot_db_api_t *namedb_memcached_api(void);
/** @internal Make memcached options. */
void *namedb_memcached_mkopts(const char *conf, size_t maxsize)
#include <assert.h>
#include <string.h>
#include <libmemcached/memcached.h>
-#include <libknot/internal/namedb/namedb.h>
+#include <libknot/db/db.h>
#include <libknot/errcode.h>
#include <contrib/cleanup.h>
/* Oh, the irony... */
typedef array_t(char *) freelist_t;
-static int init(namedb_t **db, mm_ctx_t *mm, void *arg)
+static int init(knot_db_t **db, knot_mm_t *mm, void *arg)
{
if (!db || !arg) {
return KNOT_EINVAL;
return KNOT_EOK;
}
-static void deinit(namedb_t *db)
+static void deinit(knot_db_t *db)
{
memcached_free((memcached_st *)db);
}
-static int txn_begin(namedb_t *db, namedb_txn_t *txn, unsigned flags)
+static int txn_begin(knot_db_t *db, knot_db_txn_t *txn, unsigned flags)
{
freelist_t *freelist = malloc(sizeof(*freelist));
if (!freelist) {
return KNOT_EOK;
}
-static int txn_commit(namedb_txn_t *txn)
+static int txn_commit(knot_db_txn_t *txn)
{
freelist_t *freelist = txn->txn;
if (freelist) {
return KNOT_EOK;
}
-static void txn_abort(namedb_txn_t *txn)
+static void txn_abort(knot_db_txn_t *txn)
{
/** @warning No real transactions here,
* all the reads/writes are done synchronously.
txn_commit(txn);
}
-static int count(namedb_txn_t *txn)
+static int count(knot_db_txn_t *txn)
{
memcached_return_t error = 0;
memcached_stat_st *stats = memcached_stat(txn->db, NULL, &error);
return ret;
}
-static int clear(namedb_txn_t *txn)
+static int clear(knot_db_txn_t *txn)
{
memcached_return_t ret = memcached_flush(txn->db, 0);
if (ret != 0) {
return KNOT_EOK;
}
-static int find(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
+static int find(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, unsigned flags)
{
uint32_t mc_flags = 0;
memcached_return_t error = 0;
return KNOT_EOK;
}
-static int insert(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
+static int insert(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, unsigned flags)
{
if (!txn || !key || !val) {
return KNOT_EINVAL;
return KNOT_EOK;
}
-static int del(namedb_txn_t *txn, namedb_val_t *key)
+static int del(knot_db_txn_t *txn, knot_db_val_t *key)
{
memcached_return_t ret = memcached_delete(txn->db, key->data, key->len, 0);
if (ret != 0) {
return KNOT_EOK;
}
-static namedb_iter_t *iter_begin(namedb_txn_t *txn, unsigned flags)
+static knot_db_iter_t *iter_begin(knot_db_txn_t *txn, unsigned flags)
{
/* Iteration is not supported, pruning should be
* left on the memcached server */
return NULL;
}
-static namedb_iter_t *iter_seek(namedb_iter_t *iter, namedb_val_t *key, unsigned flags)
+static knot_db_iter_t *iter_seek(knot_db_iter_t *iter, knot_db_val_t *key, unsigned flags)
{
assert(0);
return NULL; /* ENOTSUP */
}
-static namedb_iter_t *iter_next(namedb_iter_t *iter)
+static knot_db_iter_t *iter_next(knot_db_iter_t *iter)
{
assert(0);
return NULL;
}
-static int iter_key(namedb_iter_t *iter, namedb_val_t *val)
+static int iter_key(knot_db_iter_t *iter, knot_db_val_t *val)
{
return KNOT_ENOTSUP;
}
-static int iter_val(namedb_iter_t *iter, namedb_val_t *val)
+static int iter_val(knot_db_iter_t *iter, knot_db_val_t *val)
{
return KNOT_ENOTSUP;
}
-static void iter_finish(namedb_iter_t *iter)
+static void iter_finish(knot_db_iter_t *iter)
{
assert(0);
}
-const namedb_api_t *namedb_memcached_api(void)
+const knot_db_api_t *namedb_memcached_api(void)
{
- static const namedb_api_t api = {
+ static const knot_db_api_t api = {
"memcached",
init, deinit,
txn_begin, txn_commit, txn_abort,
#include <assert.h>
#include <string.h>
-#include <libknot/internal/namedb/namedb.h>
+#include <libknot/db/db.h>
#include "modules/redis/redis.h"
free(cli);
}
-static int init(namedb_t **db, mm_ctx_t *mm, void *arg)
+static int init(knot_db_t **db, knot_mm_t *mm, void *arg)
{
if (!db || !arg) {
return kr_error(EINVAL);
return ret;
}
-static void deinit(namedb_t *db)
+static void deinit(knot_db_t *db)
{
struct redis_cli *cli = db;
cli_free(cli);
}
-static int txn_begin(namedb_t *db, namedb_txn_t *txn, unsigned flags)
+static int txn_begin(knot_db_t *db, knot_db_txn_t *txn, unsigned flags)
{
if (!db || !txn) {
return kr_error(EINVAL);
return kr_ok();
}
-static int txn_commit(namedb_txn_t *txn)
+static int txn_commit(knot_db_txn_t *txn)
{
if (!txn || !txn->db) {
return kr_error(EINVAL);
return kr_ok();
}
-static void txn_abort(namedb_txn_t *txn)
+static void txn_abort(knot_db_txn_t *txn)
{
/** @warning No real transactions here. */
txn_commit(txn);
} \
}
-static int count(namedb_txn_t *txn)
+static int count(knot_db_txn_t *txn)
{
if (!txn || !txn->db) {
return kr_error(EINVAL);
return ret;
}
-static int clear(namedb_txn_t *txn)
+static int clear(knot_db_txn_t *txn)
{
if (!txn || !txn->db) {
return kr_error(EINVAL);
return kr_ok();
}
-static int find(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
+static int find(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, unsigned flags)
{
if (!txn || !key || !val) {
return kr_error(EINVAL);
return kr_ok();
}
-static int insert(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
+static int insert(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, unsigned flags)
{
if (!txn || !key || !val) {
return kr_error(EINVAL);
return kr_ok();
}
-static int del(namedb_txn_t *txn, namedb_val_t *key)
+static int del(knot_db_txn_t *txn, knot_db_val_t *key)
{
return kr_error(ENOSYS);
}
-static namedb_iter_t *iter_begin(namedb_txn_t *txn, unsigned flags)
+static knot_db_iter_t *iter_begin(knot_db_txn_t *txn, unsigned flags)
{
/* Iteration is not supported, pruning should be
* left on the Redis server setting */
return NULL;
}
-static namedb_iter_t *iter_seek(namedb_iter_t *iter, namedb_val_t *key, unsigned flags)
+static knot_db_iter_t *iter_seek(knot_db_iter_t *iter, knot_db_val_t *key, unsigned flags)
{
assert(0);
return NULL; /* ENOSYS */
}
-static namedb_iter_t *iter_next(namedb_iter_t *iter)
+static knot_db_iter_t *iter_next(knot_db_iter_t *iter)
{
assert(0);
return NULL;
}
-static int iter_key(namedb_iter_t *iter, namedb_val_t *val)
+static int iter_key(knot_db_iter_t *iter, knot_db_val_t *val)
{
return kr_error(ENOSYS);
}
-static int iter_val(namedb_iter_t *iter, namedb_val_t *val)
+static int iter_val(knot_db_iter_t *iter, knot_db_val_t *val)
{
return kr_error(ENOSYS);
}
-static void iter_finish(namedb_iter_t *iter)
+static void iter_finish(knot_db_iter_t *iter)
{
assert(0);
}
-const namedb_api_t *namedb_redis_api(void)
+const knot_db_api_t *namedb_redis_api(void)
{
- static const namedb_api_t api = {
+ static const knot_db_api_t api = {
"redis",
init, deinit,
txn_begin, txn_commit, txn_abort,
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libknot/internal/namedb/namedb.h>
+#include <libknot/db/db.h>
#include <contrib/cleanup.h>
#include <uv.h>
#include "lib/cache.h"
/** @internal Redis API */
-extern const namedb_api_t *namedb_redis_api(void);
+extern const knot_db_api_t *namedb_redis_api(void);
/** @internal Make redis options. */
void *namedb_redis_mkopts(const char *conf_, size_t maxsize)
{
/* Sample key = {[2] type, [1-255] owner} */
char key[sizeof(uint16_t) + KNOT_DNAME_MAXLEN];
- struct kr_query *qry = NULL;
- WALK_LIST(qry, rplan->resolved) {
+ for (size_t i = 0; i < rplan->resolved.len; ++i) {
/* Sample queries leading to iteration or expiring */
+ struct kr_query *qry = rplan->resolved.at[i];
if ((qry->flags & QUERY_CACHED) && !(qry->flags & QUERY_EXPIRING)) {
continue;
}
collect_answer(data, param->answer);
collect_sample(data, rplan, param->answer);
/* Count cached and unresolved */
- if (!EMPTY_LIST(rplan->resolved)) {
+ if (rplan->resolved.len > 0) {
/* Histogram of answer latency. */
- struct kr_query *first = HEAD(rplan->resolved);
- struct kr_query *last = TAIL(rplan->resolved);
+ struct kr_query *first = rplan->resolved.at[0];
+ struct kr_query *last = array_tail(rplan->resolved);
struct timeval now;
gettimeofday(&now, NULL);
long elapsed = time_diff(&first->timestamp, &now);
CMOCKA_URL="git://git.cryptomilk.org/projects/cmocka.git"
LIBUV_TAG="v1.x"
LIBUV_URL="https://github.com/libuv/libuv.git"
-KNOT_TAG="c1353efc"
+KNOT_TAG="27ccff2"
KNOT_URL="https://github.com/CZ-NIC/knot.git"
GMP_TAG="6.0.0"
GMP_URL="https://gmplib.org/download/gmp/gmp-${GMP_TAG}.tar.xz"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include "lib/defines.h"
-#include <libknot/internal/mempattern.h>
+#include "lib/utils.h"
#include <libknot/descriptor.h>
#include <libknot/rrset.h>
{ if (p) test_free(p); }
/** Memory context using CMocka allocator. */
-static inline void test_mm_ctx_init(mm_ctx_t *mm)
+static inline void test_mm_ctx_init(knot_mm_t *mm)
{
mm->alloc = &mm_test_malloc;
mm->free = &mm_test_free;
#include "tests/test.h"
#include "lib/generic/array.h"
-mm_ctx_t global_mm;
+knot_mm_t global_mm;
static void test_array(void **state)
{
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libknot/internal/namedb/namedb_lmdb.h>
+#include <libknot/db/db_lmdb.h>
#include <ucw/mempool.h>
#include "tests/test.h"
#include <time.h>
#include <dlfcn.h>
-mm_ctx_t global_mm;
+knot_mm_t global_mm;
struct kr_cache_txn global_txn;
knot_rrset_t global_rr;
const char *global_env;
#define NAMEDB_INTS 256
#define NAMEDB_DATA_SIZE (NAMEDB_INTS * sizeof(int))
uint8_t namedb_data[NAMEDB_DATA_SIZE];
-namedb_val_t global_namedb_data = {namedb_data, NAMEDB_DATA_SIZE};
+knot_db_val_t global_namedb_data = {namedb_data, NAMEDB_DATA_SIZE};
bool is_malloc_mocked = false;
#define CACHE_SIZE 10 * 4096
#define CACHE_TIME 0
void * (*original_malloc) (size_t __size);
-int (*original_knot_rdataset_add)(knot_rdataset_t *rrs, const knot_rdata_t *rr, mm_ctx_t *mm) = NULL;
+int (*original_knot_rdataset_add)(knot_rdataset_t *rrs, const knot_rdata_t *rr, knot_mm_t *mm) = NULL;
void *malloc(size_t __size)
{
return (err_mock != KNOT_EOK) ? NULL : original_malloc (__size);
}
-int knot_rdataset_add(knot_rdataset_t *rrs, const knot_rdata_t *rr, mm_ctx_t *mm)
+int knot_rdataset_add(knot_rdataset_t *rrs, const knot_rdata_t *rr, knot_mm_t *mm)
{
int err, err_mock;
err_mock = (int)mock();
}
/* Simulate init failure */
-static int fake_test_init(namedb_t **db_ptr, mm_ctx_t *mm, void *arg)
+static int fake_test_init(knot_db_t **db_ptr, knot_mm_t *mm, void *arg)
{
static char db[1024];
*db_ptr = db;
return mock();
}
-static void fake_test_deinit(namedb_t *db)
+static void fake_test_deinit(knot_db_t *db)
{
return;
}
/* Simulate commit failure */
-static int fake_test_commit(namedb_txn_t *txn)
+static int fake_test_commit(knot_db_txn_t *txn)
{
return KNOT_ESPACE;
}
/* Dummy abort */
-static void fake_test_abort(namedb_txn_t *txn)
+static void fake_test_abort(knot_db_txn_t *txn)
{
return;
}
/* Stub for find */
-static int fake_test_find(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
+static int fake_test_find(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, unsigned flags)
{
val->data = &global_fake_ce;
return KNOT_EOK;
}
/* Stub for insert */
-static int fake_test_ins(namedb_txn_t *txn, namedb_val_t *key, namedb_val_t *val, unsigned flags)
+static int fake_test_ins(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, unsigned flags)
{
struct kr_cache_entry *header = val->data;
int res_cmp, err = (int)mock();
return err;
}
-static int fake_test_txn_begin(namedb_t *db, namedb_txn_t *txn, unsigned flags)
+static int fake_test_txn_begin(knot_db_t *db, knot_db_txn_t *txn, unsigned flags)
{
return KNOT_EOK;
}
/* Fake api */
-static namedb_api_t *fake_namedb_lmdb_api(void)
+static knot_db_api_t *fake_knot_db_lmdb_api(void)
{
- static namedb_api_t fake_api = {
+ static knot_db_api_t fake_api = {
"lmdb_fake_api",
fake_test_init, fake_test_deinit,
fake_test_txn_begin, fake_test_commit, fake_test_abort,
}
/* Test cache open */
-static int test_open(void **state, namedb_api_t *api)
+static int test_open(void **state, knot_db_api_t *api)
{
static struct kr_cache cache;
- struct namedb_lmdb_opts opts;
+ struct knot_db_lmdb_opts opts;
memset(&cache, 0, sizeof(cache));
memset(&opts, 0, sizeof(opts));
opts.path = global_env;
{
bool res;
will_return(fake_test_init,KNOT_EINVAL);
- assert_int_equal(test_open(state, fake_namedb_lmdb_api()),KNOT_EINVAL);
+ assert_int_equal(test_open(state, fake_knot_db_lmdb_api()),KNOT_EINVAL);
will_return(fake_test_init,KNOT_EOK);
- assert_int_equal(test_open(state, fake_namedb_lmdb_api()),KNOT_EOK);
- res = (((struct kr_cache *)(*state))->api == fake_namedb_lmdb_api());
+ assert_int_equal(test_open(state, fake_knot_db_lmdb_api()),KNOT_EOK);
+ res = (((struct kr_cache *)(*state))->api == fake_knot_db_lmdb_api());
assert_true(res);
}
{
bool res;
assert_int_equal(test_open(state, NULL),KNOT_EOK);
- res = (((struct kr_cache *)(*state))->api == namedb_lmdb_api());
+ res = (((struct kr_cache *)(*state))->api == knot_db_lmdb_api());
assert_true(res);
}
static struct kr_cache_txn *test_txn_rdonly(void **state)
{
assert_non_null(*state);
- assert_int_equal(kr_cache_txn_begin(*state, &global_txn, NAMEDB_RDONLY), 0);
+ assert_int_equal(kr_cache_txn_begin(*state, &global_txn, KNOT_DB_RDONLY), 0);
return &global_txn;
}
static void test_fake_invalid (void **state)
{
struct kr_cache_txn *txn = NULL;
- const namedb_api_t *api_saved = NULL;
+ const knot_db_api_t *api_saved = NULL;
knot_dname_t dname[] = "";
struct kr_cache_entry *entry = NULL;
int ret = 0;
{
knot_dname_t dname[] = "";
uint32_t timestamp = CACHE_TIME;
- struct namedb_lmdb_opts opts;
+ struct knot_db_lmdb_opts opts;
struct kr_cache_entry *entry = NULL;
memset(&opts, 0, sizeof(opts));
#include "lib/generic/pack.h"
#define U8(x) (const uint8_t *)(x)
-mm_ctx_t global_mm;
+knot_mm_t global_mm;
static void test_pack_std(void **state)
{
static void test_rplan_push(void **state)
{
- mm_ctx_t mm;
+ knot_mm_t mm;
test_mm_ctx_init(&mm);
struct kr_request request = {
.pool = mm,