]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
build: library able to compile to both static/dynamic versioned libs
authorMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 9 Dec 2015 22:52:09 +0000 (23:52 +0100)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 9 Dec 2015 23:43:02 +0000 (00:43 +0100)
* 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

27 files changed:
config.mk
contrib/contrib.mk [new file with mode: 0644]
daemon/daemon.mk
daemon/engine.c
daemon/main.c
daemon/worker.c
doc/build.rst
lib/cache.c
lib/cache.h
lib/defines.h
lib/dnssec.h
lib/dnssec/ta.h
lib/generic/map.c
lib/layer.h
lib/lib.mk
lib/module.h
lib/nsrep.h
lib/resolve.h
lib/rplan.c
lib/rplan.h
lib/utils.c
lib/utils.h
lib/zonecut.c
lib/zonecut.h
platform.mk
tests/test_utils.c
tests/unit.mk

index 4a0719a54513292ac8568ebbcfb40a843a2ca112..33117bd6c61996ecc766fb49ab51c23c4a7c98d1 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -2,6 +2,8 @@
 MAJOR := 1
 MINOR := 0
 PATCH := 0-beta2
+ABIVER := 1
+BUILDMODE := dynamic
 HARDENING := yes
 
 # Paths
diff --git a/contrib/contrib.mk b/contrib/contrib.mk
new file mode 100644 (file)
index 0000000..3daf43d
--- /dev/null
@@ -0,0 +1,10 @@
+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))
index b3ee60de9e9b2617b54f3539ada999539415da7a..c96c1e46de7eecebdc3bf84da6087084e0be5a06 100644 (file)
@@ -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)
index 2890c598ff18efc2c6d692593957761a3c8f3350..fcdca1aad89837f6154bde5f3efcaa59fca1dfe2 100644 (file)
@@ -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;
index f874a1f15e18ec1699f39d45ac9a109a5384f672..62375a40e30bdd8d1a7bd090e729703fb62e731d 100644 (file)
@@ -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);
index cb5dd83b9dc493b3f35483a4451f06b6897dbca8..b05643a2726f2a99ad4137d704eed1fa25631e83 100644 (file)
@@ -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);
index 383b37b5f736c8c095b7a4e7f24709e57cb98d4e..bff2bbbedbc2ffb7991eb559a3ad31375bab5e22 100644 (file)
@@ -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
 ~~~~~~~~~~~~~~~~~~~~~
 
index 64394bd3ed6e8e0fb4e4dd679e69b819353f4b67..50347f7220d796f20bb6e2a01bd1813aca96bf4e 100644 (file)
@@ -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);
index 211eb20cf5754112083a43b611409610fec8e8cb..3fabea7ced0d18e8764e2af1434a56d308d10607 100644 (file)
@@ -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);
index c70c279f980c1657884cb8d0a05ce40162e8d7ae..7031f7ddb5fe8d9fc270ae0d1ee6e7f73a9620c2 100644 (file)
 #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
 
 /*
index 7679f730a2a41d7a410248687b09b376bda29d3f..82ea7bccfa290a0e2970ed3091ea8b05c8d0072d 100644 (file)
 
 #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);
 
index 6c712a0db162205b985d01c66d837ea8e77f8a4d..3541c4ac4e4ab275f6c307f0751e9b45344682da 100644 (file)
@@ -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);
index a6a12911a2b6bd8546dfa15b04327690ef89f45f..81a283dc5c900411875a3f9e8f622d37609ae7c8 100644 (file)
 
 #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 @@ different_byte_found:
 }
 
 /*! 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;
index 335edadef26939727af6a77e9a6174d7e9bbaf01..3d1d536a3e602e7b9b626f64d0252edd3966d383 100644 (file)
@@ -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, ...)
index d981e4f777f19adc582abc760c550a405e92bd53..822af51f78f356b1d02227c56a64caf4c8259e84 100644 (file)
@@ -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
index d3d2c7b307421b5d38a70085b68f4909462ca45e..4b9ec2b95cbc0939834ae60a04020471b02e57cf 100644 (file)
@@ -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);
 
 /**
index dbeca487645af7be80d99bbcf28e1dda30473f61..848b28f0b542be9886ddd3c62be7f773a6997776 100644 (file)
@@ -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);
index 20d589d5bb7c0c68a45211665232902681f0afb7..905e134e003c123b5cd613871f6e695e8304219a 100644 (file)
@@ -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);
 
index db6bad1646a7e69018d2debe865fe2e53789c1dc..8bae41cd1dab5e67bfab02c9b43c5a30db12ffbd 100644 (file)
@@ -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) {
index 86fd061dbeed5791a5827ea965e5a24fde706f81..0d05269c755d4c7e1140675489af4a1a7ddd866a 100644 (file)
@@ -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
index 22365787c083cc46119528711eba32f087e14d2d..b2511754411bc79cd4cee7136a2355624392c05c 100644 (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)
+bool kr_debug_status(void)
 {
-       if (*p > 0) close(*p);
+       return _env_debug;
 }
 
-void _cleanup_fclose(FILE **p)
+void kr_log_debug(const char *fmt, ...)
 {
-       if (*p) fclose(*p);
+       if (_env_debug) {
+               va_list args;
+               va_start(args, fmt);
+               vprintf(fmt, args);
+               va_end(args);
+               fflush(stdout);
+       }
 }
 
 char* kr_strcatdup(unsigned n, ...)
@@ -163,7 +170,7 @@ unsigned kr_rand_uint(unsigned max)
        return isaac_next_uint(&ISAAC, max);
 }
 
-int mm_reserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have)
+int kr_memreserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have)
 {
     if (*have >= want) {
         return 0;
@@ -306,7 +313,7 @@ int kr_bitcmp(const char *a, const char *b, int bits)
        return ret;
 }
 
-int kr_rrmap_key(char *key, const knot_dname_t *owner, uint16_t type, uint8_t rank)
+int kr_rrkey(char *key, const knot_dname_t *owner, uint16_t type, uint8_t rank)
 {
        if (!key || !owner) {
                return kr_error(EINVAL);
@@ -332,7 +339,7 @@ int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, mm_ctx_t *p
        }
 
        /* Stash key = {[1] flags, [1-255] owner, [5] type, [1] \x00 } */
-       char key[RRMAP_KEYSIZE];
+       char key[KR_RRKEY_LEN];
        uint8_t extra_flags = 0;
        uint16_t rrtype = rr->type;
        /* Stash RRSIGs in a special cache, flag them and set type to its covering RR.
@@ -341,7 +348,7 @@ int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, mm_ctx_t *p
                rrtype = knot_rrsig_type_covered(&rr->rrs, 0);
                extra_flags |= KEY_FLAG_RRSIG;
        }
-       int ret = kr_rrmap_key(key, rr->owner, rrtype, rank);
+       int ret = kr_rrkey(key, rr->owner, rrtype, rank);
        if (ret <= 0) {
                return kr_error(EILSEQ);
        }
@@ -362,7 +369,7 @@ int kr_rrmap_add(map_t *stash, const knot_rrset_t *rr, uint8_t rank, mm_ctx_t *p
 
 int kr_rrarray_add(rr_array_t *array, const knot_rrset_t *rr, mm_ctx_t *pool)
 {
-       int ret = array_reserve_mm(*array, array->len + 1, mm_reserve, pool);
+       int ret = array_reserve_mm(*array, array->len + 1, kr_memreserve, pool);
        if (ret != 0) {
                return kr_error(ENOMEM);
        }
index a5b34dffcb0b6b2e41ac1c5b956255ac6602ecdd..d47dce3b6cec0814b9baf1610ce44abf7cd0ffa0 100644 (file)
 /*
  * Logging and debugging.
  */
-#define log_info(fmt, ...) printf((fmt), ## __VA_ARGS__)
-#define log_error(fmt, ...) fprintf(stderr, (fmt), ## __VA_ARGS__)
+#define kr_log_info(fmt, ...) printf((fmt), ## __VA_ARGS__)
+#define kr_log_error(fmt, ...) fprintf(stderr, (fmt), ## __VA_ARGS__)
 #ifndef NDEBUG
-extern bool _env_debug; /* @internal cond variable */
 /* Toggle debug messages */
-#define log_debug_enable(x) _env_debug = (x)
-#define log_debug_status() _env_debug
-/* Message logging */
-#define log_debug(fmt, ...) do { \
-    if (_env_debug) { printf((fmt), ## __VA_ARGS__); fflush(stdout); } \
-    } while (0)
+KR_EXPORT bool kr_debug_set(bool status);
+KR_EXPORT KR_PURE bool kr_debug_status(void);
+KR_EXPORT void kr_log_debug(const char *fmt, ...);
 /* Debug block */
-#define WITH_DEBUG if(__builtin_expect(_env_debug, 0))
+#define WITH_DEBUG if(__builtin_expect(kr_debug_status(), 0))
 #else
-#define log_debug_status() false
-#define log_debug_enable(x)
-#define log_debug(fmt, ...)
+#define kr_debug_status() false
+#define kr_debug_set(x)
+#define kr_log_debug(fmt, ...)
 #define WITH_DEBUG if(0)
 #endif
 
@@ -71,47 +67,65 @@ typedef array_t(knot_rrset_t *) rr_array_t;
 #define kr_rdataset_next(rd) (rd + knot_rdata_array_size(knot_rdata_rdlen(rd)))
 
 /** Concatenate N strings. */
+KR_EXPORT
 char* kr_strcatdup(unsigned n, ...);
 
 /** Reseed CSPRNG context. */
 int kr_rand_reseed(void);
 
 /** Get pseudo-random value. */
+KR_EXPORT
 unsigned kr_rand_uint(unsigned max);
 
 /** Memory reservation routine for mm_ctx_t */
-int mm_reserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have);
+KR_EXPORT
+int kr_memreserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have);
 
 /** @internal Fast packet reset. */
+KR_EXPORT
 int kr_pkt_recycle(knot_pkt_t *pkt);
 
 /** Construct and put record to packet. */
+KR_EXPORT
 int kr_pkt_put(knot_pkt_t *pkt, const knot_dname_t *name, uint32_t ttl,
                uint16_t rclass, uint16_t rtype, const uint8_t *rdata, uint16_t rdlen);
 
 /** Address bytes for given family. */
+KR_EXPORT KR_PURE
 const char *kr_inaddr(const struct sockaddr *addr);
 /** Address length for given family. */
+KR_EXPORT KR_PURE
 int kr_inaddr_len(const struct sockaddr *addr);
 /** Return address type for string. */
+KR_EXPORT KR_PURE
 int kr_straddr_family(const char *addr);
 /** Return address length in given family. */
+KR_EXPORT KR_CONST
 int kr_family_len(int family);
 /** Parse address and return subnet length (bits).
   * @warning 'dst' must be at least `sizeof(struct in6_addr)` long. */
+KR_EXPORT
 int kr_straddr_subnet(void *dst, const char *addr);
 /** Compare memory bitwise. */
+KR_EXPORT KR_PURE
 int kr_bitcmp(const char *a, const char *b, int bits);
 
 /** @internal RR map flags. */
 #define KEY_FLAG_RRSIG 0x02
 #define KEY_FLAG_RANK(key) (key[0] >> 2)
 #define KEY_COVERING_RRSIG(key) (key[0] & KEY_FLAG_RRSIG)
-/* Stash key = {[1] flags, [1-255] owner, [5] type, [1] \x00 } */
-#define RRMAP_KEYSIZE (9 + KNOT_DNAME_MAXLEN)
 
-/** @internal Create unique string key for RR. */
-int kr_rrmap_key(char *key, const knot_dname_t *owner, uint16_t type, uint8_t rank);
+/* Stash key = {[1] flags, [1-255] owner, [5] type, [1] \x00 } */
+#define KR_RRKEY_LEN (9 + KNOT_DNAME_MAXLEN)
+/** Create unique null-terminated string key for RR.
+  * @param key Destination buffer for key size, MUST be KR_RRKEY_LEN or larger.
+  * @param owner RR owner domain name.
+  * @param type RR type.
+  * @param rank RR rank (8 bit tag usable for anything).
+  * @return key length if successful or an error
+  * */
+KR_EXPORT
+int kr_rrkey(char *key, const knot_dname_t *owner, uint16_t type, uint8_t rank);
 
 /** @internal Merges RRSets with matching owner name and type together.
  * @note RRSIG RRSets are merged according the type covered fields.
@@ -125,4 +139,5 @@ int kr_rrarray_add(rr_array_t *array, const knot_rrset_t *rr, mm_ctx_t *pool);
 /**
  * Call module property.
  */
+KR_EXPORT
 char *kr_module_call(struct kr_context *ctx, const char *module, const char *prop, const char *input);
index ca22b561d92616bf5dad1bdc1eddf4b99eb31a30..05e18a9cf8eab42977541409152c211bb3fd3990 100644 (file)
@@ -223,7 +223,7 @@ int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rd
                return kr_ok();
        }
        /* Push new address */
-       int ret = pack_reserve_mm(*pack, 1, rdlen, mm_reserve, cut->pool);
+       int ret = pack_reserve_mm(*pack, 1, rdlen, kr_memreserve, cut->pool);
        if (ret != 0) {
                return kr_error(ENOMEM);
        }
index a3eca008225a287cc1a4e46fae13ba8852e979f0..64ebd7b5b998b325171ef1faa2f416138ed0e570 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "lib/generic/map.h"
 #include "lib/generic/pack.h"
+#include "lib/defines.h"
 #include "lib/cache.h"
 
 struct kr_rplan;
@@ -42,12 +43,14 @@ struct kr_zonecut {
  * @param 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);
 
 /**
  * Clear the structure and free the address set.
  * @param cut zone cut
  */
+KR_EXPORT
 void kr_zonecut_deinit(struct kr_zonecut *cut);
 
 /**
@@ -56,6 +59,7 @@ void kr_zonecut_deinit(struct kr_zonecut *cut);
  * @param cut  zone cut to be set
  * @param name new zone cut name
  */
+KR_EXPORT
 void kr_zonecut_set(struct kr_zonecut *cut, const knot_dname_t *name);
 
 /** 
@@ -64,6 +68,7 @@ void kr_zonecut_set(struct kr_zonecut *cut, const knot_dname_t *name);
  * @param src source zone cut
  * @return 0 or an error code
  */
+KR_EXPORT
 int kr_zonecut_copy(struct kr_zonecut *dst, const struct kr_zonecut *src);
 
 /**
@@ -72,6 +77,7 @@ int kr_zonecut_copy(struct kr_zonecut *dst, const struct kr_zonecut *src);
  * @param src source zone cut
  * @return 0 or an error code
  */
+KR_EXPORT
 int kr_zonecut_copy_trust(struct kr_zonecut *dst, const struct kr_zonecut *src);
 
 /**
@@ -85,6 +91,7 @@ int kr_zonecut_copy_trust(struct kr_zonecut *dst, const struct kr_zonecut *src);
  * @param rdata  nameserver address (as rdata)
  * @return 0 or error code
  */
+KR_EXPORT
 int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rdata_t *rdata);
 
 /**
@@ -94,6 +101,7 @@ int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rd
  * @param  rdata name server address
  * @return       0 or error code
  */
+KR_EXPORT
 int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rdata_t *rdata);
 
 /**
@@ -106,6 +114,7 @@ int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rd
  * @param  ns    name server name
  * @return       pack of addresses or NULL
  */
+KR_EXPORT KR_PURE
 pack_t *kr_zonecut_find(struct kr_zonecut *cut, const knot_dname_t *ns);
 
 /**
@@ -115,6 +124,7 @@ pack_t *kr_zonecut_find(struct kr_zonecut *cut, const knot_dname_t *ns);
  * @param cut zone cut to be populated
  * @return 0 or error code
  */
+KR_EXPORT
 int kr_zonecut_set_sbelt(struct kr_context *ctx, struct kr_zonecut *cut);
 
 /**
@@ -128,5 +138,6 @@ int kr_zonecut_set_sbelt(struct kr_context *ctx, struct kr_zonecut *cut);
  * @param secured   set to true if want secured zone cut, will return false if it is provably insecure
  * @return 0 or error code (ENOENT if it doesn't find anything)
  */
+KR_EXPORT
 int kr_zonecut_find_cached(struct kr_context *ctx, struct kr_zonecut *cut, const knot_dname_t *name,
                            struct kr_cache_txn *txn, uint32_t timestamp, bool * restrict secured);
index 7d85a13212723cf7636c53d8dcbe2978dd10d436..dd01c96841f3469dfc9ec549758f52e1ee86ce1c 100644 (file)
@@ -16,6 +16,10 @@ ARTYPE  := static
 BINEXT :=
 PLATFORM = Linux
 ARCH := $(word 1, $(subst -, ,$(shell $(CC) -dumpmachine)))
+# Library versioning flags (platform-specific)
+SOVER = 
+# Library versioned extension (platform-specific)
+SOVER_EXT = $(LIBEXT).$(1)
 ifeq ($(OS),Windows_NT)
        PLATFORM := Windows
        RM := del
@@ -32,6 +36,9 @@ else
         ifneq ($(HARDENING),no)
             BINFLAGS += -Wl,-pie
         endif
+        # Version is prepended to dylib
+        SOVER_EXT = .$(1)$(LIBEXT)
+        SOVER = $(if $(1), -compatibility_version $(2) -current_version $(1),)
     else
         PLATFORM := POSIX
         LDFLAGS += -pthread -lm -Wl,-E
@@ -81,7 +88,7 @@ $(2)/$(1)$(3): $$($(1)_OBJ) $$($(1)_DEPEND)
 ifeq ($(4),-$(ARTYPE))
        $(call quiet,AR,$$@) rcs $$@ $$($(1)_OBJ)
 else
-       $(call quiet,CCLD,$$@) $$($(1)_CFLAGS) $(BUILD_CFLAGS) $$($(1)_OBJ) -o $$@ $(4) $$($(1)_LDFLAGS) $$($(1)_LIBS) $(BUILD_LDFLAGS)
+       $(call quiet,CCLD,$$@) $$($(1)_CFLAGS) $(BUILD_CFLAGS) $$($(1)_OBJ) $(call SOVER,$(7),$(7)) -o $$@ $(4) $$($(1)_LIBS) $(BUILD_LDFLAGS) $$($(1)_LDFLAGS)
 endif
 # Additional rules
 $(1)-clean:
@@ -90,10 +97,17 @@ ifeq ($(6), yes)
        $(RM) $(1).amalg.c $(1).amalg.o
 endif
 $(1)-install: $(2)/$(1)$(3)
+# Modules install to special path
 ifneq ($(5),$(MODULEDIR))
        $(INSTALL) -d $(DESTDIR)$(5)
 endif
+# Versioned library install
+ifneq ($(strip $(7)),)
+       $(INSTALL) $(2)/$(1)$(3) $(DESTDIR)$(5)/$(1)$(call SOVER_EXT,$(7))
+       $(LN) -f $(1)$(call SOVER_EXT,$(7)) $(DESTDIR)$(5)/$(1)$(3)
+else
        $(INSTALL) $(2)/$(1)$(3) $(DESTDIR)$(5)
+endif
 ifneq ($$(strip $$($(1)_HEADERS)),)
        $(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)/$(1)
        $(INSTALL) -m 644 $$($(1)_HEADERS) $(DESTDIR)$(INCLUDEDIR)/$(1)
@@ -101,9 +115,9 @@ endif
 .PHONY: $(1)-clean $(1)-install
 endef
 
-# Make targets (name,path,amalgable yes|no)
+# Make targets (name,path,amalgable yes|no,abiver)
 make_bin = $(call make_target,$(1),$(2),$(BINEXT),$(BINFLAGS),$(BINDIR),$(3))
-make_lib = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(LIBDIR),$(3))
+make_lib = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(LIBDIR),$(3),$(4))
 make_module = $(call make_target,$(1),$(2),$(LIBEXT),-$(LIBTYPE),$(MODULEDIR),$(3))
 make_shared = $(call make_target,$(1),$(2),$(MODEXT),-$(MODTYPE),$(LIBDIR),$(3))
 make_static = $(call make_target,$(1),$(2),$(AREXT),-$(ARTYPE),$(LIBDIR),$(3))
index f4e1b582eb1c7edfaba1b546fb6bbe3685a465aa..c874ef8d68649103235b2fd0e84534db4725acd8 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <sys/socket.h>
 #include <stdio.h>
+#include <contrib/cleanup.h>
 
 #include "tests/test.h"
 #include "lib/utils.h"
index ef819622254c08fcc2401771a957e3e03f108762..9e16890957a31c79f127c5e5956a439efa25f170 100644 (file)
@@ -22,6 +22,13 @@ $(eval $(call make_lib,mock_cmodule,tests))
 tests_DEPEND := $(libkres) $(mock_cmodule) $(mock_gomodule)
 tests_LIBS :=  $(libkres_TARGET) $(libkres_LIBS) $(cmocka_LIBS)
 
+# Platform-specific library injection
+ifeq ($(PLATFORM),Darwin)
+       preload_syms := DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_LIBRARY_PATH="$(DYLD_LIBRARY_PATH):$(abspath lib)"
+else
+       preload_syms := LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):$(abspath lib)"
+endif
+
 # Make test binaries
 define make_test
 $(1)_CFLAGS := -fPIE
@@ -30,7 +37,7 @@ $(1)_LIBS := $(tests_LIBS)
 $(1)_DEPEND := $(tests_DEPEND)
 $(call make_bin,$(1),tests)
 $(1): $$($(1))
-       @$$<
+       @$(preload_syms) $$<
 .PHONY: $(1)
 endef