Commit e0fe89e5 authored by Marek Vavruša's avatar Marek Vavruša Committed by Marek Vavruša

build: library able to compile to both static/dynamic versioned libs

* PIE,RELRO+NOW and other security features enabled
* support for both static/dynamic builds with BUILDMODE
* dynamic library is ABI-versioned, starting at 1
* pkg-config file is installed
parent 374ed2ca
......@@ -2,6 +2,8 @@
MAJOR := 1
MINOR := 0
PATCH := 0-beta2
ABIVER := 1
BUILDMODE := dynamic
HARDENING := yes
# Paths
......
contrib_SOURCES := \
contrib/ccan/asprintf/asprintf.c \
contrib/ccan/ilog/ilog.c \
contrib/ccan/isaac/isaac.c \
contrib/ccan/json/json.c \
contrib/ucw/mempool.c \
contrib/murmurhash3/murmurhash3.c
contrib_CFLAGS := -fPIC
contrib_TARGET := $(abspath contrib)/contrib$(AREXT)
$(eval $(call make_static,contrib,contrib))
......@@ -24,7 +24,7 @@ bindings-install: $(kresd_DIST) $(DESTDIR)$(MODULEDIR)
kresd_CFLAGS := -fPIE
kresd_DEPEND := $(libkres) $(contrib)
kresd_LIBS := $(contrib_TARGET) $(libkres_TARGET) $(libknot_LIBS) $(libdnssec_LIBS) $(libuv_LIBS) $(lua_LIBS)
kresd_LIBS := $(libkres_TARGET) $(contrib_TARGET) $(libknot_LIBS) $(libdnssec_LIBS) $(libuv_LIBS) $(lua_LIBS)
# Make binary
ifeq ($(HAS_lua)|$(HAS_libuv), yes|yes)
......
......@@ -154,9 +154,9 @@ static int l_quit(lua_State *L)
static int l_verbose(lua_State *L)
{
if (lua_isboolean(L, 1) || lua_isnumber(L, 1)) {
log_debug_enable(lua_toboolean(L, 1));
kr_debug_set(lua_toboolean(L, 1));
}
lua_pushboolean(L, log_debug_status());
lua_pushboolean(L, kr_debug_status());
return 1;
}
......@@ -177,7 +177,7 @@ static int l_option(lua_State *L)
unsigned opt_code = 0;
if (lua_isstring(L, 1)) {
const char *opt = lua_tostring(L, 1);
for (const lookup_table_t *it = query_flag_names; it->name; ++it) {
for (const lookup_table_t *it = kr_query_flag_names(); it->name; ++it) {
if (strcmp(it->name, opt) == 0) {
opt_code = it->id;
break;
......
......@@ -236,12 +236,12 @@ int main(int argc, char **argv)
g_interactive = 0;
forks = atoi(optarg);
if (forks == 0) {
log_error("[system] error '-f' requires number, not '%s'\n", optarg);
kr_log_error("[system] error '-f' requires number, not '%s'\n", optarg);
return EXIT_FAILURE;
}
#if (!defined(UV_VERSION_HEX)) || (!defined(SO_REUSEPORT))
if (forks > 1) {
log_error("[system] libuv 1.7+ is required for SO_REUSEPORT support, multiple forks not supported\n");
kr_log_error("[system] libuv 1.7+ is required for SO_REUSEPORT support, multiple forks not supported\n");
return EXIT_FAILURE;
}
#endif
......@@ -269,15 +269,15 @@ int main(int argc, char **argv)
}
free(keyfile_buf);
if (!keyfile) {
log_error("[system] keyfile '%s': not writeable\n", optarg);
kr_log_error("[system] keyfile '%s': not writeable\n", optarg);
return EXIT_FAILURE;
}
break;
case 'v':
log_debug_enable(true);
kr_debug_set(true);
break;
case 'V':
log_info("%s, version %s\n", "Knot DNS Resolver", PACKAGE_VERSION);
kr_log_info("%s, version %s\n", "Knot DNS Resolver", PACKAGE_VERSION);
return EXIT_SUCCESS;
case 'h':
case '?':
......@@ -293,17 +293,17 @@ int main(int argc, char **argv)
if (optind < argc) {
const char *rundir = argv[optind];
if (access(rundir, W_OK) != 0) {
log_error("[system] rundir '%s': %s\n", rundir, strerror(errno));
kr_log_error("[system] rundir '%s': %s\n", rundir, strerror(errno));
return EXIT_FAILURE;
}
ret = chdir(rundir);
if (ret != 0) {
log_error("[system] rundir '%s': %s\n", rundir, strerror(errno));
kr_log_error("[system] rundir '%s': %s\n", rundir, strerror(errno));
return EXIT_FAILURE;
}
if(config && access(config, R_OK) != 0) {
log_error("[system] rundir '%s'\n", rundir);
log_error("[system] config '%s': %s\n", config, strerror(errno));
kr_log_error("[system] rundir '%s'\n", rundir);
kr_log_error("[system] config '%s': %s\n", config, strerror(errno));
return EXIT_FAILURE;
}
}
......@@ -340,13 +340,13 @@ int main(int argc, char **argv)
struct engine engine;
ret = engine_init(&engine, &pool);
if (ret != 0) {
log_error("[system] failed to initialize engine: %s\n", kr_strerror(ret));
kr_log_error("[system] failed to initialize engine: %s\n", kr_strerror(ret));
return EXIT_FAILURE;
}
/* Create worker */
struct worker_ctx *worker = init_worker(loop, &engine, &pool, forks, fork_count);
if (!worker) {
log_error("[system] not enough memory\n");
kr_log_error("[system] not enough memory\n");
return EXIT_FAILURE;
}
/* Bind to sockets and run */
......@@ -355,7 +355,7 @@ int main(int argc, char **argv)
const char *addr = set_addr(addr_set.at[i], &port);
ret = network_listen(&engine.net, addr, (uint16_t)port, NET_UDP|NET_TCP);
if (ret != 0) {
log_error("[system] bind to '%s#%d' %s\n", addr, port, knot_strerror(ret));
kr_log_error("[system] bind to '%s#%d' %s\n", addr, port, knot_strerror(ret));
ret = EXIT_FAILURE;
}
}
......@@ -366,7 +366,7 @@ int main(int argc, char **argv)
if (keyfile) {
auto_free char *cmd = afmt("trust_anchors.file = '%s'", keyfile);
if (!cmd) {
log_error("[system] not enough memory\n");
kr_log_error("[system] not enough memory\n");
return EXIT_FAILURE;
}
engine_cmd(&engine, cmd);
......
......@@ -484,7 +484,7 @@ static int subreq_key(char *dst, struct qr_task *task)
assert(task);
knot_pkt_t *pkt = task->pktbuf;
assert(knot_wire_get_qr(pkt->wire) == false);
return kr_rrmap_key(dst, knot_pkt_qname(pkt), knot_pkt_qtype(pkt), knot_pkt_qclass(pkt));
return kr_rrkey(dst, knot_pkt_qname(pkt), knot_pkt_qtype(pkt), knot_pkt_qclass(pkt));
}
static void subreq_finalize(struct qr_task *task, const struct sockaddr *packet_source, knot_pkt_t *pkt)
......@@ -498,7 +498,7 @@ static void subreq_finalize(struct qr_task *task, const struct sockaddr *packet_
/* Clear from outstanding table. */
if (!task->leading)
return;
char key[RRMAP_KEYSIZE];
char key[KR_RRKEY_LEN];
int ret = subreq_key(key, task);
if (ret > 0) {
assert(map_get(&task->worker->outstanding, key) == task);
......@@ -525,7 +525,7 @@ static void subreq_finalize(struct qr_task *task, const struct sockaddr *packet_
static void subreq_lead(struct qr_task *task)
{
assert(task);
char key[RRMAP_KEYSIZE];
char key[KR_RRKEY_LEN];
if (subreq_key(key, task) > 0) {
assert(map_contains(&task->worker->outstanding, key) == false);
map_set(&task->worker->outstanding, key, task);
......@@ -536,12 +536,12 @@ static void subreq_lead(struct qr_task *task)
static bool subreq_enqueue(struct qr_task *task)
{
assert(task);
char key[RRMAP_KEYSIZE];
char key[KR_RRKEY_LEN];
if (subreq_key(key, task) > 0) {
struct qr_task *leader = map_get(&task->worker->outstanding, key);
if (leader) {
/* Enqueue itself to leader for this subrequest. */
int ret = array_reserve_mm(leader->waiting, leader->waiting.len + 1, mm_reserve, &leader->req.pool);
int ret = array_reserve_mm(leader->waiting, leader->waiting.len + 1, kr_memreserve, &leader->req.pool);
if (ret == 0) {
array_push(leader->waiting, task);
qr_task_ref(task);
......
......@@ -137,7 +137,7 @@ You can add more flags to the build by appending them to `CFLAGS` variable, e.g.
"-pie", "**enabled**", "enables ASLR for kresd (disable with ``make HARDENING=no``)"
"RELRO", "**enabled**", "full [#]_"
You can also disable ELF hardening when it's unsupported with ``make HARDENING=no``.
You can also disable linker hardening when it's unsupported with ``make HARDENING=no``.
.. [#] See `checksec.sh <http://www.trapkit.de/tools/checksec.html>`_
......@@ -162,16 +162,29 @@ All paths are prefixed with ``PREFIX`` variable by default if not specified othe
.. csv-table::
:header: "Component", "Variable", "Default", "Notes"
"library", "``LIBDIR``", "``$(PREFIX)/lib``", "Built statically."
"library", "``LIBDIR``", "``$(PREFIX)/lib``", "pkg-config is auto-generated [#]_"
"daemon", "``BINDIR``", "``$(PREFIX)/bin``", ""
"configuration", "``ETCDIR``", "``$(PREFIX)/etc/kresd``", "Configuration file, templates."
"modules", "``MODULEDIR``", "``$(LIBDIR)/kdns_modules``", "[#]_"
"work directory", "", "``$(PREFIX)/var/run/kresd``", "Run directory for daemon."
.. [#] The ``libkres.pc`` is installed in ``$(LIBDIR)/pkgconfig``.
.. [#] Users may install additional modules in ``~/.local/lib/kdns_modules`` or in the rundir of a specific instance.
.. note:: Each module is self-contained and may install additional bundled files within ``$(MODULEDIR)/$(modulename)``. These files should be read-only, non-executable.
Static or dynamic?
~~~~~~~~~~~~~~~~~~
By default the resolver library is built as a dynamic library with versioned ABI. You can revert to static build with ``BUILDMODE`` variable.
.. code-block:: bash
$ make BUILDMODE=dynamic # Default, create dynamic library
$ make BUILDMODE=static # Create static library
When the library is linked statically, it usually produces a smaller binary. However linking it to various C modules might violate ODR and increase the size.
Building dependencies
~~~~~~~~~~~~~~~~~~~~~
......
......@@ -58,7 +58,7 @@ static void assert_right_version(struct kr_cache *cache)
/* Recreate cache and write version key */
ret = txn_api(&txn)->count(&txn.t);
if (ret > 0) { /* Non-empty cache, purge it. */
log_info("[cache] purging cache\n");
kr_log_info("[cache] purging cache\n");
kr_cache_clear(&txn);
kr_cache_txn_commit(&txn);
ret = kr_cache_txn_begin(cache, &txn, 0);
......
......@@ -18,6 +18,7 @@
#include <libknot/rrset.h>
#include <libknot/internal/namedb/namedb.h>
#include "lib/defines.h"
/** Cache entry tag */
enum kr_cache_tag {
......@@ -86,6 +87,7 @@ struct kr_cache_txn {
* @param mm memory context.
* @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);
/**
......@@ -93,6 +95,7 @@ int kr_cache_open(struct kr_cache *cache, const namedb_api_t *api, void *opts, m
* @note This doesn't clear the data, just closes the connection to the database.
* @param cache database instance
*/
KR_EXPORT
void kr_cache_close(struct kr_cache *cache);
/**
......@@ -103,6 +106,7 @@ void kr_cache_close(struct kr_cache *cache);
* @param flags transaction flags (see namedb.h in libknot)
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_txn_begin(struct kr_cache *cache, struct kr_cache_txn *txn, unsigned flags);
/**
......@@ -110,12 +114,14 @@ int kr_cache_txn_begin(struct kr_cache *cache, struct kr_cache_txn *txn, unsigne
* @param txn transaction instance
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_txn_commit(struct kr_cache_txn *txn);
/**
* Abort existing transaction instance.
* @param txn transaction instance
*/
KR_EXPORT
void kr_cache_txn_abort(struct kr_cache_txn *txn);
/**
......@@ -129,6 +135,7 @@ void kr_cache_txn_abort(struct kr_cache_txn *txn);
* @param timestamp current time (will be replaced with drift if successful)
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_peek(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type,
struct kr_cache_entry **entry, uint32_t *timestamp);
......@@ -144,6 +151,7 @@ int kr_cache_peek(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *nam
* @param data inserted data
* @return 0 or an errcode
*/
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);
......@@ -155,6 +163,7 @@ int kr_cache_insert(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *n
* @param type record type
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_remove(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type);
/**
......@@ -162,6 +171,7 @@ int kr_cache_remove(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *n
* @param txn transaction instance
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_clear(struct kr_cache_txn *txn);
/**
......@@ -173,6 +183,7 @@ int kr_cache_clear(struct kr_cache_txn *txn);
* @param timestamp current time
* @return rank (0 or positive), or an error (negative number)
*/
KR_EXPORT
int kr_cache_peek_rank(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type, uint32_t timestamp);
/**
......@@ -184,6 +195,7 @@ int kr_cache_peek_rank(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t
* @param timestamp current time (will be replaced with drift if successful)
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_peek_rr(struct kr_cache_txn *txn, knot_rrset_t *rr, uint16_t *rank, uint32_t *timestamp);
/**
......@@ -194,6 +206,7 @@ int kr_cache_peek_rr(struct kr_cache_txn *txn, knot_rrset_t *rr, uint16_t *rank,
* @param mm memory context
* @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);
/**
......@@ -204,6 +217,7 @@ int kr_cache_materialize(knot_rrset_t *dst, const knot_rrset_t *src, uint32_t dr
* @param timestamp current time
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_insert_rr(struct kr_cache_txn *txn, const knot_rrset_t *rr, uint16_t rank, uint32_t timestamp);
/**
......@@ -215,6 +229,7 @@ int kr_cache_insert_rr(struct kr_cache_txn *txn, const knot_rrset_t *rr, uint16_
* @param timestamp current time (will be replaced with drift if successful)
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_peek_rrsig(struct kr_cache_txn *txn, knot_rrset_t *rr, uint16_t *rank, uint32_t *timestamp);
/**
......@@ -226,4 +241,5 @@ int kr_cache_peek_rrsig(struct kr_cache_txn *txn, knot_rrset_t *rr, uint16_t *ra
* @param timestamp current time
* @return 0 or an errcode
*/
KR_EXPORT
int kr_cache_insert_rrsig(struct kr_cache_txn *txn, const knot_rrset_t *rr, uint16_t rank, uint32_t timestamp);
......@@ -27,11 +27,13 @@
#define KR_CONST __attribute__((__const__))
#define KR_PURE __attribute__((__pure__))
#define KR_NORETURN __attribute__((__noreturn__))
#define KR_COLD __attribute__((__cold__))
#else
#define KR_EXPORT
#define KR_CONST
#define KR_PURE
#define KR_NORETURN
#define KR_COLD
#endif
/*
......
......@@ -16,23 +16,27 @@
#pragma once
#include "lib/defines.h"
#include <libknot/internal/consts.h>
#include <libknot/packet/pkt.h>
/**
* Initialise cryptographic back-end.
*/
KR_EXPORT
void kr_crypto_init(void);
/**
* De-initialise cryptographic back-end.
*/
KR_EXPORT
void kr_crypto_cleanup(void);
/**
* Re-initialise cryptographic back-end.
* @note Must be called after fork() in the child.
*/
KR_EXPORT
void kr_crypto_reinit(void);
/** Opaque DNSSEC key pointer. */
......@@ -89,12 +93,15 @@ int kr_dnskeys_trusted(const knot_pkt_t *pkt, knot_section_t section_id, const k
bool has_nsec3);
/** Return true if the DNSKEY can be used as a ZSK. */
KR_EXPORT KR_PURE
bool kr_dnssec_key_zsk(const uint8_t *dnskey_rdata);
/** Return true if the DNSKEY indicates being KSK (=> has SEP). */
KR_EXPORT KR_PURE
bool kr_dnssec_key_ksk(const uint8_t *dnskey_rdata);
/** Return true if the DNSKEY is revoked. */
KR_EXPORT KR_PURE
bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata);
/** Return DNSKEY tag.
......@@ -103,6 +110,7 @@ bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata);
* @param rdlen RDATA length.
* @return Key tag (positive number), or an error code
*/
KR_EXPORT KR_PURE
int kr_dnssec_key_tag(uint16_t rrtype, const uint8_t *rdata, size_t rdlen);
/** Return 0 if the two keys are identical.
......@@ -113,6 +121,7 @@ int kr_dnssec_key_tag(uint16_t rrtype, const uint8_t *rdata, size_t rdlen);
* @param key_b_rdlen Second key RDATA length
* @return 0 if they match or an error code
*/
KR_EXPORT KR_PURE
int kr_dnssec_key_match(const uint8_t *key_a_rdata, size_t key_a_rdlen,
const uint8_t *key_b_rdata, size_t key_b_rdlen);
......
......@@ -25,6 +25,7 @@
* @param name name of the TA
* @return non-empty RRSet or NULL
*/
KR_EXPORT
knot_rrset_t *kr_ta_get(map_t *trust_anchors, const knot_dname_t *name);
/**
......@@ -37,6 +38,7 @@ knot_rrset_t *kr_ta_get(map_t *trust_anchors, const knot_dname_t *name);
* @param rdlen
* @return 0 or an error
*/
KR_EXPORT
int kr_ta_add(map_t *trust_anchors, const knot_dname_t *name, uint16_t type,
uint32_t ttl, const uint8_t *rdata, uint16_t rdlen);
......@@ -47,6 +49,7 @@ int kr_ta_add(map_t *trust_anchors, const knot_dname_t *name, uint16_t type,
* @param name name of the TA
* @return boolean
*/
KR_EXPORT KR_PURE
int kr_ta_covers(map_t *trust_anchors, const knot_dname_t *name);
/**
......@@ -55,10 +58,12 @@ int kr_ta_covers(map_t *trust_anchors, const knot_dname_t *name);
* @param name name of the TA
* @return 0 or an error
*/
KR_EXPORT
int kr_ta_del(map_t *trust_anchors, const knot_dname_t *name);
/**
* Clear trust store.
* @param trust_anchors trust store
*/
KR_EXPORT
void kr_ta_clear(map_t *trust_anchors);
......@@ -17,6 +17,13 @@
#include "map.h"
/* Exports */
#if defined _WIN32 || defined __CYGWIN__
#define EXPORT __attribute__ ((dllexport))
#else
#define EXPORT __attribute__ ((visibility ("default")))
#endif
#ifdef _MSC_VER /* MSVC */
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
......@@ -112,7 +119,7 @@ static cb_data_t *cbt_make_data(map_t *map, const uint8_t *str, size_t len, void
}
/*! Creates a new, empty critbit map */
map_t map_make(void)
EXPORT map_t map_make(void)
{
map_t map;
map.root = NULL;
......@@ -123,12 +130,12 @@ map_t map_make(void)
}
/*! Returns non-zero if map contains str */
int map_contains(map_t *map, const char *str)
EXPORT int map_contains(map_t *map, const char *str)
{
return map_get(map, str) != NULL;
}
void *map_get(map_t *map, const char *str)
EXPORT void *map_get(map_t *map, const char *str)
{
const uint8_t *ubytes = (void *)str;
const size_t ulen = strlen(str);
......@@ -161,7 +168,7 @@ void *map_get(map_t *map, const char *str)
}
/*! Inserts str into map, returns 0 on success */
int map_set(map_t *map, const char *str, void *value)
EXPORT int map_set(map_t *map, const char *str, void *value)
{
const uint8_t *const ubytes = (void *)str;
const size_t ulen = strlen(str);
......@@ -262,7 +269,7 @@ int map_set(map_t *map, const char *str, void *value)
}
/*! Deletes str from the map, returns 0 on success */
int map_del(map_t *map, const char *str)
EXPORT int map_del(map_t *map, const char *str)
{
const uint8_t *ubytes = (void *)str;
const size_t ulen = strlen(str);
......@@ -307,7 +314,7 @@ int map_del(map_t *map, const char *str)
}
/*! Clears the given map */
void map_clear(map_t *map)
EXPORT void map_clear(map_t *map)
{
if (map->root) {
cbt_traverse_delete(map, map->root);
......@@ -316,7 +323,7 @@ void map_clear(map_t *map)
}
/*! Calls callback for all strings in map with the given prefix */
int map_walk_prefixed(map_t *map, const char *prefix,
EXPORT int map_walk_prefixed(map_t *map, const char *prefix,
int (*callback)(const char *, void *, void *), void *baton)
{
const uint8_t *ubytes = (void *)prefix;
......
......@@ -25,7 +25,7 @@
#define QRDEBUG(query, cls, fmt, ...) do { \
unsigned _ind = 0; \
for (struct kr_query *q = (query); q; q = q->parent, _ind += 2); \
log_debug("[%s] %*s" fmt, cls, _ind, "", ## __VA_ARGS__); \
kr_log_debug("[%s] %*s" fmt, cls, _ind, "", ## __VA_ARGS__); \
} while (0)
#else
#define QRDEBUG(query, cls, fmt, ...)
......
......@@ -45,11 +45,30 @@ libkres_LIBS := $(contrib_TARGET) $(libknot_LIBS) $(libdnssec_LIBS)
libkres_TARGET := -L$(abspath lib) -lkres
# Make library
ifeq ($(BUILDMODE), static)
$(eval $(call make_static,libkres,lib,yes))
else
$(eval $(call make_lib,libkres,lib,yes,$(ABIVER)))
endif
# Generate pkg-config file
libkres.pc:
@echo 'prefix='$(PREFIX) > $@
@echo 'exec_prefix=$${prefix}' >> $@
@echo 'libdir='$(LIBDIR) >> $@
@echo 'includedir='$(INCLUDEDIR) >> $@
@echo 'Name: libkres' >> $@
@echo 'Description: Knot DNS Resolver library' >> $@
@echo 'URL: https://www.knot-dns.cz' >> $@
@echo 'Version: $(MAJOR).$(MINOR).$(PATCH)' >> $@
@echo 'Libs: -L$${libdir} -lkres' >> $@
@echo 'Cflags: -I$${includedir}' >> $@
libkres-pcinstall: libkres.pc libkres-install
$(INSTALL) -m 644 $< $(DESTDIR)$(LIBDIR)/pkgconfig
# Targets
lib: $(libkres)
lib-install: libkres-install
lib-install: libkres-install libkres-pcinstall
lib-clean: libkres-clean
.PHONY: lib lib-install lib-clean
.PHONY: lib lib-install lib-clean libkres.pc
......@@ -72,6 +72,7 @@ struct kr_module {
* @param path module search path
* @return 0 or an error
*/
KR_EXPORT
int kr_module_load(struct kr_module *module, const char *name, const char *path);
/**
......@@ -79,6 +80,7 @@ int kr_module_load(struct kr_module *module, const char *name, const char *path)
*
* @param module module structure
*/
KR_EXPORT
void kr_module_unload(struct kr_module *module);
/**
......
......@@ -87,6 +87,7 @@ struct kr_nsrep
* @param addr_len address bytes length (type will be derived from this)
* @return 0 or an error code
*/
KR_EXPORT
int kr_nsrep_set(struct kr_query *qry, uint8_t *addr, size_t addr_len);
/**
......@@ -95,6 +96,7 @@ int kr_nsrep_set(struct kr_query *qry, uint8_t *addr, size_t addr_len);
* @param ctx resolution context
* @return 0 or an error code
*/
KR_EXPORT
int kr_nsrep_elect(struct kr_query *qry, struct kr_context *ctx);
/**
......@@ -103,6 +105,7 @@ int kr_nsrep_elect(struct kr_query *qry, struct kr_context *ctx);
* @param ctx resolution context
* @return 0 or an error code
*/
KR_EXPORT
int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx);
/**
......@@ -116,6 +119,7 @@ int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx);
* @param cache LRU cache
* @return 0 on success, error code on failure
*/
KR_EXPORT
int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr, unsigned score, kr_nsrep_lru_t *cache);
/**
......@@ -126,4 +130,5 @@ int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr, unsign
* @param cache LRU cache
* @return 0 on success, error code on failure
*/
KR_EXPORT
int kr_nsrep_update_rep(struct kr_nsrep *ns, unsigned reputation, kr_nsrep_lru_t *cache);
......@@ -132,6 +132,7 @@ struct kr_request {
* @param answer allocated packet for final answer
* @return CONSUME (expecting query)
*/
KR_EXPORT
int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pkt_t *answer);
/**
......@@ -144,6 +145,7 @@ int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pk
* @param packet [in] input packet
* @return any state
*/
KR_EXPORT
int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, knot_pkt_t *packet);
/**
......@@ -159,6 +161,7 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k
* @param packet [out] packet to be filled with additional query
* @return any state
*/
KR_EXPORT
int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *type, knot_pkt_t *packet);
/**
......@@ -171,6 +174,7 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t
* @param state either DONE or FAIL state
* @return DONE
*/
KR_EXPORT
int kr_resolve_finish(struct kr_request *request, int state);
/**
......@@ -178,6 +182,7 @@ int kr_resolve_finish(struct kr_request *request, int state);
* @param request request state
* @return pointer to rplan
*/
KR_EXPORT KR_PURE
struct kr_rplan *kr_resolve_plan(struct kr_request *request);
/**
......@@ -185,5 +190,6 @@ struct kr_rplan *kr_resolve_plan(struct kr_request *request);
* @param request request state
* @return mempool
*/
KR_EXPORT KR_PURE
mm_ctx_t *kr_resolve_pool(struct kr_request *request);
......@@ -36,6 +36,11 @@ const lookup_table_t query_flag_names[] = {
{ 0, NULL }
};
const lookup_table_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)
{
if (name == NULL) {
......
......@@ -54,7 +54,8 @@ enum kr_query_flag {
};
/** Query flag names table */
extern const lookup_table_t query_flag_names[];
KR_EXPORT KR_CONST
const lookup_table_t *kr_query_flag_names(void);
/**
* Single query representation.
......@@ -94,12 +95,14 @@ struct kr_rplan {
* @param request resolution request
* @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);
/**
* Deinitialize resolution plan, aborting any uncommited transactions.
* @param rplan plan instance
*/
KR_EXPORT
void kr_rplan_deinit(struct kr_rplan *rplan);
/**
......@@ -107,6 +110,7 @@ void kr_rplan_deinit(struct kr_rplan *rplan);
* @param rplan plan instance
* @return true or false
*/
KR_EXPORT KR_PURE
bool kr_rplan_empty(struct kr_rplan *rplan);
/**
......@@ -119,6 +123,7 @@ bool kr_rplan_empty(struct kr_rplan *rplan);
* @param type resolved type
* @return query instance or NULL
*/
KR_EXPORT
struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
const knot_dname_t *name, uint16_t cls, uint16_t type);
......@@ -129,15 +134,19 @@ struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent,
* @param qry resolved query
* @return 0 or an error
*/
KR_EXPORT
int kr_rplan_pop(struct kr_rplan *rplan, struct kr_query *qry);
/**
* Return true if resolution chain satisfies given query.
*/
KR_EXPORT KR_PURE
bool kr_rplan_satisfies(struct kr_query *closure, const knot_dname_t *name, uint16_t cls, uint16_t type);
/** Return last resolved query. */
KR_EXPORT KR_PURE
struct kr_query *kr_rplan_resolved(struct kr_rplan *rplan);
/** Return query predecessor. */
KR_EXPORT KR_PURE
struct kr_query *kr_rplan_next(struct kr_query *qry);
\ No newline at end of file
......@@ -34,7 +34,7 @@
#include "lib/resolve.h"
/* Logging & debugging */
bool _env_debug = false;
static bool _env_debug = false;
/** @internal CSPRNG context */
static isaac_ctx ISAAC;
......@@ -64,19 +64,26 @@ static inline int u16tostr(uint8_t *dst, uint16_t num)
/*
* Cleanup callbacks.
*/
void _cleanup_free(char **p)
bool kr_debug_set(bool status)
{
free(*p);
return _env_debug = status;
}
void _cleanup_close(int *p)